summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoryan11.meng <yan11.meng@samsung.com>2020-02-26 12:47:07 +0900
committeryan11.meng <yan11.meng@samsung.com>2020-02-26 12:47:07 +0900
commit13ec6f74c73b377d6233de42cc942846e976541b (patch)
tree894efb8d5e53dd68dd463f7b222406439f4f494d
parent5015799de7fb1dc08b584c0044d8393e4062ff34 (diff)
downloadpython-M2Crypto-13ec6f74c73b377d6233de42cc942846e976541b.tar.gz
python-M2Crypto-13ec6f74c73b377d6233de42cc942846e976541b.tar.bz2
python-M2Crypto-13ec6f74c73b377d6233de42cc942846e976541b.zip
Imported Upstream version 0.35.1upstream/0.35.1.1submit/tizen/20200302.173023
Change-Id: Id4a444b8c1d11fee1026b433a47ca5aabcf11622
-rw-r--r--CHANGES256
-rw-r--r--CONTRIBUTORS.rst43
-rw-r--r--INSTALL226
-rw-r--r--INSTALL.rst166
-rw-r--r--M2Crypto.egg-info/PKG-INFO23
-rw-r--r--M2Crypto.egg-info/SOURCES.txt354
-rw-r--r--M2Crypto.egg-info/dependency_links.txt1
-rw-r--r--M2Crypto.egg-info/top_level.txt1
-rw-r--r--M2Crypto/ASN1.py187
-rw-r--r--M2Crypto/AuthCookie.py107
-rw-r--r--M2Crypto/BIO.py274
-rw-r--r--[-rwxr-xr-x]M2Crypto/BN.py37
-rw-r--r--M2Crypto/DH.py59
-rw-r--r--M2Crypto/DSA.py371
-rw-r--r--M2Crypto/EC.py422
-rw-r--r--M2Crypto/EVP.py329
-rw-r--r--M2Crypto/Engine.py73
-rw-r--r--M2Crypto/Err.py60
-rw-r--r--M2Crypto/PGP/PublicKey.py58
-rw-r--r--M2Crypto/PGP/PublicKeyRing.py81
-rw-r--r--M2Crypto/PGP/RSA.py36
-rw-r--r--M2Crypto/PGP/__init__.py14
-rw-r--r--M2Crypto/PGP/constants.py19
-rw-r--r--M2Crypto/PGP/packet.py379
-rw-r--r--M2Crypto/RC4.py19
-rw-r--r--M2Crypto/RSA.py360
-rw-r--r--M2Crypto/Rand.py148
-rw-r--r--M2Crypto/SMIME.py202
-rw-r--r--M2Crypto/SSL/Checker.py163
-rw-r--r--M2Crypto/SSL/Cipher.py32
-rw-r--r--M2Crypto/SSL/Connection.py525
-rw-r--r--M2Crypto/SSL/Context.py360
-rw-r--r--M2Crypto/SSL/SSLServer.py53
-rw-r--r--M2Crypto/SSL/Session.py30
-rw-r--r--M2Crypto/SSL/TwistedProtocolWrapper.py293
-rw-r--r--M2Crypto/SSL/__init__.py53
-rw-r--r--M2Crypto/SSL/cb.py59
-rw-r--r--M2Crypto/SSL/ssl_dispatcher.py27
-rw-r--r--M2Crypto/SSL/timeout.py34
-rw-r--r--M2Crypto/X509.py995
-rw-r--r--M2Crypto/__init__.py59
-rw-r--r--M2Crypto/callback.py4
-rw-r--r--M2Crypto/ftpslib.py21
-rw-r--r--M2Crypto/httpslib.py211
-rw-r--r--M2Crypto/m2.py6
-rw-r--r--M2Crypto/m2crypto.py87
-rw-r--r--M2Crypto/m2urllib.py111
-rw-r--r--M2Crypto/m2urllib2.py100
-rw-r--r--M2Crypto/m2xmlrpclib.py40
-rw-r--r--M2Crypto/six.py950
-rw-r--r--M2Crypto/threading.py11
-rw-r--r--M2Crypto/util.py82
-rw-r--r--MANIFEST.in13
-rw-r--r--PKG-INFO23
-rw-r--r--README.rst (renamed from README)32
-rw-r--r--SWIG/Makefile6
-rw-r--r--SWIG/Makefile.mw34
-rw-r--r--SWIG/Makefile.osx32
-rw-r--r--SWIG/_aes.i41
-rw-r--r--SWIG/_asn1.i86
-rw-r--r--SWIG/_bio.i366
-rw-r--r--[-rwxr-xr-x]SWIG/_bn.i84
-rw-r--r--SWIG/_dh.i120
-rw-r--r--SWIG/_dsa.i293
-rw-r--r--SWIG/_ec.i196
-rw-r--r--SWIG/_engine.i1
-rw-r--r--SWIG/_evp.i304
-rw-r--r--SWIG/_lib.h16
-rw-r--r--SWIG/_lib.i360
-rw-r--r--SWIG/_lib11_compat.i458
-rw-r--r--SWIG/_m2crypto.def2
-rw-r--r--SWIG/_m2crypto.i48
-rw-r--r--SWIG/_m2crypto_wrap.c32491
-rw-r--r--SWIG/_objects.i8
-rw-r--r--SWIG/_pkcs7.i113
-rw-r--r--SWIG/_py3k_compat.i43
-rw-r--r--SWIG/_rand.i74
-rw-r--r--SWIG/_rc4.i25
-rw-r--r--SWIG/_rsa.i280
-rw-r--r--SWIG/_ssl.i498
-rw-r--r--SWIG/_threads.i21
-rw-r--r--SWIG/_util.i13
-rw-r--r--SWIG/_x509.i335
-rw-r--r--SWIG/libcrypto-compat.h62
-rw-r--r--SWIG/py3k_compat.h32
-rw-r--r--appveyor.yml151
-rw-r--r--contrib/SimpleX509create.py201
-rw-r--r--contrib/dave.patch180
-rw-r--r--contrib/dispatcher.py368
-rw-r--r--contrib/isaac.httpslib.py185
-rw-r--r--contrib/m2crypto.spec46
-rw-r--r--contrib/smimeplus.py45
-rw-r--r--demo/CipherSaber/CipherSaber.py62
-rw-r--r--demo/CipherSaber/cstest1.cs11
-rw-r--r--demo/Zope/ZServer/HTTPS_Server.py187
-rw-r--r--demo/Zope/ZServer/__init__.py95
-rw-r--r--demo/Zope/ZServer/medusa/ftps_server.py438
-rw-r--r--demo/Zope/ZServer/medusa/https_server.py83
-rw-r--r--demo/Zope/ca.pem20
-rw-r--r--demo/Zope/dh1024.pem5
-rw-r--r--demo/Zope/lib/python/Products/GuardedFile/GuardedFile.py53
-rw-r--r--demo/Zope/lib/python/Products/GuardedFile/README.txt16
-rw-r--r--demo/Zope/lib/python/Products/GuardedFile/TODO.txt1
-rw-r--r--demo/Zope/lib/python/Products/GuardedFile/__init__.py25
-rw-r--r--demo/Zope/lib/python/Products/GuardedFile/add.dtml78
-rw-r--r--demo/Zope/lib/python/Products/GuardedFile/refresh.txt0
-rw-r--r--demo/Zope/lib/python/Products/GuardedFile/version.txt1
-rw-r--r--demo/Zope/lib/python/Products/ZSmime/README.txt18
-rw-r--r--demo/Zope/lib/python/Products/ZSmime/SmimeTag.py104
-rw-r--r--demo/Zope/lib/python/Products/ZSmime/__init__.py9
-rw-r--r--demo/Zope/lib/python/Products/ZSmime/version.txt1
-rw-r--r--demo/Zope/server.pem36
-rw-r--r--demo/Zope/starts17
-rwxr-xr-xdemo/Zope/starts.bat1
-rw-r--r--demo/Zope/utilities/x509_user.py79
-rw-r--r--demo/Zope/z2s.py1078
-rw-r--r--demo/Zope/z2s.py.diff266
-rw-r--r--demo/Zope27/INSTALL.txt200
-rw-r--r--demo/Zope27/install_dir/lib/python/ZServer/HTTPS_Server.py187
-rw-r--r--demo/Zope27/install_dir/lib/python/ZServer/__init__.py.patch10
-rw-r--r--demo/Zope27/install_dir/lib/python/ZServer/component.xml.patch28
-rw-r--r--demo/Zope27/install_dir/lib/python/ZServer/datatypes.py.patch59
-rw-r--r--demo/Zope27/install_dir/lib/python/ZServer/medusa/https_server.py83
-rw-r--r--demo/Zope27/instance_home/README.txt.patch7
-rw-r--r--demo/Zope27/instance_home/etc/zope.conf.patch16
-rw-r--r--demo/Zope27/instance_home/ssl/ca.pem20
-rw-r--r--demo/Zope27/instance_home/ssl/dh1024.pem5
-rw-r--r--demo/Zope27/instance_home/ssl/server.pem36
-rw-r--r--demo/ZopeX3/INSTALL.txt73
-rw-r--r--demo/ZopeX3/install_dir/lib/python/zope/app/server/configure.zcml.patch28
-rw-r--r--demo/ZopeX3/install_dir/lib/python/zope/app/server/https.py28
-rw-r--r--demo/ZopeX3/install_dir/lib/python/zope/server/http/https_server.py104
-rw-r--r--demo/ZopeX3/install_dir/lib/python/zope/server/http/https_serverchannel.py55
-rw-r--r--demo/ZopeX3/install_dir/lib/python/zope/server/http/publisherhttps_server.py83
-rw-r--r--demo/ZopeX3/instance_home/etc/zope.conf.patch26
-rw-r--r--demo/ZopeX3/instance_home/ssl/ca.pem20
-rw-r--r--demo/ZopeX3/instance_home/ssl/dh1024.pem5
-rw-r--r--demo/ZopeX3/instance_home/ssl/server.pem36
-rw-r--r--demo/bio_mem_rw.py44
-rw-r--r--demo/dhtest.py27
-rw-r--r--demo/dsa1024pvtkey.pem12
-rw-r--r--demo/dsa_bench.py176
-rw-r--r--demo/dsatest.pem8
-rw-r--r--demo/dsatest.py57
-rw-r--r--demo/ec/ecdhtest.py31
-rw-r--r--demo/ec/ecdsa_bench.py368
-rw-r--r--demo/ec/ecdsatest.pem5
-rw-r--r--demo/ec/ecdsatest.py68
-rw-r--r--demo/ec/secp160r1pvtkey.pem4
-rw-r--r--demo/https.howto/ca.pem59
-rw-r--r--demo/https.howto/dh1024.pem5
-rwxr-xr-xdemo/https.howto/get_https.py32
-rw-r--r--demo/https.howto/https_cli.py49
-rw-r--r--demo/https.howto/orig_https_srv.py153
-rw-r--r--demo/https.howto/server.pem74
-rw-r--r--demo/medusa/00_README32
-rw-r--r--demo/medusa/START.py71
-rw-r--r--demo/medusa/START_xmlrpc.py72
-rw-r--r--demo/medusa/asynchat.py292
-rw-r--r--demo/medusa/asyncore.py552
-rw-r--r--demo/medusa/auth_handler.py135
-rw-r--r--demo/medusa/ca.pem20
-rw-r--r--demo/medusa/counter.py48
-rw-r--r--demo/medusa/default_handler.py215
-rw-r--r--demo/medusa/dh1024.pem5
-rw-r--r--demo/medusa/filesys.py466
-rw-r--r--demo/medusa/ftp_server.py1127
-rw-r--r--demo/medusa/ftps_server.py438
-rw-r--r--demo/medusa/http_date.py126
-rw-r--r--demo/medusa/http_server.py784
-rw-r--r--demo/medusa/https_server.py83
-rw-r--r--demo/medusa/index.html6
-rw-r--r--demo/medusa/logger.py262
-rw-r--r--demo/medusa/m_syslog.py177
-rw-r--r--demo/medusa/medusa_gif.py8
-rw-r--r--demo/medusa/mime_type_table.py113
-rw-r--r--demo/medusa/poison_handler.py69
-rw-r--r--demo/medusa/producers.py329
-rw-r--r--demo/medusa/put_handler.py113
-rw-r--r--demo/medusa/redirecting_handler.py44
-rw-r--r--demo/medusa/server.pem36
-rw-r--r--demo/medusa/status_handler.py282
-rw-r--r--demo/medusa/virtual_handler.py60
-rw-r--r--demo/medusa/xmlrpc_handler.py104
-rw-r--r--demo/medusa054/00_README30
-rw-r--r--demo/medusa054/START.py71
-rw-r--r--demo/medusa054/START_xmlrpc.py72
-rw-r--r--demo/medusa054/ca.pem20
-rw-r--r--demo/medusa054/counter.py51
-rw-r--r--demo/medusa054/default_handler.py213
-rw-r--r--demo/medusa054/dh1024.pem5
-rw-r--r--demo/medusa054/filesys.py394
-rw-r--r--demo/medusa054/ftp_server.py1111
-rw-r--r--demo/medusa054/ftps_server.py438
-rw-r--r--demo/medusa054/http_date.py126
-rw-r--r--demo/medusa054/http_server.py749
-rw-r--r--demo/medusa054/https_server.py85
-rw-r--r--demo/medusa054/index.html6
-rw-r--r--demo/medusa054/logger.py261
-rw-r--r--demo/medusa054/m_syslog.py182
-rw-r--r--demo/medusa054/medusa_gif.py8
-rw-r--r--demo/medusa054/poison_handler.py69
-rw-r--r--demo/medusa054/producers.py323
-rw-r--r--demo/medusa054/server.pem36
-rw-r--r--demo/medusa054/status_handler.py272
-rw-r--r--demo/medusa054/xmlrpc_handler.py103
-rw-r--r--demo/perf/memio.py49
-rw-r--r--demo/perf/sha1.py46
-rw-r--r--demo/pgp/pgpstep.py113
-rw-r--r--demo/pgp/pubring.pgpbin1088 -> 0 bytes
-rw-r--r--demo/pgp/secring.pgpbin1969 -> 0 bytes
-rw-r--r--demo/pkcs7/pkcs7-thawte.pem45
-rw-r--r--demo/pkcs7/test.py6
-rw-r--r--demo/rsa.priv.pem9
-rw-r--r--demo/rsa.priv0.pem15
-rw-r--r--demo/rsa.pub.pem4
-rw-r--r--demo/rsa1024pvtkey.pem15
-rw-r--r--demo/rsa_bench.py183
-rw-r--r--demo/rsatest.py45
-rw-r--r--demo/smime.howto/README5
-rw-r--r--demo/smime.howto/decrypt.py22
-rw-r--r--demo/smime.howto/dv.py41
-rw-r--r--demo/smime.howto/encrypt.p717
-rw-r--r--demo/smime.howto/encrypt.py44
-rw-r--r--demo/smime.howto/recipient.pem18
-rw-r--r--demo/smime.howto/recipient_key.pem15
-rw-r--r--demo/smime.howto/se.p756
-rw-r--r--demo/smime.howto/se.py54
-rw-r--r--demo/smime.howto/sendsmime.py82
-rw-r--r--demo/smime.howto/sign.p746
-rw-r--r--demo/smime.howto/sign.py37
-rw-r--r--demo/smime.howto/signer.pem18
-rw-r--r--demo/smime.howto/signer_key.pem15
-rw-r--r--demo/smime.howto/verify.py30
-rw-r--r--demo/smime/README54
-rw-r--r--demo/smime/ca.pem20
-rw-r--r--demo/smime/clear.p767
-rw-r--r--demo/smime/client.p12bin1604 -> 0 bytes
-rw-r--r--demo/smime/client.pem36
-rw-r--r--demo/smime/client2.pem36
-rw-r--r--demo/smime/m2.se.p784
-rw-r--r--demo/smime/ns.p753
-rw-r--r--demo/smime/ns.se.p775
-rw-r--r--demo/smime/opaque.p747
-rw-r--r--demo/smime/sendsmime.py82
-rw-r--r--demo/smime/test.py192
-rw-r--r--demo/smime/unsmime.py50
-rw-r--r--demo/ssl/README25
-rw-r--r--demo/ssl/c.py70
-rw-r--r--demo/ssl/c_bio.py70
-rw-r--r--demo/ssl/ca.derbin841 -> 0 bytes
-rw-r--r--demo/ssl/ca.pem20
-rw-r--r--demo/ssl/client.p12bin1604 -> 0 bytes
-rw-r--r--demo/ssl/client.pem35
-rw-r--r--demo/ssl/dh1024.pem5
-rw-r--r--demo/ssl/echo-eg.py51
-rw-r--r--demo/ssl/echo.py59
-rw-r--r--demo/ssl/echod-async.py112
-rw-r--r--demo/ssl/echod-eg1.py49
-rw-r--r--demo/ssl/echod-forking.py22
-rw-r--r--demo/ssl/echod-iterative.py23
-rw-r--r--demo/ssl/echod-thread.py55
-rw-r--r--demo/ssl/echod-threading.py32
-rw-r--r--demo/ssl/echod_lib.py45
-rw-r--r--demo/ssl/ftp_tls.py41
-rw-r--r--demo/ssl/http_cli_20.py22
-rw-r--r--demo/ssl/https_cli.py45
-rw-r--r--demo/ssl/https_cli_async.py106
-rw-r--r--demo/ssl/https_srv.py150
-rw-r--r--demo/ssl/myapp.py30
-rw-r--r--demo/ssl/s_client.py108
-rw-r--r--demo/ssl/s_server.py203
-rw-r--r--demo/ssl/server.pem36
-rw-r--r--demo/ssl/server3.py121
-rw-r--r--demo/ssl/sess.py89
-rw-r--r--demo/ssl/sess2.py78
-rw-r--r--demo/ssl/sess2.ssldump.out112
-rw-r--r--demo/ssl/socklib.py46
-rw-r--r--demo/ssl/somelib.py21
-rw-r--r--demo/ssl/ss.py25
-rwxr-xr-xdemo/ssl/twistedsslclient.py43
-rwxr-xr-xdemo/ssl/twistedsslserver.py37
-rw-r--r--demo/ssl/xmlrpc_cli.py26
-rw-r--r--demo/ssl/xmlrpc_srv.py26
-rw-r--r--demo/tinderbox/build_lib.py162
-rw-r--r--demo/tinderbox/killableprocess.py212
-rwxr-xr-xdemo/tinderbox/slave.py172
-rw-r--r--demo/tinderbox/winprocess.py262
-rw-r--r--demo/x509/ca.py104
-rwxr-xr-xdemo/x509/certdata2pem.py64
-rw-r--r--demo/x509/client2.pem36
-rw-r--r--demo/x509/demo1.py54
-rw-r--r--demo/x509/proxy_destroy.py43
-rw-r--r--demo/x509/proxy_info.py61
-rw-r--r--demo/x509/proxy_init.py49
-rw-r--r--demo/x509/proxylib.py327
-rw-r--r--demo/x509/server-expired.pem36
-rw-r--r--demo/x509/server.pem36
-rw-r--r--demo/x509/x509auth.py675
-rw-r--r--dev-requirements.txt2
-rw-r--r--doc/M2Crypto.SSL.rst91
-rw-r--r--doc/M2Crypto.rst218
-rw-r--r--doc/Makefile153
-rw-r--r--doc/ZServerSSL-HOWTO.html271
-rw-r--r--doc/ZServerSSL-HOWTO.rst239
-rw-r--r--doc/conf.py285
-rw-r--r--doc/doctrees/M2Crypto.SSL.doctreebin0 -> 349315 bytes
-rw-r--r--doc/doctrees/M2Crypto.doctreebin0 -> 963869 bytes
-rw-r--r--doc/doctrees/ZServerSSL-HOWTO.doctreebin0 -> 43570 bytes
-rw-r--r--doc/doctrees/environment.picklebin0 -> 535122 bytes
-rw-r--r--doc/doctrees/howto.ca.doctreebin0 -> 49113 bytes
-rw-r--r--doc/doctrees/howto.smime.doctreebin0 -> 88860 bytes
-rw-r--r--doc/doctrees/howto.ssl.doctreebin0 -> 20890 bytes
-rw-r--r--doc/doctrees/index.doctreebin0 -> 6360 bytes
-rw-r--r--doc/howto.ca.html891
-rw-r--r--doc/howto.ca.rst370
-rw-r--r--doc/howto.smime.html1570
-rw-r--r--doc/howto.smime.rst778
-rw-r--r--doc/howto.ssl.html206
-rw-r--r--doc/howto.ssl.rst131
-rw-r--r--doc/html/.buildinfo4
-rw-r--r--doc/html/M2Crypto.SSL.html1706
-rw-r--r--doc/html/M2Crypto.html4874
-rw-r--r--doc/html/ZServerSSL-HOWTO.html355
-rw-r--r--doc/html/_modules/M2Crypto/ASN1.html357
-rw-r--r--doc/html/_modules/M2Crypto/AuthCookie.html273
-rw-r--r--doc/html/_modules/M2Crypto/BIO.html494
-rw-r--r--doc/html/_modules/M2Crypto/BN.html162
-rw-r--r--doc/html/_modules/M2Crypto/DH.html217
-rw-r--r--doc/html/_modules/M2Crypto/DSA.html552
-rw-r--r--doc/html/_modules/M2Crypto/EC.html563
-rw-r--r--doc/html/_modules/M2Crypto/EVP.html571
-rw-r--r--doc/html/_modules/M2Crypto/Engine.html254
-rw-r--r--doc/html/_modules/M2Crypto/Err.html177
-rw-r--r--doc/html/_modules/M2Crypto/RC4.html140
-rw-r--r--doc/html/_modules/M2Crypto/RSA.html570
-rw-r--r--doc/html/_modules/M2Crypto/Rand.html251
-rw-r--r--doc/html/_modules/M2Crypto/SMIME.html395
-rw-r--r--doc/html/_modules/M2Crypto/SSL.html145
-rw-r--r--doc/html/_modules/M2Crypto/SSL/Checker.html403
-rw-r--r--doc/html/_modules/M2Crypto/SSL/Cipher.html166
-rw-r--r--doc/html/_modules/M2Crypto/SSL/Connection.html796
-rw-r--r--doc/html/_modules/M2Crypto/SSL/Context.html552
-rw-r--r--doc/html/_modules/M2Crypto/SSL/SSLServer.html172
-rw-r--r--doc/html/_modules/M2Crypto/SSL/Session.html176
-rw-r--r--doc/html/_modules/M2Crypto/SSL/TwistedProtocolWrapper.html597
-rw-r--r--doc/html/_modules/M2Crypto/SSL/cb.html202
-rw-r--r--doc/html/_modules/M2Crypto/SSL/ssl_dispatcher.html149
-rw-r--r--doc/html/_modules/M2Crypto/SSL/timeout.html156
-rw-r--r--doc/html/_modules/M2Crypto/X509.html1495
-rw-r--r--doc/html/_modules/M2Crypto/ftpslib.html195
-rw-r--r--doc/html/_modules/M2Crypto/httpslib.html373
-rw-r--r--doc/html/_modules/M2Crypto/m2urllib.html225
-rw-r--r--doc/html/_modules/M2Crypto/m2urllib2.html290
-rw-r--r--doc/html/_modules/M2Crypto/m2xmlrpclib.html183
-rw-r--r--doc/html/_modules/M2Crypto/threading.html129
-rw-r--r--doc/html/_modules/M2Crypto/util.html193
-rw-r--r--doc/html/_modules/index.html137
-rw-r--r--doc/html/_modules/urllib/request.html2841
-rw-r--r--doc/html/_sources/M2Crypto.SSL.rst.txt91
-rw-r--r--doc/html/_sources/M2Crypto.rst.txt218
-rw-r--r--doc/html/_sources/ZServerSSL-HOWTO.rst.txt239
-rw-r--r--doc/html/_sources/howto.ca.rst.txt370
-rw-r--r--doc/html/_sources/howto.smime.rst.txt778
-rw-r--r--doc/html/_sources/howto.ssl.rst.txt131
-rw-r--r--doc/html/_sources/index.rst.txt30
-rw-r--r--doc/html/_static/ajax-loader.gifbin0 -> 673 bytes
-rw-r--r--doc/html/_static/alabaster.css701
-rw-r--r--doc/html/_static/basic.css676
-rw-r--r--doc/html/_static/comment-bright.pngbin0 -> 756 bytes
-rw-r--r--doc/html/_static/comment-close.pngbin0 -> 829 bytes
-rw-r--r--doc/html/_static/comment.pngbin0 -> 641 bytes
-rw-r--r--doc/html/_static/custom.css1
-rw-r--r--doc/html/_static/doctools.js315
-rw-r--r--doc/html/_static/documentation_options.js10
-rw-r--r--doc/html/_static/down-pressed.pngbin0 -> 222 bytes
-rw-r--r--doc/html/_static/down.pngbin0 -> 202 bytes
-rw-r--r--doc/html/_static/file.pngbin0 -> 286 bytes
-rw-r--r--doc/html/_static/jquery-3.2.1.js10253
-rw-r--r--doc/html/_static/jquery.js4
-rw-r--r--doc/html/_static/language_data.js297
-rw-r--r--doc/html/_static/minus.pngbin0 -> 90 bytes
-rw-r--r--doc/html/_static/plus.pngbin0 -> 90 bytes
-rw-r--r--doc/html/_static/pygments.css69
-rw-r--r--doc/html/_static/searchtools.js481
-rw-r--r--doc/html/_static/underscore-1.3.1.js999
-rw-r--r--doc/html/_static/underscore.js31
-rw-r--r--doc/html/_static/up-pressed.pngbin0 -> 214 bytes
-rw-r--r--doc/html/_static/up.pngbin0 -> 203 bytes
-rw-r--r--doc/html/_static/websupport.js808
-rw-r--r--doc/html/genindex.html1731
-rw-r--r--doc/html/howto.ca.html478
-rw-r--r--doc/html/howto.smime.html849
-rw-r--r--doc/html/howto.ssl.html219
-rw-r--r--doc/html/index.html177
-rw-r--r--doc/html/objects.invbin0 -> 4395 bytes
-rw-r--r--doc/html/py-modindex.html307
-rw-r--r--doc/html/search.html120
-rw-r--r--doc/html/searchindex.js1
-rw-r--r--doc/index.rst30
-rw-r--r--doc/make.bat190
-rw-r--r--epydoc.conf3
-rwxr-xr-xfedora_setup.sh15
-rw-r--r--pack.py37
-rw-r--r--packaging/python-M2Crypto.spec2
-rw-r--r--pylintrc272
-rw-r--r--setup.cfg9
-rw-r--r--setup.py464
-rw-r--r--tests/__init__.py16
-rw-r--r--tests/alltests.py54
-rw-r--r--tests/bad_date_cert.crt19
-rw-r--r--tests/ca.pem135
-rw-r--r--tests/ca_key.pem27
-rw-r--r--tests/easy_rsa.pem74
-rw-r--r--tests/ec.priv.pem7
-rw-r--r--tests/ec.pub.pem5
-rw-r--r--tests/fips.py7
-rwxr-xr-xtests/makecerts.py213
-rw-r--r--tests/recipient.pem133
-rw-r--r--tests/recipient_key.pem38
-rw-r--r--tests/sample-p7.pem102
-rw-r--r--tests/server.pem142
-rw-r--r--tests/server_key.pem27
-rw-r--r--tests/signer.pem106
-rw-r--r--tests/signer_key.pem38
-rw-r--r--tests/te_chunked_response.txt11
-rw-r--r--tests/test_aes.py80
-rw-r--r--tests/test_asn1.py93
-rwxr-xr-x[-rw-r--r--]tests/test_authcookie.py148
-rw-r--r--tests/test_bio.py84
-rw-r--r--tests/test_bio_file.py140
-rw-r--r--tests/test_bio_iobuf.py39
-rw-r--r--tests/test_bio_membuf.py79
-rw-r--r--tests/test_bio_ssl.py127
-rw-r--r--[-rwxr-xr-x]tests/test_bn.py27
-rw-r--r--tests/test_dh.py35
-rw-r--r--tests/test_dsa.py73
-rw-r--r--tests/test_ec_curves.py258
-rw-r--r--tests/test_ecdh.py28
-rw-r--r--tests/test_ecdsa.py57
-rw-r--r--tests/test_engine.py30
-rw-r--r--tests/test_err.py28
-rw-r--r--tests/test_evp.py578
-rw-r--r--tests/test_obj.py132
-rw-r--r--tests/test_pgp.py40
-rw-r--r--tests/test_rand.py87
-rw-r--r--tests/test_rc4.py41
-rw-r--r--tests/test_rsa.py307
-rw-r--r--tests/test_smime.py342
-rw-r--r--tests/test_ssl.py1179
-rw-r--r--tests/test_ssl_offline.py56
-rw-r--r--tests/test_ssl_win.py57
-rw-r--r--tests/test_threading.py3
-rw-r--r--tests/test_timeout.py135
-rw-r--r--tests/test_util.py48
-rw-r--r--tests/test_x509.py751
-rw-r--r--tests/vendor/unittest2/__init__.py68
-rw-r--r--tests/vendor/unittest2/__main__.py10
-rw-r--r--tests/vendor/unittest2/case.py1084
-rw-r--r--tests/vendor/unittest2/collector.py9
-rw-r--r--tests/vendor/unittest2/compatibility.py64
-rw-r--r--tests/vendor/unittest2/loader.py322
-rw-r--r--tests/vendor/unittest2/main.py241
-rw-r--r--tests/vendor/unittest2/result.py183
-rw-r--r--tests/vendor/unittest2/runner.py206
-rw-r--r--tests/vendor/unittest2/signals.py57
-rw-r--r--tests/vendor/unittest2/suite.py287
-rw-r--r--tests/vendor/unittest2/util.py99
-rw-r--r--tests/x509.derbin656 -> 830 bytes
-rw-r--r--tests/x509.pem142
-rw-r--r--tests/x509_key.pem27
471 files changed, 93189 insertions, 32050 deletions
diff --git a/CHANGES b/CHANGES
index 8355a94..882a835 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,191 @@
+0.35.1 - 2019-06-08
+-------------------
+
+- Actually, really fix compatibility with OpenSSL 1.1.1c. Thank you,
+ Sebastian Andrzej Siewior from the Debian team for resolving it.
+
+0.34.0 - 2019-05-30
+-------------------
+
+- Use more recent version of OpenSSL on Windows
+- Be resilient against the situation when no erorr happened.
+- Correct URL of https://www.schneier.com/academic/smime/
+- Use shlex.split() for CPP
+
+0.33.0 - 2019-04-26
+-------------------
+
+- eb4525c - Stop pretending to support Python 3.4. <Matěj Cepl>
+- 6a89548 - Fix use of urlunsplit (25 hours ago) <Andreas Schwab>
+- 0a5a356 - tests/test_ssl: use -ciphercuites for TLS1.3 cipher in
+ openssl1.1 <Sebastian Andrzej Siewior>
+- 8a0a3e3 - There are apparently multiword CPP variables. Taking that
+ into account. <Matěj Cepl>
+
+0.32.0 - 2019-03-04
+-------------------
+
+- 471582f - setup.py: use ${CPP} as path to cpp <Duncan Macleod>
+- efb1580 - Bump pipeline OpenSSL from 1.1.0i to 1.1.0j
+- 35bb71b - Stub wchar_t helpers and ignore unused WCHAR defs <makepost>
+- effc7be - Add type comment to setup.py <Matěj Cepl>
+
+0.31.0 - 2018-11-08
+-------------------
+
+- Compatibility with OpenSSL 1.1.1 (partly workaround, maybe requires
+ further investigation)
+- Fixes for Windows builds
+- Fixes of installs on AWS Lambda
+- Fixes of Mac OS X related failures
+- Fix Python 2.6 compatibility issues
+
+0.30.1 - 2018-04-29
+-------------------
+- Fix packaging (missed packaging testing file)
+
+0.30.0 - 2018-04-25
+-------------------
+- Various small typos (Windows builds, Fix SSL.Connection.__del__)
+- The project is now Linux-distribution agnostic
+- Replace all old-style classes with the new ones (it shouldn't cause
+ any problems, but feel free to file an issue, if it does)
+- Do not by-pass a potential transfer decoding in m2urllib2
+- Update M2Crypto.six with 1.11.0 and replace our local workarounds with
+ new functions.
+- SSLv3 just removed.
+- Don't support Python 2.6 on Windows anymore. Windows users don't have
+ python as a system package, so they are usually more likely to upgrade
+ anyway.
+
+0.29.0 - 2018-02-23
+-------------------
+- Fix building on Windows (all tests fix on Win32 and Win64 on all
+ supported combinations of versions of OpenSSL and Python)
+- Fixes of some small bugs
+
+0.28.0 - 2018-02-08
+-------------------
+- Mainly port to Python 3 (supporting 2.6, 2.7, 3.3, 3.4, 3.5, 3.6)
+- Some lame efforts to make setup.py build --openssl work better (needs
+ more real testing on Mac OS X)
+- Fix licence: it is MIT, not BSD
+- Fix and add tests for SWIG/_aes.i module
+- Improve somehow situation on Mac OS X (some testing, improve setup.py,
+ testsuite should fully pass)
+- Bundle-in unittest2 for Python 2.6 (dealing with the need for
+ specific version of unittest2 package was too complicated)
+- Remove all PGP modules
+
+0.27.0 - 2017-10-05
+-------------------
+- Fix licence: it is MIT, not BSD
+- At least minimal support of SNI in httpslib.
+- Small bugfixes and cleanups.
+- More effort to make build system more robust (now should work even on
+ Debian LTS).
+- Restore m2.rsa_set_e() and m2.rsa_set_n().
+- Make sure that every exceptional return throws and exception and vice
+ versa.
+
+0.26.4 - 2017-09-26
+-------------------
+- Proper fix of deprecation warning for OpenSSL 1.1.0
+- Small mostly stylistic bugfixes
+- Emergency release to fix FTBFS.
+
+0.26.3 - 2017-09-22
+-------------------
+- Fix a syntax typo.
+
+0.26.2 - 2017-09-20
+-------------------
+- port to support OpenSSL 1.1.0 API
+- add generated Sphinx documentation
+- another set of cleanups
+
+0.26.0 - 2017-03-21
+-------------------
+- Fix packaging on RHEL-6
+- Replace ASN1_UTCTIME with ASN1_TIME which supports both UTCTime and
+ GeneralizedTime
+- Add possibility to sign PKCS7 with a non-default digest.
+- Add possibility to set custom callback for X509 verification.
+- Clean up imports and PEP8ization
+- A lot of cleanups on the way towards Python 3
+- Other small bugfixes
+
+0.25.1 - 2016-07-25
+-------------------
+- Actually do check, whether we have SSLv2 compiled in, and don't run
+ test for it.
+
+0.25.0 - 2016-03-21
+-------------------
+- More cleanups, removal of obsolete stuff, and moves towards py3k
+ compatibility.
+- Add support for EC.get_builtin_curves() and use it for testing.
+- Enable AES CTR mode
+- Bundle-in six module v. 1.10.0
+- add rand_file_name and rand_status
+- remove all LHASH fiddling
+- Extend Travis and GitLab CI configuration to test also py3k (with
+ allowed_failures) and CentOS6 (on GitLab CI).
+- Add CONTRIBUTORS.rst. Thank you!
+- Add PEP-484 type hints in comments to all Python files (except for
+ tests)
+- Use context managers for file handling wherever possible instead of
+ leaking open file descriptors.
+- Improve defaults handling for SSL_CTX_new().
+- Fix PGP tests to actually run
+
+0.24.0 - 2016-03-21
+-------------------
+- More cleanups, removal of obsolete stuff, and moves towards py3k
+ compatibility.
+- Add DSA.pub_key_from_params() factory function (and m2.dsa_set_pub()).
+- Allow import/export of EC public key with binary values
+- Add EVP.load_key_string_pubkey() function, as well as helper functions
+- Add EVP.get_digestbyname() functionality.
+- Convert documentation to rST (and add instructions for building on Mac
+ OS X)
+- Another round of fixing multiarch building.
+- Disable tests with weak ciphers on some platforms (Debain)
+
+0.23.0 - 2016-01-29
+-------------------
+- Add Travis and GitLab CI configurations
+- Allow building without SSLv2
+- More cleanups and removing obsolete code
+- Fix README
+- Fix buffer overflow in pkcs5_pbkdf2_hmac_sha1
+- First moves towards Python 3 compatibility
+- Removed rather large and completely unmaintained demo/ subdirectory
+ (now in a separate repo https://gitlab.com/m2crypto/m2crypto_demo)
+- Automatically generated test data files
+- Finally fix building on multiarch systems
+- All objects derived from BIO.BIO now could work as context managers
+- Switch setup.py to setuptools
+
+0.22.5 - 2015-10-13
+-------------------
+- Add forgoteen SWIG/*.h among distributed files.
+
+0.22.4 - 2015-10-13
+-------------------
+- Matěj Cepl takes over leadership of the upstream maintenance
+- Fedora/RHEL distribution patches merged to the main development
+ (mainly, but not only, upgrading to the more recent versions of
+ OpenSSL, swig which is now at 3.0.5, but anything above 2.0.4 is
+ supported as well, and python which now has to be at least 2.6).
+- Tons of cleaning up the code for obsolete constructs, PEP8ization,
+ etc.
+
+0.22.3 - 2014-01-22
+-------------------
+(released by Martin Paljak, later development started on top of 0.21.1
+with his improvements cherry picked to the new development branch)
+
0.21.1 - 2011-01-15
-------------------
- Distribution fix
@@ -43,7 +231,7 @@
was held by another thread, by Miloslav Trmac
- Allow more blocking OpenSSL functions to run without GIL, by Miloslav Trmac
- Fixed httpslib to send only the path+query+fragment part of the URL when
- using CONNECT proxy, by James Bowes
+ using CONNECT proxy, by James Bowes
- SSLServer.__init__ now takes optional bind_and_activate parameter and
initializes by calling SocketServer.BaseServer.__init__, which
are Python 2.6 compatibility fixes, by Christian
@@ -54,7 +242,7 @@
- Added support for disabling padding when using RSA encryption,
by Chris Collis
- ASN1_INTEGERs can now be larger than fits in an int, for example to support
- X509 certificates with large serial numbers,
+ X509 certificates with large serial numbers,
patch by Mikhail Vorozhtsov and testcase by Barry G.
- Reverted a change done in 0.17 to m2urllib2 which changed urls to include
host when it should stay as it was
@@ -180,7 +368,7 @@
are both None
- Fixed X509.check_purpose() (was always raising exceptions)
- smime_read_pkcs7 was changed to automatically call BIO_set_mem_eof_return
- on memory BIOs because otherwise the read would fail with
+ on memory BIOs because otherwise the read would fail with
"SMIME_Error: not enough data"
- X509.new_extension('subjectKeyIdentifier', 'hash') raises ValueError instead
of crashing Python
@@ -262,7 +450,7 @@
M2Crypto.Rand.
- Updated ZServerSSL files to match Zope 2.7.0 versions.
- Integrated (overlapping) patches by Peter Teniz and Heikki Toivonen
- covering operations on X.509-related structures that gives M2Crypto
+ covering operations on X.509-related structures that gives M2Crypto
PKI functionality. Thanks Peter and Heikki.
- Peter Teniz contributed demo2004/pki/x509auth.py.
- Created demo2004/ directory that will contain new or updated demos.
@@ -274,15 +462,15 @@
-------------------------
- Patches from Artur Frysiak <wiget@pld-linux.org>. Thanks Artur.
= Allow using a passphrase callback in class SMIME.
- = Added method get0_signers to class PKCS7, which retrieves signers'
+ = Added method get0_signers to class PKCS7, which retrieves signers'
certificates from a PKCS7 blob.
= Added methods as_pem and save_pem to class X509.
= Added file version.py.
- = Allow SSL.Context.load_verify_locations to accept both 'cafile' and
+ = Allow SSL.Context.load_verify_locations to accept both 'cafile' and
'capath'.
-- Fixed BIO.read() not reading until EOF. Thanks to Egil Muller
+- Fixed BIO.read() not reading until EOF. Thanks to Egil Muller
<redhog@redhog.org> for suggestion.
-- Honour 'mode' parameter in SSL.Connection.makefile. Thanks again to Egil
+- Honour 'mode' parameter in SSL.Connection.makefile. Thanks again to Egil
Muller.
- Roger Binns contributed epydoc-generated docs for M2Crypto. Thanks Roger.
- Peter Teniz contributed patches to create X.509 requests and certificates.
@@ -295,24 +483,24 @@
--------------------
- ZServerSSL with client certificate-based authentication rides again.
- Created Makefile for Python 2.3.
-- Modified LICENCE: changed my name to the generic "the author" in the
+- Modified LICENCE: changed my name to the generic "the author" in the
all-caps disclaimer paragraph.
- Allow to save RSA key pair in the clear.
- ZServerSSL for Zope 2.7.
-- Excluded RC5. IDEA was taken out several releases ago. This should
+- Excluded RC5. IDEA was taken out several releases ago. This should
allow M2Crypto to build with stock OpenSSL on various Linuxen.
- Added ssl_set_tmp_dh_callback.
- Added ssl_set_tmp_rsa and ssl_set_tmp_rsa_callback to support weak-cipher
browsers.
-- ZServerSSL exports SSL_CIPHER request header (a la mod_ssl) to Zope
+- ZServerSSL exports SSL_CIPHER request header (a la mod_ssl) to Zope
applications.
- Perform distutils's SWIG .i search path tweaking within setup.py. setup.py
should now work "out of the box".
-- Added contrib/smimeplus.py, a high-level S/MIME interface, contributed by
+- Added contrib/smimeplus.py, a high-level S/MIME interface, contributed by
Bernard Yue <bernie@3captus.com>. Thanks Bernard.
-- Added in long forms of nid's in X509_Name. Thanks to William K Volkman
+- Added in long forms of nid's in X509_Name. Thanks to William K Volkman
<development@netshark.com> for patch.
-- Updated Mac OS X build instructions. Thanks to Larry Bugbee
+- Updated Mac OS X build instructions. Thanks to Larry Bugbee
Changes since 0.10
@@ -335,19 +523,19 @@
Changes since 0.09
--------------------
- Updated to OpenSSL 0.9.7. Thanks to Toby Allsopp <toby@MI6.GEN.NZ> for
- patches.
-- Added functionality to create a basic certificate request. Also
- contributed by Toby Allsopp.
+ patches.
+- Added functionality to create a basic certificate request. Also
+ contributed by Toby Allsopp.
- Finally, AES!
Changes since 0.08
--------------------
-- Replaced demo/Zope/ZServer/__init__.py with the correct version
+- Replaced demo/Zope/ZServer/__init__.py with the correct version
for Zope 2.6.0.
- Added a sample starts.bat for ZServerSSL.
- Incoporated a patch by prashanth@jibe.biz that handled the
- new-in-Python-2.2.2 "strict" parameter for the various HTTP[S] connection
+ new-in-Python-2.2.2 "strict" parameter for the various HTTP[S] connection
classes in httplib.py. Thanks prashanth. This fixes M2Crypto's XMLRPC
support for Python 2.2.2. (Apparently it was working for Python 2.2.1.)
- Incorporated some cosmetic patches from Adam Karpierz <karpierz@zope.pl>.
@@ -365,7 +553,7 @@
- Included in contrib/ Isaac Salzberg's application of Mihai Ibanescu's
patch that allows IIS interoperability thru an authenticating proxy.
Thanks Isaac.
-- Included in contrib/ patch by Dave Brueck <dave@pythonaprocrypha.com>
+- Included in contrib/ patch by Dave Brueck <dave@pythonaprocrypha.com>
that has smarter non-blocking behaviour. Thanks Dave.
@@ -387,7 +575,7 @@
Changes since 0.05
-----------------------
- Handled the cases where Python callbacks raised exceptions.
-- Fixed a NULL-deref bug in _ssl.i which crashes Medusa https when IE
+- Fixed a NULL-deref bug in _ssl.i which crashes Medusa https when IE
or Opera comes a-calling.
- ZServerSSL rides again - a more robust ZServerSSL for Zope 2.3.0.
- Added the MIME type 'application/x-x509-ca-cert' to
@@ -411,17 +599,17 @@
- Fixed yet more memory leaks. Thanks to Ray Suorsa <res@loudcloud.com>.
- Build instructions for Borland BC++ 5.5 free compiler suite.
- Bundles the June 2000 unencumbered release of Medusa.
-- SSL callback thread-safety. Thanks again to Ray Suorsa for insights and
+- SSL callback thread-safety. Thanks again to Ray Suorsa for insights and
patches.
-- Renamed M2Crypto.M2Crypto to M2Crypto.m2 to prevent package/module loading
+- Renamed M2Crypto.M2Crypto to M2Crypto.m2 to prevent package/module loading
confusion.
- SSL.Session and a demo in demo/ssl/sess.py.
- https_srv.py, an enhanced, https version of SimpleHTTPServer.py.
-- Interface change: SMIME.load_pkcs7_bio() is renamed
- SMIME.smime_load_pkcs7_bio(), similarly SMIME.load_pkcs7() to
+- Interface change: SMIME.load_pkcs7_bio() is renamed
+ SMIME.smime_load_pkcs7_bio(), similarly SMIME.load_pkcs7() to
SMIME.smime_load_pkcs7(); these load PKCS7 objects generated by S/MIME.
-- Interface change: SMIME.load_pkcs7_bio() now loads a PKCS7 PEM file, i.e., a
- file of the format "-----BEGIN PKCS7-----".
+- Interface change: SMIME.load_pkcs7_bio() now loads a PKCS7 PEM file, i.e., a
+ file of the format "-----BEGIN PKCS7-----".
- Works with both Python 2.0 and Python 1.5.2.
- OpenSSL 0.9.6. (Possibly incompatible with earlier OpenSSL releases.)
- Unit tests with PyUnit.
@@ -430,7 +618,7 @@
= Diligent error checking.
= Fixed memory leaks.
- Renamed M2Crypto.urllib2 to M2Crypto.m2urllib.
-- HTTPS clients of Python 1.5.2's and Python 2.0's httplib and urllib.
+- HTTPS clients of Python 1.5.2's and Python 2.0's httplib and urllib.
Changes since 0.03
@@ -444,7 +632,7 @@
- Unified SSL read() and write() for synchronous and asynchronous operation.
- S/MIME and PKCS #7.
- Integrated with OpenSSL 0.9.5.
-- Enhanced the PRNG interface.
+- Enhanced the PRNG interface.
Changes since 0.02
@@ -457,7 +645,7 @@
6. Beginnings of PGP2 support.
7. Replaced eval() calls with other (hopefully) safe ones.
8. Miscellaneous enhancements and bug fixes.
-
+
Changes since 0.01
-----------------------
@@ -467,12 +655,12 @@
- An SSLServer modeled after SocketServer.
- A ForkingSSLServer that seems to work well.
- A ThreadingSSLServer that runs one thread at a time. (!) ;-)
-
+
For building servers, nonblocking i/o:
- An ssl_dispatcher modeled after asyncore.dispatcher.
A HTTPS server based on Medusa.
-
+
For client-side web programming:
- httpslib
- urllib2
@@ -482,7 +670,7 @@
3. Reduced per-module name space pollution.
4. Have Swig check for NULL pointers: reduced .i cut-&-paste.
5. Standardise on MPINT for passing big integers between Python and OpenSSL.
-6. Removed MD5, SHA1, RIPEMD160. Just use EVP.MessageDigest.
-7. Removed HMAC. Just use EVP.HMAC.
+6. Removed MD5, SHA1, RIPEMD160. Just use EVP.MessageDigest.
+7. Removed HMAC. Just use EVP.HMAC.
diff --git a/CONTRIBUTORS.rst b/CONTRIBUTORS.rst
new file mode 100644
index 0000000..d46dff0
--- /dev/null
+++ b/CONTRIBUTORS.rst
@@ -0,0 +1,43 @@
+* The original project was created inside of the huge `Chandler project`_
+ where it was mostly work of Ng Pheng Siong [#]_ .
+
+* Then for a log time it was maintained and extended to the large part
+ by Heikki Toivonen.
+
+With 247 and 415 commits, respectively, these two first maintainers
+provided by far the biggest amount of work on the project. Thank you.
+
+* An attempt to restart the project was made by Martin Paljak. Although
+ his effort was most mostly discarded in the end, all his suggested
+ changes were reviewed and some of them incorporated in some other
+ form. Just two commits of his remaining in the tree hugely
+ underestimate an effort he made to keep this project alive. Thank you
+ very much for your work.
+
+* Plenty of work on keeping this project alive was made by the
+ maintainer of the package inside of RHEL, Martin TrmaÄ. He also helped
+ a lot by advice with this last effort to revive the project, and his
+ pestering me to do proper small commits rather than freaking dumps of
+ my current thoughts helped to make changes to be made a little bit
+ better (and revieweable).
+
+* This last hyena-like effort to revive a dead carcas has been started
+ by Matěj Cepl.
+
+* I got a lot of help especially with reviewing patches from Hubert
+ Kario.
+
+* Craig Rodrigues didn't loose the hope that M2Crypto could be ported to
+ be py3k-compatible, which lead to the renewed effort to do so. He also
+ helped with plenty of patches in this effort.
+
+* Casey Deccio helped a lot with fixing EC module.
+
+* Remaining contributors could be find in the output of ``git shortlog
+ -s`` command. Thank you to all.
+
+.. _`Chandler project`:
+ https://en.wikipedia.org/wiki/Chandler_%28software%29
+
+.. [#] His and everybody else emails can be found in the git log,
+ I won't make spammers even more happy to collect them here.
diff --git a/INSTALL b/INSTALL
deleted file mode 100644
index f67fed4..0000000
--- a/INSTALL
+++ /dev/null
@@ -1,226 +0,0 @@
-====================
- Installing M2Crypto
-====================
-
-:Maintainer: Heikki Toivonen
-:Web-Site: http://chandlerproject.org/Projects/MeTooCrypto
-
-.. contents::
-
-
-Pre-requisites
-----------------
-
-The following software packages are pre-requisites:
-
-- **Python 2.3 or newer**
-- **OpenSSL 0.9.7 or newer**
-- **SWIG 1.3.28 or newer**
-
-Note about OpenSSL versions early in the 0.9.7 series
------------------------------------------------------
-
-Early OpenSSL 0.9.7 versions require the __i386__ symbol to be defined.
-Uncomment this line in setup.py:
-
- #'-D__i386__', # Uncomment for early OpenSSL 0.9.7 versions
-
-if you get this compile-time error:
-
- This openssl-devel package does not work your architecture?
-
-Note about Fedora Core -based Distributions
------------------------------------------------------
-
-Fedora Core (and RedHat, CentOS etc.) have made changes to OpenSSL
-configuration compared to many other Linux distributions. If you can not
-build M2Crypto normally, try the fedora_setup.sh script included with
-M2Crypto sources.
-
-Installing on Unix-like systems, including Cygwin
--------------------------------------------------
-
-::
-
- $ tar zxf m2crypto-<version>.tar.gz
- $ cd m2crypto-<version>
- $ python setup.py build
- $ python setup.py install
-
-If you have installed setuptools you can also optionally run tests like this:
-
- $ python setup.py test
-
-This assumes OpenSSL is installed in /usr. You can provide an alternate
-OpenSSL prefix location with --openssl option to build_ext command. Other
-commands accept standard options if you need them.
-
-Some distributions, like Fedora Core, package OpenSSL headers in a different
-location from OpenSSL itself. In that case you need to tell build_ext the
-additional include location with -I option.
-
-Differences when installing on Windows
---------------------------------------
-
-Before building from source, you need to install OpenSSL's include files,
-import libraries and DLLs. By default setup.py assumes that OpenSSL include
-files are in ``c:\pkg\openssl\include``, and the import libraries
-in ``c:\pkg\openssl\lib``. As with other platforms, you can specify a different
-OpenSSL location with --openssl option to build_ext command.
-
-Using OpenSSL 0.9.8 on Windows requires Python be built with applink.c
-(add an include statement in python.c). This is not a requirement for
-Linux or MacOSX. (applink.c is provided by OpenSSL.)
-
-
-MSVC++
-~~~~~~~~
-
-setup.py is already configured to work with MSVC++ by default.
-
-With MSVC++, the OpenSSL DLLs, as built, are named ``libeay32.dll``
-and ``ssleay32.dll``. Install these somewhere on your PATH; for example
-in ``c:\bin``, together with ``openssl.exe``.
-
-For MSVC++, the import libraries, as built by OpenSSL, are named
-``libeay32.lib`` and ``ssleay32.lib``.
-
-
-MINGW
-~~~~~~~
-
-.. NOTE::
- The following instructions for building M2Crypto with MINGW are from
- M2Crypto 0.12. These instructions should continue to work for this release,
- although I have not tested them.
-
-Read Sebastien Sauvage's webpage:
-
- http://sebsauvage.net/python/mingw.html
-
-For mingw32, the OpenSSL import libraries are named ``libeay32.a`` and
-``libssl32.a``. You may need to edit setup.py file for these.
-
-You'll also need to create ``libpython2[123].a``, depending on your version
-of Python.
-
-OpenSSL DLLs for mingw32 are named ``libeay32.dll`` and ``libssl32.dll``.
-Install these somewhere on your PATH; for example in
-``c:\bin``, together with ``openssl.exe``.
-
-Build M2Crypto:
-
- python setup.py build -cmingw32
- python setup.py install
-
-
-BC++
-~~~~~~
-
-.. NOTE::
- The following instructions for building M2Crypto with MSVC++ 6.0 and
- BC++ 5.5 free compiler suite are from M2Crypto 0.10. These instructions
- should continue to work for this release, although I have not tested
- them.
-
-For BC++ these files are created from the MSVC++-built ones using the
-tool ``coff2omf.exe``. I call them ``libeay32_bc.lib`` and
-``ssleay32_bc.lib``, respectively. You will need to edit setup.py file
-for these.
-
-You'll also need Python's import library, e.g., ``python22.lib``, to
-be the BC++-compatible version; i.e., create ``python22_bc.lib`` from
-``python22.lib``, save a copy of ``python22.lib`` (as ``python22_vc.lib``,
-say), then rename ``python22_bc.lib`` to ``python22.lib``.
-
-
-Now you are ready to build M2Crypto. Do one of the following::
-
- python setup.py build
- python setup.py build -cbcpp
-
-Then,
-
-::
-
- python setup.py install
-
-
-MacOSX
-------
-
-Follow the standard instructions to build and install M2Crypto.
-However, should you encounter difficulties, you may want to consider
-the following possibilities.
-
- - Distutils for Python 2.5 now provides support for universal
- builds (ppc and i386) and Distutils requires a recent version
- of Xcode. See http://developer.apple.com/tools/download/
-
- - OpenSSL 0.9.7l gets installed in /usr with Apple's Security
- Update 2006-007. If you need features in OpenSSL 0.9.8, you
- should consider installing 0.9.8 in /usr/local. The commands
- are:
-
- OpenSSL:
- ./config shared --prefix=/usr/local
- make
- make test
- sudo make install [or... install_sw]
-
- M2Crypto:
- python setup.py build build_ext --openssl=/usr/local
- sudo python setup.py install build_ext --openssl=/usr/local
-
-To make Universal builds, you will need to uncomment a line in setup.py:
-
- extra_link_args = ['-Wl,-search_paths_first'],
-
-If that does not work, here is what Marc Hedlund was able to get working:
-
- First, download OpenSSL 0.9.8d and unpack it. Edit the OpenSSL Makefiles
- per PROBLEMS. Then:
-
- ./config no-shared no-asm --prefix=/usr/local
- make
- make test
- sudo make install
- make clean
- ./Configure no-shared no-asm --prefix=/usr/local darwin-ppc-cc
- make build_libs "CC=cc -arch ppc"
- lipo -info lib*
- mkdir -p build/ppc
- mv lib* build/ppc
- make clean
- ./Configure no-shared no-asm --prefix=/usr/local darwin-i386-cc
- make build_libs "CC=cc -arch i386"
- lipo -info lib*
- mkdir -p build/i386
- mv lib* build/i386/
- /bin/ls -1 build/i386/ > libnames.tmp
- mkdir universal
-
- Create a script in the OpenSSL directory called 'make_universal', with these
- contents:
-
- #!/bin/sh
- for lib in `cat libnames.tmp`; do
- lipo -create build/*/$lib -output universal/$lib
- done
- exit 0
-
- Then:
-
- sh make_universal
- lipo -info universal/lib*
- sudo cp universal/lib* /usr/local/lib
- lipo -info /usr/local/lib/lib{crypto,ssl}*
- cd ../m2crypto-0.17
-
- Then edit the m2crypto setup.py and uncomment the extra_link_args line at
- the end.
-
- python setup.py build build_ext --openssl=/usr/local
- sudo python setup.py install build_ext --openssl=/usr/local
-
-
diff --git a/INSTALL.rst b/INSTALL.rst
new file mode 100644
index 0000000..f0ab79e
--- /dev/null
+++ b/INSTALL.rst
@@ -0,0 +1,166 @@
+Installing M2Crypto
+===================
+
+.. contents::
+
+Pre-requisites
+--------------
+
+The following is required to *use* M2Crypto (once installed):
+
+- ``Python 2.6``, ``2.7``, ``3.5``, or newer
+- ``OpenSSL 1.0.1e`` or newer
+
+To *install* M2Crypto, you must be able to compile and link C sources
+against Python and OpenSSL headers/libraries. For example on a Debian-based
+system the following packages are needed:
+
+- ``build-essential``
+- ``python3-dev`` and/or ``python-dev``
+- ``libssl-dev``
+- ``swig 2.0.4`` or newer (installation is also possible on some
+particular old systems with swig v1.*)
+
+Installing on Unix-like systems, including Cygwin
+-------------------------------------------------
+
+(not tested and most likely obsolete, updated information for building
+with Cygwin are welcome).::
+
+ $ tar zxf m2crypto-<version>.tar.gz
+ $ cd m2crypto-<version>
+ $ python setup.py build
+ $ python setup.py install
+
+If you have installed setuptools you can also optionally run tests like
+this:::
+
+ $ python setup.py test
+
+This assumes OpenSSL is installed in ``/usr``. You can provide an
+alternate OpenSSL prefix location with --openssl option to
+``build\_ext`` (or ``build``) command. So, for example, if you
+build your local version of OpenSSL and install it with
+``/usr/local`` prefix (your includes are in
+``/usr/local/include/openssl`` and libs in ``/usr/local/lib``),
+then you would add ``--openssl=/usr/local`` to your ``build``
+command.
+
+
+Differences when installing on Windows
+--------------------------------------
+
+(Python 2.6 is not supported on Windows anymore, please, just
+update to 2.7 if you want to stay on Python 2)
+
+(needs updating)
+
+Before building from source, you need to install OpenSSL's include
+files, import libraries and DLLs. OpenSSL 1.1.0 and on are installed
+by default in ``%ProgramFiles(86)%\OpenSSL`` (32-bit), or
+in ``%ProgramW6432%\OpenSSL`` (64-bit), or as a last resort, in
+``%ProgramFiles%\OpenSSL``. setup.py will look in those locations.
+OpenSSL before 1.1.0 doesn't have a default install location, so
+you have to specify its install location explicitely.
+
+As with other platforms, you can specify a OpenSSL location with
+--openssl option to ``build\_ext`` (or ``build``) command. For
+example, ``--openssl=c:\pkg\openssl`` would specify that the OpenSSL
+include files can be found in ``c:\pkg\openssl\include`` and the
+librariesin ``c:\pkg\openssl\lib``.
+
+The '--openssl' option will configure swig and the compiler to look in the
+default locations for headers and libraries. If your OpenSSL is installed in a
+or you want to modify the default options run the build_ext step with normal
+distutils options: `--swig-opts`, `--include-dirs`, `--library-dirs`, and
+`--libraries`.
+
+MSVC++ ~\ :sub:`:sub:`:sub:`~```
+
+setup.py is already configured to work with MSVC++ by default.
+
+With MSVC++, the OpenSSL pre 1.1.0 DLLs, as built, are named
+``libeay32.dll`` and ``ssleay32.dll``. The OpenSSL 1.1.x DLLs are
+named ``libcrypto-1_1.dll`` and ``libssl-1_1.dll``. Install these
+somewhere on your PATH; for example in ``c:\bin``, together with
+``openssl.exe``.
+
+For MSVC++, the import libraries, as built by OpenSSL pre 1.1.0, are
+named ``libeay32.lib`` and ``ssleay32.lib``. The OpenSSL 1.1.x import
+libraries are named ``libcrypto.lib`` and ``libssl.lib``.
+
+MINGW :sub:`:sub:`:sub:`~```
+
+.. NOTE:: The following instructions for building M2Crypto with MINGW
+ are from M2Crypto 0.12. These instructions should continue to work
+ for this release, although I have not tested them.
+
+Read Sebastien Sauvage's webpage::
+
+ http://sebsauvage.net/python/mingw.html
+
+For mingw32, the OpenSSL pre 1.1.0 import libraries are named
+``libeay32.dll.a`` and ``libssl32.dll.a``. You may need to edit
+setup.py file for these.
+
+You'll also need to create ``libpython2[123].a``, depending on your
+version of Python.
+
+OpenSSL pre 1.1.0 DLLs for mingw32 are named ``libeay32.dll`` and
+``libssl32.dll``. OpenSSL 1.1.x DLLs are named ``libcrypto-1_1.dll``
+and ``libssl-1_1.dll``. Install these somewhere on your PATH; for
+example in ``c:\bin``, together with ``openssl.exe``.
+
+Build M2Crypto::
+
+ python setup.py build -cmingw32
+ python setup.py install
+
+BC++ :sub:`:sub:`~``\ ~
+
+.. NOTE:: The following instructions for building M2Crypto with MSVC++
+ 6.0 and BC++ 5.5 free compiler suite are from M2Crypto 0.10. These
+ instructions should continue to work for this release, although
+ I have not tested them.
+
+.. NOTE:: OpenSSL 1.1.x doesn't support BC++.
+
+For BC++ these files are created from the MSVC++-built ones using the
+tool ``coff2omf.exe``. I call them ``libeay32_bc.lib`` and
+``ssleay32_bc.lib``, respectively. You will need to edit setup.py file
+for these.
+
+You'll also need Python's import library, e.g., ``python22.lib``, to be
+the BC++-compatible version; i.e., create ``python22_bc.lib`` from
+``python22.lib``, save a copy of ``python22.lib`` (as
+``python22_vc.lib``, say), then rename ``python22_bc.lib`` to
+``python22.lib``.
+
+Now you are ready to build M2Crypto. Do one of the following::
+
+ python setup.py build
+ python setup.py build -cbcpp
+
+Then,::
+
+ python setup.py install
+
+MacOSX
+------
+
+Apple does not provide on more recent versions of Mac OS X (at least
+certainly `since 10.11`_) any version of OpenSSL, so it is necessary to
+use ``brew`` or similar packaging systems to install third party
+packages. A Mac OS X users suggested, that this series of commands gave
+him a working copy of M2Crypto on his system::
+
+ $ brew install openssl && brew install swig
+ $ brew --prefix openssl
+ /usr/local/opt/openssl
+ $ LDFLAGS="-L$(brew --prefix openssl)/lib" \
+ CFLAGS="-I$(brew --prefix openssl)/include" \
+ SWIG_FEATURES="-I$(brew --prefix openssl)/include" \
+ pip install m2crypto
+
+.. _`since 10.11`:
+ https://gitlab.com/m2crypto/m2crypto/merge_requests/7#note_2581821
diff --git a/M2Crypto.egg-info/PKG-INFO b/M2Crypto.egg-info/PKG-INFO
deleted file mode 100644
index 3972df5..0000000
--- a/M2Crypto.egg-info/PKG-INFO
+++ /dev/null
@@ -1,23 +0,0 @@
-Metadata-Version: 1.0
-Name: M2Crypto
-Version: 0.21.1
-Summary: M2Crypto: A Python crypto and SSL toolkit
-Home-page: http://chandlerproject.org/Projects/MeTooCrypto
-Author: Heikki Toivonen
-Author-email: heikki@osafoundation.org
-License: BSD-style license
-Description: M2Crypto is the most complete Python wrapper for OpenSSL featuring RSA, DSA,
- DH, EC, HMACs, message digests, symmetric ciphers (including AES); SSL
- functionality to implement clients and servers; HTTPS extensions to Python's
- httplib, urllib, and xmlrpclib; unforgeable HMAC'ing AuthCookies for web
- session management; FTP/TLS client and server; S/MIME; ZServerSSL: A HTTPS
- server for Zope and ZSmime: An S/MIME messenger for Zope. M2Crypto can also be
- used to provide SSL for Twisted.
-Platform: any
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: Intended Audience :: Developers
-Classifier: Operating System :: OS Independent
-Classifier: Programming Language :: C
-Classifier: Programming Language :: Python
-Classifier: Topic :: Security :: Cryptography
-Classifier: Topic :: Software Development :: Libraries :: Python Modules
diff --git a/M2Crypto.egg-info/SOURCES.txt b/M2Crypto.egg-info/SOURCES.txt
deleted file mode 100644
index dffdb58..0000000
--- a/M2Crypto.egg-info/SOURCES.txt
+++ /dev/null
@@ -1,354 +0,0 @@
-CHANGES
-INSTALL
-LICENCE
-README
-epydoc.conf
-fedora_setup.sh
-pack.py
-setup.cfg
-setup.py
-M2Crypto/ASN1.py
-M2Crypto/AuthCookie.py
-M2Crypto/BIO.py
-M2Crypto/BN.py
-M2Crypto/DH.py
-M2Crypto/DSA.py
-M2Crypto/EC.py
-M2Crypto/EVP.py
-M2Crypto/Engine.py
-M2Crypto/Err.py
-M2Crypto/RC4.py
-M2Crypto/RSA.py
-M2Crypto/Rand.py
-M2Crypto/SMIME.py
-M2Crypto/X509.py
-M2Crypto/__init__.py
-M2Crypto/callback.py
-M2Crypto/ftpslib.py
-M2Crypto/httpslib.py
-M2Crypto/m2.py
-M2Crypto/m2urllib.py
-M2Crypto/m2urllib2.py
-M2Crypto/m2xmlrpclib.py
-M2Crypto/threading.py
-M2Crypto/util.py
-M2Crypto.egg-info/PKG-INFO
-M2Crypto.egg-info/SOURCES.txt
-M2Crypto.egg-info/dependency_links.txt
-M2Crypto.egg-info/top_level.txt
-M2Crypto/PGP/PublicKey.py
-M2Crypto/PGP/PublicKeyRing.py
-M2Crypto/PGP/RSA.py
-M2Crypto/PGP/__init__.py
-M2Crypto/PGP/constants.py
-M2Crypto/PGP/packet.py
-M2Crypto/SSL/Checker.py
-M2Crypto/SSL/Cipher.py
-M2Crypto/SSL/Connection.py
-M2Crypto/SSL/Context.py
-M2Crypto/SSL/SSLServer.py
-M2Crypto/SSL/Session.py
-M2Crypto/SSL/TwistedProtocolWrapper.py
-M2Crypto/SSL/__init__.py
-M2Crypto/SSL/cb.py
-M2Crypto/SSL/ssl_dispatcher.py
-M2Crypto/SSL/timeout.py
-SWIG/Makefile
-SWIG/Makefile.mw
-SWIG/Makefile.osx
-SWIG/_aes.i
-SWIG/_asn1.i
-SWIG/_bio.i
-SWIG/_bn.i
-SWIG/_dh.i
-SWIG/_dsa.i
-SWIG/_ec.i
-SWIG/_engine.i
-SWIG/_evp.i
-SWIG/_lib.h
-SWIG/_lib.i
-SWIG/_m2crypto.def
-SWIG/_m2crypto.i
-SWIG/_objects.i
-SWIG/_pkcs7.i
-SWIG/_rand.i
-SWIG/_rc4.i
-SWIG/_rsa.i
-SWIG/_ssl.i
-SWIG/_threads.i
-SWIG/_util.i
-SWIG/_x509.i
-contrib/README
-contrib/SimpleX509create.README
-contrib/SimpleX509create.py
-contrib/dave.README
-contrib/dave.patch
-contrib/dispatcher.README
-contrib/dispatcher.py
-contrib/isaac.README
-contrib/isaac.httpslib.py
-contrib/m2crypto.spec
-contrib/smimeplus.README
-contrib/smimeplus.py
-demo/bio_mem_rw.py
-demo/dhtest.py
-demo/dsa1024pvtkey.pem
-demo/dsa_bench.py
-demo/dsatest.pem
-demo/dsatest.py
-demo/rsa.priv.pem
-demo/rsa.priv0.pem
-demo/rsa.pub.pem
-demo/rsa1024pvtkey.pem
-demo/rsa_bench.py
-demo/rsatest.py
-demo/CipherSaber/CipherSaber.py
-demo/CipherSaber/cstest1.cs1
-demo/Zope/ca.pem
-demo/Zope/dh1024.pem
-demo/Zope/server.pem
-demo/Zope/starts
-demo/Zope/starts.bat
-demo/Zope/z2s.py
-demo/Zope/z2s.py.diff
-demo/Zope/ZServer/HTTPS_Server.py
-demo/Zope/ZServer/__init__.py
-demo/Zope/ZServer/medusa/ftps_server.py
-demo/Zope/ZServer/medusa/https_server.py
-demo/Zope/lib/python/Products/GuardedFile/GuardedFile.py
-demo/Zope/lib/python/Products/GuardedFile/README.txt
-demo/Zope/lib/python/Products/GuardedFile/TODO.txt
-demo/Zope/lib/python/Products/GuardedFile/__init__.py
-demo/Zope/lib/python/Products/GuardedFile/add.dtml
-demo/Zope/lib/python/Products/GuardedFile/refresh.txt
-demo/Zope/lib/python/Products/GuardedFile/version.txt
-demo/Zope/lib/python/Products/ZSmime/README.txt
-demo/Zope/lib/python/Products/ZSmime/SmimeTag.py
-demo/Zope/lib/python/Products/ZSmime/__init__.py
-demo/Zope/lib/python/Products/ZSmime/version.txt
-demo/Zope/utilities/x509_user.py
-demo/Zope27/INSTALL.txt
-demo/Zope27/install_dir/lib/python/ZServer/HTTPS_Server.py
-demo/Zope27/install_dir/lib/python/ZServer/__init__.py.patch
-demo/Zope27/install_dir/lib/python/ZServer/component.xml.patch
-demo/Zope27/install_dir/lib/python/ZServer/datatypes.py.patch
-demo/Zope27/install_dir/lib/python/ZServer/medusa/https_server.py
-demo/Zope27/instance_home/README.txt.patch
-demo/Zope27/instance_home/etc/zope.conf.patch
-demo/Zope27/instance_home/ssl/ca.pem
-demo/Zope27/instance_home/ssl/dh1024.pem
-demo/Zope27/instance_home/ssl/server.pem
-demo/ZopeX3/INSTALL.txt
-demo/ZopeX3/install_dir/lib/python/zope/app/server/configure.zcml.patch
-demo/ZopeX3/install_dir/lib/python/zope/app/server/https.py
-demo/ZopeX3/install_dir/lib/python/zope/server/http/https_server.py
-demo/ZopeX3/install_dir/lib/python/zope/server/http/https_serverchannel.py
-demo/ZopeX3/install_dir/lib/python/zope/server/http/publisherhttps_server.py
-demo/ZopeX3/instance_home/etc/zope.conf.patch
-demo/ZopeX3/instance_home/ssl/ca.pem
-demo/ZopeX3/instance_home/ssl/dh1024.pem
-demo/ZopeX3/instance_home/ssl/server.pem
-demo/ec/ecdhtest.py
-demo/ec/ecdsa_bench.py
-demo/ec/ecdsatest.pem
-demo/ec/ecdsatest.py
-demo/ec/secp160r1pvtkey.pem
-demo/https.howto/ca.pem
-demo/https.howto/dh1024.pem
-demo/https.howto/get_https.py
-demo/https.howto/https_cli.py
-demo/https.howto/orig_https_srv.py
-demo/https.howto/server.pem
-demo/medusa/00_README
-demo/medusa/START.py
-demo/medusa/START_xmlrpc.py
-demo/medusa/asynchat.py
-demo/medusa/asyncore.py
-demo/medusa/auth_handler.py
-demo/medusa/ca.pem
-demo/medusa/counter.py
-demo/medusa/default_handler.py
-demo/medusa/dh1024.pem
-demo/medusa/filesys.py
-demo/medusa/ftp_server.py
-demo/medusa/ftps_server.py
-demo/medusa/http_date.py
-demo/medusa/http_server.py
-demo/medusa/https_server.py
-demo/medusa/index.html
-demo/medusa/logger.py
-demo/medusa/m_syslog.py
-demo/medusa/medusa_gif.py
-demo/medusa/mime_type_table.py
-demo/medusa/poison_handler.py
-demo/medusa/producers.py
-demo/medusa/put_handler.py
-demo/medusa/redirecting_handler.py
-demo/medusa/server.pem
-demo/medusa/status_handler.py
-demo/medusa/virtual_handler.py
-demo/medusa/xmlrpc_handler.py
-demo/medusa054/00_README
-demo/medusa054/START.py
-demo/medusa054/START_xmlrpc.py
-demo/medusa054/ca.pem
-demo/medusa054/counter.py
-demo/medusa054/default_handler.py
-demo/medusa054/dh1024.pem
-demo/medusa054/filesys.py
-demo/medusa054/ftp_server.py
-demo/medusa054/ftps_server.py
-demo/medusa054/http_date.py
-demo/medusa054/http_server.py
-demo/medusa054/https_server.py
-demo/medusa054/index.html
-demo/medusa054/logger.py
-demo/medusa054/m_syslog.py
-demo/medusa054/medusa_gif.py
-demo/medusa054/poison_handler.py
-demo/medusa054/producers.py
-demo/medusa054/server.pem
-demo/medusa054/status_handler.py
-demo/medusa054/xmlrpc_handler.py
-demo/perf/memio.py
-demo/perf/sha1.py
-demo/pgp/pgpstep.py
-demo/pgp/pubring.pgp
-demo/pgp/secring.pgp
-demo/pkcs7/pkcs7-thawte.pem
-demo/pkcs7/test.py
-demo/smime/README
-demo/smime/ca.pem
-demo/smime/clear.p7
-demo/smime/client.p12
-demo/smime/client.pem
-demo/smime/client2.pem
-demo/smime/m2.se.p7
-demo/smime/ns.p7
-demo/smime/ns.se.p7
-demo/smime/opaque.p7
-demo/smime/sendsmime.py
-demo/smime/test.py
-demo/smime/unsmime.py
-demo/smime.howto/README
-demo/smime.howto/decrypt.py
-demo/smime.howto/dv.py
-demo/smime.howto/encrypt.p7
-demo/smime.howto/encrypt.py
-demo/smime.howto/recipient.pem
-demo/smime.howto/recipient_key.pem
-demo/smime.howto/se.p7
-demo/smime.howto/se.py
-demo/smime.howto/sendsmime.py
-demo/smime.howto/sign.p7
-demo/smime.howto/sign.py
-demo/smime.howto/signer.pem
-demo/smime.howto/signer_key.pem
-demo/smime.howto/verify.py
-demo/ssl/README
-demo/ssl/c.py
-demo/ssl/c_bio.py
-demo/ssl/ca.der
-demo/ssl/ca.pem
-demo/ssl/client.p12
-demo/ssl/client.pem
-demo/ssl/dh1024.pem
-demo/ssl/echo-eg.py
-demo/ssl/echo.py
-demo/ssl/echod-async.py
-demo/ssl/echod-eg1.py
-demo/ssl/echod-forking.py
-demo/ssl/echod-iterative.py
-demo/ssl/echod-thread.py
-demo/ssl/echod-threading.py
-demo/ssl/echod_lib.py
-demo/ssl/ftp_tls.py
-demo/ssl/http_cli_20.py
-demo/ssl/https_cli.py
-demo/ssl/https_cli_async.py
-demo/ssl/https_srv.py
-demo/ssl/myapp.py
-demo/ssl/s_client.py
-demo/ssl/s_server.py
-demo/ssl/server.pem
-demo/ssl/server3.py
-demo/ssl/sess.py
-demo/ssl/sess2.py
-demo/ssl/sess2.ssldump.out
-demo/ssl/socklib.py
-demo/ssl/somelib.py
-demo/ssl/ss.py
-demo/ssl/twistedsslclient.py
-demo/ssl/twistedsslserver.py
-demo/ssl/xmlrpc_cli.py
-demo/ssl/xmlrpc_srv.py
-demo/tinderbox/build_lib.py
-demo/tinderbox/killableprocess.py
-demo/tinderbox/slave.py
-demo/tinderbox/winprocess.py
-demo/x509/ca.py
-demo/x509/certdata2pem.py
-demo/x509/client2.pem
-demo/x509/demo1.py
-demo/x509/proxy_destroy.py
-demo/x509/proxy_info.py
-demo/x509/proxy_init.py
-demo/x509/proxylib.py
-demo/x509/server-expired.pem
-demo/x509/server.pem
-demo/x509/x509auth.py
-doc/ZServerSSL-HOWTO.html
-doc/howto.ca.html
-doc/howto.smime.html
-doc/howto.ssl.html
-tests/README
-tests/__init__.py
-tests/alltests.py
-tests/ca.pem
-tests/der_encoded_seq.b64
-tests/dhparams.pem
-tests/dsa.param.pem
-tests/dsa.priv.pem
-tests/dsa.pub.pem
-tests/ec.priv.pem
-tests/ec.pub.pem
-tests/fips.py
-tests/long_serial_cert.pem
-tests/pubring.pgp
-tests/recipient.pem
-tests/recipient_key.pem
-tests/rsa.priv.pem
-tests/rsa.priv2.pem
-tests/rsa.pub.pem
-tests/server.pem
-tests/signer.pem
-tests/signer_key.pem
-tests/test_asn1.py
-tests/test_authcookie.py
-tests/test_bio.py
-tests/test_bio_file.py
-tests/test_bio_iobuf.py
-tests/test_bio_membuf.py
-tests/test_bio_ssl.py
-tests/test_bn.py
-tests/test_dh.py
-tests/test_dsa.py
-tests/test_ec_curves.py
-tests/test_ecdh.py
-tests/test_ecdsa.py
-tests/test_engine.py
-tests/test_evp.py
-tests/test_obj.py
-tests/test_pgp.py
-tests/test_rand.py
-tests/test_rc4.py
-tests/test_rsa.py
-tests/test_smime.py
-tests/test_ssl.py
-tests/test_ssl_offline.py
-tests/test_ssl_win.py
-tests/test_threading.py
-tests/test_x509.py
-tests/thawte.pem
-tests/x509.der
-tests/x509.pem \ No newline at end of file
diff --git a/M2Crypto.egg-info/dependency_links.txt b/M2Crypto.egg-info/dependency_links.txt
deleted file mode 100644
index 8b13789..0000000
--- a/M2Crypto.egg-info/dependency_links.txt
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/M2Crypto.egg-info/top_level.txt b/M2Crypto.egg-info/top_level.txt
deleted file mode 100644
index fa4a704..0000000
--- a/M2Crypto.egg-info/top_level.txt
+++ /dev/null
@@ -1 +0,0 @@
-M2Crypto
diff --git a/M2Crypto/ASN1.py b/M2Crypto/ASN1.py
index 09d9e9f..bcdb034 100644
--- a/M2Crypto/ASN1.py
+++ b/M2Crypto/ASN1.py
@@ -1,3 +1,5 @@
+from __future__ import absolute_import
+
"""
M2Crypto wrapper for OpenSSL ASN1 API.
@@ -7,115 +9,156 @@ Portions created by Open Source Applications Foundation (OSAF) are
Copyright (C) 2005 OSAF. All Rights Reserved.
"""
-import time, datetime
+import datetime
+import time
-import BIO
-import m2
+from M2Crypto import BIO, m2, py27plus, six
+if py27plus:
+ from typing import Any, Callable, Optional, Tuple # noqa
MBSTRING_FLAG = 0x1000
-MBSTRING_ASC = MBSTRING_FLAG | 1
-MBSTRING_BMP = MBSTRING_FLAG | 2
+MBSTRING_ASC = MBSTRING_FLAG | 1
+MBSTRING_BMP = MBSTRING_FLAG | 2
-class ASN1_Integer:
+class ASN1_Integer(object):
m2_asn1_integer_free = m2.asn1_integer_free
def __init__(self, asn1int, _pyfree=0):
+ # type: (ASN1_Integer, int) -> None
self.asn1int = asn1int
self._pyfree = _pyfree
-
+
def __cmp__(self, other):
+ # type: (ASN1_Integer) -> int
+ if not isinstance(other, ASN1_Integer):
+ raise TypeError(
+ "Comparisons supported only between ANS1_Integer objects")
+
return m2.asn1_integer_cmp(self.asn1int, other.asn1int)
def __del__(self):
+ # type: () -> None
if self._pyfree:
self.m2_asn1_integer_free(self.asn1int)
+ def __int__(self):
+ # type: () -> int
+ return m2.asn1_integer_get(self.asn1int)
+
+
+class ASN1_String(object):
-class ASN1_String:
-
m2_asn1_string_free = m2.asn1_string_free
-
+
def __init__(self, asn1str, _pyfree=0):
+ # type: (ASN1_String, int) -> None
self.asn1str = asn1str
self._pyfree = _pyfree
- def __str__(self):
+ def __bytes__(self):
+ # type: () -> bytes
buf = BIO.MemoryBuffer()
- m2.asn1_string_print( buf.bio_ptr(), self.asn1str )
+ m2.asn1_string_print(buf.bio_ptr(), self.asn1str)
return buf.read_all()
+ def __str__(self):
+ # type: () -> str
+ return six.ensure_text(self.__bytes__())
+
def __del__(self):
+ # type: () -> None
if getattr(self, '_pyfree', 0):
self.m2_asn1_string_free(self.asn1str)
-
+
def _ptr(self):
return self.asn1str
-
+
def as_text(self, flags=0):
+ # type: (int) -> str
+ """Output an ASN1_STRING structure according to the set flags.
+
+ :param flags: determine the format of the output by using
+ predetermined constants, see ASN1_STRING_print_ex(3)
+ manpage for their meaning.
+ :return: output an ASN1_STRING structure.
+ """
buf = BIO.MemoryBuffer()
- m2.asn1_string_print_ex( buf.bio_ptr(), self.asn1str, flags)
- return buf.read_all()
+ m2.asn1_string_print_ex(buf.bio_ptr(), self.asn1str, flags)
+ return six.ensure_text(buf.read_all())
-class ASN1_Object:
-
+class ASN1_Object(object):
+
m2_asn1_object_free = m2.asn1_object_free
def __init__(self, asn1obj, _pyfree=0):
+ # type: (ASN1_Object, int) -> None
self.asn1obj = asn1obj
self._pyfree = _pyfree
-
+
def __del__(self):
+ # type: () -> None
if self._pyfree:
self.m2_asn1_object_free(self.asn1obj)
def _ptr(self):
return self.asn1obj
+
class _UTC(datetime.tzinfo):
def tzname(self, dt):
+ # type: (Optional[datetime.datetime]) -> str
return "UTC"
-
+
def dst(self, dt):
+ # type: (Optional[datetime.datetime]) -> datetime.timedelta
return datetime.timedelta(0)
-
+
def utcoffset(self, dt):
+ # type: (Optional[datetime.datetime]) -> datetime.timedelta
return datetime.timedelta(0)
def __repr__(self):
return "<Timezone: %s>" % self.tzname(None)
-UTC = _UTC()
+
+
+UTC = _UTC() # type: _UTC
class LocalTimezone(datetime.tzinfo):
- """ Localtimezone from datetime manual """
+ """Localtimezone from datetime manual."""
+
def __init__(self):
- self._stdoffset = datetime.timedelta(seconds = -time.timezone)
+ # type: () -> None
+ self._stdoffset = datetime.timedelta(seconds=-time.timezone)
if time.daylight:
- self._dstoffset = datetime.timedelta(seconds = -time.altzone)
+ self._dstoffset = datetime.timedelta(seconds=-time.altzone)
else:
self._dstoffset = self._stdoffset
self._dstdiff = self._dstoffset - self._stdoffset
-
def utcoffset(self, dt):
+ # type: (datetime.datetime) -> datetime.timedelta
if self._isdst(dt):
return self._dstoffset
else:
return self._stdoffset
def dst(self, dt):
+ # type: (datetime.datetime) -> datetime.timedelta
if self._isdst(dt):
return self._dstdiff
else:
return datetime.timedelta(0)
def tzname(self, dt):
- return time.tzname[self._isdst(dt)]
+ # type: (datetime.datetime) -> str
+ return time.tzname[self._isdst(dt).real]
def _isdst(self, dt):
+ # type: (datetime.datetime) -> bool
tt = (dt.year, dt.month, dt.day,
dt.hour, dt.minute, dt.second,
dt.weekday(), 0, -1)
@@ -124,49 +167,59 @@ class LocalTimezone(datetime.tzinfo):
return tt.tm_isdst > 0
-class ASN1_UTCTIME:
+class ASN1_TIME(object):
_ssl_months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug",
"Sep", "Oct", "Nov", "Dec"]
- m2_asn1_utctime_free = m2.asn1_utctime_free
-
- def __init__(self, asn1_utctime=None, _pyfree=0):
- if asn1_utctime is not None:
- assert m2.asn1_utctime_type_check(asn1_utctime), "'asn1_utctime' type error'"
- self.asn1_utctime = asn1_utctime
+ m2_asn1_time_free = m2.asn1_time_free
+
+ def __init__(self, asn1_time=None, _pyfree=0, asn1_utctime=None):
+ # type: (Optional[ASN1_TIME], Optional[int], Optional[ASN1_TIME]) -> None
+ # handle old keyword parameter
+ if asn1_time is None:
+ asn1_time = asn1_utctime
+ if asn1_time is not None:
+ assert m2.asn1_time_type_check(asn1_time), \
+ "'asn1_time' type error'"
+ self.asn1_time = asn1_time
self._pyfree = _pyfree
else:
- self.asn1_utctime = m2.asn1_utctime_new ()
+ self.asn1_time = m2.asn1_time_new()
self._pyfree = 1
-
+
def __del__(self):
+ # type: () -> None
if getattr(self, '_pyfree', 0):
- self.m2_asn1_utctime_free(self.asn1_utctime)
-
+ self.m2_asn1_time_free(self.asn1_time)
+
def __str__(self):
- assert m2.asn1_utctime_type_check(self.asn1_utctime), "'asn1_utctime' type error'"
+ # type: () -> str
+ assert m2.asn1_time_type_check(self.asn1_time), \
+ "'asn1_time' type error'"
buf = BIO.MemoryBuffer()
- m2.asn1_utctime_print( buf.bio_ptr(), self.asn1_utctime )
- return buf.read_all()
+ m2.asn1_time_print(buf.bio_ptr(), self.asn1_time)
+ return six.ensure_text(buf.read_all())
def _ptr(self):
- assert m2.asn1_utctime_type_check(self.asn1_utctime), "'asn1_utctime' type error'"
- return self.asn1_utctime
-
- def set_string (self, string):
- """
- Set time from UTC string.
- """
- assert m2.asn1_utctime_type_check(self.asn1_utctime), "'asn1_utctime' type error'"
- return m2.asn1_utctime_set_string( self.asn1_utctime, string )
-
- def set_time (self, time):
- """
- Set time from seconds since epoch (long).
- """
- assert m2.asn1_utctime_type_check(self.asn1_utctime), "'asn1_utctime' type error'"
- return m2.asn1_utctime_set( self.asn1_utctime, time )
+ assert m2.asn1_time_type_check(self.asn1_time), \
+ "'asn1_time' type error'"
+ return self.asn1_time
+
+ def set_string(self, string):
+ # type: (bytes) -> int
+ """Set time from UTC string."""
+ assert m2.asn1_time_type_check(self.asn1_time), \
+ "'asn1_time' type error'"
+ return m2.asn1_time_set_string(self.asn1_time, string)
+
+ def set_time(self, time):
+ # type: (int) -> ASN1_TIME
+ """Set time from seconds since epoch (int)."""
+ assert m2.asn1_time_type_check(self.asn1_time), \
+ "'asn1_time' type error'"
+ return m2.asn1_time_set(self.asn1_time, time)
def get_datetime(self):
+ # type: () -> ASN1_TIME
date = str(self)
timezone = None
@@ -174,19 +227,27 @@ class ASN1_UTCTIME:
raise ValueError("Invalid date: %s" % date)
month, rest = date.split(' ', 1)
if month not in self._ssl_months:
- raise ValueError("Invalid date %s: Invalid month: %s" % (date, m))
+ raise ValueError("Invalid date %s: Invalid month: %s" %
+ (date, month))
if rest.endswith(' GMT'):
timezone = UTC
rest = rest[:-4]
- tm = list(time.strptime(rest, "%d %H:%M:%S %Y"))[:6]
- tm[1] = self._ssl_months.index(month) + 1
- tm.append(0)
- tm.append(timezone)
- return datetime.datetime(*tm)
+ if '.' in rest:
+ dt = datetime.datetime.strptime(rest, "%d %H:%M:%S.%f %Y")
+ else:
+ dt = datetime.datetime.strptime(rest, "%d %H:%M:%S %Y")
+ dt = dt.replace(month=self._ssl_months.index(month) + 1)
+ if timezone:
+ dt = dt.replace(tzinfo=UTC)
+ return dt
def set_datetime(self, date):
+ # type: (datetime.datetime) -> ASN1_TIME
local = LocalTimezone()
if date.tzinfo is None:
date = date.replace(tzinfo=local)
date = date.astimezone(local)
return self.set_time(int(time.mktime(date.timetuple())))
+
+
+ASN1_UTCTIME = ASN1_TIME
diff --git a/M2Crypto/AuthCookie.py b/M2Crypto/AuthCookie.py
index d401708..c843797 100644
--- a/M2Crypto/AuthCookie.py
+++ b/M2Crypto/AuthCookie.py
@@ -1,28 +1,41 @@
+from __future__ import absolute_import
+
"""Secure Authenticator Cookies
Copyright (c) 1999-2002 Ng Pheng Siong. All rights reserved."""
-# M2Crypto
-import Rand, m2
+import logging
+import re
+import time
+
+from M2Crypto import Rand, m2, py27plus, six, util
+from M2Crypto.six.moves.http_cookies import SimpleCookie # pylint: disable=no-name-in-module,import-error
-# Python. Cookie is bundled with Python 2.x.
-import Cookie, binascii, re, time
+if py27plus:
+ from typing import re as type_re, AnyStr, Dict, Optional, Union # noqa
+_MIX_FORMAT = 'exp=%f&data=%s&digest='
+_MIX_RE = re.compile(r'exp=(\d+\.\d+)&data=(.+)&digest=(\S*)')
+
+log = logging.getLogger(__name__)
-_MIX_FORMAT = 'exp=%s&data=%s&digest='
-_MIX_RE = re.compile('exp=(\d+\.\d+)&data=(.+)&digest=(\S*)')
def mix(expiry, data, format=_MIX_FORMAT):
- return format % (repr(expiry), data)
+ # type: (float, AnyStr, str) -> AnyStr
+ return format % (expiry, data)
+
def unmix(dough, regex=_MIX_RE):
+ # type: (AnyStr, type_re) -> object
mo = regex.match(dough)
if mo:
return float(mo.group(1)), mo.group(2)
else:
return None
+
def unmix3(dough, regex=_MIX_RE):
+ # type: (AnyStr, type_re) -> Optional[tuple[float, AnyStr, AnyStr]]
mo = regex.match(dough)
if mo:
return float(mo.group(1)), mo.group(2), mo.group(3)
@@ -30,23 +43,37 @@ def unmix3(dough, regex=_MIX_RE):
return None
-_TOKEN = '_M2AUTH_'
+_TOKEN = '_M2AUTH_' # type: str
+
-class AuthCookieJar:
+class AuthCookieJar(object):
- _keylen = 20
+ _keylen = 20 # type: int
def __init__(self):
+ # type: () -> None
self._key = Rand.rand_bytes(self._keylen)
-
+
def _hmac(self, key, data):
- return binascii.b2a_base64(m2.hmac(key, data, m2.sha1()))[:-1]
-
+ # type: (bytes, str) -> str
+ return util.bin_to_hex(m2.hmac(key, six.ensure_binary(data), m2.sha1()))
+
def makeCookie(self, expiry, data):
+ # type: (float, str) -> AuthCookie
+ """
+ Make a cookie
+
+ :param expiry: expiration time (float in seconds)
+ :param data: cookie content
+ :return: AuthCookie object
+ """
+ if not isinstance(expiry, (six.integer_types, float)):
+ raise ValueError('Expiration time must be number, not "%s' % expiry)
dough = mix(expiry, data)
return AuthCookie(expiry, data, dough, self._hmac(self._key, dough))
def isGoodCookie(self, cookie):
+ # type: (AuthCookie) -> Union[bool, int]
assert isinstance(cookie, AuthCookie)
if cookie.isExpired():
return 0
@@ -56,59 +83,87 @@ class AuthCookieJar:
and (c._mac == cookie._mac) \
and (c.output() == cookie.output())
- def isGoodCookieString(self, cookie_str):
- c = Cookie.SmartCookie()
+ def isGoodCookieString(self, cookie_str, _debug=False):
+ # type: (Union[dict, bytes], bool) -> Union[bool, int]
+ c = SimpleCookie()
c.load(cookie_str)
- if not c.has_key(_TOKEN):
+ if _TOKEN not in c:
+ log.debug('_TOKEN not in c (keys = %s)', dir(c))
return 0
undough = unmix3(c[_TOKEN].value)
if undough is None:
+ log.debug('undough is None')
return 0
exp, data, mac = undough
c2 = self.makeCookie(exp, data)
+ if _debug and (c2._mac == mac):
+ log.error('cookie_str = %s', cookie_str)
+ log.error('c2.isExpired = %s', c2.isExpired())
+ log.error('mac = %s', mac)
+ log.error('c2._mac = %s', c2._mac)
+ log.error('c2._mac == mac: %s', str(c2._mac == mac))
return (not c2.isExpired()) and (c2._mac == mac)
-class AuthCookie:
-
+class AuthCookie(object):
+
def __init__(self, expiry, data, dough, mac):
+ # type: (float, str, str, str) -> None
+ """
+ Create new authentication cookie
+
+ :param expiry: expiration time (in seconds)
+ :param data: cookie payload (as a string)
+ :param dough: expiry & data concatenated to URL compliant
+ string
+ :param mac: SHA1-based HMAC of dough and random key
+ """
self._expiry = expiry
self._data = data
self._mac = mac
- self._cookie = Cookie.SmartCookie()
+ self._cookie = SimpleCookie()
self._cookie[_TOKEN] = '%s%s' % (dough, mac)
- self._name = '%s%s' % (dough, mac) # XXX WebKit only.
+ self._name = '%s%s' % (dough, mac) # WebKit only.
def expiry(self):
+ # type: () -> float
"""Return the cookie's expiry time."""
return self._expiry
def data(self):
+ # type: () -> str
"""Return the data portion of the cookie."""
return self._data
def mac(self):
+ # type: () -> str
"""Return the cookie's MAC."""
return self._mac
- def output(self):
+ def output(self, header="Set-Cookie:"):
+ # type: (Optional[str]) -> str
"""Return the cookie's output in "Set-Cookie" format."""
- return self._cookie.output()
+ return self._cookie.output(header=header)
def value(self):
+ # type: () -> str
"""Return the cookie's output minus the "Set-Cookie: " portion.
"""
return self._cookie[_TOKEN].value
def isExpired(self):
+ # type: () -> bool
"""Return 1 if the cookie has expired, 0 otherwise."""
- return (time.time() > self._expiry)
+ return isinstance(self._expiry, (float, six.integer_types)) and \
+ (time.time() > self._expiry)
- # XXX Following methods are for WebKit only. These should be pushed
- # to WKAuthCookie.
+ # Following two methods are for WebKit only.
+ # I may wish to push them to WKAuthCookie, but they are part
+ # of the API now. Oh well.
def name(self):
+ # type: () -> str
return self._name
def headerValue(self):
+ # type: () -> str
return self.value()
-
diff --git a/M2Crypto/BIO.py b/M2Crypto/BIO.py
index 11dbce4..71a486a 100644
--- a/M2Crypto/BIO.py
+++ b/M2Crypto/BIO.py
@@ -1,31 +1,38 @@
+from __future__ import absolute_import
+
"""M2Crypto wrapper for OpenSSL BIO API.
Copyright (c) 1999-2004 Ng Pheng Siong. All rights reserved."""
-import m2
+import logging
+
+from M2Crypto import m2, py27plus, six
+if py27plus:
+ from typing import AnyStr, Callable, Iterable, Optional, Union # noqa
-# Deprecated
-from m2 import bio_do_handshake as bio_do_ssl_handshake
+log = logging.getLogger('BIO')
-from cStringIO import StringIO
-class BIOError(Exception): pass
+class BIOError(ValueError):
+ pass
+
m2.bio_init(BIOError)
-class BIO:
+class BIO(object):
"""Abstract object interface to the BIO API."""
m2_bio_free = m2.bio_free
def __init__(self, bio=None, _pyfree=0, _close_cb=None):
+ # type: (Optional[BIO], int, Optional[Callable]) -> None
self.bio = bio
self._pyfree = _pyfree
self._close_cb = _close_cb
self.closed = 0
self.write_closed = 0
-
+
def __del__(self):
if self._pyfree:
self.m2_bio_free(self.bio)
@@ -37,160 +44,248 @@ class BIO:
bio_ptr = _ptr
def fileno(self):
+ # type: () -> int
return m2.bio_get_fd(self.bio)
def readable(self):
+ # type: () -> bool
return not self.closed
def read(self, size=None):
+ # type: (int) -> Union[bytes, bytearray]
if not self.readable():
- raise IOError, 'cannot read'
+ raise IOError('cannot read')
if size is None:
- buf = StringIO()
+ buf = bytearray()
while 1:
data = m2.bio_read(self.bio, 4096)
- if not data: break
- buf.write(data)
- return buf.getvalue()
+ if not data:
+ break
+ buf += data
+ return buf
elif size == 0:
- return ''
+ return b''
elif size < 0:
- raise ValueError, 'read count is negative'
+ raise ValueError('read count is negative')
else:
- return m2.bio_read(self.bio, size)
+ return bytes(m2.bio_read(self.bio, size))
def readline(self, size=4096):
+ # type: (int) -> bytes
if not self.readable():
- raise IOError, 'cannot read'
+ raise IOError('cannot read')
buf = m2.bio_gets(self.bio, size)
- return buf
+ buf = '' if buf is None else buf
+ return six.ensure_binary(buf)
def readlines(self, sizehint='ignored'):
+ # type: (Union[AnyStr, int]) -> Iterable[bytes]
if not self.readable():
- raise IOError, 'cannot read'
- lines=[]
+ raise IOError('cannot read')
+ lines = []
while 1:
- buf=m2.bio_gets(self.bio, 4096)
+ buf = m2.bio_gets(self.bio, 4096)
if buf is None:
break
- lines.append(buf)
+ lines.append(six.ensure_binary(buf))
return lines
def writeable(self):
+ # type: () -> bool
return (not self.closed) and (not self.write_closed)
-
+
def write(self, data):
+ # type: (AnyStr) -> int
+ """Write data to BIO.
+
+ :return: either data written, or [0, -1] for nothing written,
+ -2 not implemented
+ """
if not self.writeable():
- raise IOError, 'cannot write'
+ raise IOError('cannot write')
+ if isinstance(data, six.text_type):
+ data = data.encode('utf8')
return m2.bio_write(self.bio, data)
def write_close(self):
+ # type: () -> None
self.write_closed = 1
def flush(self):
+ # type: () -> None
+ """Flush the buffers.
+
+ :return: 1 for success, and 0 or -1 for failure
+ """
m2.bio_flush(self.bio)
def reset(self):
- """
- Sets the bio to its initial state
+ # type: () -> int
+ """Set the bio to its initial state.
+
+ :return: 1 for success, and 0 or -1 for failure
"""
return m2.bio_reset(self.bio)
def close(self):
+ # type: () -> None
self.closed = 1
if self._close_cb:
self._close_cb()
def should_retry(self):
+ # type: () -> int
"""
Can the call be attempted again, or was there an error
- ie do_handshake
-
+ ie do_handshake
+
"""
- return m2.bio_should_retry(self.bio)
+ return m2.bio_should_retry(self.bio)
def should_read(self):
- """
- Returns whether the cause of the condition is the bio
- should read more data
- """
+ # type: () -> int
+ """Should we read more data?"""
+
return m2.bio_should_read(self.bio)
-
+
def should_write(self):
- """
- Returns whether the cause of the condition is the bio
- should write more data
- """
+ # type: () -> int
+ """Should we write more data?"""
return m2.bio_should_write(self.bio)
-
+
+ def tell(self):
+ """Return the current offset."""
+ return m2.bio_tell(self.bio)
+
+ def seek(self, off):
+ """Seek to the specified absolute offset."""
+ return m2.bio_seek(self.bio, off)
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, *args):
+ # type: (*Any) -> int
+ self.close()
+
+
class MemoryBuffer(BIO):
+ """Object interface to BIO_s_mem.
- """
- Object interface to BIO_s_mem.
-
- Empirical testing suggests that this class performs less well than cStringIO,
- because cStringIO is implemented in C, whereas this class is implemented in
- Python. Thus, the recommended practice is to use cStringIO for regular work and
- convert said cStringIO object to a MemoryBuffer object only when necessary.
+ Empirical testing suggests that this class performs less well than
+ cStringIO, because cStringIO is implemented in C, whereas this class
+ is implemented in Python. Thus, the recommended practice is to use
+ cStringIO for regular work and convert said cStringIO object to
+ a MemoryBuffer object only when necessary.
"""
def __init__(self, data=None):
- BIO.__init__(self)
+ # type: (Optional[bytes]) -> None
+ super(MemoryBuffer, self).__init__(self)
+ if data is not None and not isinstance(data, bytes):
+ raise TypeError(
+ "data must be bytes or None, not %s" % (type(data).__name__, ))
self.bio = m2.bio_new(m2.bio_s_mem())
self._pyfree = 1
if data is not None:
m2.bio_write(self.bio, data)
def __len__(self):
+ # type: () -> int
return m2.bio_ctrl_pending(self.bio)
def read(self, size=0):
+ # type: (int) -> bytes
if not self.readable():
- raise IOError, 'cannot read'
+ raise IOError('cannot read')
if size:
return m2.bio_read(self.bio, size)
else:
return m2.bio_read(self.bio, m2.bio_ctrl_pending(self.bio))
-
+
# Backwards-compatibility.
getvalue = read_all = read
def write_close(self):
- self.write_closed = 1
+ # type: () -> None
+ super(MemoryBuffer, self).write_close()
m2.bio_set_mem_eof_return(self.bio, 0)
close = write_close
class File(BIO):
+ """Object interface to BIO_s_pyfd.
- """
- Object interface to BIO_s_fp.
-
- This class interfaces Python to OpenSSL functions that expect BIO *. For
+ This class interfaces Python to OpenSSL functions that expect BIO. For
general file manipulation in Python, use Python's builtin file object.
"""
- def __init__(self, pyfile, close_pyfile=1):
- BIO.__init__(self, _pyfree=1)
+ def __init__(self, pyfile, close_pyfile=1, mode='rb'):
+ # type: (Union[io.BytesIO, AnyStr], int, AnyStr) -> None
+ super(File, self).__init__(self, _pyfree=1)
+
+ if isinstance(pyfile, six.string_types):
+ pyfile = open(pyfile, mode)
+
+ # This is for downward compatibility, but I don't think, that it is
+ # good practice to have two handles for the same file. Whats about
+ # concurrent write access? Last write, last wins? Especially since Py3
+ # has its own buffer management. See:
+ #
+ # https://docs.python.org/3.3/c-api/file.html
+ #
+ pyfile.flush()
+ self.fname = pyfile.name
self.pyfile = pyfile
+ # Be wary of https://github.com/openssl/openssl/pull/1925
+ # BIO_new_fd is NEVER to be used before OpenSSL 1.1.1
+ if hasattr(m2, "bio_new_pyfd"):
+ self.bio = m2.bio_new_pyfd(pyfile.fileno(), m2.bio_noclose)
+ else:
+ self.bio = m2.bio_new_pyfile(pyfile, m2.bio_noclose)
+
self.close_pyfile = close_pyfile
- self.bio = m2.bio_new_fp(pyfile, 0)
+ self.closed = False
+
+ def flush(self):
+ # type: () -> None
+ super(File, self).flush()
+ self.pyfile.flush()
def close(self):
- self.closed = 1
+ # type: () -> None
+ self.flush()
+ super(File, self).close()
if self.close_pyfile:
self.pyfile.close()
+ def reset(self):
+ # type: () -> int
+ """Set the bio to its initial state.
+
+ :return: 0 for success, and -1 for failure
+ """
+ return super(File, self).reset()
+
+ def __del__(self):
+ if not self.closed:
+ m2.bio_free(self.bio)
+
+
def openfile(filename, mode='rb'):
- return File(open(filename, mode))
+ # type: (AnyStr, AnyStr) -> File
+ try:
+ f = open(filename, mode)
+ except IOError as ex:
+ raise BIOError(ex.args)
+
+ return File(f)
class IOBuffer(BIO):
+ """Object interface to BIO_f_buffer.
- """
- Object interface to BIO_f_buffer.
-
Its principal function is to be BIO_push()'ed on top of a BIO_f_ssl, so
that makefile() of said underlying SSL socket works.
"""
@@ -199,30 +294,30 @@ class IOBuffer(BIO):
m2_bio_free = m2.bio_free
def __init__(self, under_bio, mode='rwb', _pyfree=1):
- BIO.__init__(self, _pyfree=_pyfree)
+ # type: (BIO, str, int) -> None
+ super(IOBuffer, self).__init__(self, _pyfree=_pyfree)
self.io = m2.bio_new(m2.bio_f_buffer())
self.bio = m2.bio_push(self.io, under_bio._ptr())
# This reference keeps the underlying BIO alive while we're not closed.
- self._under_bio = under_bio
+ self._under_bio = under_bio
if 'w' in mode:
self.write_closed = 0
else:
self.write_closed = 1
-
+
def __del__(self):
+ # type: () -> None
if getattr(self, '_pyfree', 0):
self.m2_bio_pop(self.bio)
self.m2_bio_free(self.io)
def close(self):
+ # type: () -> None
BIO.close(self)
class CipherStream(BIO):
-
- """
- Object interface to BIO_f_cipher.
- """
+ """Object interface to BIO_f_cipher."""
SALT_LEN = m2.PKCS5_SALT_LEN
@@ -230,57 +325,66 @@ class CipherStream(BIO):
m2_bio_free = m2.bio_free
def __init__(self, obio):
- BIO.__init__(self, _pyfree=1)
+ # type: (BIO) -> None
+ super(CipherStream, self).__init__(self, _pyfree=1)
self.obio = obio
self.bio = m2.bio_new(m2.bio_f_cipher())
self.closed = 0
-
+
def __del__(self):
+ # type: () -> None
if not getattr(self, 'closed', 1):
self.close()
def close(self):
+ # type: () -> None
self.m2_bio_pop(self.bio)
self.m2_bio_free(self.bio)
self.closed = 1
-
+
def write_close(self):
+ # type: () -> None
self.obio.write_close()
def set_cipher(self, algo, key, iv, op):
+ # type: (str, AnyStr, AnyStr, int) -> None
cipher = getattr(m2, algo, None)
if cipher is None:
- raise ValueError, ('unknown cipher', algo)
- m2.bio_set_cipher(self.bio, cipher(), key, iv, op)
+ raise ValueError('unknown cipher', algo)
+ else:
+ if not isinstance(key, bytes):
+ key = key.encode('utf8')
+ if not isinstance(iv, bytes):
+ iv = iv.encode('utf8')
+ m2.bio_set_cipher(self.bio, cipher(), key, iv, int(op))
m2.bio_push(self.bio, self.obio._ptr())
class SSLBio(BIO):
- """
- Object interface to BIO_f_ssl
- """
+ """Object interface to BIO_f_ssl."""
+
def __init__(self, _pyfree=1):
- BIO.__init__(self, _pyfree)
+ # type: (int) -> None
+ super(SSLBio, self).__init__(self, _pyfree=_pyfree)
self.bio = m2.bio_new(m2.bio_f_ssl())
self.closed = 0
-
def set_ssl(self, conn, close_flag=m2.bio_noclose):
+ # type: (Connection, int) -> None
"""
Sets the bio to the SSL pointer which is
- contained in the connection object.
+ contained in the connection object.
"""
- self._pyfree = 0
+ self._pyfree = 0
m2.bio_set_ssl(self.bio, conn.ssl, close_flag)
if close_flag == m2.bio_noclose:
conn.set_ssl_close_flag(m2.bio_close)
-
+
def do_handshake(self):
- """
- Do the handshake.
-
+ # type: () -> int
+ """Do the handshake.
+
Return 1 if the handshake completes
Return 0 or a negative number if there is a problem
"""
return m2.bio_do_handshake(self.bio)
-
diff --git a/M2Crypto/BN.py b/M2Crypto/BN.py
index ec741c0..57a13a6 100755..100644
--- a/M2Crypto/BN.py
+++ b/M2Crypto/BN.py
@@ -1,47 +1,58 @@
+from __future__ import absolute_import
+
"""
M2Crypto wrapper for OpenSSL BN (BIGNUM) API.
Copyright (c) 2005 Open Source Applications Foundation. All rights reserved.
"""
-import m2
+from M2Crypto import m2, util
+if util.py27plus:
+ from typing import Optional # noqa
+
def rand(bits, top=-1, bottom=0):
+ # type: (int, int, int) -> Optional[int]
"""
Generate cryptographically strong random number.
-
- @param bits: Length of random number in bits.
- @param top: If -1, the most significant bit can be 0. If 0, the most
+
+ :param bits: Length of random number in bits.
+ :param top: If -1, the most significant bit can be 0. If 0, the most
significant bit is 1, and if 1, the two most significant
bits will be 1.
- @param bottom: If bottom is true, the number will be odd.
+ :param bottom: If bottom is true, the number will be odd.
"""
return m2.bn_rand(bits, top, bottom)
def rand_range(range):
+ # type: (int) -> int
"""
Generate a random number in a range.
-
- @param range: Upper limit for range.
- @return: A random number in the range [0, range)
+
+ :param range: Upper limit for range.
+ :return: A random number in the range [0, range)
"""
return m2.bn_rand_range(range)
def randfname(length):
+ # type: (int) -> str
"""
Return a random filename, which is simply a string where all
the characters are from the set [a-zA-Z0-9].
- @param length: Length of filename to return.
- @type length: int
- @return: random filename string
+ :param length: Length of filename to return.
+ :return: random filename string
"""
+ import warnings
+ warnings.warn(
+ "Don't use BN.randfname(), use tempfile methods instead.",
+ DeprecationWarning, stacklevel=2)
letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890'
lettersLen = len(letters)
- fname = []
+ fname = [] # type: list
for x in range(length):
fname += [letters[m2.bn_rand_range(lettersLen)]]
-
+
return ''.join(fname)
diff --git a/M2Crypto/DH.py b/M2Crypto/DH.py
index 4d454ef..b46a305 100644
--- a/M2Crypto/DH.py
+++ b/M2Crypto/DH.py
@@ -1,37 +1,45 @@
+from __future__ import absolute_import
+
"""M2Crypto wrapper for OpenSSL DH API.
Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
-from util import genparam_callback
-import BIO, Err, m2
+from M2Crypto import BIO, m2, util
+from M2Crypto.util import genparam_callback
+if util.py27plus:
+ from typing import AnyStr, Callable # noqa
+
-class DHError(Exception): pass
+class DHError(Exception):
+ pass
m2.dh_init(DHError)
-class DH:
- """
- Object interface to the Diffie-Hellman key exchange
- protocol.
+class DH(object):
+ """Object interface to the Diffie-Hellman key exchange protocol.
"""
m2_dh_free = m2.dh_free
def __init__(self, dh, _pyfree=0):
+ # type: (bytes, int) -> None
assert m2.dh_type_check(dh)
self.dh = dh
self._pyfree = _pyfree
-
+
def __del__(self):
+ # type: () -> None
if getattr(self, '_pyfree', 0):
self.m2_dh_free(self.dh)
def __len__(self):
+ # type: () -> int
assert m2.dh_type_check(self.dh), "'dh' type error"
- return m2.dh_size(self.dh)
+ return int(m2.dh_size(self.dh))
def __getattr__(self, name):
+ # type: (str) -> bytes
if name in ('p', 'g', 'pub', 'priv'):
method = getattr(m2, 'dh_get_%s' % (name,))
assert m2.dh_type_check(self.dh), "'dh' type error"
@@ -40,10 +48,11 @@ class DH:
raise AttributeError
def __setattr__(self, name, value):
+ # type: (str, bytes) -> bytes
if name in ('p', 'g'):
- raise DHError, 'set (p, g) via set_params()'
- elif name in ('pub','priv'):
- raise DHError, 'generate (pub, priv) via gen_key()'
+ raise DHError('set (p, g) via set_params()')
+ elif name in ('pub', 'priv'):
+ raise DHError('generate (pub, priv) via gen_key()')
else:
self.__dict__[name] = value
@@ -51,46 +60,54 @@ class DH:
return self.dh
def check_params(self):
+ # type: () -> int
assert m2.dh_type_check(self.dh), "'dh' type error"
return m2.dh_check(self.dh)
-
+
def gen_key(self):
+ # type: () -> None
assert m2.dh_type_check(self.dh), "'dh' type error"
- m2.dh_generate_key(self.dh)
+ m2.dh_generate_key(self.dh)
def compute_key(self, pubkey):
+ # type: (bytes) -> bytes
assert m2.dh_type_check(self.dh), "'dh' type error"
return m2.dh_compute_key(self.dh, pubkey)
def print_params(self, bio):
+ # type: (BIO.BIO) -> int
assert m2.dh_type_check(self.dh), "'dh' type error"
return m2.dhparams_print(bio._ptr(), self.dh)
def gen_params(plen, g, callback=genparam_callback):
- return DH(m2.dh_generate_parameters(plen, g, callback), 1)
+ # type: (int, int, Optional[Callable]) -> DH
+ dh_parms = m2.dh_generate_parameters(plen, g, callback)
+ dh_obj = DH(dh_parms, 1)
+ return dh_obj
def load_params(file):
- bio = BIO.openfile(file)
- return load_params_bio(bio)
+ # type: (AnyStr) -> DH
+ with BIO.openfile(file) as bio:
+ return load_params_bio(bio)
def load_params_bio(bio):
+ # type: (BIO.BIO) -> DH
return DH(m2.dh_read_parameters(bio._ptr()), 1)
def set_params(p, g):
+ # type: (bytes, bytes) -> DH
dh = m2.dh_new()
- m2.dh_set_p(dh, p)
- m2.dh_set_g(dh, g)
+ m2.dh_set_pg(dh, p, g)
return DH(dh, 1)
-#def free_params(cptr):
+# def free_params(cptr):
# m2.dh_free(cptr)
DH_GENERATOR_2 = m2.DH_GENERATOR_2
DH_GENERATOR_5 = m2.DH_GENERATOR_5
-
diff --git a/M2Crypto/DSA.py b/M2Crypto/DSA.py
index db1f2ff..224848d 100644
--- a/M2Crypto/DSA.py
+++ b/M2Crypto/DSA.py
@@ -1,3 +1,5 @@
+from __future__ import absolute_import, print_function
+
"""
M2Crypto wrapper for OpenSSL DSA API.
@@ -7,71 +9,77 @@
Copyright (C) 2004 OSAF. All Rights Reserved.
"""
-import sys
-import util, BIO, m2
+from M2Crypto import BIO, m2, util
+if util.py27plus:
+ from typing import AnyStr, Callable, Tuple # noqa
+
-class DSAError(Exception): pass
+class DSAError(Exception):
+ pass
m2.dsa_init(DSAError)
-class DSA:
+
+class DSA(object):
"""
This class is a context supporting DSA key and parameter
values, signing and verifying.
-
+
Simple example::
-
+
from M2Crypto import EVP, DSA, util
-
+
message = 'Kilroy was here!'
md = EVP.MessageDigest('sha1')
- md.update(message)
+ md.update(message)
digest = md.final()
-
+
dsa = DSA.gen_params(1024)
dsa.gen_key()
r, s = dsa.sign(digest)
good = dsa.verify(digest, r, s)
if good:
- print ' ** success **'
+ print(' ** success **')
else:
- print ' ** verification failed **'
+ print(' ** verification failed **')
"""
m2_dsa_free = m2.dsa_free
def __init__(self, dsa, _pyfree=0):
+ # type: (bytes, int) -> None
"""
Use one of the factory functions to create an instance.
+ :param dsa: binary representation of OpenSSL DSA type
"""
assert m2.dsa_type_check(dsa), "'dsa' type error"
self.dsa = dsa
self._pyfree = _pyfree
-
+
def __del__(self):
+ # type: () -> None
if getattr(self, '_pyfree', 0):
self.m2_dsa_free(self.dsa)
def __len__(self):
+ # type: () -> int
"""
Return the key length.
-
- @rtype: int
- @return: the DSA key length in bits
+
+ :return: the DSA key length in bits
"""
assert m2.dsa_type_check(self.dsa), "'dsa' type error"
return m2.dsa_keylen(self.dsa)
def __getattr__(self, name):
+ # type: (str) -> bytes
"""
Return specified DSA parameters and key values.
-
- @type name: str
- @param name: name of variable to be returned. Must be
+
+ :param name: name of variable to be returned. Must be
one of 'p', 'q', 'g', 'pub', 'priv'.
- @rtype: str
- @return: value of specified variable (a "byte string")
+ :return: value of specified variable (a "byte string")
"""
if name in ['p', 'q', 'g', 'pub', 'priv']:
method = getattr(m2, 'dsa_get_%s' % (name,))
@@ -81,87 +89,95 @@ class DSA:
raise AttributeError
def __setattr__(self, name, value):
+ # type: (str, bytes) -> None
if name in ['p', 'q', 'g']:
raise DSAError('set (p, q, g) via set_params()')
- elif name in ['pub','priv']:
+ elif name in ['pub', 'priv']:
raise DSAError('generate (pub, priv) via gen_key()')
else:
self.__dict__[name] = value
def set_params(self, p, q, g):
+ # type: (bytes, bytes, bytes) -> None
"""
Set new parameters.
-
+
+ :param p: MPI binary representation ... format that consists of
+ the number's length in bytes represented as a 4-byte
+ big-endian number, and the number itself in big-endian
+ format, where the most significant bit signals
+ a negative number (the representation of numbers with
+ the MSB set is prefixed with null byte).
+ :param q: ditto
+ :param g: ditto
+
@warning: This does not change the private key, so it may be
unsafe to use this method. It is better to use
gen_params function to create a new DSA object.
"""
- m2.dsa_set_p(self.dsa, p)
- m2.dsa_set_q(self.dsa, q)
- m2.dsa_set_g(self.dsa, g)
+ m2.dsa_set_pqg(self.dsa, p, q, g)
def gen_key(self):
+ # type: () -> None
"""
Generate a key pair.
"""
assert m2.dsa_type_check(self.dsa), "'dsa' type error"
- m2.dsa_gen_key(self.dsa)
+ m2.dsa_gen_key(self.dsa)
def save_params(self, filename):
+ # type: (AnyStr) -> int
"""
Save the DSA parameters to a file.
-
- @type filename: str
- @param filename: Save the DSA parameters to this file.
- @return: 1 (true) if successful
+
+ :param filename: Save the DSA parameters to this file.
+ :return: 1 (true) if successful
"""
- bio = BIO.openfile(filename, 'wb')
- ret = m2.dsa_write_params_bio(self.dsa, bio._ptr())
- bio.close()
+ with BIO.openfile(filename, 'wb') as bio:
+ ret = m2.dsa_write_params_bio(self.dsa, bio._ptr())
+
return ret
def save_params_bio(self, bio):
+ # type: (BIO.BIO) -> int
"""
Save DSA parameters to a BIO object.
-
- @type bio: M2Crypto.BIO object
- @param bio: Save DSA parameters to this object.
- @return: 1 (true) if successful
+
+ :param bio: Save DSA parameters to this object.
+ :return: 1 (true) if successful
"""
return m2.dsa_write_params_bio(self.dsa, bio._ptr())
- def save_key(self, filename, cipher='aes_128_cbc',
+ def save_key(self, filename, cipher='aes_128_cbc',
callback=util.passphrase_callback):
+ # type: (AnyStr, str, Callable) -> int
"""
Save the DSA key pair to a file.
-
- @type filename: str
- @param filename: Save the DSA key pair to this file.
- @type cipher: str
- @param cipher: name of symmetric key algorithm and mode
+
+ :param filename: Save the DSA key pair to this file.
+ :param cipher: name of symmetric key algorithm and mode
to encrypt the private key.
- @return: 1 (true) if successful
+ :return: 1 (true) if successful
"""
- bio = BIO.openfile(filename, 'wb')
- ret = self.save_key_bio(bio, cipher, callback)
- bio.close()
+ with BIO.openfile(filename, 'wb') as bio:
+ ret = self.save_key_bio(bio, cipher, callback)
+
return ret
- def save_key_bio(self, bio, cipher='aes_128_cbc',
+ def save_key_bio(self, bio, cipher='aes_128_cbc',
callback=util.passphrase_callback):
+ # type: (BIO.BIO, str, Callable) -> int
"""
Save DSA key pair to a BIO object.
-
- @type bio: M2Crypto.BIO object
- @param bio: Save DSA parameters to this object.
- @type cipher: str
- @param cipher: name of symmetric key algorithm and mode
+
+ :param bio: Save DSA parameters to this object.
+ :param cipher: name of symmetric key algorithm and mode
to encrypt the private key.
- @return: 1 (true) if successful
+ :return: 1 (true) if successful
"""
if cipher is None:
- return m2.dsa_write_key_bio_no_cipher(self.dsa,
- bio._ptr(), callback)
+ return m2.dsa_write_key_bio_no_cipher(self.dsa,
+ bio._ptr(), callback)
else:
ciph = getattr(m2, cipher, None)
if ciph is None:
@@ -171,58 +187,54 @@ class DSA:
return m2.dsa_write_key_bio(self.dsa, bio._ptr(), ciph, callback)
def save_pub_key(self, filename):
+ # type: (AnyStr) -> int
"""
Save the DSA public key (with parameters) to a file.
-
- @type filename: str
- @param filename: Save DSA public key (with parameters)
+
+ :param filename: Save DSA public key (with parameters)
to this file.
- @return: 1 (true) if successful
+ :return: 1 (true) if successful
"""
- bio = BIO.openfile(filename, 'wb')
- ret = self.save_pub_key_bio(bio)
- bio.close()
+ with BIO.openfile(filename, 'wb') as bio:
+ ret = self.save_pub_key_bio(bio)
+
return ret
def save_pub_key_bio(self, bio):
+ # type: (BIO.BIO) -> int
"""
Save DSA public key (with parameters) to a BIO object.
-
- @type bio: M2Crypto.BIO object
- @param bio: Save DSA public key (with parameters)
+
+ :param bio: Save DSA public key (with parameters)
to this object.
- @return: 1 (true) if successful
+ :return: 1 (true) if successful
"""
return m2.dsa_write_pub_key_bio(self.dsa, bio._ptr())
def sign(self, digest):
+ # type: (bytes) -> Tuple[bytes, bytes]
"""
Sign the digest.
-
- @type digest: str
- @param digest: SHA-1 hash of message (same as output
+
+ :param digest: SHA-1 hash of message (same as output
from MessageDigest, a "byte string")
- @rtype: tuple
- @return: DSA signature, a tuple of two values, r and s,
+ :return: DSA signature, a tuple of two values, r and s,
both "byte strings".
"""
assert self.check_key(), 'key is not initialised'
return m2.dsa_sign(self.dsa, digest)
-
+
def verify(self, digest, r, s):
+ # type: (bytes, bytes, bytes) -> int
"""
- Verify a newly calculated digest against the signature
+ Verify a newly calculated digest against the signature
values r and s.
-
- @type digest: str
- @param digest: SHA-1 hash of message (same as output
+
+ :param digest: SHA-1 hash of message (same as output
from MessageDigest, a "byte string")
- @type r: str
- @param r: r value of the signature, a "byte string"
- @type s: str
- @param s: s value of the signature, a "byte string"
- @rtype: int
- @return: 1 (true) if verify succeeded, 0 if failed
+ :param r: r value of the signature, a "byte string"
+ :param s: s value of the signature, a "byte string"
+ :return: 1 (true) if verify succeeded, 0 if failed
"""
assert self.check_key(), 'key is not initialised'
return m2.dsa_verify(self.dsa, digest, r, s)
@@ -230,7 +242,7 @@ class DSA:
def sign_asn1(self, digest):
assert self.check_key(), 'key is not initialised'
return m2.dsa_sign_asn1(self.dsa, digest)
-
+
def verify_asn1(self, digest, blob):
assert self.check_key(), 'key is not initialised'
return m2.dsa_verify_asn1(self.dsa, digest, blob)
@@ -238,202 +250,199 @@ class DSA:
def check_key(self):
"""
Check to be sure the DSA object has a valid private key.
-
- @rtype: int
- @return: 1 (true) if a valid private key
+
+ :return: 1 (true) if a valid private key
"""
assert m2.dsa_type_check(self.dsa), "'dsa' type error"
return m2.dsa_check_key(self.dsa)
-
class DSA_pub(DSA):
"""
- This class is a DSA context that only supports a public key
- and verification. It does NOT support a private key or
+ This class is a DSA context that only supports a public key
+ and verification. It does NOT support a private key or
signing.
-
+
"""
def sign(self, *argv):
+ # type: (*Any) -> None
raise DSAError('DSA_pub object has no private key')
sign_asn1 = sign
def check_key(self):
+ # type: () -> int
+ """
+ :return: does DSA_pub contain a pub key?
+ """
return m2.dsa_check_pub_key(self.dsa)
-
+
save_key = DSA.save_pub_key
save_key_bio = DSA.save_pub_key_bio
-#---------------------------------------------------------------
-# factories and other functions
+# --------------------------------------------------------------
+# factories and other functions
+
def gen_params(bits, callback=util.genparam_callback):
+ # type: (int, Callable) -> DSA
"""
- Factory function that generates DSA parameters and
+ Factory function that generates DSA parameters and
instantiates a DSA object from the output.
- @type bits: int
- @param bits: The length of the prime to be generated. If
+ :param bits: The length of the prime to be generated. If
'bits' < 512, it is set to 512.
- @type callback: function
- @param callback: A Python callback object that will be
- invoked during parameter generation; it usual
+ :param callback: A Python callback object that will be
+ invoked during parameter generation; it usual
purpose is to provide visual feedback.
- @rtype: DSA
- @return: instance of DSA.
+ :return: instance of DSA.
"""
dsa = m2.dsa_generate_parameters(bits, callback)
- if dsa is None:
- raise DSAError('problem generating DSA parameters')
return DSA(dsa, 1)
+
def set_params(p, q, g):
+ # type: (bytes, bytes, bytes) -> DSA
"""
Factory function that instantiates a DSA object with DSA
parameters.
- @type p: str
- @param p: value of p, a "byte string"
- @type q: str
- @param q: value of q, a "byte string"
- @type g: str
- @param g: value of g, a "byte string"
- @rtype: DSA
- @return: instance of DSA.
+ :param p: value of p, a "byte string"
+ :param q: value of q, a "byte string"
+ :param g: value of g, a "byte string"
+ :return: instance of DSA.
"""
dsa = m2.dsa_new()
- m2.dsa_set_p(dsa, p)
- m2.dsa_set_q(dsa, q)
- m2.dsa_set_g(dsa, g)
+ m2.dsa_set_pqg(dsa, p, q, g)
return DSA(dsa, 1)
+
def load_params(file, callback=util.passphrase_callback):
+ # type: (AnyStr, Callable) -> DSA
"""
- Factory function that instantiates a DSA object with DSA
+ Factory function that instantiates a DSA object with DSA
parameters from a file.
- @type file: str
- @param file: Names the file (a path) that contains the PEM
- representation of the DSA parameters.
- @type callback: A Python callable
- @param callback: A Python callback object that will be
- invoked if the DSA parameters file is
+ :param file: Names the file (a path) that contains the PEM
+ representation of the DSA parameters.
+ :param callback: A Python callback object that will be
+ invoked if the DSA parameters file is
passphrase-protected.
- @rtype: DSA
- @return: instance of DSA.
+ :return: instance of DSA.
"""
- bio = BIO.openfile(file)
- ret = load_params_bio(bio, callback)
- bio.close()
+ with BIO.openfile(file) as bio:
+ ret = load_params_bio(bio, callback)
+
return ret
def load_params_bio(bio, callback=util.passphrase_callback):
+ # type: (BIO.BIO, Callable) -> DSA
"""
Factory function that instantiates a DSA object with DSA
parameters from a M2Crypto.BIO object.
- @type bio: M2Crypto.BIO object
- @param bio: Contains the PEM representation of the DSA
- parameters.
- @type callback: A Python callable
- @param callback: A Python callback object that will be
- invoked if the DSA parameters file is
+ :param bio: Contains the PEM representation of the DSA
+ parameters.
+ :param callback: A Python callback object that will be
+ invoked if the DSA parameters file is
passphrase-protected.
- @rtype: DSA
- @return: instance of DSA.
+ :return: instance of DSA.
"""
dsa = m2.dsa_read_params(bio._ptr(), callback)
- if dsa is None:
- raise DSAError('problem loading DSA parameters')
return DSA(dsa, 1)
def load_key(file, callback=util.passphrase_callback):
+ # type: (AnyStr, Callable) -> DSA
"""
Factory function that instantiates a DSA object from a
PEM encoded DSA key pair.
- @type file: str
- @param file: Names the file (a path) that contains the PEM
- representation of the DSA key pair.
- @type callback: A Python callable
- @param callback: A Python callback object that will be
- invoked if the DSA key pair is
+ :param file: Names the file (a path) that contains the PEM
+ representation of the DSA key pair.
+ :param callback: A Python callback object that will be
+ invoked if the DSA key pair is
passphrase-protected.
- @rtype: DSA
- @return: instance of DSA.
+ :return: instance of DSA.
"""
- bio = BIO.openfile(file)
- ret = load_key_bio(bio, callback)
- bio.close()
+ with BIO.openfile(file) as bio:
+ ret = load_key_bio(bio, callback)
+
return ret
def load_key_bio(bio, callback=util.passphrase_callback):
+ # type: (BIO.BIO, Callable) -> DSA
"""
Factory function that instantiates a DSA object from a
PEM encoded DSA key pair.
- @type bio: M2Crypto.BIO object
- @param bio: Contains the PEM representation of the DSA
- key pair.
- @type callback: A Python callable
- @param callback: A Python callback object that will be
- invoked if the DSA key pair is
+ :param bio: Contains the PEM representation of the DSA
+ key pair.
+ :param callback: A Python callback object that will be
+ invoked if the DSA key pair is
passphrase-protected.
- @rtype: DSA
- @return: instance of DSA.
+ :return: instance of DSA.
"""
dsa = m2.dsa_read_key(bio._ptr(), callback)
- if not dsa:
- raise DSAError('problem loading DSA key pair')
return DSA(dsa, 1)
+def pub_key_from_params(p, q, g, pub):
+ # type: (bytes, bytes, bytes, bytes) -> DSA_pub
+ """
+ Factory function that instantiates a DSA_pub object using
+ the parameters and public key specified.
+
+ :param p: value of p
+ :param q: value of q
+ :param g: value of g
+ :param pub: value of the public key
+ :return: instance of DSA_pub.
+ """
+ dsa = m2.dsa_new()
+ m2.dsa_set_pqg(dsa, p, q, g)
+ m2.dsa_set_pub(dsa, pub)
+ return DSA_pub(dsa, 1)
+
+
def load_pub_key(file, callback=util.passphrase_callback):
+ # type: (AnyStr, Callable) -> DSA_pub
"""
Factory function that instantiates a DSA_pub object using
- a DSA public key contained in PEM file. The PEM file
+ a DSA public key contained in PEM file. The PEM file
must contain the parameters in addition to the public key.
- @type file: str
- @param file: Names the file (a path) that contains the PEM
- representation of the DSA public key.
- @type callback: A Python callable
- @param callback: A Python callback object that will be
- invoked should the DSA public key be
+ :param file: Names the file (a path) that contains the PEM
+ representation of the DSA public key.
+ :param callback: A Python callback object that will be
+ invoked should the DSA public key be
passphrase-protected.
- @rtype: DSA_pub
- @return: instance of DSA_pub.
+ :return: instance of DSA_pub.
"""
- bio = BIO.openfile(file)
- ret = load_pub_key_bio(bio, callback)
- bio.close()
+ with BIO.openfile(file) as bio:
+ ret = load_pub_key_bio(bio, callback)
+
return ret
def load_pub_key_bio(bio, callback=util.passphrase_callback):
+ # type: (BIO.BIO, Callable) -> DSA_pub
"""
Factory function that instantiates a DSA_pub object using
- a DSA public key contained in PEM format. The PEM
+ a DSA public key contained in PEM format. The PEM
must contain the parameters in addition to the public key.
- @type bio: M2Crypto.BIO object
- @param bio: Contains the PEM representation of the DSA
- public key (with params).
- @type callback: A Python callable
- @param callback: A Python callback object that will be
- invoked should the DSA public key be
+ :param bio: Contains the PEM representation of the DSA
+ public key (with params).
+ :param callback: A Python callback object that will be
+ invoked should the DSA public key be
passphrase-protected.
- @rtype: DSA_pub
- @return: instance of DSA_pub.
+ :return: instance of DSA_pub.
"""
dsapub = m2.dsa_read_pub_key(bio._ptr(), callback)
- if not dsapub:
- raise DSAError('problem loading DSA public key')
return DSA_pub(dsapub, 1)
diff --git a/M2Crypto/EC.py b/M2Crypto/EC.py
index b1ed43e..b730334 100644
--- a/M2Crypto/EC.py
+++ b/M2Crypto/EC.py
@@ -1,3 +1,5 @@
+from __future__ import absolute_import
+
"""
M2Crypto wrapper for OpenSSL ECDH/ECDSA API.
@@ -5,139 +7,180 @@ M2Crypto wrapper for OpenSSL ECDH/ECDSA API.
Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved.
-Portions copyright (c) 2005-2006 Vrije Universiteit Amsterdam.
+Portions copyright (c) 2005-2006 Vrije Universiteit Amsterdam.
All rights reserved."""
-import util, BIO, m2
+from M2Crypto import BIO, Err, EVP, m2, util
+if util.py27plus:
+ from typing import AnyStr, Callable, Dict, Optional, Tuple, Union # noqa
+
+EC_Key = bytes
+
-class ECError(Exception): pass
+class ECError(Exception):
+ pass
m2.ec_init(ECError)
# Curve identifier constants
-NID_secp112r1 = m2.NID_secp112r1
-NID_secp112r2 = m2.NID_secp112r2
-NID_secp128r1 = m2.NID_secp128r1
-NID_secp128r2 = m2.NID_secp128r2
-NID_secp160k1 = m2.NID_secp160k1
-NID_secp160r1 = m2.NID_secp160r1
-NID_secp160r2 = m2.NID_secp160r2
-NID_secp192k1 = m2.NID_secp192k1
-NID_secp224k1 = m2.NID_secp224k1
-NID_secp224r1 = m2.NID_secp224r1
-NID_secp256k1 = m2.NID_secp256k1
-NID_secp384r1 = m2.NID_secp384r1
-NID_secp521r1 = m2.NID_secp521r1
-NID_sect113r1 = m2.NID_sect113r1
-NID_sect113r2 = m2.NID_sect113r2
-NID_sect131r1 = m2.NID_sect131r1
-NID_sect131r2 = m2.NID_sect131r2
-NID_sect163k1 = m2.NID_sect163k1
-NID_sect163r1 = m2.NID_sect163r1
-NID_sect163r2 = m2.NID_sect163r2
-NID_sect193r1 = m2.NID_sect193r1
-NID_sect193r2 = m2.NID_sect193r2
-NID_sect233k1 = m2.NID_sect233k1 # default for secg.org TLS test server
-NID_sect233r1 = m2.NID_sect233r1
-NID_sect239k1 = m2.NID_sect239k1
-NID_sect283k1 = m2.NID_sect283k1
-NID_sect283r1 = m2.NID_sect283r1
-NID_sect409k1 = m2.NID_sect409k1
-NID_sect409r1 = m2.NID_sect409r1
-NID_sect571k1 = m2.NID_sect571k1
-NID_sect571r1 = m2.NID_sect571r1
-
-NID_X9_62_prime192v1 = m2.NID_X9_62_prime192v1
-NID_X9_62_prime192v2 = m2.NID_X9_62_prime192v2
-NID_X9_62_prime192v3 = m2.NID_X9_62_prime192v3
-NID_X9_62_prime239v1 = m2.NID_X9_62_prime239v1
-NID_X9_62_prime239v2 = m2.NID_X9_62_prime239v2
-NID_X9_62_prime239v3 = m2.NID_X9_62_prime239v3
-NID_X9_62_prime256v1 = m2.NID_X9_62_prime256v1
-NID_X9_62_c2pnb163v1 = m2.NID_X9_62_c2pnb163v1
-NID_X9_62_c2pnb163v2 = m2.NID_X9_62_c2pnb163v2
-NID_X9_62_c2pnb163v3 = m2.NID_X9_62_c2pnb163v3
-NID_X9_62_c2pnb176v1 = m2.NID_X9_62_c2pnb176v1
-NID_X9_62_c2tnb191v1 = m2.NID_X9_62_c2tnb191v1
-NID_X9_62_c2tnb191v2 = m2.NID_X9_62_c2tnb191v2
-NID_X9_62_c2tnb191v3 = m2.NID_X9_62_c2tnb191v3
-NID_X9_62_c2pnb208w1 = m2.NID_X9_62_c2pnb208w1
-NID_X9_62_c2tnb239v1 = m2.NID_X9_62_c2tnb239v1
-NID_X9_62_c2tnb239v2 = m2.NID_X9_62_c2tnb239v2
-NID_X9_62_c2tnb239v3 = m2.NID_X9_62_c2tnb239v3
-NID_X9_62_c2pnb272w1 = m2.NID_X9_62_c2pnb272w1
-NID_X9_62_c2pnb304w1 = m2.NID_X9_62_c2pnb304w1
-NID_X9_62_c2tnb359v1 = m2.NID_X9_62_c2tnb359v1
-NID_X9_62_c2pnb368w1 = m2.NID_X9_62_c2pnb368w1
-NID_X9_62_c2tnb431r1 = m2.NID_X9_62_c2tnb431r1
-
-NID_wap_wsg_idm_ecid_wtls1 = m2.NID_wap_wsg_idm_ecid_wtls1
-NID_wap_wsg_idm_ecid_wtls3 = m2.NID_wap_wsg_idm_ecid_wtls3
-NID_wap_wsg_idm_ecid_wtls4 = m2.NID_wap_wsg_idm_ecid_wtls4
-NID_wap_wsg_idm_ecid_wtls5 = m2.NID_wap_wsg_idm_ecid_wtls5
-NID_wap_wsg_idm_ecid_wtls6 = m2.NID_wap_wsg_idm_ecid_wtls6
-NID_wap_wsg_idm_ecid_wtls7 = m2.NID_wap_wsg_idm_ecid_wtls7
-NID_wap_wsg_idm_ecid_wtls8 = m2.NID_wap_wsg_idm_ecid_wtls8
-NID_wap_wsg_idm_ecid_wtls9 = m2.NID_wap_wsg_idm_ecid_wtls9
-NID_wap_wsg_idm_ecid_wtls10 = m2.NID_wap_wsg_idm_ecid_wtls10
-NID_wap_wsg_idm_ecid_wtls11 = m2.NID_wap_wsg_idm_ecid_wtls11
-NID_wap_wsg_idm_ecid_wtls12 = m2.NID_wap_wsg_idm_ecid_wtls12
-
-# The following two curves, according to OpenSSL, have a
-# "Questionable extension field!" and are not supported by
+NID_secp112r1 = m2.NID_secp112r1 # type: int
+NID_secp112r2 = m2.NID_secp112r2 # type: int
+NID_secp128r1 = m2.NID_secp128r1 # type: int
+NID_secp128r2 = m2.NID_secp128r2 # type: int
+NID_secp160k1 = m2.NID_secp160k1 # type: int
+NID_secp160r1 = m2.NID_secp160r1 # type: int
+NID_secp160r2 = m2.NID_secp160r2 # type: int
+NID_secp192k1 = m2.NID_secp192k1 # type: int
+NID_secp224k1 = m2.NID_secp224k1 # type: int
+NID_secp224r1 = m2.NID_secp224r1 # type: int
+NID_secp256k1 = m2.NID_secp256k1 # type: int
+NID_secp384r1 = m2.NID_secp384r1 # type: int
+NID_secp521r1 = m2.NID_secp521r1 # type: int
+NID_sect113r1 = m2.NID_sect113r1 # type: int
+NID_sect113r2 = m2.NID_sect113r2 # type: int
+NID_sect131r1 = m2.NID_sect131r1 # type: int
+NID_sect131r2 = m2.NID_sect131r2 # type: int
+NID_sect163k1 = m2.NID_sect163k1 # type: int
+NID_sect163r1 = m2.NID_sect163r1 # type: int
+NID_sect163r2 = m2.NID_sect163r2 # type: int
+NID_sect193r1 = m2.NID_sect193r1 # type: int
+NID_sect193r2 = m2.NID_sect193r2 # type: int
+# default for secg.org TLS test server
+NID_sect233k1 = m2.NID_sect233k1 # type: int
+NID_sect233r1 = m2.NID_sect233r1 # type: int
+NID_sect239k1 = m2.NID_sect239k1 # type: int
+NID_sect283k1 = m2.NID_sect283k1 # type: int
+NID_sect283r1 = m2.NID_sect283r1 # type: int
+NID_sect409k1 = m2.NID_sect409k1 # type: int
+NID_sect409r1 = m2.NID_sect409r1 # type: int
+NID_sect571k1 = m2.NID_sect571k1 # type: int
+NID_sect571r1 = m2.NID_sect571r1 # type: int
+
+NID_prime192v1 = m2.NID_X9_62_prime192v1 # type: int
+NID_prime192v2 = m2.NID_X9_62_prime192v2 # type: int
+NID_prime192v3 = m2.NID_X9_62_prime192v3 # type: int
+NID_prime239v1 = m2.NID_X9_62_prime239v1 # type: int
+NID_prime239v2 = m2.NID_X9_62_prime239v2 # type: int
+NID_prime239v3 = m2.NID_X9_62_prime239v3 # type: int
+NID_prime256v1 = m2.NID_X9_62_prime256v1 # type: int
+NID_c2pnb163v1 = m2.NID_X9_62_c2pnb163v1 # type: int
+NID_c2pnb163v2 = m2.NID_X9_62_c2pnb163v2 # type: int
+NID_c2pnb163v3 = m2.NID_X9_62_c2pnb163v3 # type: int
+NID_c2pnb176v1 = m2.NID_X9_62_c2pnb176v1 # type: int
+NID_c2tnb191v1 = m2.NID_X9_62_c2tnb191v1 # type: int
+NID_c2tnb191v2 = m2.NID_X9_62_c2tnb191v2 # type: int
+NID_c2tnb191v3 = m2.NID_X9_62_c2tnb191v3 # type: int
+NID_c2pnb208w1 = m2.NID_X9_62_c2pnb208w1 # type: int
+NID_c2tnb239v1 = m2.NID_X9_62_c2tnb239v1 # type: int
+NID_c2tnb239v2 = m2.NID_X9_62_c2tnb239v2 # type: int
+NID_c2tnb239v3 = m2.NID_X9_62_c2tnb239v3 # type: int
+NID_c2pnb272w1 = m2.NID_X9_62_c2pnb272w1 # type: int
+NID_c2pnb304w1 = m2.NID_X9_62_c2pnb304w1 # type: int
+NID_c2tnb359v1 = m2.NID_X9_62_c2tnb359v1 # type: int
+NID_c2pnb368w1 = m2.NID_X9_62_c2pnb368w1 # type: int
+NID_c2tnb431r1 = m2.NID_X9_62_c2tnb431r1 # type: int
+
+# To preserve compatibility with older names
+NID_X9_62_prime192v1 = NID_prime192v1 # type: int
+NID_X9_62_prime192v2 = NID_prime192v2 # type: int
+NID_X9_62_prime192v3 = NID_prime192v3 # type: int
+NID_X9_62_prime239v1 = NID_prime239v1 # type: int
+NID_X9_62_prime239v2 = NID_prime239v2 # type: int
+NID_X9_62_prime239v3 = NID_prime239v3 # type: int
+NID_X9_62_prime256v1 = NID_prime256v1 # type: int
+NID_X9_62_c2pnb163v1 = NID_c2pnb163v1 # type: int
+NID_X9_62_c2pnb163v2 = NID_c2pnb163v2 # type: int
+NID_X9_62_c2pnb163v3 = NID_c2pnb163v3 # type: int
+NID_X9_62_c2pnb176v1 = NID_c2pnb176v1 # type: int
+NID_X9_62_c2tnb191v1 = NID_c2tnb191v1 # type: int
+NID_X9_62_c2tnb191v2 = NID_c2tnb191v2 # type: int
+NID_X9_62_c2tnb191v3 = NID_c2tnb191v3 # type: int
+NID_X9_62_c2pnb208w1 = NID_c2pnb208w1 # type: int
+NID_X9_62_c2tnb239v1 = NID_c2tnb239v1 # type: int
+NID_X9_62_c2tnb239v2 = NID_c2tnb239v2 # type: int
+NID_X9_62_c2tnb239v3 = NID_c2tnb239v3 # type: int
+NID_X9_62_c2pnb272w1 = NID_c2pnb272w1 # type: int
+NID_X9_62_c2pnb304w1 = NID_c2pnb304w1 # type: int
+NID_X9_62_c2tnb359v1 = NID_c2tnb359v1 # type: int
+NID_X9_62_c2pnb368w1 = NID_c2pnb368w1 # type: int
+NID_X9_62_c2tnb431r1 = NID_c2tnb431r1 # type: int
+
+NID_wap_wsg_idm_ecid_wtls1 = m2.NID_wap_wsg_idm_ecid_wtls1 # type: int
+NID_wap_wsg_idm_ecid_wtls3 = m2.NID_wap_wsg_idm_ecid_wtls3 # type: int
+NID_wap_wsg_idm_ecid_wtls4 = m2.NID_wap_wsg_idm_ecid_wtls4 # type: int
+NID_wap_wsg_idm_ecid_wtls5 = m2.NID_wap_wsg_idm_ecid_wtls5 # type: int
+NID_wap_wsg_idm_ecid_wtls6 = m2.NID_wap_wsg_idm_ecid_wtls6 # type: int
+NID_wap_wsg_idm_ecid_wtls7 = m2.NID_wap_wsg_idm_ecid_wtls7 # type: int
+NID_wap_wsg_idm_ecid_wtls8 = m2.NID_wap_wsg_idm_ecid_wtls8 # type: int
+NID_wap_wsg_idm_ecid_wtls9 = m2.NID_wap_wsg_idm_ecid_wtls9 # type: int
+NID_wap_wsg_idm_ecid_wtls10 = m2.NID_wap_wsg_idm_ecid_wtls10 # type: int
+NID_wap_wsg_idm_ecid_wtls11 = m2.NID_wap_wsg_idm_ecid_wtls11 # type: int
+NID_wap_wsg_idm_ecid_wtls12 = m2.NID_wap_wsg_idm_ecid_wtls12 # type: int
+
+# The following two curves, according to OpenSSL, have a
+# "Questionable extension field!" and are not supported by
# the OpenSSL inverse function. ECError: no inverse.
-# As such they cannot be used for signing. They might,
-# however, be usable for encryption but that has not
+# As such they cannot be used for signing. They might,
+# however, be usable for encryption but that has not
# been tested. Until thir usefulness can be established,
# they are not supported at this time.
# NID_ipsec3 = m2.NID_ipsec3
# NID_ipsec4 = m2.NID_ipsec4
-class EC:
+class EC(object):
"""
Object interface to a EC key pair.
"""
m2_ec_key_free = m2.ec_key_free
-
+
def __init__(self, ec, _pyfree=0):
+ # type: (EC, int) -> None
assert m2.ec_key_type_check(ec), "'ec' type error"
self.ec = ec
self._pyfree = _pyfree
def __del__(self):
+ # type: () -> None
if getattr(self, '_pyfree', 0):
self.m2_ec_key_free(self.ec)
def __len__(self):
+ # type: () -> int
assert m2.ec_key_type_check(self.ec), "'ec' type error"
return m2.ec_key_keylen(self.ec)
def gen_key(self):
+ # type: () -> int
"""
Generates the key pair from its parameters. Use::
+
keypair = EC.gen_params(curve)
keypair.gen_key()
+
to create an EC key pair.
"""
assert m2.ec_key_type_check(self.ec), "'ec' type error"
- m2.ec_key_gen_key(self.ec)
+ m2.ec_key_gen_key(self.ec)
def pub(self):
+ # type: () -> EC_pub
# Don't let python free
return EC_pub(self.ec, 0)
def sign_dsa(self, digest):
+ # type: (bytes) -> Tuple[bytes, bytes]
"""
Sign the given digest using ECDSA. Returns a tuple (r,s), the two
ECDSA signature parameters.
"""
assert self._check_key_type(), "'ec' type error"
return m2.ecdsa_sign(self.ec, digest)
-
+
def verify_dsa(self, digest, r, s):
+ # type: (bytes, bytes, bytes) -> int
"""
Verify the given digest using ECDSA. r and s are the ECDSA
signature parameters.
@@ -146,39 +189,41 @@ class EC:
return m2.ecdsa_verify(self.ec, digest, r, s)
def sign_dsa_asn1(self, digest):
+ # type: (bytes) -> bytes
assert self._check_key_type(), "'ec' type error"
return m2.ecdsa_sign_asn1(self.ec, digest)
-
+
def verify_dsa_asn1(self, digest, blob):
assert self._check_key_type(), "'ec' type error"
return m2.ecdsa_verify_asn1(self.ec, digest, blob)
- def compute_dh_key(self,pub_key):
+ def compute_dh_key(self, pub_key):
+ # type: (EC) -> Optional[bytes]
"""
- Compute the ECDH shared key of this key pair and the given public
- key object. They must both use the same curve. Returns the
- shared key in binary as a buffer object. No Key Derivation Function is
+ Compute the ECDH shared key of this key pair and the given public
+ key object. They must both use the same curve. Returns the
+ shared key in binary as a buffer object. No Key Derivation Function is
applied.
"""
assert self.check_key(), 'key is not initialised'
return m2.ecdh_compute_key(self.ec, pub_key.ec)
- def save_key_bio(self, bio, cipher='aes_128_cbc', callback=util.passphrase_callback):
+ def save_key_bio(self, bio, cipher='aes_128_cbc',
+ callback=util.passphrase_callback):
+ # type: (BIO.BIO, Optional[str], Callable) -> int
"""
Save the key pair to an M2Crypto.BIO.BIO object in PEM format.
- @type bio: M2Crypto.BIO.BIO
- @param bio: M2Crypto.BIO.BIO object to save key to.
+ :param bio: M2Crypto.BIO.BIO object to save key to.
- @type cipher: string
- @param cipher: Symmetric cipher to protect the key. The default
- cipher is 'aes_128_cbc'. If cipher is None, then the key is saved
- in the clear.
+ :param cipher: Symmetric cipher to protect the key. The default
+ cipher is 'aes_128_cbc'. If cipher is None, then
+ the key is saved in the clear.
- @type callback: Python callable
- @param callback: A Python callable object that is invoked
- to acquire a passphrase with which to protect the key.
- The default is util.passphrase_callback.
+ :param callback: A Python callable object that is invoked
+ to acquire a passphrase with which to protect
+ the key. The default is
+ util.passphrase_callback.
"""
if cipher is None:
return m2.ec_key_write_bio_no_cipher(self.ec, bio._ptr(), callback)
@@ -188,64 +233,78 @@ class EC:
raise ValueError('not such cipher %s' % cipher)
return m2.ec_key_write_bio(self.ec, bio._ptr(), ciph(), callback)
- def save_key(self, file, cipher='aes_128_cbc', callback=util.passphrase_callback):
+ def save_key(self, file, cipher='aes_128_cbc',
+ callback=util.passphrase_callback):
+ # type: (AnyStr, Optional[str], Callable) -> int
"""
Save the key pair to a file in PEM format.
- @type file: string
- @param file: Name of file to save key to.
+ :param file: Name of filename to save key to.
- @type cipher: string
- @param cipher: Symmetric cipher to protect the key. The default
- cipher is 'aes_128_cbc'. If cipher is None, then the key is saved
- in the clear.
+ :param cipher: Symmetric cipher to protect the key. The default
+ cipher is 'aes_128_cbc'. If cipher is None, then
+ the key is saved in the clear.
- @type callback: Python callable
- @param callback: A Python callable object that is invoked
- to acquire a passphrase with which to protect the key.
- The default is util.passphrase_callback.
+ :param callback: A Python callable object that is invoked
+ to acquire a passphrase with which to protect
+ the key. The default is
+ util.passphrase_callback.
"""
- bio = BIO.openfile(file, 'wb')
- return self.save_key_bio(bio, cipher, callback)
-
+ with BIO.openfile(file, 'wb') as bio:
+ return self.save_key_bio(bio, cipher, callback)
+
def save_pub_key_bio(self, bio):
+ # type: (BIO.BIO) -> int
"""
Save the public key to an M2Crypto.BIO.BIO object in PEM format.
- @type bio: M2Crypto.BIO.BIO
- @param bio: M2Crypto.BIO.BIO object to save key to.
- """
+ :param bio: M2Crypto.BIO.BIO object to save key to.
+ """
return m2.ec_key_write_pubkey(self.ec, bio._ptr())
def save_pub_key(self, file):
+ # type: (AnyStr) -> int
"""
- Save the public key to a file in PEM format.
+ Save the public key to a filename in PEM format.
- @type file: string
- @param file: Name of file to save key to.
+ :param file: Name of filename to save key to.
"""
- bio = BIO.openfile(file, 'wb')
- return m2.ec_key_write_pubkey(self.ec, bio._ptr())
-
+ with BIO.openfile(file, 'wb') as bio:
+ return m2.ec_key_write_pubkey(self.ec, bio._ptr())
+
+ def as_pem(self, cipher='aes_128_cbc', callback=util.passphrase_callback):
+ """
+ Returns the key(pair) as a string in PEM format.
+ If no password is passed and the cipher is set
+ it exits with error
+ """
+ with BIO.MemoryBuffer() as bio:
+ self.save_key_bio(bio, cipher, callback)
+ return bio.read()
+
def _check_key_type(self):
+ # type: () -> int
return m2.ec_key_type_check(self.ec)
def check_key(self):
+ # type: () -> int
assert m2.ec_key_type_check(self.ec), "'ec' type error"
return m2.ec_key_check_key(self.ec)
-
+
class EC_pub(EC):
"""
- Object interface to an EC public key.
+ Object interface to an EC public key.
((don't like this implementation inheritance))
"""
- def __init__(self,ec,_pyfree=0):
- EC.__init__(self,ec,_pyfree)
- self.der = None
+ def __init__(self, ec, _pyfree=0):
+ # type: (EC, int) -> None
+ EC.__init__(self, ec, _pyfree)
+ self.der = None # type: Optional[bytes]
def get_der(self):
+ # type: () -> bytes
"""
Returns the public key in DER format as a buffer object.
"""
@@ -254,82 +313,147 @@ class EC_pub(EC):
self.der = m2.ec_key_get_public_der(self.ec)
return self.der
+ def get_key(self):
+ # type: () -> bytes
+ """
+ Returns the public key as a byte string.
+ """
+ assert self.check_key(), 'key is not initialised'
+ return m2.ec_key_get_public_key(self.ec)
+
save_key = EC.save_pub_key
save_key_bio = EC.save_pub_key_bio
def gen_params(curve):
+ # type: (int) -> EC
"""
- Factory function that generates EC parameters and
+ Factory function that generates EC parameters and
instantiates a EC object from the output.
- @param curve: This is the OpenSSL nid of the curve to use.
+ :param curve: This is the OpenSSL nid of the curve to use.
"""
+ assert curve in [x['NID'] for x in m2.ec_get_builtin_curves()], \
+ 'Elliptic curve %s is not available on this system.' % \
+ m2.obj_nid2sn(curve)
return EC(m2.ec_key_new_by_curve_name(curve), 1)
def load_key(file, callback=util.passphrase_callback):
+ # type: (AnyStr, Callable) -> EC
"""
Factory function that instantiates a EC object.
- @param file: Names the file that contains the PEM representation
- of the EC key pair.
+ :param file: Names the filename that contains the PEM representation
+ of the EC key pair.
- @param callback: Python callback object that will be invoked
- if the EC key pair is passphrase-protected.
+ :param callback: Python callback object that will be invoked
+ if the EC key pair is passphrase-protected.
"""
- bio = BIO.openfile(file)
- return load_key_bio(bio, callback)
+ with BIO.openfile(file) as bio:
+ return load_key_bio(bio, callback)
+
+
+def load_key_string(string, callback=util.passphrase_callback):
+ # type: (str, Callable) -> EC
+ """
+ Load an EC key pair from a string.
+
+ :param string: String containing EC key pair in PEM format.
+
+ :param callback: A Python callable object that is invoked
+ to acquire a passphrase with which to unlock the
+ key. The default is util.passphrase_callback.
+
+ :return: M2Crypto.EC.EC object.
+ """
+ with BIO.MemoryBuffer(string) as bio:
+ return load_key_bio(bio, callback)
def load_key_bio(bio, callback=util.passphrase_callback):
+ # type: (BIO.BIO, Callable) -> EC
"""
Factory function that instantiates a EC object.
- @param bio: M2Crypto.BIO object that contains the PEM
- representation of the EC key pair.
+ :param bio: M2Crypto.BIO object that contains the PEM
+ representation of the EC key pair.
- @param callback: Python callback object that will be invoked
- if the EC key pair is passphrase-protected.
+ :param callback: Python callback object that will be invoked
+ if the EC key pair is passphrase-protected.
"""
return EC(m2.ec_key_read_bio(bio._ptr(), callback), 1)
+
def load_pub_key(file):
+ # type: (AnyStr) -> EC_pub
+ """
+ Load an EC public key from filename.
+
+ :param file: Name of filename containing EC public key in PEM
+ format.
+
+ :return: M2Crypto.EC.EC_pub object.
+ """
+ with BIO.openfile(file) as bio:
+ return load_pub_key_bio(bio)
+
+
+def load_key_string_pubkey(string, callback=util.passphrase_callback):
+ # type: (str, Callable) -> PKey
"""
- Load an EC public key from file.
+ Load an M2Crypto.EC.PKey from a public key as a string.
+
+ :param string: String containing the key in PEM format.
- @type file: string
- @param file: Name of file containing EC public key in PEM format.
+ :param callback: A Python callable object that is invoked
+ to acquire a passphrase with which to protect the
+ key.
- @rtype: M2Crypto.EC.EC_pub
- @return: M2Crypto.EC.EC_pub object.
+ :return: M2Crypto.EC.PKey object.
"""
- bio = BIO.openfile(file)
- return load_pub_key_bio(bio)
+ with BIO.MemoryBuffer(string) as bio:
+ return EVP.load_key_bio_pubkey(bio, callback)
def load_pub_key_bio(bio):
+ # type: (BIO.BIO) -> EC_pub
"""
Load an EC public key from an M2Crypto.BIO.BIO object.
- @type bio: M2Crypto.BIO.BIO
- @param bio: M2Crypto.BIO.BIO object containing EC public key in PEM
- format.
+ :param bio: M2Crypto.BIO.BIO object containing EC public key in PEM
+ format.
- @rtype: M2Crypto.EC.EC_pub
- @return: M2Crypto.EC.EC_pub object.
- """
+ :return: M2Crypto.EC.EC_pub object.
+ """
ec = m2.ec_key_read_pubkey(bio._ptr())
if ec is None:
ec_error()
return EC_pub(ec, 1)
+
def ec_error():
- raise ECError, m2.err_reason_error_string(m2.err_get_error())
+ # type: () -> ECError
+ raise ECError(Err.get_error_message())
+
def pub_key_from_der(der):
+ # type: (bytes) -> EC_pub
"""
Create EC_pub from DER.
"""
return EC_pub(m2.ec_key_from_pubkey_der(der), 1)
+
+
+def pub_key_from_params(curve, bytes):
+ # type: (bytes, bytes) -> EC_pub
+ """
+ Create EC_pub from curve name and octet string.
+ """
+ return EC_pub(m2.ec_key_from_pubkey_params(curve, bytes), 1)
+
+
+def get_builtin_curves():
+ # type: () -> Tuple[Dict[str, Union[int, str]]]
+ return m2.ec_get_builtin_curves()
diff --git a/M2Crypto/EVP.py b/M2Crypto/EVP.py
index cb92380..b21dec6 100644
--- a/M2Crypto/EVP.py
+++ b/M2Crypto/EVP.py
@@ -1,3 +1,5 @@
+from __future__ import absolute_import
+
"""M2Crypto wrapper for OpenSSL EVP API.
Copyright (c) 1999-2004 Ng Pheng Siong. All rights reserved.
@@ -6,54 +8,62 @@ Portions Copyright (c) 2004-2007 Open Source Applications Foundation.
Author: Heikki Toivonen
"""
-from M2Crypto import Err, util, BIO, RSA
-import m2
+import logging
+from M2Crypto import BIO, Err, RSA, m2, util
+if util.py27plus:
+ from typing import AnyStr, Optional, Callable # noqa
+
+log = logging.getLogger('EVP')
-class EVPError(Exception): pass
+class EVPError(ValueError):
+ pass
m2.evp_init(EVPError)
def pbkdf2(password, salt, iter, keylen):
+ # type: (bytes, bytes, int, int) -> bytes
"""
Derive a key from password using PBKDF2 algorithm specified in RFC 2898.
-
- @param password: Derive the key from this password.
- @type password: str
- @param salt: Salt.
- @type salt: str
- @param iter: Number of iterations to perform.
- @type iter: int
- @param keylen: Length of key to produce.
- @type keylen: int
- @return: Key.
- @rtype: str
+
+ :param password: Derive the key from this password.
+ :param salt: Salt.
+ :param iter: Number of iterations to perform.
+ :param keylen: Length of key to produce.
+ :return: Key.
"""
return m2.pkcs5_pbkdf2_hmac_sha1(password, salt, iter, keylen)
-class MessageDigest:
+
+class MessageDigest(object):
"""
Message Digest
"""
m2_md_ctx_free = m2.md_ctx_free
def __init__(self, algo):
- md = getattr(m2, algo, None)
+ # type: (str) -> None
+ md = getattr(m2, algo, None) # type: Optional[Callable]
if md is None:
- raise ValueError, ('unknown algorithm', algo)
- self.md=md()
- self.ctx=m2.md_ctx_new()
+ # if the digest algorithm isn't found as an attribute of the m2
+ # module, try to look up the digest using get_digestbyname()
+ self.md = m2.get_digestbyname(algo)
+ else:
+ self.md = md()
+ self.ctx = m2.md_ctx_new()
m2.digest_init(self.ctx, self.md)
-
+
def __del__(self):
+ # type: () -> None
if getattr(self, 'ctx', None):
self.m2_md_ctx_free(self.ctx)
def update(self, data):
+ # type: (bytes) -> int
"""
Add data to be digested.
-
- @return: -1 for Python error, 1 for success, 0 for OpenSSL failure.
+
+ :return: -1 for Python error, 1 for success, 0 for OpenSSL failure.
"""
return m2.digest_update(self.ctx, data)
@@ -61,94 +71,112 @@ class MessageDigest:
return m2.digest_final(self.ctx)
# Deprecated.
- digest = final
+ digest = final
-class HMAC:
-
+class HMAC(object):
+
m2_hmac_ctx_free = m2.hmac_ctx_free
def __init__(self, key, algo='sha1'):
+ # type: (bytes, str) -> None
md = getattr(m2, algo, None)
if md is None:
- raise ValueError, ('unknown algorithm', algo)
- self.md=md()
- self.ctx=m2.hmac_ctx_new()
+ raise ValueError('unknown algorithm', algo)
+ self.md = md()
+ self.ctx = m2.hmac_ctx_new()
m2.hmac_init(self.ctx, key, self.md)
-
+
def __del__(self):
+ # type: () -> None
if getattr(self, 'ctx', None):
self.m2_hmac_ctx_free(self.ctx)
def reset(self, key):
+ # type: (bytes) -> None
m2.hmac_init(self.ctx, key, self.md)
def update(self, data):
+ # type: (bytes) -> None
m2.hmac_update(self.ctx, data)
def final(self):
+ # type: () -> bytes
return m2.hmac_final(self.ctx)
-
- digest=final
+
+ digest = final
+
def hmac(key, data, algo='sha1'):
+ # type: (bytes, bytes, str) -> bytes
md = getattr(m2, algo, None)
if md is None:
- raise ValueError, ('unknown algorithm', algo)
+ raise ValueError('unknown algorithm', algo)
return m2.hmac(key, data, md())
-class Cipher:
+class Cipher(object):
m2_cipher_ctx_free = m2.cipher_ctx_free
- def __init__(self, alg, key, iv, op, key_as_bytes=0, d='md5', salt='12345678', i=1, padding=1):
+ def __init__(self, alg, key, iv, op, key_as_bytes=0, d='md5',
+ salt=b'12345678', i=1, padding=1):
+ # type: (str, bytes, bytes, object, int, str, bytes, int, int) -> None
cipher = getattr(m2, alg, None)
if cipher is None:
- raise ValueError, ('unknown cipher', alg)
- self.cipher=cipher()
+ raise ValueError('unknown cipher', alg)
+ self.cipher = cipher()
if key_as_bytes:
kmd = getattr(m2, d, None)
if kmd is None:
- raise ValueError, ('unknown message digest', d)
+ raise ValueError('unknown message digest', d)
key = m2.bytes_to_key(self.cipher, kmd(), key, salt, iv, i)
- self.ctx=m2.cipher_ctx_new()
+ self.ctx = m2.cipher_ctx_new()
m2.cipher_init(self.ctx, self.cipher, key, iv, op)
self.set_padding(padding)
del key
-
+
def __del__(self):
- if getattr(self, 'ctx', None):
+ # type: () -> None
+ if getattr(self, 'ctx', None):
self.m2_cipher_ctx_free(self.ctx)
def update(self, data):
+ # type: (bytes) -> bytes
return m2.cipher_update(self.ctx, data)
def final(self):
+ # type: () -> bytes
return m2.cipher_final(self.ctx)
def set_padding(self, padding=1):
- return m2.cipher_set_padding(self.ctx, padding)
+ # type: (int) -> int
+ """
+ Actually always return 1
+ """
+ return m2.cipher_set_padding(self.ctx, padding)
-class PKey:
+class PKey(object):
"""
Public Key
"""
-
+
m2_pkey_free = m2.pkey_free
m2_md_ctx_free = m2.md_ctx_free
def __init__(self, pkey=None, _pyfree=0, md='sha1'):
+ # type: (Optional[bytes], int, str) -> None
if pkey is not None:
- self.pkey = pkey
+ self.pkey = pkey # type: bytes
self._pyfree = _pyfree
else:
self.pkey = m2.pkey_new()
self._pyfree = 1
self._set_context(md)
-
+
def __del__(self):
+ # type: () -> None
if getattr(self, '_pyfree', 0):
self.m2_pkey_free(self.pkey)
if getattr(self, 'ctx', None):
@@ -158,42 +186,44 @@ class PKey:
return self.pkey
def _set_context(self, md):
- mda = getattr(m2, md, None)
+ # type: (str) -> None
+ mda = getattr(m2, md, None) # type: Optional[Callable]
if mda is None:
- raise ValueError, ('unknown message digest', md)
+ raise ValueError('unknown message digest', md)
self.md = mda()
- self.ctx = m2.md_ctx_new()
+ self.ctx = m2.md_ctx_new() # type: Context
def reset_context(self, md='sha1'):
+ # type: (str) -> None
"""
Reset internal message digest context.
- @type md: string
- @param md: The message digest algorithm.
+ :param md: The message digest algorithm.
"""
self._set_context(md)
def sign_init(self):
+ # type: () -> None
"""
Initialise signing operation with self.
"""
m2.sign_init(self.ctx, self.md)
def sign_update(self, data):
+ # type: (bytes) -> None
"""
Feed data to signing operation.
- @type data: string
- @param data: Data to be signed.
+ :param data: Data to be signed.
"""
m2.sign_update(self.ctx, data)
def sign_final(self):
+ # type: () -> bytes
"""
Return signature.
- @rtype: string
- @return: The signature.
+ :return: The signature.
"""
return m2.sign_final(self.ctx, self.pkey)
@@ -202,46 +232,45 @@ class PKey:
final = sign_final
def verify_init(self):
+ # type: () -> None
"""
Initialise signature verification operation with self.
"""
m2.verify_init(self.ctx, self.md)
def verify_update(self, data):
+ # type: (bytes) -> int
"""
Feed data to verification operation.
- @type data: string
- @param data: Data to be verified.
- @return: -1 on Python error, 1 for success, 0 for OpenSSL error
+ :param data: Data to be verified.
+ :return: -1 on Python error, 1 for success, 0 for OpenSSL error
"""
return m2.verify_update(self.ctx, data)
def verify_final(self, sign):
+ # type: (bytes) -> int
"""
Return result of verification.
- @param sign: Signature to use for verification
- @rtype: int
- @return: Result of verification: 1 for success, 0 for failure, -1 on
+ :param sign: Signature to use for verification
+ :return: Result of verification: 1 for success, 0 for failure, -1 on
other error.
"""
return m2.verify_final(self.ctx, sign, self.pkey)
def assign_rsa(self, rsa, capture=1):
+ # type: (RSA.RSA, int) -> int
"""
Assign the RSA key pair to self.
- @type rsa: M2Crypto.RSA.RSA
- @param rsa: M2Crypto.RSA.RSA object to be assigned to self.
+ :param rsa: M2Crypto.RSA.RSA object to be assigned to self.
- @type capture: boolean
- @param capture: If true (default), this PKey object will own the RSA
+ :param capture: If true (default), this PKey object will own the RSA
object, meaning that once the PKey object gets
deleted it is no longer safe to use the RSA object.
-
- @rtype: int
- @return: Return 1 for success and 0 for failure.
+
+ :return: Return 1 for success and 0 for failure.
"""
if capture:
ret = m2.pkey_assign_rsa(self.pkey, rsa.rsa)
@@ -252,157 +281,187 @@ class PKey:
return ret
def get_rsa(self):
+ # type: () -> RSA.RSA_pub
"""
Return the underlying RSA key if that is what the EVP
instance is holding.
"""
rsa_ptr = m2.pkey_get1_rsa(self.pkey)
- if rsa_ptr is None:
- raise ValueError("PKey instance is not holding a RSA key")
-
+
rsa = RSA.RSA_pub(rsa_ptr, 1)
return rsa
- def save_key(self, file, cipher='aes_128_cbc', callback=util.passphrase_callback):
+ def save_key(self, file, cipher='aes_128_cbc',
+ callback=util.passphrase_callback):
+ # type: (AnyStr, Optional[str], Callable) -> int
"""
Save the key pair to a file in PEM format.
- @type file: string
- @param file: Name of file to save key to.
+ :param file: Name of file to save key to.
- @type cipher: string
- @param cipher: Symmetric cipher to protect the key. The default
- cipher is 'aes_128_cbc'. If cipher is None, then the key is saved
- in the clear.
+ :param cipher: Symmetric cipher to protect the key. The default
+ cipher is 'aes_128_cbc'. If cipher is None, then
+ the key is saved in the clear.
- @type callback: Python callable
- @param callback: A Python callable object that is invoked
- to acquire a passphrase with which to protect the key.
- The default is util.passphrase_callback.
+ :param callback: A Python callable object that is invoked
+ to acquire a passphrase with which to protect
+ the key. The default is
+ util.passphrase_callback.
"""
- bio = BIO.openfile(file, 'wb')
- return self.save_key_bio(bio, cipher, callback)
+ with BIO.openfile(file, 'wb') as bio:
+ return self.save_key_bio(bio, cipher, callback)
- def save_key_bio(self, bio, cipher='aes_128_cbc', callback=util.passphrase_callback):
+ def save_key_bio(self, bio, cipher='aes_128_cbc',
+ callback=util.passphrase_callback):
+ # type: (BIO.BIO, Optional[str], Callable) -> int
"""
Save the key pair to the M2Crypto.BIO object 'bio' in PEM format.
- @type bio: M2Crypto.BIO
- @param bio: M2Crypto.BIO object to save key to.
+ :param bio: M2Crypto.BIO object to save key to.
- @type cipher: string
- @param cipher: Symmetric cipher to protect the key. The default
- cipher is 'aes_128_cbc'. If cipher is None, then the key is saved
- in the clear.
+ :param cipher: Symmetric cipher to protect the key. The default
+ cipher is 'aes_128_cbc'. If cipher is None, then
+ the key is saved in the clear.
- @type callback: Python callable
- @param callback: A Python callable object that is invoked
- to acquire a passphrase with which to protect the key.
- The default is util.passphrase_callback.
+ :param callback: A Python callable object that is invoked
+ to acquire a passphrase with which to protect
+ the key. The default is
+ util.passphrase_callback.
"""
if cipher is None:
return m2.pkey_write_pem_no_cipher(self.pkey, bio._ptr(), callback)
else:
proto = getattr(m2, cipher, None)
if proto is None:
- raise ValueError, 'no such cipher %s' % cipher
+ raise ValueError('no such cipher %s' % cipher)
return m2.pkey_write_pem(self.pkey, bio._ptr(), proto(), callback)
def as_pem(self, cipher='aes_128_cbc', callback=util.passphrase_callback):
+ # type: (Optional[str], Callable) -> bytes
"""
Return key in PEM format in a string.
- @type cipher: string
- @param cipher: Symmetric cipher to protect the key. The default
- cipher is 'aes_128_cbc'. If cipher is None, then the key is saved
- in the clear.
+ :param cipher: Symmetric cipher to protect the key. The default
+ cipher is ``'aes_128_cbc'``. If cipher is None,
+ then the key is saved in the clear.
- @type callback: Python callable
- @param callback: A Python callable object that is invoked
- to acquire a passphrase with which to protect the key.
- The default is util.passphrase_callback.
+ :param callback: A Python callable object that is invoked
+ to acquire a passphrase with which to protect
+ the key. The default is
+ util.passphrase_callback.
"""
bio = BIO.MemoryBuffer()
self.save_key_bio(bio, cipher, callback)
return bio.read_all()
def as_der(self):
+ # type: () -> bytes
"""
Return key in DER format in a string
"""
buf = m2.pkey_as_der(self.pkey)
bio = BIO.MemoryBuffer(buf)
return bio.read_all()
-
+
def size(self):
+ # type: () -> int
"""
Return the size of the key in bytes.
"""
return m2.pkey_size(self.pkey)
-
+
def get_modulus(self):
+ # type: () -> Optional[bytes]
"""
Return the modulus in hex format.
"""
return m2.pkey_get_modulus(self.pkey)
-
+
def load_key(file, callback=util.passphrase_callback):
+ # type: (AnyStr, Callable) -> PKey
"""
Load an M2Crypto.EVP.PKey from file.
- @type file: string
- @param file: Name of file containing the key in PEM format.
+ :param file: Name of file containing the key in PEM format.
- @type callback: Python callable
- @param callback: A Python callable object that is invoked
- to acquire a passphrase with which to protect the key.
+ :param callback: A Python callable object that is invoked
+ to acquire a passphrase with which to protect the
+ key.
- @rtype: M2Crypto.EVP.PKey
- @return: M2Crypto.EVP.PKey object.
+ :return: M2Crypto.EVP.PKey object.
"""
- bio = m2.bio_new_file(file, 'r')
- if bio is None:
- raise BIO.BIOError(Err.get_error())
- cptr = m2.pkey_read_pem(bio, callback)
- m2.bio_free(bio)
- if cptr is None:
- raise EVPError(Err.get_error())
+ with BIO.openfile(file, 'r') as bio:
+ cptr = m2.pkey_read_pem(bio.bio, callback)
+
return PKey(cptr, 1)
+
def load_key_bio(bio, callback=util.passphrase_callback):
+ # type: (BIO.BIO, Callable) -> PKey
"""
Load an M2Crypto.EVP.PKey from an M2Crypto.BIO object.
- @type bio: M2Crypto.BIO
- @param bio: M2Crypto.BIO object containing the key in PEM format.
+ :param bio: M2Crypto.BIO object containing the key in PEM format.
- @type callback: Python callable
- @param callback: A Python callable object that is invoked
- to acquire a passphrase with which to protect the key.
+ :param callback: A Python callable object that is invoked
+ to acquire a passphrase with which to protect the
+ key.
- @rtype: M2Crypto.EVP.PKey
- @return: M2Crypto.EVP.PKey object.
+ :return: M2Crypto.EVP.PKey object.
"""
cptr = m2.pkey_read_pem(bio._ptr(), callback)
+ return PKey(cptr, 1)
+
+
+def load_key_bio_pubkey(bio, callback=util.passphrase_callback):
+ # type: (BIO.BIO, Callable) -> PKey
+ """
+ Load an M2Crypto.EVP.PKey from a public key as a M2Crypto.BIO object.
+
+ :param bio: M2Crypto.BIO object containing the key in PEM format.
+
+ :param callback: A Python callable object that is invoked
+ to acquire a passphrase with which to protect the
+ key.
+
+ :return: M2Crypto.EVP.PKey object.
+ """
+ cptr = m2.pkey_read_pem_pubkey(bio._ptr(), callback)
if cptr is None:
raise EVPError(Err.get_error())
return PKey(cptr, 1)
+
def load_key_string(string, callback=util.passphrase_callback):
+ # type: (AnyStr, Callable) -> PKey
"""
Load an M2Crypto.EVP.PKey from a string.
- @type string: string
- @param string: String containing the key in PEM format.
+ :param string: String containing the key in PEM format.
- @type callback: Python callable
- @param callback: A Python callable object that is invoked
- to acquire a passphrase with which to protect the key.
+ :param callback: A Python callable object that is invoked
+ to acquire a passphrase with which to protect the
+ key.
- @rtype: M2Crypto.EVP.PKey
- @return: M2Crypto.EVP.PKey object.
+ :return: M2Crypto.EVP.PKey object.
"""
bio = BIO.MemoryBuffer(string)
- return load_key_bio( bio, callback)
+ return load_key_bio(bio, callback)
+
+def load_key_string_pubkey(string, callback=util.passphrase_callback):
+ # type: (AnyStr, Callable) -> PKey
+ """
+ Load an M2Crypto.EVP.PKey from a public key as a string.
+
+ :param string: String containing the key in PEM format.
+
+ :param callback: A Python callable object that is invoked
+ to acquire a passphrase with which to protect the
+ key.
+
+ :return: M2Crypto.EVP.PKey object.
+ """
+ bio = BIO.MemoryBuffer(string)
+ return load_key_bio_pubkey(bio, callback)
diff --git a/M2Crypto/Engine.py b/M2Crypto/Engine.py
index d6b879b..fa79e46 100644
--- a/M2Crypto/Engine.py
+++ b/M2Crypto/Engine.py
@@ -1,4 +1,6 @@
# vim: sts=4 sw=4 et
+from __future__ import absolute_import
+
"""
M2Crypto wrapper for OpenSSL ENGINE API.
@@ -6,18 +8,24 @@ Pavel Shramov
IMEC MSU
"""
-from M2Crypto import m2, EVP, X509, Err
+from M2Crypto import EVP, Err, X509, m2, six, util
+if util.py27plus:
+ from typing import AnyStr, Callable, Optional # noqa
+
-class EngineError(Exception): pass
+class EngineError(Exception):
+ pass
m2.engine_init_error(EngineError)
-class Engine:
+
+class Engine(object):
"""Wrapper for ENGINE object."""
m2_engine_free = m2.engine_free
-
- def __init__(self, id = None, _ptr = None, _pyfree = 1):
+
+ def __init__(self, id=None, _ptr=None, _pyfree=1):
+ # type: (Optional[bytes], Optional[bytes], int) -> None
"""Create new Engine from ENGINE pointer or obtain by id"""
if not _ptr and not id:
raise ValueError("No engine id specified")
@@ -29,38 +37,52 @@ class Engine:
self._pyfree = _pyfree
def __del__(self):
+ # type: () -> None
if getattr(self, '_pyfree', 0):
self.m2_engine_free(self._ptr)
def init(self):
+ # type: () -> int
"""Obtain a functional reference to the engine.
-
- @return: 0 on error, non-zero on success."""
+
+ :return: 0 on error, non-zero on success."""
return m2.engine_init(self._ptr)
-
+
def finish(self):
+ # type: () -> int
"""Release a functional and structural reference to the engine."""
return m2.engine_finish(self._ptr)
- def ctrl_cmd_string(self, cmd, arg, optional = 0):
+ def ctrl_cmd_string(self, cmd, arg, optional=0):
+ # type: (AnyStr, Optional[AnyStr], int) -> None
"""Call ENGINE_ctrl_cmd_string"""
+ cmd = six.ensure_str(cmd)
+ if arg is not None:
+ arg = six.ensure_str(arg)
if not m2.engine_ctrl_cmd_string(self._ptr, cmd, arg, optional):
raise EngineError(Err.get_error())
def get_name(self):
+ # type: () -> bytes
"""Return engine name"""
return m2.engine_get_name(self._ptr)
def get_id(self):
+ # type: () -> bytes
"""Return engine id"""
return m2.engine_get_id(self._ptr)
- def set_default(self, methods = m2.ENGINE_METHOD_ALL):
- """Use this engine as default for methods specified in argument
- Possible values are bitwise OR of m2.ENGINE_METHOD_*"""
+ def set_default(self, methods=m2.ENGINE_METHOD_ALL):
+ # type: (int) -> int
+ """
+ Use this engine as default for methods specified in argument
+
+ :param methods: Possible values are bitwise OR of m2.ENGINE_METHOD_*
+ """
return m2.engine_set_default(self._ptr, methods)
- def _engine_load_key(self, func, name, pin = None):
+ def _engine_load_key(self, func, name, pin=None):
+ # type: (Callable, bytes, Optional[bytes]) -> EVP.PKey
"""Helper function for loading keys"""
ui = m2.ui_openssl()
cbd = m2.engine_pkcs11_data_new(pin)
@@ -68,52 +90,61 @@ class Engine:
kptr = func(self._ptr, name, ui, cbd)
if not kptr:
raise EngineError(Err.get_error())
- key = EVP.PKey(kptr, _pyfree = 1)
+ key = EVP.PKey(kptr, _pyfree=1)
finally:
m2.engine_pkcs11_data_free(cbd)
return key
- def load_private_key(self, name, pin = None):
+ def load_private_key(self, name, pin=None):
+ # type: (bytes, Optional[bytes]) -> X509.X509
"""Load private key with engine methods (e.g from smartcard).
If pin is not set it will be asked
"""
return self._engine_load_key(m2.engine_load_private_key, name, pin)
- def load_public_key(self, name, pin = None):
+ def load_public_key(self, name, pin=None):
+ # type: (bytes, Optional[bytes]) -> EVP.PKey
"""Load public key with engine methods (e.g from smartcard)."""
return self._engine_load_key(m2.engine_load_public_key, name, pin)
def load_certificate(self, name):
+ # type: (bytes) -> X509.X509
"""Load certificate from engine (e.g from smartcard).
NOTE: This function may be not implemented by engine!"""
cptr = m2.engine_load_certificate(self._ptr, name)
if not cptr:
raise EngineError("Certificate or card not found")
- return X509.X509(cptr, _pyfree = 1)
+ return X509.X509(cptr, _pyfree=1)
def load_dynamic_engine(id, sopath):
+ # type: (bytes, AnyStr) -> Engine
"""Load and return dymanic engine from sopath and assign id to it"""
+ if isinstance(sopath, six.text_type):
+ sopath = sopath.encode('utf8')
m2.engine_load_dynamic()
e = Engine('dynamic')
- e.ctrl_cmd_string("SO_PATH", sopath)
- e.ctrl_cmd_string("ID", id)
- e.ctrl_cmd_string("LIST_ADD", "1")
- e.ctrl_cmd_string("LOAD", None)
+ e.ctrl_cmd_string('SO_PATH', sopath)
+ e.ctrl_cmd_string('ID', id)
+ e.ctrl_cmd_string('LIST_ADD', '1')
+ e.ctrl_cmd_string('LOAD', None)
return e
def load_dynamic():
+ # type: () -> None
"""Load dynamic engine"""
m2.engine_load_dynamic()
def load_openssl():
+ # type: () -> None
"""Load openssl engine"""
m2.engine_load_openssl()
def cleanup():
+ # type: () -> None
"""If you load any engines, you need to clean up after your application
is finished with the engines."""
m2.engine_cleanup()
diff --git a/M2Crypto/Err.py b/M2Crypto/Err.py
index 3588f76..70974c9 100644
--- a/M2Crypto/Err.py
+++ b/M2Crypto/Err.py
@@ -1,49 +1,77 @@
+from __future__ import absolute_import
+
"""M2Crypto wrapper for OpenSSL Error API.
Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
-import BIO
-import m2
+from M2Crypto import BIO, m2, py27plus, util, six # noqa
+if py27plus:
+ from typing import Optional # noqa
+
def get_error():
- err=BIO.MemoryBuffer()
+ # type: () -> Optional[str]
+ err = BIO.MemoryBuffer()
m2.err_print_errors(err.bio_ptr())
- return err.getvalue()
+ err_msg = err.read()
+ if err_msg:
+ return six.ensure_text(err_msg)
+
def get_error_code():
+ # type: () -> int
return m2.err_get_error()
+
def peek_error_code():
+ # type: () -> int
return m2.err_peek_error()
+
def get_error_lib(err):
- return m2.err_lib_error_string(err)
+ # type: (Optional[int]) -> str
+ err_str = m2.err_lib_error_string(err)
+ return six.ensure_text(err_str) if err_str else ''
+
def get_error_func(err):
- return m2.err_func_error_string(err)
+ # type: (Optional[int]) -> str
+ err_str = m2.err_func_error_string(err)
+ return six.ensure_text(err_str) if err_str else ''
+
def get_error_reason(err):
- return m2.err_reason_error_string(err)
+ # type: (Optional[int]) -> str
+ err_str = m2.err_reason_error_string(err)
+ return six.ensure_text(err_str) if err_str else ''
+
+
+def get_error_message():
+ # type: () -> str
+ return six.ensure_text(get_error_reason(get_error_code()))
+
def get_x509_verify_error(err):
- return m2.x509_get_verify_error(err)
+ # type: (Optional[int]) -> str
+ err_str = m2.x509_get_verify_error(err)
+ return six.ensure_text(err_str) if err_str else ''
+
class SSLError(Exception):
def __init__(self, err, client_addr):
+ # type: (int, util.AddrType) -> None
self.err = err
self.client_addr = client_addr
def __str__(self):
- if (isinstance(self.client_addr, unicode)):
- s = self.client_addr.encode('utf8')
+ # type: () -> str
+ if not isinstance(self.client_addr, six.text_type):
+ s = self.client_addr.decode('utf8')
else:
s = self.client_addr
- return "%s: %s: %s" % \
- (m2.err_func_error_string(self.err), \
- s, \
- m2.err_reason_error_string(self.err))
+ return "%s: %s: %s" % (get_error_func(self.err), s,
+ get_error_reason(self.err))
+
class M2CryptoError(Exception):
pass
-
-
diff --git a/M2Crypto/PGP/PublicKey.py b/M2Crypto/PGP/PublicKey.py
deleted file mode 100644
index f892ade..0000000
--- a/M2Crypto/PGP/PublicKey.py
+++ /dev/null
@@ -1,58 +0,0 @@
-"""M2Crypto PGP2.
-
-Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
-
-from constants import *
-from packet import *
-import RSA
-
-class PublicKey:
- def __init__(self, pubkey_pkt):
- import warnings
- warnings.warn('Deprecated. No maintainer for PGP. If you use this, please inform M2Crypto maintainer.', DeprecationWarning)
-
- self._pubkey_pkt = pubkey_pkt
- self._pubkey = RSA.new_pub_key((pubkey_pkt._e, pubkey_pkt._n))
- self._userid = {}
- self._signature = {}
-
- def keyid(self):
- return self._pubkey.n[-8:]
-
- def add_userid(self, u_pkt):
- assert isinstance(u_pkt, userid_packet)
- self._userid[u_pkt.userid()] = u_pkt
-
- def remove_userid(self, userid):
- del self._userid[userid]
-
- def add_signature(self, userid, s_pkt):
- assert isinstance(s_pkt, signature_packet)
- assert self._userid.has_key(userid)
- if self._signature.has_key(userid):
- self._signature.append(s_pkt)
- else:
- self._signature = [s_pkt]
-
- def __getitem__(self, id):
- return self._userid[id]
-
- def __setitem__(self, *args):
- raise NotImplementedError
-
- def __delitem__(self, id):
- del self._userid[id]
- if self._signature[id]:
- del self._signature[id]
-
- def write(self, stream):
- pass
-
- def encrypt(self, ptxt):
- # XXX Munge ptxt into pgp format.
- return self._pubkey.public_encrypt(ptxt, RSA.pkcs1_padding)
-
- def decrypt(self, ctxt):
- # XXX Munge ctxt into pgp format.
- return self._pubkey.public_encrypt(ctxt, RSA.pkcs1_padding)
-
diff --git a/M2Crypto/PGP/PublicKeyRing.py b/M2Crypto/PGP/PublicKeyRing.py
deleted file mode 100644
index a8447b3..0000000
--- a/M2Crypto/PGP/PublicKeyRing.py
+++ /dev/null
@@ -1,81 +0,0 @@
-"""M2Crypto PGP2.
-
-Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
-
-from constants import *
-from packet import *
-from PublicKey import *
-
-class PublicKeyRing:
- def __init__(self, keyring):
- import warnings
- warnings.warn('Deprecated. No maintainer for PGP. If you use this, please inform M2Crypto maintainer.', DeprecationWarning)
-
- self._keyring = keyring
- self._userid = {}
- self._keyid = {}
- self._spurious = []
- self._pubkey = []
-
- def load(self):
- curr_pub = None
- curr_index = -1
-
- ps = packet_stream(self._keyring)
- while 1:
- pkt = ps.read()
-
- if pkt is None:
- break
-
- elif isinstance(pkt, public_key_packet):
- curr_index = curr_index + 1
- curr_pub = PublicKey(pkt)
- self._pubkey.append(curr_pub)
- #self._keyid[curr_pub.keyid()] = (curr_pub, curr_index)
-
- elif isinstance(pkt, userid_packet):
- if curr_pub is None:
- self._spurious.append(pkt)
- else:
- curr_pub.add_userid(pkt)
- self._userid[pkt.userid()] = (curr_pub, curr_index)
-
- elif isinstance(pkt, signature_packet):
- if curr_pub is None:
- self._spurious.append(pkt)
- else:
- curr_pub.add_signature(pkt)
-
- else:
- self._spurious.append(pkt)
-
- ps.close()
-
- def __getitem__(self, id):
- return self._userid[id][0]
-
- def __setitem__(self, *args):
- raise NotImplementedError
-
- def __delitem__(self, id):
- pkt, idx = self._userid[id]
- del self._pubkey[idx]
- del self._userid[idx]
- pkt, idx = self._keyid[id]
- del self._keyid[idx]
-
- def spurious(self):
- return tuple(self._spurious)
-
- def save(self, keyring):
- for p in self._pubkey:
- pp = p.pack()
- keyring.write(pp)
-
-
-def load_pubring(filename='pubring.pgp'):
- pkr = PublicKeyRing(open(filename, 'rb'))
- pkr.load()
- return pkr
-
diff --git a/M2Crypto/PGP/RSA.py b/M2Crypto/PGP/RSA.py
deleted file mode 100644
index 153193d..0000000
--- a/M2Crypto/PGP/RSA.py
+++ /dev/null
@@ -1,36 +0,0 @@
-"""M2Crypto PGP2 RSA.
-
-Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
-
-import sys
-from M2Crypto import m2, RSA
-_RSA = RSA
-del RSA
-
-
-class RSA(_RSA.RSA):
- pass
-
-
-class RSA_pub(_RSA.RSA_pub):
- pass
-
-
-def new_pub_key((e, n)):
- """
- Factory function that instantiates an RSA_pub object from a (e, n) tuple.
-
- 'e' is the RSA public exponent; it is a string in OpenSSL's binary format,
- i.e., a number of bytes in big-endian.
-
- 'n' is the RSA composite of primes; it is a string in OpenSSL's binary format,
- i.e., a number of bytes in big-endian.
- """
- import warnings
- warnings.warn('Deprecated. No maintainer for PGP. If you use this, please inform M2Crypto maintainer.', DeprecationWarning)
-
- rsa = m2.rsa_new()
- m2.rsa_set_e_bin(rsa, e)
- m2.rsa_set_n_bin(rsa, n)
- return RSA_pub(rsa, 1)
-
diff --git a/M2Crypto/PGP/__init__.py b/M2Crypto/PGP/__init__.py
deleted file mode 100644
index 27fd669..0000000
--- a/M2Crypto/PGP/__init__.py
+++ /dev/null
@@ -1,14 +0,0 @@
-"""M2Crypto PGP2.
-
-Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
-
-from constants import *
-
-from packet import public_key_packet, trust_packet, userid_packet,\
- comment_packet, signature_packet, private_key_packet, cke_packet,\
- pke_packet, literal_packet, packet_stream
-
-from PublicKey import *
-from PublicKeyRing import *
-
-
diff --git a/M2Crypto/PGP/constants.py b/M2Crypto/PGP/constants.py
deleted file mode 100644
index 9a7810f..0000000
--- a/M2Crypto/PGP/constants.py
+++ /dev/null
@@ -1,19 +0,0 @@
-"""M2Crypto PGP2.
-
-Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
-
-CTB_TAG = 128
-
-CTB_PKE = 1
-CTB_SIGNATURE = 2
-CTB_MESSAGE_DIGETS = 3
-CTB_PRIVATE_KEY = 5
-CTB_PUBLIC_KEY = 6
-CTB_COMPRESSED_DATA = 8
-CTB_CKE = 9
-CTB_LITERAL_DATA = 11
-CTB_TRUST = 12
-CTB_USERID = 13
-CTB_COMMENT = 14
-
-
diff --git a/M2Crypto/PGP/packet.py b/M2Crypto/PGP/packet.py
deleted file mode 100644
index d662c84..0000000
--- a/M2Crypto/PGP/packet.py
+++ /dev/null
@@ -1,379 +0,0 @@
-"""M2Crypto PGP2.
-
-This module implements PGP packets per RFC1991 and various source distributions.
-
-Each packet type is represented by a class; packet classes derive from
-the abstract 'packet' class.
-
-The 'message digest' packet type, mentioned but not documented in RFC1991,
-is not implemented.
-
-Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
-
-# XXX Work-in-progress.
-
-# Be liberal in what you accept.
-# Be conservative in what you send.
-# Be lazy in what you eval.
-
-import struct, time
-
-try:
- from cStringIO import StringIO
-except ImportError:
- from StringIO import StringIO
-
-from M2Crypto import EVP, RSA
-from M2Crypto.util import octx_to_num
-
-from constants import *
-
-_OK_VERSION = ('\002', '\003')
-_OK_VALIDITY = ('\000',)
-_OK_PKC = ('\001',)
-
-
-class packet:
- def __init__(self, ctb, body=None):
- import warnings
- warnings.warn('Deprecated. No maintainer for PGP. If you use this, please inform M2Crypto maintainer.', DeprecationWarning)
-
- self.ctb = ctb
- if body is not None:
- self.body = StringIO(body)
- else:
- self.body = None
-
- def validate(self):
- return 1
-
- def pack(self):
- raise NotImplementedError, '%s.pack(): abstract method' % (self.__class__,)
-
- def version(self):
- if hasattr(self, '_version'):
- return ord(self._version)
- else:
- return None
-
- def timestamp(self):
- if hasattr(self, '_timestamp'):
- return struct.unpack('>L', self._timestamp)[0]
- else:
- return None
-
- def validity(self):
- if hasattr(self, '_validity'):
- return struct.unpack('>H', self._validity)[0]
- else:
- return None
-
- def pkc(self):
- if hasattr(self, '_pkc'):
- return self._pkc
- else:
- return None
-
- def _llf(self, lenf):
- if lenf < 256:
- return (0, chr(lenf))
- elif lenf < 65536:
- return (1, struct.pack('>H', lenf))
- else:
- assert lenf < 2L**32
- return (2, struct.pack('>L', lenf))
-
- def _ctb(self, llf):
- ctbv = _FACTORY[self.__class__]
- return chr((1 << 7) | (ctbv << 2) | llf)
-
-
-class public_key_packet(packet):
- def __init__(self, ctb, body=None):
- packet.__init__(self, ctb, body)
- if self.body is not None:
- self._version = self.body.read(1)
- self._timestamp = self.body.read(4)
- self._validity = self.body.read(2)
- self._pkc = self.body.read(1)
-
- self._nlen = self.body.read(2)
- nlen = (struct.unpack('>H', self._nlen)[0] + 7) / 8
- self._n = self.body.read(nlen)
-
- self._elen = self.body.read(2)
- elen = (struct.unpack('>H', self._elen)[0] + 7) / 8
- self._e = self.body.read(elen)
-
- def pack(self):
- if self.body is None:
- self.body = StringIO()
- self.body.write(self._version)
- self.body.write(self._timestamp)
- self.body.write(self._validity)
- self.body.write(self._pkc)
- self.body.write(self._nlen)
- self.body.write(self._n)
- self.body.write(self._elen)
- self.body.write(self._e)
- self.body = self.body.getvalue()
- llf, lenf = self._llf(len(self.body))
- ctb = self._ctb(llf)
- return '%s%s%s' % (ctb, lenf, self.body)
-
- def pubkey(self):
- return self._pubkey.pub()
-
-
-class trust_packet(packet):
- # This implementation neither interprets nor emits trust packets.
- def __init__(self, ctb, body=None):
- packet.__init__(self, ctb, body)
- if body is not None:
- self.trust = self.body.read(1)
-
-
-class userid_packet(packet):
- def __init__(self, ctb, body=None):
- packet.__init__(self, ctb, body)
- if body is not None:
- self._userid = body
-
- def pack(self):
- if self.body is None:
- self.body = StringIO()
- self.body.write(chr(len(self._userid)))
- self.body.write(self._userid)
- self.body = self.body.getvalue()
- return self.ctb + self.body
-
- def userid(self):
- return self._userid
-
-
-class comment_packet(packet):
- def __init__(self, ctb, body=None):
- packet.__init__(self, ctb, body)
- if body is not None:
- self.comment = self.body.getvalue()
-
- def pack(self):
- if self.body is None:
- self.body = StringIO()
- self.body.write(chr(len(self.comment)))
- self.body.write(self.comment)
- self.body = self.body.getvalue()
- return self.ctb + self.body
-
-
-class signature_packet(packet):
- def __init__(self, ctb, body=None):
- packet.__init__(self, ctb, body)
- if body is not None:
- self._version = self.body.read(1)
- self._len_md_stuff = self.body.read(1)
- self._classification = self.body.read(1)
- self._timestamp = self.body.read(4)
- self._keyid = self.body.read(8)
- self._pkc = self.body.read(1)
- self._md_algo = self.body.read(1)
- self._md_chksum = self.body.read(2)
- self._sig = self.body.read()
-
- def pack(self):
- if self.body is None:
- self.body = StringIO()
- self.body.write(self._version)
- self.body.write(self._len_md_stuff)
- self.body.write(self._classification)
- self.body.write(self._timestamp)
- self.body.write(self._keyid)
- self.body.write(self._pkc)
- self.body.write(self._md_algo)
- self.body.write(self._md_chksum)
- self.body.write(self._sig)
- self.body = self.body.getvalue()
- llf, lenf = self._llf(len(body))
- self.ctb = self.ctb | llf
- return '%s%s%s' % (self.ctb, lenf, self.body)
-
-
- def validate(self):
- if self._version not in _OK_VERSION:
- return None
- if self._len_md_stuff != '\005':
- return None
-
-
-class private_key_packet(packet):
- def __init__(self, ctb, body=None):
- packet.__init__(self, ctb, body)
- if body is not None:
- self._version = self.body.read(1)
- self._timestamp = self.body.read(4)
- self._validity = self.body.read(2)
- self._pkc = self.body.read(1)
-
- self._nlen = self.body.read(2)
- nlen = (struct.unpack('>H', self._nlen)[0] + 7) / 8
- self._n = self.body.read(nlen)
-
- self._elen = self.body.read(2)
- elen = (struct.unpack('>H', self._elen)[0] + 7) / 8
- self._e = self.body.read(elen)
-
- self._cipher = self.body.read(1)
- if self._cipher == '\001':
- self._iv = self.body.read(8)
- else:
- self._iv = None
-
- for param in ['d', 'p', 'q', 'u']:
- _plen = self.body.read(2)
- setattr(self, '_'+param+'len', _plen)
- plen = (struct.unpack('>H', _plen)[0] + 7) / 8
- setattr(self, '_'+param, self.body.read(plen))
-
- self._cksum = self.body.read(2)
-
- def is_encrypted(self):
- return ord(self._cipher)
-
-
-class cke_packet(packet):
- def __init__(self, ctb, body=None):
- packet.__init__(self, ctb, body)
- if body is not None:
- self._iv = self.body.read(8)
- self._cksum = self.body.read(2)
- self._ctxt = self.body.read()
-
-
-class pke_packet(packet):
- def __init__(self, ctb, body=None):
- packet.__init__(self, ctb, body)
- if body is not None:
- self._version = self.body.read(1)
- self._keyid = self.body.read(8)
- self._pkc = ord(self.body.read(1))
-
- deklen = (struct.unpack('>H', self.body.read(2))[0] + 7 ) / 8
- self._dek = octx_to_num(self.body.read(deklen))
-
-
-class literal_packet(packet):
- def __init__(self, ctb, body=None):
- packet.__init__(self, ctb, body)
- if body is not None:
- self.fmode = self.body.read(1)
- fnlen = self.body.read(1)
- self.fname = self.body.read(fnlen)
- self.ftime = self.body.read(4)
- #self.data = self.body.read()
-
-
-class compressed_packet(packet):
- def __init__(self, ctb, stream):
- packet.__init__(self, ctb, '')
- if body is not None:
- self.algo = stream.read(1)
- # This reads the entire stream into memory.
- self.data = stream.read()
-
- def validate(self):
- return (self.algo == '\001')
-
- def uncompress(self):
- import zlib
- decomp = zlib.decompressobj(-13) # RFC 2440, pg 61.
- # This doubles the memory usage.
- stream = StringIO(decomp.decompress(self.data))
- return stream
-
-
-_FACTORY = {
- 1 : pke_packet,
- 2 : signature_packet,
- #3 : message_digest_packet, # XXX not implemented
- 5 : private_key_packet,
- 6 : public_key_packet,
- #8 : compressed_packet, # special case
- 9 : cke_packet,
- 11 : literal_packet,
- 12 : trust_packet,
- 13 : userid_packet,
- 14 : comment_packet,
- pke_packet : 1,
- signature_packet : 2,
- #3 : message_digest_packet,
- private_key_packet : 5,
- public_key_packet : 6,
- #8 : compressed_packet,
- cke_packet : 9,
- literal_packet : 11,
- trust_packet : 12,
- userid_packet : 13,
- comment_packet : 14
-}
-
-
-class packet_stream:
- def __init__(self, input):
- self.stream = input
- self.under_current = None
- self._count = 0
-
- def close(self):
- self.stream.close()
- if self.under_current is not None:
- self.under_current.close()
-
- def read(self, keep_trying=0):
- while 1:
- ctb0 = self.stream.read(1)
- if not ctb0:
- return None
- ctb = ord(ctb0)
- if is_ctb(ctb):
- break
- elif keep_trying:
- continue
- else:
- raise XXXError
- ctbt = (ctb & 0x3c) >> 2
-
- if ctbt == CTB_COMPRESSED_DATA:
- self.under_current = self.stream
- cp = compressed_packet(ctb0, self.stream)
- self.stream = cp.uncompress()
- return self.read()
-
- # Decode the length of following data. See RFC for details.
- llf = ctb & 3
- if llf == 0:
- lenf = ord(self.stream.read(1))
- elif llf == 1:
- lenf = struct.unpack('>H', self.stream.read(2))[0]
- elif llf == 2:
- lenf = struct.unpack('>L', self.stream.read(4))[0]
- else: # llf == 3
- raise XXXError, 'impossible case'
-
- body = self.stream.read(lenf)
- if not body or (len(body) != lenf):
- raise XXXError, 'corrupted packet'
-
- self._count = self.stream.tell()
- try:
- return _FACTORY[ctbt](ctb0, body)
- except KeyError:
- return packet(ctb0, body)
-
- def count(self):
- return self._count
-
-def is_ctb(ctb):
- return ctb & 0xc0
-
-def make_ctb(value, llf):
- return chr((1 << 7) | (value << 2) | llf)
diff --git a/M2Crypto/RC4.py b/M2Crypto/RC4.py
index 1b5d408..26e1079 100644
--- a/M2Crypto/RC4.py
+++ b/M2Crypto/RC4.py
@@ -1,31 +1,36 @@
+from __future__ import absolute_import
+
"""M2Crypto wrapper for OpenSSL RC4 API.
Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
-from m2 import rc4_new, rc4_free, rc4_set_key, rc4_update
+from M2Crypto.m2 import rc4_free, rc4_new, rc4_set_key, rc4_update
-class RC4:
+class RC4(object):
"""Object interface to the stream cipher RC4."""
rc4_free = rc4_free
def __init__(self, key=None):
+ # type: (bytes) -> None
self.cipher = rc4_new()
if key:
rc4_set_key(self.cipher, key)
-
+
def __del__(self):
- if getattr(self, 'cipher', None):
+ # type: () -> None
+ if getattr(self, 'cipher', None):
self.rc4_free(self.cipher)
def set_key(self, key):
- rc4_set_key(self.cipher, key)
+ # type: (bytes) -> None
+ rc4_set_key(self.cipher, key)
def update(self, data):
+ # type: (bytes) -> bytes
return rc4_update(self.cipher, data)
def final(self):
+ # type: () -> str
return ''
-
-
diff --git a/M2Crypto/RSA.py b/M2Crypto/RSA.py
index 2dff160..1292e1d 100644
--- a/M2Crypto/RSA.py
+++ b/M2Crypto/RSA.py
@@ -1,11 +1,18 @@
+from __future__ import absolute_import
+
"""M2Crypto wrapper for OpenSSL RSA API.
Copyright (c) 1999-2004 Ng Pheng Siong. All rights reserved."""
import sys
-import util, BIO, Err, m2
-class RSAError(Exception): pass
+from M2Crypto import BIO, Err, m2, util
+if util.py27plus:
+ from typing import Any, AnyStr, Callable, Dict, List, IO, Optional, Tuple # noqa
+
+
+class RSAError(Exception):
+ pass
m2.rsa_init(RSAError)
@@ -15,7 +22,7 @@ sslv23_padding = m2.sslv23_padding
pkcs1_oaep_padding = m2.pkcs1_oaep_padding
-class RSA:
+class RSA(object):
"""
RSA Key Pair.
"""
@@ -23,18 +30,25 @@ class RSA:
m2_rsa_free = m2.rsa_free
def __init__(self, rsa, _pyfree=0):
+ # type: (bytes, int) -> None
+ """
+ :param rsa: binary representation of OpenSSL RSA type
+ """
assert m2.rsa_type_check(rsa), "'rsa' type error"
self.rsa = rsa
self._pyfree = _pyfree
-
+
def __del__(self):
+ # type: () -> None
if getattr(self, '_pyfree', 0):
self.m2_rsa_free(self.rsa)
def __len__(self):
- return m2.rsa_size(self.rsa) << 3
+ # type: () -> int
+ return int(m2.rsa_size(self.rsa) << 3)
def __getattr__(self, name):
+ # type: (str) -> bytes
if name == 'e':
return m2.rsa_get_e(self.rsa)
elif name == 'n':
@@ -43,75 +57,81 @@ class RSA:
raise AttributeError
def pub(self):
+ # type: () -> Tuple[bytes, bytes]
assert self.check_key(), 'key is not initialised'
return m2.rsa_get_e(self.rsa), m2.rsa_get_n(self.rsa)
def public_encrypt(self, data, padding):
+ # type: (bytes, int) -> bytes
assert self.check_key(), 'key is not initialised'
return m2.rsa_public_encrypt(self.rsa, data, padding)
def public_decrypt(self, data, padding):
+ # type: (bytes, int) -> bytes
assert self.check_key(), 'key is not initialised'
return m2.rsa_public_decrypt(self.rsa, data, padding)
def private_encrypt(self, data, padding):
+ # type: (bytes, int) -> bytes
assert self.check_key(), 'key is not initialised'
return m2.rsa_private_encrypt(self.rsa, data, padding)
def private_decrypt(self, data, padding):
+ # type: (bytes, int) -> bytes
assert self.check_key(), 'key is not initialised'
return m2.rsa_private_decrypt(self.rsa, data, padding)
- def save_key_bio(self, bio, cipher='aes_128_cbc', callback=util.passphrase_callback):
+ def save_key_bio(self, bio, cipher='aes_128_cbc',
+ callback=util.passphrase_callback):
+ # type: (BIO.BIO, Optional[str], Callable) -> int
"""
Save the key pair to an M2Crypto.BIO.BIO object in PEM format.
- @type bio: M2Crypto.BIO.BIO
- @param bio: M2Crypto.BIO.BIO object to save key to.
+ :param bio: M2Crypto.BIO.BIO object to save key to.
- @type cipher: string
- @param cipher: Symmetric cipher to protect the key. The default
- cipher is 'aes_128_cbc'. If cipher is None, then the key is saved
- in the clear.
+ :param cipher: Symmetric cipher to protect the key. The default
+ cipher is 'aes_128_cbc'. If cipher is None, then
+ the key is saved in the clear.
- @type callback: Python callable
- @param callback: A Python callable object that is invoked
- to acquire a passphrase with which to protect the key.
- The default is util.passphrase_callback.
+ :param callback: A Python callable object that is invoked
+ to acquire a passphrase with which to protect
+ the key. The default is
+ util.passphrase_callback.
"""
if cipher is None:
return m2.rsa_write_key_no_cipher(self.rsa, bio._ptr(), callback)
else:
ciph = getattr(m2, cipher, None)
if ciph is None:
- raise RSAError, 'not such cipher %s' % cipher
+ raise RSAError('not such cipher %s' % cipher)
else:
ciph = ciph()
return m2.rsa_write_key(self.rsa, bio._ptr(), ciph, callback)
- def save_key(self, file, cipher='aes_128_cbc', callback=util.passphrase_callback):
+ def save_key(self, file, cipher='aes_128_cbc',
+ callback=util.passphrase_callback):
+ # type: (AnyStr, Optional[str], Callable) -> int
"""
Save the key pair to a file in PEM format.
- @type file: string
- @param file: Name of file to save key to.
+ :param file: Name of file to save key to.
- @type cipher: string
- @param cipher: Symmetric cipher to protect the key. The default
- cipher is 'aes_128_cbc'. If cipher is None, then the key is saved
- in the clear.
+ :param cipher: Symmetric cipher to protect the key. The default
+ cipher is 'aes_128_cbc'. If cipher is None, then
+ the key is saved in the clear.
- @type callback: Python callable
- @param callback: A Python callable object that is invoked
- to acquire a passphrase with which to protect the key.
- The default is util.passphrase_callback.
+ :param callback: A Python callable object that is invoked
+ to acquire a passphrase with which to protect
+ the key. The default is
+ util.passphrase_callback.
"""
- bio = BIO.openfile(file, 'wb')
- return self.save_key_bio(bio, cipher, callback)
+ with BIO.openfile(file, 'wb') as bio:
+ return self.save_key_bio(bio, cipher, callback)
save_pem = save_key
def as_pem(self, cipher='aes_128_cbc', callback=util.passphrase_callback):
+ # type: (Optional[str], Callable) -> bytes
"""
Returns the key(pair) as a string in PEM format.
"""
@@ -120,143 +140,148 @@ class RSA:
return bio.read()
def save_key_der_bio(self, bio):
+ # type: (BIO.BIO) -> int
"""
Save the key pair to an M2Crypto.BIO.BIO object in DER format.
- @type bio: M2Crypto.BIO.BIO
- @param bio: M2Crypto.BIO.BIO object to save key to.
+ :param bio: M2Crypto.BIO.BIO object to save key to.
"""
return m2.rsa_write_key_der(self.rsa, bio._ptr())
def save_key_der(self, file):
+ # type: (AnyStr) -> int
"""
Save the key pair to a file in DER format.
- @type file: str
- @param file: Filename to save key to
+ :param file: Filename to save key to
"""
- bio = BIO.openfile(file, 'wb')
- return self.save_key_der_bio(bio)
+ with BIO.openfile(file, 'wb') as bio:
+ return self.save_key_der_bio(bio)
def save_pub_key_bio(self, bio):
+ # type: (BIO.BIO) -> int
"""
Save the public key to an M2Crypto.BIO.BIO object in PEM format.
- @type bio: M2Crypto.BIO.BIO
- @param bio: M2Crypto.BIO.BIO object to save key to.
- """
+ :param bio: M2Crypto.BIO.BIO object to save key to.
+ """
return m2.rsa_write_pub_key(self.rsa, bio._ptr())
def save_pub_key(self, file):
+ # type: (AnyStr) -> int
"""
Save the public key to a file in PEM format.
- @type file: string
- @param file: Name of file to save key to.
+ :param file: Name of file to save key to.
"""
- bio = BIO.openfile(file, 'wb')
- return m2.rsa_write_pub_key(self.rsa, bio._ptr())
+ with BIO.openfile(file, 'wb') as bio:
+ return m2.rsa_write_pub_key(self.rsa, bio._ptr())
def check_key(self):
+ # type: () -> int
+ """
+ Validate RSA keys.
+
+ It checks that p and q are in fact prime, and that n = p*q.
+
+ :return: returns 1 if rsa is a valid RSA key, and 0 otherwise.
+ -1 is returned if an error occurs while checking the key.
+ If the key is invalid or an error occurred, the reason
+ code can be obtained using ERR_get_error(3).
+ """
return m2.rsa_check_key(self.rsa)
def sign_rsassa_pss(self, digest, algo='sha1', salt_length=20):
+ # type: (bytes, str, int) -> bytes
"""
Signs a digest with the private key using RSASSA-PSS
-
- @requires: OpenSSL 0.9.7h or later.
- @type digest: str
- @param digest: A digest created by using the digest method
+ :param digest: A digest created by using the digest method
- @type salt_length: int
- @param salt_length: The length of the salt to use
-
- @type algo: str
- @param algo: The hash algorithm to use
+ :param salt_length: The length of the salt to use
- @return: a string which is the signature
+ :param algo: The hash algorithm to use
+ Legal values like 'sha1','sha224', 'sha256',
+ 'ripemd160', and 'md5'.
+
+ :return: a string which is the signature
"""
hash = getattr(m2, algo, None)
+
if hash is None:
- raise ValueError('not such hash algorithm %s' % hash_algo)
+ raise RSAError('not such hash algorithm %s' % algo)
signature = m2.rsa_padding_add_pkcs1_pss(self.rsa, digest, hash(), salt_length)
-
- return self.private_encrypt(signature, m2.no_padding)
+
+ return self.private_encrypt(signature, m2.no_padding)
def verify_rsassa_pss(self, data, signature, algo='sha1', salt_length=20):
+ # type: (bytes, bytes, str, int) -> int
"""
Verifies the signature RSASSA-PSS
- @requires: OpenSSL 0.9.7h or later.
+ :param data: Data that has been signed
- @type data: str
- @param data: Data that has been signed
+ :param signature: The signature signed with RSASSA-PSS
- @type signature: str
- @param signature: The signature signed with RSASSA-PSS
-
- @type salt_length: int
- @param salt_length: The length of the salt that was used
+ :param salt_length: The length of the salt that was used
- @type algo: str
- @param algo: The hash algorithm to use
+ :param algo: The hash algorithm to use
+ Legal values are for example 'sha1','sha224',
+ 'sha256', 'ripemd160', and 'md5'.
- @return: 1 or 0, depending on whether the signature was
- verified or not.
+ :return: 1 or 0, depending on whether the signature was
+ verified or not.
"""
hash = getattr(m2, algo, None)
+
if hash is None:
- raise ValueError('not such hash algorithm %s' % hash_algo)
+ raise RSAError('not such hash algorithm %s' % algo)
plain_signature = self.public_decrypt(signature, m2.no_padding)
-
+
return m2.rsa_verify_pkcs1_pss(self.rsa, data, plain_signature, hash(), salt_length)
def sign(self, digest, algo='sha1'):
+ # type: (bytes, str) -> bytes
"""
Signs a digest with the private key
- @type digest: str
- @param digest: A digest created by using the digest method
+ :param digest: A digest created by using the digest method
- @type algo: str
- @param algo: The method that created the digest.
- Legal values are 'sha1','sha224', 'sha256', 'ripemd160',
- and 'md5'.
-
- @return: a string which is the signature
+ :param algo: The method that created the digest.
+ Legal values like 'sha1','sha224', 'sha256',
+ 'ripemd160', and 'md5'.
+
+ :return: a string which is the signature
"""
- digest_type = getattr(m2, 'NID_' + algo, None)
+ digest_type = getattr(m2, 'NID_' + algo, None)
if digest_type is None:
- raise ValueError, ('unknown algorithm', algo)
-
- return m2.rsa_sign(self.rsa, digest, digest_type)
-
+ raise ValueError('unknown algorithm', algo)
+
+ return m2.rsa_sign(self.rsa, digest, digest_type)
+
def verify(self, data, signature, algo='sha1'):
+ # type: (bytes, bytes, str) -> int
"""
Verifies the signature with the public key
- @type data: str
- @param data: Data that has been signed
+ :param data: Data that has been signed
- @type signature: str
- @param signature: The signature signed with the private key
+ :param signature: The signature signed with the private key
- @type algo: str
- @param algo: The method use to create digest from the data
- before it was signed. Legal values are 'sha1','sha224',
- 'sha256', 'ripemd160', and 'md5'.
+ :param algo: The method use to create digest from the data
+ before it was signed. Legal values like
+ 'sha1','sha224', 'sha256', 'ripemd160', and 'md5'.
- @return: True or False, depending on whether the signature was
- verified.
+ :return: 1 or 0, depending on whether the signature was
+ verified or not.
"""
digest_type = getattr(m2, 'NID_' + algo, None)
if digest_type is None:
- raise ValueError, ('unknown algorithm', algo)
-
- return m2.rsa_verify(self.rsa, data, signature, digest_type)
+ raise ValueError('unknown algorithm', algo)
+
+ return m2.rsa_verify(self.rsa, data, signature, digest_type)
class RSA_pub(RSA):
@@ -266,106 +291,107 @@ class RSA_pub(RSA):
"""
def __setattr__(self, name, value):
+ # type: (str, bytes) -> None
if name in ['e', 'n']:
- raise RSAError, \
- 'use factory function new_pub_key() to set (e, n)'
+ raise RSAError('use factory function new_pub_key() to set (e, n)')
else:
self.__dict__[name] = value
-
+
def private_encrypt(self, *argv):
- raise RSAError, 'RSA_pub object has no private key'
+ # type: (*Any) -> None
+ raise RSAError('RSA_pub object has no private key')
def private_decrypt(self, *argv):
- raise RSAError, 'RSA_pub object has no private key'
+ # type: (*Any) -> None
+ raise RSAError('RSA_pub object has no private key')
def save_key(self, file, *args, **kw):
+ # type: (AnyStr, *Any, **Any) -> int
"""
Save public key to file.
"""
return self.save_pub_key(file)
def save_key_bio(self, bio, *args, **kw):
+ # type: (BIO.BIO, *Any, **Any) -> int
"""
Save public key to BIO.
"""
return self.save_pub_key_bio(bio)
- #save_key_der
+ # save_key_der
- #save_key_der_bio
+ # save_key_der_bio
def check_key(self):
+ # type: () -> int
return m2.rsa_check_pub_key(self.rsa)
def rsa_error():
- raise RSAError, m2.err_reason_error_string(m2.err_get_error())
+ # type: () -> None
+ raise RSAError(Err.get_error_message())
def keygen_callback(p, n, out=sys.stdout):
+ # type: (int, Any, IO[str]) -> None
"""
Default callback for gen_key().
"""
- ch = ['.','+','*','\n']
+ ch = ['.', '+', '*', '\n']
out.write(ch[p])
out.flush()
def gen_key(bits, e, callback=keygen_callback):
+ # type: (int, int, Callable) -> RSA
"""
Generate an RSA key pair.
- @type bits: int
- @param bits: Key length, in bits.
+ :param bits: Key length, in bits.
- @type e: int
- @param e: The RSA public exponent.
+ :param e: The RSA public exponent.
- @type callback: Python callable
- @param callback: A Python callable object that is invoked
- during key generation; its usual purpose is to provide visual
- feedback. The default callback is keygen_callback.
+ :param callback: A Python callable object that is invoked
+ during key generation; its usual purpose is to
+ provide visual feedback. The default callback is
+ keygen_callback.
- @rtype: M2Crypto.RSA.RSA
- @return: M2Crypto.RSA.RSA object.
- """
+ :return: M2Crypto.RSA.RSA object.
+ """
return RSA(m2.rsa_generate_key(bits, e, callback), 1)
def load_key(file, callback=util.passphrase_callback):
+ # type: (AnyStr, Callable) -> RSA
"""
Load an RSA key pair from file.
- @type file: string
- @param file: Name of file containing RSA public key in PEM format.
+ :param file: Name of file containing RSA public key in PEM format.
- @type callback: Python callable
- @param callback: A Python callable object that is invoked
- to acquire a passphrase with which to unlock the key.
- The default is util.passphrase_callback.
+ :param callback: A Python callable object that is invoked
+ to acquire a passphrase with which to unlock the
+ key. The default is util.passphrase_callback.
- @rtype: M2Crypto.RSA.RSA
- @return: M2Crypto.RSA.RSA object.
+ :return: M2Crypto.RSA.RSA object.
"""
- bio = BIO.openfile(file)
- return load_key_bio(bio, callback)
+ with BIO.openfile(file) as bio:
+ return load_key_bio(bio, callback)
def load_key_bio(bio, callback=util.passphrase_callback):
+ # type: (BIO.BIO, Callable) -> RSA
"""
Load an RSA key pair from an M2Crypto.BIO.BIO object.
- @type bio: M2Crypto.BIO.BIO
- @param bio: M2Crypto.BIO.BIO object containing RSA key pair in PEM
- format.
+ :param bio: M2Crypto.BIO.BIO object containing RSA key pair in PEM
+ format.
- @type callback: Python callable
- @param callback: A Python callable object that is invoked
- to acquire a passphrase with which to unlock the key.
- The default is util.passphrase_callback.
+ :param callback: A Python callable object that is invoked
+ to acquire a passphrase with which to unlock the
+ key. The default is util.passphrase_callback.
- @rtype: M2Crypto.RSA.RSA
- @return: M2Crypto.RSA.RSA object.
+ :return: M2Crypto.RSA.RSA object.
"""
rsa = m2.rsa_read_key(bio._ptr(), callback)
if rsa is None:
@@ -374,75 +400,67 @@ def load_key_bio(bio, callback=util.passphrase_callback):
def load_key_string(string, callback=util.passphrase_callback):
+ # type: (AnyStr, Callable) -> RSA
"""
Load an RSA key pair from a string.
- @type string: string
- @param string: String containing RSA key pair in PEM format.
+ :param string: String containing RSA key pair in PEM format.
- @type callback: Python callable
- @param callback: A Python callable object that is invoked
- to acquire a passphrase with which to unlock the key.
- The default is util.passphrase_callback.
+ :param callback: A Python callable object that is invoked
+ to acquire a passphrase with which to unlock the
+ key. The default is util.passphrase_callback.
- @rtype: M2Crypto.RSA.RSA
- @return: M2Crypto.RSA.RSA object.
+ :return: M2Crypto.RSA.RSA object.
"""
bio = BIO.MemoryBuffer(string)
return load_key_bio(bio, callback)
def load_pub_key(file):
+ # type: (AnyStr) -> RSA_pub
"""
Load an RSA public key from file.
- @type file: string
- @param file: Name of file containing RSA public key in PEM format.
+ :param file: Name of file containing RSA public key in PEM format.
- @rtype: M2Crypto.RSA.RSA_pub
- @return: M2Crypto.RSA.RSA_pub object.
+ :return: M2Crypto.RSA.RSA_pub object.
"""
- bio = BIO.openfile(file)
- return load_pub_key_bio(bio)
+ with BIO.openfile(file) as bio:
+ return load_pub_key_bio(bio)
def load_pub_key_bio(bio):
+ # type: (BIO.BIO) -> RSA_pub
"""
Load an RSA public key from an M2Crypto.BIO.BIO object.
- @type bio: M2Crypto.BIO.BIO
- @param bio: M2Crypto.BIO.BIO object containing RSA public key in PEM
- format.
+ :param bio: M2Crypto.BIO.BIO object containing RSA public key in PEM
+ format.
- @rtype: M2Crypto.RSA.RSA_pub
- @return: M2Crypto.RSA.RSA_pub object.
- """
+ :return: M2Crypto.RSA.RSA_pub object.
+ """
rsa = m2.rsa_read_pub_key(bio._ptr())
if rsa is None:
rsa_error()
return RSA_pub(rsa, 1)
-def new_pub_key((e, n)):
+def new_pub_key(e_n):
+ # type: (Tuple[bytes, bytes]) -> RSA_pub
"""
Instantiate an RSA_pub object from an (e, n) tuple.
- @type e: string
- @param e: The RSA public exponent; it is a string in OpenSSL's MPINT
- format - 4-byte big-endian bit-count followed by the appropriate
- number of bits.
+ :param e: The RSA public exponent; it is a string in OpenSSL's MPINT
+ format - 4-byte big-endian bit-count followed by the
+ appropriate number of bits.
- @type n: string
- @param n: The RSA composite of primes; it is a string in OpenSSL's MPINT
- format - 4-byte big-endian bit-count followed by the appropriate
- number of bits.
+ :param n: The RSA composite of primes; it is a string in OpenSSL's
+ MPINT format - 4-byte big-endian bit-count followed by the
+ appropriate number of bits.
- @rtype: M2Crypto.RSA.RSA_pub
- @return: M2Crypto.RSA.RSA_pub object.
- """
+ :return: M2Crypto.RSA.RSA_pub object.
+ """
+ (e, n) = e_n
rsa = m2.rsa_new()
- m2.rsa_set_e(rsa, e)
- m2.rsa_set_n(rsa, n)
+ m2.rsa_set_en(rsa, e, n)
return RSA_pub(rsa, 1)
-
-
diff --git a/M2Crypto/Rand.py b/M2Crypto/Rand.py
index 1e6a918..86a6f16 100644
--- a/M2Crypto/Rand.py
+++ b/M2Crypto/Rand.py
@@ -1,17 +1,147 @@
"""M2Crypto wrapper for OpenSSL PRNG. Requires OpenSSL 0.9.5 and above.
-Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
+Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved.
+Copyright (c) 2014-2017 Matej Cepl. All rights reserved.
+
+See LICENCE for the license information.
+"""
+from __future__ import absolute_import
+
+from M2Crypto import m2, py27plus, six
+if py27plus:
+ from typing import AnyStr, Tuple # noqa
+
__all__ = ['rand_seed', 'rand_add', 'load_file', 'save_file', 'rand_bytes',
- 'rand_pseudo_bytes']
+ 'rand_pseudo_bytes', 'rand_file_name', 'rand_status']
+
+
+class RandError(ValueError):
+ pass
+
+m2.rand_init(RandError)
+
+
+def rand_add(blob, entropy):
+ # type: (bytes, float) -> None
+ """
+ Mixes blob into the PRNG state.
+
+ :param blob: added data
+ :param entropy: (the lower bound of) an estimate of how much randomness
+ is contained in blob, measured in bytes.
+
+ Thus, if the data at buf are unpredictable to an adversary, this
+ increases the uncertainty about the state and makes the PRNG output less
+ predictable. Suitable input comes from user interaction (random key
+ presses, mouse movements) and certain hardware events.
+
+ Details about sources of randomness and how to estimate their entropy
+ can be found in the literature, e.g. RFC 1750.
+ """
+ m2.rand_add(blob, entropy) # pylint: disable=no-member
+
+
+def rand_seed(seed):
+ # type: (bytes) -> None
+ """
+ Equivalent to rand_add() when len(seed) == entropy.
+
+ :param seed: added data (see description at rand_add)
+ """
+ m2.rand_seed(seed) # pylint: disable=no-member
+
+
+def rand_status():
+ # type: () -> int
+ """
+ Check whether there is enough entropy in PRNG.
+
+ :return: 1 if the PRNG has been seeded with enough
+ data, 0 otherwise.
+ """
+ return m2.rand_status() # pylint: disable=no-member
+
+
+def rand_file_name():
+ # type: () -> str
+ """
+ Generate a default path for the random seed file.
+
+ :return: string with the filename.
+ The seed file is $RANDFILE if that environment variable
+ is set, $HOME/.rnd otherwise. If $HOME is not set either,
+ an error occurs.
+ """
+ return six.ensure_text(m2.rand_file_name()) # pylint: disable=no-member
+
+
+def load_file(filename, max_bytes):
+ # type: (AnyStr, int) -> int
+ """
+ Read a number of bytes from file filename and adds them to the PRNG.
+
+ If max_bytes is non-negative, up to to max_bytes are read; starting with
+ OpenSSL 0.9.5, if max_bytes is -1, the complete file is read.
+
+ :param filename:
+ :param max_bytes:
+ :return: the number of bytes read.
+ """
+ return m2.rand_load_file(six.ensure_str(filename), max_bytes) # pylint: disable=no-member
+
+
+def save_file(filename):
+ # type: (AnyStr) -> int
+ """
+ Write a number of random bytes (currently 1024) to file.
+
+ The file then can be used to initialize the PRNG by calling load_file() in
+ a later session.
+
+ :param filename:
+ :return: returns the number of bytes written, and -1 if the bytes
+ written were generated without appropriate seed.
+ """
+ return m2.rand_save_file(filename) # pylint: disable=no-member
+
+
+def rand_bytes(num):
+ # type: (int) -> bytes
+ """
+ Return n cryptographically strong pseudo-random bytes.
+
+ An error occurs if the PRNG has not been seeded with enough randomness
+ to ensure an unpredictable byte sequence.
+
+ :param num: number of bytes to be returned
+ :return: random bytes
+ """
+ return m2.rand_bytes(num) # pylint: disable=no-member
+
+
+def rand_pseudo_bytes(num):
+ # type: (int) -> Tuple[bytes, int]
+ """
+ Return num pseudo-random bytes into buf.
-import m2
+ Pseudo-random byte sequences generated by this method will be unique
+ if they are of sufficient length, but are not necessarily
+ unpredictable. They can be used for non-cryptographic purposes and for
+ certain purposes in cryptographic protocols, but usually not for key
+ generation etc.
-rand_seed = m2.rand_seed
-rand_add = m2.rand_add
-load_file = m2.rand_load_file
-save_file = m2.rand_save_file
-rand_bytes = m2.rand_bytes
-rand_pseudo_bytes = m2.rand_pseudo_bytes
+ Output of the function is mixed into the entropy pool before
+ retrieving the new pseudo-random bytes unless disabled at compile
+ time (see FAQ).
+ :param num: number of bytes to be returned
+ :return: random bytes
+ """
+ import warnings
+ if m2.OPENSSL_VERSION_NUMBER >= 0x10100000:
+ warnings.warn('The underlying OpenSSL method has been ' +
+ 'deprecated. Use Rand.rand_bytes instead.',
+ DeprecationWarning)
+ return m2.rand_pseudo_bytes(num) # pylint: disable=no-member
diff --git a/M2Crypto/SMIME.py b/M2Crypto/SMIME.py
index 556cd8f..7c78d19 100644
--- a/M2Crypto/SMIME.py
+++ b/M2Crypto/SMIME.py
@@ -1,42 +1,55 @@
+from __future__ import absolute_import
+
"""M2Crypto wrapper for OpenSSL S/MIME API.
Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
-import BIO, EVP, X509, Err, util
-import m2
+from M2Crypto import BIO, EVP, Err, X509, m2, util
+if util.py27plus:
+ from typing import AnyStr, Callable, Optional # noqa
+
+PKCS7_TEXT = m2.PKCS7_TEXT # type: int
+PKCS7_NOCERTS = m2.PKCS7_NOCERTS # type: int
+PKCS7_NOSIGS = m2.PKCS7_NOSIGS # type: int
+PKCS7_NOCHAIN = m2.PKCS7_NOCHAIN # type: int
+PKCS7_NOINTERN = m2.PKCS7_NOINTERN # type: int
+PKCS7_NOVERIFY = m2.PKCS7_NOVERIFY # type: int
+PKCS7_DETACHED = m2.PKCS7_DETACHED # type: int
+PKCS7_BINARY = m2.PKCS7_BINARY # type: int
+PKCS7_NOATTR = m2.PKCS7_NOATTR # type: int
-PKCS7_TEXT = m2.PKCS7_TEXT
-PKCS7_NOCERTS = m2.PKCS7_NOCERTS
-PKCS7_NOSIGS = m2.PKCS7_NOSIGS
-PKCS7_NOCHAIN = m2.PKCS7_NOCHAIN
-PKCS7_NOINTERN = m2.PKCS7_NOINTERN
-PKCS7_NOVERIFY = m2.PKCS7_NOVERIFY
-PKCS7_DETACHED = m2.PKCS7_DETACHED
-PKCS7_BINARY = m2.PKCS7_BINARY
-PKCS7_NOATTR = m2.PKCS7_NOATTR
+PKCS7_SIGNED = m2.PKCS7_SIGNED # type: int
+PKCS7_ENVELOPED = m2.PKCS7_ENVELOPED # type: int
+PKCS7_SIGNED_ENVELOPED = m2.PKCS7_SIGNED_ENVELOPED # Deprecated
+PKCS7_DATA = m2.PKCS7_DATA # type: int
-PKCS7_SIGNED = m2.PKCS7_SIGNED
-PKCS7_ENVELOPED = m2.PKCS7_ENVELOPED
-PKCS7_SIGNED_ENVELOPED = m2.PKCS7_SIGNED_ENVELOPED # Deprecated
-PKCS7_DATA = m2.PKCS7_DATA
-class PKCS7_Error(Exception): pass
+class PKCS7_Error(Exception):
+ pass
m2.pkcs7_init(PKCS7_Error)
-class PKCS7:
+
+class PKCS7(object):
m2_pkcs7_free = m2.pkcs7_free
def __init__(self, pkcs7=None, _pyfree=0):
+ # type: (Optional[bytes], int) -> None
+ """PKCS7 object.
+
+ :param pkcs7: binary representation of
+ the OpenSSL type PKCS7
+ """
if pkcs7 is not None:
self.pkcs7 = pkcs7
self._pyfree = _pyfree
else:
self.pkcs7 = m2.pkcs7_new()
self._pyfree = 1
-
+
def __del__(self):
+ # type: () -> None
if getattr(self, '_pyfree', 0):
self.m2_pkcs7_free(self.pkcs7)
@@ -44,63 +57,71 @@ class PKCS7:
return self.pkcs7
def type(self, text_name=0):
+ # type: (int) -> int
if text_name:
return m2.pkcs7_type_sn(self.pkcs7)
else:
return m2.pkcs7_type_nid(self.pkcs7)
def write(self, bio):
+ # type: (BIO.BIO) -> int
return m2.pkcs7_write_bio(self.pkcs7, bio._ptr())
def write_der(self, bio):
+ # type: (BIO.BIO) -> int
return m2.pkcs7_write_bio_der(self.pkcs7, bio._ptr())
- def get0_signers(self, certs, flags = 0):
+ def get0_signers(self, certs, flags=0):
+ # type: (X509.X509_Stack, int) -> X509.X509_Stack
return X509.X509_Stack(m2.pkcs7_get0_signers(self.pkcs7,
certs.stack, flags), 1)
def load_pkcs7(p7file):
- bio = m2.bio_new_file(p7file, 'r')
- if bio is None:
- raise BIO.BIOError(Err.get_error())
+ # type: (AnyStr) -> PKCS7
+ with BIO.openfile(p7file, 'r') as bio:
+ p7_ptr = m2.pkcs7_read_bio(bio.bio)
+
+ return PKCS7(p7_ptr, 1)
+
+
+def load_pkcs7_der(p7file):
+ # type: (AnyStr) -> PKCS7
+ with BIO.openfile(p7file, 'rb') as bio:
+ p7_ptr = m2.pkcs7_read_bio_der(bio.bio)
- try:
- p7_ptr = m2.pkcs7_read_bio(bio)
- finally:
- m2.bio_free(bio)
-
- if p7_ptr is None:
- raise PKCS7_Error(Err.get_error())
return PKCS7(p7_ptr, 1)
-
+
def load_pkcs7_bio(p7_bio):
+ # type: (BIO.BIO) -> PKCS7
p7_ptr = m2.pkcs7_read_bio(p7_bio._ptr())
- if p7_ptr is None:
- raise PKCS7_Error(Err.get_error())
return PKCS7(p7_ptr, 1)
-
+
+
+def load_pkcs7_bio_der(p7_bio):
+ # type: (BIO.BIO) -> PKCS7
+ p7_ptr = m2.pkcs7_read_bio_der(p7_bio._ptr())
+ return PKCS7(p7_ptr, 1)
+
def smime_load_pkcs7(p7file):
+ # type: (AnyStr) -> PKCS7
bio = m2.bio_new_file(p7file, 'r')
- if bio is None:
- raise BIO.BIOError(Err.get_error())
-
+
try:
p7_ptr, bio_ptr = m2.smime_read_pkcs7(bio)
finally:
m2.bio_free(bio)
-
- if p7_ptr is None:
- raise SMIME_Error(Err.get_error())
+
if bio_ptr is None:
return PKCS7(p7_ptr, 1), None
else:
return PKCS7(p7_ptr, 1), BIO.BIO(bio_ptr, 1)
-
+
def smime_load_pkcs7_bio(p7_bio):
+ # type: (BIO.BIO) -> PKCS7
p7_ptr, bio_ptr = m2.smime_read_pkcs7(p7_bio._ptr())
if p7_ptr is None:
raise SMIME_Error(Err.get_error())
@@ -108,126 +129,151 @@ def smime_load_pkcs7_bio(p7_bio):
return PKCS7(p7_ptr, 1), None
else:
return PKCS7(p7_ptr, 1), BIO.BIO(bio_ptr, 1)
-
-
-class Cipher:
- """
- Object interface to EVP_CIPHER without all the frills of M2Crypto.EVP.Cipher.
+
+class Cipher(object):
+ """Object interface to EVP_CIPHER without all the frills of
+ M2Crypto.EVP.Cipher.
"""
def __init__(self, algo):
+ # type: (str) -> None
cipher = getattr(m2, algo, None)
if cipher is None:
- raise ValueError, ('unknown cipher', algo)
+ raise ValueError('unknown cipher', algo)
self.cipher = cipher()
def _ptr(self):
return self.cipher
-class SMIME_Error(Exception): pass
+class SMIME_Error(Exception):
+ pass
m2.smime_init(SMIME_Error)
-class SMIME:
- def load_key(self, keyfile, certfile=None, callback=util.passphrase_callback):
+
+# FIXME class has no __init__ method
+class SMIME(object):
+ def load_key(self, keyfile, certfile=None,
+ callback=util.passphrase_callback):
+ # type: (AnyStr, Optional[AnyStr], Callable) -> None
if certfile is None:
certfile = keyfile
self.pkey = EVP.load_key(keyfile, callback)
self.x509 = X509.load_cert(certfile)
- def load_key_bio(self, keybio, certbio=None, callback=util.passphrase_callback):
+ def load_key_bio(self, keybio, certbio=None,
+ callback=util.passphrase_callback):
+ # type: (BIO.BIO, Optional[BIO.BIO], Callable) -> None
if certbio is None:
certbio = keybio
self.pkey = EVP.load_key_bio(keybio, callback)
self.x509 = X509.load_cert_bio(certbio)
def set_x509_stack(self, stack):
+ # type: (X509.X509_Stack) -> None
assert isinstance(stack, X509.X509_Stack)
self.x509_stack = stack
def set_x509_store(self, store):
+ # type: (X509.X509_Store) -> None
assert isinstance(store, X509.X509_Store)
self.x509_store = store
def set_cipher(self, cipher):
+ # type: (Cipher) -> None
assert isinstance(cipher, Cipher)
self.cipher = cipher
def unset_key(self):
+ # type: () -> None
del self.pkey
del self.x509
def unset_x509_stack(self):
+ # type: () -> None
del self.x509_stack
def unset_x509_store(self):
+ # type: () -> None
del self.x509_store
def unset_cipher(self):
+ # type: () -> None
del self.cipher
def encrypt(self, data_bio, flags=0):
+ # type: (BIO.BIO, int) -> PKCS7
if not hasattr(self, 'cipher'):
- raise SMIME_Error, 'no cipher: use set_cipher()'
+ raise SMIME_Error('no cipher: use set_cipher()')
if not hasattr(self, 'x509_stack'):
- raise SMIME_Error, 'no recipient certs: use set_x509_stack()'
- pkcs7 = m2.pkcs7_encrypt(self.x509_stack._ptr(), data_bio._ptr(), self.cipher._ptr(), flags)
- if pkcs7 is None:
- raise SMIME_Error(Err.get_error())
+ raise SMIME_Error('no recipient certs: use set_x509_stack()')
+
+ pkcs7 = m2.pkcs7_encrypt(self.x509_stack._ptr(), data_bio._ptr(),
+ self.cipher._ptr(), flags)
+
return PKCS7(pkcs7, 1)
def decrypt(self, pkcs7, flags=0):
+ # type: (PKCS7, int) -> Optional[bytes]
if not hasattr(self, 'pkey'):
- raise SMIME_Error, 'no private key: use load_key()'
+ raise SMIME_Error('no private key: use load_key()')
if not hasattr(self, 'x509'):
- raise SMIME_Error, 'no certificate: load_key() used incorrectly?'
- blob = m2.pkcs7_decrypt(pkcs7._ptr(), self.pkey._ptr(), self.x509._ptr(), flags)
- if blob is None:
- raise SMIME_Error(Err.get_error())
+ raise SMIME_Error('no certificate: load_key() used incorrectly?')
+ blob = m2.pkcs7_decrypt(pkcs7._ptr(), self.pkey._ptr(),
+ self.x509._ptr(), flags)
return blob
- def sign(self, data_bio, flags=0):
+ def sign(self, data_bio, flags=0, algo='sha1'):
+ # type: (BIO.BIO, int, Optional[str]) -> PKCS7
if not hasattr(self, 'pkey'):
- raise SMIME_Error, 'no private key: use load_key()'
+ raise SMIME_Error('no private key: use load_key()')
+
+ hash = getattr(m2, algo, None)
+
+ if hash is None:
+ raise SMIME_Error('no such hash algorithm %s' % algo)
+
if hasattr(self, 'x509_stack'):
- pkcs7 = m2.pkcs7_sign1(self.x509._ptr(), self.pkey._ptr(),
- self.x509_stack._ptr(), data_bio._ptr(), flags)
- if pkcs7 is None:
- raise SMIME_Error(Err.get_error())
+ pkcs7 = m2.pkcs7_sign1(self.x509._ptr(), self.pkey._ptr(),
+ self.x509_stack._ptr(),
+ data_bio._ptr(), hash(), flags)
return PKCS7(pkcs7, 1)
else:
- pkcs7 = m2.pkcs7_sign0(self.x509._ptr(), self.pkey._ptr(),
- data_bio._ptr(), flags)
- if pkcs7 is None:
- raise SMIME_Error(Err.get_error())
+ pkcs7 = m2.pkcs7_sign0(self.x509._ptr(), self.pkey._ptr(),
+ data_bio._ptr(), hash(), flags)
return PKCS7(pkcs7, 1)
def verify(self, pkcs7, data_bio=None, flags=0):
+ # type: (PKCS7, BIO.BIO, int) -> Optional[bytes]
if not hasattr(self, 'x509_stack'):
- raise SMIME_Error, 'no signer certs: use set_x509_stack()'
+ raise SMIME_Error('no signer certs: use set_x509_stack()')
if not hasattr(self, 'x509_store'):
- raise SMIME_Error, 'no x509 cert store: use set_x509_store()'
+ raise SMIME_Error('no x509 cert store: use set_x509_store()')
assert isinstance(pkcs7, PKCS7), 'pkcs7 not an instance of PKCS7'
p7 = pkcs7._ptr()
if data_bio is None:
- blob = m2.pkcs7_verify0(p7, self.x509_stack._ptr(), self.x509_store._ptr(), flags)
+ blob = m2.pkcs7_verify0(p7, self.x509_stack._ptr(),
+ self.x509_store._ptr(), flags)
else:
- blob = m2.pkcs7_verify1(p7, self.x509_stack._ptr(), self.x509_store._ptr(), data_bio._ptr(), flags)
- if blob is None:
- raise SMIME_Error(Err.get_error())
+ blob = m2.pkcs7_verify1(p7, self.x509_stack._ptr(),
+ self.x509_store._ptr(),
+ data_bio._ptr(), flags)
return blob
def write(self, out_bio, pkcs7, data_bio=None, flags=0):
+ # type: (BIO.BIO, PKCS7, Optional[BIO.BIO], int) -> int
assert isinstance(pkcs7, PKCS7)
if data_bio is None:
return m2.smime_write_pkcs7(out_bio._ptr(), pkcs7._ptr(), flags)
else:
- return m2.smime_write_pkcs7_multi(out_bio._ptr(), pkcs7._ptr(), data_bio._ptr(), flags)
+ return m2.smime_write_pkcs7_multi(out_bio._ptr(), pkcs7._ptr(),
+ data_bio._ptr(), flags)
def text_crlf(text):
+ # type: (bytes) -> bytes
bio_in = BIO.MemoryBuffer(text)
bio_out = BIO.MemoryBuffer()
if m2.smime_crlf_copy(bio_in._ptr(), bio_out._ptr()):
@@ -237,9 +283,9 @@ def text_crlf(text):
def text_crlf_bio(bio_in):
+ # type: (BIO.BIO) -> BIO.BIO
bio_out = BIO.MemoryBuffer()
if m2.smime_crlf_copy(bio_in._ptr(), bio_out._ptr()):
return bio_out
else:
raise SMIME_Error(Err.get_error())
-
diff --git a/M2Crypto/SSL/Checker.py b/M2Crypto/SSL/Checker.py
index 5218663..86ed8ba 100644
--- a/M2Crypto/SSL/Checker.py
+++ b/M2Crypto/SSL/Checker.py
@@ -10,78 +10,105 @@ Copyright 2008 Heikki Toivonen. All rights reserved.
__all__ = ['SSLVerificationError', 'NoCertificate', 'WrongCertificate',
'WrongHost', 'Checker']
-from M2Crypto import util, EVP, m2
import re
+import socket
+
+from M2Crypto import X509, m2, six, util # noqa
+if util.py27plus:
+ from typing import AnyStr, Optional # noqa
+
class SSLVerificationError(Exception):
pass
+
class NoCertificate(SSLVerificationError):
pass
+
class WrongCertificate(SSLVerificationError):
pass
+
class WrongHost(SSLVerificationError):
def __init__(self, expectedHost, actualHost, fieldName='commonName'):
+ # type: (str, AnyStr, str) -> None
"""
This exception will be raised if the certificate returned by the
peer was issued for a different host than we tried to connect to.
This could be due to a server misconfiguration or an active attack.
-
- @param expectedHost: The name of the host we expected to find in the
+
+ :param expectedHost: The name of the host we expected to find in the
certificate.
- @param actualHost: The name of the host we actually found in the
+ :param actualHost: The name of the host we actually found in the
certificate.
- @param fieldName: The field name where we noticed the error. This
+ :param fieldName: The field name where we noticed the error. This
should be either 'commonName' or 'subjectAltName'.
"""
if fieldName not in ('commonName', 'subjectAltName'):
- raise ValueError('Unknown fieldName, should be either commonName or subjectAltName')
-
+ raise ValueError(
+ 'Unknown fieldName, should be either commonName ' +
+ 'or subjectAltName')
+
SSLVerificationError.__init__(self)
self.expectedHost = expectedHost
self.actualHost = actualHost
self.fieldName = fieldName
-
+
def __str__(self):
+ # type: () -> str
s = 'Peer certificate %s does not match host, expected %s, got %s' \
- % (self.fieldName, self.expectedHost, self.actualHost)
- if isinstance(s, unicode):
- s = s.encode('utf8')
- return s
+ % (self.fieldName, self.expectedHost, self.actualHost)
+ return six.ensure_text(s)
-class Checker:
-
+class Checker(object):
+
numericIpMatch = re.compile('^[0-9]+(\.[0-9]+)*$')
-
+
def __init__(self, host=None, peerCertHash=None, peerCertDigest='sha1'):
+ # type: (Optional[str], Optional[bytes], str) -> None
self.host = host
+ if peerCertHash is not None:
+ peerCertHash = six.ensure_binary(peerCertHash)
self.fingerprint = peerCertHash
- self.digest = peerCertDigest
+ self.digest = peerCertDigest # type: str
def __call__(self, peerCert, host=None):
+ # type: (X509.X509, Optional[str]) -> bool
if peerCert is None:
raise NoCertificate('peer did not return certificate')
if host is not None:
- self.host = host
-
+ self.host = host # type: str
+
if self.fingerprint:
if self.digest not in ('sha1', 'md5'):
- raise ValueError('unsupported digest "%s"' %(self.digest))
-
- if (self.digest == 'sha1' and len(self.fingerprint) != 40) or \
- (self.digest == 'md5' and len(self.fingerprint) != 32):
- raise WrongCertificate('peer certificate fingerprint length does not match')
-
- der = peerCert.as_der()
- md = EVP.MessageDigest(self.digest)
- md.update(der)
- digest = md.final()
- if util.octx_to_num(digest) != int(self.fingerprint, 16):
- raise WrongCertificate('peer certificate fingerprint does not match')
+ raise ValueError('unsupported digest "%s"' % self.digest)
+
+ if self.digest == 'sha1':
+ expected_len = 40
+ elif self.digest == 'md5':
+ expected_len = 32
+ else:
+ raise ValueError('Unexpected digest {0}'.format(self.digest))
+
+ if len(self.fingerprint) != expected_len:
+ raise WrongCertificate(
+ ('peer certificate fingerprint length does not match\n' +
+ 'fingerprint: {0}\nexpected = {1}\n' +
+ 'observed = {2}').format(self.fingerprint,
+ expected_len,
+ len(self.fingerprint)))
+
+ expected_fingerprint = six.ensure_text(self.fingerprint)
+ observed_fingerprint = peerCert.get_fingerprint(md=self.digest)
+ if observed_fingerprint != expected_fingerprint:
+ raise WrongCertificate(
+ ('peer certificate fingerprint does not match\n' +
+ 'expected = {0},\n' +
+ 'observed = {1}').format(expected_fingerprint,
+ observed_fingerprint))
if self.host:
hostValidationPassed = False
@@ -93,7 +120,7 @@ class Checker:
if self._splitSubjectAltName(self.host, subjectAltName):
hostValidationPassed = True
elif self.useSubjectAltNameOnly:
- raise WrongHost(expectedHost=self.host,
+ raise WrongHost(expectedHost=self.host,
actualHost=subjectAltName,
fieldName='subjectAltName')
except LookupError:
@@ -103,7 +130,8 @@ class Checker:
if not hostValidationPassed:
hasCommonName = False
commonNames = ''
- for entry in peerCert.get_subject().get_entries_by_nid(m2.NID_commonName):
+ for entry in peerCert.get_subject().get_entries_by_nid(
+ m2.NID_commonName):
hasCommonName = True
commonName = entry.get_data().as_text()
if not commonNames:
@@ -125,31 +153,42 @@ class Checker:
return True
def _splitSubjectAltName(self, host, subjectAltName):
+ # type: (AnyStr, AnyStr) -> bool
"""
>>> check = Checker()
- >>> check._splitSubjectAltName(host='my.example.com', subjectAltName='DNS:my.example.com')
+ >>> check._splitSubjectAltName(host='my.example.com',
+ ... subjectAltName='DNS:my.example.com')
True
- >>> check._splitSubjectAltName(host='my.example.com', subjectAltName='DNS:*.example.com')
+ >>> check._splitSubjectAltName(host='my.example.com',
+ ... subjectAltName='DNS:*.example.com')
True
- >>> check._splitSubjectAltName(host='my.example.com', subjectAltName='DNS:m*.example.com')
+ >>> check._splitSubjectAltName(host='my.example.com',
+ ... subjectAltName='DNS:m*.example.com')
True
- >>> check._splitSubjectAltName(host='my.example.com', subjectAltName='DNS:m*ample.com')
+ >>> check._splitSubjectAltName(host='my.example.com',
+ ... subjectAltName='DNS:m*ample.com')
False
>>> check.useSubjectAltNameOnly
True
- >>> check._splitSubjectAltName(host='my.example.com', subjectAltName='DNS:m*ample.com, othername:<unsupported>')
+ >>> check._splitSubjectAltName(host='my.example.com',
+ ... subjectAltName='DNS:m*ample.com, othername:<unsupported>')
False
- >>> check._splitSubjectAltName(host='my.example.com', subjectAltName='DNS:m*ample.com, DNS:my.example.org')
+ >>> check._splitSubjectAltName(host='my.example.com',
+ ... subjectAltName='DNS:m*ample.com, DNS:my.example.org')
False
- >>> check._splitSubjectAltName(host='my.example.com', subjectAltName='DNS:m*ample.com, DNS:my.example.com')
+ >>> check._splitSubjectAltName(host='my.example.com',
+ ... subjectAltName='DNS:m*ample.com, DNS:my.example.com')
True
- >>> check._splitSubjectAltName(host='my.example.com', subjectAltName='DNS:my.example.com, DNS:my.example.org')
+ >>> check._splitSubjectAltName(host='my.example.com',
+ ... subjectAltName='DNS:my.example.com, DNS:my.example.org')
True
>>> check.useSubjectAltNameOnly
True
- >>> check._splitSubjectAltName(host='my.example.com', subjectAltName='')
+ >>> check._splitSubjectAltName(host='my.example.com',
+ ... subjectAltName='')
False
- >>> check._splitSubjectAltName(host='my.example.com', subjectAltName='othername:<unsupported>')
+ >>> check._splitSubjectAltName(host='my.example.com',
+ ... subjectAltName='othername:<unsupported>')
False
>>> check.useSubjectAltNameOnly
False
@@ -161,10 +200,14 @@ class Checker:
self.useSubjectAltNameOnly = True
if self._match(host, certHost[4:]):
return True
+ elif certHost[:11] == 'ip address:':
+ self.useSubjectAltNameOnly = True
+ if self._matchIPAddress(host, certHost[11:]):
+ return True
return False
-
def _match(self, host, certHost):
+ # type: (str, str) -> bool
"""
>>> check = Checker()
>>> check._match(host='my.example.com', certHost='my.example.com')
@@ -200,7 +243,7 @@ class Checker:
return False
if self.numericIpMatch.match(host) or \
- self.numericIpMatch.match(certHost.replace('*', '')):
+ self.numericIpMatch.match(certHost.replace('*', '')):
# Not sure if * allowed in numeric IP, but think not.
return False
@@ -213,11 +256,41 @@ class Checker:
# Massage certHost so that it can be used in regex
certHost = certHost.replace('.', '\.')
certHost = certHost.replace('*', '[^\.]*')
- if re.compile('^%s$' %(certHost)).match(host):
+ if re.compile('^%s$' % certHost).match(host):
return True
return False
+ def _matchIPAddress(self, host, certHost):
+ # type: (AnyStr, AnyStr) -> bool
+ """
+ >>> check = Checker()
+ >>> check._matchIPAddress(host='my.example.com',
+ ... certHost='my.example.com')
+ False
+ >>> check._matchIPAddress(host='1.2.3.4', certHost='1.2.3.4')
+ True
+ >>> check._matchIPAddress(host='1.2.3.4', certHost='*.2.3.4')
+ False
+ >>> check._matchIPAddress(host='1.2.3.4', certHost='1.2.3.40')
+ False
+ >>> check._matchIPAddress(host='::1', certHost='::1')
+ True
+ >>> check._matchIPAddress(host='::1', certHost='0:0:0:0:0:0:0:1')
+ True
+ >>> check._matchIPAddress(host='::1', certHost='::2')
+ False
+ """
+ try:
+ canonical = socket.getaddrinfo(host, 0, 0, socket.SOCK_STREAM, 0,
+ socket.AI_NUMERICHOST)
+ certCanonical = socket.getaddrinfo(certHost, 0, 0,
+ socket.SOCK_STREAM, 0,
+ socket.AI_NUMERICHOST)
+ except:
+ return False
+ return canonical == certCanonical
+
if __name__ == '__main__':
import doctest
diff --git a/M2Crypto/SSL/Cipher.py b/M2Crypto/SSL/Cipher.py
index 2d2c088..4683377 100644
--- a/M2Crypto/SSL/Cipher.py
+++ b/M2Crypto/SSL/Cipher.py
@@ -4,41 +4,57 @@ Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
__all__ = ['Cipher', 'Cipher_Stack']
-from M2Crypto import m2
+from M2Crypto import m2, py27plus, six
+if py27plus:
+ from typing import Iterable # noqa
-class Cipher:
+
+class Cipher(object):
def __init__(self, cipher):
- self.cipher=cipher
+ # type: (str) -> None
+ self.cipher = cipher
def __len__(self):
+ # type: () -> int
return m2.ssl_cipher_get_bits(self.cipher)
def __repr__(self):
+ # type: () -> str
return "%s-%s" % (self.name(), len(self))
def __str__(self):
+ # type: () -> str
return "%s-%s" % (self.name(), len(self))
def version(self):
+ # type: () -> int
return m2.ssl_cipher_get_version(self.cipher)
def name(self):
- return m2.ssl_cipher_get_name(self.cipher)
+ # type: () -> str
+ return six.ensure_text(m2.ssl_cipher_get_name(self.cipher))
-class Cipher_Stack:
+class Cipher_Stack(object):
def __init__(self, stack):
- self.stack=stack
+ # type: (bytes) -> None
+ """
+ :param stack: binary of the C-type STACK_OF(SSL_CIPHER)
+ """
+ self.stack = stack
def __len__(self):
+ # type: () -> int
return m2.sk_ssl_cipher_num(self.stack)
def __getitem__(self, idx):
+ # type: (int) -> Cipher
if not 0 <= idx < m2.sk_ssl_cipher_num(self.stack):
raise IndexError('index out of range')
- v=m2.sk_ssl_cipher_value(self.stack, idx)
+ v = m2.sk_ssl_cipher_value(self.stack, idx)
return Cipher(v)
def __iter__(self):
- for i in xrange(m2.sk_ssl_cipher_num(self.stack)):
+ # type: () -> Iterable
+ for i in six.moves.range(m2.sk_ssl_cipher_num(self.stack)):
yield self[i]
diff --git a/M2Crypto/SSL/Connection.py b/M2Crypto/SSL/Connection.py
index ef6a2c8..7053aa6 100644
--- a/M2Crypto/SSL/Connection.py
+++ b/M2Crypto/SSL/Connection.py
@@ -1,3 +1,5 @@
+from __future__ import absolute_import
+
"""SSL Connection aka socket
Copyright (c) 1999-2004 Ng Pheng Siong. All rights reserved.
@@ -8,28 +10,30 @@ Copyright (C) 2004-2007 OSAF. All Rights Reserved.
Copyright 2008 Heikki Toivonen. All rights reserved.
"""
+import logging
+import socket
+
+from M2Crypto import BIO, Err, X509, m2, py27plus, six, util # noqa
+from M2Crypto.SSL import Checker, Context, timeout # noqa
+from M2Crypto.SSL import SSLError
+from M2Crypto.SSL.Cipher import Cipher, Cipher_Stack
+from M2Crypto.SSL.Session import Session
+if py27plus:
+ from typing import Any, AnyStr, Callable, Dict, List, Optional, Tuple, Union # noqa
+
__all__ = ['Connection',
- 'timeout', # XXX Not really, but for documentation purposes
+ 'timeout', # XXX Not really, but for documentation purposes
]
-# Python
-import socket
+log = logging.getLogger(__name__)
-# M2Crypto
-from Cipher import Cipher, Cipher_Stack
-from Session import Session
-from M2Crypto import BIO, X509, m2
-import timeout
-import Checker
-
-#SSLError = getattr(__import__('M2Crypto.SSL', globals(), locals(), 'SSLError'), 'SSLError')
-from M2Crypto.SSL import SSLError
def _serverPostConnectionCheck(*args, **kw):
+ # type: (*Any, **Any) -> int
return 1
-class Connection:
+class Connection(object):
"""An SSL connection."""
clientPostConnectionCheck = Checker.Checker()
@@ -37,35 +41,57 @@ class Connection:
m2_bio_free = m2.bio_free
m2_ssl_free = m2.ssl_free
-
- def __init__(self, ctx, sock=None):
+ m2_bio_noclose = m2.bio_noclose
+
+ def __init__(self, ctx, sock=None, family=socket.AF_INET):
+ # type: (Context, socket.socket, int) -> None
+ """
+
+ :param ctx: SSL.Context
+ :param sock: socket to be used
+ :param family: socket family
+ """
self.ctx = ctx
- self.ssl = m2.ssl_new(self.ctx.ctx)
- if sock is not None:
+ self.ssl = m2.ssl_new(self.ctx.ctx) # type: bytes
+ if sock is not None:
self.socket = sock
else:
- self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ self.socket = socket.socket(family, socket.SOCK_STREAM)
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self._fileno = self.socket.fileno()
-
- self.blocking = self.socket.gettimeout()
-
+
+ self._timeout = self.socket.gettimeout()
+ if self._timeout is None:
+ self._timeout = -1.0
+
self.ssl_close_flag = m2.bio_noclose
-
+ if self.ctx.post_connection_check is not None:
+ self.set_post_connection_check_callback(
+ self.ctx.post_connection_check)
+
+ self.host = None
+
def __del__(self):
+ # type: () -> None
+ # Notice that M2Crypto doesn't automatically shuts down the
+ # connection here. You have to call self.close() in your
+ # program, M2Crypto won't do it automatically for you.
if getattr(self, 'sslbio', None):
self.m2_bio_free(self.sslbio)
if getattr(self, 'sockbio', None):
self.m2_bio_free(self.sockbio)
- if self.ssl_close_flag == m2.bio_noclose and getattr(self, 'ssl', None):
+ if self.ssl_close_flag == self.m2_bio_noclose and \
+ getattr(self, 'ssl', None):
self.m2_ssl_free(self.ssl)
self.socket.close()
def close(self):
+ # type: () -> None
m2.ssl_shutdown(self.ssl)
def clear(self):
+ # type: () -> int
"""
If there were errors in this connection, call clear() rather
than close() to end it, so that bad sessions will be cleared
@@ -74,61 +100,116 @@ class Connection:
return m2.ssl_clear(self.ssl)
def set_shutdown(self, mode):
+ # type: (int) -> None
+ """Sets the shutdown state of the Connection to mode.
+
+ The shutdown state of an ssl connection is a bitmask of (use
+ m2.SSL_* constants):
+
+ 0 No shutdown setting, yet.
+
+ SSL_SENT_SHUTDOWN
+ A "close notify" shutdown alert was sent to the peer, the
+ connection is being considered closed and the session is
+ closed and correct.
+
+ SSL_RECEIVED_SHUTDOWN
+ A shutdown alert was received form the peer, either a normal
+ "close notify" or a fatal error.
+
+ SSL_SENT_SHUTDOWN and SSL_RECEIVED_SHUTDOWN can be set at the
+ same time.
+
+ :param mode: set the mode bitmask.
+ """
m2.ssl_set_shutdown1(self.ssl, mode)
def get_shutdown(self):
+ # type: () -> None
+ """Get the current shutdown mode of the Connection."""
return m2.ssl_get_shutdown(self.ssl)
def bind(self, addr):
+ # type: (util.AddrType) -> None
self.socket.bind(addr)
def listen(self, qlen=5):
- self.socket.listen(qlen)
+ # type: (int) -> None
+ self.socket.listen(qlen)
def ssl_get_error(self, ret):
+ # type: (int) -> int
return m2.ssl_get_error(self.ssl, ret)
def set_bio(self, readbio, writebio):
- """
- Explicitly set read and write bios
+ # type: (BIO.BIO, BIO.BIO) -> None
+ """Explicitly set read and write bios
+
+ Connects the BIOs for the read and write operations of the
+ TLS/SSL (encrypted) side of ssl.
+
+ The SSL engine inherits the behaviour of both BIO objects,
+ respectively. If a BIO is non-blocking, the Connection will also
+ have non-blocking behaviour.
+
+ If there was already a BIO connected to Connection, BIO_free()
+ will be called (for both the reading and writing side, if
+ different).
+
+ :param readbio: BIO for reading
+ :param writebio: BIO for writing.
"""
m2.ssl_set_bio(self.ssl, readbio._ptr(), writebio._ptr())
-
+
def set_client_CA_list_from_file(self, cafile):
- """
- Set the acceptable client CA list. If the client
- returns a certificate, it must have been issued by
+ # type: (AnyStr) -> None
+ """Set the acceptable client CA list.
+
+ If the client returns a certificate, it must have been issued by
one of the CAs listed in cafile.
-
+
Makes sense only for servers.
-
- @param cafile: Filename from which to load the CA list.
+
+ :param cafile: Filename from which to load the CA list.
+
+ :return: 0 A failure while manipulating the STACK_OF(X509_NAME)
+ object occurred or the X509_NAME could not be
+ extracted from cacert. Check the error stack to find
+ out the reason.
+
+ 1 The operation succeeded.
"""
m2.ssl_set_client_CA_list_from_file(self.ssl, cafile)
def set_client_CA_list_from_context(self):
+ # type: () -> None
"""
Set the acceptable client CA list. If the client
returns a certificate, it must have been issued by
one of the CAs listed in context.
-
+
Makes sense only for servers.
"""
m2.ssl_set_client_CA_list_from_context(self.ssl, self.ctx.ctx)
def setup_addr(self, addr):
+ # type: (util.AddrType) -> None
self.addr = addr
def set_ssl_close_flag(self, flag):
+ # type: (int) -> None
"""
By default, SSL struct will be freed in __del__. Call with
m2.bio_close to override this default.
+
+ :param flag: either m2.bio_close or m2.bio_noclose
"""
if flag not in (m2.bio_close, m2.bio_noclose):
raise ValueError("flag must be m2.bio_close or m2.bio_noclose")
self.ssl_close_flag = flag
def setup_ssl(self):
+ # type: () -> None
# Make a BIO_s_socket.
self.sockbio = m2.bio_new_socket(self.socket.fileno(), 0)
# Link SSL struct with the BIO_socket.
@@ -139,223 +220,471 @@ class Connection:
m2.bio_set_ssl(self.sslbio, self.ssl, m2.bio_noclose)
def _setup_ssl(self, addr):
+ # type: (util.AddrType) -> None
"""Deprecated"""
self.setup_addr(addr)
self.setup_ssl()
def set_accept_state(self):
+ # type: () -> None
+ """Sets Connection to work in the server mode."""
m2.ssl_set_accept_state(self.ssl)
def accept_ssl(self):
- return m2.ssl_accept(self.ssl)
+ # type: () -> Optional[int]
+ """Waits for a TLS/SSL client to initiate the TLS/SSL handshake.
+
+ The communication channel must already have been set and
+ assigned to the ssl by setting an underlying BIO.
+
+ :return: 0 The TLS/SSL handshake was not successful but was shut
+ down controlled and by the specifications of the
+ TLS/SSL protocol. Call get_error() with the return
+ value ret to find out the reason.
+
+ 1 The TLS/SSL handshake was successfully completed,
+ a TLS/SSL connection has been established.
+
+ <0 The TLS/SSL handshake was not successful because
+ a fatal error occurred either at the protocol level
+ or a connection failure occurred. The shutdown was
+ not clean. It can also occur of action is need to
+ continue the operation for non-blocking BIOs. Call
+ get_error() with the return value ret to find
+ out the reason.
+ """
+ return m2.ssl_accept(self.ssl, self._timeout)
def accept(self):
- """Accept an SSL connection. The return value is a pair (ssl, addr) where
- ssl is a new SSL connection object and addr is the address bound to
- the other end of the SSL connection."""
+ # type: () -> Tuple[Connection, util.AddrType]
+ """Accept an SSL connection.
+
+ The return value is a pair (ssl, addr) where ssl is a new SSL
+ connection object and addr is the address bound to the other end
+ of the SSL connection.
+
+ :return: tuple of Connection and addr. Address can take very
+ various forms (see socket documentation), for IPv4 it
+ is tuple(str, int), for IPv6 a tuple of four (host,
+ port, flowinfo, scopeid), where the last two are
+ optional ints.
+ """
sock, addr = self.socket.accept()
ssl = Connection(self.ctx, sock)
ssl.addr = addr
ssl.setup_ssl()
ssl.set_accept_state()
ssl.accept_ssl()
- check = getattr(self, 'postConnectionCheck', self.serverPostConnectionCheck)
+ check = getattr(self, 'postConnectionCheck',
+ self.serverPostConnectionCheck)
if check is not None:
if not check(ssl.get_peer_cert(), ssl.addr[0]):
- raise Checker.SSLVerificationError, 'post connection check failed'
+ raise Checker.SSLVerificationError(
+ 'post connection check failed')
return ssl, addr
def set_connect_state(self):
+ # type: () -> None
+ """Sets Connection to work in the client mode."""
m2.ssl_set_connect_state(self.ssl)
def connect_ssl(self):
- return m2.ssl_connect(self.ssl)
+ # type: () -> Optional[int]
+ return m2.ssl_connect(self.ssl, self._timeout)
def connect(self, addr):
+ # type: (util.AddrType) -> int
+ """Overloading socket.connect()
+
+ :param addr: addresses have various depending on their type
+
+ :return:status of ssl_connect()
+ """
self.socket.connect(addr)
self.addr = addr
self.setup_ssl()
self.set_connect_state()
ret = self.connect_ssl()
- check = getattr(self, 'postConnectionCheck', self.clientPostConnectionCheck)
+ check = getattr(self, 'postConnectionCheck',
+ self.clientPostConnectionCheck)
if check is not None:
- if not check(self.get_peer_cert(), self.addr[0]):
- raise Checker.SSLVerificationError, 'post connection check failed'
+ if not check(self.get_peer_cert(),
+ self.host if self.host else self.addr[0]):
+ raise Checker.SSLVerificationError(
+ 'post connection check failed')
return ret
def shutdown(self, how):
+ # type: (int) -> None
m2.ssl_set_shutdown(self.ssl, how)
def renegotiate(self):
+ # type: () -> int
"""Renegotiate this connection's SSL parameters."""
return m2.ssl_renegotiate(self.ssl)
def pending(self):
- """Return the numbers of octets that can be read from the
- connection."""
+ # type: () -> int
+ """Return the numbers of octets that can be read from the connection."""
return m2.ssl_pending(self.ssl)
def _write_bio(self, data):
- return m2.ssl_write(self.ssl, data)
+ # type: (bytes) -> int
+ return m2.ssl_write(self.ssl, data, self._timeout)
def _write_nbio(self, data):
+ # type: (bytes) -> int
return m2.ssl_write_nbio(self.ssl, data)
def _read_bio(self, size=1024):
+ # type: (int) -> bytes
if size <= 0:
- raise ValueError, 'size <= 0'
- return m2.ssl_read(self.ssl, size)
+ raise ValueError('size <= 0')
+ return m2.ssl_read(self.ssl, size, self._timeout)
def _read_nbio(self, size=1024):
+ # type: (int) -> bytes
if size <= 0:
- raise ValueError, 'size <= 0'
+ raise ValueError('size <= 0')
return m2.ssl_read_nbio(self.ssl, size)
def write(self, data):
- if self.blocking:
+ # type: (bytes) -> int
+ if self._timeout != 0.0:
return self._write_bio(data)
return self._write_nbio(data)
sendall = send = write
-
+
+ def _decref_socketios(self):
+ pass
+
+ def recv_into(self, buff, nbytes=0):
+ # type: (Union[bytearray, memoryview], int) -> int
+ """
+ A version of recv() that stores its data into a buffer rather
+ than creating a new string. Receive up to buffersize bytes from
+ the socket. If buffersize is not specified (or 0), receive up
+ to the size available in the given buffer.
+
+ If buff is bytearray, it will have after return length of the
+ actually returned number of bytes. If buff is memoryview, then
+ the size of buff won't change (it cannot), but all bytes after
+ the number of returned bytes will be NULL.
+
+ :param buffer: a buffer for the received bytes
+ :param nbytes: maximum number of bytes to read
+ :return: number of bytes read
+
+ See recv() for documentation about the flags.
+ """
+ n = len(buff) if nbytes == 0 else nbytes
+
+ if n <= 0:
+ raise ValueError('size <= 0')
+
+ # buff_bytes are actual bytes returned
+ buff_bytes = m2.ssl_read(self.ssl, n, self._timeout)
+ buflen = len(buff_bytes)
+
+ # memoryview type has been added in 2.7
+ if py27plus and isinstance(buff, memoryview):
+ buff[:buflen] = buff_bytes
+ buff[buflen:] = b'\x00' * (len(buff) - buflen)
+ else:
+ buff[:] = buff_bytes
+
+ return buflen
+
def read(self, size=1024):
- if self.blocking:
+ # type: (int) -> bytes
+ if self._timeout != 0.0:
return self._read_bio(size)
return self._read_nbio(size)
recv = read
def setblocking(self, mode):
- """Set this connection's underlying socket to _mode_."""
+ # type: (int) -> None
+ """Set this connection's underlying socket to _mode_.
+
+ Set blocking or non-blocking mode of the socket: if flag is 0,
+ the socket is set to non-blocking, else to blocking mode.
+ Initially all sockets are in blocking mode. In non-blocking mode,
+ if a recv() call doesn't find any data, or if a send() call can't
+ immediately dispose of the data, a error exception is raised;
+ in blocking mode, the calls block until they can proceed.
+ s.setblocking(0) is equivalent to s.settimeout(0.0);
+ s.setblocking(1) is equivalent to s.settimeout(None).
+
+ :param mode: new mode to be set
+ """
self.socket.setblocking(mode)
- self.blocking = mode
+ if mode:
+ self._timeout = -1.0
+ else:
+ self._timeout = 0.0
+
+ def settimeout(self, timeout):
+ # type: (float) -> None
+ """Set this connection's underlying socket's timeout to _timeout_."""
+ self.socket.settimeout(timeout)
+ self._timeout = timeout
+ if self._timeout is None:
+ self._timeout = -1.0
def fileno(self):
+ # type: () -> int
return self.socket.fileno()
- def getsockopt(self, *args):
- return apply(self.socket.getsockopt, args)
+ def getsockopt(self, level, optname, buflen=None):
+ # type: (int, int, Optional[int]) -> Union[int, bytes]
+ """Get the value of the given socket option.
+
+ :param level: level at which the option resides.
+ To manipulate options at the sockets API level, level is
+ specified as socket.SOL_SOCKET. To manipulate options at
+ any other level the protocol number of the appropriate
+ protocol controlling the option is supplied. For example,
+ to indicate that an option is to be interpreted by the
+ TCP protocol, level should be set to the protocol number
+ of socket.SOL_TCP; see getprotoent(3).
+
+ :param optname: The value of the given socket option is
+ described in the Unix man page getsockopt(2)). The needed
+ symbolic constants (SO_* etc.) are defined in the socket
+ module.
+
+ :param buflen: If it is absent, an integer option is assumed
+ and its integer value is returned by the function. If
+ buflen is present, it specifies the maximum length of the
+ buffer used to receive the option in, and this buffer is
+ returned as a bytes object.
+
+ :return: Either integer or bytes value of the option. It is up
+ to the caller to decode the contents of the buffer (see
+ the optional built-in module struct for a way to decode
+ C structures encoded as byte strings).
+ """
+ return self.socket.getsockopt(level, optname, buflen)
- def setsockopt(self, *args):
- return apply(self.socket.setsockopt, args)
+ def setsockopt(self, level, optname, value=None):
+ # type: (int, int, Union[int, bytes, None]) -> Optional[bytes]
+ """Set the value of the given socket option.
+
+ :param level: same as with getsockopt() above
+
+ :param optname: same as with getsockopt() above
+
+ :param value: an integer or a string representing a buffer. In
+ the latter case it is up to the caller to ensure
+ that the string contains the proper bits (see the
+ optional built-in module struct for a way to
+ encode C structures as strings).
+
+ :return: None for success or the error handler for failure.
+ """
+ return self.socket.setsockopt(level, optname, value)
def get_context(self):
- """Return the SSL.Context object associated with this
- connection."""
+ # type: () -> Context
+ """Return the Context object associated with this connection."""
return m2.ssl_get_ssl_ctx(self.ssl)
def get_state(self):
- """Return the SSL state of this connection."""
+ # type: () -> bytes
+ """Return the SSL state of this connection.
+
+ During its use, an SSL objects passes several states. The state
+ is internally maintained. Querying the state information is not
+ very informative before or when a connection has been
+ established. It however can be of significant interest during
+ the handshake.
+
+ :return: 6 letter string indicating the current state of the SSL
+ object ssl.
+ """
return m2.ssl_get_state(self.ssl)
def verify_ok(self):
+ # type: () -> bool
return (m2.ssl_get_verify_result(self.ssl) == m2.X509_V_OK)
def get_verify_mode(self):
+ # type: () -> int
"""Return the peer certificate verification mode."""
return m2.ssl_get_verify_mode(self.ssl)
def get_verify_depth(self):
+ # type: () -> int
"""Return the peer certificate verification depth."""
return m2.ssl_get_verify_depth(self.ssl)
def get_verify_result(self):
+ # type: () -> int
"""Return the peer certificate verification result."""
return m2.ssl_get_verify_result(self.ssl)
def get_peer_cert(self):
- """Return the peer certificate; if the peer did not provide
- a certificate, return None."""
- c=m2.ssl_get_peer_cert(self.ssl)
+ # type: () -> X509.X509
+ """Return the peer certificate.
+
+ If the peer did not provide a certificate, return None.
+ """
+ c = m2.ssl_get_peer_cert(self.ssl)
if c is None:
return None
# Need to free the pointer coz OpenSSL doesn't.
return X509.X509(c, 1)
-
+
def get_peer_cert_chain(self):
- """Return the peer certificate chain; if the peer did not provide
+ # type: () -> Optional[X509.X509_Stack]
+ """Return the peer certificate chain; if the peer did not provide
a certificate chain, return None.
-
- @warning: The returned chain will be valid only for as long as the
- connection object is alive. Once the connection object gets freed,
- the chain will be freed as well.
+
+ :warning: The returned chain will be valid only for as long as the
+ connection object is alive. Once the connection object
+ gets freed, the chain will be freed as well.
"""
- c=m2.ssl_get_peer_cert_chain(self.ssl)
+ c = m2.ssl_get_peer_cert_chain(self.ssl)
if c is None:
return None
# No need to free the pointer coz OpenSSL does.
return X509.X509_Stack(c)
-
+
def get_cipher(self):
- """Return an M2Crypto.SSL.Cipher object for this connection; if the
- connection has not been initialised with a cipher suite, return None."""
- c=m2.ssl_get_current_cipher(self.ssl)
+ # type: () -> Optional[Cipher]
+ """Return an M2Crypto.SSL.Cipher object for this connection; if the
+ connection has not been initialised with a cipher suite, return None.
+ """
+ c = m2.ssl_get_current_cipher(self.ssl)
if c is None:
return None
return Cipher(c)
-
+
def get_ciphers(self):
- """Return an M2Crypto.SSL.Cipher_Stack object for this connection; if the
- connection has not been initialised with cipher suites, return None."""
- c=m2.ssl_get_ciphers(self.ssl)
+ # type: () -> Optional[Cipher_Stack]
+ """Return an M2Crypto.SSL.Cipher_Stack object for this
+ connection; if the connection has not been initialised with
+ cipher suites, return None.
+ """
+ c = m2.ssl_get_ciphers(self.ssl)
if c is None:
return None
return Cipher_Stack(c)
def get_cipher_list(self, idx=0):
+ # type: (int) -> str
"""Return the cipher suites for this connection as a string object."""
- return m2.ssl_get_cipher_list(self.ssl, idx)
+ return six.ensure_text(m2.ssl_get_cipher_list(self.ssl, idx))
def set_cipher_list(self, cipher_list):
+ # type: (str) -> int
"""Set the cipher suites for this connection."""
return m2.ssl_set_cipher_list(self.ssl, cipher_list)
- def makefile(self, mode='rb', bufsize='ignored'):
- r = 'r' in mode or '+' in mode
- w = 'w' in mode or 'a' in mode or '+' in mode
- b = 'b' in mode
- m2mode = ['', 'r'][r] + ['', 'w'][w] + ['', 'b'][b]
- # XXX Need to dup().
- bio = BIO.BIO(self.sslbio, _close_cb=self.close)
- m2.bio_do_handshake(bio._ptr())
- return BIO.IOBuffer(bio, m2mode, _pyfree=0)
+ def makefile(self, mode='rb', bufsize=-1):
+ # type: (AnyStr, int) -> socket._fileobject
+ if six.PY3:
+ return socket.SocketIO(self, mode)
+ else:
+ return socket._fileobject(self, mode, bufsize)
def getsockname(self):
+ # type: () -> util.AddrType
+ """Return the socket's own address.
+
+ This is useful to find out the port number of an IPv4/v6 socket,
+ for instance. (The format of the address returned depends
+ on the address family -- see above.)
+
+ :return:socket's address as addr type
+ """
return self.socket.getsockname()
def getpeername(self):
+ # type: () -> util.AddrType
+ """Return the remote address to which the socket is connected.
+
+ This is useful to find out the port number of a remote IPv4/v6 socket,
+ for instance.
+ On some systems this function is not supported.
+
+ :return:
+ """
return self.socket.getpeername()
def set_session_id_ctx(self, id):
+ # type: (bytes) -> int
ret = m2.ssl_set_session_id_context(self.ssl, id)
if not ret:
- raise SSLError(m2.err_reason_error_string(m2.err_get_error()))
+ raise SSLError(Err.get_error_message())
def get_session(self):
+ # type: () -> Session
sess = m2.ssl_get_session(self.ssl)
return Session(sess)
def set_session(self, session):
+ # type: (Session) -> None
m2.ssl_set_session(self.ssl, session._ptr())
def get_default_session_timeout(self):
+ # type: () -> int
return m2.ssl_get_default_session_timeout(self.ssl)
def get_socket_read_timeout(self):
- return timeout.struct_to_timeout(self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_RCVTIMEO, timeout.struct_size()))
+ # type: () -> timeout
+ return timeout.struct_to_timeout(
+ self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_RCVTIMEO,
+ timeout.struct_size()))
+
+ @staticmethod
+ def _hexdump(s):
+ assert isinstance(s, six.binary_type)
+ return ":".join("{0:02x}".format(ord(c) if six.PY2 else c) for c in s)
def get_socket_write_timeout(self):
- return timeout.struct_to_timeout(self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_SNDTIMEO, timeout.struct_size()))
+ # type: () -> timeout
+ binstr = self.socket.getsockopt(
+ socket.SOL_SOCKET, socket.SO_SNDTIMEO, timeout.struct_size())
+ timeo = timeout.struct_to_timeout(binstr)
+ #print("Debug: get_socket_write_timeout: "
+ # "get sockopt value: %s -> returned timeout(sec=%r, microsec=%r)" %
+ # (self._hexdump(binstr), timeo.sec, timeo.microsec))
+ return timeo
def set_socket_read_timeout(self, timeo):
+ # type: (timeout) -> None
assert isinstance(timeo, timeout.timeout)
- self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_RCVTIMEO, timeo.pack())
+ self.socket.setsockopt(
+ socket.SOL_SOCKET, socket.SO_RCVTIMEO, timeo.pack())
def set_socket_write_timeout(self, timeo):
+ # type: (timeout) -> None
assert isinstance(timeo, timeout.timeout)
- self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_SNDTIMEO, timeo.pack())
+ binstr = timeo.pack()
+ #print("Debug: set_socket_write_timeout: "
+ # "input timeout(sec=%r, microsec=%r) -> set sockopt value: %s" %
+ # (timeo.sec, timeo.microsec, self._hexdump(binstr)))
+ self.socket.setsockopt(
+ socket.SOL_SOCKET, socket.SO_SNDTIMEO, binstr)
def get_version(self):
- "Return the TLS/SSL protocol version for this connection."
- return m2.ssl_get_version(self.ssl)
+ # type: () -> str
+ """Return the TLS/SSL protocol version for this connection."""
+ return six.ensure_text(m2.ssl_get_version(self.ssl))
- def set_post_connection_check_callback(self, postConnectionCheck):
+ def set_post_connection_check_callback(self, postConnectionCheck): # noqa
+ # type: (Callable) -> None
self.postConnectionCheck = postConnectionCheck
+
+ def set_tlsext_host_name(self, name):
+ # type: (bytes) -> None
+ """Set the requested hostname for the SNI (Server Name Indication)
+ extension.
+ """
+ m2.ssl_set_tlsext_host_name(self.ssl, name)
+
+ def set1_host(self, name):
+ # type: (bytes) -> None
+ """Set the requested hostname to check in the server certificate."""
+ self.host = name
diff --git a/M2Crypto/SSL/Context.py b/M2Crypto/SSL/Context.py
index b8d159f..7faccf0 100644
--- a/M2Crypto/SSL/Context.py
+++ b/M2Crypto/SSL/Context.py
@@ -1,114 +1,135 @@
+from __future__ import absolute_import
+
"""SSL Context
Copyright (c) 1999-2004 Ng Pheng Siong. All rights reserved."""
-__all__ = ['map', 'Context']
-
+from M2Crypto import BIO, Err, RSA, X509, m2, util # noqa
+from M2Crypto.SSL import cb # noqa
+from M2Crypto.SSL.Session import Session # noqa
from weakref import WeakValueDictionary
+if util.py27plus:
+ from typing import Any, AnyStr, Callable, Optional, Union # noqa
+
+__all__ = ['ctxmap', 'Context', 'map']
-# M2Crypto
-import cb
-from M2Crypto import util, BIO, Err, RSA, m2, X509
-class _ctxmap:
- singleton = None
+class _ctxmap(object):
+ singleton = None # type: Optional[_ctxmap]
+
def __init__(self):
- self.map = WeakValueDictionary()
+ # type: () -> None
+ """Simple WeakReffed list.
+ """
+ self._ctxmap = WeakValueDictionary()
def __getitem__(self, key):
- return self.map[key]
+ # type: (int) -> Any
+ return self._ctxmap[key]
def __setitem__(self, key, value):
- self.map[key] = value
+ # type: (int, Any) -> None
+ self._ctxmap[key] = value
def __delitem__(self, key):
- del self.map[key]
+ # type: (int) -> None
+ del self._ctxmap[key]
-def map():
+
+def ctxmap():
+ # type: () -> _ctxmap
if _ctxmap.singleton is None:
_ctxmap.singleton = _ctxmap()
return _ctxmap.singleton
+# deprecated!!!
+map = ctxmap
-class Context:
+class Context(object):
"""'Context' for SSL connections."""
m2_ssl_ctx_free = m2.ssl_ctx_free
- def __init__(self, protocol='sslv23', weak_crypto=None):
+ def __init__(self, protocol='tls', weak_crypto=None,
+ post_connection_check=None):
+ # type: (str, Optional[int], Optional[Callable]) -> None
proto = getattr(m2, protocol + '_method', None)
if proto is None:
- raise ValueError, "no such protocol '%s'" % protocol
+ # default is 'sslv23' for older versions of OpenSSL
+ if protocol == 'tls':
+ proto = getattr(m2, 'sslv23_method')
+ else:
+ raise ValueError("no such protocol '%s'" % protocol)
self.ctx = m2.ssl_ctx_new(proto())
- self.allow_unknown_ca = 0
- map()[long(self.ctx)] = self
- m2.ssl_ctx_set_cache_size(self.ctx, 128L)
- if weak_crypto is None:
- if protocol == 'sslv23':
- self.set_options(m2.SSL_OP_ALL | m2.SSL_OP_NO_SSLv2)
- self.set_cipher_list('ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH')
-
+ self.allow_unknown_ca = 0 # type: Union[int, bool]
+ self.post_connection_check = post_connection_check
+ ctxmap()[int(self.ctx)] = self
+ m2.ssl_ctx_set_cache_size(self.ctx, 128)
+ if weak_crypto is None and protocol in ('sslv23', 'tls'):
+ self.set_options(m2.SSL_OP_ALL | m2.SSL_OP_NO_SSLv2 |
+ m2.SSL_OP_NO_SSLv3)
+
def __del__(self):
+ # type: () -> None
if getattr(self, 'ctx', None):
self.m2_ssl_ctx_free(self.ctx)
def close(self):
- del map()[long(self.ctx)]
-
- def load_cert(self, certfile, keyfile=None, callback=util.passphrase_callback):
+ # type: () -> None
+ del ctxmap()[int(self.ctx)]
+
+ def load_cert(self, certfile, keyfile=None,
+ callback=util.passphrase_callback):
+ # type: (AnyStr, Optional[AnyStr], Callable) -> None
"""Load certificate and private key into the context.
-
- @param certfile: File that contains the PEM-encoded certificate.
- @type certfile: str
- @param keyfile: File that contains the PEM-encoded private key.
+
+ :param certfile: File that contains the PEM-encoded certificate.
+ :param keyfile: File that contains the PEM-encoded private key.
Default value of None indicates that the private key
is to be found in 'certfile'.
- @type keyfile: str
-
- @param callback: Callable object to be invoked if the private key is
+ :param callback: Callable object to be invoked if the private key is
passphrase-protected. Default callback provides a
simple terminal-style input for the passphrase.
"""
m2.ssl_ctx_passphrase_callback(self.ctx, callback)
m2.ssl_ctx_use_cert(self.ctx, certfile)
- if not keyfile:
+ if not keyfile:
keyfile = certfile
m2.ssl_ctx_use_privkey(self.ctx, keyfile)
if not m2.ssl_ctx_check_privkey(self.ctx):
- raise ValueError, 'public/private key mismatch'
+ raise ValueError('public/private key mismatch')
- def load_cert_chain(self, certchainfile, keyfile=None, callback=util.passphrase_callback):
+ def load_cert_chain(self, certchainfile, keyfile=None,
+ callback=util.passphrase_callback):
+ # type: (AnyStr, Optional[AnyStr], Callable) -> None
"""Load certificate chain and private key into the context.
-
- @param certchainfile: File object containing the PEM-encoded
+
+ :param certchainfile: File object containing the PEM-encoded
certificate chain.
- @type certchainfile: str
- @param keyfile: File object containing the PEM-encoded private
+ :param keyfile: File object containing the PEM-encoded private
key. Default value of None indicates that the
private key is to be found in 'certchainfile'.
- @type keyfile: str
-
- @param callback: Callable object to be invoked if the private key
- is passphrase-protected. Default callback
+ :param callback: Callable object to be invoked if the private key
+ is passphrase-protected. Default callback
provides a simple terminal-style input for the
passphrase.
"""
m2.ssl_ctx_passphrase_callback(self.ctx, callback)
m2.ssl_ctx_use_cert_chain(self.ctx, certchainfile)
- if not keyfile:
+ if not keyfile:
keyfile = certchainfile
m2.ssl_ctx_use_privkey(self.ctx, keyfile)
if not m2.ssl_ctx_check_privkey(self.ctx):
- raise ValueError, 'public/private key mismatch'
+ raise ValueError('public/private key mismatch')
def set_client_CA_list_from_file(self, cafile):
+ # type: (AnyStr) -> None
"""Load CA certs into the context. These CA certs are sent to the
peer during *SSLv3 certificate request*.
-
- @param cafile: File object containing one or more PEM-encoded CA
+
+ :param cafile: File object containing one or more PEM-encoded CA
certificates concatenated together.
- @type cafile: str
"""
m2.ssl_ctx_set_client_CA_list_from_file(self.ctx, cafile)
@@ -116,15 +137,23 @@ class Context:
load_client_CA = load_client_ca = set_client_CA_list_from_file
def load_verify_locations(self, cafile=None, capath=None):
- """Load CA certs into the context. These CA certs are used during
- verification of the peer's certificate.
+ # type: (Optional[AnyStr], Optional[AnyStr]) -> int
+ """Load CA certs into the context.
+
+ These CA certs are used during verification of the peer's
+ certificate.
- @param cafile: File containing one or more PEM-encoded CA certificates
- concatenated together.
- @type cafile: str
- @param capath: Directory containing PEM-encoded CA certificates
+ :param cafile: File containing one or more PEM-encoded CA
+ certificates concatenated together.
+
+ :param capath: Directory containing PEM-encoded CA certificates
(one certificate per file).
- @type capath: str
+
+ :return: 0 if the operation failed because CAfile and CApath are NULL
+ or the processing at one of the locations specified failed.
+ Check the error stack to find out the reason.
+
+ 1 The operation succeeded.
"""
if cafile is None and capath is None:
raise ValueError("cafile and capath can not both be None.")
@@ -134,38 +163,79 @@ class Context:
load_verify_info = load_verify_locations
def set_session_id_ctx(self, id):
+ # type: (bytes) -> None
+ """Sets the session id for the SSL.Context w/in a session can be reused.
+
+ :param id: Sessions are generated within a certain context. When
+ exporting/importing sessions with
+ i2d_SSL_SESSION/d2i_SSL_SESSION it would be possible,
+ to re-import a session generated from another context
+ (e.g. another application), which might lead to
+ malfunctions. Therefore each application must set its
+ own session id context sid_ctx which is used to
+ distinguish the contexts and is stored in exported
+ sessions. The sid_ctx can be any kind of binary data
+ with a given length, it is therefore possible to use
+ e.g. the name of the application and/or the hostname
+ and/or service name.
+ """
ret = m2.ssl_ctx_set_session_id_context(self.ctx, id)
if not ret:
raise Err.SSLError(Err.get_error_code(), '')
- def set_allow_unknown_ca(self, ok):
- """Set the context to accept/reject a peer certificate if the
+ def set_default_verify_paths(self):
+ # type: () -> int
+ """
+ Specifies that the default locations from which CA certs are
+ loaded should be used.
+
+ There is one default directory and one default file. The default
+ CA certificates directory is called "certs" in the default
+ OpenSSL directory. Alternatively the SSL_CERT_DIR environment
+ variable can be defined to override this location. The default
+ CA certificates file is called "cert.pem" in the default OpenSSL
+ directory. Alternatively the SSL_CERT_FILE environment variable
+ can be defined to override this location.
+
+ @return 0 if the operation failed. A missing default location is
+ still treated as a success. No error code is set.
+
+ 1 The operation succeeded.
+ """
+ ret = m2.ssl_ctx_set_default_verify_paths(self.ctx)
+ if not ret:
+ raise ValueError('Cannot use default SSL certificate store!')
+
+ def set_allow_unknown_ca(self, ok):
+ # type: (Union[int, bool]) -> None
+ """Set the context to accept/reject a peer certificate if the
certificate's CA is unknown.
- @param ok: True to accept, False to reject.
- @type ok: boolean
+ :param ok: True to accept, False to reject.
"""
self.allow_unknown_ca = ok
def get_allow_unknown_ca(self):
+ # type: () -> Union[int, bool]
"""Get the context's setting that accepts/rejects a peer
certificate if the certificate's CA is unknown.
+
+ FIXME 2Bconverted to bool
"""
return self.allow_unknown_ca
def set_verify(self, mode, depth, callback=None):
+ # type: (int, int, Optional[Callable]) -> None
"""
Set verify options. Most applications will need to call this
method with the right options to make a secure SSL connection.
-
- @param mode: The verification mode to use. Typically at least
+
+ :param mode: The verification mode to use. Typically at least
SSL.verify_peer is used. Clients would also typically
add SSL.verify_fail_if_no_peer_cert.
- @type mode: int
- @param depth: The maximum allowed depth of the certificate chain
+ :param depth: The maximum allowed depth of the certificate chain
returned by the peer.
- @type depth: int
- @param callback: Callable that can be used to specify custom
+ :param callback: Callable that can be used to specify custom
verification checks.
"""
if callback is None:
@@ -175,80 +245,202 @@ class Context:
m2.ssl_ctx_set_verify_depth(self.ctx, depth)
def get_verify_mode(self):
+ # type: () -> int
return m2.ssl_ctx_get_verify_mode(self.ctx)
def get_verify_depth(self):
+ # type: () -> int
+ """Returns the verification mode currently set in the SSL Context."""
return m2.ssl_ctx_get_verify_depth(self.ctx)
def set_tmp_dh(self, dhpfile):
+ # type: (AnyStr) -> int
"""Load ephemeral DH parameters into the context.
- @param dhpfile: File object containing the PEM-encoded DH
- parameters.
- @type dhpfile: str
+ :param dhpfile: Filename of the file containing the PEM-encoded
+ DH parameters.
"""
f = BIO.openfile(dhpfile)
dhp = m2.dh_read_parameters(f.bio_ptr())
return m2.ssl_ctx_set_tmp_dh(self.ctx, dhp)
def set_tmp_dh_callback(self, callback=None):
+ # type: (Optional[Callable]) -> None
+ """Sets the callback function for SSL.Context.
+
+ :param callback: Callable to be used when a DH parameters are required.
+ """
if callback is not None:
- m2.ssl_ctx_set_tmp_dh_callback(self.ctx, callback)
+ m2.ssl_ctx_set_tmp_dh_callback(self.ctx, callback)
def set_tmp_rsa(self, rsa):
+ # type: (RSA.RSA) -> int
"""Load ephemeral RSA key into the context.
- @param rsa: M2Crypto.RSA.RSA instance.
+ :param rsa: RSA.RSA instance.
"""
if isinstance(rsa, RSA.RSA):
return m2.ssl_ctx_set_tmp_rsa(self.ctx, rsa.rsa)
else:
- raise TypeError, "Expected an instance of RSA.RSA, got %s." % (rsa,)
+ raise TypeError("Expected an instance of RSA.RSA, got %s." % rsa)
def set_tmp_rsa_callback(self, callback=None):
+ # type: (Optional[Callable]) -> None
+ """Sets the callback function to be used when
+ a temporary/ephemeral RSA key is required.
+ """
if callback is not None:
- m2.ssl_ctx_set_tmp_rsa_callback(self.ctx, callback)
+ m2.ssl_ctx_set_tmp_rsa_callback(self.ctx, callback)
def set_info_callback(self, callback=cb.ssl_info_callback):
+ # type: (Callable) -> None
+ """Set a callback function to get state information.
+
+ It can be used to get state information about the SSL
+ connections that are created from this context.
+
+ :param callback: Callback function. The default prints
+ information to stderr.
"""
- Set a callback function that can be used to get state information
- about the SSL connections that are created from this context.
-
- @param callback: Callback function. The default prints information to
- stderr.
- """
- m2.ssl_ctx_set_info_callback(self.ctx, callback)
+ m2.ssl_ctx_set_info_callback(self.ctx, callback)
def set_cipher_list(self, cipher_list):
+ # type: (str) -> int
+ """Sets the list of available ciphers.
+
+ :param cipher_list: The format of the string is described in
+ ciphers(1).
+ :return: 1 if any cipher could be selected and 0 on complete
+ failure.
+ """
return m2.ssl_ctx_set_cipher_list(self.ctx, cipher_list)
def add_session(self, session):
+ # type: (Session) -> int
+ """Add the session to the context.
+
+ :param session: the session to be added.
+
+ :return: 0 The operation failed. It was tried to add the same
+ (identical) session twice.
+
+ 1 The operation succeeded.
+ """
return m2.ssl_ctx_add_session(self.ctx, session._ptr())
def remove_session(self, session):
+ # type: (Session) -> int
+ """Remove the session from the context.
+
+ :param session: the session to be removed.
+
+ :return: 0 The operation failed. The session was not found in
+ the cache.
+
+ 1 The operation succeeded.
+ """
return m2.ssl_ctx_remove_session(self.ctx, session._ptr())
def get_session_timeout(self):
+ # type: () -> int
+ """Get current session timeout.
+
+ Whenever a new session is created, it is assigned a maximum
+ lifetime. This lifetime is specified by storing the creation
+ time of the session and the timeout value valid at this time. If
+ the actual time is later than creation time plus timeout, the
+ session is not reused.
+
+ Due to this realization, all sessions behave according to the
+ timeout value valid at the time of the session negotiation.
+ Changes of the timeout value do not affect already established
+ sessions.
+
+ Expired sessions are removed from the internal session cache,
+ whenever SSL_CTX_flush_sessions(3) is called, either directly by
+ the application or automatically (see
+ SSL_CTX_set_session_cache_mode(3))
+
+ The default value for session timeout is decided on a per
+ protocol basis, see SSL_get_default_timeout(3). All currently
+ supported protocols have the same default timeout value of 300
+ seconds.
+
+ SSL_CTX_set_timeout() returns the previously set timeout value.
+
+ :return: the currently set timeout value.
+ """
return m2.ssl_ctx_get_session_timeout(self.ctx)
def set_session_timeout(self, timeout):
+ # type: (int) -> int
+ """Set new session timeout.
+
+ See self.get_session_timeout() for explanation of the session
+ timeouts.
+
+ :param timeout: new timeout value.
+
+ :return: the previously set timeout value.
+ """
return m2.ssl_ctx_set_session_timeout(self.ctx, timeout)
def set_session_cache_mode(self, mode):
+ # type: (int) -> int
+ """Enables/disables session caching.
+
+ The mode is set by using m2.SSL_SESS_CACHE_* constants.
+
+ :param mode: new mode value.
+
+ :return: the previously set cache mode value.
+ """
return m2.ssl_ctx_set_session_cache_mode(self.ctx, mode)
def get_session_cache_mode(self):
+ # type: () -> int
+ """Gets the current session caching.
+
+ The mode is set to m2.SSL_SESS_CACHE_* constants.
+
+ :return: the previously set cache mode value.
+ """
return m2.ssl_ctx_get_session_cache_mode(self.ctx)
def set_options(self, op):
+ # type: (int) -> int
+ """Adds the options set via bitmask in options to the Context.
+
+ !!! Options already set before are not cleared!
+
+ The behaviour of the SSL library can be changed by setting
+ several options. The options are coded as bitmasks and can be
+ combined by a logical or operation (|).
+
+ SSL.Context.set_options() and SSL.set_options() affect the
+ (external) protocol behaviour of the SSL library. The (internal)
+ behaviour of the API can be changed by using the similar
+ SSL.Context.set_mode() and SSL.set_mode() functions.
+
+ During a handshake, the option settings of the SSL object are
+ used. When a new SSL object is created from a context using
+ SSL(), the current option setting is copied. Changes to ctx
+ do not affect already created SSL objects. SSL.clear() does not
+ affect the settings.
+
+ :param op: bitmask of additional options specified in
+ SSL_CTX_set_options(3) manpage.
+
+ :return: the new options bitmask after adding options.
+ """
return m2.ssl_ctx_set_options(self.ctx, op)
def get_cert_store(self):
+ # type: () -> X509.X509
"""
Get the certificate store associated with this context.
-
- @warning: The store is NOT refcounted, and as such can not be relied
- to be valid once the context goes away or is changed.
+
+ :warning: The store is NOT refcounted, and as such can not be relied
+ to be valid once the context goes away or is changed.
"""
return X509.X509_Store(m2.ssl_ctx_get_cert_store(self.ctx))
-
diff --git a/M2Crypto/SSL/SSLServer.py b/M2Crypto/SSL/SSLServer.py
index d894d3b..886019e 100644
--- a/M2Crypto/SSL/SSLServer.py
+++ b/M2Crypto/SSL/SSLServer.py
@@ -1,32 +1,45 @@
+from __future__ import absolute_import, print_function
+
"""SSLServer
Copyright (c) 1999-2002 Ng Pheng Siong. All rights reserved."""
-__all__ = ['SSLServer', 'ForkingSSLServer', 'ThreadingSSLServer']
-
-# Python
-import socket, SocketServer
# M2Crypto
-from Connection import Connection
from M2Crypto.SSL import SSLError
-from M2Crypto import m2
+from M2Crypto.SSL.Connection import Connection
+from M2Crypto.SSL.Context import Context # noqa
+from M2Crypto import six # noqa
+from M2Crypto import util # noqa
+from M2Crypto.six.moves.socketserver import (BaseServer, TCPServer,
+ ThreadingMixIn)
+import os
+if os.name != 'nt':
+ from M2Crypto.six.moves.socketserver import ForkingMixIn
+from socket import socket # noqa
+if util.py27plus:
+ from typing import Union # noqa
+
+__all__ = ['SSLServer', 'ForkingSSLServer', 'ThreadingSSLServer']
-class SSLServer(SocketServer.TCPServer):
- def __init__(self, server_address, RequestHandlerClass, ssl_context, bind_and_activate=True):
- """
+class SSLServer(TCPServer):
+ def __init__(self, server_address, RequestHandlerClass, ssl_context, # noqa
+ bind_and_activate=True):
+ # type: (util.AddrType, socketserver.BaseRequestHandler, Context, bool) -> None
+ """
Superclass says: Constructor. May be extended, do not override.
This class says: Ho-hum.
"""
- SocketServer.BaseServer.__init__(self, server_address, RequestHandlerClass)
- self.ssl_ctx=ssl_context
- self.socket=Connection(self.ssl_ctx)
+ BaseServer.__init__(self, server_address, RequestHandlerClass)
+ self.ssl_ctx = ssl_context
+ self.socket = Connection(self.ssl_ctx)
if bind_and_activate:
self.server_bind()
- self.server_activate()
+ self.server_activate()
def handle_request(self):
+ # type: () -> None
request = None
client_address = None
try:
@@ -37,17 +50,17 @@ class SSLServer(SocketServer.TCPServer):
self.handle_error(request, client_address)
def handle_error(self, request, client_address):
- print '-'*40
+ # type: (Union[socket, Connection], util.AddrType) -> None
+ print('-' * 40)
import traceback
traceback.print_exc()
- print '-'*40
-
-
-class ForkingSSLServer(SocketServer.ForkingMixIn, SSLServer):
- pass
+ print('-' * 40)
-class ThreadingSSLServer(SocketServer.ThreadingMixIn, SSLServer):
+class ThreadingSSLServer(ThreadingMixIn, SSLServer):
pass
+if os.name != 'nt':
+ class ForkingSSLServer(ForkingMixIn, SSLServer):
+ pass
diff --git a/M2Crypto/SSL/Session.py b/M2Crypto/SSL/Session.py
index 1edf5b0..8c4e8f4 100644
--- a/M2Crypto/SSL/Session.py
+++ b/M2Crypto/SSL/Session.py
@@ -4,55 +4,67 @@ Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
__all__ = ['Session', 'load_session']
-from M2Crypto import BIO, Err, m2
+from M2Crypto import BIO, Err, m2, util
+from M2Crypto.SSL import SSLError
+if util.py27plus:
+ from typing import AnyStr # noqa
-class Session:
+
+class Session(object):
m2_ssl_session_free = m2.ssl_session_free
def __init__(self, session, _pyfree=0):
+ # type: (bytes, int) -> None
assert session is not None
self.session = session
self._pyfree = _pyfree
-
+
def __del__(self):
+ # type: () -> None
if getattr(self, '_pyfree', 0):
self.m2_ssl_session_free(self.session)
def _ptr(self):
+ # type: () -> bytes
return self.session
def as_text(self):
+ # type: () -> bytes
buf = BIO.MemoryBuffer()
m2.ssl_session_print(buf.bio_ptr(), self.session)
return buf.read_all()
def as_der(self):
+ # type: () -> bytes
buf = BIO.MemoryBuffer()
m2.i2d_ssl_session(buf.bio_ptr(), self.session)
return buf.read_all()
def write_bio(self, bio):
+ # type: (BIO.BIO) -> int
return m2.ssl_session_write_bio(bio.bio_ptr(), self.session)
def get_time(self):
+ # type: () -> int
return m2.ssl_session_get_time(self.session)
def set_time(self, t):
+ # type: (int) -> int
return m2.ssl_session_set_time(self.session, t)
def get_timeout(self):
+ # type: () -> int
return m2.ssl_session_get_timeout(self.session)
def set_timeout(self, t):
+ # type: (int) -> int
return m2.ssl_session_set_timeout(self.session, t)
def load_session(pemfile):
- f = BIO.openfile(pemfile)
- cptr = m2.ssl_session_read_pem(f.bio_ptr())
- f.close()
- if cptr is None:
- from M2Crypto.SSL import SSLError
- raise SSLError(Err.get_error())
+ # type: (AnyStr) -> Session
+ with BIO.openfile(pemfile) as f:
+ cptr = m2.ssl_session_read_pem(f.bio_ptr())
+
return Session(cptr, 1)
diff --git a/M2Crypto/SSL/TwistedProtocolWrapper.py b/M2Crypto/SSL/TwistedProtocolWrapper.py
index 930dd32..f9f7ccd 100644
--- a/M2Crypto/SSL/TwistedProtocolWrapper.py
+++ b/M2Crypto/SSL/TwistedProtocolWrapper.py
@@ -3,20 +3,32 @@ Make Twisted use M2Crypto for SSL
Copyright (c) 2004-2007 Open Source Applications Foundation.
All rights reserved.
+
+FIXME THIS HAS NOT BEEN FINISHED. NEITHER PEP484 NOR PORT PYTHON3 HAS
+BEEN FINISHED. THE FURTHER WORK WILL BE DONE WHEN THE STATUS OF TWISTED
+IN THE PYTHON 3 (AND ASYNCIO) WORLD WILL BE CLEAR.
"""
__all__ = ['connectSSL', 'connectTCP', 'listenSSL', 'listenTCP',
'TLSProtocolWrapper']
-import twisted.protocols.policies as policies
+import logging
+
+from functools import partial
+
import twisted.internet.reactor
-from twisted.protocols.policies import ProtocolWrapper
+import twisted.protocols.policies as policies
+
+from M2Crypto import BIO, X509, m2, util
+from M2Crypto.SSL.Checker import Checker, SSLVerificationError
+
from twisted.internet.interfaces import ITLSTransport
-from zope.interface import implements
+from twisted.protocols.policies import ProtocolWrapper
+if util.py27plus:
+ from typing import AnyStr, Callable, Iterable, Optional # noqa
+ from zope.interface import implementer
-import M2Crypto # for M2Crypto.BIO.BIOError
-from M2Crypto import m2, X509
-from M2Crypto.SSL import Checker
+log = logging.getLogger(__name__)
def _alwaysSucceedsPostConnectionCheck(peerX509, expectedHost):
@@ -26,11 +38,12 @@ def _alwaysSucceedsPostConnectionCheck(peerX509, expectedHost):
def connectSSL(host, port, factory, contextFactory, timeout=30,
bindAddress=None,
reactor=twisted.internet.reactor,
- postConnectionCheck=Checker.Checker()):
+ postConnectionCheck=Checker()):
+ # type: (str, int, object, object, int, Optional[str], twisted.internet.reactor, Checker) -> reactor.connectTCP
"""
A convenience function to start an SSL/TLS connection using Twisted.
-
- See IReactorSSL interface in Twisted.
+
+ See IReactorSSL interface in Twisted.
"""
wrappingFactory = policies.WrappingFactory(factory)
wrappingFactory.protocol = lambda factory, wrappedProtocol: \
@@ -41,17 +54,18 @@ def connectSSL(host, port, factory, contextFactory, timeout=30,
contextFactory=contextFactory,
postConnectionCheck=postConnectionCheck)
return reactor.connectTCP(host, port, wrappingFactory, timeout, bindAddress)
-
+
def connectTCP(host, port, factory, timeout=30, bindAddress=None,
reactor=twisted.internet.reactor,
- postConnectionCheck=Checker.Checker()):
+ postConnectionCheck=Checker()):
+ # type: (str, int, object, int, Optional[util.AddrType], object, Callable) -> object
"""
- A convenience function to start a TCP connection using Twisted.
+ A convenience function to start a TCP connection using Twisted.
NOTE: You must call startTLS(ctx) to go into SSL/TLS mode.
- See IReactorTCP interface in Twisted.
+ See IReactorTCP interface in Twisted.
"""
wrappingFactory = policies.WrappingFactory(factory)
wrappingFactory.protocol = lambda factory, wrappedProtocol: \
@@ -65,12 +79,12 @@ def connectTCP(host, port, factory, timeout=30, bindAddress=None,
def listenSSL(port, factory, contextFactory, backlog=5, interface='',
- reactor=twisted.internet.reactor,
+ reactor=twisted.internet.reactor,
postConnectionCheck=_alwaysSucceedsPostConnectionCheck):
"""
- A convenience function to listen for SSL/TLS connections using Twisted.
+ A convenience function to listen for SSL/TLS connections using Twisted.
- See IReactorSSL interface in Twisted.
+ See IReactorSSL interface in Twisted.
"""
wrappingFactory = policies.WrappingFactory(factory)
wrappingFactory.protocol = lambda factory, wrappedProtocol: \
@@ -84,14 +98,14 @@ def listenSSL(port, factory, contextFactory, backlog=5, interface='',
def listenTCP(port, factory, backlog=5, interface='',
- reactor=twisted.internet.reactor,
+ reactor=twisted.internet.reactor,
postConnectionCheck=None):
"""
- A convenience function to listen for TCP connections using Twisted.
-
+ A convenience function to listen for TCP connections using Twisted.
+
NOTE: You must call startTLS(ctx) to go into SSL/TLS mode.
- See IReactorTCP interface in Twisted.
+ See IReactorTCP interface in Twisted.
"""
wrappingFactory = policies.WrappingFactory(factory)
wrappingFactory.protocol = lambda factory, wrappedProtocol: \
@@ -104,90 +118,90 @@ def listenTCP(port, factory, backlog=5, interface='',
return reactor.listenTCP(port, wrappingFactory, backlog, interface)
-class _BioProxy:
+class _BioProxy(object):
"""
The purpose of this class is to eliminate the __del__ method from
TLSProtocolWrapper, and thus letting it be garbage collected.
"""
-
+
m2_bio_free_all = m2.bio_free_all
def __init__(self, bio):
self.bio = bio
-
+
def _ptr(self):
return self.bio
-
+
def __del__(self):
if self.bio is not None:
self.m2_bio_free_all(self.bio)
-class _SSLProxy:
+class _SSLProxy(object):
"""
The purpose of this class is to eliminate the __del__ method from
TLSProtocolWrapper, and thus letting it be garbage collected.
"""
-
+
m2_ssl_free = m2.ssl_free
def __init__(self, ssl):
self.ssl = ssl
-
+
def _ptr(self):
return self.ssl
-
+
def __del__(self):
if self.ssl is not None:
self.m2_ssl_free(self.ssl)
+@implementer(ITLSTransport)
class TLSProtocolWrapper(ProtocolWrapper):
"""
A SSL/TLS protocol wrapper to be used with Twisted. Typically
- you would not use this class directly. Use connectTCP,
+ you would not use this class directly. Use connectTCP,
connectSSL, listenTCP, listenSSL functions defined above,
which will hook in this class.
"""
- implements(ITLSTransport)
-
def __init__(self, factory, wrappedProtocol, startPassThrough, client,
contextFactory, postConnectionCheck):
+ # type: (policies.WrappingFactory, object, int, int, object, Checker) -> None
"""
- @param factory:
- @param wrappedProtocol:
- @param startPassThrough: If true we won't encrypt at all. Need to
+ :param factory:
+ :param wrappedProtocol:
+ :param startPassThrough: If true we won't encrypt at all. Need to
call startTLS() later to switch to SSL/TLS.
- @param client: True if this should be a client protocol.
- @param contextFactory: Factory that creates SSL.Context objects.
+ :param client: True if this should be a client protocol.
+ :param contextFactory: Factory that creates SSL.Context objects.
The called function is getContext().
- @param postConnectionCheck: The post connection check callback that
+ :param postConnectionCheck: The post connection check callback that
will be called just after connection has
been established but before any real data
has been exchanged. The first argument to
this function is an X509 object, the second
is the expected host name string.
"""
- #ProtocolWrapper.__init__(self, factory, wrappedProtocol)
- #XXX: Twisted 2.0 has a new addition where the wrappingFactory is
- # set as the factory of the wrappedProtocol. This is an issue
- # as the wrap should be transparent. What we want is
- # the factory of the wrappedProtocol to be the wrappedFactory and
- # not the outer wrappingFactory. This is how it was implemented in
- # Twisted 1.3
+ # ProtocolWrapper.__init__(self, factory, wrappedProtocol)
+ # XXX: Twisted 2.0 has a new addition where the wrappingFactory is
+ # set as the factory of the wrappedProtocol. This is an issue
+ # as the wrap should be transparent. What we want is
+ # the factory of the wrappedProtocol to be the wrappedFactory and
+ # not the outer wrappingFactory. This is how it was implemented in
+ # Twisted 1.3
self.factory = factory
self.wrappedProtocol = wrappedProtocol
-
+
# wrappedProtocol == client/server instance
# factory.wrappedFactory == client/server factory
- self.data = '' # Clear text to encrypt and send
- self.encrypted = '' # Encrypted data we need to decrypt and pass on
- self.tlsStarted = 0 # SSL/TLS mode or pass through
- self.checked = 0 # Post connection check done or not
+ self.data = b'' # Clear text to encrypt and send
+ self.encrypted = b'' # Encrypted data we need to decrypt and pass on
+ self.tlsStarted = 0 # SSL/TLS mode or pass through
+ self.checked = 0 # Post connection check done or not
self.isClient = client
- self.helloDone = 0 # True when hello has been sent
+ self.helloDone = 0 # True when hello has been sent
if postConnectionCheck is None:
self.postConnectionCheck = _alwaysSucceedsPostConnectionCheck
else:
@@ -195,7 +209,7 @@ class TLSProtocolWrapper(ProtocolWrapper):
if not startPassThrough:
self.startTLS(contextFactory.getContext())
-
+
def clear(self):
"""
Clear this instance, after which it is ready for reuse.
@@ -205,15 +219,15 @@ class TLSProtocolWrapper(ProtocolWrapper):
self.ssl = None
self.internalBio = None
self.networkBio = None
- self.data = ''
- self.encrypted = ''
+ self.data = b''
+ self.encrypted = b''
self.tlsStarted = 0
self.checked = 0
self.isClient = 1
self.helloDone = 0
# We can reuse self.ctx and it will be deleted automatically
# when this instance dies
-
+
def startTLS(self, ctx):
"""
Start SSL/TLS. If this is not called, this instance just passes data
@@ -223,7 +237,7 @@ class TLSProtocolWrapper(ProtocolWrapper):
# expects transports to have. This will be called automatically
# by Twisted in STARTTLS situations, for example with SMTP.
if self.tlsStarted:
- raise Exception, 'TLS already started'
+ raise Exception('TLS already started')
self.ctx = ctx
@@ -241,7 +255,7 @@ class TLSProtocolWrapper(ProtocolWrapper):
m2.ssl_set_connect_state(self.ssl._ptr())
else:
m2.ssl_set_accept_state(self.ssl._ptr())
-
+
m2.ssl_set_bio(self.ssl._ptr(), self.internalBio, self.internalBio)
m2.bio_set_ssl(self.sslBio._ptr(), self.ssl._ptr(), m2.bio_noclose)
@@ -255,6 +269,7 @@ class TLSProtocolWrapper(ProtocolWrapper):
self.tlsStarted = 1
def write(self, data):
+ # type: (bytes) -> None
if not self.tlsStarted:
ProtocolWrapper.write(self, data)
return
@@ -263,18 +278,19 @@ class TLSProtocolWrapper(ProtocolWrapper):
encryptedData = self._encrypt(data)
ProtocolWrapper.write(self, encryptedData)
self.helloDone = 1
- except M2Crypto.BIO.BIOError, e:
+ except BIO.BIOError as e:
# See http://www.openssl.org/docs/apps/verify.html#DIAGNOSTICS
# for the error codes returned by SSL_get_verify_result.
e.args = (m2.ssl_get_verify_result(self.ssl._ptr()), e.args[0])
raise e
def writeSequence(self, data):
+ # type: (Iterable[bytes]) -> None
if not self.tlsStarted:
- ProtocolWrapper.writeSequence(self, ''.join(data))
+ ProtocolWrapper.writeSequence(self, b''.join(data))
return
- self.write(''.join(data))
+ self.write(b''.join(data))
def loseConnection(self):
# XXX Do we need to do m2.ssl_shutdown(self.ssl._ptr())?
@@ -286,6 +302,7 @@ class TLSProtocolWrapper(ProtocolWrapper):
self._clientHello()
def dataReceived(self, data):
+ # type: (bytes) -> None
if not self.tlsStarted:
ProtocolWrapper.dataReceived(self, data)
return
@@ -303,15 +320,16 @@ class TLSProtocolWrapper(ProtocolWrapper):
ProtocolWrapper.dataReceived(self, decryptedData)
- if decryptedData == '' and encryptedData == '':
+ if decryptedData == b'' and encryptedData == b'':
break
- except M2Crypto.BIO.BIOError, e:
+ except BIO.BIOError as e:
# See http://www.openssl.org/docs/apps/verify.html#DIAGNOSTICS
# for the error codes returned by SSL_get_verify_result.
e.args = (m2.ssl_get_verify_result(self.ssl._ptr()), e.args[0])
raise e
def connectionLost(self, reason):
+ # type: (AnyStr) -> None
self.clear()
ProtocolWrapper.connectionLost(self, reason)
@@ -325,7 +343,7 @@ class TLSProtocolWrapper(ProtocolWrapper):
else:
host = self.transport.getPeer().host
if not self.postConnectionCheck(x509, host):
- raise Checker.SSLVerificationError, 'post connection check'
+ raise SSLVerificationError('post connection check')
self.checked = 1
def _clientHello(self):
@@ -335,75 +353,138 @@ class TLSProtocolWrapper(ProtocolWrapper):
encryptedData = self._encrypt(clientHello=1)
ProtocolWrapper.write(self, encryptedData)
self.helloDone = 1
- except M2Crypto.BIO.BIOError, e:
+ except BIO.BIOError as e:
# See http://www.openssl.org/docs/apps/verify.html#DIAGNOSTICS
# for the error codes returned by SSL_get_verify_result.
e.args = (m2.ssl_get_verify_result(self.ssl._ptr()), e.args[0])
raise e
- def _encrypt(self, data='', clientHello=0):
- # XXX near mirror image of _decrypt - refactor
- encryptedData = ''
+ # Optimizations to reduce attribute accesses
+
+ @property
+ def _get_wr_guar_ssl(self):
+ # type: () -> Callable[[], int]
+ """Return max. length of data can be written to the BIO.
+
+ Writes larger than this value will return a value from
+ BIO_write() less than the amount requested or if the buffer is
+ full request a retry.
+ """
+ return partial(m2.bio_ctrl_get_write_guarantee,
+ self.sslBio._ptr())
+
+ @property
+ def _get_wr_guar_net(self):
+ # type: () -> Callable[[], int]
+ return partial(m2.bio_ctrl_get_write_guarantee,
+ self.networkBio._ptr())
+
+ @property
+ def _shoud_retry_ssl(self):
+ # type: () -> Callable[[], int]
+ # BIO_should_retry() is true if the call that produced this
+ # condition should then be retried at a later time.
+ return partial(m2.bio_should_retry, self.sslBio._ptr())
+
+ @property
+ def _shoud_retry_net(self):
+ # type: () -> Callable[[], int]
+ return partial(m2.bio_should_retry, self.networkBio._ptr())
+
+ @property
+ def _ctrl_pend_ssl(self):
+ # type: () -> Callable[[], int]
+ # size_t BIO_ctrl_pending(BIO *b);
+ # BIO_ctrl_pending() return the number of pending characters in
+ # the BIOs read and write buffers.
+ return partial(m2.bio_ctrl_pending, self.sslBio._ptr())
+
+ @property
+ def _ctrl_pend_net(self):
+ # type: () -> Callable[[], int]
+ return partial(m2.bio_ctrl_pending, self.networkBio._ptr())
+
+ @property
+ def _write_ssl(self):
+ # type: () -> Callable[[bytes], int]
+ # All these functions return either the amount of data
+ # successfully read or written (if the return value is
+ # positive) or that no data was successfully read or written
+ # if the result is 0 or -1. If the return value is -2 then
+ # the operation is not implemented in the specific BIO type.
+ return partial(m2.bio_write, self.sslBio._ptr())
+
+ @property
+ def _write_net(self):
+ # type: () -> Callable[[bytes], int]
+ return partial(m2.bio_write, self.networkBio._ptr())
+
+ @property
+ def _read_ssl(self):
+ # type: () -> Callable[[int], Optional[bytes]]
+ return partial(m2.bio_read, self.sslBio._ptr())
+
+ @property
+ def _read_net(self):
+ # type: () -> Callable[[int], Optional[bytes]]
+ return partial(m2.bio_read, self.networkBio._ptr())
+
+ def _encrypt(self, data=b'', clientHello=0):
+ # type: (bytes, int) -> bytes
+ """
+ :param data:
+ :param clientHello:
+ :return:
+ """
+ encryptedData = b''
self.data += data
- # Optimizations to reduce attribute accesses
- sslBioPtr = self.sslBio._ptr()
- networkBio = self.networkBio._ptr()
- m2bio_ctrl_get_write_guarantee = m2.bio_ctrl_get_write_guarantee
- m2bio_write = m2.bio_write
- m2bio_should_retry = m2.bio_should_retry
- m2bio_ctrl_pending = m2.bio_ctrl_pending
- m2bio_read = m2.bio_read
-
+
while 1:
- g = m2bio_ctrl_get_write_guarantee(sslBioPtr)
- if g > 0 and self.data != '' or clientHello:
- r = m2bio_write(sslBioPtr, self.data)
+ if (self._get_wr_guar_ssl() > 0 and self.data != b'') or clientHello:
+ r = self._write_ssl(self.data)
if r <= 0:
- assert(m2bio_should_retry(sslBioPtr))
+ if not self._shoud_retry_ssl():
+ raise IOError(
+ ('Data left to be written to {}, ' +
+ 'but cannot retry SSL connection!').format(self.sslBio))
else:
- assert(self.checked)
+ assert self.checked
self.data = self.data[r:]
-
- pending = m2bio_ctrl_pending(networkBio)
+
+ pending = self._ctrl_pend_net()
if pending:
- d = m2bio_read(networkBio, pending)
- if d is not None: # This is strange, but d can be None
+ d = self._read_net(pending)
+ if d is not None: # This is strange, but d can be None
encryptedData += d
else:
- assert(m2bio_should_retry(networkBio))
+ assert(self._shoud_retry_net())
else:
break
return encryptedData
- def _decrypt(self, data=''):
- # XXX near mirror image of _encrypt - refactor
+ def _decrypt(self, data=b''):
+ # type: (bytes) -> bytes
self.encrypted += data
- decryptedData = ''
- # Optimizations to reduce attribute accesses
- sslBioPtr = self.sslBio._ptr()
- networkBio = self.networkBio._ptr()
- m2bio_ctrl_get_write_guarantee = m2.bio_ctrl_get_write_guarantee
- m2bio_write = m2.bio_write
- m2bio_should_retry = m2.bio_should_retry
- m2bio_ctrl_pending = m2.bio_ctrl_pending
- m2bio_read = m2.bio_read
-
+ decryptedData = b''
+
while 1:
- g = m2bio_ctrl_get_write_guarantee(networkBio)
- if g > 0 and self.encrypted != '':
- r = m2bio_write(networkBio, self.encrypted)
+ if self._get_wr_guar_ssl() > 0 and self.encrypted != b'':
+ r = self._write_net(self.encrypted)
if r <= 0:
- assert(m2bio_should_retry(networkBio))
+ if not self._shoud_retry_net():
+ raise IOError(
+ ('Data left to be written to {}, ' +
+ 'but cannot retry SSL connection!').format(self.networkBio))
else:
self.encrypted = self.encrypted[r:]
-
- pending = m2bio_ctrl_pending(sslBioPtr)
+
+ pending = self._ctrl_pend_ssl()
if pending:
- d = m2bio_read(sslBioPtr, pending)
- if d is not None: # This is strange, but d can be None
+ d = self._read_ssl(pending)
+ if d is not None: # This is strange, but d can be None
decryptedData += d
else:
- assert(m2bio_should_retry(sslBioPtr))
+ assert(self._shoud_retry_ssl())
else:
break
diff --git a/M2Crypto/SSL/__init__.py b/M2Crypto/SSL/__init__.py
index a013569..b62e81c 100644
--- a/M2Crypto/SSL/__init__.py
+++ b/M2Crypto/SSL/__init__.py
@@ -1,28 +1,41 @@
+from __future__ import absolute_import
+
"""M2Crypto SSL services.
Copyright (c) 1999-2004 Ng Pheng Siong. All rights reserved."""
+import socket, os
+
# M2Crypto
-from M2Crypto import m2
+from M2Crypto import _m2crypto as m2
+
+
+class SSLError(Exception):
+ pass
+
-class SSLError(Exception): pass
-m2.ssl_init(SSLError)
+class SSLTimeoutError(SSLError, socket.timeout):
+ pass
+
+m2.ssl_init(SSLError, SSLTimeoutError)
# M2Crypto.SSL
-from Cipher import Cipher, Cipher_Stack
-from Context import Context
-from Connection import Connection
-from SSLServer import SSLServer, ForkingSSLServer, ThreadingSSLServer
-from ssl_dispatcher import ssl_dispatcher
-from timeout import timeout
-
-verify_none = m2.SSL_VERIFY_NONE
-verify_peer = m2.SSL_VERIFY_PEER
-verify_fail_if_no_peer_cert = m2.SSL_VERIFY_FAIL_IF_NO_PEER_CERT
-verify_client_once = m2.SSL_VERIFY_CLIENT_ONCE
-
-SSL_SENT_SHUTDOWN = m2.SSL_SENT_SHUTDOWN
-SSL_RECEIVED_SHUTDOWN = m2.SSL_RECEIVED_SHUTDOWN
-
-op_all = m2.SSL_OP_ALL
-op_no_sslv2 = m2.SSL_OP_NO_SSLv2
+from M2Crypto.SSL.Cipher import Cipher, Cipher_Stack
+from M2Crypto.SSL.Connection import Connection
+from M2Crypto.SSL.Context import Context
+from M2Crypto.SSL.SSLServer import SSLServer, ThreadingSSLServer
+if os.name != 'nt':
+ from M2Crypto.SSL.SSLServer import ForkingSSLServer
+from M2Crypto.SSL.ssl_dispatcher import ssl_dispatcher
+from M2Crypto.SSL.timeout import timeout, struct_to_timeout, struct_size
+
+verify_none = m2.SSL_VERIFY_NONE # type: int
+verify_peer = m2.SSL_VERIFY_PEER # type: int
+verify_fail_if_no_peer_cert = m2.SSL_VERIFY_FAIL_IF_NO_PEER_CERT # type: int
+verify_client_once = m2.SSL_VERIFY_CLIENT_ONCE # type: int
+
+SSL_SENT_SHUTDOWN = m2.SSL_SENT_SHUTDOWN # type: int
+SSL_RECEIVED_SHUTDOWN = m2.SSL_RECEIVED_SHUTDOWN # type: int
+
+op_all = m2.SSL_OP_ALL # type: int
+op_no_sslv2 = m2.SSL_OP_NO_SSLv2 # type: int
diff --git a/M2Crypto/SSL/cb.py b/M2Crypto/SSL/cb.py
index c1710cc..d10735d 100644
--- a/M2Crypto/SSL/cb.py
+++ b/M2Crypto/SSL/cb.py
@@ -1,16 +1,18 @@
+from __future__ import absolute_import
+
"""SSL callbacks
Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
+import sys
+
+from M2Crypto import m2, util
+if util.py27plus:
+ from typing import Any, List # noqa
+
__all__ = ['unknown_issuer', 'ssl_verify_callback_stub', 'ssl_verify_callback',
'ssl_verify_callback_allow_unknown_ca', 'ssl_info_callback']
-# Python
-import sys
-
-# M2Crypto
-import Context
-from M2Crypto import m2
def ssl_verify_callback_stub(ssl_ctx_ptr, x509_ptr, errnum, errdepth, ok):
# Deprecated
@@ -21,14 +23,19 @@ unknown_issuer = [
m2.X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY,
m2.X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE,
m2.X509_V_ERR_CERT_UNTRUSTED,
- ]
+]
+
def ssl_verify_callback(ssl_ctx_ptr, x509_ptr, errnum, errdepth, ok):
+ # type: (bytes, bytes, int, int, int) -> int
# Deprecated
- ssl_ctx = Context.map()[long(ssl_ctx_ptr)]
- if errnum in unknown_issuer:
+
+ from M2Crypto.SSL.Context import Context
+ ssl_ctx = Context.ctxmap()[int(ssl_ctx_ptr)]
+ if errnum in unknown_issuer:
if ssl_ctx.get_allow_unknown_ca():
- sys.stderr.write("policy: %s: permitted...\n" % (m2.x509_get_verify_error(errnum)))
+ sys.stderr.write("policy: %s: permitted...\n" %
+ (m2.x509_get_verify_error(errnum)))
sys.stderr.flush()
ok = 1
# CRL checking goes here...
@@ -39,45 +46,51 @@ def ssl_verify_callback(ssl_ctx_ptr, x509_ptr, errnum, errdepth, ok):
ok = 0
return ok
+
def ssl_verify_callback_allow_unknown_ca(ok, store):
+ # type: (int, Any) -> int
errnum = store.get_error()
if errnum in unknown_issuer:
ok = 1
return ok
+
# Cribbed from OpenSSL's apps/s_cb.c.
def ssl_info_callback(where, ret, ssl_ptr):
+ # type: (int, int, bytes) -> None
w = where & ~m2.SSL_ST_MASK
- if (w & m2.SSL_ST_CONNECT):
+ if w & m2.SSL_ST_CONNECT:
state = "SSL connect"
- elif (w & m2.SSL_ST_ACCEPT):
+ elif w & m2.SSL_ST_ACCEPT:
state = "SSL accept"
else:
state = "SSL state unknown"
- if (where & m2.SSL_CB_LOOP):
- sys.stderr.write("LOOP: %s: %s\n" % (state, m2.ssl_get_state_v(ssl_ptr)))
+ if where & m2.SSL_CB_LOOP:
+ sys.stderr.write("LOOP: %s: %s\n" %
+ (state, m2.ssl_get_state_v(ssl_ptr)))
sys.stderr.flush()
return
- if (where & m2.SSL_CB_EXIT):
+ if where & m2.SSL_CB_EXIT:
if not ret:
- sys.stderr.write("FAILED: %s: %s\n" % (state, m2.ssl_get_state_v(ssl_ptr)))
+ sys.stderr.write("FAILED: %s: %s\n" %
+ (state, m2.ssl_get_state_v(ssl_ptr)))
sys.stderr.flush()
else:
- sys.stderr.write("INFO: %s: %s\n" % (state, m2.ssl_get_state_v(ssl_ptr)))
+ sys.stderr.write("INFO: %s: %s\n" %
+ (state, m2.ssl_get_state_v(ssl_ptr)))
sys.stderr.flush()
return
- if (where & m2.SSL_CB_ALERT):
- if (where & m2.SSL_CB_READ):
+ if where & m2.SSL_CB_ALERT:
+ if where & m2.SSL_CB_READ:
w = 'read'
else:
w = 'write'
- sys.stderr.write("ALERT: %s: %s: %s\n" % \
- (w, m2.ssl_get_alert_type_v(ret), m2.ssl_get_alert_desc_v(ret)))
+ sys.stderr.write("ALERT: %s: %s: %s\n" %
+ (w, m2.ssl_get_alert_type_v(ret),
+ m2.ssl_get_alert_desc_v(ret)))
sys.stderr.flush()
return
-
-
diff --git a/M2Crypto/SSL/ssl_dispatcher.py b/M2Crypto/SSL/ssl_dispatcher.py
index 1e8c875..73a4b82 100644
--- a/M2Crypto/SSL/ssl_dispatcher.py
+++ b/M2Crypto/SSL/ssl_dispatcher.py
@@ -1,36 +1,43 @@
+from __future__ import absolute_import
+
"""SSL dispatcher
Copyright (c) 1999-2002 Ng Pheng Siong. All rights reserved."""
-__all__ = ['ssl_dispatcher']
-
# Python
-import asyncore, socket
+import asyncore
+import socket
# M2Crypto
-from Connection import Connection
-from M2Crypto import Err, m2
+from M2Crypto import util # noqa
+from M2Crypto.SSL.Connection import Connection
+from M2Crypto.SSL.Context import Context # noqa
+
+__all__ = ['ssl_dispatcher']
class ssl_dispatcher(asyncore.dispatcher):
def create_socket(self, ssl_context):
- self.family_and_type=socket.AF_INET, socket.SOCK_STREAM
- self.ssl_ctx=ssl_context
- self.socket=Connection(self.ssl_ctx)
- #self.socket.setblocking(0)
+ # type: (Context) -> None
+ self.family_and_type = socket.AF_INET, socket.SOCK_STREAM
+ self.ssl_ctx = ssl_context
+ self.socket = Connection(self.ssl_ctx)
+ # self.socket.setblocking(0)
self.add_channel()
def connect(self, addr):
+ # type: (util.AddrType) -> None
self.socket.setblocking(1)
self.socket.connect(addr)
self.socket.setblocking(0)
def recv(self, buffer_size=4096):
+ # type: (int) -> bytes
"""Receive data over SSL."""
return self.socket.recv(buffer_size)
def send(self, buffer):
+ # type: (bytes) -> int
"""Send data over SSL."""
return self.socket.send(buffer)
-
diff --git a/M2Crypto/SSL/timeout.py b/M2Crypto/SSL/timeout.py
index d76556d..42b0291 100644
--- a/M2Crypto/SSL/timeout.py
+++ b/M2Crypto/SSL/timeout.py
@@ -7,24 +7,44 @@ Copyright 2008 Heikki Toivonen. All rights reserved.
__all__ = ['DEFAULT_TIMEOUT', 'timeout', 'struct_to_timeout', 'struct_size']
+import sys
import struct
-from M2Crypto import m2
-DEFAULT_TIMEOUT = 600
+DEFAULT_TIMEOUT = 600 # type: int
-class timeout:
+
+class timeout(object):
def __init__(self, sec=DEFAULT_TIMEOUT, microsec=0):
+ # type: (int, int) -> None
self.sec = sec
self.microsec = microsec
def pack(self):
- return struct.pack('ll', self.sec, self.microsec)
+ if sys.platform == 'win32':
+ millisec = int(self.sec * 1000 + round(float(self.microsec) / 1000))
+ binstr = struct.pack('l', millisec)
+ else:
+ binstr = struct.pack('ll', self.sec, self.microsec)
+ return binstr
def struct_to_timeout(binstr):
- (s, ms) = struct.unpack('ll', binstr)
- return timeout(s, ms)
+ # type: (bytes) -> timeout
+ if sys.platform == 'win32':
+ millisec = struct.unpack('l', binstr)[0]
+ # On py3, int/int performs exact division and returns float. We want
+ # the whole number portion of the exact division result:
+ sec = int(millisec / 1000)
+ microsec = (millisec % 1000) * 1000
+ else:
+ (sec, microsec) = struct.unpack('ll', binstr)
+ return timeout(sec, microsec)
+
def struct_size():
- return struct.calcsize('ll')
+ # type: () -> int
+ if sys.platform == 'win32':
+ return struct.calcsize('l')
+ else:
+ return struct.calcsize('ll')
diff --git a/M2Crypto/X509.py b/M2Crypto/X509.py
index eef83fe..fc00ada 100644
--- a/M2Crypto/X509.py
+++ b/M2Crypto/X509.py
@@ -1,3 +1,5 @@
+from __future__ import absolute_import
+
"""M2Crypto wrapper for OpenSSL X509 API.
Copyright (c) 1999-2004 Ng Pheng Siong. All rights reserved.
@@ -7,141 +9,172 @@ Copyright (C) 2004-2007 OSAF. All Rights Reserved.
Author: Heikki Toivonen
"""
-# M2Crypto
-from M2Crypto import ASN1, BIO, Err, EVP, util
-import m2
+import binascii
+import logging
+
+from M2Crypto import ASN1, BIO, EVP, m2, py27plus, six # noqa
+if py27plus:
+ from typing import AnyStr, Optional # noqa
FORMAT_DER = 0
FORMAT_PEM = 1
-class X509Error(Exception): pass
+log = logging.getLogger(__name__)
+
+
+class X509Error(ValueError):
+ pass
m2.x509_init(X509Error)
-V_OK = m2.X509_V_OK
+V_OK = m2.X509_V_OK # type: int
+
+
+def x509_store_default_cb(ok, ctx):
+ # type: (int, X509_Store_Context) -> int
+ return ok
+
def new_extension(name, value, critical=0, _pyfree=1):
+ # type: (str, bytes, int, int) -> X509_Extension
"""
Create new X509_Extension instance.
"""
if name == 'subjectKeyIdentifier' and \
- value.strip('0123456789abcdefABCDEF:') is not '':
+ value.strip('0123456789abcdefABCDEF:') is not '':
raise ValueError('value must be precomputed hash')
- lhash = m2.x509v3_lhash()
- ctx = m2.x509v3_set_conf_lhash(lhash)
- x509_ext_ptr = m2.x509v3_ext_conf(lhash, ctx, name, value)
+ ctx = m2.x509v3_set_nconf()
+ x509_ext_ptr = m2.x509v3_ext_conf(None, ctx, name, value)
+ if x509_ext_ptr is None:
+ raise X509Error(
+ "Cannot create X509_Extension with name '%s' and value '%s'" %
+ (name, value))
x509_ext = X509_Extension(x509_ext_ptr, _pyfree)
x509_ext.set_critical(critical)
- return x509_ext
+ return x509_ext
-class X509_Extension:
+class X509_Extension(object):
"""
X509 Extension
"""
-
+
m2_x509_extension_free = m2.x509_extension_free
-
+
def __init__(self, x509_ext_ptr=None, _pyfree=1):
+ # type: (Optional[bytes], int) -> None
self.x509_ext = x509_ext_ptr
self._pyfree = _pyfree
def __del__(self):
+ # type: () -> None
if getattr(self, '_pyfree', 0) and self.x509_ext:
self.m2_x509_extension_free(self.x509_ext)
def _ptr(self):
+ # type: () -> bytes
return self.x509_ext
def set_critical(self, critical=1):
+ # type: (int) -> int
"""
Mark this extension critical or noncritical. By default an
extension is not critical.
- @type critical: int
- @param critical: Nonzero sets this extension as critical.
+ :param critical: Nonzero sets this extension as critical.
Calling this method without arguments will
set this extension to critical.
+ :return: 1 for success, 0 for failure
"""
return m2.x509_extension_set_critical(self.x509_ext, critical)
-
+
def get_critical(self):
+ # type: () -> int
"""
Return whether or not this is a critical extension.
- @rtype: int
- @return: Nonzero if this is a critical extension.
+ :return: Nonzero if this is a critical extension.
"""
return m2.x509_extension_get_critical(self.x509_ext)
-
+
def get_name(self):
+ # type: () -> str
"""
Get the extension name, for example 'subjectAltName'.
"""
- return m2.x509_extension_get_name(self.x509_ext)
+ return six.ensure_text(m2.x509_extension_get_name(self.x509_ext))
def get_value(self, flag=0, indent=0):
+ # type: (int, int) -> str
"""
Get the extension value, for example 'DNS:www.example.com'.
-
- @param flag: Flag to control what and how to print.
- @param indent: How many spaces to print before actual value.
+
+ :param flag: Flag to control what and how to print.
+ :param indent: How many spaces to print before actual value.
"""
- buf=BIO.MemoryBuffer()
+ buf = BIO.MemoryBuffer()
m2.x509_ext_print(buf.bio_ptr(), self.x509_ext, flag, indent)
- return buf.read_all()
+ return six.ensure_text(buf.read_all())
-class X509_Extension_Stack:
+class X509_Extension_Stack(object):
"""
X509 Extension Stack
-
- @warning: Do not modify the underlying OpenSSL stack
- except through this interface, or use any OpenSSL functions that do so
- indirectly. Doing so will get the OpenSSL stack and the internal pystack
- of this class out of sync, leading to python memory leaks, exceptions
- or even python crashes!
+
+ :warning: Do not modify the underlying OpenSSL stack
+ except through this interface, or use any OpenSSL
+ functions that do so indirectly. Doing so will get the
+ OpenSSL stack and the internal pystack of this class out
+ of sync, leading to python memory leaks, exceptions or
+ even python crashes!
"""
m2_sk_x509_extension_free = m2.sk_x509_extension_free
def __init__(self, stack=None, _pyfree=0):
+ # type: (Optional[bytes], int) -> None
if stack is not None:
self.stack = stack
self._pyfree = _pyfree
num = m2.sk_x509_extension_num(self.stack)
for i in range(num):
- self.pystack.append(X509_Extension(m2.sk_x509_extension_value(self.stack, i),
- _pyfree=_pyfree))
+ self.pystack.append(X509_Extension(
+ m2.sk_x509_extension_value(self.stack, i),
+ _pyfree=_pyfree))
else:
self.stack = m2.sk_x509_extension_new_null()
self._pyfree = 1
- self.pystack = [] # This must be kept in sync with self.stack
-
+ self.pystack = [] # This must be kept in sync with self.stack
+
def __del__(self):
+ # type: () -> None
+ # see BIO.py - unbalanced __init__ / __del__
if getattr(self, '_pyfree', 0):
self.m2_sk_x509_extension_free(self.stack)
def __len__(self):
+ # type: () -> int
assert m2.sk_x509_extension_num(self.stack) == len(self.pystack)
return len(self.pystack)
def __getitem__(self, idx):
+ # type: (int) -> X509_Extension
return self.pystack[idx]
-
+
def __iter__(self):
return iter(self.pystack)
-
+
def _ptr(self):
+ # type: () -> bytes
return self.stack
def push(self, x509_ext):
+ # type: (X509_Extension) -> int
"""
Push X509_Extension object onto the stack.
- @type x509_ext: M2Crypto.X509.X509_Extension
- @param x509_ext: X509_Extension object to be pushed onto the stack.
- @return: The number of extensions on the stack.
+ :param x509_ext: X509_Extension object to be pushed onto the stack.
+ :return: The number of extensions on the stack.
"""
self.pystack.append(x509_ext)
ret = m2.sk_x509_extension_push(self.stack, x509_ext._ptr())
@@ -149,10 +182,11 @@ class X509_Extension_Stack:
return ret
def pop(self):
+ # type: () -> X509_Extension
"""
Pop X509_Extension object from the stack.
-
- @return: X509_Extension popped
+
+ :return: X509_Extension popped
"""
x509_ext_ptr = m2.sk_x509_extension_pop(self.stack)
if x509_ext_ptr is None:
@@ -161,7 +195,7 @@ class X509_Extension_Stack:
return self.pystack.pop()
-class X509_Name_Entry:
+class X509_Name_Entry(object):
"""
X509 Name Entry
"""
@@ -169,121 +203,202 @@ class X509_Name_Entry:
m2_x509_name_entry_free = m2.x509_name_entry_free
def __init__(self, x509_name_entry, _pyfree=0):
+ # type: (bytes, int) -> None
+ """
+ :param x509_name_entry: this should be OpenSSL X509_NAME_ENTRY binary
+ :param _pyfree:
+ """
self.x509_name_entry = x509_name_entry
self._pyfree = _pyfree
-
+
def __del__(self):
+ # type: () -> None
if getattr(self, '_pyfree', 0):
self.m2_x509_name_entry_free(self.x509_name_entry)
def _ptr(self):
+ # type: () -> bytes
return self.x509_name_entry
def set_object(self, asn1obj):
+ # type: (ASN1.ASN1_Object) -> int
+ """
+ Sets the field name to asn1obj
+
+ :param asn1obj:
+ :return: 0 on failure, 1 on success
+ """
return m2.x509_name_entry_set_object(self.x509_name_entry,
asn1obj._ptr())
def set_data(self, data, type=ASN1.MBSTRING_ASC):
- return m2.x509_name_entry_set_data(self.x509_name_entry,
- type, data)
+ # type: (bytes, int) -> int
+ """
+ Sets the field name to asn1obj
+
+ :param data: data in a binary form to be set
+ :return: 0 on failure, 1 on success
+ """
+ return m2.x509_name_entry_set_data(self.x509_name_entry, type, data)
def get_object(self):
- return ASN1.ASN1_Object(m2.x509_name_entry_get_object(self.x509_name_entry))
-
+ # type: () -> ASN1.ASN1_Object
+ return ASN1.ASN1_Object(
+ m2.x509_name_entry_get_object(self.x509_name_entry))
+
def get_data(self):
- return ASN1.ASN1_String(m2.x509_name_entry_get_data(self.x509_name_entry))
+ # type: () -> ASN1.ASN1_String
+ return ASN1.ASN1_String(
+ m2.x509_name_entry_get_data(self.x509_name_entry))
- def create_by_txt( self, field, type, entry, len):
+ def create_by_txt(self, field, type, entry, len):
return m2.x509_name_entry_create_by_txt(self.x509_name_entry._ptr(),
field, type, entry, len)
-
-class X509_Name:
+
+class X509_Name(object):
"""
X509 Name
"""
- nid = {'C' : m2.NID_countryName,
- 'SP' : m2.NID_stateOrProvinceName,
- 'ST' : m2.NID_stateOrProvinceName,
- 'stateOrProvinceName' : m2.NID_stateOrProvinceName,
- 'L' : m2.NID_localityName,
- 'localityName' : m2.NID_localityName,
- 'O' : m2.NID_organizationName,
- 'organizationName' : m2.NID_organizationName,
- 'OU' : m2.NID_organizationalUnitName,
- 'organizationUnitName' : m2.NID_organizationalUnitName,
- 'CN' : m2.NID_commonName,
- 'commonName' : m2.NID_commonName,
- 'Email' : m2.NID_pkcs9_emailAddress,
- 'emailAddress' : m2.NID_pkcs9_emailAddress,
- 'serialNumber' : m2.NID_serialNumber,
- 'SN' : m2.NID_surname,
- 'surname' : m2.NID_surname,
- 'GN' : m2.NID_givenName,
- 'givenName' : m2.NID_givenName
+ nid = {'C': m2.NID_countryName,
+ 'SP': m2.NID_stateOrProvinceName,
+ 'ST': m2.NID_stateOrProvinceName,
+ 'stateOrProvinceName': m2.NID_stateOrProvinceName,
+ 'L': m2.NID_localityName,
+ 'localityName': m2.NID_localityName,
+ 'O': m2.NID_organizationName,
+ 'organizationName': m2.NID_organizationName,
+ 'OU': m2.NID_organizationalUnitName,
+ 'organizationUnitName': m2.NID_organizationalUnitName,
+ 'CN': m2.NID_commonName,
+ 'commonName': m2.NID_commonName,
+ 'Email': m2.NID_pkcs9_emailAddress,
+ 'emailAddress': m2.NID_pkcs9_emailAddress,
+ 'serialNumber': m2.NID_serialNumber,
+ 'SN': m2.NID_surname,
+ 'surname': m2.NID_surname,
+ 'GN': m2.NID_givenName,
+ 'givenName': m2.NID_givenName
}
m2_x509_name_free = m2.x509_name_free
def __init__(self, x509_name=None, _pyfree=0):
+ # type: (bytes, int) -> None
+ """
+ :param x509_name: this should be OpenSSL X509_NAME binary
+ :param _pyfree:
+ """
if x509_name is not None:
assert m2.x509_name_type_check(x509_name), "'x509_name' type error"
self.x509_name = x509_name
self._pyfree = _pyfree
else:
- self.x509_name = m2.x509_name_new ()
+ self.x509_name = m2.x509_name_new()
self._pyfree = 1
-
+
def __del__(self):
+ # type: () -> None
if getattr(self, '_pyfree', 0):
self.m2_x509_name_free(self.x509_name)
def __str__(self):
- assert m2.x509_name_type_check(self.x509_name), "'x509_name' type error"
+ # type: () -> bytes
+ assert m2.x509_name_type_check(self.x509_name), \
+ "'x509_name' type error"
return m2.x509_name_oneline(self.x509_name)
def __getattr__(self, attr):
+ # type: (str) -> str
if attr in self.nid:
- assert m2.x509_name_type_check(self.x509_name), "'x509_name' type error"
- return m2.x509_name_by_nid(self.x509_name, self.nid[attr])
+ assert m2.x509_name_type_check(self.x509_name), \
+ "'x509_name' type error"
+ return six.ensure_text(m2.x509_name_by_nid(self.x509_name, self.nid[attr]))
if attr in self.__dict__:
return self.__dict__[attr]
- raise AttributeError, (self, attr)
+ raise AttributeError(self, attr)
def __setattr__(self, attr, value):
+ # type: (str, AnyStr) -> int
+ """
+ :return: 1 for success of 0 if an error occurred.
+ """
if attr in self.nid:
- assert m2.x509_name_type_check(self.x509_name), "'x509_name' type error"
- return m2.x509_name_set_by_nid(self.x509_name, self.nid[attr], value)
+ assert m2.x509_name_type_check(self.x509_name), \
+ "'x509_name' type error"
+ return m2.x509_name_set_by_nid(self.x509_name, self.nid[attr],
+ six.ensure_binary(value))
self.__dict__[attr] = value
def __len__(self):
+ # type: () -> int
return m2.x509_name_entry_count(self.x509_name)
-
+
def __getitem__(self, idx):
+ # type: (int) -> X509_Name_Entry
if not 0 <= idx < self.entry_count():
raise IndexError("index out of range")
return X509_Name_Entry(m2.x509_name_get_entry(self.x509_name, idx))
def __iter__(self):
- for i in xrange(self.entry_count()):
+ for i in range(self.entry_count()):
yield self[i]
def _ptr(self):
- #assert m2.x509_name_type_check(self.x509_name), "'x509_name' type error"
+ assert m2.x509_name_type_check(self.x509_name), \
+ "'x509_name' type error"
return self.x509_name
def add_entry_by_txt(self, field, type, entry, len, loc, set):
- return m2.x509_name_add_entry_by_txt(self.x509_name, field, type,
- entry, len, loc, set )
+ # entry_type: (str, int, bytes, int, int, int) -> int
+ """
+ Add X509_Name field whose name is identified by its name.
+
+ :param field: name of the entry
+ :param type: use MBSTRING_ASC or MBSTRING_UTF8
+ (or standard ASN1 type like V_ASN1_IA5STRING)
+ :param entry: value
+ :param len: buf_len of the entry
+ (-1 and the length is computed automagically)
+
+ The ``loc`` and ``set`` parameters determine where a new entry
+ should be added.
+ For almost all applications loc can be set to -1 and set to 0.
+ This adds a new entry to the end of name as a single valued
+ RelativeDistinguishedName (RDN).
+
+ :param loc: determines the index where the new entry is
+ inserted: if it is -1 it is appended.
+ :param set: determines how the new type is added. If it is zero
+ a new RDN is created.
+ If set is -1 or 1 it is added to the previous or next RDN
+ structure respectively. This will then be a multivalued
+ RDN: since multivalues RDNs are very seldom used set is
+ almost always set to zero.
+
+ :return: 1 for success of 0 if an error occurred.
+ """
+ return m2.x509_name_add_entry_by_txt(self.x509_name,
+ six.ensure_str(field), type,
+ six.ensure_str(entry), len, loc, set)
+
+ def entry_count(self):
+ # type: () -> int
+ return m2.x509_name_entry_count(self.x509_name)
- def entry_count( self ):
- return m2.x509_name_entry_count( self.x509_name )
-
def get_entries_by_nid(self, nid):
+ # type: (int) -> List[X509_Name_Entry]
+ """
+ Retrieve the next index matching nid.
+
+ :param nid: name of the entry (as m2.NID* constants)
+
+ :return: list of X509_Name_Entry items
+ """
ret = []
lastpos = -1
@@ -292,33 +407,40 @@ class X509_Name:
lastpos)
if lastpos == -1:
break
-
+
ret.append(self[lastpos])
-
+
return ret
-
+
def as_text(self, indent=0, flags=m2.XN_FLAG_COMPAT):
+ # type: (int, int) -> str
"""
as_text returns the name as a string.
-
- @param indent: Each line in multiline format is indented
+
+ :param indent: Each line in multiline format is indented
by this many spaces.
- @param flags: Flags that control how the output should be formatted.
+ :param flags: Flags that control how the output should be formatted.
"""
- assert m2.x509_name_type_check(self.x509_name), "'x509_name' type error"
- buf=BIO.MemoryBuffer()
+ assert m2.x509_name_type_check(self.x509_name), \
+ "'x509_name' type error"
+ buf = BIO.MemoryBuffer()
m2.x509_name_print_ex(buf.bio_ptr(), self.x509_name, indent, flags)
- return buf.read_all()
+ return six.ensure_text(buf.read_all())
def as_der(self):
- assert m2.x509_name_type_check(self.x509_name), "'x509_name' type error"
+ # type: () -> bytes
+ assert m2.x509_name_type_check(self.x509_name), \
+ "'x509_name' type error"
return m2.x509_name_get_der(self.x509_name)
def as_hash(self):
- assert m2.x509_name_type_check(self.x509_name), "'x509_name' type error"
+ # type: () -> int
+ assert m2.x509_name_type_check(self.x509_name), \
+ "'x509_name' type error"
return m2.x509_name_hash(self.x509_name)
-class X509:
+
+class X509(object):
"""
X.509 Certificate
"""
@@ -326,107 +448,143 @@ class X509:
m2_x509_free = m2.x509_free
def __init__(self, x509=None, _pyfree=0):
+ # type: (Optional[bytes], int) -> None
+ """
+ :param x509: binary representation of
+ the underlying OpenSSL X509 object.
+ :param _pyfree:
+ """
if x509 is not None:
assert m2.x509_type_check(x509), "'x509' type error"
self.x509 = x509
self._pyfree = _pyfree
else:
- self.x509 = m2.x509_new ()
+ self.x509 = m2.x509_new()
self._pyfree = 1
-
+
def __del__(self):
+ # type: () -> None
if getattr(self, '_pyfree', 0):
self.m2_x509_free(self.x509)
def _ptr(self):
+ # type: () -> bytes
assert m2.x509_type_check(self.x509), "'x509' type error"
return self.x509
def as_text(self):
+ # type: () -> str
assert m2.x509_type_check(self.x509), "'x509' type error"
- buf=BIO.MemoryBuffer()
+ buf = BIO.MemoryBuffer()
m2.x509_print(buf.bio_ptr(), self.x509)
- return buf.read_all()
+ return six.ensure_text(buf.read_all())
def as_der(self):
+ # type: () -> bytes
assert m2.x509_type_check(self.x509), "'x509' type error"
return m2.i2d_x509(self.x509)
def as_pem(self):
- buf=BIO.MemoryBuffer()
+ # type: () -> bytes
+ buf = BIO.MemoryBuffer()
m2.x509_write_pem(buf.bio_ptr(), self.x509)
return buf.read_all()
def save_pem(self, filename):
+ # type: (AnyStr) -> int
"""
- save_pem
+ :param filename: name of the file to be loaded
+ :return: 1 for success or 0 for failure
"""
- bio=BIO.openfile(filename, 'wb')
- return m2.x509_write_pem(bio.bio_ptr(), self.x509)
+ with BIO.openfile(filename, 'wb') as bio:
+ return m2.x509_write_pem(bio.bio_ptr(), self.x509)
def save(self, filename, format=FORMAT_PEM):
+ # type: (AnyStr, int) -> int
"""
Saves X.509 certificate to a file. Default output
format is PEM.
- @type filename: string
- @param filename: Name of the file the cert will be saved to.
- @type format: int
- @param format: Controls what output format is used to save the cert.
- Either FORMAT_PEM or FORMAT_DER to save in PEM or DER format.
- Raises a ValueError if an unknow format is used.
+ :param filename: Name of the file the cert will be saved to.
+
+ :param format: Controls what output format is used to save the cert.
+ Either FORMAT_PEM or FORMAT_DER to save in PEM or
+ DER format. Raises a ValueError if an unknow
+ format is used.
+
+ :return: 1 for success or 0 for failure
"""
- bio = BIO.openfile(filename, 'wb')
- if format == FORMAT_PEM:
- return m2.x509_write_pem(bio.bio_ptr(), self.x509)
- elif format == FORMAT_DER:
- return m2.i2d_x509_bio(bio.bio_ptr(), self.x509)
- else:
- raise ValueError("Unknown filetype. Must be either FORMAT_PEM or FORMAT_DER")
+ with BIO.openfile(filename, 'wb') as bio:
+ if format == FORMAT_PEM:
+ return m2.x509_write_pem(bio.bio_ptr(), self.x509)
+ elif format == FORMAT_DER:
+ return m2.i2d_x509_bio(bio.bio_ptr(), self.x509)
+ else:
+ raise ValueError(
+ "Unknown filetype. Must be either FORMAT_PEM or FORMAT_DER")
def set_version(self, version):
+ # type: (int) -> int
"""
- Set version.
+ Set version of the certificate.
- @type version: int
- @param version: Version number.
- @rtype: int
- @return: Returns 0 on failure.
+ :param version: Version number.
+ :return: Returns 0 on failure.
"""
assert m2.x509_type_check(self.x509), "'x509' type error"
return m2.x509_set_version(self.x509, version)
- def set_not_before(self, asn1_utctime):
+ def set_not_before(self, asn1_time):
+ # type: (ASN1.ASN1_TIME) -> int
+ """
+ :return: 1 on success, 0 on failure
+ """
assert m2.x509_type_check(self.x509), "'x509' type error"
- return m2.x509_set_not_before(self.x509, asn1_utctime._ptr())
+ return m2.x509_set_not_before(self.x509, asn1_time._ptr())
- def set_not_after(self, asn1_utctime):
+ def set_not_after(self, asn1_time):
+ # type: (ASN1.ASN1_TIME) -> int
+ """
+ :return: 1 on success, 0 on failure
+ """
assert m2.x509_type_check(self.x509), "'x509' type error"
- return m2.x509_set_not_after(self.x509, asn1_utctime._ptr())
+ return m2.x509_set_not_after(self.x509, asn1_time._ptr())
def set_subject_name(self, name):
+ # type: (X509_Name) -> int
+ """
+ :return: 1 on success, 0 on failure
+ """
assert m2.x509_type_check(self.x509), "'x509' type error"
return m2.x509_set_subject_name(self.x509, name.x509_name)
def set_issuer_name(self, name):
+ # type: (X509_Name) -> int
+ """
+ :return: 1 on success, 0 on failure
+ """
assert m2.x509_type_check(self.x509), "'x509' type error"
return m2.x509_set_issuer_name(self.x509, name.x509_name)
def get_version(self):
+ # type: () -> int
assert m2.x509_type_check(self.x509), "'x509' type error"
return m2.x509_get_version(self.x509)
def get_serial_number(self):
+ # type: () -> ASN1.ASN1_Integer
assert m2.x509_type_check(self.x509), "'x509' type error"
asn1_integer = m2.x509_get_serial_number(self.x509)
return m2.asn1_integer_get(asn1_integer)
def set_serial_number(self, serial):
+ # type: (ASN1.ASN1_Integer) -> int
"""
Set serial number.
- @type serial: int
- @param serial: Serial number.
+ :param serial: Serial number.
+
+ :return 1 for success and 0 for failure.
"""
assert m2.x509_type_check(self.x509), "'x509' type error"
# This "magically" changes serial since asn1_integer
@@ -434,243 +592,281 @@ class X509:
asn1_integer = m2.x509_get_serial_number(self.x509)
return m2.asn1_integer_set(asn1_integer, serial)
# XXX Or should I do this?
- #asn1_integer = m2.asn1_integer_new()
- #m2.asn1_integer_set(asn1_integer, serial)
- #return m2.x509_set_serial_number(self.x509, asn1_integer)
+ # asn1_integer = m2.asn1_integer_new()
+ # m2.asn1_integer_set(asn1_integer, serial)
+ # return m2.x509_set_serial_number(self.x509, asn1_integer)
def get_not_before(self):
+ # type: () -> ASN1.ASN1_TIME
assert m2.x509_type_check(self.x509), "'x509' type error"
- return ASN1.ASN1_UTCTIME(m2.x509_get_not_before(self.x509))
+ return ASN1.ASN1_TIME(m2.x509_get_not_before(self.x509))
def get_not_after(self):
+ # type: () -> ASN1.ASN1_TIME
assert m2.x509_type_check(self.x509), "'x509' type error"
- return ASN1.ASN1_UTCTIME(m2.x509_get_not_after(self.x509))
+ out = ASN1.ASN1_TIME(m2.x509_get_not_after(self.x509))
+ if 'Bad time value' in str(out):
+ raise X509Error(
+ '''M2Crypto cannot handle dates after year 2050.
+ See RFC 5280 4.1.2.5 for more information.
+ ''')
+ return out
def get_pubkey(self):
+ # type: () -> EVP.PKey
assert m2.x509_type_check(self.x509), "'x509' type error"
return EVP.PKey(m2.x509_get_pubkey(self.x509), _pyfree=1)
def set_pubkey(self, pkey):
+ # type: (EVP.PKey) -> int
"""
Set the public key for the certificate
- @type pkey: EVP_PKEY
- @param pkey: Public key
+ :param pkey: Public key
+
+ :return 1 for success and 0 for failure
"""
assert m2.x509_type_check(self.x509), "'x509' type error"
return m2.x509_set_pubkey(self.x509, pkey.pkey)
def get_issuer(self):
+ # type: () -> X509_Name
assert m2.x509_type_check(self.x509), "'x509' type error"
return X509_Name(m2.x509_get_issuer_name(self.x509))
def set_issuer(self, name):
+ # type: (X509_Name) -> int
"""
Set issuer name.
- @type name: X509_Name
- @param name: subjectName field.
+ :param name: subjectName field.
+
+ :return 1 for success and 0 for failure
"""
assert m2.x509_type_check(self.x509), "'x509' type error"
return m2.x509_set_issuer_name(self.x509, name.x509_name)
def get_subject(self):
+ # type: () -> X509_Name
assert m2.x509_type_check(self.x509), "'x509' type error"
return X509_Name(m2.x509_get_subject_name(self.x509))
def set_subject(self, name):
+ # type: (X509_Name) -> int
"""
Set subject name.
- @type name: X509_Name
- @param name: subjectName field.
+ :param name: subjectName field.
+
+ :return 1 for success and 0 for failure
"""
assert m2.x509_type_check(self.x509), "'x509' type error"
return m2.x509_set_subject_name(self.x509, name.x509_name)
def add_ext(self, ext):
+ # type: (X509_Extension) -> int
"""
Add X509 extension to this certificate.
- @type ext: X509_Extension
- @param ext: Extension
+ :param ext: Extension
+
+ :return 1 for success and 0 for failure
"""
assert m2.x509_type_check(self.x509), "'x509' type error"
return m2.x509_add_ext(self.x509, ext.x509_ext, -1)
def get_ext(self, name):
+ # type: (str) -> X509_Extension
"""
Get X509 extension by name.
- @type name: Name of the extension
- @param name: str
- @return: X509_Extension
+ :param name: Name of the extension
+
+ :return: X509_Extension
"""
# Optimizations to reduce attribute accesses
m2x509_get_ext = m2.x509_get_ext
m2x509_extension_get_name = m2.x509_extension_get_name
x509 = self.x509
-
+
+ name = six.ensure_binary(name)
for i in range(m2.x509_get_ext_count(x509)):
- extPtr = m2x509_get_ext(x509, i)
- if m2x509_extension_get_name(extPtr) == name:
- return X509_Extension(extPtr, _pyfree=0)
+ ext_ptr = m2x509_get_ext(x509, i)
+ if m2x509_extension_get_name(ext_ptr) == name:
+ return X509_Extension(ext_ptr, _pyfree=0)
raise LookupError
def get_ext_at(self, index):
+ # type: (int) -> X509_Extension
"""
Get X509 extension by index.
- @type index: Name of the extension
- @param index: int
- @return: X509_Extension
+ :param index: Name of the extension
+
+ :return: X509_Extension
"""
if index < 0 or index >= self.get_ext_count():
raise IndexError
-
+
return X509_Extension(m2.x509_get_ext(self.x509, index),
_pyfree=0)
def get_ext_count(self):
+ # type: () -> int
"""
Get X509 extension count.
"""
- return m2.x509_get_ext_count(self.x509)
+ return m2.x509_get_ext_count(self.x509)
def sign(self, pkey, md):
+ # type: (EVP.PKey, str) -> int
"""
Sign the certificate.
- @type pkey: EVP_PKEY
- @param pkey: Public key
- @type md: str
- @param md: Message digest algorithm to use for signing,
+ :param pkey: Public key
+
+ :param md: Message digest algorithm to use for signing,
for example 'sha1'.
+
+ :return int
"""
assert m2.x509_type_check(self.x509), "'x509' type error"
mda = getattr(m2, md, None)
if mda is None:
- raise ValueError, ('unknown message digest', md)
+ raise ValueError('unknown message digest', md)
return m2.x509_sign(self.x509, pkey.pkey, mda())
def verify(self, pkey=None):
+ # type: (Optional[EVP.PKey]) -> int
assert m2.x509_type_check(self.x509), "'x509' type error"
if pkey:
return m2.x509_verify(self.x509, pkey.pkey)
else:
return m2.x509_verify(self.x509, self.get_pubkey().pkey)
-
+
def check_ca(self):
+ # type: () -> int
"""
Check if the certificate is a Certificate Authority (CA) certificate.
-
- @return: 0 if the certificate is not CA, nonzero otherwise.
-
- @requires: OpenSSL 0.9.8 or newer
+
+ :return: 0 if the certificate is not CA, nonzero otherwise.
+
+ :requires: OpenSSL 0.9.8 or newer
"""
return m2.x509_check_ca(self.x509)
-
+
def check_purpose(self, id, ca):
+ # type: (int, int) -> int
"""
Check if the certificate's purpose matches the asked purpose.
-
- @param id: Purpose id. See X509_PURPOSE_* constants.
- @param ca: 1 if the certificate should be CA, 0 otherwise.
- @return: 0 if the certificate purpose does not match, nonzero otherwise.
+
+ :param id: Purpose id. See X509_PURPOSE_* constants.
+
+ :param ca: 1 if the certificate should be CA, 0 otherwise.
+
+ :return: 0 if the certificate purpose does not match, nonzero
+ otherwise.
"""
return m2.x509_check_purpose(self.x509, id, ca)
def get_fingerprint(self, md='md5'):
+ # type: (str) -> str
"""
Get the fingerprint of the certificate.
-
- @param md: Message digest algorithm to use.
- @return: String containing the fingerprint in hex format.
+
+ :param md: Message digest algorithm to use.
+
+ :return: String containing the fingerprint in hex format.
"""
der = self.as_der()
md = EVP.MessageDigest(md)
md.update(der)
digest = md.final()
- return hex(util.octx_to_num(digest))[2:-1].upper()
+ return six.ensure_text(binascii.hexlify(digest).upper())
+
def load_cert(file, format=FORMAT_PEM):
+ # type: (AnyStr, int) -> X509
"""
Load certificate from file.
- @type file: string
- @param file: Name of file containing certificate in either DER or PEM format.
- @type format: int, either FORMAT_PEM or FORMAT_DER
- @param format: Describes the format of the file to be loaded, either PEM or DER.
+ :param file: Name of file containing certificate in either DER or
+ PEM format.
- @rtype: M2Crypto.X509.X509
- @return: M2Crypto.X509.X509 object.
+ :param format: Describes the format of the file to be loaded,
+ either PEM or DER.
+
+ :return: M2Crypto.X509.X509 object.
"""
- bio = BIO.openfile(file)
- if format == FORMAT_PEM:
- return load_cert_bio(bio)
- elif format == FORMAT_DER:
- cptr = m2.d2i_x509(bio._ptr())
- if cptr is None:
- raise X509Error(Err.get_error())
- return X509(cptr, _pyfree=1)
- else:
- raise ValueError("Unknown format. Must be either FORMAT_DER or FORMAT_PEM")
+ with BIO.openfile(file) as bio:
+ if format == FORMAT_PEM:
+ return load_cert_bio(bio)
+ elif format == FORMAT_DER:
+ cptr = m2.d2i_x509(bio._ptr())
+ return X509(cptr, _pyfree=1)
+ else:
+ raise ValueError(
+ "Unknown format. Must be either FORMAT_DER or FORMAT_PEM")
+
def load_cert_bio(bio, format=FORMAT_PEM):
+ # type: (BIO.BIO, int) -> X509
"""
Load certificate from a bio.
- @type bio: M2Crypto.BIO.BIO
- @param bio: BIO pointing at a certificate in either DER or PEM format.
- @type format: int, either FORMAT_PEM or FORMAT_DER
- @param format: Describes the format of the cert to be loaded, either PEM or DER.
+ :param bio: BIO pointing at a certificate in either DER or PEM format.
- @rtype: M2Crypto.X509.X509
- @return: M2Crypto.X509.X509 object.
+ :param format: Describes the format of the cert to be loaded,
+ either PEM or DER (via constants FORMAT_PEM
+ and FORMAT_FORMAT_DER)
+
+ :return: M2Crypto.X509.X509 object.
"""
if format == FORMAT_PEM:
cptr = m2.x509_read_pem(bio._ptr())
elif format == FORMAT_DER:
cptr = m2.d2i_x509(bio._ptr())
else:
- raise ValueError("Unknown format. Must be either FORMAT_DER or FORMAT_PEM")
- if cptr is None:
- raise X509Error(Err.get_error())
+ raise ValueError(
+ "Unknown format. Must be either FORMAT_DER or FORMAT_PEM")
return X509(cptr, _pyfree=1)
+
def load_cert_string(string, format=FORMAT_PEM):
+ # type: (AnyStr, int) -> X509
"""
Load certificate from a string.
- @type string: string
- @param string: String containing a certificate in either DER or PEM format.
- @type format: int, either FORMAT_PEM or FORMAT_DER
- @param format: Describes the format of the cert to be loaded, either PEM or DER.
+ :param string: String containing a certificate in either DER or PEM format.
+
+ :param format: Describes the format of the cert to be loaded,
+ either PEM or DER (via constants FORMAT_PEM
+ and FORMAT_FORMAT_DER)
- @rtype: M2Crypto.X509.X509
- @return: M2Crypto.X509.X509 object.
+ :return: M2Crypto.X509.X509 object.
"""
+ string = six.ensure_binary(string)
bio = BIO.MemoryBuffer(string)
return load_cert_bio(bio, format)
+
def load_cert_der_string(string):
+ # type: (AnyStr) -> X509
"""
Load certificate from a string.
- @type string: string
- @param string: String containing a certificate in DER format.
+ :param string: String containing a certificate in DER format.
- @rtype: M2Crypto.X509.X509
- @return: M2Crypto.X509.X509 object.
+ :return: M2Crypto.X509.X509 object.
"""
+ string = six.ensure_binary(string)
bio = BIO.MemoryBuffer(string)
cptr = m2.d2i_x509(bio._ptr())
- if cptr is None:
- raise X509Error(Err.get_error())
return X509(cptr, _pyfree=1)
-class X509_Store_Context:
+
+class X509_Store_Context(object):
"""
X509 Store Context
"""
@@ -678,49 +874,63 @@ class X509_Store_Context:
m2_x509_store_ctx_free = m2.x509_store_ctx_free
def __init__(self, x509_store_ctx, _pyfree=0):
+ # type: (bytes, int) -> None
+ """
+
+ :param x509_store_ctx: binary data for
+ OpenSSL X509_STORE_CTX type
+ """
self.ctx = x509_store_ctx
self._pyfree = _pyfree
-
+
def __del__(self):
- if self._pyfree:
+ # type: () -> None
+ # see BIO.py - unbalanced __init__ / __del__
+ if not hasattr(self, '_pyfree'):
+ pass # print("OOPS")
+ elif self._pyfree:
self.m2_x509_store_ctx_free(self.ctx)
-
+
def _ptr(self):
return self.ctx
-
+
def get_current_cert(self):
+ # type: () -> X509
"""
Get current X.509 certificate.
-
- @warning: The returned certificate is NOT refcounted, so you can not
- rely on it being valid once the store context goes away or is modified.
+
+ :warning: The returned certificate is NOT refcounted, so you can not
+ rely on it being valid once the store context goes
+ away or is modified.
"""
return X509(m2.x509_store_ctx_get_current_cert(self.ctx), _pyfree=0)
def get_error(self):
+ # type: () -> int
"""
Get error code.
"""
return m2.x509_store_ctx_get_error(self.ctx)
-
+
def get_error_depth(self):
+ # type: () -> int
"""
Get error depth.
"""
return m2.x509_store_ctx_get_error_depth(self.ctx)
-
+
def get1_chain(self):
+ # type: () -> X509_Stack
"""
Get certificate chain.
-
- @return: Reference counted (i.e. safe to use even after the store
+
+ :return: Reference counted (i.e. safe to use even after the store
context goes away) stack of certificates in the chain.
- @rtype: X509_Stack
"""
return X509_Stack(m2.x509_store_ctx_get1_chain(self.ctx), 1, 1)
-
-class X509_Store:
+
+class X509_Store(object):
"""
X509 Store
"""
@@ -728,14 +938,19 @@ class X509_Store:
m2_x509_store_free = m2.x509_store_free
def __init__(self, store=None, _pyfree=0):
+ # type: (Optional[bytes], int) -> None
+ """
+ :param store: binary data for OpenSSL X509_STORE_CTX type.
+ """
if store is not None:
self.store = store
self._pyfree = _pyfree
else:
self.store = m2.x509_store_new()
self._pyfree = 1
-
+
def __del__(self):
+ # type: () -> None
if getattr(self, '_pyfree', 0):
self.m2_x509_store_free(self.store)
@@ -743,38 +958,72 @@ class X509_Store:
return self.store
def load_info(self, file):
- ret = m2.x509_store_load_locations(self.store, file)
- if ret < 1:
- raise X509Error(Err.get_error())
+ # type: (AnyStr) -> int
+ """
+ :param file: filename
+
+ :return: 1 on success, 0 on failure
+ """
+ ret = m2.x509_store_load_locations(self.store, file)
return ret
load_locations = load_info
-
+
def add_x509(self, x509):
+ # type: (X509) -> int
assert isinstance(x509, X509)
return m2.x509_store_add_cert(self.store, x509._ptr())
-
+
+ def set_verify_cb(self, callback=None):
+ # type: (Optional[callable]) -> None
+ """
+ Set callback which will be called when the store is verified.
+ Wrapper over OpenSSL X509_STORE_set_verify_cb().
+
+ :param callback: Callable to specify verification options.
+ Type of the callable must be:
+ (int, X509_Store_Context) -> int.
+ If None: set the standard options.
+
+ :note: compile-time or run-time errors in the callback would result
+ in mysterious errors during verification, which could be hard
+ to trace.
+
+ :note: Python exceptions raised in callbacks do not propagate to
+ verify() call.
+
+ :return: None
+ """
+ if callback is None:
+ return self.set_verify_cb(x509_store_default_cb)
+
+ if not callable(callback):
+ raise X509Error("set_verify(): callback is not callable")
+ return m2.x509_store_set_verify_cb(self.store, callback)
+
add_cert = add_x509
-class X509_Stack:
+class X509_Stack(object):
"""
X509 Stack
- @warning: Do not modify the underlying OpenSSL stack
- except through this interface, or use any OpenSSL functions that do so
- indirectly. Doing so will get the OpenSSL stack and the internal pystack
- of this class out of sync, leading to python memory leaks, exceptions
- or even python crashes!
+ :warning: Do not modify the underlying OpenSSL stack
+ except through this interface, or use any OpenSSL
+ functions that do so indirectly. Doing so will get the
+ OpenSSL stack and the internal pystack of this class out
+ of sync, leading to python memory leaks, exceptions or
+ even python crashes!
"""
m2_sk_x509_free = m2.sk_x509_free
def __init__(self, stack=None, _pyfree=0, _pyfree_x509=0):
+ # type: (bytes, int, int) -> None
if stack is not None:
self.stack = stack
self._pyfree = _pyfree
- self.pystack = [] # This must be kept in sync with self.stack
+ self.pystack = [] # This must be kept in sync with self.stack
num = m2.sk_x509_num(self.stack)
for i in range(num):
self.pystack.append(X509(m2.sk_x509_value(self.stack, i),
@@ -782,19 +1031,22 @@ class X509_Stack:
else:
self.stack = m2.sk_x509_new_null()
self._pyfree = 1
- self.pystack = [] # This must be kept in sync with self.stack
-
+ self.pystack = [] # This must be kept in sync with self.stack
+
def __del__(self):
+ # type: () -> None
if getattr(self, '_pyfree', 0):
self.m2_sk_x509_free(self.stack)
-
+
def __len__(self):
+ # type: () -> int
assert m2.sk_x509_num(self.stack) == len(self.pystack)
return len(self.pystack)
def __getitem__(self, idx):
+ # type: (int) -> X509
return self.pystack[idx]
-
+
def __iter__(self):
return iter(self.pystack)
@@ -802,11 +1054,13 @@ class X509_Stack:
return self.stack
def push(self, x509):
+ # type: (X509) -> int
"""
push an X509 certificate onto the stack.
-
- @param x509: X509 object.
- @return: The number of X509 objects currently on the stack.
+
+ :param x509: X509 object.
+
+ :return: The number of X509 objects currently on the stack.
"""
assert isinstance(x509, X509)
self.pystack.append(x509)
@@ -815,11 +1069,12 @@ class X509_Stack:
return ret
def pop(self):
+ # type: () -> X509
"""
pop a certificate from the stack.
-
- @return: X509 object that was popped, or None if there is nothing
- to pop.
+
+ :return: X509 object that was popped, or None if there is
+ nothing to pop.
"""
x509_ptr = m2.sk_x509_pop(self.stack)
if x509_ptr is None:
@@ -828,25 +1083,26 @@ class X509_Stack:
return self.pystack.pop()
def as_der(self):
+ # type: () -> bytes
"""
Return the stack as a DER encoded string
"""
- return m2.get_der_encoding_stack(self.stack)
+ return m2.get_der_encoding_stack(self.stack)
def new_stack_from_der(der_string):
+ # type: (bytes) -> X509_Stack
"""
Create a new X509_Stack from DER string.
-
- @return: X509_Stack
+
+ :return: X509_Stack
"""
+ der_string = six.ensure_binary(der_string)
stack_ptr = m2.make_stack_from_der_sequence(der_string)
- if stack_ptr is None:
- raise X509Error(Err.get_error())
return X509_Stack(stack_ptr, 1, 1)
-class Request:
+class Request(object):
"""
X509 Certificate Request.
"""
@@ -854,206 +1110,235 @@ class Request:
m2_x509_req_free = m2.x509_req_free
def __init__(self, req=None, _pyfree=0):
+ # type: (Optional[int], int) -> None
if req is not None:
self.req = req
self._pyfree = _pyfree
else:
self.req = m2.x509_req_new()
+ m2.x509_req_set_version(self.req, 0)
self._pyfree = 1
-
+
def __del__(self):
+ # type: () -> None
if getattr(self, '_pyfree', 0):
self.m2_x509_req_free(self.req)
-
+
def as_text(self):
- buf=BIO.MemoryBuffer()
+ # type: () -> str
+ buf = BIO.MemoryBuffer()
m2.x509_req_print(buf.bio_ptr(), self.req)
- return buf.read_all()
+ return six.ensure_text(buf.read_all())
def as_pem(self):
- buf=BIO.MemoryBuffer()
+ # type: () -> bytes
+ buf = BIO.MemoryBuffer()
m2.x509_req_write_pem(buf.bio_ptr(), self.req)
return buf.read_all()
def as_der(self):
+ # type: () -> bytes
buf = BIO.MemoryBuffer()
m2.i2d_x509_req_bio(buf.bio_ptr(), self.req)
return buf.read_all()
def save_pem(self, filename):
- bio=BIO.openfile(filename, 'wb')
- return m2.x509_req_write_pem(bio.bio_ptr(), self.req)
-
+ # type: (AnyStr) -> int
+ with BIO.openfile(filename, 'wb') as bio:
+ return m2.x509_req_write_pem(bio.bio_ptr(), self.req)
+
def save(self, filename, format=FORMAT_PEM):
+ # type: (AnyStr, int) -> int
"""
Saves X.509 certificate request to a file. Default output
format is PEM.
- @type filename: string
- @param filename: Name of the file the request will be saved to.
- @type format: int
- @param format: Controls what output format is used to save the request.
- Either FORMAT_PEM or FORMAT_DER to save in PEM or DER format.
- Raises ValueError if an unknown format is used.
+ :param filename: Name of the file the request will be saved to.
+
+ :param format: Controls what output format is used to save the
+ request. Either FORMAT_PEM or FORMAT_DER to save
+ in PEM or DER format. Raises ValueError if an
+ unknown format is used.
+
+ :return: 1 for success, 0 for failure.
+ The error code can be obtained by ERR_get_error.
"""
- bio = BIO.openfile(filename, 'wb')
- if format == FORMAT_PEM:
- return m2.x509_req_write_pem(bio.bio_ptr(), self.req)
- elif format == FORMAT_DER:
- return m2.i2d_x509_req_bio(bio.bio_ptr(), self.req)
- else:
- raise ValueError("Unknown filetype. Must be either FORMAT_DER or FORMAT_PEM")
+ with BIO.openfile(filename, 'wb') as bio:
+ if format == FORMAT_PEM:
+ return m2.x509_req_write_pem(bio.bio_ptr(), self.req)
+ elif format == FORMAT_DER:
+ return m2.i2d_x509_req_bio(bio.bio_ptr(), self.req)
+ else:
+ raise ValueError(
+ "Unknown filetype. Must be either FORMAT_DER or FORMAT_PEM")
def get_pubkey(self):
+ # type: () -> EVP.PKey
"""
Get the public key for the request.
- @rtype: EVP_PKEY
- @return: Public key from the request.
+ :return: Public key from the request.
"""
return EVP.PKey(m2.x509_req_get_pubkey(self.req), _pyfree=1)
def set_pubkey(self, pkey):
+ # type: (EVP.PKey) -> int
"""
Set the public key for the request.
- @type pkey: EVP_PKEY
- @param pkey: Public key
+ :param pkey: Public key
- @rtype: int
- @return: Return 1 for success and 0 for failure.
+ :return: Return 1 for success and 0 for failure.
"""
- return m2.x509_req_set_pubkey( self.req, pkey.pkey )
+ return m2.x509_req_set_pubkey(self.req, pkey.pkey)
def get_version(self):
+ # type: () -> int
"""
Get version.
- @rtype: int
- @return: Returns version.
+ :return: Returns version.
"""
return m2.x509_req_get_version(self.req)
def set_version(self, version):
+ # type: (int) -> int
"""
Set version.
- @type version: int
- @param version: Version number.
- @rtype: int
- @return: Returns 0 on failure.
+ :param version: Version number.
+ :return: Returns 0 on failure.
"""
- return m2.x509_req_set_version( self.req, version )
+ return m2.x509_req_set_version(self.req, version)
def get_subject(self):
- return X509_Name(m2.x509_req_get_subject_name( self.req ))
+ # type: () -> X509_Name
+ return X509_Name(m2.x509_req_get_subject_name(self.req))
def set_subject_name(self, name):
+ # type: (X509_Name) -> int
"""
Set subject name.
- @type name: X509_Name
- @param name: subjectName field.
+ :param name: subjectName field.
+ :return: 1 for success and 0 for failure
"""
- return m2.x509_req_set_subject_name( self.req, name.x509_name )
+ return m2.x509_req_set_subject_name(self.req, name.x509_name)
set_subject = set_subject_name
def add_extensions(self, ext_stack):
+ # type: (X509_Extension_Stack) -> int
"""
Add X509 extensions to this request.
- @type ext_stack: X509_Extension_Stack
- @param ext_stack: Stack of extensions to add.
+ :param ext_stack: Stack of extensions to add.
+ :return: 1 for success and 0 for failure
"""
return m2.x509_req_add_extensions(self.req, ext_stack._ptr())
def verify(self, pkey):
+ # type: (EVP.PKey) -> int
+ """
+
+ :param pkey: PKey to be verified
+ :return: 1 for success and 0 for failure
+ """
return m2.x509_req_verify(self.req, pkey.pkey)
def sign(self, pkey, md):
+ # type: (EVP.PKey, str) -> int
+ """
+
+ :param pkey: PKey to be signed
+ :param md: used algorigthm
+ :return: 1 for success and 0 for failure
+ """
mda = getattr(m2, md, None)
if mda is None:
- raise ValueError, ('unknown message digest', md)
+ raise ValueError('unknown message digest', md)
return m2.x509_req_sign(self.req, pkey.pkey, mda())
def load_request(file, format=FORMAT_PEM):
+ # type: (AnyStr, int) -> Request
"""
Load certificate request from file.
- @type file: string
- @param file: Name of file containing certificate request in either PEM or DER format.
- @type format: int, either FORMAT_PEM or FORMAT_DER
- @param format: Describes the format of the file to be loaded, either PEM or DER.
-
- @rtype: M2Crypto.X509.Request
- @return: M2Crypto.X509.Request object.
+ :param file: Name of file containing certificate request in
+ either PEM or DER format.
+ :param format: Describes the format of the file to be loaded,
+ either PEM or DER. (using constants FORMAT_PEM
+ and FORMAT_DER)
+ :return: Request object.
"""
- f=BIO.openfile(file)
- if format == FORMAT_PEM:
- cptr=m2.x509_req_read_pem(f.bio_ptr())
- elif format == FORMAT_DER:
- cptr = m2.d2i_x509_req(f.bio_ptr())
- else:
- raise ValueError("Unknown filetype. Must be either FORMAT_PEM or FORMAT_DER")
- f.close()
- if cptr is None:
- raise X509Error(Err.get_error())
+ with BIO.openfile(file) as f:
+ if format == FORMAT_PEM:
+ cptr = m2.x509_req_read_pem(f.bio_ptr())
+ elif format == FORMAT_DER:
+ cptr = m2.d2i_x509_req(f.bio_ptr())
+ else:
+ raise ValueError(
+ "Unknown filetype. Must be either FORMAT_PEM or FORMAT_DER")
+
return Request(cptr, 1)
+
def load_request_bio(bio, format=FORMAT_PEM):
+ # type: (BIO.BIO, int) -> Request
"""
Load certificate request from a bio.
- @type bio: M2Crypto.BIO.BIO
- @param bio: BIO pointing at a certificate request in either DER or PEM format.
- @type format: int, either FORMAT_PEM or FORMAT_DER
- @param format: Describes the format of the request to be loaded, either PEM or DER.
-
- @rtype: M2Crypto.X509.Request
- @return: M2Crypto.X509.Request object.
+ :param bio: BIO pointing at a certificate request in
+ either DER or PEM format.
+ :param format: Describes the format of the request to be loaded,
+ either PEM or DER. (using constants FORMAT_PEM
+ and FORMAT_DER)
+ :return: M2Crypto.X509.Request object.
"""
if format == FORMAT_PEM:
cptr = m2.x509_req_read_pem(bio._ptr())
elif format == FORMAT_DER:
cptr = m2.d2i_x509_req(bio._ptr())
else:
- raise ValueError("Unknown format. Must be either FORMAT_DER or FORMAT_PEM")
- if cptr is None:
- raise X509Error(Err.get_error())
+ raise ValueError(
+ "Unknown format. Must be either FORMAT_DER or FORMAT_PEM")
+
return Request(cptr, _pyfree=1)
+
def load_request_string(string, format=FORMAT_PEM):
+ # type: (AnyStr, int) -> Request
"""
Load certificate request from a string.
- @type string: string
- @param string: String containing a certificate request in either DER or PEM format.
- @type format: int, either FORMAT_PEM or FORMAT_DER
- @param format: Describes the format of the request to be loaded, either PEM or DER.
+ :param string: String containing a certificate request in
+ either DER or PEM format.
+ :param format: Describes the format of the request to be loaded,
+ either PEM or DER. (using constants FORMAT_PEM
+ and FORMAT_DER)
- @rtype: M2Crypto.X509.Request
- @return: M2Crypto.X509.Request object.
+ :return: M2Crypto.X509.Request object.
"""
+ string = six.ensure_binary(string)
bio = BIO.MemoryBuffer(string)
return load_request_bio(bio, format)
+
def load_request_der_string(string):
+ # type: (AnyStr) -> Request
"""
Load certificate request from a string.
- @type string: string
- @param string: String containing a certificate request in DER format.
-
- @rtype: M2Crypto.X509.Request
- @return: M2Crypto.X509.Request object.
+ :param string: String containing a certificate request in DER format.
+ :return: M2Crypto.X509.Request object.
"""
+ string = six.ensure_binary(string)
bio = BIO.MemoryBuffer(string)
return load_request_bio(bio, FORMAT_DER)
-class CRL:
+class CRL(object):
"""
X509 Certificate Revocation List
"""
@@ -1061,44 +1346,46 @@ class CRL:
m2_x509_crl_free = m2.x509_crl_free
def __init__(self, crl=None, _pyfree=0):
+ # type: (Optional[bytes], int) -> None
+ """
+
+ :param crl: binary representation of
+ the underlying OpenSSL X509_CRL object.
+ """
if crl is not None:
self.crl = crl
self._pyfree = _pyfree
else:
self.crl = m2.x509_crl_new()
self._pyfree = 1
-
+
def __del__(self):
+ # type: () -> None
if getattr(self, '_pyfree', 0):
self.m2_x509_crl_free(self.crl)
def as_text(self):
+ # type: () -> str
"""
Return CRL in PEM format in a string.
- @rtype: string
- @return: String containing the CRL in PEM format.
+ :return: String containing the CRL in PEM format.
"""
- buf=BIO.MemoryBuffer()
+ buf = BIO.MemoryBuffer()
m2.x509_crl_print(buf.bio_ptr(), self.crl)
- return buf.read_all()
+ return six.ensure_text(buf.read_all())
def load_crl(file):
+ # type: (AnyStr) -> CRL
"""
Load CRL from file.
- @type file: string
- @param file: Name of file containing CRL in PEM format.
+ :param file: Name of file containing CRL in PEM format.
- @rtype: M2Crypto.X509.CRL
- @return: M2Crypto.X509.CRL object.
+ :return: M2Crypto.X509.CRL object.
"""
- f=BIO.openfile(file)
- cptr=m2.x509_crl_read_pem(f.bio_ptr())
- f.close()
- if cptr is None:
- raise X509Error(Err.get_error())
- return CRL(cptr, 1)
-
+ with BIO.openfile(file) as f:
+ cptr = m2.x509_crl_read_pem(f.bio_ptr())
+ return CRL(cptr, 1)
diff --git a/M2Crypto/__init__.py b/M2Crypto/__init__.py
index e7acfe7..f515883 100644
--- a/M2Crypto/__init__.py
+++ b/M2Crypto/__init__.py
@@ -1,3 +1,5 @@
+from __future__ import absolute_import
+
"""
M2Crypto is the most complete Python wrapper for OpenSSL featuring RSA, DSA,
DH, EC, HMACs, message digests, symmetric ciphers (including AES); SSL
@@ -15,46 +17,29 @@ Copyright (C) 2004-2007 OSAF. All Rights Reserved.
Copyright 2008-2011 Heikki Toivonen. All rights reserved.
"""
+# noqa
+import sys
+from distutils.version import StrictVersion
+__version__ = '0.35.1'
+version = __version__ # type: str
+version_info = StrictVersion(__version__).version
+
+# This means "Python 2.7 or higher" so it is True for py3k as well
+py27plus = sys.version_info[:2] > (2, 6) # type: bool
+
+from M2Crypto import (ASN1, AuthCookie, BIO, BN, DH, DSA, EVP, Engine, Err,
+ RSA, Rand, SMIME, SSL, X509, m2crypto, ftpslib,
+ httpslib, m2, m2urllib, m2xmlrpclib, threading,
+ util)
-version_info = (0, 21, 1)
-version = '.'.join([str(_v) for _v in version_info])
-
-import __m2crypto
-import m2
-import ASN1
-import AuthCookie
-import BIO
-import BN
-import Rand
-import DH
-import DSA
if m2.OPENSSL_VERSION_NUMBER >= 0x90800F and m2.OPENSSL_NO_EC == 0:
- import EC
-import Err
-import Engine
-import EVP
-import RSA
-import RC4
-import SMIME
-import SSL
-import X509
-import PGP
-import m2urllib
+ from M2Crypto import EC
+if m2.OPENSSL_NO_RC4 == 0:
+ from M2Crypto import RC4
# Backwards compatibility.
urllib2 = m2urllib
-import sys
-if sys.version_info >= (2,4):
- import m2urllib2
-del sys
-
-import ftpslib
-import httpslib
-import m2xmlrpclib
-import threading
-import util
-
-encrypt=1
-decrypt=0
+encrypt = 1
+decrypt = 0
-__m2crypto.lib_init()
+m2crypto.lib_init()
diff --git a/M2Crypto/callback.py b/M2Crypto/callback.py
index 46613ca..c6f54d8 100644
--- a/M2Crypto/callback.py
+++ b/M2Crypto/callback.py
@@ -1,3 +1,5 @@
+from __future__ import absolute_import
+
"""Deprecated, use the util module instead.
Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
@@ -6,4 +8,4 @@ import warnings
warnings.warn('Use the util module instead', DeprecationWarning)
-from util import genparam_callback, passphrase_callback
+from M2Crypto.util import genparam_callback, passphrase_callback
diff --git a/M2Crypto/ftpslib.py b/M2Crypto/ftpslib.py
index b7d82fd..e996981 100644
--- a/M2Crypto/ftpslib.py
+++ b/M2Crypto/ftpslib.py
@@ -1,3 +1,5 @@
+from __future__ import absolute_import
+
"""M2Crypto client-side FTP/TLS.
This implementation complies with draft-murray-auth-ftp-ssl-07.txt.
@@ -31,16 +33,13 @@ drwxr-xr-x 12 0 0 512 May 31 17:08 python2.1
Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
-# Python
-from ftplib import *
-from ftplib import parse150, parse227
-from ftplib import error_reply, error_temp, error_perm, error_proto
-import socket, time
+# We want to import whole stdlib ftplib objects, because our users want
+# to use them.
+from ftplib import * # noqa
# M2Crypto
-import SSL
+from M2Crypto import SSL
-DEFAULT_PROTOCOL='sslv23'
class FTP_TLS(FTP):
@@ -51,7 +50,7 @@ class FTP_TLS(FTP):
if ssl_ctx is not None:
self.ssl_ctx = ssl_ctx
else:
- self.ssl_ctx = SSL.Context(DEFAULT_PROTOCOL)
+ self.ssl_ctx = SSL.Context()
FTP.__init__(self, host)
self.prot = 0
@@ -74,12 +73,12 @@ class FTP_TLS(FTP):
self.voidcmd('PBSZ 0')
self.voidcmd('PROT P')
self.prot = 1
-
+
def prot_c(self):
"""Set up data connection in the clear."""
self.voidcmd('PROT C')
self.prot = 0
-
+
def ntransfercmd(self, cmd, rest=None):
"""Initiate a data transfer."""
conn, size = FTP.ntransfercmd(self, cmd, rest)
@@ -90,5 +89,3 @@ class FTP_TLS(FTP):
conn.set_session(self.sock.get_session())
conn.connect_ssl()
return conn, size
-
-
diff --git a/M2Crypto/httpslib.py b/M2Crypto/httpslib.py
index c1bfd78..f624865 100644
--- a/M2Crypto/httpslib.py
+++ b/M2Crypto/httpslib.py
@@ -1,15 +1,22 @@
-"""M2Crypto support for Python's httplib.
+from __future__ import absolute_import
+
+import warnings
+
+"""M2Crypto support for Python's httplib.
Copyright (c) 1999-2004 Ng Pheng Siong. All rights reserved."""
-import string, sys
-import socket
-from urlparse import urlsplit, urlunsplit
import base64
+import socket
+
+from M2Crypto import SSL, py27plus, six
+from M2Crypto.six.moves.urllib_parse import urlsplit, urlunsplit
+from M2Crypto.six.moves.http_client import * # noqa
+# This is not imported with just '*'
+from M2Crypto.six.moves.http_client import HTTPS_PORT
+if py27plus:
+ from typing import Any, AnyStr, Callable, Dict, List, Optional # noqa
-from httplib import *
-from httplib import HTTPS_PORT # This is not imported with just '*'
-import SSL
class HTTPSConnection(HTTPConnection):
@@ -20,43 +27,77 @@ class HTTPSConnection(HTTPConnection):
default_port = HTTPS_PORT
def __init__(self, host, port=None, strict=None, **ssl):
- self.session = None
- keys = ssl.keys()
- try:
- keys.remove('key_file')
- except ValueError:
- pass
- try:
- keys.remove('cert_file')
- except ValueError:
- pass
- try:
- keys.remove('ssl_context')
- except ValueError:
- pass
+ # type: (str, Optional[int], Optional[bool], **Any) -> None
+ """
+ Represents one transaction with an HTTP server over the SSL
+ connection.
+
+ :param host: host name
+ :param port: port number
+ :param strict: if switched on, it raises BadStatusLine to be
+ raised if the status line can't be parsed as
+ a valid HTTP/1.0 or 1.1 status line.
+ :param ssl: dict with all remaining named real parameters of the
+ function. Specifically, ``ssl_context`` is expected
+ to be included with SSL.Context; if it is not
+ default ``'sslv23'`` is substituted).
+ """
+ self.session = None # type: bytes
+ self.host = host
+ self.port = port
+ keys = set(ssl.keys()) - set(('key_file', 'cert_file', 'ssl_context'))
if keys:
- raise ValueError('unknown keyword argument')
+ raise ValueError('unknown keyword argument: %s', keys)
try:
self.ssl_ctx = ssl['ssl_context']
assert isinstance(self.ssl_ctx, SSL.Context), self.ssl_ctx
except KeyError:
- self.ssl_ctx = SSL.Context('sslv23')
+ self.ssl_ctx = SSL.Context()
HTTPConnection.__init__(self, host, port, strict)
def connect(self):
- self.sock = SSL.Connection(self.ssl_ctx)
- if self.session:
- self.sock.set_session(self.session)
- self.sock.connect((self.host, self.port))
+ # type: () -> None
+ error = None
+ # We ignore the returned sockaddr because SSL.Connection.connect needs
+ # a host name.
+ for (family, _, _, _, _) in \
+ socket.getaddrinfo(self.host, self.port, 0,
+ socket.SOCK_STREAM):
+ sock = None
+ try:
+ sock = SSL.Connection(self.ssl_ctx, family=family)
+
+ # set SNI server name since we know it at this point
+ sock.set_tlsext_host_name(self.host)
+
+ if self.session is not None:
+ sock.set_session(self.session)
+ sock.connect((self.host, self.port))
+
+ self.sock = sock
+ sock = None
+ return
+ except socket.error as e:
+ # Other exception are probably SSL-related, in that case we
+ # abort and the exception is forwarded to the caller.
+ error = e
+ finally:
+ if sock is not None:
+ sock.close()
+
+ if error is None:
+ raise AssertionError("Empty list returned by getaddrinfo")
+ raise error
def close(self):
+ # type: () -> None
# This kludges around line 545 of httplib.py,
# which closes the connection in this object;
# the connection remains open in the response
# object.
#
# M2Crypto doesn't close-here-keep-open-there,
- # so, in effect, we don't close until the whole
+ # so, in effect, we don't close until the whole
# business is over and gc kicks in.
#
# XXX Long-running callers beware leakage.
@@ -65,30 +106,17 @@ class HTTPSConnection(HTTPConnection):
# XXX but I've not investigated if the above conditions
# XXX remain.
pass
-
+
def get_session(self):
+ # type: () -> SSL.Session.Session
return self.sock.get_session()
def set_session(self, session):
+ # type: (SSL.Session.Session) -> None
self.session = session
-
-
-class HTTPS(HTTP):
-
- _connection_class = HTTPSConnection
-
- def __init__(self, host='', port=None, strict=None, **ssl):
- HTTP.__init__(self, host, port, strict)
- try:
- self.ssl_ctx = ssl['ssl_context']
- except KeyError:
- self.ssl_ctx = SSL.Context('sslv23')
- assert isinstance(self._conn, HTTPSConnection)
- self._conn.ssl_ctx = self.ssl_ctx
class ProxyHTTPSConnection(HTTPSConnection):
-
"""
An HTTPS Connection that uses a proxy and the CONNECT request.
@@ -101,56 +129,78 @@ class ProxyHTTPSConnection(HTTPSConnection):
through the proxy.
"""
- _ports = {'http' : 80, 'https' : 443}
+ _ports = {'http': 80, 'https': 443}
_AUTH_HEADER = "Proxy-Authorization"
_UA_HEADER = "User-Agent"
def __init__(self, host, port=None, strict=None, username=None,
- password=None, **ssl):
+ password=None, **ssl):
+ # type: (str, Optional[int], Optional[bool], Optional[AnyStr], Optional[AnyStr], **Any) -> None
"""
Create the ProxyHTTPSConnection object.
- host and port are the hostname and port number of the proxy server.
+ :param host: host name of the proxy server
+ :param port: port number of the proxy server
+ :param strict: if switched on, it raises BadStatusLine to be
+ raised if the status line can't be parsed as
+ a valid HTTP/1.0 or 1.1 status line.
+ :param username: username on the proxy server, when required
+ Username can be ``str``, but preferred type
+ is ``bytes``. M2Crypto does some conversion to
+ ``bytes`` when necessary, but it's better when
+ the user of the library does it on its own.
+ :param password: password on the proxy server, when required
+ The same as with ``username``, ``str`` is accepted,
+ but ``bytes`` are preferred.
+ :param ssl: dict with all remaining named real parameters of the
+ function. Specifically, ``ssl_context`` is expected
+ to be included with SSL.Context; if it is not
+ default ``'sslv23'`` is substituted).
"""
HTTPSConnection.__init__(self, host, port, strict, **ssl)
- self._username = username
- self._password = password
- self._proxy_auth = None
- self._proxy_UA = None
+ self._username = username.encode('utf8') \
+ if isinstance(username, six.string_types) else username
+ self._password = password.encode('utf8') \
+ if isinstance(password, six.string_types) else password
+ self._proxy_auth = None # type: str
+ self._proxy_UA = None # type: str
def putrequest(self, method, url, skip_host=0, skip_accept_encoding=0):
- #putrequest is called before connect, so can interpret url and get
- #real host/port to be used to make CONNECT request to proxy
+ # type: (AnyStr, AnyStr, int, int) -> None
+ """
+ putrequest is called before connect, so can interpret url and get
+ real host/port to be used to make CONNECT request to proxy
+ """
proto, netloc, path, query, fragment = urlsplit(url)
if not proto:
- raise ValueError, "unknown URL type: %s" % url
-
- #get host & port
+ raise ValueError("unknown URL type: %s" % url)
+
+ # get host & port
try:
username_password, host_port = netloc.split('@')
except ValueError:
host_port = netloc
try:
- host, port = host_port.split(':')
+ host, port_s = host_port.split(':')
+ port = int(port_s)
except ValueError:
host = host_port
- #try to get port from proto
+ # try to get port from proto
try:
port = self._ports[proto]
except KeyError:
- raise ValueError, "unknown protocol for: %s" % url
+ raise ValueError("unknown protocol for: %s" % url)
- self._real_host = host
- self._real_port = int(port)
- rest = urlunsplit((None, None, path, query, fragment))
- if sys.version_info < (2,4):
- HTTPSConnection.putrequest(self, method, rest, skip_host)
- else:
- HTTPSConnection.putrequest(self, method, rest, skip_host, skip_accept_encoding)
+ self._real_host = host # type: str
+ self._real_port = port # type: int
+ rest = urlunsplit(('', '', path, query, fragment))
+ HTTPSConnection.putrequest(self, method, rest, skip_host,
+ skip_accept_encoding)
def putheader(self, header, value):
+ # type: (AnyStr, AnyStr) -> None
# Store the auth header if passed in.
if header.lower() == self._UA_HEADER.lower():
self._proxy_UA = value
@@ -159,43 +209,47 @@ class ProxyHTTPSConnection(HTTPSConnection):
else:
HTTPSConnection.putheader(self, header, value)
- def endheaders(self):
+ def endheaders(self, *args, **kwargs):
+ # type: (*Any, **Any) -> None
# We've recieved all of hte headers. Use the supplied username
# and password for authorization, possibly overriding the authstring
# supplied in the headers.
if not self._proxy_auth:
self._proxy_auth = self._encode_auth()
- HTTPSConnection.endheaders(self)
+ HTTPSConnection.endheaders(self, *args, **kwargs)
def connect(self):
+ # type: () -> None
HTTPConnection.connect(self)
- #send proxy CONNECT request
+ # send proxy CONNECT request
self.sock.sendall(self._get_connect_msg())
response = HTTPResponse(self.sock)
response.begin()
-
+
code = response.status
if code != 200:
- #proxy returned and error, abort connection, and raise exception
+ # proxy returned and error, abort connection, and raise exception
self.close()
- raise socket.error, "Proxy connection failed: %d" % code
-
+ raise socket.error("Proxy connection failed: %d" % code)
+
self._start_ssl()
def _get_connect_msg(self):
+ # type: () -> bytes
""" Return an HTTP CONNECT request to send to the proxy. """
msg = "CONNECT %s:%d HTTP/1.1\r\n" % (self._real_host, self._real_port)
msg = msg + "Host: %s:%d\r\n" % (self._real_host, self._real_port)
if self._proxy_UA:
msg = msg + "%s: %s\r\n" % (self._UA_HEADER, self._proxy_UA)
if self._proxy_auth:
- msg = msg + "%s: %s\r\n" % (self._AUTH_HEADER, self._proxy_auth)
+ msg = msg + "%s: %s\r\n" % (self._AUTH_HEADER, self._proxy_auth)
msg = msg + "\r\n"
- return msg
+ return six.ensure_binary(msg)
def _start_ssl(self):
+ # type: () -> None
""" Make this connection's socket SSL-aware. """
self.sock = SSL.Connection(self.ssl_ctx, self.sock)
self.sock.setup_ssl()
@@ -203,10 +257,13 @@ class ProxyHTTPSConnection(HTTPSConnection):
self.sock.connect_ssl()
def _encode_auth(self):
+ # type: () -> Optional[bytes]
""" Encode the username and password for use in the auth header. """
if not (self._username and self._password):
return None
# Authenticated proxy
userpass = "%s:%s" % (self._username, self._password)
- enc_userpass = base64.encodestring(userpass).replace("\n", "")
- return "Basic %s" % enc_userpass
+ with warnings.catch_warnings():
+ warnings.simplefilter("ignore", DeprecationWarning)
+ enc_userpass = base64.encodestring(userpass).replace("\n", "")
+ return six.ensure_binary("Basic %s" % enc_userpass)
diff --git a/M2Crypto/m2.py b/M2Crypto/m2.py
index e4bb695..81e4315 100644
--- a/M2Crypto/m2.py
+++ b/M2Crypto/m2.py
@@ -1,3 +1,5 @@
+from __future__ import absolute_import
+
"""M2Crypto low level OpenSSL wrapper functions.
m2 is the low level wrapper for OpenSSL functions. Typically you would not
@@ -25,7 +27,5 @@ Portions created by Open Source Applications Foundation (OSAF) are
Copyright (C) 2004 OSAF. All Rights Reserved.
"""
-from __m2crypto import *
+from M2Crypto.m2crypto import *
lib_init()
-
-
diff --git a/M2Crypto/m2crypto.py b/M2Crypto/m2crypto.py
new file mode 100644
index 0000000..9cad6f4
--- /dev/null
+++ b/M2Crypto/m2crypto.py
@@ -0,0 +1,87 @@
+# This file was automatically generated by SWIG (http://www.swig.org).
+# Version 2.0.10
+#
+# Do not make changes to this file unless you know what you are doing--modify
+# the SWIG interface file instead.
+
+
+
+from sys import version_info
+if version_info >= (2,6,0):
+ def swig_import_helper():
+ from os.path import dirname
+ import imp
+ fp = None
+ try:
+ fp, pathname, description = imp.find_module('_m2crypto', [dirname(__file__)])
+ except ImportError:
+ import _m2crypto
+ return _m2crypto
+ if fp is not None:
+ try:
+ _mod = imp.load_module('_m2crypto', fp, pathname, description)
+ finally:
+ fp.close()
+ return _mod
+ _m2crypto = swig_import_helper()
+ del swig_import_helper
+else:
+ import _m2crypto
+del version_info
+from _m2crypto import *
+try:
+ _swig_property = property
+except NameError:
+ pass # Python < 2.2 doesn't have 'property'.
+def _swig_setattr_nondynamic(self,class_type,name,value,static=1):
+ if (name == "thisown"): return self.this.own(value)
+ if (name == "this"):
+ if type(value).__name__ == 'SwigPyObject':
+ self.__dict__[name] = value
+ return
+ method = class_type.__swig_setmethods__.get(name,None)
+ if method: return method(self,value)
+ if (not static):
+ self.__dict__[name] = value
+ else:
+ raise AttributeError("You cannot add attributes to %s" % self)
+
+def _swig_setattr(self,class_type,name,value):
+ return _swig_setattr_nondynamic(self,class_type,name,value,0)
+
+def _swig_getattr(self,class_type,name):
+ if (name == "thisown"): return self.this.own()
+ method = class_type.__swig_getmethods__.get(name,None)
+ if method: return method(self)
+ raise AttributeError(name)
+
+def _swig_repr(self):
+ try: strthis = "proxy of " + self.this.__repr__()
+ except: strthis = ""
+ return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)
+
+try:
+ _object = object
+ _newclass = 1
+except AttributeError:
+ class _object : pass
+ _newclass = 0
+
+
+def _swig_setattr_nondynamic_method(set):
+ def set_attr(self,name,value):
+ if (name == "thisown"): return self.this.own(value)
+ if hasattr(self,name) or (name == "this"):
+ set(self,name,value)
+ else:
+ raise AttributeError("You cannot add attributes to %s" % self)
+ return set_attr
+
+
+
+
+
+
+
+
+
diff --git a/M2Crypto/m2urllib.py b/M2Crypto/m2urllib.py
index d951eb2..79791d4 100644
--- a/M2Crypto/m2urllib.py
+++ b/M2Crypto/m2urllib.py
@@ -1,51 +1,102 @@
-"""M2Crypto enhancement to Python's urllib for handling
+from __future__ import absolute_import, print_function
+
+"""M2Crypto enhancement to Python's urllib for handling
'https' url's.
+FIXME: it is questionable whether we need this old-style module at all. urllib
+(not urllib2) is in Python 3 support just as a legacy API.
+
Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
-import string, sys, urllib
-from urllib import *
+import base64
+import warnings
+
+from M2Crypto import SSL, httpslib, six, util
+
+from M2Crypto.six.moves.urllib_response import addinfourl
+if util.py27plus:
+ from typing import AnyStr, Optional # noqa
-import SSL
-import httpslib
+# six.moves doesn't support star imports
+if six.PY3:
+ from urllib.request import * # noqa for other modules to import
+ from urllib.parse import * # noqa for other modules to import
+ from urllib.error import * # noqa for other modules to import
+else:
+ from urllib import * # noqa
-DEFAULT_PROTOCOL='sslv23'
def open_https(self, url, data=None, ssl_context=None):
+ # type: (URLOpener, AnyStr, Optional[bytes], Optional[SSL.Context]) -> addinfourl
+ """
+ Open URL over the SSL connection.
+
+ :param url: URL to be opened
+ :param data: data for the POST request
+ :param ssl_context: SSL.Context to be used
+ :return:
+ """
+ if six.PY3:
+ warnings.warn('URLOpener has been deprecated in Py3k', DeprecationWarning)
+
if ssl_context is not None and isinstance(ssl_context, SSL.Context):
self.ctx = ssl_context
else:
- self.ctx = SSL.Context(DEFAULT_PROTOCOL)
+ self.ctx = SSL.Context()
user_passwd = None
- if type(url) is type(""):
- host, selector = splithost(url)
- if host:
- user_passwd, host = splituser(host)
- host = unquote(host)
- realhost = host
+ if isinstance(url, six.string_types):
+ try: # python 2
+ # http://pydoc.org/2.5.1/urllib.html
+ host, selector = splithost(url)
+ if host:
+ user_passwd, host = splituser(host)
+ host = unquote(host)
+ realhost = host
+ except NameError: # python 3 has no splithost
+ # https://docs.python.org/3/library/urllib.parse.html
+ parsed = urlparse(url)
+ host = parsed.hostname
+ if parsed.port:
+ host += ":{0}".format(parsed.port)
+ user_passwd = parsed.password
+ if parsed.password:
+ user_passwd += ":{0}".format(parsed.password)
+ selector = parsed.path
else:
host, selector = url
urltype, rest = splittype(selector)
url = rest
user_passwd = None
- if string.lower(urltype) != 'http':
+ if urltype.lower() != 'http':
realhost = None
else:
- realhost, rest = splithost(rest)
- if realhost:
- user_passwd, realhost = splituser(realhost)
- if user_passwd:
- selector = "%s://%s%s" % (urltype, realhost, rest)
- #print "proxy via http:", host, selector
- if not host: raise IOError, ('http error', 'no host given')
+ try: # python 2
+ realhost, rest = splithost(rest)
+ if realhost:
+ user_passwd, realhost = splituser(realhost)
+ if user_passwd:
+ selector = "%s://%s%s" % (urltype, realhost, rest)
+ except NameError: # python 3 has no splithost
+ parsed = urlparse(rest)
+ host = parsed.hostname
+ if parsed.port:
+ host += ":{0}".format(parsed.port)
+ user_passwd = parsed.username
+ if parsed.password:
+ user_passwd += ":{0}".format(parsed.password)
+ # print("proxy via http:", host, selector)
+ if not host:
+ raise IOError('http error', 'no host given')
if user_passwd:
- import base64
- auth = string.strip(base64.encodestring(user_passwd))
+ if six.PY3:
+ auth = base64.encodebytes(user_passwd).strip()
+ else:
+ auth = base64.encodestring(user_passwd).strip()
else:
auth = None
# Start here!
h = httpslib.HTTPSConnection(host=host, ssl_context=self.ctx)
- #h.set_debuglevel(1)
+ # h.set_debuglevel(1)
# Stop here!
if data is not None:
h.putrequest('POST', selector)
@@ -53,18 +104,18 @@ def open_https(self, url, data=None, ssl_context=None):
h.putheader('Content-length', '%d' % len(data))
else:
h.putrequest('GET', selector)
- if auth: h.putheader('Authorization', 'Basic %s' % auth)
- for args in self.addheaders: apply(h.putheader, args)
+ if auth:
+ h.putheader('Authorization', 'Basic %s' % auth)
+ for args in self.addheaders:
+ h.putheader(*args) # for python3 - used to use apply
h.endheaders()
if data is not None:
h.send(data + '\r\n')
# Here again!
resp = h.getresponse()
fp = resp.fp
- return urllib.addinfourl(fp, resp.msg, "https:" + url)
+ return addinfourl(fp, resp.msg, "https:" + url)
# Stop again.
-# Minor brain surgery.
+# Minor brain surgery.
URLopener.open_https = open_https
-
-
diff --git a/M2Crypto/m2urllib2.py b/M2Crypto/m2urllib2.py
index e500410..acac92f 100644
--- a/M2Crypto/m2urllib2.py
+++ b/M2Crypto/m2urllib2.py
@@ -1,5 +1,7 @@
+from __future__ import absolute_import
+
"""
-M2Crypto enhancement to Python's urllib2 for handling
+M2Crypto enhancement to Python's urllib2 for handling
'https' url's.
Code from urllib2 is Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007
@@ -12,29 +14,46 @@ Summary of changes:
"""
import socket
-from urllib2 import *
-import urlparse
-import SSL
-import httpslib
+from M2Crypto import SSL, httpslib, six, util
+
+from M2Crypto.six.moves.urllib_parse import urldefrag, urlparse as url_parse
+from M2Crypto.six.moves.urllib_response import addinfourl
+if util.py27plus:
+ from typing import List, Optional # noqa
+
+# six.moves doesn't support star imports
+if six.PY3:
+ from urllib.request import * # noqa other modules want to import
+ from urllib.error import * # noqa other modules want to import
+else:
+ from urllib2 import * # noqa
+
+try:
+ mother_class = socket._fileobject
+except AttributeError:
+ mother_class = socket.SocketIO
-class _closing_fileobject(socket._fileobject):
- '''socket._fileobject that propagates self.close() to the socket.
+
+class _closing_fileobject(mother_class): # noqa
+ """socket._fileobject that propagates self.close() to the socket.
Python 2.5 provides this as socket._fileobject(sock, close=True).
- '''
+ """
- def __init__(self, sock):
- socket._fileobject.__init__(self, sock)
+# for python 3
+try:
+ AbstractHTTPHandler
+except NameError:
+ # somehow this won't get imported by the import * above
+ import urllib.request
+ AbstractHTTPHandler = urllib.request.AbstractHTTPHandler
- def close(self):
- sock = self._sock
- socket._fileobject.close(self)
- sock.close()
class HTTPSHandler(AbstractHTTPHandler):
- def __init__(self, ssl_context = None):
+ def __init__(self, ssl_context=None):
+ # type: (SSL.Context) -> None
AbstractHTTPHandler.__init__(self)
if ssl_context is not None:
@@ -45,28 +64,41 @@ class HTTPSHandler(AbstractHTTPHandler):
# Copied from urllib2, so we can set the ssl context.
def https_open(self, req):
+ # type: (Request) -> addinfourl
"""Return an addinfourl object for the request, using http_class.
http_class must implement the HTTPConnection API from httplib.
The addinfourl return value is a file-like object. It also
has methods and attributes including:
+
- info(): return a mimetools.Message object for the headers
+
- geturl(): return the original request URL
+
- code: HTTP status code
"""
- host = req.get_host()
+ # https://docs.python.org/3.3/library/urllib.request.html#urllib.request.Request.get_host
+ try: # up to python-3.2
+ host = req.get_host()
+ except AttributeError: # from python-3.3
+ host = req.host
if not host:
raise URLError('no host given')
# Our change: Check to see if we're using a proxy.
# Then create an appropriate ssl-aware connection.
- full_url = req.get_full_url()
- target_host = urlparse.urlparse(full_url)[1]
+ full_url = req.get_full_url()
+ target_host = url_parse(full_url)[1]
- if (target_host != host):
- h = httpslib.ProxyHTTPSConnection(host = host, ssl_context = self.ctx)
+ if target_host != host:
+ request_uri = urldefrag(full_url)[0]
+ h = httpslib.ProxyHTTPSConnection(host=host, ssl_context=self.ctx)
else:
- h = httpslib.HTTPSConnection(host = host, ssl_context = self.ctx)
+ try: # up to python-3.2
+ request_uri = req.get_selector()
+ except AttributeError: # from python-3.3
+ request_uri = req.selector
+ h = httpslib.HTTPSConnection(host=host, ssl_context=self.ctx)
# End our change
h.set_debuglevel(self._debuglevel)
@@ -80,9 +112,9 @@ class HTTPSHandler(AbstractHTTPHandler):
# request.
headers["Connection"] = "close"
try:
- h.request(req.get_method(), req.get_selector(), req.data, headers)
+ h.request(req.get_method(), request_uri, req.data, headers)
r = h.getresponse()
- except socket.error, err: # XXX what error?
+ except socket.error as err: # XXX what error?
raise URLError(err)
# Pick apart the HTTPResponse object to get the addinfourl
@@ -92,24 +124,27 @@ class HTTPSHandler(AbstractHTTPHandler):
# for Windows. That adapter calls recv(), so delegate recv()
# to read(). This weird wrapping allows the returned object to
# have readline() and readlines() methods.
-
- # XXX It might be better to extract the read buffering code
- # out of socket._fileobject() and into a base class.
-
r.recv = r.read
- fp = _closing_fileobject(r)
+ if six.PY2:
+ fp = socket._fileobject(r, close=True)
+ else:
+ r._decref_socketios = lambda: None
+ r.ssl = h.sock.ssl
+ r._timeout = -1.0
+ r.recv_into = r.readinto
+ fp = socket.SocketIO(r, 'rb')
resp = addinfourl(fp, r.msg, req.get_full_url())
resp.code = r.status
resp.msg = r.reason
return resp
-
https_request = AbstractHTTPHandler.do_request_
# Copied from urllib2 with modifications for ssl
-def build_opener(ssl_context = None, *handlers):
+def build_opener(ssl_context=None, *handlers):
+ # type: (Optional[SSL.Context], *object) -> OpenerDirector
"""Create an opener object from a list of handlers.
The opener will use several default handlers, including support
@@ -118,9 +153,9 @@ def build_opener(ssl_context = None, *handlers):
If any of the handlers passed as arguments are subclasses of the
default handlers, the default handlers will not be used.
"""
- import types
+
def isclass(obj):
- return isinstance(obj, types.ClassType) or hasattr(obj, "__bases__")
+ return isinstance(obj, type) or hasattr(obj, "__bases__")
opener = OpenerDirector()
default_classes = [ProxyHandler, UnknownHandler, HTTPHandler,
@@ -144,7 +179,6 @@ def build_opener(ssl_context = None, *handlers):
if HTTPSHandler not in skip:
opener.add_handler(HTTPSHandler(ssl_context))
-
for h in handlers:
if isclass(h):
h = h()
diff --git a/M2Crypto/m2xmlrpclib.py b/M2Crypto/m2xmlrpclib.py
index bb50a01..c7fe142 100644
--- a/M2Crypto/m2xmlrpclib.py
+++ b/M2Crypto/m2xmlrpclib.py
@@ -1,32 +1,47 @@
+from __future__ import absolute_import
+
"""M2Crypto enhancement to xmlrpclib.
Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
-import base64, string, sys
+import base64
-from xmlrpclib import *
import M2Crypto
-import SSL, httpslib, m2urllib
-__version__ = M2Crypto.version
+from M2Crypto import SSL, httpslib, m2urllib, six, util
+if util.py27plus:
+ from typing import Any, AnyStr, Callable, Optional # noqa
+
+from M2Crypto.six.moves.xmlrpc_client import ProtocolError, Transport
+# six.moves doesn't support star imports
+if six.PY3:
+ from xmlrpc.client import * # noqa
+else:
+ from xmlrpclib import * # noqa
+
+__version__ = M2Crypto.__version__
+
class SSL_Transport(Transport):
- user_agent = "M2Crypto_XMLRPC/%s - %s" % (__version__, Transport.user_agent)
+ user_agent = "M2Crypto_XMLRPC/%s - %s" % (__version__,
+ Transport.user_agent)
def __init__(self, ssl_context=None, *args, **kw):
- if getattr(Transport, '__init__', None) is not None:
- Transport.__init__(self, *args, **kw)
+ # type: (Optional[SSL.Context], *Any, **Any) -> None
+ Transport.__init__(self, *args, **kw)
if ssl_context is None:
- self.ssl_ctx=SSL.Context('sslv23')
+ self.ssl_ctx = SSL.Context()
else:
- self.ssl_ctx=ssl_context
+ self.ssl_ctx = ssl_context
def request(self, host, handler, request_body, verbose=0):
+ # type: (AnyStr, Callable, bytes, int) -> object
# Handle username and password.
user_passwd, host_port = m2urllib.splituser(host)
_host, _port = m2urllib.splitport(host_port)
- h = httpslib.HTTPS(_host, int(_port), ssl_context=self.ssl_ctx)
+ h = httpslib.HTTPSConnection(_host, int(_port),
+ ssl_context=self.ssl_ctx)
if verbose:
h.set_debuglevel(1)
@@ -43,7 +58,7 @@ class SSL_Transport(Transport):
# Authorisation.
if user_passwd is not None:
- auth=string.strip(base64.encodestring(user_passwd))
+ auth = base64.encodestring(user_passwd).strip()
h.putheader('Authorization', 'Basic %s' % auth)
h.endheaders()
@@ -58,8 +73,7 @@ class SSL_Transport(Transport):
host + handler,
errcode, errmsg,
headers
- )
+ )
self.verbose = verbose
return self.parse_response(h.getfile())
-
diff --git a/M2Crypto/six.py b/M2Crypto/six.py
new file mode 100644
index 0000000..8d9ac41
--- /dev/null
+++ b/M2Crypto/six.py
@@ -0,0 +1,950 @@
+# Copyright (c) 2010-2018 Benjamin Peterson
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+"""Utilities for writing code that runs on Python 2 and 3"""
+
+from __future__ import absolute_import
+
+import functools
+import itertools
+import operator
+import sys
+import types
+
+__author__ = "Benjamin Peterson <benjamin@python.org>"
+__version__ = "1.11.0"
+
+
+# Useful for very coarse version differentiation.
+PY2 = sys.version_info[0] == 2
+PY3 = sys.version_info[0] == 3
+PY34 = sys.version_info[0:2] >= (3, 4)
+
+if PY3:
+ string_types = str,
+ integer_types = int,
+ class_types = type,
+ text_type = str
+ binary_type = bytes
+
+ MAXSIZE = sys.maxsize
+else:
+ string_types = basestring,
+ integer_types = (int, long)
+ class_types = (type, types.ClassType)
+ text_type = unicode
+ binary_type = str
+
+ if sys.platform.startswith("java"):
+ # Jython always uses 32 bits.
+ MAXSIZE = int((1 << 31) - 1)
+ else:
+ # It's possible to have sizeof(long) != sizeof(Py_ssize_t).
+ class X(object):
+
+ def __len__(self):
+ return 1 << 31
+ try:
+ len(X())
+ except OverflowError:
+ # 32-bit
+ MAXSIZE = int((1 << 31) - 1)
+ else:
+ # 64-bit
+ MAXSIZE = int((1 << 63) - 1)
+ del X
+
+
+def _add_doc(func, doc):
+ """Add documentation to a function."""
+ func.__doc__ = doc
+
+
+def _import_module(name):
+ """Import module, returning the module after the last dot."""
+ __import__(name)
+ return sys.modules[name]
+
+
+class _LazyDescr(object):
+
+ def __init__(self, name):
+ self.name = name
+
+ def __get__(self, obj, tp):
+ result = self._resolve()
+ setattr(obj, self.name, result) # Invokes __set__.
+ try:
+ # This is a bit ugly, but it avoids running this again by
+ # removing this descriptor.
+ delattr(obj.__class__, self.name)
+ except AttributeError:
+ pass
+ return result
+
+
+class MovedModule(_LazyDescr):
+
+ def __init__(self, name, old, new=None):
+ super(MovedModule, self).__init__(name)
+ if PY3:
+ if new is None:
+ new = name
+ self.mod = new
+ else:
+ self.mod = old
+
+ def _resolve(self):
+ return _import_module(self.mod)
+
+ def __getattr__(self, attr):
+ _module = self._resolve()
+ value = getattr(_module, attr)
+ setattr(self, attr, value)
+ return value
+
+
+class _LazyModule(types.ModuleType):
+
+ def __init__(self, name):
+ super(_LazyModule, self).__init__(name)
+ self.__doc__ = self.__class__.__doc__
+
+ def __dir__(self):
+ attrs = ["__doc__", "__name__"]
+ attrs += [attr.name for attr in self._moved_attributes]
+ return attrs
+
+ # Subclasses should override this
+ _moved_attributes = []
+
+
+class MovedAttribute(_LazyDescr):
+
+ def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None):
+ super(MovedAttribute, self).__init__(name)
+ if PY3:
+ if new_mod is None:
+ new_mod = name
+ self.mod = new_mod
+ if new_attr is None:
+ if old_attr is None:
+ new_attr = name
+ else:
+ new_attr = old_attr
+ self.attr = new_attr
+ else:
+ self.mod = old_mod
+ if old_attr is None:
+ old_attr = name
+ self.attr = old_attr
+
+ def _resolve(self):
+ module = _import_module(self.mod)
+ return getattr(module, self.attr)
+
+
+class _SixMetaPathImporter(object):
+
+ """
+ A meta path importer to import six.moves and its submodules.
+
+ This class implements a PEP302 finder and loader. It should be compatible
+ with Python 2.5 and all existing versions of Python3
+ """
+
+ def __init__(self, six_module_name):
+ self.name = six_module_name
+ self.known_modules = {}
+
+ def _add_module(self, mod, *fullnames):
+ for fullname in fullnames:
+ self.known_modules[self.name + "." + fullname] = mod
+
+ def _get_module(self, fullname):
+ return self.known_modules[self.name + "." + fullname]
+
+ def find_module(self, fullname, path=None):
+ if fullname in self.known_modules:
+ return self
+ return None
+
+ def __get_module(self, fullname):
+ try:
+ return self.known_modules[fullname]
+ except KeyError:
+ raise ImportError("This loader does not know module " + fullname)
+
+ def load_module(self, fullname):
+ try:
+ # in case of a reload
+ return sys.modules[fullname]
+ except KeyError:
+ pass
+ mod = self.__get_module(fullname)
+ if isinstance(mod, MovedModule):
+ mod = mod._resolve()
+ else:
+ mod.__loader__ = self
+ sys.modules[fullname] = mod
+ return mod
+
+ def is_package(self, fullname):
+ """
+ Return true, if the named module is a package.
+
+ We need this method to get correct spec objects with
+ Python 3.4 (see PEP451)
+ """
+ return hasattr(self.__get_module(fullname), "__path__")
+
+ def get_code(self, fullname):
+ """Return None
+
+ Required, if is_package is implemented"""
+ self.__get_module(fullname) # eventually raises ImportError
+ return None
+ get_source = get_code # same as get_code
+
+_importer = _SixMetaPathImporter(__name__)
+
+
+class _MovedItems(_LazyModule):
+
+ """Lazy loading of moved objects"""
+ __path__ = [] # mark as package
+
+
+_moved_attributes = [
+ MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"),
+ MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"),
+ MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"),
+ MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"),
+ MovedAttribute("intern", "__builtin__", "sys"),
+ MovedAttribute("map", "itertools", "builtins", "imap", "map"),
+ MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"),
+ MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"),
+ MovedAttribute("getoutput", "commands", "subprocess"),
+ MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"),
+ MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"),
+ MovedAttribute("reduce", "__builtin__", "functools"),
+ MovedAttribute("shlex_quote", "pipes", "shlex", "quote"),
+ MovedAttribute("StringIO", "StringIO", "io"),
+ MovedAttribute("UserDict", "UserDict", "collections"),
+ MovedAttribute("UserList", "UserList", "collections"),
+ MovedAttribute("UserString", "UserString", "collections"),
+ MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"),
+ MovedAttribute("zip", "itertools", "builtins", "izip", "zip"),
+ MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"),
+ MovedModule("builtins", "__builtin__"),
+ MovedModule("configparser", "ConfigParser"),
+ MovedModule("copyreg", "copy_reg"),
+ MovedModule("dbm_gnu", "gdbm", "dbm.gnu"),
+ MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread"),
+ MovedModule("http_cookiejar", "cookielib", "http.cookiejar"),
+ MovedModule("http_cookies", "Cookie", "http.cookies"),
+ MovedModule("html_entities", "htmlentitydefs", "html.entities"),
+ MovedModule("html_parser", "HTMLParser", "html.parser"),
+ MovedModule("http_client", "httplib", "http.client"),
+ MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"),
+ MovedModule("email_mime_image", "email.MIMEImage", "email.mime.image"),
+ MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"),
+ MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"),
+ MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"),
+ MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"),
+ MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"),
+ MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"),
+ MovedModule("cPickle", "cPickle", "pickle"),
+ MovedModule("queue", "Queue"),
+ MovedModule("reprlib", "repr"),
+ MovedModule("socketserver", "SocketServer"),
+ MovedModule("_thread", "thread", "_thread"),
+ MovedModule("tkinter", "Tkinter"),
+ MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"),
+ MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"),
+ MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"),
+ MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"),
+ MovedModule("tkinter_tix", "Tix", "tkinter.tix"),
+ MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"),
+ MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"),
+ MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"),
+ MovedModule("tkinter_colorchooser", "tkColorChooser",
+ "tkinter.colorchooser"),
+ MovedModule("tkinter_commondialog", "tkCommonDialog",
+ "tkinter.commondialog"),
+ MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"),
+ MovedModule("tkinter_font", "tkFont", "tkinter.font"),
+ MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"),
+ MovedModule("tkinter_tksimpledialog", "tkSimpleDialog",
+ "tkinter.simpledialog"),
+ MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"),
+ MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"),
+ MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"),
+ MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"),
+ MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"),
+ MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"),
+]
+# Add windows specific modules.
+if sys.platform == "win32":
+ _moved_attributes += [
+ MovedModule("winreg", "_winreg"),
+ ]
+
+for attr in _moved_attributes:
+ setattr(_MovedItems, attr.name, attr)
+ if isinstance(attr, MovedModule):
+ _importer._add_module(attr, "moves." + attr.name)
+del attr
+
+_MovedItems._moved_attributes = _moved_attributes
+
+moves = _MovedItems(__name__ + ".moves")
+_importer._add_module(moves, "moves")
+
+
+class Module_six_moves_urllib_parse(_LazyModule):
+
+ """Lazy loading of moved objects in six.moves.urllib_parse"""
+
+
+_urllib_parse_moved_attributes = [
+ MovedAttribute("ParseResult", "urlparse", "urllib.parse"),
+ MovedAttribute("SplitResult", "urlparse", "urllib.parse"),
+ MovedAttribute("parse_qs", "urlparse", "urllib.parse"),
+ MovedAttribute("parse_qsl", "urlparse", "urllib.parse"),
+ MovedAttribute("urldefrag", "urlparse", "urllib.parse"),
+ MovedAttribute("urljoin", "urlparse", "urllib.parse"),
+ MovedAttribute("urlparse", "urlparse", "urllib.parse"),
+ MovedAttribute("urlsplit", "urlparse", "urllib.parse"),
+ MovedAttribute("urlunparse", "urlparse", "urllib.parse"),
+ MovedAttribute("urlunsplit", "urlparse", "urllib.parse"),
+ MovedAttribute("quote", "urllib", "urllib.parse"),
+ MovedAttribute("quote_plus", "urllib", "urllib.parse"),
+ MovedAttribute("unquote", "urllib", "urllib.parse"),
+ MovedAttribute("unquote_plus", "urllib", "urllib.parse"),
+ MovedAttribute("unquote_to_bytes", "urllib", "urllib.parse", "unquote", "unquote_to_bytes"),
+ MovedAttribute("urlencode", "urllib", "urllib.parse"),
+ MovedAttribute("splitquery", "urllib", "urllib.parse"),
+ MovedAttribute("splittag", "urllib", "urllib.parse"),
+ MovedAttribute("splituser", "urllib", "urllib.parse"),
+ MovedAttribute("splitvalue", "urllib", "urllib.parse"),
+ MovedAttribute("uses_fragment", "urlparse", "urllib.parse"),
+ MovedAttribute("uses_netloc", "urlparse", "urllib.parse"),
+ MovedAttribute("uses_params", "urlparse", "urllib.parse"),
+ MovedAttribute("uses_query", "urlparse", "urllib.parse"),
+ MovedAttribute("uses_relative", "urlparse", "urllib.parse"),
+]
+for attr in _urllib_parse_moved_attributes:
+ setattr(Module_six_moves_urllib_parse, attr.name, attr)
+del attr
+
+Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes
+
+_importer._add_module(Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"),
+ "moves.urllib_parse", "moves.urllib.parse")
+
+
+class Module_six_moves_urllib_error(_LazyModule):
+
+ """Lazy loading of moved objects in six.moves.urllib_error"""
+
+
+_urllib_error_moved_attributes = [
+ MovedAttribute("URLError", "urllib2", "urllib.error"),
+ MovedAttribute("HTTPError", "urllib2", "urllib.error"),
+ MovedAttribute("ContentTooShortError", "urllib", "urllib.error"),
+]
+for attr in _urllib_error_moved_attributes:
+ setattr(Module_six_moves_urllib_error, attr.name, attr)
+del attr
+
+Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes
+
+_importer._add_module(Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"),
+ "moves.urllib_error", "moves.urllib.error")
+
+
+class Module_six_moves_urllib_request(_LazyModule):
+
+ """Lazy loading of moved objects in six.moves.urllib_request"""
+
+
+_urllib_request_moved_attributes = [
+ MovedAttribute("urlopen", "urllib2", "urllib.request"),
+ MovedAttribute("install_opener", "urllib2", "urllib.request"),
+ MovedAttribute("build_opener", "urllib2", "urllib.request"),
+ MovedAttribute("pathname2url", "urllib", "urllib.request"),
+ MovedAttribute("url2pathname", "urllib", "urllib.request"),
+ MovedAttribute("getproxies", "urllib", "urllib.request"),
+ MovedAttribute("Request", "urllib2", "urllib.request"),
+ MovedAttribute("OpenerDirector", "urllib2", "urllib.request"),
+ MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"),
+ MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"),
+ MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"),
+ MovedAttribute("ProxyHandler", "urllib2", "urllib.request"),
+ MovedAttribute("BaseHandler", "urllib2", "urllib.request"),
+ MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"),
+ MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"),
+ MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"),
+ MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"),
+ MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"),
+ MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"),
+ MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"),
+ MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"),
+ MovedAttribute("HTTPHandler", "urllib2", "urllib.request"),
+ MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"),
+ MovedAttribute("FileHandler", "urllib2", "urllib.request"),
+ MovedAttribute("FTPHandler", "urllib2", "urllib.request"),
+ MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"),
+ MovedAttribute("UnknownHandler", "urllib2", "urllib.request"),
+ MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"),
+ MovedAttribute("urlretrieve", "urllib", "urllib.request"),
+ MovedAttribute("urlcleanup", "urllib", "urllib.request"),
+ MovedAttribute("URLopener", "urllib", "urllib.request"),
+ MovedAttribute("FancyURLopener", "urllib", "urllib.request"),
+ MovedAttribute("proxy_bypass", "urllib", "urllib.request"),
+ MovedAttribute("parse_http_list", "urllib2", "urllib.request"),
+ MovedAttribute("parse_keqv_list", "urllib2", "urllib.request"),
+]
+for attr in _urllib_request_moved_attributes:
+ setattr(Module_six_moves_urllib_request, attr.name, attr)
+del attr
+
+Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes
+
+_importer._add_module(Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"),
+ "moves.urllib_request", "moves.urllib.request")
+
+
+class Module_six_moves_urllib_response(_LazyModule):
+
+ """Lazy loading of moved objects in six.moves.urllib_response"""
+
+
+_urllib_response_moved_attributes = [
+ MovedAttribute("addbase", "urllib", "urllib.response"),
+ MovedAttribute("addclosehook", "urllib", "urllib.response"),
+ MovedAttribute("addinfo", "urllib", "urllib.response"),
+ MovedAttribute("addinfourl", "urllib", "urllib.response"),
+]
+for attr in _urllib_response_moved_attributes:
+ setattr(Module_six_moves_urllib_response, attr.name, attr)
+del attr
+
+Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes
+
+_importer._add_module(Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"),
+ "moves.urllib_response", "moves.urllib.response")
+
+
+class Module_six_moves_urllib_robotparser(_LazyModule):
+
+ """Lazy loading of moved objects in six.moves.urllib_robotparser"""
+
+
+_urllib_robotparser_moved_attributes = [
+ MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"),
+]
+for attr in _urllib_robotparser_moved_attributes:
+ setattr(Module_six_moves_urllib_robotparser, attr.name, attr)
+del attr
+
+Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes
+
+_importer._add_module(Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"),
+ "moves.urllib_robotparser", "moves.urllib.robotparser")
+
+
+class Module_six_moves_urllib(types.ModuleType):
+
+ """Create a six.moves.urllib namespace that resembles the Python 3 namespace"""
+ __path__ = [] # mark as package
+ parse = _importer._get_module("moves.urllib_parse")
+ error = _importer._get_module("moves.urllib_error")
+ request = _importer._get_module("moves.urllib_request")
+ response = _importer._get_module("moves.urllib_response")
+ robotparser = _importer._get_module("moves.urllib_robotparser")
+
+ def __dir__(self):
+ return ['parse', 'error', 'request', 'response', 'robotparser']
+
+_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"),
+ "moves.urllib")
+
+
+def add_move(move):
+ """Add an item to six.moves."""
+ setattr(_MovedItems, move.name, move)
+
+
+def remove_move(name):
+ """Remove item from six.moves."""
+ try:
+ delattr(_MovedItems, name)
+ except AttributeError:
+ try:
+ del moves.__dict__[name]
+ except KeyError:
+ raise AttributeError("no such move, %r" % (name,))
+
+
+if PY3:
+ _meth_func = "__func__"
+ _meth_self = "__self__"
+
+ _func_closure = "__closure__"
+ _func_code = "__code__"
+ _func_defaults = "__defaults__"
+ _func_globals = "__globals__"
+else:
+ _meth_func = "im_func"
+ _meth_self = "im_self"
+
+ _func_closure = "func_closure"
+ _func_code = "func_code"
+ _func_defaults = "func_defaults"
+ _func_globals = "func_globals"
+
+
+try:
+ advance_iterator = next
+except NameError:
+ def advance_iterator(it):
+ return it.next()
+next = advance_iterator
+
+
+try:
+ callable = callable
+except NameError:
+ def callable(obj):
+ return any("__call__" in klass.__dict__ for klass in type(obj).__mro__)
+
+
+if PY3:
+ def get_unbound_function(unbound):
+ return unbound
+
+ create_bound_method = types.MethodType
+
+ def create_unbound_method(func, cls):
+ return func
+
+ Iterator = object
+else:
+ def get_unbound_function(unbound):
+ return unbound.im_func
+
+ def create_bound_method(func, obj):
+ return types.MethodType(func, obj, obj.__class__)
+
+ def create_unbound_method(func, cls):
+ return types.MethodType(func, None, cls)
+
+ class Iterator(object):
+
+ def next(self):
+ return type(self).__next__(self)
+
+ callable = callable
+_add_doc(get_unbound_function,
+ """Get the function out of a possibly unbound function""")
+
+
+get_method_function = operator.attrgetter(_meth_func)
+get_method_self = operator.attrgetter(_meth_self)
+get_function_closure = operator.attrgetter(_func_closure)
+get_function_code = operator.attrgetter(_func_code)
+get_function_defaults = operator.attrgetter(_func_defaults)
+get_function_globals = operator.attrgetter(_func_globals)
+
+
+if PY3:
+ def iterkeys(d, **kw):
+ return iter(d.keys(**kw))
+
+ def itervalues(d, **kw):
+ return iter(d.values(**kw))
+
+ def iteritems(d, **kw):
+ return iter(d.items(**kw))
+
+ def iterlists(d, **kw):
+ return iter(d.lists(**kw))
+
+ viewkeys = operator.methodcaller("keys")
+
+ viewvalues = operator.methodcaller("values")
+
+ viewitems = operator.methodcaller("items")
+else:
+ def iterkeys(d, **kw):
+ return d.iterkeys(**kw)
+
+ def itervalues(d, **kw):
+ return d.itervalues(**kw)
+
+ def iteritems(d, **kw):
+ return d.iteritems(**kw)
+
+ def iterlists(d, **kw):
+ return d.iterlists(**kw)
+
+ viewkeys = operator.methodcaller("viewkeys")
+
+ viewvalues = operator.methodcaller("viewvalues")
+
+ viewitems = operator.methodcaller("viewitems")
+
+_add_doc(iterkeys, "Return an iterator over the keys of a dictionary.")
+_add_doc(itervalues, "Return an iterator over the values of a dictionary.")
+_add_doc(iteritems,
+ "Return an iterator over the (key, value) pairs of a dictionary.")
+_add_doc(iterlists,
+ "Return an iterator over the (key, [values]) pairs of a dictionary.")
+
+
+if PY3:
+ def b(s):
+ return s.encode("latin-1")
+
+ def u(s):
+ return s
+ unichr = chr
+ import struct
+ int2byte = struct.Struct(">B").pack
+ del struct
+ byte2int = operator.itemgetter(0)
+ indexbytes = operator.getitem
+ iterbytes = iter
+ import io
+ StringIO = io.StringIO
+ BytesIO = io.BytesIO
+ _assertCountEqual = "assertCountEqual"
+ if sys.version_info[1] <= 1:
+ _assertRaisesRegex = "assertRaisesRegexp"
+ _assertRegex = "assertRegexpMatches"
+ else:
+ _assertRaisesRegex = "assertRaisesRegex"
+ _assertRegex = "assertRegex"
+else:
+ def b(s):
+ return s
+ # Workaround for standalone backslash
+
+ def u(s):
+ return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape")
+ unichr = unichr
+ int2byte = chr
+
+ def byte2int(bs):
+ return ord(bs[0])
+
+ def indexbytes(buf, i):
+ return ord(buf[i])
+ iterbytes = functools.partial(itertools.imap, ord)
+ import StringIO
+ StringIO = BytesIO = StringIO.StringIO
+ _assertCountEqual = "assertItemsEqual"
+ _assertRaisesRegex = "assertRaisesRegexp"
+ _assertRegex = "assertRegexpMatches"
+_add_doc(b, """Byte literal""")
+_add_doc(u, """Text literal""")
+
+
+def assertCountEqual(self, *args, **kwargs):
+ return getattr(self, _assertCountEqual)(*args, **kwargs)
+
+
+def assertRaisesRegex(self, *args, **kwargs):
+ return getattr(self, _assertRaisesRegex)(*args, **kwargs)
+
+
+def assertRegex(self, *args, **kwargs):
+ return getattr(self, _assertRegex)(*args, **kwargs)
+
+
+if PY3:
+ exec_ = getattr(moves.builtins, "exec")
+
+ def reraise(tp, value, tb=None):
+ try:
+ if value is None:
+ value = tp()
+ if value.__traceback__ is not tb:
+ raise value.with_traceback(tb)
+ raise value
+ finally:
+ value = None
+ tb = None
+
+else:
+ def exec_(_code_, _globs_=None, _locs_=None):
+ """Execute code in a namespace."""
+ if _globs_ is None:
+ frame = sys._getframe(1)
+ _globs_ = frame.f_globals
+ if _locs_ is None:
+ _locs_ = frame.f_locals
+ del frame
+ elif _locs_ is None:
+ _locs_ = _globs_
+ exec("""exec _code_ in _globs_, _locs_""")
+
+ exec_("""def reraise(tp, value, tb=None):
+ try:
+ raise tp, value, tb
+ finally:
+ tb = None
+""")
+
+
+if sys.version_info[:2] == (3, 2):
+ exec_("""def raise_from(value, from_value):
+ try:
+ if from_value is None:
+ raise value
+ raise value from from_value
+ finally:
+ value = None
+""")
+elif sys.version_info[:2] > (3, 2):
+ exec_("""def raise_from(value, from_value):
+ try:
+ raise value from from_value
+ finally:
+ value = None
+""")
+else:
+ def raise_from(value, from_value):
+ raise value
+
+
+print_ = getattr(moves.builtins, "print", None)
+if print_ is None:
+ def print_(*args, **kwargs):
+ """The new-style print function for Python 2.4 and 2.5."""
+ fp = kwargs.pop("file", sys.stdout)
+ if fp is None:
+ return
+
+ def write(data):
+ if not isinstance(data, basestring):
+ data = str(data)
+ # If the file has an encoding, encode unicode with it.
+ if (isinstance(fp, file) and
+ isinstance(data, unicode) and
+ fp.encoding is not None):
+ errors = getattr(fp, "errors", None)
+ if errors is None:
+ errors = "strict"
+ data = data.encode(fp.encoding, errors)
+ fp.write(data)
+ want_unicode = False
+ sep = kwargs.pop("sep", None)
+ if sep is not None:
+ if isinstance(sep, unicode):
+ want_unicode = True
+ elif not isinstance(sep, str):
+ raise TypeError("sep must be None or a string")
+ end = kwargs.pop("end", None)
+ if end is not None:
+ if isinstance(end, unicode):
+ want_unicode = True
+ elif not isinstance(end, str):
+ raise TypeError("end must be None or a string")
+ if kwargs:
+ raise TypeError("invalid keyword arguments to print()")
+ if not want_unicode:
+ for arg in args:
+ if isinstance(arg, unicode):
+ want_unicode = True
+ break
+ if want_unicode:
+ newline = unicode("\n")
+ space = unicode(" ")
+ else:
+ newline = "\n"
+ space = " "
+ if sep is None:
+ sep = space
+ if end is None:
+ end = newline
+ for i, arg in enumerate(args):
+ if i:
+ write(sep)
+ write(arg)
+ write(end)
+if sys.version_info[:2] < (3, 3):
+ _print = print_
+
+ def print_(*args, **kwargs):
+ fp = kwargs.get("file", sys.stdout)
+ flush = kwargs.pop("flush", False)
+ _print(*args, **kwargs)
+ if flush and fp is not None:
+ fp.flush()
+
+_add_doc(reraise, """Reraise an exception.""")
+
+if sys.version_info[0:2] < (3, 4):
+ def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS,
+ updated=functools.WRAPPER_UPDATES):
+ def wrapper(f):
+ f = functools.wraps(wrapped, assigned, updated)(f)
+ f.__wrapped__ = wrapped
+ return f
+ return wrapper
+else:
+ wraps = functools.wraps
+
+
+def with_metaclass(meta, *bases):
+ """Create a base class with a metaclass."""
+ # This requires a bit of explanation: the basic idea is to make a dummy
+ # metaclass for one level of class instantiation that replaces itself with
+ # the actual metaclass.
+ class metaclass(type):
+
+ def __new__(cls, name, this_bases, d):
+ return meta(name, bases, d)
+
+ @classmethod
+ def __prepare__(cls, name, this_bases):
+ return meta.__prepare__(name, bases)
+ return type.__new__(metaclass, 'temporary_class', (), {})
+
+
+def add_metaclass(metaclass):
+ """Class decorator for creating a class with a metaclass."""
+ def wrapper(cls):
+ orig_vars = cls.__dict__.copy()
+ slots = orig_vars.get('__slots__')
+ if slots is not None:
+ if isinstance(slots, str):
+ slots = [slots]
+ for slots_var in slots:
+ orig_vars.pop(slots_var)
+ orig_vars.pop('__dict__', None)
+ orig_vars.pop('__weakref__', None)
+ return metaclass(cls.__name__, cls.__bases__, orig_vars)
+ return wrapper
+
+
+def ensure_binary(s, encoding='utf-8', errors='strict'):
+ """Coerce **s** to six.binary_type.
+
+ For Python 2:
+ - `unicode` -> encoded to `str`
+ - `str` -> `str`
+
+ For Python 3:
+ - `str` -> encoded to `bytes`
+ - `bytes` -> `bytes`
+ """
+ if isinstance(s, text_type):
+ return s.encode(encoding, errors)
+ elif isinstance(s, binary_type):
+ return s
+ else:
+ raise TypeError("not expecting type '%s'" % type(s))
+
+
+def ensure_str(s, encoding='utf-8', errors='strict'):
+ """Coerce *s* to `str`.
+
+ For Python 2:
+ - `unicode` -> encoded to `str`
+ - `str` -> `str`
+
+ For Python 3:
+ - `str` -> `str`
+ - `bytes` -> decoded to `str`
+ """
+ if not isinstance(s, (text_type, binary_type)):
+ raise TypeError("not expecting type '%s'" % type(s))
+ if PY2 and isinstance(s, text_type):
+ s = s.encode(encoding, errors)
+ elif PY3 and isinstance(s, binary_type):
+ s = s.decode(encoding, errors)
+ return s
+
+
+def ensure_text(s, encoding='utf-8', errors='strict'):
+ """Coerce *s* to six.text_type.
+
+ For Python 2:
+ - `unicode` -> `unicode`
+ - `str` -> `unicode`
+
+ For Python 3:
+ - `str` -> `str`
+ - `bytes` -> decoded to `str`
+ """
+ if isinstance(s, binary_type):
+ return s.decode(encoding, errors)
+ elif isinstance(s, text_type):
+ return s
+ else:
+ raise TypeError("not expecting type '%s'" % type(s))
+
+
+
+def python_2_unicode_compatible(klass):
+ """
+ A decorator that defines __unicode__ and __str__ methods under Python 2.
+ Under Python 3 it does nothing.
+
+ To support Python 2 and 3 with a single code base, define a __str__ method
+ returning text and apply this decorator to the class.
+ """
+ if PY2:
+ if '__str__' not in klass.__dict__:
+ raise ValueError("@python_2_unicode_compatible cannot be applied "
+ "to %s because it doesn't define __str__()." %
+ klass.__name__)
+ klass.__unicode__ = klass.__str__
+ klass.__str__ = lambda self: self.__unicode__().encode('utf-8')
+ return klass
+
+
+# Complete the moves implementation.
+# This code is at the end of this module to speed up module loading.
+# Turn this module into a package.
+__path__ = [] # required for PEP 302 and PEP 451
+__package__ = __name__ # see PEP 366 @ReservedAssignment
+if globals().get("__spec__") is not None:
+ __spec__.submodule_search_locations = [] # PEP 451 @UndefinedVariable
+# Remove other six meta path importers, since they cause problems. This can
+# happen if six is removed from sys.modules and then reloaded. (Setuptools does
+# this for some reason.)
+if sys.meta_path:
+ for i, importer in enumerate(sys.meta_path):
+ # Here's some real nastiness: Another "instance" of the six module might
+ # be floating around. Therefore, we can't use isinstance() to check for
+ # the six meta path importer, since the other six instance will have
+ # inserted an importer with different class.
+ if (type(importer).__name__ == "_SixMetaPathImporter" and
+ importer.name == __name__):
+ del sys.meta_path[i]
+ break
+ del i, importer
+# Finally, add the importer to the meta path import hook.
+sys.meta_path.append(_importer)
diff --git a/M2Crypto/threading.py b/M2Crypto/threading.py
index 4cb8149..f9f2683 100644
--- a/M2Crypto/threading.py
+++ b/M2Crypto/threading.py
@@ -1,20 +1,25 @@
+from __future__ import absolute_import
+
"""
-M2Crypto threading support, required for multithreaded applications.
+M2Crypto threading support, required for multithreaded applications.
Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
# M2Crypto
-import m2
+from M2Crypto import m2
+
def init():
+ # type: () -> None
"""
Initialize threading support.
"""
m2.threading_init()
+
def cleanup():
+ # type: () -> None
"""
End and cleanup threading support.
"""
m2.threading_cleanup()
-
diff --git a/M2Crypto/util.py b/M2Crypto/util.py
index 12103fc..9abf141 100644
--- a/M2Crypto/util.py
+++ b/M2Crypto/util.py
@@ -1,64 +1,81 @@
+from __future__ import absolute_import
"""
M2Crypto utility routines.
-
+
+ NOTHING IN THIS MODULE IS GUARANTEED TO BE STABLE, USED ONLY FOR
+ INTERNAL PURPOSES OF M2CRYPTO.
+
Copyright (c) 1999-2004 Ng Pheng Siong. All rights reserved.
-
+
Portions created by Open Source Applications Foundation (OSAF) are
Copyright (C) 2004 OSAF. All Rights Reserved.
"""
+import binascii
+import logging
import sys
-import m2
-class UtilError(Exception): pass
+from M2Crypto import m2, py27plus, six
+if py27plus:
+ from typing import Any, AnyStr, Optional, Tuple, Union # noqa
+ # see https://github.com/python/typeshed/issues/222
+ AddrType = Union[Tuple[str, int], str]
+
+log = logging.getLogger('util')
+
+
+class UtilError(Exception):
+ pass
m2.util_init(UtilError)
-def h2b(s):
- import array, string
- ar=array.array('c')
- start=0
- if s[:2]=='0x':
- start=2
- for i in range(start, len(s), 2):
- num=string.atoi("%s"%(s[i:i+2],), 16)
- ar.append(chr(num))
- return ar.tostring()
def pkcs5_pad(data, blklen=8):
- pad=(8-(len(data)%8))
- return data+chr(pad)*pad
+ # type: (str, int) -> str
+ pad = (8 - (len(data) % 8))
+ return data + chr(pad) * pad
+
def pkcs7_pad(data, blklen):
- if blklen>255:
- raise ValueError, 'illegal block size'
- pad=(blklen-(len(data)%blklen))
- return data+chr(pad)*pad
+ # type: (str, int) -> str
+ if blklen > 255:
+ raise ValueError('illegal block size')
+ pad = (blklen - (len(data) % blklen))
+ return data + chr(pad) * pad
+
+
+def bin_to_hex(b):
+ # type: (bytes) -> str
+ return six.ensure_text(binascii.b2a_base64(b)[:-1])
+
def octx_to_num(x):
- v = 0L
- lx = len(x)
- for i in range(lx):
- v = v + ord(x[i]) * (256L ** (lx-i-1))
- return v
+ # type: (bytes) -> int
+ return int(binascii.hexlify(x), 16)
+
def genparam_callback(p, n, out=sys.stdout):
- ch = ['.','+','*','\n']
+ # type: (int, Any, file) -> None
+ ch = ['.', '+', '*', '\n']
out.write(ch[p])
out.flush()
+
def quiet_genparam_callback(p, n, out):
+ # type: (Any, Any, Any) -> None
pass
-def passphrase_callback(v, prompt1='Enter passphrase:',
- prompt2='Verify passphrase:'):
+
+def passphrase_callback(v, prompt1='Enter passphrase:',
+ prompt2='Verify passphrase:'):
+ # type: (bool, str, str) -> Optional[str]
from getpass import getpass
while 1:
try:
- p1=getpass(prompt1)
+ p1 = getpass(prompt1)
if v:
- p2=getpass(prompt2)
- if p1==p2:
+ p2 = getpass(prompt2)
+ if p1 == p2:
break
else:
break
@@ -66,6 +83,7 @@ def passphrase_callback(v, prompt1='Enter passphrase:',
return None
return p1
+
def no_passphrase_callback(*args):
+ # type: (*Any) -> str
return ''
-
diff --git a/MANIFEST.in b/MANIFEST.in
new file mode 100644
index 0000000..1eb138a
--- /dev/null
+++ b/MANIFEST.in
@@ -0,0 +1,13 @@
+include SWIG/*.i
+include SWIG/*.h
+include SWIG/*.def
+recursive-include tests *.py *.pem *.der *.b64 README *.pgp *.dat *.p7* *.crt *.txt
+recursive-include doc *
+recursive-include contrib *
+include INSTALL.rst
+include README.rst
+include CHANGES
+include epydoc.conf
+include LICENCE
+include SWIG/_m2crypto_wrap.c
+include M2Crypto/m2crypto.py
diff --git a/PKG-INFO b/PKG-INFO
deleted file mode 100644
index 3972df5..0000000
--- a/PKG-INFO
+++ /dev/null
@@ -1,23 +0,0 @@
-Metadata-Version: 1.0
-Name: M2Crypto
-Version: 0.21.1
-Summary: M2Crypto: A Python crypto and SSL toolkit
-Home-page: http://chandlerproject.org/Projects/MeTooCrypto
-Author: Heikki Toivonen
-Author-email: heikki@osafoundation.org
-License: BSD-style license
-Description: M2Crypto is the most complete Python wrapper for OpenSSL featuring RSA, DSA,
- DH, EC, HMACs, message digests, symmetric ciphers (including AES); SSL
- functionality to implement clients and servers; HTTPS extensions to Python's
- httplib, urllib, and xmlrpclib; unforgeable HMAC'ing AuthCookies for web
- session management; FTP/TLS client and server; S/MIME; ZServerSSL: A HTTPS
- server for Zope and ZSmime: An S/MIME messenger for Zope. M2Crypto can also be
- used to provide SSL for Twisted.
-Platform: any
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: Intended Audience :: Developers
-Classifier: Operating System :: OS Independent
-Classifier: Programming Language :: C
-Classifier: Programming Language :: Python
-Classifier: Topic :: Security :: Cryptography
-Classifier: Topic :: Software Development :: Libraries :: Python Modules
diff --git a/README b/README.rst
index 99affa0..f0b3a27 100644
--- a/README
+++ b/README.rst
@@ -1,13 +1,15 @@
-=========
- M2Crypto
-=========
-
-:Maintainer: Heikki Toivonen
-:Web-Site: http://chandlerproject.org/Projects/MeTooCrypto
+========
+M2Crypto
+========
+:Maintainer: Matěj Cepl
+:Web-Site: https://gitlab.com/m2crypto/m2crypto
+:Documentation: https://m2crypto.readthedocs.io/
+:Email list: m2crypto@lists.redcrew.org or http://redcrew.org/mailman/listinfo/m2crypto
+:IRC channel: `#m2crypto`_ on Freenode
M2Crypto = Python + OpenSSL + SWIG
-------------------------------------
+----------------------------------
M2Crypto is a crypto and SSL toolkit for Python.
@@ -18,7 +20,7 @@ M2Crypto comes with the following:
- **RSA**, **DSA**, **DH**, **HMACs**, **message digests**,
**symmetric ciphers** including **AES**,
-- **SSL** functionality to implement **clients and servers**.
+- **TLS** functionality to implement **clients and servers**.
- **Example SSL client and server programs**, which are variously
**threading**, **forking** or based on **non-blocking socket IO**.
@@ -35,9 +37,15 @@ M2Crypto comes with the following:
- **ZSmime**: An S/MIME messenger for **Zope**.
+We care a lot about stable API and all Python methods should be
+preserved, note however that ``m2.`` namespace is considered internal to
+the library and it doesn't have to be preserved. If however some change
+to it breaks your app, let us know and we will try to make things
+working for you.
+
- And much more.
-M2Crypto is released under a very liberal BSD-style licence. See
+M2Crypto is released under a very liberal MIT licence. See
LICENCE for details.
To install, see the file INSTALL.
@@ -52,10 +60,12 @@ Note these caveats:
Python side and other objects on the C side, and these may change
between OpenSSL versions. (Multiple free's lead to crashes very
quickly, so these should be relatively rare.)
-
+
- No memory locking/clearing for keys, passphrases, etc. because AFAIK
Python does not provide the features needed. On the C (OpenSSL) side
things are cleared when the Python objects are deleted.
-
Have fun! Your feedback is welcome.
+
+.. _`#m2crypto`:
+ irc://Freenode/#m2crypto
diff --git a/SWIG/Makefile b/SWIG/Makefile
index 7d73a3b..9a3bd56 100644
--- a/SWIG/Makefile
+++ b/SWIG/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile 299 2005-06-09 17:32:28Z heikki $
+# $Id$
CFLAGS = -DTHREADING -g
INCLUDE = -I/usr/local/include -I.
@@ -17,8 +17,8 @@ all: _m2crypto
_m2crypto: _m2crypto.i
swig -python -shadow _m2crypto.i
cc -c -fpic $(CFLAGS) $(INCLUDE) $(PYINCLUDE) _m2crypto_wrap.c
- ld -Bshareable -o __m2crypto.so _m2crypto_wrap.o $(LIBS)
- cp _m2crypto.py __m2crypto.so ../M2Crypto
+ ld -Bshareable -o _m2crypto.so _m2crypto_wrap.o $(LIBS)
+ cp m2crypto.py _m2crypto.so ../M2Crypto
clean:
rm -f *_wrap* *.o *.so _*.py *.pyc
diff --git a/SWIG/Makefile.mw b/SWIG/Makefile.mw
deleted file mode 100644
index 02f5ae5..0000000
--- a/SWIG/Makefile.mw
+++ /dev/null
@@ -1,34 +0,0 @@
-# $Id: Makefile.mw 299 2005-06-09 17:32:28Z heikki $
-
-# Python
-PYFLAGS=-D__WIN32__ -DHAVE_CONFIG_H -Ic:/pkg/py23/include
-PYLIB=c:/pkg/py23/libs/libpython23.a
-PYINCLUDE=-Ic:/pkg/py23/include
-
-# OpenSSL
-SSLINCLUDE=-Ic:/pkg/openssl/include
-SSLLIB=c:/pkg/openssl/lib/libssl32.a c:/pkg/openssl/lib/libeay32.a
-
-# Windoze
-INCLUDE=$(PYINCLUDE) $(SSLINCLUDE) -I.
-LIBS=$(PYLIB) $(SSLLIB)
-
-SWIG=c:/pkg/swig/swig.exe
-SWIGFLAGS=-shadow -python #-verbose
-
-CP=cp
-
-all: swig
-
-swig: _m2crypto.i
- $(SWIG) $(SWIGFLAGS) _m2crypto.i
- gcc -c -DTHREADING -g $(INCLUDE) _m2crypto_wrap.c
- dllwrap --dllname __m2crypto.pyd --driver-name gcc \
- --def _m2crypto.def -o __m2crypto.pyd _m2crypto_wrap.o \
- -s --entry _DllMain@12 --target=i386-mingw32 $(LIBS)
- $(CP) _m2crypto.py ..\M2Crypto
- $(CP) __m2crypto.pyd ..\M2Crypto
-
-clean:
- del *wrap* *.o *.dll *.exp *.ilk *.pdb *.lib _*.py *.pyc
-
diff --git a/SWIG/Makefile.osx b/SWIG/Makefile.osx
deleted file mode 100644
index a8508a6..0000000
--- a/SWIG/Makefile.osx
+++ /dev/null
@@ -1,32 +0,0 @@
-# $Id: Makefile.osx 299 2005-06-09 17:32:28Z heikki $
-
-# 2003-10-26, ngps: Beware any mixup of tabs and spaces caused by me.
-
-WHICHOPENSSL = /usr/local
-
-CFLAGS = -DTHREADING -DHAVE_CONFIG -g -O2
-INCLUDE = -I. -I/Library/Frameworks/Python.framework/Headers
-LIBS = $(WHICHOPENSSL)/lib/libssl.a \
- $(WHICHOPENSSL)/lib/libcrypto.a \
- /Library/Frameworks/Python.framework/python
-
-all: __m2crypto.so
-
-_m2crypto_wrap.c: _m2crypto.i
- swig -shadow -python _m2crypto.i
-
-_m2crypto_wrap.o: _m2crypto_wrap.c
- cc -c $(CFLAGS) $(INCLUDES) _m2crypto_wrap.c
-
-__m2crypto.so: _m2crypto_wrap.o
- cc -bundle _m2crypto_wrap.o $(LIBS) -lcc_dynamic -o __m2crypto.so
- cp __m2crypto.so ../M2Crypto
-
-clean:
- rm -f *_wrap* *.o *.so _*.py *.pyc
-
-versions:
- python -c "import sys, os; \
- print os.popen('gcc --version').readlines()[0],; \
- print 'Python '+sys.version.split()[0]; \
- print os.popen('$(WHICHOPENSSL)/bin/openssl version').readlines()[0]"
diff --git a/SWIG/_aes.i b/SWIG/_aes.i
index be0af87..ea36167 100644
--- a/SWIG/_aes.i
+++ b/SWIG/_aes.i
@@ -1,5 +1,5 @@
/* Copyright (c) 1999-2004 Ng Pheng Siong. All rights reserved. */
-/* $Id: _aes.i 721 2010-02-13 06:30:33Z heikki $ */
+/* $Id$ */
%{
#include <openssl/evp.h>
@@ -28,8 +28,11 @@ extern EVP_CIPHER const *EVP_aes_256_ctr(void);
AES_KEY *aes_new(void) {
AES_KEY *key;
- if (!(key = (AES_KEY *)PyMem_Malloc(sizeof(AES_KEY))))
- PyErr_SetString(PyExc_MemoryError, "aes_new");
+ if (!(key = (AES_KEY *)PyMem_Malloc(sizeof(AES_KEY)))) {
+ PyErr_SetString(PyExc_MemoryError,
+ "Insufficient memory for AES key.");
+ return NULL;
+ }
return key;
}
@@ -38,34 +41,34 @@ void AES_free(AES_KEY *key) {
}
/*
-// op == 0: decrypt
-// otherwise: encrypt (Python code will supply the value 1.)
+// op == 0: encrypt
+// otherwise: decrypt (Python code will supply the value 1.)
*/
PyObject *AES_set_key(AES_KEY *key, PyObject *value, int bits, int op) {
- const void *vbuf;
+ char *vbuf;
Py_ssize_t vlen;
- if (PyObject_AsReadBuffer(value, &vbuf, &vlen) == -1)
+ if (PyBytes_AsStringAndSize(value, &vbuf, &vlen) == -1)
return NULL;
if (op == 0)
- AES_set_encrypt_key(vbuf, bits, key);
+ AES_set_encrypt_key((const unsigned char *)vbuf, bits, key);
else
- AES_set_decrypt_key(vbuf, bits, key);
- Py_INCREF(Py_None);
- return Py_None;
+ AES_set_decrypt_key((const unsigned char *)vbuf, bits, key);
+ Py_RETURN_NONE;
}
/*
-// op == 0: decrypt
-// otherwise: encrypt (Python code will supply the value 1.)
+// op == 0: encrypt
+// otherwise: decrypt (Python code will supply the value 1.)
*/
PyObject *AES_crypt(const AES_KEY *key, PyObject *in, int outlen, int op) {
- const void *buf;
+ char *buf;
Py_ssize_t len;
unsigned char *out;
+ PyObject *res;
- if (PyObject_AsReadBuffer(in, &buf, &len) == -1)
+ if (PyBytes_AsStringAndSize(in, &buf, &len) == -1)
return NULL;
if (!(out=(unsigned char *)PyMem_Malloc(outlen))) {
@@ -73,10 +76,12 @@ PyObject *AES_crypt(const AES_KEY *key, PyObject *in, int outlen, int op) {
return NULL;
}
if (op == 0)
- AES_encrypt((const unsigned char *)in, out, key);
+ AES_encrypt((const unsigned char *)buf, out, key);
else
- AES_decrypt((const unsigned char *)in, out, key);
- return PyString_FromStringAndSize((char*)out, outlen);
+ AES_decrypt((const unsigned char *)buf, out, key);
+ res = PyBytes_FromStringAndSize((char*)out, outlen);
+ PyMem_Free(out);
+ return res;
}
int AES_type_check(AES_KEY *key) {
diff --git a/SWIG/_asn1.i b/SWIG/_asn1.i
index 6dab7ff..b51b33f 100644
--- a/SWIG/_asn1.i
+++ b/SWIG/_asn1.i
@@ -4,7 +4,7 @@
** Portions created by Open Source Applications Foundation (OSAF) are
** Copyright (C) 2004 OSAF. All Rights Reserved.
*/
-/* $Id: _asn1.i 696 2009-07-28 03:43:19Z heikki $ */
+/* $Id$ */
%{
#include <openssl/asn1.h>
@@ -14,7 +14,7 @@
%apply Pointer NONNULL { ASN1_OBJECT * };
%apply Pointer NONNULL { ASN1_STRING * };
%apply Pointer NONNULL { ASN1_INTEGER * };
-%apply Pointer NONNULL { ASN1_UTCTIME * };
+%apply Pointer NONNULL { ASN1_TIME * };
%rename(asn1_object_new) ASN1_OBJECT_new;
extern ASN1_OBJECT *ASN1_OBJECT_new( void );
@@ -24,10 +24,8 @@ extern ASN1_OBJECT *ASN1_OBJECT_create( int, unsigned char *, int, const char *,
extern void ASN1_OBJECT_free( ASN1_OBJECT *);
%rename(i2d_asn1_object) i2d_ASN1_OBJECT;
extern int i2d_ASN1_OBJECT( ASN1_OBJECT *, unsigned char **);
-%rename(c2i_asn1_object) c2i_ASN1_OBJECT;
-extern ASN1_OBJECT *c2i_ASN1_OBJECT( ASN1_OBJECT **, CONST098 unsigned char **, long);
%rename(d2i_asn1_object) d2i_ASN1_OBJECT;
-extern ASN1_OBJECT *d2i_ASN1_OBJECT( ASN1_OBJECT **, CONST098 unsigned char **, long);
+extern ASN1_OBJECT *d2i_ASN1_OBJECT( ASN1_OBJECT **, const unsigned char **, long);
%rename(asn1_bit_string_new) ASN1_BIT_STRING_new;
extern ASN1_BIT_STRING *ASN1_BIT_STRING_new( void );
@@ -37,18 +35,20 @@ extern ASN1_STRING *ASN1_STRING_new( void );
%rename(asn1_string_free) ASN1_STRING_free;
extern void ASN1_STRING_free( ASN1_STRING *);
-%typemap(in) (const void *, int) {
- if (PyString_Check($input)) {
+%typemap(in) (const void *, int) {
+ if (PyBytes_Check($input)) {
Py_ssize_t len;
- $1 = PyString_AsString($input);
- len = PyString_Size($input);
+ $1 = PyBytes_AsString($input);
+ len = PyBytes_Size($input);
+
if (len > INT_MAX) {
PyErr_SetString(PyExc_ValueError, "object too large");
return NULL;
}
$2 = len;
- } else {
+ }
+ else {
PyErr_SetString(PyExc_TypeError, "expected string");
return NULL;
}
@@ -66,19 +66,19 @@ extern int ASN1_STRING_print(BIO *, ASN1_STRING *);
%rename(asn1_string_print_ex) ASN1_STRING_print_ex;
extern int ASN1_STRING_print_ex(BIO *, ASN1_STRING *, unsigned long);
-%rename(asn1_utctime_new) ASN1_UTCTIME_new;
-extern ASN1_UTCTIME *ASN1_UTCTIME_new( void );
-%rename(asn1_utctime_free) ASN1_UTCTIME_free;
-extern void ASN1_UTCTIME_free(ASN1_UTCTIME *);
-%rename(asn1_utctime_check) ASN1_UTCTIME_check;
-extern int ASN1_UTCTIME_check(ASN1_UTCTIME *);
-%rename(asn1_utctime_set) ASN1_UTCTIME_set;
-extern ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *, long);
-%rename(asn1_utctime_set_string) ASN1_UTCTIME_set_string;
-extern int ASN1_UTCTIME_set_string(ASN1_UTCTIME *, CONST098 char *);
-%rename(asn1_utctime_print) ASN1_UTCTIME_print;
-%threadallow ASN1_UTCTIME_print;
-extern int ASN1_UTCTIME_print(BIO *, ASN1_UTCTIME *);
+%rename(asn1_time_new) ASN1_TIME_new;
+extern ASN1_TIME *ASN1_TIME_new( void );
+%rename(asn1_time_free) ASN1_TIME_free;
+extern void ASN1_TIME_free(ASN1_TIME *);
+%rename(asn1_time_check) ASN1_TIME_check;
+extern int ASN1_TIME_check(ASN1_TIME *);
+%rename(asn1_time_set) ASN1_TIME_set;
+extern ASN1_TIME *ASN1_TIME_set(ASN1_TIME *, long);
+%rename(asn1_time_set_string) ASN1_TIME_set_string;
+extern int ASN1_TIME_set_string(ASN1_TIME *, const char *);
+%rename(asn1_time_print) ASN1_TIME_print;
+%threadallow ASN1_TIME_print;
+extern int ASN1_TIME_print(BIO *, ASN1_TIME *);
%rename(asn1_integer_new) ASN1_INTEGER_new;
extern ASN1_INTEGER *ASN1_INTEGER_new( void );
@@ -92,8 +92,12 @@ extern int ASN1_INTEGER_cmp(ASN1_INTEGER *, ASN1_INTEGER *);
%constant int ASN1_STRFLGS_ESC_MSB = 4;
%constant int ASN1_STRFLGS_ESC_QUOTE = 8;
%constant int ASN1_STRFLGS_UTF8_CONVERT = 0x10;
+%constant int ASN1_STRFLGS_IGNORE_TYPE = 0x20;
+%constant int ASN1_STRFLGS_SHOW_TYPE = 0x40;
+%constant int ASN1_STRFLGS_DUMP_ALL = 0x80;
%constant int ASN1_STRFLGS_DUMP_UNKNOWN = 0x100;
%constant int ASN1_STRFLGS_DUMP_DER = 0x200;
+
%constant int ASN1_STRFLGS_RFC2253 = (ASN1_STRFLGS_ESC_2253 | \
ASN1_STRFLGS_ESC_CTRL | \
ASN1_STRFLGS_ESC_MSB | \
@@ -102,8 +106,8 @@ extern int ASN1_INTEGER_cmp(ASN1_INTEGER *, ASN1_INTEGER *);
ASN1_STRFLGS_DUMP_DER);
%inline %{
-/* ASN1_UTCTIME_set_string () is a macro */
-int asn1_utctime_type_check(ASN1_UTCTIME *ASN1_UTCTIME) {
+/* ASN1_TIME_set_string () is a macro */
+int asn1_time_type_check(ASN1_TIME *ASN1_TIME) {
return 1;
}
@@ -115,16 +119,14 @@ PyObject *asn1_integer_get(ASN1_INTEGER *asn1) {
bn = ASN1_INTEGER_to_BN(asn1, NULL);
if (!bn){
- PyErr_SetString(
- PyExc_RuntimeError, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(PyExc_RuntimeError);
return NULL;
}
hex = BN_bn2hex(bn);
if (!hex){
- PyErr_SetString(
- PyExc_RuntimeError, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(PyExc_RuntimeError);
BN_free(bn);
return NULL;
}
@@ -142,15 +144,23 @@ int asn1_integer_set(ASN1_INTEGER *asn1, PyObject *value) {
BIGNUM *bn = NULL;
PyObject *fmt, *args, *hex;
- if (PyInt_Check(value))
- return ASN1_INTEGER_set(asn1, PyInt_AS_LONG(value));
+/* Despite all hopes to the contrary, we cannot survive here with
+ * PyLong_AsLong shims as provided in
+ * /usr/include/python2.7/longobject.h.
+ */
+ long val = PyLong_AsLong(value);
+ if (val >= 0) {
+ return ASN1_INTEGER_set(asn1, val);
+ } else {
+ PyErr_Clear();
+ }
if (!PyLong_Check(value)){
PyErr_SetString(PyExc_TypeError, "expected int or long");
return 0;
}
- fmt = PyString_FromString("%x");
+ fmt = PyUnicode_FromString("%x");
if (!fmt)
return 0;
@@ -165,7 +175,7 @@ int asn1_integer_set(ASN1_INTEGER *asn1, PyObject *value) {
Py_INCREF(value);
PyTuple_SET_ITEM(args, 0, value);
- hex = PyString_Format(fmt, args);
+ hex = PyUnicode_Format(fmt, args);
if (!hex){
PyErr_SetString(PyExc_RuntimeError, "PyString_Format() failed");
@@ -177,9 +187,8 @@ int asn1_integer_set(ASN1_INTEGER *asn1, PyObject *value) {
Py_DECREF(fmt);
Py_DECREF(args);
- if (BN_hex2bn(&bn, PyString_AsString(hex)) <= 0){
- PyErr_SetString(
- PyExc_RuntimeError, ERR_reason_error_string(ERR_get_error()));
+ if (BN_hex2bn(&bn, PyUnicode_AsUTF8(hex)) <= 0){
+ m2_PyErr_Msg(PyExc_RuntimeError);
Py_DECREF(hex);
return 0;
}
@@ -187,9 +196,8 @@ int asn1_integer_set(ASN1_INTEGER *asn1, PyObject *value) {
Py_DECREF(hex);
if (!BN_to_ASN1_INTEGER(bn, asn1)){
- PyErr_SetString(
- PyExc_RuntimeError, ERR_reason_error_string(ERR_get_error()));
- BN_free(bn);
+ m2_PyErr_Msg(PyExc_RuntimeError);
+ BN_free(bn);
return 0;
}
diff --git a/SWIG/_bio.i b/SWIG/_bio.i
index 441ba06..e85a275 100644
--- a/SWIG/_bio.i
+++ b/SWIG/_bio.i
@@ -4,8 +4,9 @@
* Portions created by Open Source Applications Foundation (OSAF) are
* Copyright (C) 2004-2005 OSAF. All Rights Reserved.
* Author: Heikki Toivonen
-*/
-/* $Id: _bio.i 695 2009-07-24 06:37:01Z heikki $ */
+ *
+ * Copyright 2018 Daniel Wozniak. All Rights Reserved.*/
+/* $Id$ */
%{
#include <openssl/bio.h>
@@ -31,15 +32,8 @@ extern BIO_METHOD *BIO_f_cipher(void);
extern BIO *BIO_new(BIO_METHOD *);
%rename(bio_new_socket) BIO_new_socket;
extern BIO *BIO_new_socket(int, int);
-%rename(bio_new_fd) BIO_new_fd;
-extern BIO *BIO_new_fd(int, int);
-%rename(bio_new_fp) BIO_new_fp;
-extern BIO *BIO_new_fp(FILE *, int);
-%rename(bio_new_file) BIO_new_file;
-extern BIO *BIO_new_file(const char *, const char *);
-%rename(bio_free) BIO_free;
-%threadallow BIO_free;
-extern int BIO_free(BIO *);
+%rename(bio_new_fd) BIO_new_pyfd;
+%rename(bio_new_pyfd) BIO_new_pyfd;
%rename(bio_free_all) BIO_free_all;
%threadallow BIO_free_all;
extern void BIO_free_all(BIO *);
@@ -51,6 +45,9 @@ extern BIO *BIO_push(BIO *, BIO *);
%rename(bio_pop) BIO_pop;
extern BIO *BIO_pop(BIO *);
+%rename(bio_eof) BIO_eof;
+extern int BIO_eof(BIO *);
+
%constant int bio_noclose = BIO_NOCLOSE;
%constant int bio_close = BIO_CLOSE;
%constant int BIO_FLAGS_READ = 0x01;
@@ -60,12 +57,71 @@ extern BIO *BIO_pop(BIO *);
%constant int BIO_FLAGS_SHOULD_RETRY = 0x08;
%constant int BIO_FLAGS_MEM_RDONLY = 0x200;
+%warnfilter(454) _bio_err;
%inline %{
static PyObject *_bio_err;
+
+void pyfd_init(void);
+
void bio_init(PyObject *bio_err) {
Py_INCREF(bio_err);
_bio_err = bio_err;
+ pyfd_init();
+}
+
+int bio_free(BIO *bio) {
+ int ret;
+
+ Py_BEGIN_ALLOW_THREADS
+ ret = BIO_free(bio);
+ Py_END_ALLOW_THREADS
+ if (ret == 0) {
+ m2_PyErr_Msg(_bio_err);
+ }
+ return ret;
+}
+
+BIO * bio_new_file(const char *filename, const char *mode) {
+ BIO *ret;
+
+ Py_BEGIN_ALLOW_THREADS
+ ret = BIO_new_file(filename, mode);
+ Py_END_ALLOW_THREADS
+
+ if (ret == NULL) {
+ m2_PyErr_Msg(_bio_err);
+ }
+
+ return ret;
+}
+
+BIO *bio_new_pyfile(PyObject *pyfile, int bio_close) {
+ FILE *fp = NULL;
+ BIO *bio = NULL;
+
+ fp = PyFile_AsFile(pyfile);
+
+ bio = BIO_new_fp(fp, bio_close);
+
+ /* returns NULL if error occurred */
+ if (bio == NULL) {
+ /* Find out the name of the file so we can have good error
+ * message. */
+ PyObject *pyname = m2_PyFile_Name(pyfile);
+ char *name = PyBytes_AsString(pyname);
+
+ if (name == NULL) {
+ PyErr_Format(_bio_err,
+ "Opening of the new BIO on file failed!");
+ }
+ else {
+ PyErr_Format(_bio_err,
+ "Opening of the new BIO on file %s failed!", name);
+ }
+ Py_DECREF(pyname);
+ }
+ return bio;
}
PyObject *bio_read(BIO *bio, int num) {
@@ -83,13 +139,14 @@ PyObject *bio_read(BIO *bio, int num) {
if (r < 0) {
PyMem_Free(buf);
if (ERR_peek_error()) {
- PyErr_SetString(_bio_err, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(_bio_err);
return NULL;
}
- Py_INCREF(Py_None);
- return Py_None;
+ Py_RETURN_NONE;
}
- blob = PyString_FromStringAndSize(buf, r);
+
+ blob = PyBytes_FromStringAndSize(buf, r);
+
PyMem_Free(buf);
return blob;
}
@@ -106,23 +163,24 @@ PyObject *bio_gets(BIO *bio, int num) {
Py_BEGIN_ALLOW_THREADS
r = BIO_gets(bio, buf, num);
Py_END_ALLOW_THREADS
- if (r < 0) {
+ if (r < 1) {
PyMem_Free(buf);
if (ERR_peek_error()) {
- PyErr_SetString(_bio_err, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(_bio_err);
return NULL;
}
- Py_INCREF(Py_None);
- return Py_None;
+ Py_RETURN_NONE;
}
- blob = PyString_FromStringAndSize(buf, r);
+
+ blob = PyBytes_FromStringAndSize(buf, r);
+
PyMem_Free(buf);
return blob;
}
int bio_write(BIO *bio, PyObject *from) {
const void *fbuf;
- int flen, ret;
+ int flen = 0, ret;
if (m2_PyObject_AsReadBufferInt(from, &fbuf, &flen) == -1)
return -1;
@@ -132,7 +190,8 @@ int bio_write(BIO *bio, PyObject *from) {
Py_END_ALLOW_THREADS
if (ret < 0) {
if (ERR_peek_error()) {
- PyErr_SetString(_bio_err, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(_bio_err);
+ return -1;
}
}
return ret;
@@ -166,6 +225,10 @@ int bio_seek(BIO *bio, int offset) {
return (int)BIO_seek(bio, offset);
}
+int bio_tell(BIO* bio) {
+ return BIO_tell(bio);
+}
+
void bio_set_flags(BIO *bio, int flags) {
BIO_set_flags(bio, flags);
}
@@ -174,6 +237,11 @@ int bio_get_flags(BIO *bio) {
return BIO_get_flags(bio);
}
+/*
+ * sets the cipher of BIO @param b to c using key @param key and IV @iv.
+ * @param enc should be set to 1 for encryption and zero to decryption.
+ *
+ */
PyObject *bio_set_cipher(BIO *b, EVP_CIPHER *c, PyObject *key, PyObject *iv, int op) {
const void *kbuf, *ibuf;
Py_ssize_t klen, ilen;
@@ -184,8 +252,7 @@ PyObject *bio_set_cipher(BIO *b, EVP_CIPHER *c, PyObject *key, PyObject *iv, int
BIO_set_cipher(b, (const EVP_CIPHER *)c,
(unsigned char *)kbuf, (unsigned char *)ibuf, op);
- Py_INCREF(Py_None);
- return Py_None;
+ Py_RETURN_NONE;
}
int bio_set_mem_eof_return(BIO *b, int v) {
@@ -197,6 +264,7 @@ int bio_get_fd(BIO *bio) {
}
%}
+%warnfilter(454) methods_fdp;
%threadallow bio_do_handshake;
%inline %{
int bio_do_handshake(BIO *bio) {
@@ -223,5 +291,255 @@ int bio_should_read(BIO* a) {
int bio_should_write(BIO* a) {
return BIO_should_write(a);
}
+
+/* Macros for things not defined before 1.1.0 */
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+static BIO_METHOD *
+BIO_meth_new( int type, const char *name )
+{
+ BIO_METHOD *method = malloc( sizeof(BIO_METHOD) );
+ memset( method, 0, sizeof(BIO_METHOD) );
+
+ method->type = type;
+ method->name = name;
+
+ return method;
+}
+
+static void
+BIO_meth_free( BIO_METHOD *meth )
+{
+ if ( meth == NULL ) {
+ return;
+ }
+
+ free(meth);
+}
+#define BIO_meth_set_write(m, f) (m)->bwrite = (f)
+#define BIO_meth_set_read(m, f) (m)->bread = (f)
+#define BIO_meth_set_puts(m, f) (m)->bputs = (f)
+#define BIO_meth_set_gets(m, f) (m)->bgets = (f)
+#define BIO_meth_set_ctrl(m, f) (m)->ctrl = (f)
+#define BIO_meth_set_create(m, f) (m)->create = (f)
+#define BIO_meth_set_destroy(m, f) (m)->destroy = (f)
+#define BIO_set_shutdown(b, x) (b)->shutdown = x
+#define BIO_get_shutdown(b) (b)->shutdown
+#define BIO_set_init(b, x) b->init = x
+#define BIO_get_init(b) (b)->init
+#define BIO_set_data(b, x) b->ptr = x
+#define BIO_clear_flags(b, x) b->flags &= ~(x)
+#define BIO_get_data(b) b->ptr
+#endif
+
+/* implment custom BIO_s_pyfd */
+
+#ifdef _WIN32
+# define clear_sys_error() SetLastError(0)
+/* Linux doesn't use underscored calls yet */
+# define open(p, f, m) _open(p, f, m)
+# define read(f, b, n) _read(f, b, n)
+# define write(f, b, n) _write(f, b, n)
+# define close(f) _close(f)
+# define lseek(fd, o, w) _lseek(fd, o, w)
+#else
+# define clear_sys_error() errno=0
+#endif
+
+typedef struct pyfd_struct {
+ int fd;
+} BIO_PYFD_CTX;
+
+/* Setting up methods_fdp */
+static BIO_METHOD *methods_fdp;
+
+static int pyfd_write(BIO *b, const char *in, int inl) {
+ int ret, fd;
+
+ if (BIO_get_fd(b, &fd) == -1) {
+ PyErr_SetString(_bio_err, "BIO has not been initialized.");
+ return -1;
+ }
+ clear_sys_error();
+ ret = write(fd, in, inl);
+ BIO_clear_retry_flags(b);
+ if (ret <= 0) {
+ if (BIO_fd_should_retry(ret))
+ BIO_set_retry_write(b);
+ }
+ return ret;
+}
+
+static int pyfd_read(BIO *b, char *out, int outl) {
+ int ret = 0, fd;
+
+ if (BIO_get_fd(b, &fd) == -1) {
+ PyErr_SetString(_bio_err, "BIO has not been initialized.");
+ return -1;
+ }
+ if (out != NULL) {
+ clear_sys_error();
+ ret = read(fd, out, outl);
+ BIO_clear_retry_flags(b);
+ if (ret <= 0) {
+ if (BIO_fd_should_retry(ret))
+ BIO_set_retry_read(b);
+ }
+ }
+ return ret;
+}
+
+static int pyfd_puts(BIO *bp, const char *str) {
+ int n, ret;
+
+ n = strlen(str);
+ ret = pyfd_write(bp, str, n);
+ return ret;
+}
+
+static int pyfd_gets(BIO *bp, char *buf, int size) {
+ int ret = 0;
+ char *ptr = buf;
+ char *end = buf + size - 1;
+
+ /* See
+ https://github.com/openssl/openssl/pull/3442
+ We were here just repeating a bug from OpenSSL
+ */
+ while (ptr < end && pyfd_read(bp, ptr, 1) > 0) {
+ if (*ptr++ == '\n')
+ break;
+ }
+
+ ptr[0] = '\0';
+
+ if (buf[0] != '\0')
+ ret = strlen(buf);
+ return ret;
+}
+
+static int pyfd_new(BIO* b) {
+ BIO_PYFD_CTX* ctx;
+
+ ctx = OPENSSL_zalloc(sizeof(*ctx));
+ if (ctx == NULL)
+ return 0;
+
+ ctx->fd = -1;
+
+ BIO_set_data(b, ctx);
+ BIO_set_shutdown(b, 0);
+ BIO_set_init(b, 1);
+
+ return 1;
+ }
+
+static int pyfd_free(BIO* b) {
+ BIO_PYFD_CTX* ctx;
+
+ if (b == 0)
+ return 0;
+
+ ctx = BIO_get_data(b);
+ if (ctx == NULL)
+ return 0;
+
+ if (BIO_get_shutdown(b) && BIO_get_init(b))
+ close(ctx->fd);
+
+ BIO_set_data(b, NULL);
+ BIO_set_shutdown(b, 0);
+ BIO_set_init(b, 0);
+
+ OPENSSL_free(ctx);
+
+ return 1;
+}
+
+static long pyfd_ctrl(BIO *b, int cmd, long num, void *ptr) {
+ BIO_PYFD_CTX* ctx;
+ int *ip;
+ long ret = 1;
+
+ ctx = BIO_get_data(b);
+ if (ctx == NULL)
+ return 0;
+
+ switch (cmd) {
+ case BIO_CTRL_RESET:
+ num = 0;
+ case BIO_C_FILE_SEEK:
+ ret = (long)lseek(ctx->fd, num, 0);
+ break;
+ case BIO_C_FILE_TELL:
+ case BIO_CTRL_INFO:
+ ret = (long)lseek(ctx->fd, 0, 1);
+ break;
+ case BIO_C_SET_FD:
+ pyfd_free(b);
+ if (*((int *)ptr) > -1) {
+ if (!pyfd_new(b) || !(ctx = BIO_get_data(b)))
+ return 0;
+ ctx->fd = *((int *)ptr);
+ BIO_set_shutdown(b, (int)num);
+ BIO_set_init(b, 1);
+ }
+ break;
+ case BIO_C_GET_FD:
+ if (BIO_get_init(b)) {
+ ip = (int *)ptr;
+ if (ip != NULL)
+ *ip = ctx->fd;
+ ret = ctx->fd;
+ } else
+ ret = -1;
+ break;
+ case BIO_CTRL_GET_CLOSE:
+ ret = BIO_get_shutdown(b);
+ break;
+ case BIO_CTRL_SET_CLOSE:
+ BIO_set_shutdown(b, (int)num);
+ break;
+ case BIO_CTRL_PENDING:
+ case BIO_CTRL_WPENDING:
+ ret = 0;
+ break;
+ case BIO_CTRL_DUP:
+ case BIO_CTRL_FLUSH:
+ ret = 1;
+ break;
+ default:
+ ret = 0;
+ break;
+ }
+ return ret;
+}
+
+void pyfd_init(void) {
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ methods_fdp = BIO_meth_new(
+ BIO_get_new_index()|BIO_TYPE_DESCRIPTOR|BIO_TYPE_SOURCE_SINK,
+ "python file descriptor");
+#else
+ methods_fdp = BIO_meth_new(
+ 100 |BIO_TYPE_DESCRIPTOR|BIO_TYPE_SOURCE_SINK,
+ "python file descriptor");
+#endif
+
+ BIO_meth_set_write(methods_fdp, pyfd_write);
+ BIO_meth_set_read(methods_fdp, pyfd_read);
+ BIO_meth_set_puts(methods_fdp, pyfd_puts);
+ BIO_meth_set_gets(methods_fdp, pyfd_gets);
+ BIO_meth_set_ctrl(methods_fdp, pyfd_ctrl);
+ BIO_meth_set_create(methods_fdp, pyfd_new);
+ BIO_meth_set_destroy(methods_fdp, pyfd_free);
+}
+
+BIO* BIO_new_pyfd(int fd, int close_flag) {
+ BIO *ret;
+
+ ret = BIO_new(methods_fdp);
+ BIO_set_fd(ret, fd, close_flag);
+ return ret;
+ }
%}
diff --git a/SWIG/_bn.i b/SWIG/_bn.i
index a3b73c4..18dc154 100755..100644
--- a/SWIG/_bn.i
+++ b/SWIG/_bn.i
@@ -17,27 +17,32 @@
%inline %{
PyObject *bn_rand(int bits, int top, int bottom)
{
- BIGNUM rnd;
+ BIGNUM* rnd;
PyObject *ret;
char *randhex;
-
- BN_init(&rnd);
- if (!BN_rand(&rnd, bits, top, bottom)) {
+
+ rnd = BN_new();
+ if (rnd == NULL) {
+ m2_PyErr_Msg(PyExc_Exception);
+ return NULL;
+ }
+
+ if (!BN_rand(rnd, bits, top, bottom)) {
/*Custom errors?*/
- PyErr_SetString(PyExc_Exception, ERR_reason_error_string(ERR_get_error()));
- BN_free(&rnd);
+ m2_PyErr_Msg(PyExc_Exception);
+ BN_free(rnd);
return NULL;
}
-
- randhex = BN_bn2hex(&rnd);
+
+ randhex = BN_bn2hex(rnd);
if (!randhex) {
/*Custom errors?*/
- PyErr_SetString(PyExc_Exception, ERR_reason_error_string(ERR_get_error()));
- BN_free(&rnd);
+ m2_PyErr_Msg(PyExc_Exception);
+ BN_free(rnd);
return NULL;
}
- BN_free(&rnd);
-
+ BN_free(rnd);
+
ret = PyLong_FromString(randhex, NULL, 16);
OPENSSL_free(randhex);
return ret;
@@ -46,15 +51,18 @@ PyObject *bn_rand(int bits, int top, int bottom)
PyObject *bn_rand_range(PyObject *range)
{
- BIGNUM rnd;
+ BIGNUM* rnd;
BIGNUM *rng = NULL;
PyObject *ret, *tuple;
PyObject *format, *rangePyString;
- char *randhex, *rangehex;
-
+ char *randhex; /* PyLong_FromString is unhappy with const */
+ const char *rangehex;
+
/* Wow, it's a lot of work to convert into a hex string in C! */
- format = PyString_FromString("%x");
+ format = PyUnicode_FromString("%x");
+
if (!format) {
+ PyErr_SetString(PyExc_RuntimeError, "Cannot create Python string '%x'");
return NULL;
}
tuple = PyTuple_New(1);
@@ -65,47 +73,53 @@ PyObject *bn_rand_range(PyObject *range)
}
Py_INCREF(range);
PyTuple_SET_ITEM(tuple, 0, range);
- rangePyString = PyString_Format(format, tuple);
+
+ rangePyString = PyUnicode_Format(format, tuple);
+
if (!rangePyString) {
- PyErr_SetString(PyExc_Exception, "PyString_Format failed");
+ PyErr_SetString(PyExc_Exception, "String Format failed");
Py_DECREF(format);
Py_DECREF(tuple);
- return NULL;
+ return NULL;
}
Py_DECREF(format);
Py_DECREF(tuple);
- rangehex = PyString_AsString(rangePyString);
-
+
+ rangehex = (const char*)PyUnicode_AsUTF8(rangePyString);
+
if (!BN_hex2bn(&rng, rangehex)) {
/*Custom errors?*/
- PyErr_SetString(PyExc_Exception, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(PyExc_Exception);
Py_DECREF(rangePyString);
- return NULL;
+ return NULL;
}
Py_DECREF(rangePyString);
-
- BN_init(&rnd);
- if (!BN_rand_range(&rnd, rng)) {
+ if (!(rnd = BN_new())) {
+ PyErr_SetString(PyExc_MemoryError, "bn_rand_range");
+ return NULL;
+ }
+
+ if (!BN_rand_range(rnd, rng)) {
/*Custom errors?*/
- PyErr_SetString(PyExc_Exception, ERR_reason_error_string(ERR_get_error()));
- BN_free(&rnd);
+ m2_PyErr_Msg(PyExc_Exception);
+ BN_free(rnd);
BN_free(rng);
- return NULL;
- }
+ return NULL;
+ }
BN_free(rng);
- randhex = BN_bn2hex(&rnd);
+ randhex = BN_bn2hex(rnd);
if (!randhex) {
/*Custom errors?*/
- PyErr_SetString(PyExc_Exception, ERR_reason_error_string(ERR_get_error()));
- BN_free(&rnd);
+ m2_PyErr_Msg(PyExc_Exception);
+ BN_free(rnd);
return NULL;
}
- BN_free(&rnd);
-
+ BN_free(rnd);
+
ret = PyLong_FromString(randhex, NULL, 16);
OPENSSL_free(randhex);
return ret;
diff --git a/SWIG/_dh.i b/SWIG/_dh.i
index 675b39f..398f418 100644
--- a/SWIG/_dh.i
+++ b/SWIG/_dh.i
@@ -1,5 +1,5 @@
/* Copyright (c) 1999 Ng Pheng Siong. All rights reserved. */
-/* $Id: _dh.i 695 2009-07-24 06:37:01Z heikki $ */
+/* $Id$ */
%{
#include <openssl/bn.h>
@@ -32,6 +32,7 @@ extern int DHparams_print(BIO *, const DH *);
%constant DH_GENERATOR_2 = 2;
%constant DH_GENERATOR_5 = 5;
+%warnfilter(454) _dh_err;
%inline %{
static PyObject *_dh_err;
@@ -53,26 +54,35 @@ DH *dh_read_parameters(BIO *bio) {
return PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
}
-void gendh_callback(int p, int n, void *arg) {
- PyObject *argv, *ret, *cbfunc;
-
- cbfunc = (PyObject *)arg;
- argv = Py_BuildValue("(ii)", p, n);
- ret = PyEval_CallObject(cbfunc, argv);
- PyErr_Clear();
- Py_DECREF(argv);
- Py_XDECREF(ret);
-}
-
DH *dh_generate_parameters(int plen, int g, PyObject *pyfunc) {
DH *dh;
+ BN_GENCB *gencb;
+ int ret;
+
+ if ((gencb=BN_GENCB_new()) == NULL) {
+ m2_PyErr_Msg(_dh_err);
+ return NULL;
+ }
+
+ if ((dh=DH_new()) == NULL) {
+ m2_PyErr_Msg(_dh_err);
+ BN_GENCB_free(gencb);
+ return NULL;
+ }
+
+ BN_GENCB_set(gencb, bn_gencb_callback, (void *)pyfunc);
Py_INCREF(pyfunc);
- dh = DH_generate_parameters(plen, g, gendh_callback, (void *)pyfunc);
+ ret = DH_generate_parameters_ex(dh, plen, g, gencb);
Py_DECREF(pyfunc);
- if (!dh)
- PyErr_SetString(_dh_err, ERR_reason_error_string(ERR_get_error()));
- return dh;
+ BN_GENCB_free(gencb);
+
+ if (ret)
+ return dh;
+
+ m2_PyErr_Msg(_dh_err);
+ DH_free(dh);
+ return NULL;
}
/* Note return value shenanigan. */
@@ -84,7 +94,7 @@ int dh_check(DH *dh) {
PyObject *dh_compute_key(DH *dh, PyObject *pubkey) {
const void *pkbuf;
- int pklen, klen;
+ int pklen = 0, klen;
void *key;
BIGNUM *pk;
PyObject *ret;
@@ -93,7 +103,7 @@ PyObject *dh_compute_key(DH *dh, PyObject *pubkey) {
return NULL;
if (!(pk = BN_mpi2bn((unsigned char *)pkbuf, pklen, NULL))) {
- PyErr_SetString(_dh_err, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(_dh_err);
return NULL;
}
if (!(key = PyMem_Malloc(DH_size(dh)))) {
@@ -104,83 +114,73 @@ PyObject *dh_compute_key(DH *dh, PyObject *pubkey) {
if ((klen = DH_compute_key((unsigned char *)key, pk, dh)) == -1) {
BN_free(pk);
PyMem_Free(key);
- PyErr_SetString(_dh_err, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(_dh_err);
return NULL;
}
- ret = PyString_FromStringAndSize((const char *)key, klen);
+
+ ret = PyBytes_FromStringAndSize((const char *)key, klen);
+
BN_free(pk);
PyMem_Free(key);
return ret;
}
-
+
PyObject *dh_get_p(DH *dh) {
- if (!dh->p) {
+ const BIGNUM* p = NULL;
+ DH_get0_pqg(dh, &p, NULL, NULL);
+ if (!p) {
PyErr_SetString(_dh_err, "'p' is unset");
return NULL;
}
- return bn_to_mpi(dh->p);
+ return bn_to_mpi(p);
}
PyObject *dh_get_g(DH *dh) {
- if (!dh->g) {
+ const BIGNUM* g = NULL;
+ DH_get0_pqg(dh, NULL, NULL, &g);
+ if (!g) {
PyErr_SetString(_dh_err, "'g' is unset");
return NULL;
}
- return bn_to_mpi(dh->g);
+ return bn_to_mpi(g);
}
PyObject *dh_get_pub(DH *dh) {
- if (!dh->pub_key) {
+ const BIGNUM* pub_key = NULL;
+ DH_get0_key(dh, &pub_key, NULL);
+ if (!pub_key) {
PyErr_SetString(_dh_err, "'pub' is unset");
return NULL;
}
- return bn_to_mpi(dh->pub_key);
+ return bn_to_mpi(pub_key);
}
PyObject *dh_get_priv(DH *dh) {
- if (!dh->priv_key) {
+ const BIGNUM* priv_key = NULL;
+ DH_get0_key(dh, NULL, &priv_key);
+ if (!priv_key) {
PyErr_SetString(_dh_err, "'priv' is unset");
return NULL;
}
- return bn_to_mpi(dh->priv_key);
+ return bn_to_mpi(priv_key);
}
-PyObject *dh_set_p(DH *dh, PyObject *value) {
- BIGNUM *bn;
- const void *vbuf;
- int vlen;
-
- if (m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
- return NULL;
+PyObject *dh_set_pg(DH *dh, PyObject *pval, PyObject* gval) {
+ BIGNUM* p, *g;
- if (!(bn = BN_mpi2bn((unsigned char *)vbuf, vlen, NULL))) {
- PyErr_SetString(_dh_err, ERR_reason_error_string(ERR_get_error()));
+ if (!(p = m2_PyObject_AsBIGNUM(pval, _dh_err))
+ || !(g = m2_PyObject_AsBIGNUM(gval, _dh_err)))
return NULL;
- }
- if (dh->p)
- BN_free(dh->p);
- dh->p = bn;
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-PyObject *dh_set_g(DH *dh, PyObject *value) {
- BIGNUM *bn;
- const void *vbuf;
- int vlen;
- if (m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
+ if (!DH_set0_pqg(dh, p, NULL, g)) {
+ PyErr_SetString(_dh_err,
+ "Cannot set prime number or generator of Z_p for DH.");
+ BN_free(p);
+ BN_free(g);
return NULL;
+ }
- if (!(bn = BN_mpi2bn((unsigned char *)vbuf, vlen, NULL))) {
- PyErr_SetString(_dh_err, ERR_reason_error_string(ERR_get_error()));
- return NULL;
- }
- if (dh->g)
- BN_free(dh->g);
- dh->g = bn;
- Py_INCREF(Py_None);
- return Py_None;
+ Py_RETURN_NONE;
}
%}
diff --git a/SWIG/_dsa.i b/SWIG/_dsa.i
index addf33a..2c15c4f 100644
--- a/SWIG/_dsa.i
+++ b/SWIG/_dsa.i
@@ -1,5 +1,5 @@
/* Copyright (c) 1999-2000 Ng Pheng Siong. All rights reserved. */
-/* $Id: _dsa.i 723 2010-02-13 06:53:13Z heikki $ */
+/* $Id$ */
%{
#include <openssl/bn.h>
@@ -8,11 +8,15 @@
#include <openssl/dsa.h>
PyObject *dsa_sig_get_r(DSA_SIG *dsa_sig) {
- return bn_to_mpi(dsa_sig->r);
+ const BIGNUM* pr;
+ DSA_SIG_get0(dsa_sig, &pr, NULL);
+ return bn_to_mpi(pr);
}
PyObject *dsa_sig_get_s(DSA_SIG *dsa_sig) {
- return bn_to_mpi(dsa_sig->s);
+ const BIGNUM* qs;
+ DSA_SIG_get0(dsa_sig, NULL, &qs);
+ return bn_to_mpi(qs);
}
%}
@@ -27,6 +31,7 @@ extern int DSA_size(const DSA *); /* assert(dsa->q); */
%rename(dsa_gen_key) DSA_generate_key;
extern int DSA_generate_key(DSA *);
+%warnfilter(454) _dsa_err;
%inline %{
static PyObject *_dsa_err;
@@ -34,137 +39,189 @@ void dsa_init(PyObject *dsa_err) {
Py_INCREF(dsa_err);
_dsa_err = dsa_err;
}
+%}
-void genparam_callback(int p, int n, void *arg) {
- PyObject *argv, *ret, *cbfunc;
+%typemap(out) DSA * {
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
- cbfunc = (PyObject *)arg;
- argv = Py_BuildValue("(ii)", p, n);
- ret = PyEval_CallObject(cbfunc, argv);
- PyErr_Clear();
- Py_DECREF(argv);
- Py_XDECREF(ret);
+ if ($1 != NULL)
+ $result = SWIG_NewPointerObj($1, $1_descriptor, 0);
+ else {
+ $result = NULL;
+ }
}
-
+%inline %{
DSA *dsa_generate_parameters(int bits, PyObject *pyfunc) {
DSA *dsa;
+ BN_GENCB *gencb;
+ int ret;
+
+ if ((gencb=BN_GENCB_new()) == NULL) {
+ m2_PyErr_Msg(_dh_err);
+ return NULL;
+ }
+
+ if ((dsa = DSA_new()) == NULL) {
+ m2_PyErr_Msg(_dsa_err);
+ BN_GENCB_free(gencb);
+ return NULL;
+ }
+
+ BN_GENCB_set(gencb, bn_gencb_callback, (void *) pyfunc);
+
+ Py_INCREF(pyfunc);
+ ret = DSA_generate_parameters_ex(dsa, bits, NULL, 0, NULL, NULL,
+ gencb);
+ Py_DECREF(pyfunc);
+ BN_GENCB_free(gencb);
+
+ if (ret)
+ return dsa;
+
+ m2_PyErr_Msg(_dsa_err);
+ DSA_free(dsa);
+ return NULL;
+}
+
+DSA *dsa_read_params(BIO *f, PyObject *pyfunc) {
+ DSA *ret;
+
+ Py_INCREF(pyfunc);
+ Py_BEGIN_ALLOW_THREADS
+ ret = PEM_read_bio_DSAparams(f, NULL, passphrase_callback, (void *)pyfunc);
+ Py_END_ALLOW_THREADS
+ Py_DECREF(pyfunc);
+
+ if (ret == NULL) {
+ m2_PyErr_Msg(_dsa_err);
+ }
+
+ return ret;
+}
+
+DSA *dsa_read_key(BIO *f, PyObject *pyfunc) {
+ DSA *ret;
+
+ Py_INCREF(pyfunc);
+ Py_BEGIN_ALLOW_THREADS
+ ret = PEM_read_bio_DSAPrivateKey(f, NULL, passphrase_callback, (void *)pyfunc);
+ Py_END_ALLOW_THREADS
+ Py_DECREF(pyfunc);
+
+ if (ret == NULL) {
+ m2_PyErr_Msg(_dsa_err);
+ }
+
+ return ret;
+}
+
+DSA *dsa_read_pub_key(BIO *f, PyObject *pyfunc) {
+ DSA *ret;
Py_INCREF(pyfunc);
- dsa = DSA_generate_parameters(bits, NULL, 0, NULL, NULL, genparam_callback, (void *)pyfunc);
+ Py_BEGIN_ALLOW_THREADS
+ ret = PEM_read_bio_DSA_PUBKEY(f, NULL, passphrase_callback, (void *)pyfunc);
+ Py_END_ALLOW_THREADS
Py_DECREF(pyfunc);
- if (!dsa)
- PyErr_SetString(_dsa_err, ERR_reason_error_string(ERR_get_error()));
- return dsa;
+
+ if (ret == NULL) {
+ m2_PyErr_Msg(_dsa_err);
+ }
+
+ return ret;
}
+%}
+%typemap(out) DSA * ;
+%inline %{
PyObject *dsa_get_p(DSA *dsa) {
- if (!dsa->p) {
+ const BIGNUM* p = NULL;
+ DSA_get0_pqg(dsa, &p, NULL, NULL);
+ if (!p) {
PyErr_SetString(_dsa_err, "'p' is unset");
return NULL;
}
- return bn_to_mpi(dsa->p);
+ return bn_to_mpi(p);
}
PyObject *dsa_get_q(DSA *dsa) {
- if (!dsa->q) {
+ const BIGNUM* q = NULL;
+ DSA_get0_pqg(dsa, NULL, &q, NULL);
+ if (!q) {
PyErr_SetString(_dsa_err, "'q' is unset");
return NULL;
}
- return bn_to_mpi(dsa->q);
+ return bn_to_mpi(q);
}
PyObject *dsa_get_g(DSA *dsa) {
- if (!dsa->g) {
+ const BIGNUM* g = NULL;
+ DSA_get0_pqg(dsa, NULL, NULL, &g);
+ if (!g) {
PyErr_SetString(_dsa_err, "'g' is unset");
return NULL;
}
- return bn_to_mpi(dsa->g);
+ return bn_to_mpi(g);
}
PyObject *dsa_get_pub(DSA *dsa) {
- if (!dsa->pub_key) {
+ const BIGNUM* pub_key = NULL;
+ DSA_get0_key(dsa, &pub_key, NULL);
+ if (!pub_key) {
PyErr_SetString(_dsa_err, "'pub' is unset");
return NULL;
}
- return bn_to_mpi(dsa->pub_key);
+ return bn_to_mpi(pub_key);
}
PyObject *dsa_get_priv(DSA *dsa) {
- if (!dsa->priv_key) {
+ const BIGNUM* priv_key = NULL;
+ DSA_get0_key(dsa, NULL, &priv_key);
+ if (!priv_key) {
PyErr_SetString(_dsa_err, "'priv' is unset");
return NULL;
}
- return bn_to_mpi(dsa->priv_key);
+ return bn_to_mpi(priv_key);
}
-PyObject *dsa_set_p(DSA *dsa, PyObject *value) {
- BIGNUM *bn;
- const void *vbuf;
- int vlen;
+PyObject *dsa_set_pqg(DSA *dsa, PyObject *pval, PyObject* qval, PyObject* gval) {
+ BIGNUM* p, *q, *g;
- if (m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
+ if (!(p = m2_PyObject_AsBIGNUM(pval, _dsa_err))
+ || !(q = m2_PyObject_AsBIGNUM(qval, _dsa_err))
+ || !(g = m2_PyObject_AsBIGNUM(gval, _dsa_err)))
return NULL;
- if (!(bn = BN_mpi2bn((unsigned char *)vbuf, vlen, NULL))) {
- PyErr_SetString(_dsa_err, ERR_reason_error_string(ERR_get_error()));
+ if (!DSA_set0_pqg(dsa, p, q, g)) {
+ PyErr_SetString(
+ _dsa_err,
+ "Cannot set prime number, subprime, or generator of subgroup for DSA.");
+ BN_free(p);
+ BN_free(q);
+ BN_free(g);
return NULL;
- }
- if (dsa->p)
- BN_free(dsa->p);
- dsa->p = bn;
- Py_INCREF(Py_None);
- return Py_None;
-}
+ }
-PyObject *dsa_set_q(DSA *dsa, PyObject *value) {
- BIGNUM *bn;
- const void *vbuf;
- int vlen;
-
- if (m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
- return NULL;
-
- if (!(bn = BN_mpi2bn((unsigned char *)vbuf, vlen, NULL))) {
- PyErr_SetString(_dsa_err, ERR_reason_error_string(ERR_get_error()));
- return NULL;
+ Py_RETURN_NONE;
}
- if (dsa->q)
- BN_free(dsa->q);
- dsa->q = bn;
- Py_INCREF(Py_None);
- return Py_None;
-}
-PyObject *dsa_set_g(DSA *dsa, PyObject *value) {
+PyObject *dsa_set_pub(DSA *dsa, PyObject *value) {
BIGNUM *bn;
const void *vbuf;
- int vlen;
+ int vlen = 0;
if (m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
return NULL;
if (!(bn = BN_mpi2bn((unsigned char *)vbuf, vlen, NULL))) {
- PyErr_SetString(_dsa_err, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(_dsa_err);
return NULL;
}
- if (dsa->g)
- BN_free(dsa->g);
- dsa->g = bn;
- Py_INCREF(Py_None);
- return Py_None;
-}
-%}
-
-%inline %{
-DSA *dsa_read_params(BIO *f, PyObject *pyfunc) {
- DSA *ret;
-
- Py_INCREF(pyfunc);
- Py_BEGIN_ALLOW_THREADS
- ret = PEM_read_bio_DSAparams(f, NULL, passphrase_callback, (void *)pyfunc);
- Py_END_ALLOW_THREADS
- Py_DECREF(pyfunc);
- return ret;
+ if (!DSA_set0_key(dsa, bn, NULL)) {
+ BN_free(bn);
+ PyErr_SetString(_dsa_err, "Cannot set private and public key for DSA.");
+ }
+ Py_RETURN_NONE;
}
%}
@@ -211,41 +268,17 @@ int dsa_write_pub_key_bio(DSA* dsa, BIO* f) {
%}
%inline %{
-DSA *dsa_read_key(BIO *f, PyObject *pyfunc) {
- DSA *ret;
-
- Py_INCREF(pyfunc);
- Py_BEGIN_ALLOW_THREADS
- ret = PEM_read_bio_DSAPrivateKey(f, NULL, passphrase_callback, (void *)pyfunc);
- Py_END_ALLOW_THREADS
- Py_DECREF(pyfunc);
- return ret;
-}
-%}
-
-%inline %{
-DSA *dsa_read_pub_key(BIO *f, PyObject *pyfunc) {
- DSA *ret;
-
- Py_INCREF(pyfunc);
- Py_BEGIN_ALLOW_THREADS
- ret = PEM_read_bio_DSA_PUBKEY(f, NULL, passphrase_callback, (void *)pyfunc);
- Py_END_ALLOW_THREADS
- Py_DECREF(pyfunc);
- return ret;
-}
-
PyObject *dsa_sign(DSA *dsa, PyObject *value) {
const void *vbuf;
- int vlen;
+ int vlen = 0;
PyObject *tuple;
- DSA_SIG *sig;
+ DSA_SIG *sig;
if (m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
return NULL;
if (!(sig = DSA_do_sign(vbuf, vlen, dsa))) {
- PyErr_SetString(_dsa_err, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(_dsa_err);
return NULL;
}
if (!(tuple = PyTuple_New(2))) {
@@ -261,8 +294,9 @@ PyObject *dsa_sign(DSA *dsa, PyObject *value) {
int dsa_verify(DSA *dsa, PyObject *value, PyObject *r, PyObject *s) {
const void *vbuf, *rbuf, *sbuf;
- int vlen, rlen, slen;
+ int vlen = 0, rlen = 0, slen = 0;
DSA_SIG *sig;
+ BIGNUM* pr, *ps;
int ret;
if ((m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
@@ -271,29 +305,38 @@ int dsa_verify(DSA *dsa, PyObject *value, PyObject *r, PyObject *s) {
return -1;
if (!(sig = DSA_SIG_new())) {
- PyErr_SetString(_dsa_err, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(_dsa_err);
return -1;
}
- if (!(sig->r = BN_mpi2bn((unsigned char *)rbuf, rlen, NULL))) {
- PyErr_SetString(_dsa_err, ERR_reason_error_string(ERR_get_error()));
+ if (!(pr = BN_mpi2bn((unsigned char *)rbuf, rlen, NULL))) {
+ m2_PyErr_Msg(_dsa_err);
DSA_SIG_free(sig);
return -1;
}
- if (!(sig->s = BN_mpi2bn((unsigned char *)sbuf, slen, NULL))) {
- PyErr_SetString(_dsa_err, ERR_reason_error_string(ERR_get_error()));
+ if (!(ps = BN_mpi2bn((unsigned char *)sbuf, slen, NULL))) {
+ m2_PyErr_Msg(_dsa_err);
DSA_SIG_free(sig);
+ BN_free(pr);
return -1;
}
+ if (!DSA_SIG_set0(sig, pr, ps)) {
+ m2_PyErr_Msg(_dsa_err);
+ DSA_SIG_free(sig);
+ BN_free(pr);
+ BN_free(ps);
+ return -1;
+ }
+
ret = DSA_do_verify(vbuf, vlen, sig, dsa);
DSA_SIG_free(sig);
if (ret == -1)
- PyErr_SetString(_dsa_err, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(_dsa_err);
return ret;
}
PyObject *dsa_sign_asn1(DSA *dsa, PyObject *value) {
const void *vbuf;
- int vlen;
+ int vlen = 0;
void *sigbuf;
unsigned int siglen;
PyObject *ret;
@@ -306,19 +349,21 @@ PyObject *dsa_sign_asn1(DSA *dsa, PyObject *value) {
return NULL;
}
if (!DSA_sign(0, vbuf, vlen, (unsigned char *)sigbuf, &siglen, dsa)) {
- PyErr_SetString(_dsa_err, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(_dsa_err);
PyMem_Free(sigbuf);
return NULL;
}
- ret = PyString_FromStringAndSize(sigbuf, siglen);
+
+ ret = PyBytes_FromStringAndSize(sigbuf, siglen);
+
PyMem_Free(sigbuf);
return ret;
}
int dsa_verify_asn1(DSA *dsa, PyObject *value, PyObject *sig) {
- const void *vbuf;
+ const void *vbuf;
void *sbuf;
- int vlen, slen, ret;
+ int vlen = 0, slen = 0, ret = 0;
if ((m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
|| (m2_PyObject_AsReadBufferInt(sig, (const void **)&sbuf, &slen)
@@ -326,20 +371,26 @@ int dsa_verify_asn1(DSA *dsa, PyObject *value, PyObject *sig) {
return -1;
if ((ret = DSA_verify(0, vbuf, vlen, sbuf, slen, dsa)) == -1)
- PyErr_SetString(_dsa_err, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(_dsa_err);
return ret;
}
int dsa_check_key(DSA *dsa) {
- return (dsa->pub_key) && (dsa->priv_key);
+ const BIGNUM* pub_key, *priv_key;
+ DSA_get0_key(dsa, &pub_key, &priv_key);
+ return pub_key != NULL && priv_key != NULL;
}
int dsa_check_pub_key(DSA *dsa) {
- return dsa->pub_key ? 1 : 0;
+ const BIGNUM* pub_key;
+ DSA_get0_key(dsa, &pub_key, NULL);
+ return pub_key ? 1 : 0;
}
int dsa_keylen(DSA *dsa) {
- return BN_num_bits(dsa->p);
+ const BIGNUM* p;
+ DSA_get0_pqg(dsa, &p, NULL, NULL);
+ return BN_num_bits(p);
}
int dsa_type_check(DSA *dsa) {
diff --git a/SWIG/_ec.i b/SWIG/_ec.i
index f0e52bd..f47d593 100644
--- a/SWIG/_ec.i
+++ b/SWIG/_ec.i
@@ -1,4 +1,4 @@
-/* Copyright (c) 1999-2000 Ng Pheng Siong. All rights reserved.
+/* Copyright (c) 1999-2000 Ng Pheng Siong. All rights reserved.
Portions copyright (c) 2005-2006 Vrije Universiteit Amsterdam. All rights reserved.
Most code originally from _dsa.i, _rsa.i and _dh.i and adjusted for EC use.
@@ -28,7 +28,7 @@ extern EC_KEY *EC_KEY_new(void);
%rename(ec_key_free) EC_KEY_free;
extern void EC_KEY_free(EC_KEY *);
%rename(ec_key_size) ECDSA_size;
-extern int ECDSA_size(const EC_KEY *);
+extern int ECDSA_size(const EC_KEY *);
%rename(ec_key_gen_key) EC_KEY_generate_key;
extern int EC_KEY_generate_key(EC_KEY *);
%rename(ec_key_check_key) EC_KEY_check_key;
@@ -107,6 +107,7 @@ extern int EC_KEY_check_key(const EC_KEY *);
%constant int NID_ipsec4 = NID_ipsec4;
+%warnfilter(454) _ec_err;
%inline %{
static PyObject *_ec_err;
@@ -115,6 +116,57 @@ void ec_init(PyObject *ec_err) {
_ec_err = ec_err;
}
+PyObject *ec_get_builtin_curves(void) {
+ /* size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t
+ * nitems); */
+ EC_builtin_curve *curves;
+ Py_ssize_t ret_curves = 0;
+ size_t num_curves = EC_get_builtin_curves(NULL, 0);
+ PyObject *ret_tuple = NULL;
+ PyObject *ret_dict = NULL;
+ Py_ssize_t i;
+ const char *comment;
+ const char *sname;
+
+ if (!(curves = PyMem_Malloc(num_curves * sizeof(EC_builtin_curve)))) {
+ PyErr_SetString(PyExc_MemoryError, "ec_get_builtin_curves");
+ return NULL;
+ }
+
+ ret_curves = (Py_ssize_t)EC_get_builtin_curves(curves, num_curves);
+
+ if (!(ret_tuple = PyTuple_New(ret_curves))) {
+ PyErr_SetString(PyExc_MemoryError, "ec_get_builtin_curves");
+ return NULL;
+ }
+
+ for (i = 0; i < ret_curves; i++) {
+ if (!(ret_dict = PyDict_New())) {
+ PyErr_SetString(PyExc_MemoryError, "ec_get_builtin_curves");
+ return NULL;
+ }
+
+ comment = curves[i].comment;
+ sname = OBJ_nid2sn(curves[i].nid);
+ if (sname == NULL)
+ sname = "";
+
+ PyDict_SetItemString(ret_dict, "NID",
+ PyLong_FromLong((long)curves[i].nid));
+ PyDict_SetItemString(ret_dict, "sname",
+ PyString_FromString(sname));
+ PyDict_SetItemString(ret_dict, "comment",
+ PyString_FromString(comment));
+
+ PyTuple_SET_ITEM(ret_tuple, i, ret_dict);
+
+ }
+
+ PyMem_Free(curves);
+
+ return ret_tuple;
+}
+
EC_KEY* ec_key_new_by_curve_name(int nid)
{
EC_KEY *key;
@@ -136,8 +188,8 @@ EC_KEY* ec_key_new_by_curve_name(int nid)
}
group = EC_GROUP_new_by_curve_name(nid);
if (!group) {
+ m2_PyErr_Msg(_ec_err);
EC_KEY_free(key);
- PyErr_SetString(_ec_err, ERR_reason_error_string(ERR_get_error()));
return NULL;
}
EC_GROUP_set_asn1_flag(group, asn1_flag);
@@ -156,45 +208,53 @@ EC_KEY* ec_key_new_by_curve_name(int nid)
}
PyObject *ec_key_get_public_der(EC_KEY *key) {
-
- unsigned char *src=NULL;
- void *dst=NULL;
+ char *src=NULL;
int src_len=0;
- Py_ssize_t dst_len=0;
PyObject *pyo=NULL;
- int ret=0;
-
+
/* Convert to binary */
- src_len = i2d_EC_PUBKEY( key, &src );
+ src_len = i2d_EC_PUBKEY( key, (unsigned char**)&src );
if (src_len < 0)
{
- PyErr_SetString(_ec_err, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(_ec_err);
return NULL;
}
/* Create a PyBuffer containing a copy of the binary,
* to simplify memory deallocation
*/
- pyo = PyBuffer_New( src_len );
- ret = PyObject_AsWriteBuffer( pyo, &dst, &dst_len );
- assert( src_len == dst_len );
- if (ret < 0)
+ pyo = PyBytes_FromStringAndSize( src, src_len );
+
+ OPENSSL_free(src);
+
+ return pyo;
+}
+
+PyObject *ec_key_get_public_key(EC_KEY *key) {
+ char *src=NULL;
+ int src_len=0;
+ PyObject *pyo=NULL;
+
+ /* Convert to binary */
+ src_len = i2o_ECPublicKey(key, (unsigned char**)&src);
+ if (src_len < 0)
{
- Py_DECREF(pyo);
- OPENSSL_free(src);
- PyErr_SetString(_ec_err, "cannot get write buffer");
+ m2_PyErr_Msg(_ec_err);
return NULL;
}
- memcpy( dst, src, src_len );
+
+ pyo = PyBytes_FromStringAndSize( src, src_len );
+
OPENSSL_free(src);
return pyo;
}
+
%}
%threadallow ec_key_read_pubkey;
%inline %{
EC_KEY *ec_key_read_pubkey(BIO *f) {
- return PEM_read_bio_EC_PUBKEY(f, NULL, NULL, NULL);
+ return PEM_read_bio_EC_PUBKEY(f, NULL, NULL, NULL);
}
%}
@@ -238,7 +298,7 @@ int ec_key_write_bio_no_cipher(EC_KEY *key, BIO *f, PyObject *pyfunc) {
Py_INCREF(pyfunc);
Py_BEGIN_ALLOW_THREADS
- ret = PEM_write_bio_ECPrivateKey(f, key, NULL, NULL, 0,
+ ret = PEM_write_bio_ECPrivateKey(f, key, NULL, NULL, 0,
passphrase_callback, (void *)pyfunc);
Py_END_ALLOW_THREADS
Py_DECREF(pyfunc);
@@ -247,24 +307,28 @@ int ec_key_write_bio_no_cipher(EC_KEY *key, BIO *f, PyObject *pyfunc) {
PyObject *ecdsa_sig_get_r(ECDSA_SIG *ecdsa_sig) {
- return bn_to_mpi(ecdsa_sig->r);
+ const BIGNUM* pr;
+ ECDSA_SIG_get0(ecdsa_sig, &pr, NULL);
+ return bn_to_mpi(pr);
}
PyObject *ecdsa_sig_get_s(ECDSA_SIG *ecdsa_sig) {
- return bn_to_mpi(ecdsa_sig->s);
+ const BIGNUM* ps;
+ ECDSA_SIG_get0(ecdsa_sig, NULL, &ps);
+ return bn_to_mpi(ps);
}
PyObject *ecdsa_sign(EC_KEY *key, PyObject *value) {
const void *vbuf;
- int vlen;
+ int vlen = 0;
PyObject *tuple;
- ECDSA_SIG *sig;
+ ECDSA_SIG *sig;
if (m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
return NULL;
if (!(sig = ECDSA_do_sign(vbuf, vlen, key))) {
- PyErr_SetString(_ec_err, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(_ec_err);
return NULL;
}
if (!(tuple = PyTuple_New(2))) {
@@ -280,40 +344,50 @@ PyObject *ecdsa_sign(EC_KEY *key, PyObject *value) {
int ecdsa_verify(EC_KEY *key, PyObject *value, PyObject *r, PyObject *s) {
const void *vbuf, *rbuf, *sbuf;
- int vlen, rlen, slen;
+ int vlen = 0, rlen = 0, slen = 0;
ECDSA_SIG *sig;
int ret;
+ BIGNUM* pr, *ps;
if ((m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
|| (m2_PyObject_AsReadBufferInt(r, &rbuf, &rlen) == -1)
|| (m2_PyObject_AsReadBufferInt(s, &sbuf, &slen) == -1))
return -1;
- if (!(sig = ECDSA_SIG_new())) {
- PyErr_SetString(_ec_err, ERR_reason_error_string(ERR_get_error()));
+ if (!(pr = BN_mpi2bn((unsigned char *)rbuf, rlen, NULL))) {
+ m2_PyErr_Msg(_ec_err);
return -1;
}
- if (!BN_mpi2bn((unsigned char *)rbuf, rlen, sig->r)) {
- PyErr_SetString(_ec_err, ERR_reason_error_string(ERR_get_error()));
- ECDSA_SIG_free(sig);
+ if (!(ps = BN_mpi2bn((unsigned char *)sbuf, slen, NULL))) {
+ m2_PyErr_Msg(_ec_err);
+ BN_free(pr);
return -1;
}
- if (!BN_mpi2bn((unsigned char *)sbuf, slen, sig->s)) {
- PyErr_SetString(_ec_err, ERR_reason_error_string(ERR_get_error()));
+
+ if (!(sig = ECDSA_SIG_new())) {
+ m2_PyErr_Msg(_ec_err);
+ BN_free(pr);
+ BN_free(ps);
+ return -1;
+ }
+ if (!ECDSA_SIG_set0(sig, pr, ps)) {
+ PyErr_SetString(_ec_err, "Cannot set r and s fields of ECDSA_SIG.");
ECDSA_SIG_free(sig);
+ BN_free(pr);
+ BN_free(ps);
return -1;
}
ret = ECDSA_do_verify(vbuf, vlen, sig, key);
ECDSA_SIG_free(sig);
if (ret == -1)
- PyErr_SetString(_ec_err, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(_ec_err);
return ret;
}
PyObject *ecdsa_sign_asn1(EC_KEY *key, PyObject *value) {
const void *vbuf;
- int vlen;
+ int vlen = 0;
void *sigbuf;
unsigned int siglen;
PyObject *ret;
@@ -326,20 +400,21 @@ PyObject *ecdsa_sign_asn1(EC_KEY *key, PyObject *value) {
return NULL;
}
if (!ECDSA_sign(0, vbuf, vlen, (unsigned char *)sigbuf, &siglen, key)) {
- PyErr_SetString(_ec_err, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(_ec_err);
PyMem_Free(sigbuf);
return NULL;
}
- ret = PyString_FromStringAndSize(sigbuf, siglen);
+ ret = PyBytes_FromStringAndSize(sigbuf, siglen);
+
PyMem_Free(sigbuf);
return ret;
}
int ecdsa_verify_asn1(EC_KEY *key, PyObject *value, PyObject *sig) {
- const void *vbuf;
+ const void *vbuf;
void *sbuf;
- int vlen, slen, ret;
+ int vlen = 0, slen = 0, ret;
if ((m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
|| (m2_PyObject_AsReadBufferInt(sig, (const void **)&sbuf, &slen)
@@ -347,7 +422,7 @@ int ecdsa_verify_asn1(EC_KEY *key, PyObject *value, PyObject *sig) {
return -1;
if ((ret = ECDSA_verify(0, vbuf, vlen, sbuf, slen, key)) == -1)
- PyErr_SetString(_ec_err, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(_ec_err);
return ret;
}
@@ -360,10 +435,10 @@ PyObject *ecdh_compute_key(EC_KEY *keypairA, EC_KEY *pubkeyB) {
if ((pkpointB = EC_KEY_get0_public_key(pubkeyB)) == NULL)
{
- PyErr_SetString(_ec_err, ERR_reason_error_string(ERR_get_error()));
+ PyErr_SetString(_ec_err, "Cannot get the public key of EC_KEY object.");
return NULL;
}
-
+
groupA = EC_KEY_get0_group(keypairA);
sharedkeylen = (EC_GROUP_get_degree(groupA) + 7)/8;
@@ -372,14 +447,15 @@ PyObject *ecdh_compute_key(EC_KEY *keypairA, EC_KEY *pubkeyB) {
return NULL;
}
if ((sharedkeylen = ECDH_compute_key((unsigned char *)sharedkey, sharedkeylen, pkpointB, keypairA, NULL)) == -1) {
+ m2_PyErr_Msg(_ec_err);
PyMem_Free(sharedkey);
- PyErr_SetString(_ec_err, ERR_reason_error_string(ERR_get_error()));
return NULL;
}
- ret = PyString_FromStringAndSize((const char *)sharedkey, sharedkeylen);
+ ret = PyBytes_FromStringAndSize((const char *)sharedkey, sharedkeylen);
+
PyMem_Free(sharedkey);
-
+
return ret;
}
@@ -398,7 +474,33 @@ EC_KEY* ec_key_from_pubkey_der(PyObject *pubkey) {
tempBuf = (const unsigned char *)keypairbuf;
if ((keypair = d2i_EC_PUBKEY( NULL, &tempBuf, keypairbuflen)) == 0)
{
- PyErr_SetString(_ec_err, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(_ec_err);
+ return NULL;
+ }
+ return keypair;
+}
+
+EC_KEY* ec_key_from_pubkey_params(int nid, PyObject *pubkey) {
+ const void *keypairbuf;
+ Py_ssize_t keypairbuflen;
+ const unsigned char *tempBuf;
+ EC_KEY *keypair;
+
+ if (PyObject_AsReadBuffer(pubkey, &keypairbuf, &keypairbuflen) == -1)
+ {
+ return NULL;
+ }
+
+ keypair = ec_key_new_by_curve_name(nid);
+ if (!keypair) {
+ m2_PyErr_Msg(_ec_err);
+ return NULL;
+ }
+
+ tempBuf = (const unsigned char *)keypairbuf;
+ if ((o2i_ECPublicKey( &keypair, &tempBuf, keypairbuflen)) == 0)
+ {
+ m2_PyErr_Msg(_ec_err);
return NULL;
}
return keypair;
diff --git a/SWIG/_engine.i b/SWIG/_engine.i
index b55720f..4ba93f3 100644
--- a/SWIG/_engine.i
+++ b/SWIG/_engine.i
@@ -164,6 +164,7 @@ extern EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id,
* This function may be not implemented in engine.
* pkcs11 engine has this control.
*/
+%warnfilter(454) _engine_err;
%inline %{
static PyObject *_engine_err;
diff --git a/SWIG/_evp.i b/SWIG/_evp.i
index 0593eed..d04e806 100644
--- a/SWIG/_evp.i
+++ b/SWIG/_evp.i
@@ -1,5 +1,5 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
+/*
Copyright (c) 1999 Ng Pheng Siong. All rights reserved.
Portions Copyright (c) 2004-2007 Open Source Applications Foundation.
@@ -18,8 +18,32 @@ Copyright (c) 2009-2010 Heikki Toivonen. All rights reserved.
#include <openssl/hmac.h>
#include <openssl/rsa.h>
#include <openssl/opensslv.h>
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+
+HMAC_CTX *HMAC_CTX_new(void) {
+ HMAC_CTX *ret = PyMem_Malloc(sizeof(HMAC_CTX));
+ HMAC_CTX_init(ret);
+ return ret;
+}
+#define HMAC_CTX_reset(ctx) HMAC_CTX_init(ctx)
+#define HMAC_CTX_free(ctx) \
+ do { \
+ HMAC_CTX_cleanup(ctx); \
+ PyMem_Free((void *)ctx); \
+ } while(0)
+
+#define EVP_CIPHER_CTX_reset(ctx) EVP_CIPHER_CTX_init(ctx)
+#endif
%}
+/*
+from openssl/crypto/include/internal/evp_int.h struct evp_md_st
+typedef struct evp_md_st EVP_MD;
+from openssl/crypto/evp/evp_locl.h evp_md_ctx_st
+typedef struct evp_md_ctx_st EVP_MD_CTX;
+*/
+
%apply Pointer NONNULL { EVP_MD_CTX * };
%apply Pointer NONNULL { EVP_MD * };
%apply Pointer NONNULL { EVP_PKEY * };
@@ -101,10 +125,14 @@ extern const EVP_CIPHER *EVP_cast5_ofb(void);
%rename(rc5_cfb) extern const EVP_CIPHER *EVP_rc5_32_12_16_cfb(void);
%rename(rc5_ofb) extern const EVP_CIPHER *EVP_rc5_32_12_16_ofb(void);
*/
+#if !defined(OPENSSL_NO_RC4)
%rename(rc4) EVP_rc4;
extern const EVP_CIPHER *EVP_rc4(void);
+#endif
+#if !defined(OPENSSL_NO_RC2)
%rename(rc2_40_cbc) EVP_rc2_40_cbc;
extern const EVP_CIPHER *EVP_rc2_40_cbc(void);
+#endif
%rename(aes_128_ecb) EVP_aes_128_ecb;
extern const EVP_CIPHER *EVP_aes_128_ecb(void);
%rename(aes_128_cbc) EVP_aes_128_cbc;
@@ -113,6 +141,8 @@ extern const EVP_CIPHER *EVP_aes_128_cbc(void);
extern const EVP_CIPHER *EVP_aes_128_cfb(void);
%rename(aes_128_ofb) EVP_aes_128_ofb;
extern const EVP_CIPHER *EVP_aes_128_ofb(void);
+%rename(aes_128_ctr) EVP_aes_128_ctr;
+extern const EVP_CIPHER *EVP_aes_128_ctr(void);
%rename(aes_192_ecb) EVP_aes_192_ecb;
extern const EVP_CIPHER *EVP_aes_192_ecb(void);
%rename(aes_192_cbc) EVP_aes_192_cbc;
@@ -121,6 +151,8 @@ extern const EVP_CIPHER *EVP_aes_192_cbc(void);
extern const EVP_CIPHER *EVP_aes_192_cfb(void);
%rename(aes_192_ofb) EVP_aes_192_ofb;
extern const EVP_CIPHER *EVP_aes_192_ofb(void);
+%rename(aes_192_ctr) EVP_aes_192_ctr;
+extern const EVP_CIPHER *EVP_aes_192_ctr(void);
%rename(aes_256_ecb) EVP_aes_256_ecb;
extern const EVP_CIPHER *EVP_aes_256_ecb(void);
%rename(aes_256_cbc) EVP_aes_256_cbc;
@@ -129,12 +161,15 @@ extern const EVP_CIPHER *EVP_aes_256_cbc(void);
extern const EVP_CIPHER *EVP_aes_256_cfb(void);
%rename(aes_256_ofb) EVP_aes_256_ofb;
extern const EVP_CIPHER *EVP_aes_256_ofb(void);
+%rename(aes_256_ctr) EVP_aes_256_ctr;
+extern EVP_CIPHER const *EVP_aes_256_ctr(void);
%rename(cipher_set_padding) EVP_CIPHER_CTX_set_padding;
extern int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *, int);
-%rename(pkey_new) EVP_PKEY_new;
-extern EVP_PKEY *EVP_PKEY_new(void);
+
+%rename(cipher_set_padding) EVP_CIPHER_CTX_set_padding;
+extern int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *x, int padding);
%rename(pkey_free) EVP_PKEY_free;
extern void EVP_PKEY_free(EVP_PKEY *);
%rename(pkey_assign) EVP_PKEY_assign;
@@ -145,8 +180,6 @@ extern int EVP_PKEY_assign_EC_KEY(EVP_PKEY *, EC_KEY *);
#endif
%rename(pkey_set1_rsa) EVP_PKEY_set1_RSA;
extern int EVP_PKEY_set1_RSA(EVP_PKEY *, RSA *);
-%rename(pkey_get1_rsa) EVP_PKEY_get1_RSA;
-extern RSA* EVP_PKEY_get1_RSA(EVP_PKEY *);
%rename(sign_init) EVP_SignInit;
extern int EVP_SignInit(EVP_MD_CTX *, const EVP_MD *);
%rename(verify_init) EVP_VerifyInit;
@@ -154,6 +187,7 @@ extern int EVP_VerifyInit(EVP_MD_CTX *, const EVP_MD *);
%rename(pkey_size) EVP_PKEY_size;
extern int EVP_PKEY_size(EVP_PKEY *);
+%warnfilter(454) _evp_err;
%inline %{
#define PKCS5_SALT_LEN 8
@@ -163,16 +197,43 @@ void evp_init(PyObject *evp_err) {
Py_INCREF(evp_err);
_evp_err = evp_err;
}
+%}
+
+%typemap(out) RSA * {
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+
+ if ($1 != NULL)
+ $result = SWIG_NewPointerObj($1, $1_descriptor, 0);
+ else {
+ $result = NULL;
+ }
+}
+%inline %{
+RSA *pkey_get1_rsa(EVP_PKEY *pkey) {
+ RSA *ret = NULL;
+
+ if ((ret = EVP_PKEY_get1_RSA(pkey)) == NULL) {
+ /* _evp_err now inherits from PyExc_ValueError, so we should
+ * keep API intact.
+ */
+ PyErr_Format(_evp_err, "Invalid key in function %s.", __FUNCTION__);
+ }
+
+ return ret;
+}
+%}
+%typemap(out) RSA * ;
+%inline %{
PyObject *pkcs5_pbkdf2_hmac_sha1(PyObject *pass,
PyObject *salt,
int iter,
int keylen) {
- unsigned char key[EVP_MAX_KEY_LENGTH];
+ unsigned char *key;
unsigned char *saltbuf;
char *passbuf;
PyObject *ret;
- int passlen, saltlen;
+ int passlen = 0, saltlen = 0;
if (m2_PyObject_AsReadBufferInt(pass, (const void **)&passbuf,
&passlen) == -1)
@@ -181,10 +242,14 @@ PyObject *pkcs5_pbkdf2_hmac_sha1(PyObject *pass,
&saltlen) == -1)
return NULL;
+ key = PyMem_Malloc(keylen);
+ if (key == NULL)
+ return PyErr_NoMemory();
PKCS5_PBKDF2_HMAC_SHA1(passbuf, passlen, saltbuf, saltlen, iter,
keylen, key);
- ret = PyString_FromStringAndSize((char*)key, keylen);
+ ret = PyBytes_FromStringAndSize((char*)key, keylen);
OPENSSL_cleanse(key, keylen);
+ PyMem_Free(key);
return ret;
}
@@ -193,6 +258,7 @@ EVP_MD_CTX *md_ctx_new(void) {
if (!(ctx = EVP_MD_CTX_create())) {
PyErr_SetString(PyExc_MemoryError, "md_ctx_new");
+ return NULL;
}
return ctx;
}
@@ -216,16 +282,18 @@ PyObject *digest_final(EVP_MD_CTX *ctx) {
int blen;
PyObject *ret;
- if (!(blob = PyMem_Malloc(ctx->digest->md_size))) {
+ if (!(blob = PyMem_Malloc(EVP_MD_CTX_size(ctx)))) {
PyErr_SetString(PyExc_MemoryError, "digest_final");
return NULL;
}
if (!EVP_DigestFinal(ctx, blob, (unsigned int *)&blen)) {
PyMem_Free(blob);
- PyErr_SetString(_evp_err, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(_evp_err);
return NULL;
}
- ret = PyString_FromStringAndSize(blob, blen);
+
+ ret = PyBytes_FromStringAndSize(blob, blen);
+
PyMem_Free(blob);
return ret;
}
@@ -233,29 +301,29 @@ PyObject *digest_final(EVP_MD_CTX *ctx) {
HMAC_CTX *hmac_ctx_new(void) {
HMAC_CTX *ctx;
- if (!(ctx = (HMAC_CTX *)PyMem_Malloc(sizeof(HMAC_CTX)))) {
+ if (!(ctx = HMAC_CTX_new())) {
PyErr_SetString(PyExc_MemoryError, "hmac_ctx_new");
return NULL;
}
- HMAC_CTX_init(ctx);
return ctx;
}
void hmac_ctx_free(HMAC_CTX *ctx) {
- HMAC_CTX_cleanup(ctx);
- PyMem_Free((void *)ctx);
+ HMAC_CTX_free(ctx);
}
PyObject *hmac_init(HMAC_CTX *ctx, PyObject *key, const EVP_MD *md) {
const void *kbuf;
- int klen;
+ int klen = 0;
if (m2_PyObject_AsReadBufferInt(key, &kbuf, &klen) == -1)
return NULL;
- HMAC_Init(ctx, kbuf, klen, md);
- Py_INCREF(Py_None);
- return Py_None;
+ if (!HMAC_Init_ex(ctx, kbuf, klen, md, NULL)) {
+ PyErr_SetString(_evp_err, "HMAC_Init failed");
+ return NULL;
+ }
+ Py_RETURN_NONE;
}
PyObject *hmac_update(HMAC_CTX *ctx, PyObject *blob) {
@@ -265,9 +333,11 @@ PyObject *hmac_update(HMAC_CTX *ctx, PyObject *blob) {
if (PyObject_AsReadBuffer(blob, &buf, &len) == -1)
return NULL;
- HMAC_Update(ctx, buf, len);
- Py_INCREF(Py_None);
- return Py_None;
+ if (!HMAC_Update(ctx, buf, len)) {
+ PyErr_SetString(_evp_err, "HMAC_Update failed");
+ return NULL;
+ }
+ Py_RETURN_NONE;
}
PyObject *hmac_final(HMAC_CTX *ctx) {
@@ -275,12 +345,18 @@ PyObject *hmac_final(HMAC_CTX *ctx) {
int blen;
PyObject *ret;
- if (!(blob = PyMem_Malloc(ctx->md->md_size))) {
+ if (!(blob = PyMem_Malloc(HMAC_size(ctx)))) {
PyErr_SetString(PyExc_MemoryError, "hmac_final");
return NULL;
}
- HMAC_Final(ctx, blob, (unsigned int *)&blen);
- ret = PyString_FromStringAndSize(blob, blen);
+
+ if (!HMAC_Final(ctx, blob, (unsigned int *)&blen)) {
+ PyErr_SetString(_evp_err, "HMAC_Final failed");
+ return NULL;
+ }
+
+ ret = PyBytes_FromStringAndSize(blob, blen);
+
PyMem_Free(blob);
return ret;
}
@@ -288,7 +364,7 @@ PyObject *hmac_final(HMAC_CTX *ctx) {
PyObject *hmac(PyObject *key, PyObject *data, const EVP_MD *md) {
const void *kbuf, *dbuf;
void *blob;
- int klen;
+ int klen = 0;
unsigned int blen;
Py_ssize_t dlen;
PyObject *ret;
@@ -303,7 +379,9 @@ PyObject *hmac(PyObject *key, PyObject *data, const EVP_MD *md) {
}
HMAC(md, kbuf, klen, dbuf, dlen, blob, &blen);
blob = PyMem_Realloc(blob, blen);
- ret = PyString_FromStringAndSize(blob, blen);
+
+ ret = PyBytes_FromStringAndSize(blob, blen);
+
PyMem_Free(blob);
return ret;
}
@@ -311,26 +389,25 @@ PyObject *hmac(PyObject *key, PyObject *data, const EVP_MD *md) {
EVP_CIPHER_CTX *cipher_ctx_new(void) {
EVP_CIPHER_CTX *ctx;
- if (!(ctx = (EVP_CIPHER_CTX *)PyMem_Malloc(sizeof(EVP_CIPHER_CTX)))) {
+ if (!(ctx = EVP_CIPHER_CTX_new())) {
PyErr_SetString(PyExc_MemoryError, "cipher_ctx_new");
return NULL;
}
- EVP_CIPHER_CTX_init(ctx);
+ EVP_CIPHER_CTX_reset(ctx);
return ctx;
}
void cipher_ctx_free(EVP_CIPHER_CTX *ctx) {
- EVP_CIPHER_CTX_cleanup(ctx);
- PyMem_Free((void *)ctx);
+ EVP_CIPHER_CTX_free(ctx);
}
-PyObject *bytes_to_key(const EVP_CIPHER *cipher, EVP_MD *md,
+PyObject *bytes_to_key(const EVP_CIPHER *cipher, EVP_MD *md,
PyObject *data, PyObject *salt,
PyObject *iv, /* Not used */
int iter) {
unsigned char key[EVP_MAX_KEY_LENGTH];
const void *dbuf, *sbuf;
- int dlen, klen;
+ int dlen = 0, klen;
Py_ssize_t slen;
PyObject *ret;
@@ -339,14 +416,16 @@ PyObject *bytes_to_key(const EVP_CIPHER *cipher, EVP_MD *md,
return NULL;
assert((slen == 8) || (slen == 0));
- klen = EVP_BytesToKey(cipher, md, (unsigned char *)sbuf,
- (unsigned char *)dbuf, dlen, iter,
+ klen = EVP_BytesToKey(cipher, md, (unsigned char *)sbuf,
+ (unsigned char *)dbuf, dlen, iter,
key, NULL); /* Since we are not returning IV no need to derive it */
- ret = PyString_FromStringAndSize((char*)key, klen);
+
+ ret = PyBytes_FromStringAndSize((char*)key, klen);
+
return ret;
}
-PyObject *cipher_init(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+PyObject *cipher_init(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
PyObject *key, PyObject *iv, int mode) {
const void *kbuf, *ibuf;
Py_ssize_t klen, ilen;
@@ -357,16 +436,15 @@ PyObject *cipher_init(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
if (!EVP_CipherInit(ctx, cipher, (unsigned char *)kbuf,
(unsigned char *)ibuf, mode)) {
- PyErr_SetString(_evp_err, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(_evp_err);
return NULL;
}
- Py_INCREF(Py_None);
- return Py_None;
+ Py_RETURN_NONE;
}
PyObject *cipher_update(EVP_CIPHER_CTX *ctx, PyObject *blob) {
const void *buf;
- int len, olen;
+ int len = 0, olen;
void *obuf;
PyObject *ret;
@@ -379,10 +457,12 @@ PyObject *cipher_update(EVP_CIPHER_CTX *ctx, PyObject *blob) {
}
if (!EVP_CipherUpdate(ctx, obuf, &olen, (unsigned char *)buf, len)) {
PyMem_Free(obuf);
- PyErr_SetString(_evp_err, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(_evp_err);
return NULL;
}
- ret = PyString_FromStringAndSize(obuf, olen);
+
+ ret = PyBytes_FromStringAndSize(obuf, olen);
+
PyMem_Free(obuf);
return ret;
}
@@ -392,16 +472,18 @@ PyObject *cipher_final(EVP_CIPHER_CTX *ctx) {
int olen;
PyObject *ret;
- if (!(obuf = PyMem_Malloc(ctx->cipher->block_size))) {
+ if (!(obuf = PyMem_Malloc(EVP_CIPHER_CTX_block_size(ctx)))) {
PyErr_SetString(PyExc_MemoryError, "cipher_final");
return NULL;
}
if (!EVP_CipherFinal(ctx, (unsigned char *)obuf, &olen)) {
PyMem_Free(obuf);
- PyErr_SetString(_evp_err, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(_evp_err);
return NULL;
}
- ret = PyString_FromStringAndSize(obuf, olen);
+
+ ret = PyBytes_FromStringAndSize(obuf, olen);
+
PyMem_Free(obuf);
return ret;
}
@@ -414,11 +496,10 @@ PyObject *sign_update(EVP_MD_CTX *ctx, PyObject *blob) {
return NULL;
if (!EVP_SignUpdate(ctx, buf, len)) {
- PyErr_SetString(_evp_err, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(_evp_err);
return NULL;
}
- Py_INCREF(Py_None);
- return Py_None;
+ Py_RETURN_NONE;
}
PyObject *sign_final(EVP_MD_CTX *ctx, EVP_PKEY *pkey) {
@@ -433,12 +514,14 @@ PyObject *sign_final(EVP_MD_CTX *ctx, EVP_PKEY *pkey) {
}
if (!EVP_SignFinal(ctx, sigbuf, &siglen, pkey)) {
+ m2_PyErr_Msg(_evp_err);
OPENSSL_cleanse(sigbuf, siglen);
OPENSSL_free(sigbuf);
- PyErr_SetString(_evp_err, ERR_reason_error_string(ERR_get_error()));
return NULL;
}
- ret = PyString_FromStringAndSize((char*)sigbuf, siglen);
+
+ ret = PyBytes_FromStringAndSize((char*)sigbuf, siglen);
+
OPENSSL_cleanse(sigbuf, siglen);
OPENSSL_free(sigbuf);
return ret;
@@ -456,8 +539,8 @@ int verify_update(EVP_MD_CTX *ctx, PyObject *blob) {
int verify_final(EVP_MD_CTX *ctx, PyObject *blob, EVP_PKEY *pkey) {
- unsigned char *kbuf;
- int len;
+ unsigned char *kbuf;
+ int len = 0;
if (m2_PyObject_AsReadBufferInt(blob, (const void **)&kbuf, &len) == -1)
return -1;
@@ -466,6 +549,28 @@ int verify_final(EVP_MD_CTX *ctx, PyObject *blob, EVP_PKEY *pkey) {
}
%}
+%typemap(out) EVP_MD * {
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+
+ if ($1 != NULL)
+ $result = SWIG_NewPointerObj($1, $1_descriptor, 0);
+ else {
+ $result = NULL;
+ }
+}
+%inline %{
+const EVP_MD *get_digestbyname(const char* name) {
+ const EVP_MD *ret = NULL;
+
+ if ((ret = EVP_get_digestbyname(name)) == NULL) {
+ m2_PyErr_Msg(_evp_err);
+ }
+
+ return ret;
+}
+%}
+%typemap(out) EVP_MD *;
+
%inline %{
int pkey_write_pem_no_cipher(EVP_PKEY *pkey, BIO *f, PyObject *pyfunc) {
int ret;
@@ -494,7 +599,27 @@ int pkey_write_pem(EVP_PKEY *pkey, BIO *f, EVP_CIPHER *cipher, PyObject *pyfunc)
}
%}
+%typemap(out) EVP_PKEY * {
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+
+ if ($1 != NULL)
+ $result = SWIG_NewPointerObj($1, $1_descriptor, 0);
+ else {
+ $result = NULL;
+ }
+}
%inline %{
+EVP_PKEY *pkey_new(void) {
+ EVP_PKEY *ret;
+
+ if ((ret = EVP_PKEY_new()) == NULL) {
+ PyErr_Format(PyExc_MemoryError,
+ "Insufficient memory for new key in function %s.", __FUNCTION__);
+ }
+
+ return ret;
+}
+
EVP_PKEY *pkey_read_pem(BIO *f, PyObject *pyfunc) {
EVP_PKEY *pk;
@@ -503,9 +628,35 @@ EVP_PKEY *pkey_read_pem(BIO *f, PyObject *pyfunc) {
pk = PEM_read_bio_PrivateKey(f, NULL, passphrase_callback, (void *)pyfunc);
Py_END_ALLOW_THREADS
Py_DECREF(pyfunc);
+
+ if (pk == NULL) {
+ PyErr_Format(_evp_err,
+ "Unable to read private key in function %s.", __FUNCTION__);
+ }
+
return pk;
}
+EVP_PKEY *pkey_read_pem_pubkey(BIO *f, PyObject *pyfunc) {
+ EVP_PKEY *pk;
+
+ Py_INCREF(pyfunc);
+ Py_BEGIN_ALLOW_THREADS
+ pk = PEM_read_bio_PUBKEY(f, NULL, passphrase_callback, (void *)pyfunc);
+ Py_END_ALLOW_THREADS
+ Py_DECREF(pyfunc);
+
+ if (pk == NULL) {
+ PyErr_Format(_evp_err,
+ "Unable to read public key in function %s.", __FUNCTION__);
+ }
+
+ return pk;
+}
+%}
+%typemap(out) EVP_PKEY * ;
+
+%inline %{
int pkey_assign_rsa(EVP_PKEY *pkey, RSA *rsa) {
return EVP_PKEY_assign_RSA(pkey, rsa);
}
@@ -516,10 +667,12 @@ PyObject *pkey_as_der(EVP_PKEY *pkey) {
PyObject * der;
len = i2d_PUBKEY(pkey, &pp);
if (len < 0){
- PyErr_SetString(PyExc_ValueError, "EVP_PKEY as DER failed");
- return NULL;
+ PyErr_SetString(_evp_err, "EVP_PKEY as DER failed");
+ return NULL;
}
- der = PyString_FromStringAndSize((char*)pp, len);
+
+ der = PyBytes_FromStringAndSize((char*)pp, len);
+
OPENSSL_free(pp);
return der;
}
@@ -531,8 +684,9 @@ PyObject *pkey_get_modulus(EVP_PKEY *pkey)
BIO *bio;
BUF_MEM *bptr;
PyObject *ret;
+ const BIGNUM* bn;
- switch (pkey->type) {
+ switch (EVP_PKEY_base_id(pkey)) {
case EVP_PKEY_RSA:
rsa = EVP_PKEY_get1_RSA(pkey);
@@ -542,20 +696,23 @@ PyObject *pkey_get_modulus(EVP_PKEY *pkey)
PyErr_SetString(PyExc_MemoryError, "pkey_get_modulus");
return NULL;
}
-
- if (!BN_print(bio, rsa->n)) {
- PyErr_SetString(PyExc_RuntimeError,
- ERR_error_string(ERR_get_error(), NULL));
+
+ RSA_get0_key(rsa, &bn, NULL, NULL);
+ if (!BN_print(bio, bn)) {
+ m2_PyErr_Msg(PyExc_RuntimeError);
BIO_free(bio);
RSA_free(rsa);
return NULL;
}
BIO_get_mem_ptr(bio, &bptr);
- ret = PyString_FromStringAndSize(bptr->data, bptr->length);
- BIO_set_close(bio, BIO_CLOSE);
+
+ ret = PyBytes_FromStringAndSize(bptr->data, bptr->length);
+
+ (void)BIO_set_close(bio, BIO_CLOSE);
BIO_free(bio);
RSA_free(rsa);
+ return ret;
break;
case EVP_PKEY_DSA:
@@ -568,29 +725,28 @@ PyObject *pkey_get_modulus(EVP_PKEY *pkey)
return NULL;
}
- if (!BN_print(bio, dsa->pub_key)) {
- PyErr_SetString(PyExc_RuntimeError,
- ERR_error_string(ERR_get_error(), NULL));
+ DSA_get0_key(dsa, &bn, NULL);
+ if (!BN_print(bio, bn)) {
+ m2_PyErr_Msg(PyExc_RuntimeError);
BIO_free(bio);
DSA_free(dsa);
return NULL;
}
BIO_get_mem_ptr(bio, &bptr);
- ret = PyString_FromStringAndSize(bptr->data, bptr->length);
- BIO_set_close(bio, BIO_CLOSE);
+
+ ret = PyBytes_FromStringAndSize(bptr->data, bptr->length);
+
+ (void)BIO_set_close(bio, BIO_CLOSE);
BIO_free(bio);
DSA_free(dsa);
+ return ret;
break;
-
+
default:
- PyErr_SetString(PyExc_ValueError, "unsupported key type");
+ PyErr_SetString(_evp_err, "unsupported key type");
return NULL;
}
-
- return ret;
}
-
%}
-
diff --git a/SWIG/_lib.h b/SWIG/_lib.h
index b53bc2a..e8a8645 100644
--- a/SWIG/_lib.h
+++ b/SWIG/_lib.h
@@ -1,11 +1,7 @@
/* Copyright (c) 1999 Ng Pheng Siong. All rights reserved. */
-/* $Id: _lib.h 593 2007-10-12 21:46:34Z heikki $ */
+/* $Id$ */
-#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
-typedef int Py_ssize_t;
-#define PY_SSIZE_T_MAX INT_MAX
-#define PY_SSIZE_T_MIN INT_MIN
-#endif
+#include <openssl/bn.h>
typedef struct _blob {
unsigned char *data;
@@ -20,7 +16,13 @@ static int m2_PyObject_AsReadBufferInt(PyObject *obj, const void **buffer,
int *buffer_len);
static int m2_PyString_AsStringAndSizeInt(PyObject *obj, char **s, int *len);
-void gen_callback(int p, int n, void *arg);
+static BIGNUM* m2_PyObject_AsBIGNUM(PyObject* value, PyObject* _py_exc) ;
+
+/* Always use these two together, to correctly handle non-memoryview objects. */
+static int m2_PyObject_GetBufferInt(PyObject *obj, Py_buffer *view, int flags);
+static void m2_PyBuffer_Release(PyObject *obj, Py_buffer *view);
+
+int bn_gencb_callback(int p, int n, BN_GENCB *gencb);
int passphrase_callback(char *buf, int num, int v, void *userdata);
void lib_init(void);
diff --git a/SWIG/_lib.i b/SWIG/_lib.i
index 42dc180..c84b800 100644
--- a/SWIG/_lib.i
+++ b/SWIG/_lib.i
@@ -1,19 +1,85 @@
/* Copyright (c) 1999-2004 Ng Pheng Siong. All rights reserved. */
-/* $Id: _lib.i 695 2009-07-24 06:37:01Z heikki $ */
+/* $Id$ */
%{
+#include <openssl/bn.h>
#include <openssl/dh.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/rsa.h>
#include <openssl/ssl.h>
#include <openssl/x509.h>
+#include <openssl/x509_vfy.h>
#include <ceval.h>
+%}
+
+/* OpenSSL 1.1 compatibility shim */
+%include _lib11_compat.i
+
+/* Python 3 compatibility shim */
+%include _py3k_compat.i
+
+%{
+/* OpenSSL 1.0.2 copmatbility shim */
+#if OPENSSL_VERSION_NUMBER < 0x10002000L
+typedef void (*OPENSSL_sk_freefunc)(void *);
+typedef void *(*OPENSSL_sk_copyfunc)(const void *);
+typedef struct stack_st OPENSSL_STACK;
+
+# define MIN_NODES 4
+# define sk_deep_copy OPENSSL_sk_deep_copy
+
+void OPENSSL_sk_free(OPENSSL_STACK *st)
+{
+ if (st == NULL)
+ return;
+ OPENSSL_free(st->data);
+ OPENSSL_free(st);
+}
+
+OPENSSL_STACK *OPENSSL_sk_deep_copy(const OPENSSL_STACK *sk,
+ OPENSSL_sk_copyfunc copy_func,
+ OPENSSL_sk_freefunc free_func)
+{
+ OPENSSL_STACK *ret;
+ int i;
+
+ if (sk->num < 0)
+ return NULL;
+
+ if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL)
+ return NULL;
+
+ /* direct structure assignment */
+ *ret = *sk;
+
+ ret->num_alloc = sk->num > MIN_NODES ? (size_t)sk->num : MIN_NODES;
+ ret->data = OPENSSL_zalloc(sizeof(*ret->data) * ret->num_alloc);
+ if (ret->data == NULL) {
+ OPENSSL_free(ret);
+ return NULL;
+ }
+
+ for (i = 0; i < ret->num; ++i) {
+ if (sk->data[i] == NULL)
+ continue;
+ if ((ret->data[i] = copy_func(sk->data[i])) == NULL) {
+ while (--i >= 0)
+ if (ret->data[i] != NULL)
+ free_func((void *)ret->data[i]);
+ OPENSSL_sk_free(ret);
+ return NULL;
+ }
+ }
+ return ret;
+}
+#endif /* OpenSSL 1.0.2 copmatbility shim */
+
/* Blob interface. Deprecated. */
Blob *blob_new(int len, const char *errmsg) {
-
+
Blob *blob;
if (!(blob=(Blob *)PyMem_Malloc(sizeof(Blob)))){
PyErr_SetString(PyExc_MemoryError, errmsg);
@@ -47,9 +113,15 @@ void blob_free(Blob *blob) {
/* Python helpers. */
%}
+%ignore PyObject_CheckBuffer;
+%ignore PyObject_GetBuffer;
+%ignore PyBuffer_Release;
%ignore m2_PyObject_AsReadBufferInt;
+%ignore m2_PyObject_GetBufferInt;
+%ignore m2_PyBuffer_Release;
%ignore m2_PyString_AsStringAndSizeInt;
%{
+
static int
m2_PyObject_AsReadBufferInt(PyObject *obj, const void **buffer,
int *buffer_len)
@@ -68,13 +140,63 @@ m2_PyObject_AsReadBufferInt(PyObject *obj, const void **buffer,
return 0;
}
+static int m2_PyObject_GetBufferInt(PyObject *obj, Py_buffer *view, int flags)
+{
+ int ret;
+
+ if (PyObject_CheckBuffer(obj))
+ ret = PyObject_GetBuffer(obj, view, flags);
+ else {
+ const void *buf;
+
+ ret = PyObject_AsReadBuffer(obj, &buf, &view->len);
+ if (ret == 0)
+ view->buf = (void *)buf;
+ }
+ if (ret)
+ return ret;
+ if (view->len > INT_MAX) {
+ PyErr_SetString(PyExc_ValueError, "object too large");
+ m2_PyBuffer_Release(obj, view);
+ return -1;
+ }
+
+ return 0;
+}
+
+static BIGNUM*
+m2_PyObject_AsBIGNUM(PyObject* value, PyObject* _py_exc)
+{
+ BIGNUM* bn;
+ const void* vbuf;
+ int vlen = 0;
+
+ if (m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
+ return NULL;
+
+ if (!(bn = BN_mpi2bn((unsigned char *)vbuf, vlen, NULL))) {
+ PyErr_SetString(_py_exc, ERR_reason_error_string(ERR_get_error()));
+ return NULL;
+ }
+
+ return bn;
+}
+
+static void m2_PyBuffer_Release(PyObject *obj, Py_buffer *view)
+{
+ if (PyObject_CheckBuffer(obj))
+ PyBuffer_Release(view);
+ /* else do nothing, view->buf comes from PyObject_AsReadBuffer */
+}
+
static int
m2_PyString_AsStringAndSizeInt(PyObject *obj, char **s, int *len)
{
int ret;
Py_ssize_t len2;
- ret = PyString_AsStringAndSize(obj, s, &len2);
+ ret = PyBytes_AsStringAndSize(obj, s, &len2);
+
if (ret)
return ret;
if (len2 > INT_MAX) {
@@ -85,8 +207,46 @@ m2_PyString_AsStringAndSizeInt(PyObject *obj, char **s, int *len)
return 0;
}
+/* Works as PyFile_Name, but always returns a new object. */
+PyObject *m2_PyFile_Name(PyObject *pyfile) {
+ PyObject *out = NULL;
+#if PY_MAJOR_VERSION >= 3
+ out = PyObject_GetAttrString(pyfile, "name");
+#else
+ out = PyFile_Name(pyfile);
+ Py_XINCREF(out);
+#endif
+ return out;
+}
+
+/* Yes, __FUNCTION__ is a non-standard symbol, but it is supported by
+ * both gcc and MSVC. */
+#define m2_PyErr_Msg(type) m2_PyErr_Msg_Caller(type, (const char*) __FUNCTION__)
+
+static void m2_PyErr_Msg_Caller(PyObject *err_type, const char* caller) {
+ const char *err_reason;
+ const char *data;
+ int flags;
+ /* This max size of a (longer than ours) OpenSSL error string is hardcoded
+ * in OpenSSL's crypto/err/err_prn.c:ERR_print_errors_cb() */
+ char err_msg[4096];
+ unsigned long err_code = ERR_get_error_line_data(NULL, NULL, &data, &flags);
+
+ if (err_code != 0) {
+ err_reason = ERR_reason_error_string(err_code);
+ if (data && (flags & ERR_TXT_STRING))
+ snprintf(err_msg, sizeof(err_msg), "%s (%s)", err_reason, data);
+ else
+ snprintf(err_msg, sizeof(err_msg), "%s", err_reason);
+
+ PyErr_SetString(err_type, err_msg);
+ } else {
+ PyErr_Format(err_type, "Unknown error in function %s.", caller);
+ }
+}
+
-/* C callbacks invoked by OpenSSL; these in turn call back into
+/* C callbacks invoked by OpenSSL; these in turn call back into
Python. */
int ssl_verify_callback(int ok, X509_STORE_CTX *ctx) {
@@ -100,6 +260,7 @@ int ssl_verify_callback(int ok, X509_STORE_CTX *ctx) {
int cret;
int new_style_callback = 0, warning_raised_exception=0;
PyGILState_STATE gilstate;
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
ssl = (SSL *)X509_STORE_CTX_get_app_data(ctx);
@@ -117,7 +278,7 @@ int ssl_verify_callback(int ok, X509_STORE_CTX *ctx) {
PyCodeObject *code = (PyCodeObject *) PyFunction_GetCode(ssl_verify_cb_func);
if (code && code->co_argcount == 2) { /* XXX Python internals */
new_style_callback = 1;
- }
+ }
} else {
/* XXX There are lots of other callable types, but we will assume
* XXX that any other type of callable uses the new style callback,
@@ -125,30 +286,34 @@ int ssl_verify_callback(int ok, X509_STORE_CTX *ctx) {
*/
new_style_callback = 1;
}
-
+
if (new_style_callback) {
- PyObject *x509mod = PyDict_GetItemString(PyImport_GetModuleDict(), "M2Crypto.X509");
+ PyObject *x509mod;
+
+ x509mod = PyDict_GetItemString(PyImport_GetModuleDict(), "M2Crypto.X509");
_klass = PyObject_GetAttrString(x509mod, "X509_Store_Context");
-
+
_x509_store_ctx_swigptr = SWIG_NewPointerObj((void *)ctx, SWIGTYPE_p_X509_STORE_CTX, 0);
_x509_store_ctx_obj = Py_BuildValue("(Oi)", _x509_store_ctx_swigptr, 0);
- _x509_store_ctx_inst = PyInstance_New(_klass, _x509_store_ctx_obj, NULL);
+
+ _x509_store_ctx_inst = PyObject_CallObject(_klass, _x509_store_ctx_obj);
+
argv = Py_BuildValue("(iO)", ok, _x509_store_ctx_inst);
} else {
if (PyErr_Warn(PyExc_DeprecationWarning, "Old style callback, use cb_func(ok, store) instead")) {
warning_raised_exception = 1;
}
-
+
x509 = X509_STORE_CTX_get_current_cert(ctx);
errnum = X509_STORE_CTX_get_error(ctx);
errdepth = X509_STORE_CTX_get_error_depth(ctx);
-
- ssl = (SSL *)X509_STORE_CTX_get_app_data(ctx);
+
+ ssl = (SSL *)X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
ssl_ctx = SSL_get_SSL_CTX(ssl);
-
+
_x509 = SWIG_NewPointerObj((void *)x509, SWIGTYPE_p_X509, 0);
_ssl_ctx = SWIG_NewPointerObj((void *)ssl_ctx, SWIGTYPE_p_SSL_CTX, 0);
- argv = Py_BuildValue("(OOiii)", _ssl_ctx, _x509, errnum, errdepth, ok);
+ argv = Py_BuildValue("(OOiii)", _ssl_ctx, _x509, errnum, errdepth, ok);
}
if (!warning_raised_exception) {
@@ -161,9 +326,10 @@ int ssl_verify_callback(int ok, X509_STORE_CTX *ctx) {
/* Got an exception in PyEval_CallObject(), let's fail verification
* to be safe.
*/
- cret = 0;
+ cret = 0;
} else {
- cret = (int)PyInt_AsLong(ret);
+ /* FIXME This is possibly problematic if ret > MAXINT */
+ cret = (int)PyLong_AsLong(ret);
}
Py_XDECREF(ret);
Py_XDECREF(argv);
@@ -182,15 +348,59 @@ int ssl_verify_callback(int ok, X509_STORE_CTX *ctx) {
return cret;
}
+int x509_store_verify_callback(int ok, X509_STORE_CTX *ctx) {
+ PyGILState_STATE gilstate;
+ PyObject *argv, *ret;
+ PyObject *_x509_store_ctx_swigptr=0, *_x509_store_ctx_obj=0, *_x509_store_ctx_inst=0, *_klass=0;
+ int cret;
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+ PyObject *x509mod;
+
+
+ gilstate = PyGILState_Ensure();
+
+ /* Below, handle only what is called 'new style callback' in ssl_verify_callback().
+ TODO: does 'old style callback' exist any more? */
+ x509mod = PyDict_GetItemString(PyImport_GetModuleDict(), "M2Crypto.X509");
+ _klass = PyObject_GetAttrString(x509mod, "X509_Store_Context");
+ _x509_store_ctx_swigptr = SWIG_NewPointerObj((void *)ctx, SWIGTYPE_p_X509_STORE_CTX, 0);
+ _x509_store_ctx_obj = Py_BuildValue("(Oi)", _x509_store_ctx_swigptr, 0);
+
+ _x509_store_ctx_inst = PyObject_CallObject(_klass, _x509_store_ctx_obj);
+
+ argv = Py_BuildValue("(iO)", ok, _x509_store_ctx_inst);
+
+ ret = PyEval_CallObject(x509_store_verify_cb_func, argv);
+ if (!ret) {
+ /* Got an exception in PyEval_CallObject(), let's fail verification
+ * to be safe.
+ */
+ cret = 0;
+ } else {
+ cret = (int)PyInt_AsLong(ret);
+ }
+
+ Py_XDECREF(ret);
+ Py_XDECREF(argv);
+ Py_XDECREF(_x509_store_ctx_inst);
+ Py_XDECREF(_x509_store_ctx_obj);
+ Py_XDECREF(_x509_store_ctx_swigptr);
+ Py_XDECREF(_klass);
+
+ PyGILState_Release(gilstate);
+ return cret;
+}
+
void ssl_info_callback(const SSL *s, int where, int ret) {
PyObject *argv, *retval, *_SSL;
PyGILState_STATE gilstate;
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
gilstate = PyGILState_Ensure();
_SSL = SWIG_NewPointerObj((void *)s, SWIGTYPE_p_SSL, 0);
argv = Py_BuildValue("(iiO)", where, ret, _SSL);
-
+
retval = PyEval_CallObject(ssl_info_cb_func, argv);
Py_XDECREF(retval);
@@ -204,6 +414,7 @@ DH *ssl_set_tmp_dh_callback(SSL *ssl, int is_export, int keylength) {
PyObject *argv, *ret, *_ssl;
DH *dh;
PyGILState_STATE gilstate;
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
gilstate = PyGILState_Ensure();
@@ -227,6 +438,7 @@ RSA *ssl_set_tmp_rsa_callback(SSL *ssl, int is_export, int keylength) {
PyObject *argv, *ret, *_ssl;
RSA *rsa;
PyGILState_STATE gilstate;
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
gilstate = PyGILState_Ensure();
@@ -246,17 +458,18 @@ RSA *ssl_set_tmp_rsa_callback(SSL *ssl, int is_export, int keylength) {
return rsa;
}
-void gen_callback(int p, int n, void *arg) {
+/* Universal callback for dh_generate_parameters,
+ * dsa_generate_parametersm, and rsa_generate_key */
+int bn_gencb_callback(int p, int n, BN_GENCB *gencb) {
PyObject *argv, *ret, *cbfunc;
-
- PyGILState_STATE gilstate;
- gilstate = PyGILState_Ensure();
- cbfunc = (PyObject *)arg;
+
+ cbfunc = (PyObject *)BN_GENCB_get_arg(gencb);
argv = Py_BuildValue("(ii)", p, n);
ret = PyEval_CallObject(cbfunc, argv);
+ PyErr_Clear();
Py_DECREF(argv);
Py_XDECREF(ret);
- PyGILState_Release(gilstate);
+ return 1;
}
int passphrase_callback(char *buf, int num, int v, void *arg) {
@@ -269,20 +482,25 @@ int passphrase_callback(char *buf, int num, int v, void *arg) {
gilstate = PyGILState_Ensure();
cbfunc = (PyObject *)arg;
argv = Py_BuildValue("(i)", v);
+ /* PyEval_CallObject sets exception, if needed. */
ret = PyEval_CallObject(cbfunc, argv);
Py_DECREF(argv);
if (ret == NULL) {
PyGILState_Release(gilstate);
return -1;
}
- if (!PyString_Check(ret)) {
+
+ if (!PyBytes_Check(ret)) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "Result of callback is not bytes().");
Py_DECREF(ret);
PyGILState_Release(gilstate);
return -1;
}
- if ((len = PyString_Size(ret)) > num)
+ if ((len = PyBytes_Size(ret)) > num)
len = num;
- str = PyString_AsString(ret);
+ str = PyBytes_AsString(ret);
+
for (i = 0; i < len; i++)
buf[i] = str[i];
Py_DECREF(ret);
@@ -292,34 +510,38 @@ int passphrase_callback(char *buf, int num, int v, void *arg) {
%}
%inline %{
+
void lib_init() {
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
SSLeay_add_all_algorithms();
ERR_load_ERR_strings();
+#endif
}
-/* Bignum routines that aren't not numerous enough to
+/* Bignum routines that aren't not numerous enough to
warrant a separate file. */
-PyObject *bn_to_mpi(BIGNUM *bn) {
- int len;
+PyObject *bn_to_mpi(const BIGNUM *bn) {
+ int len = 0;
unsigned char *mpi;
- PyObject *pyo;
+ PyObject *pyo;
len = BN_bn2mpi(bn, NULL);
if (!(mpi=(unsigned char *)PyMem_Malloc(len))) {
- PyErr_SetString(PyExc_RuntimeError,
- ERR_error_string(ERR_get_error(), NULL));
+ m2_PyErr_Msg(PyExc_MemoryError);
return NULL;
}
len=BN_bn2mpi(bn, mpi);
- pyo=PyString_FromStringAndSize((const char *)mpi, len);
+
+ pyo=PyBytes_FromStringAndSize((const char *)mpi, len);
+
PyMem_Free(mpi);
return pyo;
}
-BIGNUM *mpi_to_bn(PyObject *value) {
+const BIGNUM *mpi_to_bn(PyObject *value) {
const void *vbuf;
- int vlen;
+ int vlen = 0;
if (m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
return NULL;
@@ -328,9 +550,9 @@ BIGNUM *mpi_to_bn(PyObject *value) {
}
PyObject *bn_to_bin(BIGNUM *bn) {
- int len;
+ int len = 0;
unsigned char *bin;
- PyObject *pyo;
+ PyObject *pyo;
len = BN_num_bytes(bn);
if (!(bin=(unsigned char *)PyMem_Malloc(len))) {
@@ -338,14 +560,16 @@ PyObject *bn_to_bin(BIGNUM *bn) {
return NULL;
}
BN_bn2bin(bn, bin);
- pyo=PyString_FromStringAndSize((const char *)bin, len);
+
+ pyo=PyBytes_FromStringAndSize((const char *)bin, len);
+
PyMem_Free(bin);
return pyo;
}
-BIGNUM *bin_to_bn(PyObject *value) {
+const BIGNUM *bin_to_bn(PyObject *value) {
const void *vbuf;
- int vlen;
+ int vlen = 0;
if (m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
return NULL;
@@ -355,25 +579,26 @@ BIGNUM *bin_to_bn(PyObject *value) {
PyObject *bn_to_hex(BIGNUM *bn) {
char *hex;
- PyObject *pyo;
- Py_ssize_t len;
+ PyObject *pyo;
+ Py_ssize_t len = 0;
hex = BN_bn2hex(bn);
if (!hex) {
- PyErr_SetString(PyExc_RuntimeError,
- ERR_error_string(ERR_get_error(), NULL));
+ m2_PyErr_Msg(PyExc_RuntimeError);
OPENSSL_free(hex);
- return NULL;
+ return NULL;
}
len = strlen(hex);
- pyo=PyString_FromStringAndSize(hex, len);
+
+ pyo=PyBytes_FromStringAndSize(hex, len);
+
OPENSSL_free(hex);
return pyo;
}
BIGNUM *hex_to_bn(PyObject *value) {
const void *vbuf;
- Py_ssize_t vlen;
+ Py_ssize_t vlen = 0;
BIGNUM *bn;
if (PyObject_AsReadBuffer(value, &vbuf, &vlen) == -1)
@@ -384,8 +609,7 @@ BIGNUM *hex_to_bn(PyObject *value) {
return NULL;
}
if (BN_hex2bn(&bn, (const char *)vbuf) <= 0) {
- PyErr_SetString(PyExc_RuntimeError,
- ERR_error_string(ERR_get_error(), NULL));
+ m2_PyErr_Msg(PyExc_RuntimeError);
BN_free(bn);
return NULL;
}
@@ -394,7 +618,7 @@ BIGNUM *hex_to_bn(PyObject *value) {
BIGNUM *dec_to_bn(PyObject *value) {
const void *vbuf;
- Py_ssize_t vlen;
+ Py_ssize_t vlen = 0;
BIGNUM *bn;
if (PyObject_AsReadBuffer(value, &vbuf, &vlen) == -1)
@@ -405,8 +629,7 @@ BIGNUM *dec_to_bn(PyObject *value) {
return NULL;
}
if ((BN_dec2bn(&bn, (const char *)vbuf) <= 0)) {
- PyErr_SetString(PyExc_RuntimeError,
- ERR_error_string(ERR_get_error(), NULL));
+ m2_PyErr_Msg(PyExc_RuntimeError);
BN_free(bn);
return NULL;
}
@@ -418,23 +641,26 @@ BIGNUM *dec_to_bn(PyObject *value) {
/* Various useful typemaps. */
%typemap(in) Blob * {
- Py_ssize_t len;
+ Py_ssize_t len = 0;
- if (!PyString_Check($input)) {
+ if (!PyBytes_Check($input)) {
PyErr_SetString(PyExc_TypeError, "expected PyString");
return NULL;
}
- len=PyString_Size($input);
+ len=PyBytes_Size($input);
+
if (len > INT_MAX) {
PyErr_SetString(PyExc_ValueError, "object too large");
- return -1;
+ return NULL;
}
$1=(Blob *)PyMem_Malloc(sizeof(Blob));
if (!$1) {
PyErr_SetString(PyExc_MemoryError, "malloc Blob");
return NULL;
}
- $1->data=(unsigned char *)PyString_AsString($input);
+
+ $1->data=(unsigned char *)PyBytes_AsString($input);
+
$1->len=len;
}
@@ -443,20 +669,14 @@ BIGNUM *dec_to_bn(PyObject *value) {
Py_INCREF(Py_None);
$result=Py_None;
} else {
- $result=PyString_FromStringAndSize((const char *)$1->data, $1->len);
+
+ $result=PyBytes_FromStringAndSize((const char *)$1->data, $1->len);
+
PyMem_Free($1->data);
PyMem_Free($1);
}
}
-%typemap(in) FILE * {
- if (!PyFile_Check($input)) {
- PyErr_SetString(PyExc_TypeError, "expected PyFile");
- return NULL;
- }
- $1=PyFile_AsFile($input);
-}
-
%typemap(in) PyObject *pyfunc {
if (!PyCallable_Check($input)) {
PyErr_SetString(PyExc_TypeError, "expected PyCallable");
@@ -466,7 +686,8 @@ BIGNUM *dec_to_bn(PyObject *value) {
}
%typemap(in) PyObject *pyblob {
- if (!PyString_Check($input)) {
+ if (!PyBytes_Check($input)) {
+
PyErr_SetString(PyExc_TypeError, "expected PyString");
return NULL;
}
@@ -482,7 +703,7 @@ BIGNUM *dec_to_bn(PyObject *value) {
}
%typemap(out) int {
- $result=PyInt_FromLong($1);
+ $result=PyLong_FromLong($1);
if (PyErr_Occurred()) SWIG_fail;
}
@@ -493,9 +714,6 @@ BIGNUM *dec_to_bn(PyObject *value) {
/* A bunch of "straight-thru" functions. */
-%rename(err_print_errors_fp) ERR_print_errors_fp;
-%threadallow ERR_print_errors_fp;
-extern void ERR_print_errors_fp(FILE *);
%rename(err_print_errors) ERR_print_errors;
%threadallow ERR_print_errors;
extern void ERR_print_errors(BIO *);
diff --git a/SWIG/_lib11_compat.i b/SWIG/_lib11_compat.i
new file mode 100644
index 0000000..1ec42dd
--- /dev/null
+++ b/SWIG/_lib11_compat.i
@@ -0,0 +1,458 @@
+/*
+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+%{
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+
+#include <string.h>
+#include <openssl/engine.h>
+
+# define OPENSSL_zalloc(num) \
+ CRYPTO_zalloc(num, __FILE__, __LINE__)
+
+static void *CRYPTO_zalloc(size_t num, const char *file, int line)
+{
+ void *ret = CRYPTO_malloc(num, file, line);
+ if (ret != NULL)
+ memset(ret, 0, num);
+ return ret;
+}
+
+#include <openssl/bn.h>
+
+#ifndef BN_F_BN_GENCB_NEW
+# define BN_F_BN_GENCB_NEW 143
+#endif
+
+# define BN_GENCB_get_arg(gencb) ((gencb)->arg)
+
+BN_GENCB *BN_GENCB_new(void)
+{
+ BN_GENCB *ret;
+
+ if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL) {
+ BNerr(BN_F_BN_GENCB_NEW, ERR_R_MALLOC_FAILURE);
+ return (NULL);
+ }
+
+ return ret;
+}
+
+void BN_GENCB_free(BN_GENCB *cb)
+{
+ if (cb == NULL)
+ return;
+ OPENSSL_free(cb);
+}
+
+
+int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d)
+{
+ /* If the fields n and e in r are NULL, the corresponding input
+ * parameters MUST be non-NULL for n and e. d may be
+ * left NULL (in case only the public key is used).
+ */
+ if ((r->n == NULL && n == NULL)
+ || (r->e == NULL && e == NULL))
+ return 0;
+
+ if (n != NULL) {
+ BN_free(r->n);
+ r->n = n;
+ }
+ if (e != NULL) {
+ BN_free(r->e);
+ r->e = e;
+ }
+ if (d != NULL) {
+ BN_free(r->d);
+ r->d = d;
+ }
+
+ return 1;
+}
+
+int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q)
+{
+ /* If the fields p and q in r are NULL, the corresponding input
+ * parameters MUST be non-NULL.
+ */
+ if ((r->p == NULL && p == NULL)
+ || (r->q == NULL && q == NULL))
+ return 0;
+
+ if (p != NULL) {
+ BN_free(r->p);
+ r->p = p;
+ }
+ if (q != NULL) {
+ BN_free(r->q);
+ r->q = q;
+ }
+
+ return 1;
+}
+
+int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp)
+{
+ /* If the fields dmp1, dmq1 and iqmp in r are NULL, the corresponding input
+ * parameters MUST be non-NULL.
+ */
+ if ((r->dmp1 == NULL && dmp1 == NULL)
+ || (r->dmq1 == NULL && dmq1 == NULL)
+ || (r->iqmp == NULL && iqmp == NULL))
+ return 0;
+
+ if (dmp1 != NULL) {
+ BN_free(r->dmp1);
+ r->dmp1 = dmp1;
+ }
+ if (dmq1 != NULL) {
+ BN_free(r->dmq1);
+ r->dmq1 = dmq1;
+ }
+ if (iqmp != NULL) {
+ BN_free(r->iqmp);
+ r->iqmp = iqmp;
+ }
+
+ return 1;
+}
+
+void RSA_get0_key(const RSA *r,
+ const BIGNUM **n, const BIGNUM **e, const BIGNUM **d)
+{
+ if (n != NULL)
+ *n = r->n;
+ if (e != NULL)
+ *e = r->e;
+ if (d != NULL)
+ *d = r->d;
+}
+
+void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q)
+{
+ if (p != NULL)
+ *p = r->p;
+ if (q != NULL)
+ *q = r->q;
+}
+
+void RSA_get0_crt_params(const RSA *r,
+ const BIGNUM **dmp1, const BIGNUM **dmq1,
+ const BIGNUM **iqmp)
+{
+ if (dmp1 != NULL)
+ *dmp1 = r->dmp1;
+ if (dmq1 != NULL)
+ *dmq1 = r->dmq1;
+ if (iqmp != NULL)
+ *iqmp = r->iqmp;
+}
+
+void DSA_get0_pqg(const DSA *d,
+ const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
+{
+ if (p != NULL)
+ *p = d->p;
+ if (q != NULL)
+ *q = d->q;
+ if (g != NULL)
+ *g = d->g;
+}
+
+int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g)
+{
+ /* If the fields p, q and g in d are NULL, the corresponding input
+ * parameters MUST be non-NULL.
+ */
+ if ((d->p == NULL && p == NULL)
+ || (d->q == NULL && q == NULL)
+ || (d->g == NULL && g == NULL))
+ return 0;
+
+ if (p != NULL) {
+ BN_free(d->p);
+ d->p = p;
+ }
+ if (q != NULL) {
+ BN_free(d->q);
+ d->q = q;
+ }
+ if (g != NULL) {
+ BN_free(d->g);
+ d->g = g;
+ }
+
+ return 1;
+}
+
+void DSA_get0_key(const DSA *d,
+ const BIGNUM **pub_key, const BIGNUM **priv_key)
+{
+ if (pub_key != NULL)
+ *pub_key = d->pub_key;
+ if (priv_key != NULL)
+ *priv_key = d->priv_key;
+}
+
+int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key)
+{
+ /* If the field pub_key in d is NULL, the corresponding input
+ * parameters MUST be non-NULL. The priv_key field may
+ * be left NULL.
+ */
+ if (d->pub_key == NULL && pub_key == NULL)
+ return 0;
+
+ if (pub_key != NULL) {
+ BN_free(d->pub_key);
+ d->pub_key = pub_key;
+ }
+ if (priv_key != NULL) {
+ BN_free(d->priv_key);
+ d->priv_key = priv_key;
+ }
+
+ return 1;
+}
+
+void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
+{
+ if (pr != NULL)
+ *pr = sig->r;
+ if (ps != NULL)
+ *ps = sig->s;
+}
+
+int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s)
+{
+ if (r == NULL || s == NULL)
+ return 0;
+ BN_clear_free(sig->r);
+ BN_clear_free(sig->s);
+ sig->r = r;
+ sig->s = s;
+ return 1;
+}
+
+void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
+{
+ if (pr != NULL)
+ *pr = sig->r;
+ if (ps != NULL)
+ *ps = sig->s;
+}
+
+int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s)
+{
+ if (r == NULL || s == NULL)
+ return 0;
+ BN_clear_free(sig->r);
+ BN_clear_free(sig->s);
+ sig->r = r;
+ sig->s = s;
+ return 1;
+}
+
+void DH_get0_pqg(const DH *dh,
+ const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
+{
+ if (p != NULL)
+ *p = dh->p;
+ if (q != NULL)
+ *q = dh->q;
+ if (g != NULL)
+ *g = dh->g;
+}
+
+int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g)
+{
+ /* If the fields p and g in d are NULL, the corresponding input
+ * parameters MUST be non-NULL. q may remain NULL.
+ */
+ if ((dh->p == NULL && p == NULL)
+ || (dh->g == NULL && g == NULL))
+ return 0;
+
+ if (p != NULL) {
+ BN_free(dh->p);
+ dh->p = p;
+ }
+ if (q != NULL) {
+ BN_free(dh->q);
+ dh->q = q;
+ }
+ if (g != NULL) {
+ BN_free(dh->g);
+ dh->g = g;
+ }
+
+ if (q != NULL) {
+ dh->length = BN_num_bits(q);
+ }
+
+ return 1;
+}
+
+void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key)
+{
+ if (pub_key != NULL)
+ *pub_key = dh->pub_key;
+ if (priv_key != NULL)
+ *priv_key = dh->priv_key;
+}
+
+int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key)
+{
+ /* If the field pub_key in dh is NULL, the corresponding input
+ * parameters MUST be non-NULL. The priv_key field may
+ * be left NULL.
+ */
+ if (dh->pub_key == NULL && pub_key == NULL)
+ return 0;
+
+ if (pub_key != NULL) {
+ BN_free(dh->pub_key);
+ dh->pub_key = pub_key;
+ }
+ if (priv_key != NULL) {
+ BN_free(dh->priv_key);
+ dh->priv_key = priv_key;
+ }
+
+ return 1;
+}
+
+int DH_set_length(DH *dh, long length)
+{
+ dh->length = length;
+ return 1;
+}
+
+const unsigned char *EVP_CIPHER_CTX_iv(const EVP_CIPHER_CTX *ctx)
+{
+ return ctx->iv;
+}
+
+unsigned char *EVP_CIPHER_CTX_iv_noconst(EVP_CIPHER_CTX *ctx)
+{
+ return ctx->iv;
+}
+
+EVP_MD_CTX *EVP_MD_CTX_new(void)
+{
+ return OPENSSL_zalloc(sizeof(EVP_MD_CTX));
+}
+
+void EVP_MD_CTX_free(EVP_MD_CTX *ctx)
+{
+ EVP_MD_CTX_cleanup(ctx);
+ OPENSSL_free(ctx);
+}
+
+int RSA_size(const RSA* rsa) {
+ /* BIGNUM* n = NULL;
+ RSA_get0_key(rsa, n, NULL, NULL); */
+ return BN_num_bytes(rsa->n);
+}
+
+RSA_METHOD *RSA_meth_dup(const RSA_METHOD *meth)
+{
+ RSA_METHOD *ret;
+
+ ret = OPENSSL_malloc(sizeof(RSA_METHOD));
+
+ if (ret != NULL) {
+ memcpy(ret, meth, sizeof(*meth));
+ ret->name = OPENSSL_strdup(meth->name);
+ if (ret->name == NULL) {
+ OPENSSL_free(ret);
+ return NULL;
+ }
+ }
+
+ return ret;
+}
+
+int RSA_meth_set1_name(RSA_METHOD *meth, const char *name)
+{
+ char *tmpname;
+
+ tmpname = OPENSSL_strdup(name);
+ if (tmpname == NULL) {
+ return 0;
+ }
+
+ OPENSSL_free((char *)meth->name);
+ meth->name = tmpname;
+
+ return 1;
+}
+
+int RSA_meth_set_priv_enc(RSA_METHOD *meth,
+ int (*priv_enc) (int flen, const unsigned char *from,
+ unsigned char *to, RSA *rsa,
+ int padding))
+{
+ meth->rsa_priv_enc = priv_enc;
+ return 1;
+}
+
+int RSA_meth_set_priv_dec(RSA_METHOD *meth,
+ int (*priv_dec) (int flen, const unsigned char *from,
+ unsigned char *to, RSA *rsa,
+ int padding))
+{
+ meth->rsa_priv_dec = priv_dec;
+ return 1;
+}
+
+int RSA_meth_set_finish(RSA_METHOD *meth, int (*finish) (RSA *rsa))
+{
+ meth->finish = finish;
+ return 1;
+}
+
+void RSA_meth_free(RSA_METHOD *meth)
+{
+ if (meth != NULL) {
+ OPENSSL_free((char *)meth->name);
+ OPENSSL_free(meth);
+ }
+}
+
+int RSA_bits(const RSA *r)
+{
+ return (BN_num_bits(r->n));
+}
+
+RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey)
+{
+ if (pkey->type != EVP_PKEY_RSA) {
+ return NULL;
+ }
+ return pkey->pkey.rsa;
+}
+
+int X509_NAME_get0_der(X509_NAME *nm, const unsigned char **pder,
+ size_t *pderlen)
+{
+ /* Make sure encoding is valid */
+ if (i2d_X509_NAME(nm, NULL) <= 0)
+ return 0;
+ if (pder != NULL)
+ *pder = (unsigned char *)nm->bytes->data;
+ if (pderlen != NULL)
+ *pderlen = nm->bytes->length;
+ return 1;
+}
+
+#endif /* OPENSSL_VERSION_NUMBER */
+%}
diff --git a/SWIG/_m2crypto.def b/SWIG/_m2crypto.def
index 753db2c..3e9d5bc 100644
--- a/SWIG/_m2crypto.def
+++ b/SWIG/_m2crypto.def
@@ -1,2 +1,2 @@
EXPORTS
-init__m2crypto
+init_m2crypto
diff --git a/SWIG/_m2crypto.i b/SWIG/_m2crypto.i
index 3d779a1..e300a10 100644
--- a/SWIG/_m2crypto.i
+++ b/SWIG/_m2crypto.i
@@ -8,17 +8,47 @@
*
*/
-%module(threads=1) _m2crypto
+%module(threads=1) m2crypto
/* We really don't need threadblock (PyGILState_Ensure() etc.) anywhere.
Disable threadallow as well, only enable it for operations likely to
block. */
%nothreadblock;
%nothreadallow;
+#if SWIG_VERSION >= 0x030000
+#define __WCHAR_MAX__ __WCHAR_MAX
+#define __WCHAR_MIN__ __WCHAR_MIN
+#endif
+/* https://gitlab.com/m2crypto/m2crypto/issues/246 */
+%ignore WCHAR_MAX;
+%ignore WCHAR_MIN;
+/* http://swig.10945.n7.nabble.com/SWIG-AsVal-wchar-t-error-td2264.html */
+%{
+int SWIG_AsVal_wchar_t(PyObject *p, wchar_t *c) { return SWIG_OK; }
+PyObject *SWIG_From_wchar_t(wchar_t c) { return SWIG_Py_Void(); }
+%}
+
+%{
+#ifdef _WIN32
+#define _WINSOCKAPI_
+#include <WinSock2.h>
+#include <Windows.h>
+#pragma comment(lib, "Ws2_32")
+typedef unsigned __int64 uint64_t;
+#endif
+%}
+
%{
+#if defined __GNUC__ && __GNUC__ < 5
+#pragma GCC diagnostic ignored "-Wunused-label"
+#pragma GCC diagnostic warning "-Wstrict-prototypes"
+#endif
+
#include <openssl/err.h>
#include <openssl/rand.h>
#include <_lib.h>
+#include <libcrypto-compat.h>
+#include <py3k_compat.h>
#include "compile.h"
@@ -26,22 +56,15 @@ static PyObject *ssl_verify_cb_func;
static PyObject *ssl_info_cb_func;
static PyObject *ssl_set_tmp_dh_cb_func;
static PyObject *ssl_set_tmp_rsa_cb_func;
+static PyObject *x509_store_verify_cb_func;
%}
%include <openssl/opensslv.h>
-#if OPENSSL_VERSION_NUMBER >= 0x0090707fL
-#define CONST const
-#else
-#define CONST
-#endif
-
-#if OPENSSL_VERSION_NUMBER >= 0x0090800fL
-#define CONST098 const
-#else
-#define CONST098
-#endif
/* Bring in STACK_OF macro definition */
+#ifdef _WIN32
+%include <windows.i>
+#endif
%include <openssl/safestack.h>
/* Bring in LHASH_OF macro definition */
@@ -54,6 +77,7 @@ static PyObject *ssl_set_tmp_rsa_cb_func;
#define LHASH_OF(type) struct lhash_st_##type
#endif
+
%include constraints.i
%include _threads.i
%include _lib.i
diff --git a/SWIG/_m2crypto_wrap.c b/SWIG/_m2crypto_wrap.c
new file mode 100644
index 0000000..0f07702
--- /dev/null
+++ b/SWIG/_m2crypto_wrap.c
@@ -0,0 +1,32491 @@
+/* ----------------------------------------------------------------------------
+ * This file was automatically generated by SWIG (http://www.swig.org).
+ * Version 2.0.10
+ *
+ * This file is not intended to be easily readable and contains a number of
+ * coding conventions designed to improve portability and efficiency. Do not make
+ * changes to this file unless you know what you are doing--modify the SWIG
+ * interface file instead.
+ * ----------------------------------------------------------------------------- */
+
+#define SWIGPYTHON
+#define SWIG_PYTHON_THREADS
+#define SWIG_PYTHON_DIRECTOR_NO_VTABLE
+#define SWIGPYTHON_BUILTIN
+
+/* -----------------------------------------------------------------------------
+ * This section contains generic SWIG labels for method/variable
+ * declarations/attributes, and other compiler dependent labels.
+ * ----------------------------------------------------------------------------- */
+
+/* template workaround for compilers that cannot correctly implement the C++ standard */
+#ifndef SWIGTEMPLATEDISAMBIGUATOR
+# if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560)
+# define SWIGTEMPLATEDISAMBIGUATOR template
+# elif defined(__HP_aCC)
+/* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */
+/* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */
+# define SWIGTEMPLATEDISAMBIGUATOR template
+# else
+# define SWIGTEMPLATEDISAMBIGUATOR
+# endif
+#endif
+
+/* inline attribute */
+#ifndef SWIGINLINE
+# if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__))
+# define SWIGINLINE inline
+# else
+# define SWIGINLINE
+# endif
+#endif
+
+/* attribute recognised by some compilers to avoid 'unused' warnings */
+#ifndef SWIGUNUSED
+# if defined(__GNUC__)
+# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+# define SWIGUNUSED __attribute__ ((__unused__))
+# else
+# define SWIGUNUSED
+# endif
+# elif defined(__ICC)
+# define SWIGUNUSED __attribute__ ((__unused__))
+# else
+# define SWIGUNUSED
+# endif
+#endif
+
+#ifndef SWIG_MSC_UNSUPPRESS_4505
+# if defined(_MSC_VER)
+# pragma warning(disable : 4505) /* unreferenced local function has been removed */
+# endif
+#endif
+
+#ifndef SWIGUNUSEDPARM
+# ifdef __cplusplus
+# define SWIGUNUSEDPARM(p)
+# else
+# define SWIGUNUSEDPARM(p) p SWIGUNUSED
+# endif
+#endif
+
+/* internal SWIG method */
+#ifndef SWIGINTERN
+# define SWIGINTERN static SWIGUNUSED
+#endif
+
+/* internal inline SWIG method */
+#ifndef SWIGINTERNINLINE
+# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE
+#endif
+
+/* exporting methods */
+#if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+# ifndef GCC_HASCLASSVISIBILITY
+# define GCC_HASCLASSVISIBILITY
+# endif
+#endif
+
+#ifndef SWIGEXPORT
+# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
+# if defined(STATIC_LINKED)
+# define SWIGEXPORT
+# else
+# define SWIGEXPORT __declspec(dllexport)
+# endif
+# else
+# if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY)
+# define SWIGEXPORT __attribute__ ((visibility("default")))
+# else
+# define SWIGEXPORT
+# endif
+# endif
+#endif
+
+/* calling conventions for Windows */
+#ifndef SWIGSTDCALL
+# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
+# define SWIGSTDCALL __stdcall
+# else
+# define SWIGSTDCALL
+# endif
+#endif
+
+/* Deal with Microsoft's attempt at deprecating C standard runtime functions */
+#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
+# define _CRT_SECURE_NO_DEPRECATE
+#endif
+
+/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */
+#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE)
+# define _SCL_SECURE_NO_DEPRECATE
+#endif
+
+
+
+/* Python.h has to appear first */
+#include <Python.h>
+
+/* -----------------------------------------------------------------------------
+ * swigrun.swg
+ *
+ * This file contains generic C API SWIG runtime support for pointer
+ * type checking.
+ * ----------------------------------------------------------------------------- */
+
+/* This should only be incremented when either the layout of swig_type_info changes,
+ or for whatever reason, the runtime changes incompatibly */
+#define SWIG_RUNTIME_VERSION "4"
+
+/* define SWIG_TYPE_TABLE_NAME as "SWIG_TYPE_TABLE" */
+#ifdef SWIG_TYPE_TABLE
+# define SWIG_QUOTE_STRING(x) #x
+# define SWIG_EXPAND_AND_QUOTE_STRING(x) SWIG_QUOTE_STRING(x)
+# define SWIG_TYPE_TABLE_NAME SWIG_EXPAND_AND_QUOTE_STRING(SWIG_TYPE_TABLE)
+#else
+# define SWIG_TYPE_TABLE_NAME
+#endif
+
+/*
+ You can use the SWIGRUNTIME and SWIGRUNTIMEINLINE macros for
+ creating a static or dynamic library from the SWIG runtime code.
+ In 99.9% of the cases, SWIG just needs to declare them as 'static'.
+
+ But only do this if strictly necessary, ie, if you have problems
+ with your compiler or suchlike.
+*/
+
+#ifndef SWIGRUNTIME
+# define SWIGRUNTIME SWIGINTERN
+#endif
+
+#ifndef SWIGRUNTIMEINLINE
+# define SWIGRUNTIMEINLINE SWIGRUNTIME SWIGINLINE
+#endif
+
+/* Generic buffer size */
+#ifndef SWIG_BUFFER_SIZE
+# define SWIG_BUFFER_SIZE 1024
+#endif
+
+/* Flags for pointer conversions */
+#define SWIG_POINTER_DISOWN 0x1
+#define SWIG_CAST_NEW_MEMORY 0x2
+
+/* Flags for new pointer objects */
+#define SWIG_POINTER_OWN 0x1
+
+
+/*
+ Flags/methods for returning states.
+
+ The SWIG conversion methods, as ConvertPtr, return an integer
+ that tells if the conversion was successful or not. And if not,
+ an error code can be returned (see swigerrors.swg for the codes).
+
+ Use the following macros/flags to set or process the returning
+ states.
+
+ In old versions of SWIG, code such as the following was usually written:
+
+ if (SWIG_ConvertPtr(obj,vptr,ty.flags) != -1) {
+ // success code
+ } else {
+ //fail code
+ }
+
+ Now you can be more explicit:
+
+ int res = SWIG_ConvertPtr(obj,vptr,ty.flags);
+ if (SWIG_IsOK(res)) {
+ // success code
+ } else {
+ // fail code
+ }
+
+ which is the same really, but now you can also do
+
+ Type *ptr;
+ int res = SWIG_ConvertPtr(obj,(void **)(&ptr),ty.flags);
+ if (SWIG_IsOK(res)) {
+ // success code
+ if (SWIG_IsNewObj(res) {
+ ...
+ delete *ptr;
+ } else {
+ ...
+ }
+ } else {
+ // fail code
+ }
+
+ I.e., now SWIG_ConvertPtr can return new objects and you can
+ identify the case and take care of the deallocation. Of course that
+ also requires SWIG_ConvertPtr to return new result values, such as
+
+ int SWIG_ConvertPtr(obj, ptr,...) {
+ if (<obj is ok>) {
+ if (<need new object>) {
+ *ptr = <ptr to new allocated object>;
+ return SWIG_NEWOBJ;
+ } else {
+ *ptr = <ptr to old object>;
+ return SWIG_OLDOBJ;
+ }
+ } else {
+ return SWIG_BADOBJ;
+ }
+ }
+
+ Of course, returning the plain '0(success)/-1(fail)' still works, but you can be
+ more explicit by returning SWIG_BADOBJ, SWIG_ERROR or any of the
+ SWIG errors code.
+
+ Finally, if the SWIG_CASTRANK_MODE is enabled, the result code
+ allows to return the 'cast rank', for example, if you have this
+
+ int food(double)
+ int fooi(int);
+
+ and you call
+
+ food(1) // cast rank '1' (1 -> 1.0)
+ fooi(1) // cast rank '0'
+
+ just use the SWIG_AddCast()/SWIG_CheckState()
+*/
+
+#define SWIG_OK (0)
+#define SWIG_ERROR (-1)
+#define SWIG_IsOK(r) (r >= 0)
+#define SWIG_ArgError(r) ((r != SWIG_ERROR) ? r : SWIG_TypeError)
+
+/* The CastRankLimit says how many bits are used for the cast rank */
+#define SWIG_CASTRANKLIMIT (1 << 8)
+/* The NewMask denotes the object was created (using new/malloc) */
+#define SWIG_NEWOBJMASK (SWIG_CASTRANKLIMIT << 1)
+/* The TmpMask is for in/out typemaps that use temporal objects */
+#define SWIG_TMPOBJMASK (SWIG_NEWOBJMASK << 1)
+/* Simple returning values */
+#define SWIG_BADOBJ (SWIG_ERROR)
+#define SWIG_OLDOBJ (SWIG_OK)
+#define SWIG_NEWOBJ (SWIG_OK | SWIG_NEWOBJMASK)
+#define SWIG_TMPOBJ (SWIG_OK | SWIG_TMPOBJMASK)
+/* Check, add and del mask methods */
+#define SWIG_AddNewMask(r) (SWIG_IsOK(r) ? (r | SWIG_NEWOBJMASK) : r)
+#define SWIG_DelNewMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_NEWOBJMASK) : r)
+#define SWIG_IsNewObj(r) (SWIG_IsOK(r) && (r & SWIG_NEWOBJMASK))
+#define SWIG_AddTmpMask(r) (SWIG_IsOK(r) ? (r | SWIG_TMPOBJMASK) : r)
+#define SWIG_DelTmpMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_TMPOBJMASK) : r)
+#define SWIG_IsTmpObj(r) (SWIG_IsOK(r) && (r & SWIG_TMPOBJMASK))
+
+/* Cast-Rank Mode */
+#if defined(SWIG_CASTRANK_MODE)
+# ifndef SWIG_TypeRank
+# define SWIG_TypeRank unsigned long
+# endif
+# ifndef SWIG_MAXCASTRANK /* Default cast allowed */
+# define SWIG_MAXCASTRANK (2)
+# endif
+# define SWIG_CASTRANKMASK ((SWIG_CASTRANKLIMIT) -1)
+# define SWIG_CastRank(r) (r & SWIG_CASTRANKMASK)
+SWIGINTERNINLINE int SWIG_AddCast(int r) {
+ return SWIG_IsOK(r) ? ((SWIG_CastRank(r) < SWIG_MAXCASTRANK) ? (r + 1) : SWIG_ERROR) : r;
+}
+SWIGINTERNINLINE int SWIG_CheckState(int r) {
+ return SWIG_IsOK(r) ? SWIG_CastRank(r) + 1 : 0;
+}
+#else /* no cast-rank mode */
+# define SWIG_AddCast(r) (r)
+# define SWIG_CheckState(r) (SWIG_IsOK(r) ? 1 : 0)
+#endif
+
+
+#include <string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void *(*swig_converter_func)(void *, int *);
+typedef struct swig_type_info *(*swig_dycast_func)(void **);
+
+/* Structure to store information on one type */
+typedef struct swig_type_info {
+ const char *name; /* mangled name of this type */
+ const char *str; /* human readable name of this type */
+ swig_dycast_func dcast; /* dynamic cast function down a hierarchy */
+ struct swig_cast_info *cast; /* linked list of types that can cast into this type */
+ void *clientdata; /* language specific type data */
+ int owndata; /* flag if the structure owns the clientdata */
+} swig_type_info;
+
+/* Structure to store a type and conversion function used for casting */
+typedef struct swig_cast_info {
+ swig_type_info *type; /* pointer to type that is equivalent to this type */
+ swig_converter_func converter; /* function to cast the void pointers */
+ struct swig_cast_info *next; /* pointer to next cast in linked list */
+ struct swig_cast_info *prev; /* pointer to the previous cast */
+} swig_cast_info;
+
+/* Structure used to store module information
+ * Each module generates one structure like this, and the runtime collects
+ * all of these structures and stores them in a circularly linked list.*/
+typedef struct swig_module_info {
+ swig_type_info **types; /* Array of pointers to swig_type_info structures that are in this module */
+ size_t size; /* Number of types in this module */
+ struct swig_module_info *next; /* Pointer to next element in circularly linked list */
+ swig_type_info **type_initial; /* Array of initially generated type structures */
+ swig_cast_info **cast_initial; /* Array of initially generated casting structures */
+ void *clientdata; /* Language specific module data */
+} swig_module_info;
+
+/*
+ Compare two type names skipping the space characters, therefore
+ "char*" == "char *" and "Class<int>" == "Class<int >", etc.
+
+ Return 0 when the two name types are equivalent, as in
+ strncmp, but skipping ' '.
+*/
+SWIGRUNTIME int
+SWIG_TypeNameComp(const char *f1, const char *l1,
+ const char *f2, const char *l2) {
+ for (;(f1 != l1) && (f2 != l2); ++f1, ++f2) {
+ while ((*f1 == ' ') && (f1 != l1)) ++f1;
+ while ((*f2 == ' ') && (f2 != l2)) ++f2;
+ if (*f1 != *f2) return (*f1 > *f2) ? 1 : -1;
+ }
+ return (int)((l1 - f1) - (l2 - f2));
+}
+
+/*
+ Check type equivalence in a name list like <name1>|<name2>|...
+ Return 0 if equal, -1 if nb < tb, 1 if nb > tb
+*/
+SWIGRUNTIME int
+SWIG_TypeCmp(const char *nb, const char *tb) {
+ int equiv = 1;
+ const char* te = tb + strlen(tb);
+ const char* ne = nb;
+ while (equiv != 0 && *ne) {
+ for (nb = ne; *ne; ++ne) {
+ if (*ne == '|') break;
+ }
+ equiv = SWIG_TypeNameComp(nb, ne, tb, te);
+ if (*ne) ++ne;
+ }
+ return equiv;
+}
+
+/*
+ Check type equivalence in a name list like <name1>|<name2>|...
+ Return 0 if not equal, 1 if equal
+*/
+SWIGRUNTIME int
+SWIG_TypeEquiv(const char *nb, const char *tb) {
+ return SWIG_TypeCmp(nb, tb) == 0 ? 1 : 0;
+}
+
+/*
+ Check the typename
+*/
+SWIGRUNTIME swig_cast_info *
+SWIG_TypeCheck(const char *c, swig_type_info *ty) {
+ if (ty) {
+ swig_cast_info *iter = ty->cast;
+ while (iter) {
+ if (strcmp(iter->type->name, c) == 0) {
+ if (iter == ty->cast)
+ return iter;
+ /* Move iter to the top of the linked list */
+ iter->prev->next = iter->next;
+ if (iter->next)
+ iter->next->prev = iter->prev;
+ iter->next = ty->cast;
+ iter->prev = 0;
+ if (ty->cast) ty->cast->prev = iter;
+ ty->cast = iter;
+ return iter;
+ }
+ iter = iter->next;
+ }
+ }
+ return 0;
+}
+
+/*
+ Identical to SWIG_TypeCheck, except strcmp is replaced with a pointer comparison
+*/
+SWIGRUNTIME swig_cast_info *
+SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *ty) {
+ if (ty) {
+ swig_cast_info *iter = ty->cast;
+ while (iter) {
+ if (iter->type == from) {
+ if (iter == ty->cast)
+ return iter;
+ /* Move iter to the top of the linked list */
+ iter->prev->next = iter->next;
+ if (iter->next)
+ iter->next->prev = iter->prev;
+ iter->next = ty->cast;
+ iter->prev = 0;
+ if (ty->cast) ty->cast->prev = iter;
+ ty->cast = iter;
+ return iter;
+ }
+ iter = iter->next;
+ }
+ }
+ return 0;
+}
+
+/*
+ Cast a pointer up an inheritance hierarchy
+*/
+SWIGRUNTIMEINLINE void *
+SWIG_TypeCast(swig_cast_info *ty, void *ptr, int *newmemory) {
+ return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr, newmemory);
+}
+
+/*
+ Dynamic pointer casting. Down an inheritance hierarchy
+*/
+SWIGRUNTIME swig_type_info *
+SWIG_TypeDynamicCast(swig_type_info *ty, void **ptr) {
+ swig_type_info *lastty = ty;
+ if (!ty || !ty->dcast) return ty;
+ while (ty && (ty->dcast)) {
+ ty = (*ty->dcast)(ptr);
+ if (ty) lastty = ty;
+ }
+ return lastty;
+}
+
+/*
+ Return the name associated with this type
+*/
+SWIGRUNTIMEINLINE const char *
+SWIG_TypeName(const swig_type_info *ty) {
+ return ty->name;
+}
+
+/*
+ Return the pretty name associated with this type,
+ that is an unmangled type name in a form presentable to the user.
+*/
+SWIGRUNTIME const char *
+SWIG_TypePrettyName(const swig_type_info *type) {
+ /* The "str" field contains the equivalent pretty names of the
+ type, separated by vertical-bar characters. We choose
+ to print the last name, as it is often (?) the most
+ specific. */
+ if (!type) return NULL;
+ if (type->str != NULL) {
+ const char *last_name = type->str;
+ const char *s;
+ for (s = type->str; *s; s++)
+ if (*s == '|') last_name = s+1;
+ return last_name;
+ }
+ else
+ return type->name;
+}
+
+/*
+ Set the clientdata field for a type
+*/
+SWIGRUNTIME void
+SWIG_TypeClientData(swig_type_info *ti, void *clientdata) {
+ swig_cast_info *cast = ti->cast;
+ /* if (ti->clientdata == clientdata) return; */
+ ti->clientdata = clientdata;
+
+ while (cast) {
+ if (!cast->converter) {
+ swig_type_info *tc = cast->type;
+ if (!tc->clientdata) {
+ SWIG_TypeClientData(tc, clientdata);
+ }
+ }
+ cast = cast->next;
+ }
+}
+SWIGRUNTIME void
+SWIG_TypeNewClientData(swig_type_info *ti, void *clientdata) {
+ SWIG_TypeClientData(ti, clientdata);
+ ti->owndata = 1;
+}
+
+/*
+ Search for a swig_type_info structure only by mangled name
+ Search is a O(log #types)
+
+ We start searching at module start, and finish searching when start == end.
+ Note: if start == end at the beginning of the function, we go all the way around
+ the circular list.
+*/
+SWIGRUNTIME swig_type_info *
+SWIG_MangledTypeQueryModule(swig_module_info *start,
+ swig_module_info *end,
+ const char *name) {
+ swig_module_info *iter = start;
+ do {
+ if (iter->size) {
+ register size_t l = 0;
+ register size_t r = iter->size - 1;
+ do {
+ /* since l+r >= 0, we can (>> 1) instead (/ 2) */
+ register size_t i = (l + r) >> 1;
+ const char *iname = iter->types[i]->name;
+ if (iname) {
+ register int compare = strcmp(name, iname);
+ if (compare == 0) {
+ return iter->types[i];
+ } else if (compare < 0) {
+ if (i) {
+ r = i - 1;
+ } else {
+ break;
+ }
+ } else if (compare > 0) {
+ l = i + 1;
+ }
+ } else {
+ break; /* should never happen */
+ }
+ } while (l <= r);
+ }
+ iter = iter->next;
+ } while (iter != end);
+ return 0;
+}
+
+/*
+ Search for a swig_type_info structure for either a mangled name or a human readable name.
+ It first searches the mangled names of the types, which is a O(log #types)
+ If a type is not found it then searches the human readable names, which is O(#types).
+
+ We start searching at module start, and finish searching when start == end.
+ Note: if start == end at the beginning of the function, we go all the way around
+ the circular list.
+*/
+SWIGRUNTIME swig_type_info *
+SWIG_TypeQueryModule(swig_module_info *start,
+ swig_module_info *end,
+ const char *name) {
+ /* STEP 1: Search the name field using binary search */
+ swig_type_info *ret = SWIG_MangledTypeQueryModule(start, end, name);
+ if (ret) {
+ return ret;
+ } else {
+ /* STEP 2: If the type hasn't been found, do a complete search
+ of the str field (the human readable name) */
+ swig_module_info *iter = start;
+ do {
+ register size_t i = 0;
+ for (; i < iter->size; ++i) {
+ if (iter->types[i]->str && (SWIG_TypeEquiv(iter->types[i]->str, name)))
+ return iter->types[i];
+ }
+ iter = iter->next;
+ } while (iter != end);
+ }
+
+ /* neither found a match */
+ return 0;
+}
+
+/*
+ Pack binary data into a string
+*/
+SWIGRUNTIME char *
+SWIG_PackData(char *c, void *ptr, size_t sz) {
+ static const char hex[17] = "0123456789abcdef";
+ register const unsigned char *u = (unsigned char *) ptr;
+ register const unsigned char *eu = u + sz;
+ for (; u != eu; ++u) {
+ register unsigned char uu = *u;
+ *(c++) = hex[(uu & 0xf0) >> 4];
+ *(c++) = hex[uu & 0xf];
+ }
+ return c;
+}
+
+/*
+ Unpack binary data from a string
+*/
+SWIGRUNTIME const char *
+SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
+ register unsigned char *u = (unsigned char *) ptr;
+ register const unsigned char *eu = u + sz;
+ for (; u != eu; ++u) {
+ register char d = *(c++);
+ register unsigned char uu;
+ if ((d >= '0') && (d <= '9'))
+ uu = ((d - '0') << 4);
+ else if ((d >= 'a') && (d <= 'f'))
+ uu = ((d - ('a'-10)) << 4);
+ else
+ return (char *) 0;
+ d = *(c++);
+ if ((d >= '0') && (d <= '9'))
+ uu |= (d - '0');
+ else if ((d >= 'a') && (d <= 'f'))
+ uu |= (d - ('a'-10));
+ else
+ return (char *) 0;
+ *u = uu;
+ }
+ return c;
+}
+
+/*
+ Pack 'void *' into a string buffer.
+*/
+SWIGRUNTIME char *
+SWIG_PackVoidPtr(char *buff, void *ptr, const char *name, size_t bsz) {
+ char *r = buff;
+ if ((2*sizeof(void *) + 2) > bsz) return 0;
+ *(r++) = '_';
+ r = SWIG_PackData(r,&ptr,sizeof(void *));
+ if (strlen(name) + 1 > (bsz - (r - buff))) return 0;
+ strcpy(r,name);
+ return buff;
+}
+
+SWIGRUNTIME const char *
+SWIG_UnpackVoidPtr(const char *c, void **ptr, const char *name) {
+ if (*c != '_') {
+ if (strcmp(c,"NULL") == 0) {
+ *ptr = (void *) 0;
+ return name;
+ } else {
+ return 0;
+ }
+ }
+ return SWIG_UnpackData(++c,ptr,sizeof(void *));
+}
+
+SWIGRUNTIME char *
+SWIG_PackDataName(char *buff, void *ptr, size_t sz, const char *name, size_t bsz) {
+ char *r = buff;
+ size_t lname = (name ? strlen(name) : 0);
+ if ((2*sz + 2 + lname) > bsz) return 0;
+ *(r++) = '_';
+ r = SWIG_PackData(r,ptr,sz);
+ if (lname) {
+ strncpy(r,name,lname+1);
+ } else {
+ *r = 0;
+ }
+ return buff;
+}
+
+SWIGRUNTIME const char *
+SWIG_UnpackDataName(const char *c, void *ptr, size_t sz, const char *name) {
+ if (*c != '_') {
+ if (strcmp(c,"NULL") == 0) {
+ memset(ptr,0,sz);
+ return name;
+ } else {
+ return 0;
+ }
+ }
+ return SWIG_UnpackData(++c,ptr,sz);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* Errors in SWIG */
+#define SWIG_UnknownError -1
+#define SWIG_IOError -2
+#define SWIG_RuntimeError -3
+#define SWIG_IndexError -4
+#define SWIG_TypeError -5
+#define SWIG_DivisionByZero -6
+#define SWIG_OverflowError -7
+#define SWIG_SyntaxError -8
+#define SWIG_ValueError -9
+#define SWIG_SystemError -10
+#define SWIG_AttributeError -11
+#define SWIG_MemoryError -12
+#define SWIG_NullReferenceError -13
+
+
+
+/* Compatibility macros for Python 3 */
+#if PY_VERSION_HEX >= 0x03000000
+
+#define PyClass_Check(obj) PyObject_IsInstance(obj, (PyObject *)&PyType_Type)
+#define PyInt_Check(x) PyLong_Check(x)
+#define PyInt_AsLong(x) PyLong_AsLong(x)
+#define PyInt_FromLong(x) PyLong_FromLong(x)
+#define PyInt_FromSize_t(x) PyLong_FromSize_t(x)
+#define PyString_Check(name) PyBytes_Check(name)
+#define PyString_FromString(x) PyUnicode_FromString(x)
+#define PyString_Format(fmt, args) PyUnicode_Format(fmt, args)
+#define PyString_AsString(str) PyBytes_AsString(str)
+#define PyString_Size(str) PyBytes_Size(str)
+#define PyString_InternFromString(key) PyUnicode_InternFromString(key)
+#define Py_TPFLAGS_HAVE_CLASS Py_TPFLAGS_BASETYPE
+#define PyString_AS_STRING(x) PyUnicode_AS_STRING(x)
+#define _PyLong_FromSsize_t(x) PyLong_FromSsize_t(x)
+
+#endif
+
+#ifndef Py_TYPE
+# define Py_TYPE(op) ((op)->ob_type)
+#endif
+
+/* SWIG APIs for compatibility of both Python 2 & 3 */
+
+#if PY_VERSION_HEX >= 0x03000000
+# define SWIG_Python_str_FromFormat PyUnicode_FromFormat
+#else
+# define SWIG_Python_str_FromFormat PyString_FromFormat
+#endif
+
+
+/* Warning: This function will allocate a new string in Python 3,
+ * so please call SWIG_Python_str_DelForPy3(x) to free the space.
+ */
+SWIGINTERN char*
+SWIG_Python_str_AsChar(PyObject *str)
+{
+#if PY_VERSION_HEX >= 0x03000000
+ char *cstr;
+ char *newstr;
+ Py_ssize_t len;
+ str = PyUnicode_AsUTF8String(str);
+ PyBytes_AsStringAndSize(str, &cstr, &len);
+ newstr = (char *) malloc(len+1);
+ memcpy(newstr, cstr, len+1);
+ Py_XDECREF(str);
+ return newstr;
+#else
+ return PyString_AsString(str);
+#endif
+}
+
+#if PY_VERSION_HEX >= 0x03000000
+# define SWIG_Python_str_DelForPy3(x) free( (void*) (x) )
+#else
+# define SWIG_Python_str_DelForPy3(x)
+#endif
+
+
+SWIGINTERN PyObject*
+SWIG_Python_str_FromChar(const char *c)
+{
+#if PY_VERSION_HEX >= 0x03000000
+ return PyUnicode_FromString(c);
+#else
+ return PyString_FromString(c);
+#endif
+}
+
+/* Add PyOS_snprintf for old Pythons */
+#if PY_VERSION_HEX < 0x02020000
+# if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM)
+# define PyOS_snprintf _snprintf
+# else
+# define PyOS_snprintf snprintf
+# endif
+#endif
+
+/* A crude PyString_FromFormat implementation for old Pythons */
+#if PY_VERSION_HEX < 0x02020000
+
+#ifndef SWIG_PYBUFFER_SIZE
+# define SWIG_PYBUFFER_SIZE 1024
+#endif
+
+static PyObject *
+PyString_FromFormat(const char *fmt, ...) {
+ va_list ap;
+ char buf[SWIG_PYBUFFER_SIZE * 2];
+ int res;
+ va_start(ap, fmt);
+ res = vsnprintf(buf, sizeof(buf), fmt, ap);
+ va_end(ap);
+ return (res < 0 || res >= (int)sizeof(buf)) ? 0 : PyString_FromString(buf);
+}
+#endif
+
+/* Add PyObject_Del for old Pythons */
+#if PY_VERSION_HEX < 0x01060000
+# define PyObject_Del(op) PyMem_DEL((op))
+#endif
+#ifndef PyObject_DEL
+# define PyObject_DEL PyObject_Del
+#endif
+
+/* A crude PyExc_StopIteration exception for old Pythons */
+#if PY_VERSION_HEX < 0x02020000
+# ifndef PyExc_StopIteration
+# define PyExc_StopIteration PyExc_RuntimeError
+# endif
+# ifndef PyObject_GenericGetAttr
+# define PyObject_GenericGetAttr 0
+# endif
+#endif
+
+/* Py_NotImplemented is defined in 2.1 and up. */
+#if PY_VERSION_HEX < 0x02010000
+# ifndef Py_NotImplemented
+# define Py_NotImplemented PyExc_RuntimeError
+# endif
+#endif
+
+/* A crude PyString_AsStringAndSize implementation for old Pythons */
+#if PY_VERSION_HEX < 0x02010000
+# ifndef PyString_AsStringAndSize
+# define PyString_AsStringAndSize(obj, s, len) {*s = PyString_AsString(obj); *len = *s ? strlen(*s) : 0;}
+# endif
+#endif
+
+/* PySequence_Size for old Pythons */
+#if PY_VERSION_HEX < 0x02000000
+# ifndef PySequence_Size
+# define PySequence_Size PySequence_Length
+# endif
+#endif
+
+/* PyBool_FromLong for old Pythons */
+#if PY_VERSION_HEX < 0x02030000
+static
+PyObject *PyBool_FromLong(long ok)
+{
+ PyObject *result = ok ? Py_True : Py_False;
+ Py_INCREF(result);
+ return result;
+}
+#endif
+
+/* Py_ssize_t for old Pythons */
+/* This code is as recommended by: */
+/* http://www.python.org/dev/peps/pep-0353/#conversion-guidelines */
+#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
+typedef int Py_ssize_t;
+# define PY_SSIZE_T_MAX INT_MAX
+# define PY_SSIZE_T_MIN INT_MIN
+typedef inquiry lenfunc;
+typedef intargfunc ssizeargfunc;
+typedef intintargfunc ssizessizeargfunc;
+typedef intobjargproc ssizeobjargproc;
+typedef intintobjargproc ssizessizeobjargproc;
+typedef getreadbufferproc readbufferproc;
+typedef getwritebufferproc writebufferproc;
+typedef getsegcountproc segcountproc;
+typedef getcharbufferproc charbufferproc;
+static long PyNumber_AsSsize_t (PyObject *x, void *SWIGUNUSEDPARM(exc))
+{
+ long result = 0;
+ PyObject *i = PyNumber_Int(x);
+ if (i) {
+ result = PyInt_AsLong(i);
+ Py_DECREF(i);
+ }
+ return result;
+}
+#endif
+
+#if PY_VERSION_HEX < 0x02050000
+#define PyInt_FromSize_t(x) PyInt_FromLong((long)x)
+#endif
+
+#if PY_VERSION_HEX < 0x02040000
+#define Py_VISIT(op) \
+ do { \
+ if (op) { \
+ int vret = visit((op), arg); \
+ if (vret) \
+ return vret; \
+ } \
+ } while (0)
+#endif
+
+#if PY_VERSION_HEX < 0x02030000
+typedef struct {
+ PyTypeObject type;
+ PyNumberMethods as_number;
+ PyMappingMethods as_mapping;
+ PySequenceMethods as_sequence;
+ PyBufferProcs as_buffer;
+ PyObject *name, *slots;
+} PyHeapTypeObject;
+#endif
+
+#if PY_VERSION_HEX < 0x02030000
+typedef destructor freefunc;
+#endif
+
+#if ((PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 6) || \
+ (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION > 0) || \
+ (PY_MAJOR_VERSION > 3))
+# define SWIGPY_USE_CAPSULE
+# define SWIGPY_CAPSULE_NAME ((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION ".type_pointer_capsule" SWIG_TYPE_TABLE_NAME)
+#endif
+
+#if PY_VERSION_HEX < 0x03020000
+#define PyDescr_TYPE(x) (((PyDescrObject *)(x))->d_type)
+#define PyDescr_NAME(x) (((PyDescrObject *)(x))->d_name)
+#endif
+
+/* -----------------------------------------------------------------------------
+ * error manipulation
+ * ----------------------------------------------------------------------------- */
+
+SWIGRUNTIME PyObject*
+SWIG_Python_ErrorType(int code) {
+ PyObject* type = 0;
+ switch(code) {
+ case SWIG_MemoryError:
+ type = PyExc_MemoryError;
+ break;
+ case SWIG_IOError:
+ type = PyExc_IOError;
+ break;
+ case SWIG_RuntimeError:
+ type = PyExc_RuntimeError;
+ break;
+ case SWIG_IndexError:
+ type = PyExc_IndexError;
+ break;
+ case SWIG_TypeError:
+ type = PyExc_TypeError;
+ break;
+ case SWIG_DivisionByZero:
+ type = PyExc_ZeroDivisionError;
+ break;
+ case SWIG_OverflowError:
+ type = PyExc_OverflowError;
+ break;
+ case SWIG_SyntaxError:
+ type = PyExc_SyntaxError;
+ break;
+ case SWIG_ValueError:
+ type = PyExc_ValueError;
+ break;
+ case SWIG_SystemError:
+ type = PyExc_SystemError;
+ break;
+ case SWIG_AttributeError:
+ type = PyExc_AttributeError;
+ break;
+ default:
+ type = PyExc_RuntimeError;
+ }
+ return type;
+}
+
+
+SWIGRUNTIME void
+SWIG_Python_AddErrorMsg(const char* mesg)
+{
+ PyObject *type = 0;
+ PyObject *value = 0;
+ PyObject *traceback = 0;
+
+ if (PyErr_Occurred()) PyErr_Fetch(&type, &value, &traceback);
+ if (value) {
+ char *tmp;
+ PyObject *old_str = PyObject_Str(value);
+ PyErr_Clear();
+ Py_XINCREF(type);
+
+ PyErr_Format(type, "%s %s", tmp = SWIG_Python_str_AsChar(old_str), mesg);
+ SWIG_Python_str_DelForPy3(tmp);
+ Py_DECREF(old_str);
+ Py_DECREF(value);
+ } else {
+ PyErr_SetString(PyExc_RuntimeError, mesg);
+ }
+}
+
+#if defined(SWIG_PYTHON_NO_THREADS)
+# if defined(SWIG_PYTHON_THREADS)
+# undef SWIG_PYTHON_THREADS
+# endif
+#endif
+#if defined(SWIG_PYTHON_THREADS) /* Threading support is enabled */
+# if !defined(SWIG_PYTHON_USE_GIL) && !defined(SWIG_PYTHON_NO_USE_GIL)
+# if (PY_VERSION_HEX >= 0x02030000) /* For 2.3 or later, use the PyGILState calls */
+# define SWIG_PYTHON_USE_GIL
+# endif
+# endif
+# if defined(SWIG_PYTHON_USE_GIL) /* Use PyGILState threads calls */
+# ifndef SWIG_PYTHON_INITIALIZE_THREADS
+# define SWIG_PYTHON_INITIALIZE_THREADS PyEval_InitThreads()
+# endif
+# ifdef __cplusplus /* C++ code */
+ class SWIG_Python_Thread_Block {
+ bool status;
+ PyGILState_STATE state;
+ public:
+ void end() { if (status) { PyGILState_Release(state); status = false;} }
+ SWIG_Python_Thread_Block() : status(true), state(PyGILState_Ensure()) {}
+ ~SWIG_Python_Thread_Block() { end(); }
+ };
+ class SWIG_Python_Thread_Allow {
+ bool status;
+ PyThreadState *save;
+ public:
+ void end() { if (status) { PyEval_RestoreThread(save); status = false; }}
+ SWIG_Python_Thread_Allow() : status(true), save(PyEval_SaveThread()) {}
+ ~SWIG_Python_Thread_Allow() { end(); }
+ };
+# define SWIG_PYTHON_THREAD_BEGIN_BLOCK SWIG_Python_Thread_Block _swig_thread_block
+# define SWIG_PYTHON_THREAD_END_BLOCK _swig_thread_block.end()
+# define SWIG_PYTHON_THREAD_BEGIN_ALLOW SWIG_Python_Thread_Allow _swig_thread_allow
+# define SWIG_PYTHON_THREAD_END_ALLOW _swig_thread_allow.end()
+# else /* C code */
+# define SWIG_PYTHON_THREAD_BEGIN_BLOCK PyGILState_STATE _swig_thread_block = PyGILState_Ensure()
+# define SWIG_PYTHON_THREAD_END_BLOCK PyGILState_Release(_swig_thread_block)
+# define SWIG_PYTHON_THREAD_BEGIN_ALLOW PyThreadState *_swig_thread_allow = PyEval_SaveThread()
+# define SWIG_PYTHON_THREAD_END_ALLOW PyEval_RestoreThread(_swig_thread_allow)
+# endif
+# else /* Old thread way, not implemented, user must provide it */
+# if !defined(SWIG_PYTHON_INITIALIZE_THREADS)
+# define SWIG_PYTHON_INITIALIZE_THREADS
+# endif
+# if !defined(SWIG_PYTHON_THREAD_BEGIN_BLOCK)
+# define SWIG_PYTHON_THREAD_BEGIN_BLOCK
+# endif
+# if !defined(SWIG_PYTHON_THREAD_END_BLOCK)
+# define SWIG_PYTHON_THREAD_END_BLOCK
+# endif
+# if !defined(SWIG_PYTHON_THREAD_BEGIN_ALLOW)
+# define SWIG_PYTHON_THREAD_BEGIN_ALLOW
+# endif
+# if !defined(SWIG_PYTHON_THREAD_END_ALLOW)
+# define SWIG_PYTHON_THREAD_END_ALLOW
+# endif
+# endif
+#else /* No thread support */
+# define SWIG_PYTHON_INITIALIZE_THREADS
+# define SWIG_PYTHON_THREAD_BEGIN_BLOCK
+# define SWIG_PYTHON_THREAD_END_BLOCK
+# define SWIG_PYTHON_THREAD_BEGIN_ALLOW
+# define SWIG_PYTHON_THREAD_END_ALLOW
+#endif
+
+/* -----------------------------------------------------------------------------
+ * Python API portion that goes into the runtime
+ * ----------------------------------------------------------------------------- */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* -----------------------------------------------------------------------------
+ * Constant declarations
+ * ----------------------------------------------------------------------------- */
+
+/* Constant Types */
+#define SWIG_PY_POINTER 4
+#define SWIG_PY_BINARY 5
+
+/* Constant information structure */
+typedef struct swig_const_info {
+ int type;
+ char *name;
+ long lvalue;
+ double dvalue;
+ void *pvalue;
+ swig_type_info **ptype;
+} swig_const_info;
+
+
+/* -----------------------------------------------------------------------------
+ * Wrapper of PyInstanceMethod_New() used in Python 3
+ * It is exported to the generated module, used for -fastproxy
+ * ----------------------------------------------------------------------------- */
+#if PY_VERSION_HEX >= 0x03000000
+SWIGRUNTIME PyObject* SWIG_PyInstanceMethod_New(PyObject *SWIGUNUSEDPARM(self), PyObject *func)
+{
+ return PyInstanceMethod_New(func);
+}
+#else
+SWIGRUNTIME PyObject* SWIG_PyInstanceMethod_New(PyObject *SWIGUNUSEDPARM(self), PyObject *SWIGUNUSEDPARM(func))
+{
+ return NULL;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/* -----------------------------------------------------------------------------
+ * pyrun.swg
+ *
+ * This file contains the runtime support for Python modules
+ * and includes code for managing global variables and pointer
+ * type checking.
+ *
+ * ----------------------------------------------------------------------------- */
+
+/* Common SWIG API */
+
+/* for raw pointers */
+#define SWIG_Python_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, 0)
+#define SWIG_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtr(obj, pptr, type, flags)
+#define SWIG_ConvertPtrAndOwn(obj,pptr,type,flags,own) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, own)
+
+#ifdef SWIGPYTHON_BUILTIN
+#define SWIG_NewPointerObj(ptr, type, flags) SWIG_Python_NewPointerObj(self, ptr, type, flags)
+#else
+#define SWIG_NewPointerObj(ptr, type, flags) SWIG_Python_NewPointerObj(NULL, ptr, type, flags)
+#endif
+
+#define SWIG_InternalNewPointerObj(ptr, type, flags) SWIG_Python_NewPointerObj(NULL, ptr, type, flags)
+
+#define SWIG_CheckImplicit(ty) SWIG_Python_CheckImplicit(ty)
+#define SWIG_AcquirePtr(ptr, src) SWIG_Python_AcquirePtr(ptr, src)
+#define swig_owntype int
+
+/* for raw packed data */
+#define SWIG_ConvertPacked(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty)
+#define SWIG_NewPackedObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type)
+
+/* for class or struct pointers */
+#define SWIG_ConvertInstance(obj, pptr, type, flags) SWIG_ConvertPtr(obj, pptr, type, flags)
+#define SWIG_NewInstanceObj(ptr, type, flags) SWIG_NewPointerObj(ptr, type, flags)
+
+/* for C or C++ function pointers */
+#define SWIG_ConvertFunctionPtr(obj, pptr, type) SWIG_Python_ConvertFunctionPtr(obj, pptr, type)
+#define SWIG_NewFunctionPtrObj(ptr, type) SWIG_Python_NewPointerObj(NULL, ptr, type, 0)
+
+/* for C++ member pointers, ie, member methods */
+#define SWIG_ConvertMember(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty)
+#define SWIG_NewMemberObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type)
+
+
+/* Runtime API */
+
+#define SWIG_GetModule(clientdata) SWIG_Python_GetModule(clientdata)
+#define SWIG_SetModule(clientdata, pointer) SWIG_Python_SetModule(pointer)
+#define SWIG_NewClientData(obj) SwigPyClientData_New(obj)
+
+#define SWIG_SetErrorObj SWIG_Python_SetErrorObj
+#define SWIG_SetErrorMsg SWIG_Python_SetErrorMsg
+#define SWIG_ErrorType(code) SWIG_Python_ErrorType(code)
+#define SWIG_Error(code, msg) SWIG_Python_SetErrorMsg(SWIG_ErrorType(code), msg)
+#define SWIG_fail goto fail
+
+
+/* Runtime API implementation */
+
+/* Error manipulation */
+
+SWIGINTERN void
+SWIG_Python_SetErrorObj(PyObject *errtype, PyObject *obj) {
+ SWIG_PYTHON_THREAD_BEGIN_BLOCK;
+ PyErr_SetObject(errtype, obj);
+ Py_DECREF(obj);
+ SWIG_PYTHON_THREAD_END_BLOCK;
+}
+
+SWIGINTERN void
+SWIG_Python_SetErrorMsg(PyObject *errtype, const char *msg) {
+ SWIG_PYTHON_THREAD_BEGIN_BLOCK;
+ PyErr_SetString(errtype, msg);
+ SWIG_PYTHON_THREAD_END_BLOCK;
+}
+
+#define SWIG_Python_Raise(obj, type, desc) SWIG_Python_SetErrorObj(SWIG_Python_ExceptionType(desc), obj)
+
+/* Set a constant value */
+
+#if defined(SWIGPYTHON_BUILTIN)
+
+SWIGINTERN void
+SwigPyBuiltin_AddPublicSymbol(PyObject *seq, const char *key) {
+ PyObject *s = PyString_InternFromString(key);
+ PyList_Append(seq, s);
+ Py_DECREF(s);
+}
+
+SWIGINTERN void
+SWIG_Python_SetConstant(PyObject *d, PyObject *public_interface, const char *name, PyObject *obj) {
+#if PY_VERSION_HEX < 0x02030000
+ PyDict_SetItemString(d, (char *)name, obj);
+#else
+ PyDict_SetItemString(d, name, obj);
+#endif
+ Py_DECREF(obj);
+ if (public_interface)
+ SwigPyBuiltin_AddPublicSymbol(public_interface, name);
+}
+
+#else
+
+SWIGINTERN void
+SWIG_Python_SetConstant(PyObject *d, const char *name, PyObject *obj) {
+#if PY_VERSION_HEX < 0x02030000
+ PyDict_SetItemString(d, (char *)name, obj);
+#else
+ PyDict_SetItemString(d, name, obj);
+#endif
+ Py_DECREF(obj);
+}
+
+#endif
+
+/* Append a value to the result obj */
+
+SWIGINTERN PyObject*
+SWIG_Python_AppendOutput(PyObject* result, PyObject* obj) {
+#if !defined(SWIG_PYTHON_OUTPUT_TUPLE)
+ if (!result) {
+ result = obj;
+ } else if (result == Py_None) {
+ Py_DECREF(result);
+ result = obj;
+ } else {
+ if (!PyList_Check(result)) {
+ PyObject *o2 = result;
+ result = PyList_New(1);
+ PyList_SetItem(result, 0, o2);
+ }
+ PyList_Append(result,obj);
+ Py_DECREF(obj);
+ }
+ return result;
+#else
+ PyObject* o2;
+ PyObject* o3;
+ if (!result) {
+ result = obj;
+ } else if (result == Py_None) {
+ Py_DECREF(result);
+ result = obj;
+ } else {
+ if (!PyTuple_Check(result)) {
+ o2 = result;
+ result = PyTuple_New(1);
+ PyTuple_SET_ITEM(result, 0, o2);
+ }
+ o3 = PyTuple_New(1);
+ PyTuple_SET_ITEM(o3, 0, obj);
+ o2 = result;
+ result = PySequence_Concat(o2, o3);
+ Py_DECREF(o2);
+ Py_DECREF(o3);
+ }
+ return result;
+#endif
+}
+
+/* Unpack the argument tuple */
+
+SWIGINTERN int
+SWIG_Python_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, PyObject **objs)
+{
+ if (!args) {
+ if (!min && !max) {
+ return 1;
+ } else {
+ PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got none",
+ name, (min == max ? "" : "at least "), (int)min);
+ return 0;
+ }
+ }
+ if (!PyTuple_Check(args)) {
+ if (min <= 1 && max >= 1) {
+ register int i;
+ objs[0] = args;
+ for (i = 1; i < max; ++i) {
+ objs[i] = 0;
+ }
+ return 2;
+ }
+ PyErr_SetString(PyExc_SystemError, "UnpackTuple() argument list is not a tuple");
+ return 0;
+ } else {
+ register Py_ssize_t l = PyTuple_GET_SIZE(args);
+ if (l < min) {
+ PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d",
+ name, (min == max ? "" : "at least "), (int)min, (int)l);
+ return 0;
+ } else if (l > max) {
+ PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d",
+ name, (min == max ? "" : "at most "), (int)max, (int)l);
+ return 0;
+ } else {
+ register int i;
+ for (i = 0; i < l; ++i) {
+ objs[i] = PyTuple_GET_ITEM(args, i);
+ }
+ for (; l < max; ++l) {
+ objs[l] = 0;
+ }
+ return i + 1;
+ }
+ }
+}
+
+/* A functor is a function object with one single object argument */
+#if PY_VERSION_HEX >= 0x02020000
+#define SWIG_Python_CallFunctor(functor, obj) PyObject_CallFunctionObjArgs(functor, obj, NULL);
+#else
+#define SWIG_Python_CallFunctor(functor, obj) PyObject_CallFunction(functor, "O", obj);
+#endif
+
+/*
+ Helper for static pointer initialization for both C and C++ code, for example
+ static PyObject *SWIG_STATIC_POINTER(MyVar) = NewSomething(...);
+*/
+#ifdef __cplusplus
+#define SWIG_STATIC_POINTER(var) var
+#else
+#define SWIG_STATIC_POINTER(var) var = 0; if (!var) var
+#endif
+
+/* -----------------------------------------------------------------------------
+ * Pointer declarations
+ * ----------------------------------------------------------------------------- */
+
+/* Flags for new pointer objects */
+#define SWIG_POINTER_NOSHADOW (SWIG_POINTER_OWN << 1)
+#define SWIG_POINTER_NEW (SWIG_POINTER_NOSHADOW | SWIG_POINTER_OWN)
+
+#define SWIG_POINTER_IMPLICIT_CONV (SWIG_POINTER_DISOWN << 1)
+
+#define SWIG_BUILTIN_TP_INIT (SWIG_POINTER_OWN << 2)
+#define SWIG_BUILTIN_INIT (SWIG_BUILTIN_TP_INIT | SWIG_POINTER_OWN)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* How to access Py_None */
+#if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
+# ifndef SWIG_PYTHON_NO_BUILD_NONE
+# ifndef SWIG_PYTHON_BUILD_NONE
+# define SWIG_PYTHON_BUILD_NONE
+# endif
+# endif
+#endif
+
+#ifdef SWIG_PYTHON_BUILD_NONE
+# ifdef Py_None
+# undef Py_None
+# define Py_None SWIG_Py_None()
+# endif
+SWIGRUNTIMEINLINE PyObject *
+_SWIG_Py_None(void)
+{
+ PyObject *none = Py_BuildValue((char*)"");
+ Py_DECREF(none);
+ return none;
+}
+SWIGRUNTIME PyObject *
+SWIG_Py_None(void)
+{
+ static PyObject *SWIG_STATIC_POINTER(none) = _SWIG_Py_None();
+ return none;
+}
+#endif
+
+/* The python void return value */
+
+SWIGRUNTIMEINLINE PyObject *
+SWIG_Py_Void(void)
+{
+ PyObject *none = Py_None;
+ Py_INCREF(none);
+ return none;
+}
+
+/* SwigPyClientData */
+
+typedef struct {
+ PyObject *klass;
+ PyObject *newraw;
+ PyObject *newargs;
+ PyObject *destroy;
+ int delargs;
+ int implicitconv;
+ PyTypeObject *pytype;
+} SwigPyClientData;
+
+SWIGRUNTIMEINLINE int
+SWIG_Python_CheckImplicit(swig_type_info *ty)
+{
+ SwigPyClientData *data = (SwigPyClientData *)ty->clientdata;
+ return data ? data->implicitconv : 0;
+}
+
+SWIGRUNTIMEINLINE PyObject *
+SWIG_Python_ExceptionType(swig_type_info *desc) {
+ SwigPyClientData *data = desc ? (SwigPyClientData *) desc->clientdata : 0;
+ PyObject *klass = data ? data->klass : 0;
+ return (klass ? klass : PyExc_RuntimeError);
+}
+
+
+SWIGRUNTIME SwigPyClientData *
+SwigPyClientData_New(PyObject* obj)
+{
+ if (!obj) {
+ return 0;
+ } else {
+ SwigPyClientData *data = (SwigPyClientData *)malloc(sizeof(SwigPyClientData));
+ /* the klass element */
+ data->klass = obj;
+ Py_INCREF(data->klass);
+ /* the newraw method and newargs arguments used to create a new raw instance */
+ if (PyClass_Check(obj)) {
+ data->newraw = 0;
+ data->newargs = obj;
+ Py_INCREF(obj);
+ } else {
+#if (PY_VERSION_HEX < 0x02020000)
+ data->newraw = 0;
+#else
+ data->newraw = PyObject_GetAttrString(data->klass, (char *)"__new__");
+#endif
+ if (data->newraw) {
+ Py_INCREF(data->newraw);
+ data->newargs = PyTuple_New(1);
+ PyTuple_SetItem(data->newargs, 0, obj);
+ } else {
+ data->newargs = obj;
+ }
+ Py_INCREF(data->newargs);
+ }
+ /* the destroy method, aka as the C++ delete method */
+ data->destroy = PyObject_GetAttrString(data->klass, (char *)"__swig_destroy__");
+ if (PyErr_Occurred()) {
+ PyErr_Clear();
+ data->destroy = 0;
+ }
+ if (data->destroy) {
+ int flags;
+ Py_INCREF(data->destroy);
+ flags = PyCFunction_GET_FLAGS(data->destroy);
+#ifdef METH_O
+ data->delargs = !(flags & (METH_O));
+#else
+ data->delargs = 0;
+#endif
+ } else {
+ data->delargs = 0;
+ }
+ data->implicitconv = 0;
+ data->pytype = 0;
+ return data;
+ }
+}
+
+SWIGRUNTIME void
+SwigPyClientData_Del(SwigPyClientData *data) {
+ Py_XDECREF(data->newraw);
+ Py_XDECREF(data->newargs);
+ Py_XDECREF(data->destroy);
+}
+
+/* =============== SwigPyObject =====================*/
+
+typedef struct {
+ PyObject_HEAD
+ void *ptr;
+ swig_type_info *ty;
+ int own;
+ PyObject *next;
+#ifdef SWIGPYTHON_BUILTIN
+ PyObject *dict;
+#endif
+} SwigPyObject;
+
+SWIGRUNTIME PyObject *
+SwigPyObject_long(SwigPyObject *v)
+{
+ return PyLong_FromVoidPtr(v->ptr);
+}
+
+SWIGRUNTIME PyObject *
+SwigPyObject_format(const char* fmt, SwigPyObject *v)
+{
+ PyObject *res = NULL;
+ PyObject *args = PyTuple_New(1);
+ if (args) {
+ if (PyTuple_SetItem(args, 0, SwigPyObject_long(v)) == 0) {
+ PyObject *ofmt = SWIG_Python_str_FromChar(fmt);
+ if (ofmt) {
+#if PY_VERSION_HEX >= 0x03000000
+ res = PyUnicode_Format(ofmt,args);
+#else
+ res = PyString_Format(ofmt,args);
+#endif
+ Py_DECREF(ofmt);
+ }
+ Py_DECREF(args);
+ }
+ }
+ return res;
+}
+
+SWIGRUNTIME PyObject *
+SwigPyObject_oct(SwigPyObject *v)
+{
+ return SwigPyObject_format("%o",v);
+}
+
+SWIGRUNTIME PyObject *
+SwigPyObject_hex(SwigPyObject *v)
+{
+ return SwigPyObject_format("%x",v);
+}
+
+SWIGRUNTIME PyObject *
+#ifdef METH_NOARGS
+SwigPyObject_repr(SwigPyObject *v)
+#else
+SwigPyObject_repr(SwigPyObject *v, PyObject *args)
+#endif
+{
+ const char *name = SWIG_TypePrettyName(v->ty);
+ PyObject *repr = SWIG_Python_str_FromFormat("<Swig Object of type '%s' at %p>", (name ? name : "unknown"), (void *)v);
+ if (v->next) {
+# ifdef METH_NOARGS
+ PyObject *nrep = SwigPyObject_repr((SwigPyObject *)v->next);
+# else
+ PyObject *nrep = SwigPyObject_repr((SwigPyObject *)v->next, args);
+# endif
+# if PY_VERSION_HEX >= 0x03000000
+ PyObject *joined = PyUnicode_Concat(repr, nrep);
+ Py_DecRef(repr);
+ Py_DecRef(nrep);
+ repr = joined;
+# else
+ PyString_ConcatAndDel(&repr,nrep);
+# endif
+ }
+ return repr;
+}
+
+SWIGRUNTIME int
+SwigPyObject_print(SwigPyObject *v, FILE *fp, int SWIGUNUSEDPARM(flags))
+{
+ char *str;
+#ifdef METH_NOARGS
+ PyObject *repr = SwigPyObject_repr(v);
+#else
+ PyObject *repr = SwigPyObject_repr(v, NULL);
+#endif
+ if (repr) {
+ str = SWIG_Python_str_AsChar(repr);
+ fputs(str, fp);
+ SWIG_Python_str_DelForPy3(str);
+ Py_DECREF(repr);
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+SWIGRUNTIME PyObject *
+SwigPyObject_str(SwigPyObject *v)
+{
+ char result[SWIG_BUFFER_SIZE];
+ return SWIG_PackVoidPtr(result, v->ptr, v->ty->name, sizeof(result)) ?
+ SWIG_Python_str_FromChar(result) : 0;
+}
+
+SWIGRUNTIME int
+SwigPyObject_compare(SwigPyObject *v, SwigPyObject *w)
+{
+ void *i = v->ptr;
+ void *j = w->ptr;
+ return (i < j) ? -1 : ((i > j) ? 1 : 0);
+}
+
+/* Added for Python 3.x, would it also be useful for Python 2.x? */
+SWIGRUNTIME PyObject*
+SwigPyObject_richcompare(SwigPyObject *v, SwigPyObject *w, int op)
+{
+ PyObject* res;
+ if( op != Py_EQ && op != Py_NE ) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+ res = PyBool_FromLong( (SwigPyObject_compare(v, w)==0) == (op == Py_EQ) ? 1 : 0);
+ return res;
+}
+
+
+SWIGRUNTIME PyTypeObject* SwigPyObject_TypeOnce(void);
+
+#ifdef SWIGPYTHON_BUILTIN
+static swig_type_info *SwigPyObject_stype = 0;
+SWIGRUNTIME PyTypeObject*
+SwigPyObject_type(void) {
+ SwigPyClientData *cd;
+ assert(SwigPyObject_stype);
+ cd = (SwigPyClientData*) SwigPyObject_stype->clientdata;
+ assert(cd);
+ assert(cd->pytype);
+ return cd->pytype;
+}
+#else
+SWIGRUNTIME PyTypeObject*
+SwigPyObject_type(void) {
+ static PyTypeObject *SWIG_STATIC_POINTER(type) = SwigPyObject_TypeOnce();
+ return type;
+}
+#endif
+
+SWIGRUNTIMEINLINE int
+SwigPyObject_Check(PyObject *op) {
+#ifdef SWIGPYTHON_BUILTIN
+ PyTypeObject *target_tp = SwigPyObject_type();
+ if (PyType_IsSubtype(op->ob_type, target_tp))
+ return 1;
+ return (strcmp(op->ob_type->tp_name, "SwigPyObject") == 0);
+#else
+ return (Py_TYPE(op) == SwigPyObject_type())
+ || (strcmp(Py_TYPE(op)->tp_name,"SwigPyObject") == 0);
+#endif
+}
+
+SWIGRUNTIME PyObject *
+SwigPyObject_New(void *ptr, swig_type_info *ty, int own);
+
+SWIGRUNTIME void
+SwigPyObject_dealloc(PyObject *v)
+{
+ SwigPyObject *sobj = (SwigPyObject *) v;
+ PyObject *next = sobj->next;
+ if (sobj->own == SWIG_POINTER_OWN) {
+ swig_type_info *ty = sobj->ty;
+ SwigPyClientData *data = ty ? (SwigPyClientData *) ty->clientdata : 0;
+ PyObject *destroy = data ? data->destroy : 0;
+ if (destroy) {
+ /* destroy is always a VARARGS method */
+ PyObject *res;
+ if (data->delargs) {
+ /* we need to create a temporary object to carry the destroy operation */
+ PyObject *tmp = SwigPyObject_New(sobj->ptr, ty, 0);
+ res = SWIG_Python_CallFunctor(destroy, tmp);
+ Py_DECREF(tmp);
+ } else {
+ PyCFunction meth = PyCFunction_GET_FUNCTION(destroy);
+ PyObject *mself = PyCFunction_GET_SELF(destroy);
+ res = ((*meth)(mself, v));
+ }
+ Py_XDECREF(res);
+ }
+#if !defined(SWIG_PYTHON_SILENT_MEMLEAK)
+ else {
+ const char *name = SWIG_TypePrettyName(ty);
+ printf("swig/python detected a memory leak of type '%s', no destructor found.\n", (name ? name : "unknown"));
+ }
+#endif
+ }
+ Py_XDECREF(next);
+ PyObject_DEL(v);
+}
+
+SWIGRUNTIME PyObject*
+SwigPyObject_append(PyObject* v, PyObject* next)
+{
+ SwigPyObject *sobj = (SwigPyObject *) v;
+#ifndef METH_O
+ PyObject *tmp = 0;
+ if (!PyArg_ParseTuple(next,(char *)"O:append", &tmp)) return NULL;
+ next = tmp;
+#endif
+ if (!SwigPyObject_Check(next)) {
+ return NULL;
+ }
+ sobj->next = next;
+ Py_INCREF(next);
+ return SWIG_Py_Void();
+}
+
+SWIGRUNTIME PyObject*
+#ifdef METH_NOARGS
+SwigPyObject_next(PyObject* v)
+#else
+SwigPyObject_next(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
+#endif
+{
+ SwigPyObject *sobj = (SwigPyObject *) v;
+ if (sobj->next) {
+ Py_INCREF(sobj->next);
+ return sobj->next;
+ } else {
+ return SWIG_Py_Void();
+ }
+}
+
+SWIGINTERN PyObject*
+#ifdef METH_NOARGS
+SwigPyObject_disown(PyObject *v)
+#else
+SwigPyObject_disown(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
+#endif
+{
+ SwigPyObject *sobj = (SwigPyObject *)v;
+ sobj->own = 0;
+ return SWIG_Py_Void();
+}
+
+SWIGINTERN PyObject*
+#ifdef METH_NOARGS
+SwigPyObject_acquire(PyObject *v)
+#else
+SwigPyObject_acquire(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
+#endif
+{
+ SwigPyObject *sobj = (SwigPyObject *)v;
+ sobj->own = SWIG_POINTER_OWN;
+ return SWIG_Py_Void();
+}
+
+SWIGINTERN PyObject*
+SwigPyObject_own(PyObject *v, PyObject *args)
+{
+ PyObject *val = 0;
+#if (PY_VERSION_HEX < 0x02020000)
+ if (!PyArg_ParseTuple(args,(char *)"|O:own",&val))
+#elif (PY_VERSION_HEX < 0x02050000)
+ if (!PyArg_UnpackTuple(args, (char *)"own", 0, 1, &val))
+#else
+ if (!PyArg_UnpackTuple(args, "own", 0, 1, &val))
+#endif
+ {
+ return NULL;
+ }
+ else
+ {
+ SwigPyObject *sobj = (SwigPyObject *)v;
+ PyObject *obj = PyBool_FromLong(sobj->own);
+ if (val) {
+#ifdef METH_NOARGS
+ if (PyObject_IsTrue(val)) {
+ SwigPyObject_acquire(v);
+ } else {
+ SwigPyObject_disown(v);
+ }
+#else
+ if (PyObject_IsTrue(val)) {
+ SwigPyObject_acquire(v,args);
+ } else {
+ SwigPyObject_disown(v,args);
+ }
+#endif
+ }
+ return obj;
+ }
+}
+
+#ifdef METH_O
+static PyMethodDef
+swigobject_methods[] = {
+ {(char *)"disown", (PyCFunction)SwigPyObject_disown, METH_NOARGS, (char *)"releases ownership of the pointer"},
+ {(char *)"acquire", (PyCFunction)SwigPyObject_acquire, METH_NOARGS, (char *)"acquires ownership of the pointer"},
+ {(char *)"own", (PyCFunction)SwigPyObject_own, METH_VARARGS, (char *)"returns/sets ownership of the pointer"},
+ {(char *)"append", (PyCFunction)SwigPyObject_append, METH_O, (char *)"appends another 'this' object"},
+ {(char *)"next", (PyCFunction)SwigPyObject_next, METH_NOARGS, (char *)"returns the next 'this' object"},
+ {(char *)"__repr__",(PyCFunction)SwigPyObject_repr, METH_NOARGS, (char *)"returns object representation"},
+ {0, 0, 0, 0}
+};
+#else
+static PyMethodDef
+swigobject_methods[] = {
+ {(char *)"disown", (PyCFunction)SwigPyObject_disown, METH_VARARGS, (char *)"releases ownership of the pointer"},
+ {(char *)"acquire", (PyCFunction)SwigPyObject_acquire, METH_VARARGS, (char *)"aquires ownership of the pointer"},
+ {(char *)"own", (PyCFunction)SwigPyObject_own, METH_VARARGS, (char *)"returns/sets ownership of the pointer"},
+ {(char *)"append", (PyCFunction)SwigPyObject_append, METH_VARARGS, (char *)"appends another 'this' object"},
+ {(char *)"next", (PyCFunction)SwigPyObject_next, METH_VARARGS, (char *)"returns the next 'this' object"},
+ {(char *)"__repr__",(PyCFunction)SwigPyObject_repr, METH_VARARGS, (char *)"returns object representation"},
+ {0, 0, 0, 0}
+};
+#endif
+
+#if PY_VERSION_HEX < 0x02020000
+SWIGINTERN PyObject *
+SwigPyObject_getattr(SwigPyObject *sobj,char *name)
+{
+ return Py_FindMethod(swigobject_methods, (PyObject *)sobj, name);
+}
+#endif
+
+SWIGRUNTIME PyTypeObject*
+SwigPyObject_TypeOnce(void) {
+ static char swigobject_doc[] = "Swig object carries a C/C++ instance pointer";
+
+ static PyNumberMethods SwigPyObject_as_number = {
+ (binaryfunc)0, /*nb_add*/
+ (binaryfunc)0, /*nb_subtract*/
+ (binaryfunc)0, /*nb_multiply*/
+ /* nb_divide removed in Python 3 */
+#if PY_VERSION_HEX < 0x03000000
+ (binaryfunc)0, /*nb_divide*/
+#endif
+ (binaryfunc)0, /*nb_remainder*/
+ (binaryfunc)0, /*nb_divmod*/
+ (ternaryfunc)0,/*nb_power*/
+ (unaryfunc)0, /*nb_negative*/
+ (unaryfunc)0, /*nb_positive*/
+ (unaryfunc)0, /*nb_absolute*/
+ (inquiry)0, /*nb_nonzero*/
+ 0, /*nb_invert*/
+ 0, /*nb_lshift*/
+ 0, /*nb_rshift*/
+ 0, /*nb_and*/
+ 0, /*nb_xor*/
+ 0, /*nb_or*/
+#if PY_VERSION_HEX < 0x03000000
+ 0, /*nb_coerce*/
+#endif
+ (unaryfunc)SwigPyObject_long, /*nb_int*/
+#if PY_VERSION_HEX < 0x03000000
+ (unaryfunc)SwigPyObject_long, /*nb_long*/
+#else
+ 0, /*nb_reserved*/
+#endif
+ (unaryfunc)0, /*nb_float*/
+#if PY_VERSION_HEX < 0x03000000
+ (unaryfunc)SwigPyObject_oct, /*nb_oct*/
+ (unaryfunc)SwigPyObject_hex, /*nb_hex*/
+#endif
+#if PY_VERSION_HEX >= 0x03000000 /* 3.0 */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_index, nb_inplace_divide removed */
+#elif PY_VERSION_HEX >= 0x02050000 /* 2.5.0 */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_index */
+#elif PY_VERSION_HEX >= 0x02020000 /* 2.2.0 */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_true_divide */
+#elif PY_VERSION_HEX >= 0x02000000 /* 2.0.0 */
+ 0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_or */
+#endif
+ };
+
+ static PyTypeObject swigpyobject_type;
+ static int type_init = 0;
+ if (!type_init) {
+ const PyTypeObject tmp = {
+ /* PyObject header changed in Python 3 */
+#if PY_VERSION_HEX >= 0x03000000
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+#endif
+ (char *)"SwigPyObject", /* tp_name */
+ sizeof(SwigPyObject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)SwigPyObject_dealloc, /* tp_dealloc */
+ (printfunc)SwigPyObject_print, /* tp_print */
+#if PY_VERSION_HEX < 0x02020000
+ (getattrfunc)SwigPyObject_getattr, /* tp_getattr */
+#else
+ (getattrfunc)0, /* tp_getattr */
+#endif
+ (setattrfunc)0, /* tp_setattr */
+#if PY_VERSION_HEX >= 0x03000000
+ 0, /* tp_reserved in 3.0.1, tp_compare in 3.0.0 but not used */
+#else
+ (cmpfunc)SwigPyObject_compare, /* tp_compare */
+#endif
+ (reprfunc)SwigPyObject_repr, /* tp_repr */
+ &SwigPyObject_as_number, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ (hashfunc)0, /* tp_hash */
+ (ternaryfunc)0, /* tp_call */
+ (reprfunc)SwigPyObject_str, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ swigobject_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ (richcmpfunc)SwigPyObject_richcompare,/* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+#if PY_VERSION_HEX >= 0x02020000
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ swigobject_methods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ 0, /* tp_new */
+ 0, /* tp_free */
+ 0, /* tp_is_gc */
+ 0, /* tp_bases */
+ 0, /* tp_mro */
+ 0, /* tp_cache */
+ 0, /* tp_subclasses */
+ 0, /* tp_weaklist */
+#endif
+#if PY_VERSION_HEX >= 0x02030000
+ 0, /* tp_del */
+#endif
+#if PY_VERSION_HEX >= 0x02060000
+ 0, /* tp_version */
+#endif
+#ifdef COUNT_ALLOCS
+ 0,0,0,0 /* tp_alloc -> tp_next */
+#endif
+ };
+ swigpyobject_type = tmp;
+ type_init = 1;
+#if PY_VERSION_HEX < 0x02020000
+ swigpyobject_type.ob_type = &PyType_Type;
+#else
+ if (PyType_Ready(&swigpyobject_type) < 0)
+ return NULL;
+#endif
+ }
+ return &swigpyobject_type;
+}
+
+SWIGRUNTIME PyObject *
+SwigPyObject_New(void *ptr, swig_type_info *ty, int own)
+{
+ SwigPyObject *sobj = PyObject_NEW(SwigPyObject, SwigPyObject_type());
+ if (sobj) {
+ sobj->ptr = ptr;
+ sobj->ty = ty;
+ sobj->own = own;
+ sobj->next = 0;
+ }
+ return (PyObject *)sobj;
+}
+
+/* -----------------------------------------------------------------------------
+ * Implements a simple Swig Packed type, and use it instead of string
+ * ----------------------------------------------------------------------------- */
+
+typedef struct {
+ PyObject_HEAD
+ void *pack;
+ swig_type_info *ty;
+ size_t size;
+} SwigPyPacked;
+
+SWIGRUNTIME int
+SwigPyPacked_print(SwigPyPacked *v, FILE *fp, int SWIGUNUSEDPARM(flags))
+{
+ char result[SWIG_BUFFER_SIZE];
+ fputs("<Swig Packed ", fp);
+ if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) {
+ fputs("at ", fp);
+ fputs(result, fp);
+ }
+ fputs(v->ty->name,fp);
+ fputs(">", fp);
+ return 0;
+}
+
+SWIGRUNTIME PyObject *
+SwigPyPacked_repr(SwigPyPacked *v)
+{
+ char result[SWIG_BUFFER_SIZE];
+ if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) {
+ return SWIG_Python_str_FromFormat("<Swig Packed at %s%s>", result, v->ty->name);
+ } else {
+ return SWIG_Python_str_FromFormat("<Swig Packed %s>", v->ty->name);
+ }
+}
+
+SWIGRUNTIME PyObject *
+SwigPyPacked_str(SwigPyPacked *v)
+{
+ char result[SWIG_BUFFER_SIZE];
+ if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))){
+ return SWIG_Python_str_FromFormat("%s%s", result, v->ty->name);
+ } else {
+ return SWIG_Python_str_FromChar(v->ty->name);
+ }
+}
+
+SWIGRUNTIME int
+SwigPyPacked_compare(SwigPyPacked *v, SwigPyPacked *w)
+{
+ size_t i = v->size;
+ size_t j = w->size;
+ int s = (i < j) ? -1 : ((i > j) ? 1 : 0);
+ return s ? s : strncmp((char *)v->pack, (char *)w->pack, 2*v->size);
+}
+
+SWIGRUNTIME PyTypeObject* SwigPyPacked_TypeOnce(void);
+
+SWIGRUNTIME PyTypeObject*
+SwigPyPacked_type(void) {
+ static PyTypeObject *SWIG_STATIC_POINTER(type) = SwigPyPacked_TypeOnce();
+ return type;
+}
+
+SWIGRUNTIMEINLINE int
+SwigPyPacked_Check(PyObject *op) {
+ return ((op)->ob_type == SwigPyPacked_TypeOnce())
+ || (strcmp((op)->ob_type->tp_name,"SwigPyPacked") == 0);
+}
+
+SWIGRUNTIME void
+SwigPyPacked_dealloc(PyObject *v)
+{
+ if (SwigPyPacked_Check(v)) {
+ SwigPyPacked *sobj = (SwigPyPacked *) v;
+ free(sobj->pack);
+ }
+ PyObject_DEL(v);
+}
+
+SWIGRUNTIME PyTypeObject*
+SwigPyPacked_TypeOnce(void) {
+ static char swigpacked_doc[] = "Swig object carries a C/C++ instance pointer";
+ static PyTypeObject swigpypacked_type;
+ static int type_init = 0;
+ if (!type_init) {
+ const PyTypeObject tmp = {
+ /* PyObject header changed in Python 3 */
+#if PY_VERSION_HEX>=0x03000000
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+#endif
+ (char *)"SwigPyPacked", /* tp_name */
+ sizeof(SwigPyPacked), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)SwigPyPacked_dealloc, /* tp_dealloc */
+ (printfunc)SwigPyPacked_print, /* tp_print */
+ (getattrfunc)0, /* tp_getattr */
+ (setattrfunc)0, /* tp_setattr */
+#if PY_VERSION_HEX>=0x03000000
+ 0, /* tp_reserved in 3.0.1 */
+#else
+ (cmpfunc)SwigPyPacked_compare, /* tp_compare */
+#endif
+ (reprfunc)SwigPyPacked_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ (hashfunc)0, /* tp_hash */
+ (ternaryfunc)0, /* tp_call */
+ (reprfunc)SwigPyPacked_str, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ swigpacked_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+#if PY_VERSION_HEX >= 0x02020000
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ 0, /* tp_new */
+ 0, /* tp_free */
+ 0, /* tp_is_gc */
+ 0, /* tp_bases */
+ 0, /* tp_mro */
+ 0, /* tp_cache */
+ 0, /* tp_subclasses */
+ 0, /* tp_weaklist */
+#endif
+#if PY_VERSION_HEX >= 0x02030000
+ 0, /* tp_del */
+#endif
+#if PY_VERSION_HEX >= 0x02060000
+ 0, /* tp_version */
+#endif
+#ifdef COUNT_ALLOCS
+ 0,0,0,0 /* tp_alloc -> tp_next */
+#endif
+ };
+ swigpypacked_type = tmp;
+ type_init = 1;
+#if PY_VERSION_HEX < 0x02020000
+ swigpypacked_type.ob_type = &PyType_Type;
+#else
+ if (PyType_Ready(&swigpypacked_type) < 0)
+ return NULL;
+#endif
+ }
+ return &swigpypacked_type;
+}
+
+SWIGRUNTIME PyObject *
+SwigPyPacked_New(void *ptr, size_t size, swig_type_info *ty)
+{
+ SwigPyPacked *sobj = PyObject_NEW(SwigPyPacked, SwigPyPacked_type());
+ if (sobj) {
+ void *pack = malloc(size);
+ if (pack) {
+ memcpy(pack, ptr, size);
+ sobj->pack = pack;
+ sobj->ty = ty;
+ sobj->size = size;
+ } else {
+ PyObject_DEL((PyObject *) sobj);
+ sobj = 0;
+ }
+ }
+ return (PyObject *) sobj;
+}
+
+SWIGRUNTIME swig_type_info *
+SwigPyPacked_UnpackData(PyObject *obj, void *ptr, size_t size)
+{
+ if (SwigPyPacked_Check(obj)) {
+ SwigPyPacked *sobj = (SwigPyPacked *)obj;
+ if (sobj->size != size) return 0;
+ memcpy(ptr, sobj->pack, size);
+ return sobj->ty;
+ } else {
+ return 0;
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * pointers/data manipulation
+ * ----------------------------------------------------------------------------- */
+
+SWIGRUNTIMEINLINE PyObject *
+_SWIG_This(void)
+{
+ return SWIG_Python_str_FromChar("this");
+}
+
+static PyObject *swig_this = NULL;
+
+SWIGRUNTIME PyObject *
+SWIG_This(void)
+{
+ if (swig_this == NULL)
+ swig_this = _SWIG_This();
+ return swig_this;
+}
+
+/* #define SWIG_PYTHON_SLOW_GETSET_THIS */
+
+/* TODO: I don't know how to implement the fast getset in Python 3 right now */
+#if PY_VERSION_HEX>=0x03000000
+#define SWIG_PYTHON_SLOW_GETSET_THIS
+#endif
+
+SWIGRUNTIME SwigPyObject *
+SWIG_Python_GetSwigThis(PyObject *pyobj)
+{
+ PyObject *obj;
+
+ if (SwigPyObject_Check(pyobj))
+ return (SwigPyObject *) pyobj;
+
+#ifdef SWIGPYTHON_BUILTIN
+ (void)obj;
+# ifdef PyWeakref_CheckProxy
+ if (PyWeakref_CheckProxy(pyobj)) {
+ pyobj = PyWeakref_GET_OBJECT(pyobj);
+ if (pyobj && SwigPyObject_Check(pyobj))
+ return (SwigPyObject*) pyobj;
+ }
+# endif
+ return NULL;
+#else
+
+ obj = 0;
+
+#if (!defined(SWIG_PYTHON_SLOW_GETSET_THIS) && (PY_VERSION_HEX >= 0x02030000))
+ if (PyInstance_Check(pyobj)) {
+ obj = _PyInstance_Lookup(pyobj, SWIG_This());
+ } else {
+ PyObject **dictptr = _PyObject_GetDictPtr(pyobj);
+ if (dictptr != NULL) {
+ PyObject *dict = *dictptr;
+ obj = dict ? PyDict_GetItem(dict, SWIG_This()) : 0;
+ } else {
+#ifdef PyWeakref_CheckProxy
+ if (PyWeakref_CheckProxy(pyobj)) {
+ PyObject *wobj = PyWeakref_GET_OBJECT(pyobj);
+ return wobj ? SWIG_Python_GetSwigThis(wobj) : 0;
+ }
+#endif
+ obj = PyObject_GetAttr(pyobj,SWIG_This());
+ if (obj) {
+ Py_DECREF(obj);
+ } else {
+ if (PyErr_Occurred()) PyErr_Clear();
+ return 0;
+ }
+ }
+ }
+#else
+ obj = PyObject_GetAttr(pyobj,SWIG_This());
+ if (obj) {
+ Py_DECREF(obj);
+ } else {
+ if (PyErr_Occurred()) PyErr_Clear();
+ return 0;
+ }
+#endif
+ if (obj && !SwigPyObject_Check(obj)) {
+ /* a PyObject is called 'this', try to get the 'real this'
+ SwigPyObject from it */
+ return SWIG_Python_GetSwigThis(obj);
+ }
+ return (SwigPyObject *)obj;
+#endif
+}
+
+/* Acquire a pointer value */
+
+SWIGRUNTIME int
+SWIG_Python_AcquirePtr(PyObject *obj, int own) {
+ if (own == SWIG_POINTER_OWN) {
+ SwigPyObject *sobj = SWIG_Python_GetSwigThis(obj);
+ if (sobj) {
+ int oldown = sobj->own;
+ sobj->own = own;
+ return oldown;
+ }
+ }
+ return 0;
+}
+
+/* Convert a pointer value */
+
+SWIGRUNTIME int
+SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int flags, int *own) {
+ int res;
+ SwigPyObject *sobj;
+
+ if (!obj)
+ return SWIG_ERROR;
+ if (obj == Py_None) {
+ if (ptr)
+ *ptr = 0;
+ return SWIG_OK;
+ }
+
+ res = SWIG_ERROR;
+
+ sobj = SWIG_Python_GetSwigThis(obj);
+ if (own)
+ *own = 0;
+ while (sobj) {
+ void *vptr = sobj->ptr;
+ if (ty) {
+ swig_type_info *to = sobj->ty;
+ if (to == ty) {
+ /* no type cast needed */
+ if (ptr) *ptr = vptr;
+ break;
+ } else {
+ swig_cast_info *tc = SWIG_TypeCheck(to->name,ty);
+ if (!tc) {
+ sobj = (SwigPyObject *)sobj->next;
+ } else {
+ if (ptr) {
+ int newmemory = 0;
+ *ptr = SWIG_TypeCast(tc,vptr,&newmemory);
+ if (newmemory == SWIG_CAST_NEW_MEMORY) {
+ assert(own); /* badly formed typemap which will lead to a memory leak - it must set and use own to delete *ptr */
+ if (own)
+ *own = *own | SWIG_CAST_NEW_MEMORY;
+ }
+ }
+ break;
+ }
+ }
+ } else {
+ if (ptr) *ptr = vptr;
+ break;
+ }
+ }
+ if (sobj) {
+ if (own)
+ *own = *own | sobj->own;
+ if (flags & SWIG_POINTER_DISOWN) {
+ sobj->own = 0;
+ }
+ res = SWIG_OK;
+ } else {
+ if (flags & SWIG_POINTER_IMPLICIT_CONV) {
+ SwigPyClientData *data = ty ? (SwigPyClientData *) ty->clientdata : 0;
+ if (data && !data->implicitconv) {
+ PyObject *klass = data->klass;
+ if (klass) {
+ PyObject *impconv;
+ data->implicitconv = 1; /* avoid recursion and call 'explicit' constructors*/
+ impconv = SWIG_Python_CallFunctor(klass, obj);
+ data->implicitconv = 0;
+ if (PyErr_Occurred()) {
+ PyErr_Clear();
+ impconv = 0;
+ }
+ if (impconv) {
+ SwigPyObject *iobj = SWIG_Python_GetSwigThis(impconv);
+ if (iobj) {
+ void *vptr;
+ res = SWIG_Python_ConvertPtrAndOwn((PyObject*)iobj, &vptr, ty, 0, 0);
+ if (SWIG_IsOK(res)) {
+ if (ptr) {
+ *ptr = vptr;
+ /* transfer the ownership to 'ptr' */
+ iobj->own = 0;
+ res = SWIG_AddCast(res);
+ res = SWIG_AddNewMask(res);
+ } else {
+ res = SWIG_AddCast(res);
+ }
+ }
+ }
+ Py_DECREF(impconv);
+ }
+ }
+ }
+ }
+ }
+ return res;
+}
+
+/* Convert a function ptr value */
+
+SWIGRUNTIME int
+SWIG_Python_ConvertFunctionPtr(PyObject *obj, void **ptr, swig_type_info *ty) {
+ if (!PyCFunction_Check(obj)) {
+ return SWIG_ConvertPtr(obj, ptr, ty, 0);
+ } else {
+ void *vptr = 0;
+
+ /* here we get the method pointer for callbacks */
+ const char *doc = (((PyCFunctionObject *)obj) -> m_ml -> ml_doc);
+ const char *desc = doc ? strstr(doc, "swig_ptr: ") : 0;
+ if (desc)
+ desc = ty ? SWIG_UnpackVoidPtr(desc + 10, &vptr, ty->name) : 0;
+ if (!desc)
+ return SWIG_ERROR;
+ if (ty) {
+ swig_cast_info *tc = SWIG_TypeCheck(desc,ty);
+ if (tc) {
+ int newmemory = 0;
+ *ptr = SWIG_TypeCast(tc,vptr,&newmemory);
+ assert(!newmemory); /* newmemory handling not yet implemented */
+ } else {
+ return SWIG_ERROR;
+ }
+ } else {
+ *ptr = vptr;
+ }
+ return SWIG_OK;
+ }
+}
+
+/* Convert a packed value value */
+
+SWIGRUNTIME int
+SWIG_Python_ConvertPacked(PyObject *obj, void *ptr, size_t sz, swig_type_info *ty) {
+ swig_type_info *to = SwigPyPacked_UnpackData(obj, ptr, sz);
+ if (!to) return SWIG_ERROR;
+ if (ty) {
+ if (to != ty) {
+ /* check type cast? */
+ swig_cast_info *tc = SWIG_TypeCheck(to->name,ty);
+ if (!tc) return SWIG_ERROR;
+ }
+ }
+ return SWIG_OK;
+}
+
+/* -----------------------------------------------------------------------------
+ * Create a new pointer object
+ * ----------------------------------------------------------------------------- */
+
+/*
+ Create a new instance object, without calling __init__, and set the
+ 'this' attribute.
+*/
+
+SWIGRUNTIME PyObject*
+SWIG_Python_NewShadowInstance(SwigPyClientData *data, PyObject *swig_this)
+{
+#if (PY_VERSION_HEX >= 0x02020000)
+ PyObject *inst = 0;
+ PyObject *newraw = data->newraw;
+ if (newraw) {
+ inst = PyObject_Call(newraw, data->newargs, NULL);
+ if (inst) {
+#if !defined(SWIG_PYTHON_SLOW_GETSET_THIS)
+ PyObject **dictptr = _PyObject_GetDictPtr(inst);
+ if (dictptr != NULL) {
+ PyObject *dict = *dictptr;
+ if (dict == NULL) {
+ dict = PyDict_New();
+ *dictptr = dict;
+ PyDict_SetItem(dict, SWIG_This(), swig_this);
+ }
+ }
+#else
+ PyObject *key = SWIG_This();
+ PyObject_SetAttr(inst, key, swig_this);
+#endif
+ }
+ } else {
+#if PY_VERSION_HEX >= 0x03000000
+ inst = PyBaseObject_Type.tp_new((PyTypeObject*) data->newargs, Py_None, Py_None);
+ if (inst) {
+ PyObject_SetAttr(inst, SWIG_This(), swig_this);
+ Py_TYPE(inst)->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG;
+ }
+#else
+ PyObject *dict = PyDict_New();
+ if (dict) {
+ PyDict_SetItem(dict, SWIG_This(), swig_this);
+ inst = PyInstance_NewRaw(data->newargs, dict);
+ Py_DECREF(dict);
+ }
+#endif
+ }
+ return inst;
+#else
+#if (PY_VERSION_HEX >= 0x02010000)
+ PyObject *inst = 0;
+ PyObject *dict = PyDict_New();
+ if (dict) {
+ PyDict_SetItem(dict, SWIG_This(), swig_this);
+ inst = PyInstance_NewRaw(data->newargs, dict);
+ Py_DECREF(dict);
+ }
+ return (PyObject *) inst;
+#else
+ PyInstanceObject *inst = PyObject_NEW(PyInstanceObject, &PyInstance_Type);
+ if (inst == NULL) {
+ return NULL;
+ }
+ inst->in_class = (PyClassObject *)data->newargs;
+ Py_INCREF(inst->in_class);
+ inst->in_dict = PyDict_New();
+ if (inst->in_dict == NULL) {
+ Py_DECREF(inst);
+ return NULL;
+ }
+#ifdef Py_TPFLAGS_HAVE_WEAKREFS
+ inst->in_weakreflist = NULL;
+#endif
+#ifdef Py_TPFLAGS_GC
+ PyObject_GC_Init(inst);
+#endif
+ PyDict_SetItem(inst->in_dict, SWIG_This(), swig_this);
+ return (PyObject *) inst;
+#endif
+#endif
+}
+
+SWIGRUNTIME void
+SWIG_Python_SetSwigThis(PyObject *inst, PyObject *swig_this)
+{
+ PyObject *dict;
+#if (PY_VERSION_HEX >= 0x02020000) && !defined(SWIG_PYTHON_SLOW_GETSET_THIS)
+ PyObject **dictptr = _PyObject_GetDictPtr(inst);
+ if (dictptr != NULL) {
+ dict = *dictptr;
+ if (dict == NULL) {
+ dict = PyDict_New();
+ *dictptr = dict;
+ }
+ PyDict_SetItem(dict, SWIG_This(), swig_this);
+ return;
+ }
+#endif
+ dict = PyObject_GetAttrString(inst, (char*)"__dict__");
+ PyDict_SetItem(dict, SWIG_This(), swig_this);
+ Py_DECREF(dict);
+}
+
+
+SWIGINTERN PyObject *
+SWIG_Python_InitShadowInstance(PyObject *args) {
+ PyObject *obj[2];
+ if (!SWIG_Python_UnpackTuple(args, "swiginit", 2, 2, obj)) {
+ return NULL;
+ } else {
+ SwigPyObject *sthis = SWIG_Python_GetSwigThis(obj[0]);
+ if (sthis) {
+ SwigPyObject_append((PyObject*) sthis, obj[1]);
+ } else {
+ SWIG_Python_SetSwigThis(obj[0], obj[1]);
+ }
+ return SWIG_Py_Void();
+ }
+}
+
+/* Create a new pointer object */
+
+SWIGRUNTIME PyObject *
+SWIG_Python_NewPointerObj(PyObject *self, void *ptr, swig_type_info *type, int flags) {
+ SwigPyClientData *clientdata;
+ PyObject * robj;
+ int own;
+
+ if (!ptr)
+ return SWIG_Py_Void();
+
+ clientdata = type ? (SwigPyClientData *)(type->clientdata) : 0;
+ own = (flags & SWIG_POINTER_OWN) ? SWIG_POINTER_OWN : 0;
+ if (clientdata && clientdata->pytype) {
+ SwigPyObject *newobj;
+ if (flags & SWIG_BUILTIN_TP_INIT) {
+ newobj = (SwigPyObject*) self;
+ if (newobj->ptr) {
+ PyObject *next_self = clientdata->pytype->tp_alloc(clientdata->pytype, 0);
+ while (newobj->next)
+ newobj = (SwigPyObject *) newobj->next;
+ newobj->next = next_self;
+ newobj = (SwigPyObject *)next_self;
+ }
+ } else {
+ newobj = PyObject_New(SwigPyObject, clientdata->pytype);
+ }
+ if (newobj) {
+ newobj->ptr = ptr;
+ newobj->ty = type;
+ newobj->own = own;
+ newobj->next = 0;
+#ifdef SWIGPYTHON_BUILTIN
+ newobj->dict = 0;
+#endif
+ return (PyObject*) newobj;
+ }
+ return SWIG_Py_Void();
+ }
+
+ assert(!(flags & SWIG_BUILTIN_TP_INIT));
+
+ robj = SwigPyObject_New(ptr, type, own);
+ if (robj && clientdata && !(flags & SWIG_POINTER_NOSHADOW)) {
+ PyObject *inst = SWIG_Python_NewShadowInstance(clientdata, robj);
+ Py_DECREF(robj);
+ robj = inst;
+ }
+ return robj;
+}
+
+/* Create a new packed object */
+
+SWIGRUNTIMEINLINE PyObject *
+SWIG_Python_NewPackedObj(void *ptr, size_t sz, swig_type_info *type) {
+ return ptr ? SwigPyPacked_New((void *) ptr, sz, type) : SWIG_Py_Void();
+}
+
+/* -----------------------------------------------------------------------------*
+ * Get type list
+ * -----------------------------------------------------------------------------*/
+
+#ifdef SWIG_LINK_RUNTIME
+void *SWIG_ReturnGlobalTypeList(void *);
+#endif
+
+SWIGRUNTIME swig_module_info *
+SWIG_Python_GetModule(void *SWIGUNUSEDPARM(clientdata)) {
+ static void *type_pointer = (void *)0;
+ /* first check if module already created */
+ if (!type_pointer) {
+#ifdef SWIG_LINK_RUNTIME
+ type_pointer = SWIG_ReturnGlobalTypeList((void *)0);
+#else
+# ifdef SWIGPY_USE_CAPSULE
+ type_pointer = PyCapsule_Import(SWIGPY_CAPSULE_NAME, 0);
+# else
+ type_pointer = PyCObject_Import((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION,
+ (char*)"type_pointer" SWIG_TYPE_TABLE_NAME);
+# endif
+ if (PyErr_Occurred()) {
+ PyErr_Clear();
+ type_pointer = (void *)0;
+ }
+#endif
+ }
+ return (swig_module_info *) type_pointer;
+}
+
+#if PY_MAJOR_VERSION < 2
+/* PyModule_AddObject function was introduced in Python 2.0. The following function
+ is copied out of Python/modsupport.c in python version 2.3.4 */
+SWIGINTERN int
+PyModule_AddObject(PyObject *m, char *name, PyObject *o)
+{
+ PyObject *dict;
+ if (!PyModule_Check(m)) {
+ PyErr_SetString(PyExc_TypeError,
+ "PyModule_AddObject() needs module as first arg");
+ return SWIG_ERROR;
+ }
+ if (!o) {
+ PyErr_SetString(PyExc_TypeError,
+ "PyModule_AddObject() needs non-NULL value");
+ return SWIG_ERROR;
+ }
+
+ dict = PyModule_GetDict(m);
+ if (dict == NULL) {
+ /* Internal error -- modules must have a dict! */
+ PyErr_Format(PyExc_SystemError, "module '%s' has no __dict__",
+ PyModule_GetName(m));
+ return SWIG_ERROR;
+ }
+ if (PyDict_SetItemString(dict, name, o))
+ return SWIG_ERROR;
+ Py_DECREF(o);
+ return SWIG_OK;
+}
+#endif
+
+SWIGRUNTIME void
+#ifdef SWIGPY_USE_CAPSULE
+SWIG_Python_DestroyModule(PyObject *obj)
+#else
+SWIG_Python_DestroyModule(void *vptr)
+#endif
+{
+#ifdef SWIGPY_USE_CAPSULE
+ swig_module_info *swig_module = (swig_module_info *) PyCapsule_GetPointer(obj, SWIGPY_CAPSULE_NAME);
+#else
+ swig_module_info *swig_module = (swig_module_info *) vptr;
+#endif
+ swig_type_info **types = swig_module->types;
+ size_t i;
+ for (i =0; i < swig_module->size; ++i) {
+ swig_type_info *ty = types[i];
+ if (ty->owndata) {
+ SwigPyClientData *data = (SwigPyClientData *) ty->clientdata;
+ if (data) SwigPyClientData_Del(data);
+ }
+ }
+ Py_DECREF(SWIG_This());
+ swig_this = NULL;
+}
+
+SWIGRUNTIME void
+SWIG_Python_SetModule(swig_module_info *swig_module) {
+#if PY_VERSION_HEX >= 0x03000000
+ /* Add a dummy module object into sys.modules */
+ PyObject *module = PyImport_AddModule((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION);
+#else
+ static PyMethodDef swig_empty_runtime_method_table[] = { {NULL, NULL, 0, NULL} }; /* Sentinel */
+ PyObject *module = Py_InitModule((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION, swig_empty_runtime_method_table);
+#endif
+#ifdef SWIGPY_USE_CAPSULE
+ PyObject *pointer = PyCapsule_New((void *) swig_module, SWIGPY_CAPSULE_NAME, SWIG_Python_DestroyModule);
+ if (pointer && module) {
+ PyModule_AddObject(module, (char*)"type_pointer_capsule" SWIG_TYPE_TABLE_NAME, pointer);
+ } else {
+ Py_XDECREF(pointer);
+ }
+#else
+ PyObject *pointer = PyCObject_FromVoidPtr((void *) swig_module, SWIG_Python_DestroyModule);
+ if (pointer && module) {
+ PyModule_AddObject(module, (char*)"type_pointer" SWIG_TYPE_TABLE_NAME, pointer);
+ } else {
+ Py_XDECREF(pointer);
+ }
+#endif
+}
+
+/* The python cached type query */
+SWIGRUNTIME PyObject *
+SWIG_Python_TypeCache(void) {
+ static PyObject *SWIG_STATIC_POINTER(cache) = PyDict_New();
+ return cache;
+}
+
+SWIGRUNTIME swig_type_info *
+SWIG_Python_TypeQuery(const char *type)
+{
+ PyObject *cache = SWIG_Python_TypeCache();
+ PyObject *key = SWIG_Python_str_FromChar(type);
+ PyObject *obj = PyDict_GetItem(cache, key);
+ swig_type_info *descriptor;
+ if (obj) {
+#ifdef SWIGPY_USE_CAPSULE
+ descriptor = (swig_type_info *) PyCapsule_GetPointer(obj, NULL);
+#else
+ descriptor = (swig_type_info *) PyCObject_AsVoidPtr(obj);
+#endif
+ } else {
+ swig_module_info *swig_module = SWIG_GetModule(0);
+ descriptor = SWIG_TypeQueryModule(swig_module, swig_module, type);
+ if (descriptor) {
+#ifdef SWIGPY_USE_CAPSULE
+ obj = PyCapsule_New((void*) descriptor, NULL, NULL);
+#else
+ obj = PyCObject_FromVoidPtr(descriptor, NULL);
+#endif
+ PyDict_SetItem(cache, key, obj);
+ Py_DECREF(obj);
+ }
+ }
+ Py_DECREF(key);
+ return descriptor;
+}
+
+/*
+ For backward compatibility only
+*/
+#define SWIG_POINTER_EXCEPTION 0
+#define SWIG_arg_fail(arg) SWIG_Python_ArgFail(arg)
+#define SWIG_MustGetPtr(p, type, argnum, flags) SWIG_Python_MustGetPtr(p, type, argnum, flags)
+
+SWIGRUNTIME int
+SWIG_Python_AddErrMesg(const char* mesg, int infront)
+{
+ if (PyErr_Occurred()) {
+ PyObject *type = 0;
+ PyObject *value = 0;
+ PyObject *traceback = 0;
+ PyErr_Fetch(&type, &value, &traceback);
+ if (value) {
+ char *tmp;
+ PyObject *old_str = PyObject_Str(value);
+ Py_XINCREF(type);
+ PyErr_Clear();
+ if (infront) {
+ PyErr_Format(type, "%s %s", mesg, tmp = SWIG_Python_str_AsChar(old_str));
+ } else {
+ PyErr_Format(type, "%s %s", tmp = SWIG_Python_str_AsChar(old_str), mesg);
+ }
+ SWIG_Python_str_DelForPy3(tmp);
+ Py_DECREF(old_str);
+ }
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+SWIGRUNTIME int
+SWIG_Python_ArgFail(int argnum)
+{
+ if (PyErr_Occurred()) {
+ /* add information about failing argument */
+ char mesg[256];
+ PyOS_snprintf(mesg, sizeof(mesg), "argument number %d:", argnum);
+ return SWIG_Python_AddErrMesg(mesg, 1);
+ } else {
+ return 0;
+ }
+}
+
+SWIGRUNTIMEINLINE const char *
+SwigPyObject_GetDesc(PyObject *self)
+{
+ SwigPyObject *v = (SwigPyObject *)self;
+ swig_type_info *ty = v ? v->ty : 0;
+ return ty ? ty->str : "";
+}
+
+SWIGRUNTIME void
+SWIG_Python_TypeError(const char *type, PyObject *obj)
+{
+ if (type) {
+#if defined(SWIG_COBJECT_TYPES)
+ if (obj && SwigPyObject_Check(obj)) {
+ const char *otype = (const char *) SwigPyObject_GetDesc(obj);
+ if (otype) {
+ PyErr_Format(PyExc_TypeError, "a '%s' is expected, 'SwigPyObject(%s)' is received",
+ type, otype);
+ return;
+ }
+ } else
+#endif
+ {
+ const char *otype = (obj ? obj->ob_type->tp_name : 0);
+ if (otype) {
+ PyObject *str = PyObject_Str(obj);
+ const char *cstr = str ? SWIG_Python_str_AsChar(str) : 0;
+ if (cstr) {
+ PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s(%s)' is received",
+ type, otype, cstr);
+ SWIG_Python_str_DelForPy3(cstr);
+ } else {
+ PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s' is received",
+ type, otype);
+ }
+ Py_XDECREF(str);
+ return;
+ }
+ }
+ PyErr_Format(PyExc_TypeError, "a '%s' is expected", type);
+ } else {
+ PyErr_Format(PyExc_TypeError, "unexpected type is received");
+ }
+}
+
+
+/* Convert a pointer value, signal an exception on a type mismatch */
+SWIGRUNTIME void *
+SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int SWIGUNUSEDPARM(argnum), int flags) {
+ void *result;
+ if (SWIG_Python_ConvertPtr(obj, &result, ty, flags) == -1) {
+ PyErr_Clear();
+#if SWIG_POINTER_EXCEPTION
+ if (flags) {
+ SWIG_Python_TypeError(SWIG_TypePrettyName(ty), obj);
+ SWIG_Python_ArgFail(argnum);
+ }
+#endif
+ }
+ return result;
+}
+
+#ifdef SWIGPYTHON_BUILTIN
+SWIGRUNTIME int
+SWIG_Python_NonDynamicSetAttr(PyObject *obj, PyObject *name, PyObject *value) {
+ PyTypeObject *tp = obj->ob_type;
+ PyObject *descr;
+ PyObject *encoded_name;
+ descrsetfunc f;
+ int res;
+
+# ifdef Py_USING_UNICODE
+ if (PyString_Check(name)) {
+ name = PyUnicode_Decode(PyString_AsString(name), PyString_Size(name), NULL, NULL);
+ if (!name)
+ return -1;
+ } else if (!PyUnicode_Check(name))
+# else
+ if (!PyString_Check(name))
+# endif
+ {
+ PyErr_Format(PyExc_TypeError, "attribute name must be string, not '%.200s'", name->ob_type->tp_name);
+ return -1;
+ } else {
+ Py_INCREF(name);
+ }
+
+ if (!tp->tp_dict) {
+ if (PyType_Ready(tp) < 0)
+ goto done;
+ }
+
+ res = -1;
+ descr = _PyType_Lookup(tp, name);
+ f = NULL;
+ if (descr != NULL)
+ f = descr->ob_type->tp_descr_set;
+ if (!f) {
+ if (PyString_Check(name)) {
+ encoded_name = name;
+ Py_INCREF(name);
+ } else {
+ encoded_name = PyUnicode_AsUTF8String(name);
+ }
+ PyErr_Format(PyExc_AttributeError, "'%.100s' object has no attribute '%.200s'", tp->tp_name, PyString_AsString(encoded_name));
+ Py_DECREF(encoded_name);
+ } else {
+ res = f(descr, obj, value);
+ }
+
+ done:
+ Py_DECREF(name);
+ return res;
+}
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#define SWIGPY_UNARYFUNC_CLOSURE(wrapper) \
+SWIGINTERN PyObject * \
+wrapper##_closure(PyObject *a) { \
+ return wrapper(a, NULL); \
+}
+
+#define SWIGPY_DESTRUCTOR_CLOSURE(wrapper) \
+SWIGINTERN void \
+wrapper##_closure(PyObject *a) { \
+ SwigPyObject *sobj; \
+ sobj = (SwigPyObject *)a; \
+ if (sobj->own) { \
+ PyObject *o = wrapper(a, NULL); \
+ Py_XDECREF(o); \
+ } \
+ PyObject_Del(a); \
+}
+
+#define SWIGPY_INQUIRY_CLOSURE(wrapper) \
+SWIGINTERN int \
+wrapper##_closure(PyObject *a) { \
+ PyObject *pyresult; \
+ int result; \
+ pyresult = wrapper(a, NULL); \
+ result = pyresult && PyObject_IsTrue(pyresult) ? 1 : 0; \
+ Py_XDECREF(pyresult); \
+ return result; \
+}
+
+#define SWIGPY_BINARYFUNC_CLOSURE(wrapper) \
+SWIGINTERN PyObject * \
+wrapper##_closure(PyObject *a, PyObject *b) { \
+ PyObject *tuple, *result; \
+ tuple = PyTuple_New(1); \
+ assert(tuple); \
+ PyTuple_SET_ITEM(tuple, 0, b); \
+ Py_XINCREF(b); \
+ result = wrapper(a, tuple); \
+ Py_DECREF(tuple); \
+ return result; \
+}
+
+typedef ternaryfunc ternarycallfunc;
+
+#define SWIGPY_TERNARYFUNC_CLOSURE(wrapper) \
+SWIGINTERN PyObject * \
+wrapper##_closure(PyObject *a, PyObject *b, PyObject *c) { \
+ PyObject *tuple, *result; \
+ tuple = PyTuple_New(2); \
+ assert(tuple); \
+ PyTuple_SET_ITEM(tuple, 0, b); \
+ PyTuple_SET_ITEM(tuple, 1, c); \
+ Py_XINCREF(b); \
+ Py_XINCREF(c); \
+ result = wrapper(a, tuple); \
+ Py_DECREF(tuple); \
+ return result; \
+}
+
+#define SWIGPY_TERNARYCALLFUNC_CLOSURE(wrapper) \
+SWIGINTERN PyObject * \
+wrapper##_closure(PyObject *callable_object, PyObject *args, PyObject *) { \
+ return wrapper(callable_object, args); \
+}
+
+#define SWIGPY_LENFUNC_CLOSURE(wrapper) \
+SWIGINTERN Py_ssize_t \
+wrapper##_closure(PyObject *a) { \
+ PyObject *resultobj; \
+ Py_ssize_t result; \
+ resultobj = wrapper(a, NULL); \
+ result = PyNumber_AsSsize_t(resultobj, NULL); \
+ Py_DECREF(resultobj); \
+ return result; \
+}
+
+#define SWIGPY_SSIZESSIZEARGFUNC_CLOSURE(wrapper) \
+SWIGINTERN PyObject * \
+wrapper##_closure(PyObject *a, Py_ssize_t b, Py_ssize_t c) { \
+ PyObject *tuple, *result; \
+ tuple = PyTuple_New(2); \
+ assert(tuple); \
+ PyTuple_SET_ITEM(tuple, 0, _PyLong_FromSsize_t(b)); \
+ PyTuple_SET_ITEM(tuple, 1, _PyLong_FromSsize_t(c)); \
+ result = wrapper(a, tuple); \
+ Py_DECREF(tuple); \
+ return result; \
+}
+
+#define SWIGPY_SSIZESSIZEOBJARGPROC_CLOSURE(wrapper) \
+SWIGINTERN int \
+wrapper##_closure(PyObject *a, Py_ssize_t b, Py_ssize_t c, PyObject *d) { \
+ PyObject *tuple, *resultobj; \
+ int result; \
+ tuple = PyTuple_New(d ? 3 : 2); \
+ assert(tuple); \
+ PyTuple_SET_ITEM(tuple, 0, _PyLong_FromSsize_t(b)); \
+ PyTuple_SET_ITEM(tuple, 1, _PyLong_FromSsize_t(c)); \
+ if (d) { \
+ PyTuple_SET_ITEM(tuple, 2, d); \
+ Py_INCREF(d); \
+ } \
+ resultobj = wrapper(a, tuple); \
+ result = resultobj ? 0 : -1; \
+ Py_DECREF(tuple); \
+ Py_XDECREF(resultobj); \
+ return result; \
+}
+
+#define SWIGPY_SSIZEARGFUNC_CLOSURE(wrapper) \
+SWIGINTERN PyObject * \
+wrapper##_closure(PyObject *a, Py_ssize_t b) { \
+ PyObject *tuple, *result; \
+ tuple = PyTuple_New(1); \
+ assert(tuple); \
+ PyTuple_SET_ITEM(tuple, 0, _PyLong_FromSsize_t(b)); \
+ result = wrapper(a, tuple); \
+ Py_DECREF(tuple); \
+ return result; \
+}
+
+#define SWIGPY_FUNPACK_SSIZEARGFUNC_CLOSURE(wrapper) \
+SWIGINTERN PyObject * \
+wrapper##_closure(PyObject *a, Py_ssize_t b) { \
+ PyObject *arg, *result; \
+ arg = _PyLong_FromSsize_t(b); \
+ result = wrapper(a, arg); \
+ Py_DECREF(arg); \
+ return result; \
+}
+
+#define SWIGPY_SSIZEOBJARGPROC_CLOSURE(wrapper) \
+SWIGINTERN int \
+wrapper##_closure(PyObject *a, Py_ssize_t b, PyObject *c) { \
+ PyObject *tuple, *resultobj; \
+ int result; \
+ tuple = PyTuple_New(2); \
+ assert(tuple); \
+ PyTuple_SET_ITEM(tuple, 0, _PyLong_FromSsize_t(b)); \
+ PyTuple_SET_ITEM(tuple, 1, c); \
+ Py_XINCREF(c); \
+ resultobj = wrapper(a, tuple); \
+ result = resultobj ? 0 : -1; \
+ Py_XDECREF(resultobj); \
+ Py_DECREF(tuple); \
+ return result; \
+}
+
+#define SWIGPY_OBJOBJARGPROC_CLOSURE(wrapper) \
+SWIGINTERN int \
+wrapper##_closure(PyObject *a, PyObject *b, PyObject *c) { \
+ PyObject *tuple, *resultobj; \
+ int result; \
+ tuple = PyTuple_New(c ? 2 : 1); \
+ assert(tuple); \
+ PyTuple_SET_ITEM(tuple, 0, b); \
+ Py_XINCREF(b); \
+ if (c) { \
+ PyTuple_SET_ITEM(tuple, 1, c); \
+ Py_XINCREF(c); \
+ } \
+ resultobj = wrapper(a, tuple); \
+ result = resultobj ? 0 : -1; \
+ Py_XDECREF(resultobj); \
+ Py_DECREF(tuple); \
+ return result; \
+}
+
+#define SWIGPY_REPRFUNC_CLOSURE(wrapper) \
+SWIGINTERN PyObject * \
+wrapper##_closure(PyObject *a) { \
+ return wrapper(a, NULL); \
+}
+
+#define SWIGPY_HASHFUNC_CLOSURE(wrapper) \
+SWIGINTERN long \
+wrapper##_closure(PyObject *a) { \
+ PyObject *pyresult; \
+ long result; \
+ pyresult = wrapper(a, NULL); \
+ if (!pyresult || !PyLong_Check(pyresult)) \
+ return -1; \
+ result = PyLong_AsLong(pyresult); \
+ Py_DECREF(pyresult); \
+ return result; \
+}
+
+#define SWIGPY_ITERNEXT_CLOSURE(wrapper) \
+SWIGINTERN PyObject * \
+wrapper##_closure(PyObject *a) { \
+ PyObject *result; \
+ result = wrapper(a, NULL); \
+ if (result && result == Py_None) { \
+ Py_DECREF(result); \
+ result = NULL; \
+ } \
+ return result; \
+}
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+SWIGINTERN int
+SwigPyBuiltin_BadInit(PyObject *self, PyObject *SWIGUNUSEDPARM(args), PyObject *SWIGUNUSEDPARM(kwds)) {
+ PyErr_Format(PyExc_TypeError, "Cannot create new instances of type '%.300s'", self->ob_type->tp_name);
+ return -1;
+}
+
+SWIGINTERN void
+SwigPyBuiltin_BadDealloc(PyObject *pyobj) {
+ SwigPyObject *sobj;
+ sobj = (SwigPyObject *)pyobj;
+ if (sobj->own) {
+ PyErr_Format(PyExc_TypeError, "Swig detected a memory leak in type '%.300s': no callable destructor found.", pyobj->ob_type->tp_name);
+ }
+}
+
+typedef struct {
+ PyCFunction get;
+ PyCFunction set;
+} SwigPyGetSet;
+
+SWIGINTERN PyObject *
+SwigPyBuiltin_GetterClosure (PyObject *obj, void *closure) {
+ SwigPyGetSet *getset;
+ PyObject *tuple, *result;
+ if (!closure)
+ return SWIG_Py_Void();
+ getset = (SwigPyGetSet *)closure;
+ if (!getset->get)
+ return SWIG_Py_Void();
+ tuple = PyTuple_New(0);
+ assert(tuple);
+ result = (*getset->get)(obj, tuple);
+ Py_DECREF(tuple);
+ return result;
+}
+
+SWIGINTERN PyObject *
+SwigPyBuiltin_FunpackGetterClosure (PyObject *obj, void *closure) {
+ SwigPyGetSet *getset;
+ PyObject *result;
+ if (!closure)
+ return SWIG_Py_Void();
+ getset = (SwigPyGetSet *)closure;
+ if (!getset->get)
+ return SWIG_Py_Void();
+ result = (*getset->get)(obj, NULL);
+ return result;
+}
+
+SWIGINTERN int
+SwigPyBuiltin_SetterClosure (PyObject *obj, PyObject *val, void *closure) {
+ SwigPyGetSet *getset;
+ PyObject *tuple, *result;
+ if (!closure) {
+ PyErr_Format(PyExc_TypeError, "Missing getset closure");
+ return -1;
+ }
+ getset = (SwigPyGetSet *)closure;
+ if (!getset->set) {
+ PyErr_Format(PyExc_TypeError, "Illegal member variable assignment in type '%.300s'", obj->ob_type->tp_name);
+ return -1;
+ }
+ tuple = PyTuple_New(1);
+ assert(tuple);
+ PyTuple_SET_ITEM(tuple, 0, val);
+ Py_XINCREF(val);
+ result = (*getset->set)(obj, tuple);
+ Py_DECREF(tuple);
+ Py_XDECREF(result);
+ return result ? 0 : -1;
+}
+
+SWIGINTERN int
+SwigPyBuiltin_FunpackSetterClosure (PyObject *obj, PyObject *val, void *closure) {
+ SwigPyGetSet *getset;
+ PyObject *result;
+ if (!closure) {
+ PyErr_Format(PyExc_TypeError, "Missing getset closure");
+ return -1;
+ }
+ getset = (SwigPyGetSet *)closure;
+ if (!getset->set) {
+ PyErr_Format(PyExc_TypeError, "Illegal member variable assignment in type '%.300s'", obj->ob_type->tp_name);
+ return -1;
+ }
+ result = (*getset->set)(obj, val);
+ Py_XDECREF(result);
+ return result ? 0 : -1;
+}
+
+SWIGINTERN void
+SwigPyStaticVar_dealloc(PyDescrObject *descr) {
+ _PyObject_GC_UNTRACK(descr);
+ Py_XDECREF(PyDescr_TYPE(descr));
+ Py_XDECREF(PyDescr_NAME(descr));
+ PyObject_GC_Del(descr);
+}
+
+SWIGINTERN PyObject *
+SwigPyStaticVar_repr(PyGetSetDescrObject *descr) {
+#if PY_VERSION_HEX >= 0x03000000
+
+ return PyUnicode_FromFormat("<class attribute '%S' of type '%s'>", PyDescr_NAME(descr), PyDescr_TYPE(descr)->tp_name);
+#else
+ return PyString_FromFormat("<class attribute '%s' of type '%s'>", PyString_AsString(PyDescr_NAME(descr)), PyDescr_TYPE(descr)->tp_name);
+#endif
+}
+
+SWIGINTERN int
+SwigPyStaticVar_traverse(PyObject *self, visitproc visit, void *arg) {
+ PyDescrObject *descr;
+ descr = (PyDescrObject *)self;
+ Py_VISIT((PyObject*) PyDescr_TYPE(descr));
+ return 0;
+}
+
+SWIGINTERN PyObject *
+SwigPyStaticVar_get(PyGetSetDescrObject *descr, PyObject *obj, PyObject *SWIGUNUSEDPARM(type)) {
+ if (descr->d_getset->get != NULL)
+ return descr->d_getset->get(obj, descr->d_getset->closure);
+#if PY_VERSION_HEX >= 0x03000000
+ PyErr_Format(PyExc_AttributeError, "attribute '%.300S' of '%.100s' objects is not readable", PyDescr_NAME(descr), PyDescr_TYPE(descr)->tp_name);
+#else
+ PyErr_Format(PyExc_AttributeError, "attribute '%.300s' of '%.100s' objects is not readable", PyString_AsString(PyDescr_NAME(descr)), PyDescr_TYPE(descr)->tp_name);
+#endif
+ return NULL;
+}
+
+SWIGINTERN int
+SwigPyStaticVar_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value) {
+ if (descr->d_getset->set != NULL)
+ return descr->d_getset->set(obj, value, descr->d_getset->closure);
+#if PY_VERSION_HEX >= 0x03000000
+ PyErr_Format(PyExc_AttributeError, "attribute '%.300S' of '%.100s' objects is not writable", PyDescr_NAME(descr), PyDescr_TYPE(descr)->tp_name);
+#else
+ PyErr_Format(PyExc_AttributeError, "attribute '%.300s' of '%.100s' objects is not writable", PyString_AsString(PyDescr_NAME(descr)), PyDescr_TYPE(descr)->tp_name);
+#endif
+ return -1;
+}
+
+SWIGINTERN int
+SwigPyObjectType_setattro(PyTypeObject *type, PyObject *name, PyObject *value) {
+ PyObject *attribute;
+ descrsetfunc local_set;
+ attribute = _PyType_Lookup(type, name);
+ if (attribute != NULL) {
+ /* Implement descriptor functionality, if any */
+ local_set = attribute->ob_type->tp_descr_set;
+ if (local_set != NULL)
+ return local_set(attribute, (PyObject *)type, value);
+#if PY_VERSION_HEX >= 0x03000000
+ PyErr_Format(PyExc_AttributeError, "cannot modify read-only attribute '%.50s.%.400S'", type->tp_name, name);
+#else
+ PyErr_Format(PyExc_AttributeError, "cannot modify read-only attribute '%.50s.%.400s'", type->tp_name, PyString_AS_STRING(name));
+#endif
+ } else {
+#if PY_VERSION_HEX >= 0x03000000
+ PyErr_Format(PyExc_AttributeError, "type '%.50s' has no attribute '%.400S'", type->tp_name, name);
+#else
+ PyErr_Format(PyExc_AttributeError, "type '%.50s' has no attribute '%.400s'", type->tp_name, PyString_AS_STRING(name));
+#endif
+ }
+
+ return -1;
+}
+
+SWIGINTERN PyTypeObject*
+SwigPyStaticVar_Type(void) {
+ static PyTypeObject staticvar_type;
+ static int type_init = 0;
+ if (!type_init) {
+ const PyTypeObject tmp = {
+ /* PyObject header changed in Python 3 */
+#if PY_VERSION_HEX >= 0x03000000
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+#else
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+#endif
+ "swig_static_var_getset_descriptor",
+ sizeof(PyGetSetDescrObject),
+ 0,
+ (destructor)SwigPyStaticVar_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc)SwigPyStaticVar_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC|Py_TPFLAGS_HAVE_CLASS, /* tp_flags */
+ 0, /* tp_doc */
+ SwigPyStaticVar_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ (descrgetfunc)SwigPyStaticVar_get, /* tp_descr_get */
+ (descrsetfunc)SwigPyStaticVar_set, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ 0, /* tp_new */
+ 0, /* tp_free */
+ 0, /* tp_is_gc */
+ 0, /* tp_bases */
+ 0, /* tp_mro */
+ 0, /* tp_cache */
+ 0, /* tp_subclasses */
+ 0, /* tp_weaklist */
+#if PY_VERSION_HEX >= 0x02030000
+ 0, /* tp_del */
+#endif
+#if PY_VERSION_HEX >= 0x02060000
+ 0, /* tp_version */
+#endif
+#ifdef COUNT_ALLOCS
+ 0,0,0,0 /* tp_alloc -> tp_next */
+#endif
+ };
+ staticvar_type = tmp;
+ type_init = 1;
+#if PY_VERSION_HEX < 0x02020000
+ staticvar_type.ob_type = &PyType_Type;
+#else
+ if (PyType_Ready(&staticvar_type) < 0)
+ return NULL;
+#endif
+ }
+ return &staticvar_type;
+}
+
+SWIGINTERN PyGetSetDescrObject *
+SwigPyStaticVar_new_getset(PyTypeObject *type, PyGetSetDef *getset) {
+
+ PyGetSetDescrObject *descr;
+ descr = (PyGetSetDescrObject *)PyType_GenericAlloc(SwigPyStaticVar_Type(), 0);
+ assert(descr);
+ Py_XINCREF(type);
+ PyDescr_TYPE(descr) = type;
+ PyDescr_NAME(descr) = PyString_InternFromString(getset->name);
+ descr->d_getset = getset;
+ if (PyDescr_NAME(descr) == NULL) {
+ Py_DECREF(descr);
+ descr = NULL;
+ }
+ return descr;
+}
+
+SWIGINTERN void
+SwigPyBuiltin_InitBases (PyTypeObject *type, PyTypeObject **bases) {
+ int base_count = 0;
+ PyTypeObject **b;
+ PyObject *tuple;
+ int i;
+
+ if (!bases[0]) {
+ bases[0] = SwigPyObject_type();
+ bases[1] = NULL;
+ }
+ type->tp_base = bases[0];
+ Py_INCREF((PyObject *)bases[0]);
+ for (b = bases; *b != NULL; ++b)
+ ++base_count;
+ tuple = PyTuple_New(base_count);
+ for (i = 0; i < base_count; ++i) {
+ PyTuple_SET_ITEM(tuple, i, (PyObject *)bases[i]);
+ Py_INCREF((PyObject *)bases[i]);
+ }
+ type->tp_bases = tuple;
+}
+
+SWIGINTERN PyObject *
+SwigPyBuiltin_ThisClosure (PyObject *self, void *SWIGUNUSEDPARM(closure)) {
+ PyObject *result;
+ result = (PyObject *)SWIG_Python_GetSwigThis(self);
+ Py_XINCREF(result);
+ return result;
+}
+
+SWIGINTERN void
+SwigPyBuiltin_SetMetaType (PyTypeObject *type, PyTypeObject *metatype)
+{
+#if PY_VERSION_HEX >= 0x03000000
+ type->ob_base.ob_base.ob_type = metatype;
+#else
+ type->ob_type = metatype;
+#endif
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#define SWIG_exception_fail(code, msg) do { SWIG_Error(code, msg); SWIG_fail; } while(0)
+
+#define SWIG_contract_assert(expr, msg) if (!(expr)) { SWIG_Error(SWIG_RuntimeError, msg); SWIG_fail; } else
+
+
+
+ #define SWIG_exception(code, msg) do { SWIG_Error(code, msg); SWIG_fail;; } while(0)
+
+
+/* -------- TYPES TABLE (BEGIN) -------- */
+
+#define SWIGTYPE_p_AES_KEY swig_types[0]
+#define SWIGTYPE_p_ASN1_BIT_STRING swig_types[1]
+#define SWIGTYPE_p_ASN1_INTEGER swig_types[2]
+#define SWIGTYPE_p_ASN1_OBJECT swig_types[3]
+#define SWIGTYPE_p_ASN1_STRING swig_types[4]
+#define SWIGTYPE_p_ASN1_TIME swig_types[5]
+#define SWIGTYPE_p_BIGNUM swig_types[6]
+#define SWIGTYPE_p_BIO swig_types[7]
+#define SWIGTYPE_p_BIO_METHOD swig_types[8]
+#define SWIGTYPE_p_DH swig_types[9]
+#define SWIGTYPE_p_DSA swig_types[10]
+#define SWIGTYPE_p_ECDSA_SIG swig_types[11]
+#define SWIGTYPE_p_EC_KEY swig_types[12]
+#define SWIGTYPE_p_ENGINE swig_types[13]
+#define SWIGTYPE_p_EVP_CIPHER swig_types[14]
+#define SWIGTYPE_p_EVP_CIPHER_CTX swig_types[15]
+#define SWIGTYPE_p_EVP_MD swig_types[16]
+#define SWIGTYPE_p_EVP_MD_CTX swig_types[17]
+#define SWIGTYPE_p_EVP_PKEY swig_types[18]
+#define SWIGTYPE_p_FILE swig_types[19]
+#define SWIGTYPE_p_HMAC_CTX swig_types[20]
+#define SWIGTYPE_p_PKCS7 swig_types[21]
+#define SWIGTYPE_p_PyObject swig_types[22]
+#define SWIGTYPE_p_RC4_KEY swig_types[23]
+#define SWIGTYPE_p_RSA swig_types[24]
+#define SWIGTYPE_p_SSL swig_types[25]
+#define SWIGTYPE_p_SSL_CIPHER swig_types[26]
+#define SWIGTYPE_p_SSL_CTX swig_types[27]
+#define SWIGTYPE_p_SSL_METHOD swig_types[28]
+#define SWIGTYPE_p_SSL_SESSION swig_types[29]
+#define SWIGTYPE_p_SwigPyObject swig_types[30]
+#define SWIGTYPE_p_UI_METHOD swig_types[31]
+#define SWIGTYPE_p_X509 swig_types[32]
+#define SWIGTYPE_p_X509V3_CTX swig_types[33]
+#define SWIGTYPE_p_X509_CRL swig_types[34]
+#define SWIGTYPE_p_X509_EXTENSION swig_types[35]
+#define SWIGTYPE_p_X509_NAME swig_types[36]
+#define SWIGTYPE_p_X509_NAME_ENTRY swig_types[37]
+#define SWIGTYPE_p_X509_REQ swig_types[38]
+#define SWIGTYPE_p_X509_STORE swig_types[39]
+#define SWIGTYPE_p_X509_STORE_CTX swig_types[40]
+#define SWIGTYPE_p__cbd_t swig_types[41]
+#define SWIGTYPE_p_char swig_types[42]
+#define SWIGTYPE_p_f_int_p_X509_STORE_CTX__int swig_types[43]
+#define SWIGTYPE_p_f_p_q_const__void_p_q_const__void__int swig_types[44]
+#define SWIGTYPE_p_f_p_void__p_void swig_types[45]
+#define SWIGTYPE_p_f_p_void__void swig_types[46]
+#define SWIGTYPE_p_p_ASN1_OBJECT swig_types[47]
+#define SWIGTYPE_p_p_X509_NAME_ENTRY swig_types[48]
+#define SWIGTYPE_p_p_char swig_types[49]
+#define SWIGTYPE_p_p_unsigned_char swig_types[50]
+#define SWIGTYPE_p_pyfd_struct swig_types[51]
+#define SWIGTYPE_p_stack_st swig_types[52]
+#define SWIGTYPE_p_stack_st_OPENSSL_BLOCK swig_types[53]
+#define SWIGTYPE_p_stack_st_OPENSSL_STRING swig_types[54]
+#define SWIGTYPE_p_stack_st_SSL_CIPHER swig_types[55]
+#define SWIGTYPE_p_stack_st_X509 swig_types[56]
+#define SWIGTYPE_p_stack_st_X509_EXTENSION swig_types[57]
+#define SWIGTYPE_p_unsigned_char swig_types[58]
+#define SWIGTYPE_p_void swig_types[59]
+static swig_type_info *swig_types[61];
+static swig_module_info swig_module = {swig_types, 60, 0, 0, 0, 0};
+#define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name)
+#define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name)
+
+/* -------- TYPES TABLE (END) -------- */
+
+#if (PY_VERSION_HEX <= 0x02000000)
+# if !defined(SWIG_PYTHON_CLASSIC)
+# error "This python version requires swig to be run with the '-classic' option"
+# endif
+#endif
+#if (PY_VERSION_HEX <= 0x02020000)
+# error "This python version requires swig to be run with the '-nomodern' option"
+#endif
+#if (PY_VERSION_HEX <= 0x02020000)
+# error "This python version requires swig to be run with the '-nomodernargs' option"
+#endif
+
+/*-----------------------------------------------
+ @(target):= _m2crypto.so
+ ------------------------------------------------*/
+#if PY_VERSION_HEX >= 0x03000000
+# define SWIG_init PyInit__m2crypto
+
+#else
+# define SWIG_init init_m2crypto
+
+#endif
+#define SWIG_name "_m2crypto"
+
+#define SWIGVERSION 0x020010
+#define SWIG_VERSION SWIGVERSION
+
+
+#define SWIG_as_voidptr(a) (void *)((const void *)(a))
+#define SWIG_as_voidptrptr(a) ((void)SWIG_as_voidptr(*a),(void**)(a))
+
+
+#ifdef _WIN32
+#define _WINSOCKAPI_
+#include <WinSock2.h>
+#include <Windows.h>
+#pragma comment(lib, "Ws2_32")
+typedef unsigned __int64 uint64_t;
+#endif
+
+
+#if defined __GNUC__ && __GNUC__ < 5
+#pragma GCC diagnostic ignored "-Wunused-label"
+#pragma GCC diagnostic warning "-Wstrict-prototypes"
+#endif
+
+#include <openssl/err.h>
+#include <openssl/rand.h>
+#include <_lib.h>
+#include <libcrypto-compat.h>
+#include <py3k_compat.h>
+
+#include "compile.h"
+
+static PyObject *ssl_verify_cb_func;
+static PyObject *ssl_info_cb_func;
+static PyObject *ssl_set_tmp_dh_cb_func;
+static PyObject *ssl_set_tmp_rsa_cb_func;
+static PyObject *x509_store_verify_cb_func;
+
+
+ #define SWIG_From_long PyLong_FromLong
+
+
+SWIGINTERN swig_type_info*
+SWIG_pchar_descriptor(void)
+{
+ static int init = 0;
+ static swig_type_info* info = 0;
+ if (!init) {
+ info = SWIG_TypeQuery("_p_char");
+ init = 1;
+ }
+ return info;
+}
+
+
+SWIGINTERNINLINE PyObject *
+SWIG_FromCharPtrAndSize(const char* carray, size_t size)
+{
+ if (carray) {
+ if (size > INT_MAX) {
+ swig_type_info* pchar_descriptor = SWIG_pchar_descriptor();
+ return pchar_descriptor ?
+ SWIG_InternalNewPointerObj((char *)(carray), pchar_descriptor, 0) : SWIG_Py_Void();
+ } else {
+#if PY_VERSION_HEX >= 0x03000000
+ return PyUnicode_FromStringAndSize(carray, (int)(size));
+#else
+ return PyString_FromStringAndSize(carray, (int)(size));
+#endif
+ }
+ } else {
+ return SWIG_Py_Void();
+ }
+}
+
+
+SWIGINTERNINLINE PyObject *
+SWIG_FromCharPtr(const char *cptr)
+{
+ return SWIG_FromCharPtrAndSize(cptr, (cptr ? strlen(cptr) : 0));
+}
+
+
+#include <limits.h>
+#if !defined(SWIG_NO_LLONG_MAX)
+# if !defined(LLONG_MAX) && defined(__GNUC__) && defined (__LONG_LONG_MAX__)
+# define LLONG_MAX __LONG_LONG_MAX__
+# define LLONG_MIN (-LLONG_MAX - 1LL)
+# define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL)
+# endif
+#endif
+
+
+SWIGINTERN int
+SWIG_AsVal_double (PyObject *obj, double *val)
+{
+ int res = SWIG_TypeError;
+ if (PyFloat_Check(obj)) {
+ if (val) *val = PyFloat_AsDouble(obj);
+ return SWIG_OK;
+ } else if (PyInt_Check(obj)) {
+ if (val) *val = PyInt_AsLong(obj);
+ return SWIG_OK;
+ } else if (PyLong_Check(obj)) {
+ double v = PyLong_AsDouble(obj);
+ if (!PyErr_Occurred()) {
+ if (val) *val = v;
+ return SWIG_OK;
+ } else {
+ PyErr_Clear();
+ }
+ }
+#ifdef SWIG_PYTHON_CAST_MODE
+ {
+ int dispatch = 0;
+ double d = PyFloat_AsDouble(obj);
+ if (!PyErr_Occurred()) {
+ if (val) *val = d;
+ return SWIG_AddCast(SWIG_OK);
+ } else {
+ PyErr_Clear();
+ }
+ if (!dispatch) {
+ long v = PyLong_AsLong(obj);
+ if (!PyErr_Occurred()) {
+ if (val) *val = v;
+ return SWIG_AddCast(SWIG_AddCast(SWIG_OK));
+ } else {
+ PyErr_Clear();
+ }
+ }
+ }
+#endif
+ return res;
+}
+
+
+#include <float.h>
+
+
+#include <math.h>
+
+
+SWIGINTERNINLINE int
+SWIG_CanCastAsInteger(double *d, double min, double max) {
+ double x = *d;
+ if ((min <= x && x <= max)) {
+ double fx = floor(x);
+ double cx = ceil(x);
+ double rd = ((x - fx) < 0.5) ? fx : cx; /* simple rint */
+ if ((errno == EDOM) || (errno == ERANGE)) {
+ errno = 0;
+ } else {
+ double summ, reps, diff;
+ if (rd < x) {
+ diff = x - rd;
+ } else if (rd > x) {
+ diff = rd - x;
+ } else {
+ return 1;
+ }
+ summ = rd + x;
+ reps = diff/summ;
+ if (reps < 8*DBL_EPSILON) {
+ *d = rd;
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+
+SWIGINTERN int
+SWIG_AsVal_long (PyObject *obj, long* val)
+{
+ if (PyInt_Check(obj)) {
+ if (val) *val = PyInt_AsLong(obj);
+ return SWIG_OK;
+ } else if (PyLong_Check(obj)) {
+ long v = PyLong_AsLong(obj);
+ if (!PyErr_Occurred()) {
+ if (val) *val = v;
+ return SWIG_OK;
+ } else {
+ PyErr_Clear();
+ }
+ }
+#ifdef SWIG_PYTHON_CAST_MODE
+ {
+ int dispatch = 0;
+ long v = PyInt_AsLong(obj);
+ if (!PyErr_Occurred()) {
+ if (val) *val = v;
+ return SWIG_AddCast(SWIG_OK);
+ } else {
+ PyErr_Clear();
+ }
+ if (!dispatch) {
+ double d;
+ int res = SWIG_AddCast(SWIG_AsVal_double (obj,&d));
+ if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, LONG_MIN, LONG_MAX)) {
+ if (val) *val = (long)(d);
+ return res;
+ }
+ }
+ }
+#endif
+ return SWIG_TypeError;
+}
+
+
+SWIGINTERN int
+SWIG_AsVal_int (PyObject * obj, int *val)
+{
+ long v;
+ int res = SWIG_AsVal_long (obj, &v);
+ if (SWIG_IsOK(res)) {
+ if ((v < INT_MIN || v > INT_MAX)) {
+ return SWIG_OverflowError;
+ } else {
+ if (val) *val = (int)(v);
+ }
+ }
+ return res;
+}
+
+
+SWIGINTERNINLINE PyObject*
+ SWIG_From_int (int value)
+{
+ return PyInt_FromLong((long) value);
+}
+
+
+#include <pythread.h>
+#include <openssl/crypto.h>
+
+#if defined(THREADING) && OPENSSL_VERSION_NUMBER < 0x10100000L
+#define CRYPTO_num_locks() (CRYPTO_NUM_LOCKS)
+static PyThread_type_lock lock_cs[CRYPTO_num_locks()];
+static long lock_count[CRYPTO_num_locks()];
+static int thread_mode = 0;
+#endif
+
+void threading_locking_callback(int mode, int type, const char *file, int line) {
+#if defined(THREADING) && OPENSSL_VERSION_NUMBER < 0x10100000L
+ if (mode & CRYPTO_LOCK) {
+ PyThread_acquire_lock(lock_cs[type], WAIT_LOCK);
+ lock_count[type]++;
+ } else {
+ PyThread_release_lock(lock_cs[type]);
+ lock_count[type]--;
+ }
+#endif
+}
+
+unsigned long threading_id_callback(void) {
+#if defined(THREADING) && OPENSSL_VERSION_NUMBER < 0x10100000L
+ return (unsigned long)PyThread_get_thread_ident();
+#else
+ return (unsigned long)0;
+#endif
+}
+
+
+void threading_init(void) {
+#if defined(THREADING) && OPENSSL_VERSION_NUMBER < 0x10100000L
+ int i;
+ if (!thread_mode) {
+ for (i=0; i<CRYPTO_num_locks(); i++) {
+ lock_count[i]=0;
+ lock_cs[i]=PyThread_allocate_lock();
+ }
+ CRYPTO_set_id_callback(threading_id_callback);
+ CRYPTO_set_locking_callback(threading_locking_callback);
+ }
+ thread_mode = 1;
+#endif
+}
+
+void threading_cleanup(void) {
+#if defined(THREADING) && OPENSSL_VERSION_NUMBER < 0x10100000L
+ int i;
+ if (thread_mode) {
+ CRYPTO_set_locking_callback(NULL);
+ for (i=0; i<CRYPTO_num_locks(); i++) {
+ lock_count[i]=0;
+ PyThread_release_lock(lock_cs[i]);
+ PyThread_free_lock(lock_cs[i]);
+ }
+ }
+ thread_mode = 0;
+#endif
+}
+
+
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/rsa.h>
+#include <openssl/ssl.h>
+#include <openssl/x509.h>
+#include <openssl/x509_vfy.h>
+#include <ceval.h>
+
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+
+#include <string.h>
+#include <openssl/engine.h>
+
+# define OPENSSL_zalloc(num) \
+ CRYPTO_zalloc(num, __FILE__, __LINE__)
+
+static void *CRYPTO_zalloc(size_t num, const char *file, int line)
+{
+ void *ret = CRYPTO_malloc(num, file, line);
+ if (ret != NULL)
+ memset(ret, 0, num);
+ return ret;
+}
+
+#include <openssl/bn.h>
+
+#ifndef BN_F_BN_GENCB_NEW
+# define BN_F_BN_GENCB_NEW 143
+#endif
+
+# define BN_GENCB_get_arg(gencb) ((gencb)->arg)
+
+BN_GENCB *BN_GENCB_new(void)
+{
+ BN_GENCB *ret;
+
+ if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL) {
+ BNerr(BN_F_BN_GENCB_NEW, ERR_R_MALLOC_FAILURE);
+ return (NULL);
+ }
+
+ return ret;
+}
+
+void BN_GENCB_free(BN_GENCB *cb)
+{
+ if (cb == NULL)
+ return;
+ OPENSSL_free(cb);
+}
+
+
+int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d)
+{
+ /* If the fields n and e in r are NULL, the corresponding input
+ * parameters MUST be non-NULL for n and e. d may be
+ * left NULL (in case only the public key is used).
+ */
+ if ((r->n == NULL && n == NULL)
+ || (r->e == NULL && e == NULL))
+ return 0;
+
+ if (n != NULL) {
+ BN_free(r->n);
+ r->n = n;
+ }
+ if (e != NULL) {
+ BN_free(r->e);
+ r->e = e;
+ }
+ if (d != NULL) {
+ BN_free(r->d);
+ r->d = d;
+ }
+
+ return 1;
+}
+
+int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q)
+{
+ /* If the fields p and q in r are NULL, the corresponding input
+ * parameters MUST be non-NULL.
+ */
+ if ((r->p == NULL && p == NULL)
+ || (r->q == NULL && q == NULL))
+ return 0;
+
+ if (p != NULL) {
+ BN_free(r->p);
+ r->p = p;
+ }
+ if (q != NULL) {
+ BN_free(r->q);
+ r->q = q;
+ }
+
+ return 1;
+}
+
+int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp)
+{
+ /* If the fields dmp1, dmq1 and iqmp in r are NULL, the corresponding input
+ * parameters MUST be non-NULL.
+ */
+ if ((r->dmp1 == NULL && dmp1 == NULL)
+ || (r->dmq1 == NULL && dmq1 == NULL)
+ || (r->iqmp == NULL && iqmp == NULL))
+ return 0;
+
+ if (dmp1 != NULL) {
+ BN_free(r->dmp1);
+ r->dmp1 = dmp1;
+ }
+ if (dmq1 != NULL) {
+ BN_free(r->dmq1);
+ r->dmq1 = dmq1;
+ }
+ if (iqmp != NULL) {
+ BN_free(r->iqmp);
+ r->iqmp = iqmp;
+ }
+
+ return 1;
+}
+
+void RSA_get0_key(const RSA *r,
+ const BIGNUM **n, const BIGNUM **e, const BIGNUM **d)
+{
+ if (n != NULL)
+ *n = r->n;
+ if (e != NULL)
+ *e = r->e;
+ if (d != NULL)
+ *d = r->d;
+}
+
+void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q)
+{
+ if (p != NULL)
+ *p = r->p;
+ if (q != NULL)
+ *q = r->q;
+}
+
+void RSA_get0_crt_params(const RSA *r,
+ const BIGNUM **dmp1, const BIGNUM **dmq1,
+ const BIGNUM **iqmp)
+{
+ if (dmp1 != NULL)
+ *dmp1 = r->dmp1;
+ if (dmq1 != NULL)
+ *dmq1 = r->dmq1;
+ if (iqmp != NULL)
+ *iqmp = r->iqmp;
+}
+
+void DSA_get0_pqg(const DSA *d,
+ const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
+{
+ if (p != NULL)
+ *p = d->p;
+ if (q != NULL)
+ *q = d->q;
+ if (g != NULL)
+ *g = d->g;
+}
+
+int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g)
+{
+ /* If the fields p, q and g in d are NULL, the corresponding input
+ * parameters MUST be non-NULL.
+ */
+ if ((d->p == NULL && p == NULL)
+ || (d->q == NULL && q == NULL)
+ || (d->g == NULL && g == NULL))
+ return 0;
+
+ if (p != NULL) {
+ BN_free(d->p);
+ d->p = p;
+ }
+ if (q != NULL) {
+ BN_free(d->q);
+ d->q = q;
+ }
+ if (g != NULL) {
+ BN_free(d->g);
+ d->g = g;
+ }
+
+ return 1;
+}
+
+void DSA_get0_key(const DSA *d,
+ const BIGNUM **pub_key, const BIGNUM **priv_key)
+{
+ if (pub_key != NULL)
+ *pub_key = d->pub_key;
+ if (priv_key != NULL)
+ *priv_key = d->priv_key;
+}
+
+int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key)
+{
+ /* If the field pub_key in d is NULL, the corresponding input
+ * parameters MUST be non-NULL. The priv_key field may
+ * be left NULL.
+ */
+ if (d->pub_key == NULL && pub_key == NULL)
+ return 0;
+
+ if (pub_key != NULL) {
+ BN_free(d->pub_key);
+ d->pub_key = pub_key;
+ }
+ if (priv_key != NULL) {
+ BN_free(d->priv_key);
+ d->priv_key = priv_key;
+ }
+
+ return 1;
+}
+
+void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
+{
+ if (pr != NULL)
+ *pr = sig->r;
+ if (ps != NULL)
+ *ps = sig->s;
+}
+
+int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s)
+{
+ if (r == NULL || s == NULL)
+ return 0;
+ BN_clear_free(sig->r);
+ BN_clear_free(sig->s);
+ sig->r = r;
+ sig->s = s;
+ return 1;
+}
+
+void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
+{
+ if (pr != NULL)
+ *pr = sig->r;
+ if (ps != NULL)
+ *ps = sig->s;
+}
+
+int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s)
+{
+ if (r == NULL || s == NULL)
+ return 0;
+ BN_clear_free(sig->r);
+ BN_clear_free(sig->s);
+ sig->r = r;
+ sig->s = s;
+ return 1;
+}
+
+void DH_get0_pqg(const DH *dh,
+ const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
+{
+ if (p != NULL)
+ *p = dh->p;
+ if (q != NULL)
+ *q = dh->q;
+ if (g != NULL)
+ *g = dh->g;
+}
+
+int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g)
+{
+ /* If the fields p and g in d are NULL, the corresponding input
+ * parameters MUST be non-NULL. q may remain NULL.
+ */
+ if ((dh->p == NULL && p == NULL)
+ || (dh->g == NULL && g == NULL))
+ return 0;
+
+ if (p != NULL) {
+ BN_free(dh->p);
+ dh->p = p;
+ }
+ if (q != NULL) {
+ BN_free(dh->q);
+ dh->q = q;
+ }
+ if (g != NULL) {
+ BN_free(dh->g);
+ dh->g = g;
+ }
+
+ if (q != NULL) {
+ dh->length = BN_num_bits(q);
+ }
+
+ return 1;
+}
+
+void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key)
+{
+ if (pub_key != NULL)
+ *pub_key = dh->pub_key;
+ if (priv_key != NULL)
+ *priv_key = dh->priv_key;
+}
+
+int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key)
+{
+ /* If the field pub_key in dh is NULL, the corresponding input
+ * parameters MUST be non-NULL. The priv_key field may
+ * be left NULL.
+ */
+ if (dh->pub_key == NULL && pub_key == NULL)
+ return 0;
+
+ if (pub_key != NULL) {
+ BN_free(dh->pub_key);
+ dh->pub_key = pub_key;
+ }
+ if (priv_key != NULL) {
+ BN_free(dh->priv_key);
+ dh->priv_key = priv_key;
+ }
+
+ return 1;
+}
+
+int DH_set_length(DH *dh, long length)
+{
+ dh->length = length;
+ return 1;
+}
+
+const unsigned char *EVP_CIPHER_CTX_iv(const EVP_CIPHER_CTX *ctx)
+{
+ return ctx->iv;
+}
+
+unsigned char *EVP_CIPHER_CTX_iv_noconst(EVP_CIPHER_CTX *ctx)
+{
+ return ctx->iv;
+}
+
+EVP_MD_CTX *EVP_MD_CTX_new(void)
+{
+ return OPENSSL_zalloc(sizeof(EVP_MD_CTX));
+}
+
+void EVP_MD_CTX_free(EVP_MD_CTX *ctx)
+{
+ EVP_MD_CTX_cleanup(ctx);
+ OPENSSL_free(ctx);
+}
+
+int RSA_size(const RSA* rsa) {
+ /* BIGNUM* n = NULL;
+ RSA_get0_key(rsa, n, NULL, NULL); */
+ return BN_num_bytes(rsa->n);
+}
+
+RSA_METHOD *RSA_meth_dup(const RSA_METHOD *meth)
+{
+ RSA_METHOD *ret;
+
+ ret = OPENSSL_malloc(sizeof(RSA_METHOD));
+
+ if (ret != NULL) {
+ memcpy(ret, meth, sizeof(*meth));
+ ret->name = OPENSSL_strdup(meth->name);
+ if (ret->name == NULL) {
+ OPENSSL_free(ret);
+ return NULL;
+ }
+ }
+
+ return ret;
+}
+
+int RSA_meth_set1_name(RSA_METHOD *meth, const char *name)
+{
+ char *tmpname;
+
+ tmpname = OPENSSL_strdup(name);
+ if (tmpname == NULL) {
+ return 0;
+ }
+
+ OPENSSL_free((char *)meth->name);
+ meth->name = tmpname;
+
+ return 1;
+}
+
+int RSA_meth_set_priv_enc(RSA_METHOD *meth,
+ int (*priv_enc) (int flen, const unsigned char *from,
+ unsigned char *to, RSA *rsa,
+ int padding))
+{
+ meth->rsa_priv_enc = priv_enc;
+ return 1;
+}
+
+int RSA_meth_set_priv_dec(RSA_METHOD *meth,
+ int (*priv_dec) (int flen, const unsigned char *from,
+ unsigned char *to, RSA *rsa,
+ int padding))
+{
+ meth->rsa_priv_dec = priv_dec;
+ return 1;
+}
+
+int RSA_meth_set_finish(RSA_METHOD *meth, int (*finish) (RSA *rsa))
+{
+ meth->finish = finish;
+ return 1;
+}
+
+void RSA_meth_free(RSA_METHOD *meth)
+{
+ if (meth != NULL) {
+ OPENSSL_free((char *)meth->name);
+ OPENSSL_free(meth);
+ }
+}
+
+int RSA_bits(const RSA *r)
+{
+ return (BN_num_bits(r->n));
+}
+
+RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey)
+{
+ if (pkey->type != EVP_PKEY_RSA) {
+ return NULL;
+ }
+ return pkey->pkey.rsa;
+}
+
+int X509_NAME_get0_der(X509_NAME *nm, const unsigned char **pder,
+ size_t *pderlen)
+{
+ /* Make sure encoding is valid */
+ if (i2d_X509_NAME(nm, NULL) <= 0)
+ return 0;
+ if (pder != NULL)
+ *pder = (unsigned char *)nm->bytes->data;
+ if (pderlen != NULL)
+ *pderlen = nm->bytes->length;
+ return 1;
+}
+
+#endif /* OPENSSL_VERSION_NUMBER */
+
+
+#if PY_MAJOR_VERSION >= 3
+
+FILE* PyFile_AsFile(PyObject *pyfile) {
+ FILE* fp;
+ int fd;
+ const char *mode_str = NULL;
+ PyObject *mode_obj;
+
+ if ((fd = PyObject_AsFileDescriptor(pyfile)) == -1) {
+ PyErr_SetString(PyExc_BlockingIOError,
+ "Cannot find file handler for the Python file!");
+ return NULL;
+ }
+
+ if ((mode_obj = PyObject_GetAttrString(pyfile, "mode")) == NULL) {
+ mode_str = "rb";
+ PyErr_Clear();
+ }
+ else {
+ /* convert to plain string
+ * note that error checking is embedded in the function
+ */
+ mode_str = PyUnicode_AsUTF8AndSize(mode_obj, NULL);
+ }
+
+ if((fp = fdopen(fd, mode_str)) == NULL) {
+ PyErr_SetFromErrno(PyExc_IOError);
+ }
+
+ Py_XDECREF(mode_obj);
+ return fp;
+}
+
+#else /* PY2K */
+
+#define PyLong_FromLong(x) PyInt_FromLong(x)
+#define PyUnicode_AsUTF8(x) PyString_AsString(x)
+
+#endif /* PY_MAJOR_VERSION */
+
+
+/* OpenSSL 1.0.2 copmatbility shim */
+#if OPENSSL_VERSION_NUMBER < 0x10002000L
+typedef void (*OPENSSL_sk_freefunc)(void *);
+typedef void *(*OPENSSL_sk_copyfunc)(const void *);
+typedef struct stack_st OPENSSL_STACK;
+
+# define MIN_NODES 4
+# define sk_deep_copy OPENSSL_sk_deep_copy
+
+void OPENSSL_sk_free(OPENSSL_STACK *st)
+{
+ if (st == NULL)
+ return;
+ OPENSSL_free(st->data);
+ OPENSSL_free(st);
+}
+
+OPENSSL_STACK *OPENSSL_sk_deep_copy(const OPENSSL_STACK *sk,
+ OPENSSL_sk_copyfunc copy_func,
+ OPENSSL_sk_freefunc free_func)
+{
+ OPENSSL_STACK *ret;
+ int i;
+
+ if (sk->num < 0)
+ return NULL;
+
+ if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL)
+ return NULL;
+
+ /* direct structure assignment */
+ *ret = *sk;
+
+ ret->num_alloc = sk->num > MIN_NODES ? (size_t)sk->num : MIN_NODES;
+ ret->data = OPENSSL_zalloc(sizeof(*ret->data) * ret->num_alloc);
+ if (ret->data == NULL) {
+ OPENSSL_free(ret);
+ return NULL;
+ }
+
+ for (i = 0; i < ret->num; ++i) {
+ if (sk->data[i] == NULL)
+ continue;
+ if ((ret->data[i] = copy_func(sk->data[i])) == NULL) {
+ while (--i >= 0)
+ if (ret->data[i] != NULL)
+ free_func((void *)ret->data[i]);
+ OPENSSL_sk_free(ret);
+ return NULL;
+ }
+ }
+ return ret;
+}
+#endif /* OpenSSL 1.0.2 copmatbility shim */
+
+
+/* Blob interface. Deprecated. */
+
+Blob *blob_new(int len, const char *errmsg) {
+
+ Blob *blob;
+ if (!(blob=(Blob *)PyMem_Malloc(sizeof(Blob)))){
+ PyErr_SetString(PyExc_MemoryError, errmsg);
+ return NULL;
+ }
+ if (!(blob->data=(unsigned char *)PyMem_Malloc(len))) {
+ PyMem_Free(blob);
+ PyErr_SetString(PyExc_MemoryError, errmsg);
+ return NULL;
+ }
+ blob->len=len;
+ return blob;
+}
+
+Blob *blob_copy(Blob *from, const char *errmsg) {
+ Blob *blob=blob_new(from->len, errmsg);
+ if (!blob) {
+ PyErr_SetString(PyExc_MemoryError, errmsg);
+ return NULL;
+ }
+ memcpy(blob->data, from->data, from->len);
+ return blob;
+}
+
+void blob_free(Blob *blob) {
+ PyMem_Free(blob->data);
+ PyMem_Free(blob);
+}
+
+
+/* Python helpers. */
+
+
+
+
+static int
+m2_PyObject_AsReadBufferInt(PyObject *obj, const void **buffer,
+ int *buffer_len)
+{
+ int ret;
+ Py_ssize_t len;
+
+ ret = PyObject_AsReadBuffer(obj, buffer, &len);
+ if (ret)
+ return ret;
+ if (len > INT_MAX) {
+ PyErr_SetString(PyExc_ValueError, "object too large");
+ return -1;
+ }
+ *buffer_len = len;
+ return 0;
+}
+
+static int m2_PyObject_GetBufferInt(PyObject *obj, Py_buffer *view, int flags)
+{
+ int ret;
+
+ if (PyObject_CheckBuffer(obj))
+ ret = PyObject_GetBuffer(obj, view, flags);
+ else {
+ const void *buf;
+
+ ret = PyObject_AsReadBuffer(obj, &buf, &view->len);
+ if (ret == 0)
+ view->buf = (void *)buf;
+ }
+ if (ret)
+ return ret;
+ if (view->len > INT_MAX) {
+ PyErr_SetString(PyExc_ValueError, "object too large");
+ m2_PyBuffer_Release(obj, view);
+ return -1;
+ }
+
+ return 0;
+}
+
+static BIGNUM*
+m2_PyObject_AsBIGNUM(PyObject* value, PyObject* _py_exc)
+{
+ BIGNUM* bn;
+ const void* vbuf;
+ int vlen = 0;
+
+ if (m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
+ return NULL;
+
+ if (!(bn = BN_mpi2bn((unsigned char *)vbuf, vlen, NULL))) {
+ PyErr_SetString(_py_exc, ERR_reason_error_string(ERR_get_error()));
+ return NULL;
+ }
+
+ return bn;
+}
+
+static void m2_PyBuffer_Release(PyObject *obj, Py_buffer *view)
+{
+ if (PyObject_CheckBuffer(obj))
+ PyBuffer_Release(view);
+ /* else do nothing, view->buf comes from PyObject_AsReadBuffer */
+}
+
+static int
+m2_PyString_AsStringAndSizeInt(PyObject *obj, char **s, int *len)
+{
+ int ret;
+ Py_ssize_t len2;
+
+ ret = PyBytes_AsStringAndSize(obj, s, &len2);
+
+ if (ret)
+ return ret;
+ if (len2 > INT_MAX) {
+ PyErr_SetString(PyExc_ValueError, "string too large");
+ return -1;
+ }
+ *len = len2;
+ return 0;
+}
+
+/* Works as PyFile_Name, but always returns a new object. */
+PyObject *m2_PyFile_Name(PyObject *pyfile) {
+ PyObject *out = NULL;
+#if PY_MAJOR_VERSION >= 3
+ out = PyObject_GetAttrString(pyfile, "name");
+#else
+ out = PyFile_Name(pyfile);
+ Py_XINCREF(out);
+#endif
+ return out;
+}
+
+/* Yes, __FUNCTION__ is a non-standard symbol, but it is supported by
+ * both gcc and MSVC. */
+#define m2_PyErr_Msg(type) m2_PyErr_Msg_Caller(type, (const char*) __FUNCTION__)
+
+static void m2_PyErr_Msg_Caller(PyObject *err_type, const char* caller) {
+ const char *err_reason;
+ const char *data;
+ int flags;
+ /* This max size of a (longer than ours) OpenSSL error string is hardcoded
+ * in OpenSSL's crypto/err/err_prn.c:ERR_print_errors_cb() */
+ char err_msg[4096];
+ unsigned long err_code = ERR_get_error_line_data(NULL, NULL, &data, &flags);
+
+ if (err_code != 0) {
+ err_reason = ERR_reason_error_string(err_code);
+ if (data && (flags & ERR_TXT_STRING))
+ snprintf(err_msg, sizeof(err_msg), "%s (%s)", err_reason, data);
+ else
+ snprintf(err_msg, sizeof(err_msg), "%s", err_reason);
+
+ PyErr_SetString(err_type, err_msg);
+ } else {
+ PyErr_Format(err_type, "Unknown error in function %s.", caller);
+ }
+}
+
+
+/* C callbacks invoked by OpenSSL; these in turn call back into
+Python. */
+
+int ssl_verify_callback(int ok, X509_STORE_CTX *ctx) {
+ PyObject *argv, *ret;
+ PyObject *_x509_store_ctx_swigptr=0, *_x509_store_ctx_obj=0, *_x509_store_ctx_inst=0, *_klass=0;
+ PyObject *_x509=0, *_ssl_ctx=0;
+ SSL *ssl;
+ SSL_CTX *ssl_ctx;
+ X509 *x509;
+ int errnum, errdepth;
+ int cret;
+ int new_style_callback = 0, warning_raised_exception=0;
+ PyGILState_STATE gilstate;
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+
+ ssl = (SSL *)X509_STORE_CTX_get_app_data(ctx);
+
+ gilstate = PyGILState_Ensure();
+
+ if (PyMethod_Check(ssl_verify_cb_func)) {
+ PyObject *func;
+ PyCodeObject *code;
+ func = PyMethod_Function(ssl_verify_cb_func);
+ code = (PyCodeObject *) PyFunction_GetCode(func);
+ if (code && code->co_argcount == 3) { /* XXX Python internals */
+ new_style_callback = 1;
+ }
+ } else if (PyFunction_Check(ssl_verify_cb_func)) {
+ PyCodeObject *code = (PyCodeObject *) PyFunction_GetCode(ssl_verify_cb_func);
+ if (code && code->co_argcount == 2) { /* XXX Python internals */
+ new_style_callback = 1;
+ }
+ } else {
+ /* XXX There are lots of other callable types, but we will assume
+ * XXX that any other type of callable uses the new style callback,
+ * XXX although this is not entirely safe assumption.
+ */
+ new_style_callback = 1;
+ }
+
+ if (new_style_callback) {
+ PyObject *x509mod;
+
+ x509mod = PyDict_GetItemString(PyImport_GetModuleDict(), "M2Crypto.X509");
+ _klass = PyObject_GetAttrString(x509mod, "X509_Store_Context");
+
+ _x509_store_ctx_swigptr = SWIG_NewPointerObj((void *)ctx, SWIGTYPE_p_X509_STORE_CTX, 0);
+ _x509_store_ctx_obj = Py_BuildValue("(Oi)", _x509_store_ctx_swigptr, 0);
+
+ _x509_store_ctx_inst = PyObject_CallObject(_klass, _x509_store_ctx_obj);
+
+ argv = Py_BuildValue("(iO)", ok, _x509_store_ctx_inst);
+ } else {
+ if (PyErr_Warn(PyExc_DeprecationWarning, "Old style callback, use cb_func(ok, store) instead")) {
+ warning_raised_exception = 1;
+ }
+
+ x509 = X509_STORE_CTX_get_current_cert(ctx);
+ errnum = X509_STORE_CTX_get_error(ctx);
+ errdepth = X509_STORE_CTX_get_error_depth(ctx);
+
+ ssl = (SSL *)X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
+ ssl_ctx = SSL_get_SSL_CTX(ssl);
+
+ _x509 = SWIG_NewPointerObj((void *)x509, SWIGTYPE_p_X509, 0);
+ _ssl_ctx = SWIG_NewPointerObj((void *)ssl_ctx, SWIGTYPE_p_SSL_CTX, 0);
+ argv = Py_BuildValue("(OOiii)", _ssl_ctx, _x509, errnum, errdepth, ok);
+ }
+
+ if (!warning_raised_exception) {
+ ret = PyEval_CallObject(ssl_verify_cb_func, argv);
+ } else {
+ ret = 0;
+ }
+
+ if (!ret) {
+ /* Got an exception in PyEval_CallObject(), let's fail verification
+ * to be safe.
+ */
+ cret = 0;
+ } else {
+ /* FIXME This is possibly problematic if ret > MAXINT */
+ cret = (int)PyLong_AsLong(ret);
+ }
+ Py_XDECREF(ret);
+ Py_XDECREF(argv);
+ if (new_style_callback) {
+ Py_XDECREF(_x509_store_ctx_inst);
+ Py_XDECREF(_x509_store_ctx_obj);
+ Py_XDECREF(_x509_store_ctx_swigptr);
+ Py_XDECREF(_klass);
+ } else {
+ Py_XDECREF(_x509);
+ Py_XDECREF(_ssl_ctx);
+ }
+
+ PyGILState_Release(gilstate);
+
+ return cret;
+}
+
+int x509_store_verify_callback(int ok, X509_STORE_CTX *ctx) {
+ PyGILState_STATE gilstate;
+ PyObject *argv, *ret;
+ PyObject *_x509_store_ctx_swigptr=0, *_x509_store_ctx_obj=0, *_x509_store_ctx_inst=0, *_klass=0;
+ int cret;
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+ PyObject *x509mod;
+
+
+ gilstate = PyGILState_Ensure();
+
+ /* Below, handle only what is called 'new style callback' in ssl_verify_callback().
+ TODO: does 'old style callback' exist any more? */
+ x509mod = PyDict_GetItemString(PyImport_GetModuleDict(), "M2Crypto.X509");
+ _klass = PyObject_GetAttrString(x509mod, "X509_Store_Context");
+ _x509_store_ctx_swigptr = SWIG_NewPointerObj((void *)ctx, SWIGTYPE_p_X509_STORE_CTX, 0);
+ _x509_store_ctx_obj = Py_BuildValue("(Oi)", _x509_store_ctx_swigptr, 0);
+
+ _x509_store_ctx_inst = PyObject_CallObject(_klass, _x509_store_ctx_obj);
+
+ argv = Py_BuildValue("(iO)", ok, _x509_store_ctx_inst);
+
+ ret = PyEval_CallObject(x509_store_verify_cb_func, argv);
+ if (!ret) {
+ /* Got an exception in PyEval_CallObject(), let's fail verification
+ * to be safe.
+ */
+ cret = 0;
+ } else {
+ cret = (int)PyInt_AsLong(ret);
+ }
+
+ Py_XDECREF(ret);
+ Py_XDECREF(argv);
+ Py_XDECREF(_x509_store_ctx_inst);
+ Py_XDECREF(_x509_store_ctx_obj);
+ Py_XDECREF(_x509_store_ctx_swigptr);
+ Py_XDECREF(_klass);
+
+ PyGILState_Release(gilstate);
+ return cret;
+}
+
+void ssl_info_callback(const SSL *s, int where, int ret) {
+ PyObject *argv, *retval, *_SSL;
+ PyGILState_STATE gilstate;
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+
+ gilstate = PyGILState_Ensure();
+
+ _SSL = SWIG_NewPointerObj((void *)s, SWIGTYPE_p_SSL, 0);
+ argv = Py_BuildValue("(iiO)", where, ret, _SSL);
+
+ retval = PyEval_CallObject(ssl_info_cb_func, argv);
+
+ Py_XDECREF(retval);
+ Py_XDECREF(argv);
+ Py_XDECREF(_SSL);
+
+ PyGILState_Release(gilstate);
+}
+
+DH *ssl_set_tmp_dh_callback(SSL *ssl, int is_export, int keylength) {
+ PyObject *argv, *ret, *_ssl;
+ DH *dh;
+ PyGILState_STATE gilstate;
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+
+ gilstate = PyGILState_Ensure();
+
+ _ssl = SWIG_NewPointerObj((void *)ssl, SWIGTYPE_p_SSL, 0);
+ argv = Py_BuildValue("(Oii)", _ssl, is_export, keylength);
+
+ ret = PyEval_CallObject(ssl_set_tmp_dh_cb_func, argv);
+
+ if ((SWIG_ConvertPtr(ret, (void **)&dh, SWIGTYPE_p_DH, SWIG_POINTER_EXCEPTION | 0)) == -1)
+ dh = NULL;
+ Py_XDECREF(ret);
+ Py_XDECREF(argv);
+ Py_XDECREF(_ssl);
+
+ PyGILState_Release(gilstate);
+
+ return dh;
+}
+
+RSA *ssl_set_tmp_rsa_callback(SSL *ssl, int is_export, int keylength) {
+ PyObject *argv, *ret, *_ssl;
+ RSA *rsa;
+ PyGILState_STATE gilstate;
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+
+ gilstate = PyGILState_Ensure();
+
+ _ssl = SWIG_NewPointerObj((void *)ssl, SWIGTYPE_p_SSL, 0);
+ argv = Py_BuildValue("(Oii)", _ssl, is_export, keylength);
+
+ ret = PyEval_CallObject(ssl_set_tmp_rsa_cb_func, argv);
+
+ if ((SWIG_ConvertPtr(ret, (void **)&rsa, SWIGTYPE_p_RSA, SWIG_POINTER_EXCEPTION | 0)) == -1)
+ rsa = NULL;
+ Py_XDECREF(ret);
+ Py_XDECREF(argv);
+ Py_XDECREF(_ssl);
+
+ PyGILState_Release(gilstate);
+
+ return rsa;
+}
+
+/* Universal callback for dh_generate_parameters,
+ * dsa_generate_parametersm, and rsa_generate_key */
+int bn_gencb_callback(int p, int n, BN_GENCB *gencb) {
+ PyObject *argv, *ret, *cbfunc;
+
+ cbfunc = (PyObject *)BN_GENCB_get_arg(gencb);
+ argv = Py_BuildValue("(ii)", p, n);
+ ret = PyEval_CallObject(cbfunc, argv);
+ PyErr_Clear();
+ Py_DECREF(argv);
+ Py_XDECREF(ret);
+ return 1;
+}
+
+int passphrase_callback(char *buf, int num, int v, void *arg) {
+ int i;
+ Py_ssize_t len;
+ char *str;
+ PyObject *argv, *ret, *cbfunc;
+ PyGILState_STATE gilstate;
+
+ gilstate = PyGILState_Ensure();
+ cbfunc = (PyObject *)arg;
+ argv = Py_BuildValue("(i)", v);
+ /* PyEval_CallObject sets exception, if needed. */
+ ret = PyEval_CallObject(cbfunc, argv);
+ Py_DECREF(argv);
+ if (ret == NULL) {
+ PyGILState_Release(gilstate);
+ return -1;
+ }
+
+ if (!PyBytes_Check(ret)) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "Result of callback is not bytes().");
+ Py_DECREF(ret);
+ PyGILState_Release(gilstate);
+ return -1;
+ }
+ if ((len = PyBytes_Size(ret)) > num)
+ len = num;
+ str = PyBytes_AsString(ret);
+
+ for (i = 0; i < len; i++)
+ buf[i] = str[i];
+ Py_DECREF(ret);
+ PyGILState_Release(gilstate);
+ return len;
+}
+
+
+
+void lib_init() {
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+ SSLeay_add_all_algorithms();
+ ERR_load_ERR_strings();
+#endif
+}
+
+/* Bignum routines that aren't not numerous enough to
+warrant a separate file. */
+
+PyObject *bn_to_mpi(const BIGNUM *bn) {
+ int len = 0;
+ unsigned char *mpi;
+ PyObject *pyo;
+
+ len = BN_bn2mpi(bn, NULL);
+ if (!(mpi=(unsigned char *)PyMem_Malloc(len))) {
+ m2_PyErr_Msg(PyExc_MemoryError);
+ return NULL;
+ }
+ len=BN_bn2mpi(bn, mpi);
+
+ pyo=PyBytes_FromStringAndSize((const char *)mpi, len);
+
+ PyMem_Free(mpi);
+ return pyo;
+}
+
+const BIGNUM *mpi_to_bn(PyObject *value) {
+ const void *vbuf;
+ int vlen = 0;
+
+ if (m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
+ return NULL;
+
+ return BN_mpi2bn(vbuf, vlen, NULL);
+}
+
+PyObject *bn_to_bin(BIGNUM *bn) {
+ int len = 0;
+ unsigned char *bin;
+ PyObject *pyo;
+
+ len = BN_num_bytes(bn);
+ if (!(bin=(unsigned char *)PyMem_Malloc(len))) {
+ PyErr_SetString(PyExc_MemoryError, "bn_to_bin");
+ return NULL;
+ }
+ BN_bn2bin(bn, bin);
+
+ pyo=PyBytes_FromStringAndSize((const char *)bin, len);
+
+ PyMem_Free(bin);
+ return pyo;
+}
+
+const BIGNUM *bin_to_bn(PyObject *value) {
+ const void *vbuf;
+ int vlen = 0;
+
+ if (m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
+ return NULL;
+
+ return BN_bin2bn(vbuf, vlen, NULL);
+}
+
+PyObject *bn_to_hex(BIGNUM *bn) {
+ char *hex;
+ PyObject *pyo;
+ Py_ssize_t len = 0;
+
+ hex = BN_bn2hex(bn);
+ if (!hex) {
+ m2_PyErr_Msg(PyExc_RuntimeError);
+ OPENSSL_free(hex);
+ return NULL;
+ }
+ len = strlen(hex);
+
+ pyo=PyBytes_FromStringAndSize(hex, len);
+
+ OPENSSL_free(hex);
+ return pyo;
+}
+
+BIGNUM *hex_to_bn(PyObject *value) {
+ const void *vbuf;
+ Py_ssize_t vlen = 0;
+ BIGNUM *bn;
+
+ if (PyObject_AsReadBuffer(value, &vbuf, &vlen) == -1)
+ return NULL;
+
+ if ((bn=BN_new())==NULL) {
+ PyErr_SetString(PyExc_MemoryError, "hex_to_bn");
+ return NULL;
+ }
+ if (BN_hex2bn(&bn, (const char *)vbuf) <= 0) {
+ m2_PyErr_Msg(PyExc_RuntimeError);
+ BN_free(bn);
+ return NULL;
+ }
+ return bn;
+}
+
+BIGNUM *dec_to_bn(PyObject *value) {
+ const void *vbuf;
+ Py_ssize_t vlen = 0;
+ BIGNUM *bn;
+
+ if (PyObject_AsReadBuffer(value, &vbuf, &vlen) == -1)
+ return NULL;
+
+ if ((bn=BN_new())==NULL) {
+ PyErr_SetString(PyExc_MemoryError, "dec_to_bn");
+ return NULL;
+ }
+ if ((BN_dec2bn(&bn, (const char *)vbuf) <= 0)) {
+ m2_PyErr_Msg(PyExc_RuntimeError);
+ BN_free(bn);
+ return NULL;
+ }
+ return bn;
+}
+
+
+SWIGINTERNINLINE PyObject*
+SWIG_From_unsigned_SS_long (unsigned long value)
+{
+ return (value > LONG_MAX) ?
+ PyLong_FromUnsignedLong(value) : PyLong_FromLong((long)(value));
+}
+
+
+SWIGINTERN int
+SWIG_AsVal_unsigned_SS_long (PyObject *obj, unsigned long *val)
+{
+#if PY_VERSION_HEX < 0x03000000
+ if (PyInt_Check(obj)) {
+ long v = PyInt_AsLong(obj);
+ if (v >= 0) {
+ if (val) *val = v;
+ return SWIG_OK;
+ } else {
+ return SWIG_OverflowError;
+ }
+ } else
+#endif
+ if (PyLong_Check(obj)) {
+ unsigned long v = PyLong_AsUnsignedLong(obj);
+ if (!PyErr_Occurred()) {
+ if (val) *val = v;
+ return SWIG_OK;
+ } else {
+ PyErr_Clear();
+#if PY_VERSION_HEX >= 0x03000000
+ {
+ long v = PyLong_AsLong(obj);
+ if (!PyErr_Occurred()) {
+ if (v < 0) {
+ return SWIG_OverflowError;
+ }
+ } else {
+ PyErr_Clear();
+ }
+ }
+#endif
+ }
+ }
+#ifdef SWIG_PYTHON_CAST_MODE
+ {
+ int dispatch = 0;
+ unsigned long v = PyLong_AsUnsignedLong(obj);
+ if (!PyErr_Occurred()) {
+ if (val) *val = v;
+ return SWIG_AddCast(SWIG_OK);
+ } else {
+ PyErr_Clear();
+ }
+ if (!dispatch) {
+ double d;
+ int res = SWIG_AddCast(SWIG_AsVal_double (obj,&d));
+ if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, 0, ULONG_MAX)) {
+ if (val) *val = (unsigned long)(d);
+ return res;
+ }
+ }
+ }
+#endif
+ return SWIG_TypeError;
+}
+
+
+#include <openssl/bio.h>
+
+
+static PyObject *_bio_err;
+
+
+void pyfd_init(void);
+
+void bio_init(PyObject *bio_err) {
+ Py_INCREF(bio_err);
+ _bio_err = bio_err;
+ pyfd_init();
+}
+
+int bio_free(BIO *bio) {
+ int ret;
+
+ Py_BEGIN_ALLOW_THREADS
+ ret = BIO_free(bio);
+ Py_END_ALLOW_THREADS
+ if (ret == 0) {
+ m2_PyErr_Msg(_bio_err);
+ }
+ return ret;
+}
+
+BIO * bio_new_file(const char *filename, const char *mode) {
+ BIO *ret;
+
+ Py_BEGIN_ALLOW_THREADS
+ ret = BIO_new_file(filename, mode);
+ Py_END_ALLOW_THREADS
+
+ if (ret == NULL) {
+ m2_PyErr_Msg(_bio_err);
+ }
+
+ return ret;
+}
+
+BIO *bio_new_pyfile(PyObject *pyfile, int bio_close) {
+ FILE *fp = NULL;
+ BIO *bio = NULL;
+
+ fp = PyFile_AsFile(pyfile);
+
+ bio = BIO_new_fp(fp, bio_close);
+
+ /* returns NULL if error occurred */
+ if (bio == NULL) {
+ /* Find out the name of the file so we can have good error
+ * message. */
+ PyObject *pyname = m2_PyFile_Name(pyfile);
+ char *name = PyBytes_AsString(pyname);
+
+ if (name == NULL) {
+ PyErr_Format(_bio_err,
+ "Opening of the new BIO on file failed!");
+ }
+ else {
+ PyErr_Format(_bio_err,
+ "Opening of the new BIO on file %s failed!", name);
+ }
+ Py_DECREF(pyname);
+ }
+ return bio;
+}
+
+PyObject *bio_read(BIO *bio, int num) {
+ PyObject *blob;
+ void *buf;
+ int r;
+
+ if (!(buf = PyMem_Malloc(num))) {
+ PyErr_SetString(PyExc_MemoryError, "bio_read");
+ return NULL;
+ }
+ Py_BEGIN_ALLOW_THREADS
+ r = BIO_read(bio, buf, num);
+ Py_END_ALLOW_THREADS
+ if (r < 0) {
+ PyMem_Free(buf);
+ if (ERR_peek_error()) {
+ m2_PyErr_Msg(_bio_err);
+ return NULL;
+ }
+ Py_RETURN_NONE;
+ }
+
+ blob = PyBytes_FromStringAndSize(buf, r);
+
+ PyMem_Free(buf);
+ return blob;
+}
+
+PyObject *bio_gets(BIO *bio, int num) {
+ PyObject *blob;
+ void *buf;
+ int r;
+
+ if (!(buf = PyMem_Malloc(num))) {
+ PyErr_SetString(PyExc_MemoryError, "bio_gets");
+ return NULL;
+ }
+ Py_BEGIN_ALLOW_THREADS
+ r = BIO_gets(bio, buf, num);
+ Py_END_ALLOW_THREADS
+ if (r < 1) {
+ PyMem_Free(buf);
+ if (ERR_peek_error()) {
+ m2_PyErr_Msg(_bio_err);
+ return NULL;
+ }
+ Py_RETURN_NONE;
+ }
+
+ blob = PyBytes_FromStringAndSize(buf, r);
+
+ PyMem_Free(buf);
+ return blob;
+}
+
+int bio_write(BIO *bio, PyObject *from) {
+ const void *fbuf;
+ int flen = 0, ret;
+
+ if (m2_PyObject_AsReadBufferInt(from, &fbuf, &flen) == -1)
+ return -1;
+
+ Py_BEGIN_ALLOW_THREADS
+ ret = BIO_write(bio, fbuf, flen);
+ Py_END_ALLOW_THREADS
+ if (ret < 0) {
+ if (ERR_peek_error()) {
+ m2_PyErr_Msg(_bio_err);
+ return -1;
+ }
+ }
+ return ret;
+}
+
+/* XXX Casting size_t to int. */
+int bio_ctrl_pending(BIO *bio) {
+ return (int)BIO_ctrl_pending(bio);
+}
+
+int bio_ctrl_wpending(BIO *bio) {
+ return (int)BIO_ctrl_wpending(bio);
+}
+
+int bio_ctrl_get_write_guarantee(BIO *a) {
+ return BIO_ctrl_get_write_guarantee(a);
+}
+
+int bio_reset(BIO *bio) {
+ return (int)BIO_reset(bio);
+}
+
+
+SWIGINTERN int
+SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc)
+{
+#if PY_VERSION_HEX>=0x03000000
+ if (PyUnicode_Check(obj))
+#else
+ if (PyString_Check(obj))
+#endif
+ {
+ char *cstr; Py_ssize_t len;
+#if PY_VERSION_HEX>=0x03000000
+ if (!alloc && cptr) {
+ /* We can't allow converting without allocation, since the internal
+ representation of string in Python 3 is UCS-2/UCS-4 but we require
+ a UTF-8 representation.
+ TODO(bhy) More detailed explanation */
+ return SWIG_RuntimeError;
+ }
+ obj = PyUnicode_AsUTF8String(obj);
+ PyBytes_AsStringAndSize(obj, &cstr, &len);
+ if(alloc) *alloc = SWIG_NEWOBJ;
+#else
+ PyString_AsStringAndSize(obj, &cstr, &len);
+#endif
+ if (cptr) {
+ if (alloc) {
+ /*
+ In python the user should not be able to modify the inner
+ string representation. To warranty that, if you define
+ SWIG_PYTHON_SAFE_CSTRINGS, a new/copy of the python string
+ buffer is always returned.
+
+ The default behavior is just to return the pointer value,
+ so, be careful.
+ */
+#if defined(SWIG_PYTHON_SAFE_CSTRINGS)
+ if (*alloc != SWIG_OLDOBJ)
+#else
+ if (*alloc == SWIG_NEWOBJ)
+#endif
+ {
+ *cptr = (char *)memcpy((char *)malloc((len + 1)*sizeof(char)), cstr, sizeof(char)*(len + 1));
+ *alloc = SWIG_NEWOBJ;
+ }
+ else {
+ *cptr = cstr;
+ *alloc = SWIG_OLDOBJ;
+ }
+ } else {
+ #if PY_VERSION_HEX>=0x03000000
+ assert(0); /* Should never reach here in Python 3 */
+ #endif
+ *cptr = SWIG_Python_str_AsChar(obj);
+ }
+ }
+ if (psize) *psize = len + 1;
+#if PY_VERSION_HEX>=0x03000000
+ Py_XDECREF(obj);
+#endif
+ return SWIG_OK;
+ } else {
+ swig_type_info* pchar_descriptor = SWIG_pchar_descriptor();
+ if (pchar_descriptor) {
+ void* vptr = 0;
+ if (SWIG_ConvertPtr(obj, &vptr, pchar_descriptor, 0) == SWIG_OK) {
+ if (cptr) *cptr = (char *) vptr;
+ if (psize) *psize = vptr ? (strlen((char *)vptr) + 1) : 0;
+ if (alloc) *alloc = SWIG_OLDOBJ;
+ return SWIG_OK;
+ }
+ }
+ }
+ return SWIG_TypeError;
+}
+
+
+
+
+
+int bio_flush(BIO *bio) {
+ return (int)BIO_flush(bio);
+}
+
+int bio_seek(BIO *bio, int offset) {
+ return (int)BIO_seek(bio, offset);
+}
+
+int bio_tell(BIO* bio) {
+ return BIO_tell(bio);
+}
+
+void bio_set_flags(BIO *bio, int flags) {
+ BIO_set_flags(bio, flags);
+}
+
+int bio_get_flags(BIO *bio) {
+ return BIO_get_flags(bio);
+}
+
+/*
+ * sets the cipher of BIO @param b to c using key @param key and IV @iv.
+ * @param enc should be set to 1 for encryption and zero to decryption.
+ *
+ */
+PyObject *bio_set_cipher(BIO *b, EVP_CIPHER *c, PyObject *key, PyObject *iv, int op) {
+ const void *kbuf, *ibuf;
+ Py_ssize_t klen, ilen;
+
+ if ((PyObject_AsReadBuffer(key, &kbuf, &klen) == -1)
+ || (PyObject_AsReadBuffer(iv, &ibuf, &ilen) == -1))
+ return NULL;
+
+ BIO_set_cipher(b, (const EVP_CIPHER *)c,
+ (unsigned char *)kbuf, (unsigned char *)ibuf, op);
+ Py_RETURN_NONE;
+}
+
+int bio_set_mem_eof_return(BIO *b, int v) {
+ return (int)BIO_set_mem_eof_return(b, v);
+}
+
+int bio_get_fd(BIO *bio) {
+ return BIO_get_fd(bio, NULL);
+}
+
+
+int bio_do_handshake(BIO *bio) {
+ return BIO_do_handshake(bio);
+}
+
+/* macro */
+int bio_make_bio_pair(BIO* b1, BIO* b2) {
+ return BIO_make_bio_pair(b1, b2);
+}
+
+int bio_set_write_buf_size(BIO* b, size_t size) {
+ return BIO_set_write_buf_size(b, size);
+}
+
+int bio_should_retry(BIO* a) {
+ return BIO_should_retry(a);
+}
+
+int bio_should_read(BIO* a) {
+ return BIO_should_read(a);
+}
+
+int bio_should_write(BIO* a) {
+ return BIO_should_write(a);
+}
+
+/* Macros for things not defined before 1.1.0 */
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+static BIO_METHOD *
+BIO_meth_new( int type, const char *name )
+{
+ BIO_METHOD *method = malloc( sizeof(BIO_METHOD) );
+ memset( method, 0, sizeof(BIO_METHOD) );
+
+ method->type = type;
+ method->name = name;
+
+ return method;
+}
+
+static void
+BIO_meth_free( BIO_METHOD *meth )
+{
+ if ( meth == NULL ) {
+ return;
+ }
+
+ free(meth);
+}
+#define BIO_meth_set_write(m, f) (m)->bwrite = (f)
+#define BIO_meth_set_read(m, f) (m)->bread = (f)
+#define BIO_meth_set_puts(m, f) (m)->bputs = (f)
+#define BIO_meth_set_gets(m, f) (m)->bgets = (f)
+#define BIO_meth_set_ctrl(m, f) (m)->ctrl = (f)
+#define BIO_meth_set_create(m, f) (m)->create = (f)
+#define BIO_meth_set_destroy(m, f) (m)->destroy = (f)
+#define BIO_set_shutdown(b, x) (b)->shutdown = x
+#define BIO_get_shutdown(b) (b)->shutdown
+#define BIO_set_init(b, x) b->init = x
+#define BIO_get_init(b) (b)->init
+#define BIO_set_data(b, x) b->ptr = x
+#define BIO_clear_flags(b, x) b->flags &= ~(x)
+#define BIO_get_data(b) b->ptr
+#endif
+
+/* implment custom BIO_s_pyfd */
+
+#ifdef _WIN32
+# define clear_sys_error() SetLastError(0)
+/* Linux doesn't use underscored calls yet */
+# define open(p, f, m) _open(p, f, m)
+# define read(f, b, n) _read(f, b, n)
+# define write(f, b, n) _write(f, b, n)
+# define close(f) _close(f)
+# define lseek(fd, o, w) _lseek(fd, o, w)
+#else
+# define clear_sys_error() errno=0
+#endif
+
+typedef struct pyfd_struct {
+ int fd;
+} BIO_PYFD_CTX;
+
+/* Setting up methods_fdp */
+static BIO_METHOD *methods_fdp;
+
+static int pyfd_write(BIO *b, const char *in, int inl) {
+ int ret, fd;
+
+ if (BIO_get_fd(b, &fd) == -1) {
+ PyErr_SetString(_bio_err, "BIO has not been initialized.");
+ return -1;
+ }
+ clear_sys_error();
+ ret = write(fd, in, inl);
+ BIO_clear_retry_flags(b);
+ if (ret <= 0) {
+ if (BIO_fd_should_retry(ret))
+ BIO_set_retry_write(b);
+ }
+ return ret;
+}
+
+static int pyfd_read(BIO *b, char *out, int outl) {
+ int ret = 0, fd;
+
+ if (BIO_get_fd(b, &fd) == -1) {
+ PyErr_SetString(_bio_err, "BIO has not been initialized.");
+ return -1;
+ }
+ if (out != NULL) {
+ clear_sys_error();
+ ret = read(fd, out, outl);
+ BIO_clear_retry_flags(b);
+ if (ret <= 0) {
+ if (BIO_fd_should_retry(ret))
+ BIO_set_retry_read(b);
+ }
+ }
+ return ret;
+}
+
+static int pyfd_puts(BIO *bp, const char *str) {
+ int n, ret;
+
+ n = strlen(str);
+ ret = pyfd_write(bp, str, n);
+ return ret;
+}
+
+static int pyfd_gets(BIO *bp, char *buf, int size) {
+ int ret = 0;
+ char *ptr = buf;
+ char *end = buf + size - 1;
+
+ /* See
+ https://github.com/openssl/openssl/pull/3442
+ We were here just repeating a bug from OpenSSL
+ */
+ while (ptr < end && pyfd_read(bp, ptr, 1) > 0) {
+ if (*ptr++ == '\n')
+ break;
+ }
+
+ ptr[0] = '\0';
+
+ if (buf[0] != '\0')
+ ret = strlen(buf);
+ return ret;
+}
+
+static int pyfd_new(BIO* b) {
+ BIO_PYFD_CTX* ctx;
+
+ ctx = OPENSSL_zalloc(sizeof(*ctx));
+ if (ctx == NULL)
+ return 0;
+
+ ctx->fd = -1;
+
+ BIO_set_data(b, ctx);
+ BIO_set_shutdown(b, 0);
+ BIO_set_init(b, 1);
+
+ return 1;
+ }
+
+static int pyfd_free(BIO* b) {
+ BIO_PYFD_CTX* ctx;
+
+ if (b == 0)
+ return 0;
+
+ ctx = BIO_get_data(b);
+ if (ctx == NULL)
+ return 0;
+
+ if (BIO_get_shutdown(b) && BIO_get_init(b))
+ close(ctx->fd);
+
+ BIO_set_data(b, NULL);
+ BIO_set_shutdown(b, 0);
+ BIO_set_init(b, 0);
+
+ OPENSSL_free(ctx);
+
+ return 1;
+}
+
+static long pyfd_ctrl(BIO *b, int cmd, long num, void *ptr) {
+ BIO_PYFD_CTX* ctx;
+ int *ip;
+ long ret = 1;
+
+ ctx = BIO_get_data(b);
+ if (ctx == NULL)
+ return 0;
+
+ switch (cmd) {
+ case BIO_CTRL_RESET:
+ num = 0;
+ case BIO_C_FILE_SEEK:
+ ret = (long)lseek(ctx->fd, num, 0);
+ break;
+ case BIO_C_FILE_TELL:
+ case BIO_CTRL_INFO:
+ ret = (long)lseek(ctx->fd, 0, 1);
+ break;
+ case BIO_C_SET_FD:
+ pyfd_free(b);
+ if (*((int *)ptr) > -1) {
+ if (!pyfd_new(b) || !(ctx = BIO_get_data(b)))
+ return 0;
+ ctx->fd = *((int *)ptr);
+ BIO_set_shutdown(b, (int)num);
+ BIO_set_init(b, 1);
+ }
+ break;
+ case BIO_C_GET_FD:
+ if (BIO_get_init(b)) {
+ ip = (int *)ptr;
+ if (ip != NULL)
+ *ip = ctx->fd;
+ ret = ctx->fd;
+ } else
+ ret = -1;
+ break;
+ case BIO_CTRL_GET_CLOSE:
+ ret = BIO_get_shutdown(b);
+ break;
+ case BIO_CTRL_SET_CLOSE:
+ BIO_set_shutdown(b, (int)num);
+ break;
+ case BIO_CTRL_PENDING:
+ case BIO_CTRL_WPENDING:
+ ret = 0;
+ break;
+ case BIO_CTRL_DUP:
+ case BIO_CTRL_FLUSH:
+ ret = 1;
+ break;
+ default:
+ ret = 0;
+ break;
+ }
+ return ret;
+}
+
+void pyfd_init(void) {
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ methods_fdp = BIO_meth_new(
+ BIO_get_new_index()|BIO_TYPE_DESCRIPTOR|BIO_TYPE_SOURCE_SINK,
+ "python file descriptor");
+#else
+ methods_fdp = BIO_meth_new(
+ 100 |BIO_TYPE_DESCRIPTOR|BIO_TYPE_SOURCE_SINK,
+ "python file descriptor");
+#endif
+
+ BIO_meth_set_write(methods_fdp, pyfd_write);
+ BIO_meth_set_read(methods_fdp, pyfd_read);
+ BIO_meth_set_puts(methods_fdp, pyfd_puts);
+ BIO_meth_set_gets(methods_fdp, pyfd_gets);
+ BIO_meth_set_ctrl(methods_fdp, pyfd_ctrl);
+ BIO_meth_set_create(methods_fdp, pyfd_new);
+ BIO_meth_set_destroy(methods_fdp, pyfd_free);
+}
+
+BIO* BIO_new_pyfd(int fd, int close_flag) {
+ BIO *ret;
+
+ ret = BIO_new(methods_fdp);
+ BIO_set_fd(ret, fd, close_flag);
+ return ret;
+ }
+
+
+SWIGINTERNINLINE int
+SWIG_AsVal_size_t (PyObject * obj, size_t *val)
+{
+ unsigned long v;
+ int res = SWIG_AsVal_unsigned_SS_long (obj, val ? &v : 0);
+ if (SWIG_IsOK(res) && val) *val = (size_t)(v);
+ return res;
+}
+
+
+#include <openssl/bn.h>
+
+
+PyObject *bn_rand(int bits, int top, int bottom)
+{
+ BIGNUM* rnd;
+ PyObject *ret;
+ char *randhex;
+
+ rnd = BN_new();
+ if (rnd == NULL) {
+ m2_PyErr_Msg(PyExc_Exception);
+ return NULL;
+ }
+
+ if (!BN_rand(rnd, bits, top, bottom)) {
+ /*Custom errors?*/
+ m2_PyErr_Msg(PyExc_Exception);
+ BN_free(rnd);
+ return NULL;
+ }
+
+ randhex = BN_bn2hex(rnd);
+ if (!randhex) {
+ /*Custom errors?*/
+ m2_PyErr_Msg(PyExc_Exception);
+ BN_free(rnd);
+ return NULL;
+ }
+ BN_free(rnd);
+
+ ret = PyLong_FromString(randhex, NULL, 16);
+ OPENSSL_free(randhex);
+ return ret;
+}
+
+
+PyObject *bn_rand_range(PyObject *range)
+{
+ BIGNUM* rnd;
+ BIGNUM *rng = NULL;
+ PyObject *ret, *tuple;
+ PyObject *format, *rangePyString;
+ char *randhex; /* PyLong_FromString is unhappy with const */
+ const char *rangehex;
+
+ /* Wow, it's a lot of work to convert into a hex string in C! */
+ format = PyUnicode_FromString("%x");
+
+ if (!format) {
+ PyErr_SetString(PyExc_RuntimeError, "Cannot create Python string '%x'");
+ return NULL;
+ }
+ tuple = PyTuple_New(1);
+ if (!tuple) {
+ Py_DECREF(format);
+ PyErr_SetString(PyExc_RuntimeError, "PyTuple_New() fails");
+ return NULL;
+ }
+ Py_INCREF(range);
+ PyTuple_SET_ITEM(tuple, 0, range);
+
+ rangePyString = PyUnicode_Format(format, tuple);
+
+ if (!rangePyString) {
+ PyErr_SetString(PyExc_Exception, "String Format failed");
+ Py_DECREF(format);
+ Py_DECREF(tuple);
+ return NULL;
+ }
+ Py_DECREF(format);
+ Py_DECREF(tuple);
+
+ rangehex = (const char*)PyUnicode_AsUTF8(rangePyString);
+
+ if (!BN_hex2bn(&rng, rangehex)) {
+ /*Custom errors?*/
+ m2_PyErr_Msg(PyExc_Exception);
+ Py_DECREF(rangePyString);
+ return NULL;
+ }
+
+ Py_DECREF(rangePyString);
+
+ if (!(rnd = BN_new())) {
+ PyErr_SetString(PyExc_MemoryError, "bn_rand_range");
+ return NULL;
+ }
+
+ if (!BN_rand_range(rnd, rng)) {
+ /*Custom errors?*/
+ m2_PyErr_Msg(PyExc_Exception);
+ BN_free(rnd);
+ BN_free(rng);
+ return NULL;
+ }
+
+ BN_free(rng);
+
+ randhex = BN_bn2hex(rnd);
+ if (!randhex) {
+ /*Custom errors?*/
+ m2_PyErr_Msg(PyExc_Exception);
+ BN_free(rnd);
+ return NULL;
+ }
+ BN_free(rnd);
+
+ ret = PyLong_FromString(randhex, NULL, 16);
+ OPENSSL_free(randhex);
+ return ret;
+}
+
+
+
+static PyObject *_rand_err;
+
+void rand_init(PyObject *rand_err) {
+ Py_INCREF(rand_err);
+ _rand_err = rand_err;
+}
+
+PyObject *rand_seed(PyObject *seed) {
+ const void *buf;
+ int len = 0;
+
+ m2_PyObject_AsReadBufferInt(seed, &buf, &len);
+
+ RAND_seed(buf, len);
+ Py_RETURN_NONE;
+}
+
+PyObject *rand_add(PyObject *blob, double entropy) {
+ const void *buf;
+ int len = 0;
+
+ m2_PyObject_AsReadBufferInt(blob, &buf, &len);
+
+ RAND_add(buf, len, entropy);
+ Py_RETURN_NONE;
+}
+
+PyObject *rand_bytes(int n) {
+ void *blob;
+ int ret;
+ PyObject *obj;
+
+ if (!(blob = PyMem_Malloc(n))) {
+ PyErr_SetString(PyExc_MemoryError,
+ "Insufficient memory for rand_bytes.");
+ return NULL;
+ }
+ if ((ret = RAND_bytes(blob, n)) == 1) {
+ obj = PyBytes_FromStringAndSize(blob, n);
+ PyMem_Free(blob);
+ return obj;
+ } else if (ret == 0) {
+ PyErr_SetString(_rand_err, "Not enough randomness.");
+ PyMem_Free(blob);
+ return NULL;
+ } else if (ret == -1) {
+ PyErr_SetString(_rand_err,
+ "Not supported by the current RAND method.");
+ PyMem_Free(blob);
+ return NULL;
+ } else {
+ PyMem_Free(blob);
+ m2_PyErr_Msg(_rand_err);
+ return NULL;
+ }
+}
+
+PyObject *rand_pseudo_bytes(int n) {
+ int ret;
+ unsigned char *blob;
+ PyObject *tuple;
+
+ if (!(blob=(unsigned char *)PyMem_Malloc(n))) {
+ PyErr_SetString(PyExc_MemoryError, "Insufficient memory for rand_pseudo_bytes.");
+ return NULL;
+ }
+ if (!(tuple=PyTuple_New(2))) {
+ PyErr_SetString(PyExc_RuntimeError, "PyTuple_New() fails");
+ PyMem_Free(blob);
+ return NULL;
+ }
+ ret = RAND_pseudo_bytes(blob, n);
+ if (ret == -1) {
+ PyMem_Free(blob);
+ Py_DECREF(tuple);
+ PyErr_SetString(_rand_err,
+ "Function RAND_pseudo_bytes not supported by the current RAND method.");
+ return NULL;
+ } else {
+ PyTuple_SET_ITEM(tuple, 0, PyBytes_FromStringAndSize((char*)blob, n));
+
+ PyMem_Free(blob);
+ PyTuple_SET_ITEM(tuple, 1, PyLong_FromLong((long)ret));
+ return tuple;
+ }
+}
+
+PyObject *rand_file_name(void) {
+ PyObject *obj;
+ char *str;
+ if ((obj = PyBytes_FromStringAndSize(NULL, BUFSIZ))==NULL) {
+ PyErr_SetString(PyExc_MemoryError, "rand_file_name");
+ return NULL;
+ }
+ str=PyBytes_AS_STRING(obj);
+ if (RAND_file_name(str, BUFSIZ)==NULL) {
+ PyErr_SetString(PyExc_RuntimeError, "rand_file_name");
+ return NULL;
+ }
+ if (_PyBytes_Resize(&obj, (Py_ssize_t)strlen(str))!=0)
+ return NULL; /* mem exception set by _PyBytes_Resize */
+ return obj;
+}
+
+void rand_screen(void) {
+#ifdef _WIN32
+ RAND_screen();
+#endif
+}
+
+int rand_win32_event(unsigned int imsg, int wparam, long lparam) {
+#ifdef _WIN32
+ return RAND_event(imsg, wparam, lparam);
+#else
+ return 0;
+#endif
+}
+
+
+SWIGINTERN int
+SWIG_AsVal_unsigned_SS_int (PyObject * obj, unsigned int *val)
+{
+ unsigned long v;
+ int res = SWIG_AsVal_unsigned_SS_long (obj, &v);
+ if (SWIG_IsOK(res)) {
+ if ((v > UINT_MAX)) {
+ return SWIG_OverflowError;
+ } else {
+ if (val) *val = (unsigned int)(v);
+ }
+ }
+ return res;
+}
+
+
+#include <assert.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+#include <openssl/rsa.h>
+#include <openssl/opensslv.h>
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+
+HMAC_CTX *HMAC_CTX_new(void) {
+ HMAC_CTX *ret = PyMem_Malloc(sizeof(HMAC_CTX));
+ HMAC_CTX_init(ret);
+ return ret;
+}
+#define HMAC_CTX_reset(ctx) HMAC_CTX_init(ctx)
+#define HMAC_CTX_free(ctx) \
+ do { \
+ HMAC_CTX_cleanup(ctx); \
+ PyMem_Free((void *)ctx); \
+ } while(0)
+
+#define EVP_CIPHER_CTX_reset(ctx) EVP_CIPHER_CTX_init(ctx)
+#endif
+
+
+#define PKCS5_SALT_LEN 8
+
+static PyObject *_evp_err;
+
+void evp_init(PyObject *evp_err) {
+ Py_INCREF(evp_err);
+ _evp_err = evp_err;
+}
+
+
+RSA *pkey_get1_rsa(EVP_PKEY *pkey) {
+ RSA *ret = NULL;
+
+ if ((ret = EVP_PKEY_get1_RSA(pkey)) == NULL) {
+ /* _evp_err now inherits from PyExc_ValueError, so we should
+ * keep API intact.
+ */
+ PyErr_Format(_evp_err, "Invalid key in function %s.", __FUNCTION__);
+ }
+
+ return ret;
+}
+
+
+PyObject *pkcs5_pbkdf2_hmac_sha1(PyObject *pass,
+ PyObject *salt,
+ int iter,
+ int keylen) {
+ unsigned char *key;
+ unsigned char *saltbuf;
+ char *passbuf;
+ PyObject *ret;
+ int passlen = 0, saltlen = 0;
+
+ if (m2_PyObject_AsReadBufferInt(pass, (const void **)&passbuf,
+ &passlen) == -1)
+ return NULL;
+ if (m2_PyObject_AsReadBufferInt(salt, (const void **)&saltbuf,
+ &saltlen) == -1)
+ return NULL;
+
+ key = PyMem_Malloc(keylen);
+ if (key == NULL)
+ return PyErr_NoMemory();
+ PKCS5_PBKDF2_HMAC_SHA1(passbuf, passlen, saltbuf, saltlen, iter,
+ keylen, key);
+ ret = PyBytes_FromStringAndSize((char*)key, keylen);
+ OPENSSL_cleanse(key, keylen);
+ PyMem_Free(key);
+ return ret;
+}
+
+EVP_MD_CTX *md_ctx_new(void) {
+ EVP_MD_CTX *ctx;
+
+ if (!(ctx = EVP_MD_CTX_create())) {
+ PyErr_SetString(PyExc_MemoryError, "md_ctx_new");
+ return NULL;
+ }
+ return ctx;
+}
+
+void md_ctx_free(EVP_MD_CTX *ctx) {
+ EVP_MD_CTX_destroy(ctx);
+}
+
+int digest_update(EVP_MD_CTX *ctx, PyObject *blob) {
+ const void *buf;
+ Py_ssize_t len;
+
+ if (PyObject_AsReadBuffer(blob, &buf, &len) == -1)
+ return -1;
+
+ return EVP_DigestUpdate(ctx, buf, len);
+}
+
+PyObject *digest_final(EVP_MD_CTX *ctx) {
+ void *blob;
+ int blen;
+ PyObject *ret;
+
+ if (!(blob = PyMem_Malloc(EVP_MD_CTX_size(ctx)))) {
+ PyErr_SetString(PyExc_MemoryError, "digest_final");
+ return NULL;
+ }
+ if (!EVP_DigestFinal(ctx, blob, (unsigned int *)&blen)) {
+ PyMem_Free(blob);
+ m2_PyErr_Msg(_evp_err);
+ return NULL;
+ }
+
+ ret = PyBytes_FromStringAndSize(blob, blen);
+
+ PyMem_Free(blob);
+ return ret;
+}
+
+HMAC_CTX *hmac_ctx_new(void) {
+ HMAC_CTX *ctx;
+
+ if (!(ctx = HMAC_CTX_new())) {
+ PyErr_SetString(PyExc_MemoryError, "hmac_ctx_new");
+ return NULL;
+ }
+ return ctx;
+}
+
+void hmac_ctx_free(HMAC_CTX *ctx) {
+ HMAC_CTX_free(ctx);
+}
+
+PyObject *hmac_init(HMAC_CTX *ctx, PyObject *key, const EVP_MD *md) {
+ const void *kbuf;
+ int klen = 0;
+
+ if (m2_PyObject_AsReadBufferInt(key, &kbuf, &klen) == -1)
+ return NULL;
+
+ if (!HMAC_Init_ex(ctx, kbuf, klen, md, NULL)) {
+ PyErr_SetString(_evp_err, "HMAC_Init failed");
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
+
+PyObject *hmac_update(HMAC_CTX *ctx, PyObject *blob) {
+ const void *buf;
+ Py_ssize_t len;
+
+ if (PyObject_AsReadBuffer(blob, &buf, &len) == -1)
+ return NULL;
+
+ if (!HMAC_Update(ctx, buf, len)) {
+ PyErr_SetString(_evp_err, "HMAC_Update failed");
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
+
+PyObject *hmac_final(HMAC_CTX *ctx) {
+ void *blob;
+ int blen;
+ PyObject *ret;
+
+ if (!(blob = PyMem_Malloc(HMAC_size(ctx)))) {
+ PyErr_SetString(PyExc_MemoryError, "hmac_final");
+ return NULL;
+ }
+
+ if (!HMAC_Final(ctx, blob, (unsigned int *)&blen)) {
+ PyErr_SetString(_evp_err, "HMAC_Final failed");
+ return NULL;
+ }
+
+ ret = PyBytes_FromStringAndSize(blob, blen);
+
+ PyMem_Free(blob);
+ return ret;
+}
+
+PyObject *hmac(PyObject *key, PyObject *data, const EVP_MD *md) {
+ const void *kbuf, *dbuf;
+ void *blob;
+ int klen = 0;
+ unsigned int blen;
+ Py_ssize_t dlen;
+ PyObject *ret;
+
+ if ((m2_PyObject_AsReadBufferInt(key, &kbuf, &klen) == -1)
+ || (PyObject_AsReadBuffer(data, &dbuf, &dlen) == -1))
+ return NULL;
+
+ if (!(blob = PyMem_Malloc(EVP_MAX_MD_SIZE))) {
+ PyErr_SetString(PyExc_MemoryError, "hmac");
+ return NULL;
+ }
+ HMAC(md, kbuf, klen, dbuf, dlen, blob, &blen);
+ blob = PyMem_Realloc(blob, blen);
+
+ ret = PyBytes_FromStringAndSize(blob, blen);
+
+ PyMem_Free(blob);
+ return ret;
+}
+
+EVP_CIPHER_CTX *cipher_ctx_new(void) {
+ EVP_CIPHER_CTX *ctx;
+
+ if (!(ctx = EVP_CIPHER_CTX_new())) {
+ PyErr_SetString(PyExc_MemoryError, "cipher_ctx_new");
+ return NULL;
+ }
+ EVP_CIPHER_CTX_reset(ctx);
+ return ctx;
+}
+
+void cipher_ctx_free(EVP_CIPHER_CTX *ctx) {
+ EVP_CIPHER_CTX_free(ctx);
+}
+
+PyObject *bytes_to_key(const EVP_CIPHER *cipher, EVP_MD *md,
+ PyObject *data, PyObject *salt,
+ PyObject *iv, /* Not used */
+ int iter) {
+ unsigned char key[EVP_MAX_KEY_LENGTH];
+ const void *dbuf, *sbuf;
+ int dlen = 0, klen;
+ Py_ssize_t slen;
+ PyObject *ret;
+
+ if ((m2_PyObject_AsReadBufferInt(data, &dbuf, &dlen) == -1)
+ || (PyObject_AsReadBuffer(salt, &sbuf, &slen) == -1))
+ return NULL;
+
+ assert((slen == 8) || (slen == 0));
+ klen = EVP_BytesToKey(cipher, md, (unsigned char *)sbuf,
+ (unsigned char *)dbuf, dlen, iter,
+ key, NULL); /* Since we are not returning IV no need to derive it */
+
+ ret = PyBytes_FromStringAndSize((char*)key, klen);
+
+ return ret;
+}
+
+PyObject *cipher_init(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+ PyObject *key, PyObject *iv, int mode) {
+ const void *kbuf, *ibuf;
+ Py_ssize_t klen, ilen;
+
+ if ((PyObject_AsReadBuffer(key, &kbuf, &klen) == -1)
+ || (PyObject_AsReadBuffer(iv, &ibuf, &ilen) == -1))
+ return NULL;
+
+ if (!EVP_CipherInit(ctx, cipher, (unsigned char *)kbuf,
+ (unsigned char *)ibuf, mode)) {
+ m2_PyErr_Msg(_evp_err);
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
+
+PyObject *cipher_update(EVP_CIPHER_CTX *ctx, PyObject *blob) {
+ const void *buf;
+ int len = 0, olen;
+ void *obuf;
+ PyObject *ret;
+
+ if (m2_PyObject_AsReadBufferInt(blob, &buf, &len) == -1)
+ return NULL;
+
+ if (!(obuf = PyMem_Malloc(len + EVP_CIPHER_CTX_block_size(ctx) - 1))) {
+ PyErr_SetString(PyExc_MemoryError, "cipher_update");
+ return NULL;
+ }
+ if (!EVP_CipherUpdate(ctx, obuf, &olen, (unsigned char *)buf, len)) {
+ PyMem_Free(obuf);
+ m2_PyErr_Msg(_evp_err);
+ return NULL;
+ }
+
+ ret = PyBytes_FromStringAndSize(obuf, olen);
+
+ PyMem_Free(obuf);
+ return ret;
+}
+
+PyObject *cipher_final(EVP_CIPHER_CTX *ctx) {
+ void *obuf;
+ int olen;
+ PyObject *ret;
+
+ if (!(obuf = PyMem_Malloc(EVP_CIPHER_CTX_block_size(ctx)))) {
+ PyErr_SetString(PyExc_MemoryError, "cipher_final");
+ return NULL;
+ }
+ if (!EVP_CipherFinal(ctx, (unsigned char *)obuf, &olen)) {
+ PyMem_Free(obuf);
+ m2_PyErr_Msg(_evp_err);
+ return NULL;
+ }
+
+ ret = PyBytes_FromStringAndSize(obuf, olen);
+
+ PyMem_Free(obuf);
+ return ret;
+}
+
+PyObject *sign_update(EVP_MD_CTX *ctx, PyObject *blob) {
+ const void *buf;
+ Py_ssize_t len;
+
+ if (PyObject_AsReadBuffer(blob, &buf, &len) == -1)
+ return NULL;
+
+ if (!EVP_SignUpdate(ctx, buf, len)) {
+ m2_PyErr_Msg(_evp_err);
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
+
+PyObject *sign_final(EVP_MD_CTX *ctx, EVP_PKEY *pkey) {
+ PyObject *ret;
+ unsigned char *sigbuf;
+ unsigned int siglen = EVP_PKEY_size(pkey);
+
+ sigbuf = (unsigned char*)OPENSSL_malloc(siglen);
+ if (!sigbuf) {
+ PyErr_SetString(PyExc_MemoryError, "sign_final");
+ return NULL;
+ }
+
+ if (!EVP_SignFinal(ctx, sigbuf, &siglen, pkey)) {
+ m2_PyErr_Msg(_evp_err);
+ OPENSSL_cleanse(sigbuf, siglen);
+ OPENSSL_free(sigbuf);
+ return NULL;
+ }
+
+ ret = PyBytes_FromStringAndSize((char*)sigbuf, siglen);
+
+ OPENSSL_cleanse(sigbuf, siglen);
+ OPENSSL_free(sigbuf);
+ return ret;
+}
+
+int verify_update(EVP_MD_CTX *ctx, PyObject *blob) {
+ const void *buf;
+ Py_ssize_t len;
+
+ if (PyObject_AsReadBuffer(blob, &buf, &len) == -1)
+ return -1;
+
+ return EVP_VerifyUpdate(ctx, buf, len);
+}
+
+
+int verify_final(EVP_MD_CTX *ctx, PyObject *blob, EVP_PKEY *pkey) {
+ unsigned char *kbuf;
+ int len = 0;
+
+ if (m2_PyObject_AsReadBufferInt(blob, (const void **)&kbuf, &len) == -1)
+ return -1;
+
+ return EVP_VerifyFinal(ctx, kbuf, len, pkey);
+}
+
+
+const EVP_MD *get_digestbyname(const char* name) {
+ const EVP_MD *ret = NULL;
+
+ if ((ret = EVP_get_digestbyname(name)) == NULL) {
+ m2_PyErr_Msg(_evp_err);
+ }
+
+ return ret;
+}
+
+
+int pkey_write_pem_no_cipher(EVP_PKEY *pkey, BIO *f, PyObject *pyfunc) {
+ int ret;
+
+ Py_INCREF(pyfunc);
+ Py_BEGIN_ALLOW_THREADS
+ ret = PEM_write_bio_PKCS8PrivateKey(f, pkey, NULL, NULL, 0,
+ passphrase_callback, (void *)pyfunc);
+ Py_END_ALLOW_THREADS
+ Py_DECREF(pyfunc);
+ return ret;
+}
+
+
+int pkey_write_pem(EVP_PKEY *pkey, BIO *f, EVP_CIPHER *cipher, PyObject *pyfunc) {
+ int ret;
+
+ Py_INCREF(pyfunc);
+ Py_BEGIN_ALLOW_THREADS
+ ret = PEM_write_bio_PKCS8PrivateKey(f, pkey, cipher, NULL, 0,
+ passphrase_callback, (void *)pyfunc);
+ Py_END_ALLOW_THREADS
+ Py_DECREF(pyfunc);
+ return ret;
+}
+
+
+EVP_PKEY *pkey_new(void) {
+ EVP_PKEY *ret;
+
+ if ((ret = EVP_PKEY_new()) == NULL) {
+ PyErr_Format(PyExc_MemoryError,
+ "Insufficient memory for new key in function %s.", __FUNCTION__);
+ }
+
+ return ret;
+}
+
+EVP_PKEY *pkey_read_pem(BIO *f, PyObject *pyfunc) {
+ EVP_PKEY *pk;
+
+ Py_INCREF(pyfunc);
+ Py_BEGIN_ALLOW_THREADS
+ pk = PEM_read_bio_PrivateKey(f, NULL, passphrase_callback, (void *)pyfunc);
+ Py_END_ALLOW_THREADS
+ Py_DECREF(pyfunc);
+
+ if (pk == NULL) {
+ PyErr_Format(_evp_err,
+ "Unable to read private key in function %s.", __FUNCTION__);
+ }
+
+ return pk;
+}
+
+EVP_PKEY *pkey_read_pem_pubkey(BIO *f, PyObject *pyfunc) {
+ EVP_PKEY *pk;
+
+ Py_INCREF(pyfunc);
+ Py_BEGIN_ALLOW_THREADS
+ pk = PEM_read_bio_PUBKEY(f, NULL, passphrase_callback, (void *)pyfunc);
+ Py_END_ALLOW_THREADS
+ Py_DECREF(pyfunc);
+
+ if (pk == NULL) {
+ PyErr_Format(_evp_err,
+ "Unable to read public key in function %s.", __FUNCTION__);
+ }
+
+ return pk;
+}
+
+
+int pkey_assign_rsa(EVP_PKEY *pkey, RSA *rsa) {
+ return EVP_PKEY_assign_RSA(pkey, rsa);
+}
+
+PyObject *pkey_as_der(EVP_PKEY *pkey) {
+ unsigned char * pp = NULL;
+ int len;
+ PyObject * der;
+ len = i2d_PUBKEY(pkey, &pp);
+ if (len < 0){
+ PyErr_SetString(_evp_err, "EVP_PKEY as DER failed");
+ return NULL;
+ }
+
+ der = PyBytes_FromStringAndSize((char*)pp, len);
+
+ OPENSSL_free(pp);
+ return der;
+}
+
+PyObject *pkey_get_modulus(EVP_PKEY *pkey)
+{
+ RSA *rsa;
+ DSA *dsa;
+ BIO *bio;
+ BUF_MEM *bptr;
+ PyObject *ret;
+ const BIGNUM* bn;
+
+ switch (EVP_PKEY_base_id(pkey)) {
+ case EVP_PKEY_RSA:
+ rsa = EVP_PKEY_get1_RSA(pkey);
+
+ bio = BIO_new(BIO_s_mem());
+ if (!bio) {
+ RSA_free(rsa);
+ PyErr_SetString(PyExc_MemoryError, "pkey_get_modulus");
+ return NULL;
+ }
+
+ RSA_get0_key(rsa, &bn, NULL, NULL);
+ if (!BN_print(bio, bn)) {
+ m2_PyErr_Msg(PyExc_RuntimeError);
+ BIO_free(bio);
+ RSA_free(rsa);
+ return NULL;
+ }
+ BIO_get_mem_ptr(bio, &bptr);
+
+ ret = PyBytes_FromStringAndSize(bptr->data, bptr->length);
+
+ (void)BIO_set_close(bio, BIO_CLOSE);
+ BIO_free(bio);
+ RSA_free(rsa);
+
+ return ret;
+ break;
+
+ case EVP_PKEY_DSA:
+ dsa = EVP_PKEY_get1_DSA(pkey);
+
+ bio = BIO_new(BIO_s_mem());
+ if (!bio) {
+ DSA_free(dsa);
+ PyErr_SetString(PyExc_MemoryError, "pkey_get_modulus");
+ return NULL;
+ }
+
+ DSA_get0_key(dsa, &bn, NULL);
+ if (!BN_print(bio, bn)) {
+ m2_PyErr_Msg(PyExc_RuntimeError);
+ BIO_free(bio);
+ DSA_free(dsa);
+ return NULL;
+ }
+ BIO_get_mem_ptr(bio, &bptr);
+
+ ret = PyBytes_FromStringAndSize(bptr->data, bptr->length);
+
+ (void)BIO_set_close(bio, BIO_CLOSE);
+ BIO_free(bio);
+ DSA_free(dsa);
+
+ return ret;
+ break;
+
+ default:
+ PyErr_SetString(_evp_err, "unsupported key type");
+ return NULL;
+ }
+}
+
+
+
+#include <openssl/evp.h>
+
+#if OPENSSL_VERSION_NUMBER >= 0x0090800fL
+#include <openssl/aes.h>
+#endif
+
+/*
+// 2004-10-10, ngps:
+// CTR mode is not included in the default OpenSSL build.
+// To use the AES CTR ciphers, link with your own copy of OpenSSL.
+*/
+#ifdef HAVE_AES_CTR
+extern EVP_CIPHER const *EVP_aes_128_ctr(void);
+extern EVP_CIPHER const *EVP_aes_192_ctr(void);
+extern EVP_CIPHER const *EVP_aes_256_ctr(void);
+#endif
+
+
+AES_KEY *aes_new(void) {
+ AES_KEY *key;
+
+ if (!(key = (AES_KEY *)PyMem_Malloc(sizeof(AES_KEY)))) {
+ PyErr_SetString(PyExc_MemoryError,
+ "Insufficient memory for AES key.");
+ return NULL;
+ }
+ return key;
+}
+
+void AES_free(AES_KEY *key) {
+ PyMem_Free((void *)key);
+}
+
+/*
+// op == 0: encrypt
+// otherwise: decrypt (Python code will supply the value 1.)
+*/
+PyObject *AES_set_key(AES_KEY *key, PyObject *value, int bits, int op) {
+ char *vbuf;
+ Py_ssize_t vlen;
+
+ if (PyBytes_AsStringAndSize(value, &vbuf, &vlen) == -1)
+ return NULL;
+
+ if (op == 0)
+ AES_set_encrypt_key((const unsigned char *)vbuf, bits, key);
+ else
+ AES_set_decrypt_key((const unsigned char *)vbuf, bits, key);
+ Py_RETURN_NONE;
+}
+
+/*
+// op == 0: encrypt
+// otherwise: decrypt (Python code will supply the value 1.)
+*/
+PyObject *AES_crypt(const AES_KEY *key, PyObject *in, int outlen, int op) {
+ char *buf;
+ Py_ssize_t len;
+ unsigned char *out;
+ PyObject *res;
+
+ if (PyBytes_AsStringAndSize(in, &buf, &len) == -1)
+ return NULL;
+
+ if (!(out=(unsigned char *)PyMem_Malloc(outlen))) {
+ PyErr_SetString(PyExc_MemoryError, "AES_crypt");
+ return NULL;
+ }
+ if (op == 0)
+ AES_encrypt((const unsigned char *)buf, out, key);
+ else
+ AES_decrypt((const unsigned char *)buf, out, key);
+ res = PyBytes_FromStringAndSize((char*)out, outlen);
+ PyMem_Free(out);
+ return res;
+}
+
+int AES_type_check(AES_KEY *key) {
+ return 1;
+}
+
+
+#include <openssl/rc4.h>
+
+
+RC4_KEY *rc4_new(void) {
+ RC4_KEY *key;
+
+ if (!(key = (RC4_KEY *)PyMem_Malloc(sizeof(RC4_KEY))))
+ PyErr_SetString(PyExc_MemoryError, "rc4_new");
+ return key;
+}
+
+void rc4_free(RC4_KEY *key) {
+ PyMem_Free((void *)key);
+}
+
+PyObject *rc4_set_key(RC4_KEY *key, PyObject *value) {
+ const void *vbuf;
+ int vlen = 0;
+
+ if (m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
+ return NULL;
+
+ RC4_set_key(key, vlen, vbuf);
+ Py_RETURN_NONE;
+}
+
+PyObject *rc4_update(RC4_KEY *key, PyObject *in) {
+ PyObject *ret;
+ const void *buf;
+ Py_ssize_t len;
+ void *out;
+
+ if (PyObject_AsReadBuffer(in, &buf, &len) == -1)
+ return NULL;
+
+ if (!(out = PyMem_Malloc(len))) {
+ PyErr_SetString(PyExc_MemoryError, "expected a string object");
+ return NULL;
+ }
+ RC4(key, len, buf, out);
+
+ ret = PyBytes_FromStringAndSize(out, len);
+
+ PyMem_Free(out);
+ return ret;
+}
+
+int rc4_type_check(RC4_KEY *key) {
+ return 1;
+}
+
+
+#include <openssl/bn.h>
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/dh.h>
+
+
+static PyObject *_dh_err;
+
+void dh_init(PyObject *dh_err) {
+ Py_INCREF(dh_err);
+ _dh_err = dh_err;
+}
+
+int dh_type_check(DH *dh) {
+ /* Our getting here means we passed Swig's type checking,
+ XXX Still need to check the pointer for sanity? */
+ return 1;
+}
+
+
+DH *dh_read_parameters(BIO *bio) {
+ return PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
+}
+
+DH *dh_generate_parameters(int plen, int g, PyObject *pyfunc) {
+ DH *dh;
+ BN_GENCB *gencb;
+ int ret;
+
+ if ((gencb=BN_GENCB_new()) == NULL) {
+ m2_PyErr_Msg(_dh_err);
+ return NULL;
+ }
+
+ if ((dh=DH_new()) == NULL) {
+ m2_PyErr_Msg(_dh_err);
+ BN_GENCB_free(gencb);
+ return NULL;
+ }
+
+ BN_GENCB_set(gencb, bn_gencb_callback, (void *)pyfunc);
+
+ Py_INCREF(pyfunc);
+ ret = DH_generate_parameters_ex(dh, plen, g, gencb);
+ Py_DECREF(pyfunc);
+ BN_GENCB_free(gencb);
+
+ if (ret)
+ return dh;
+
+ m2_PyErr_Msg(_dh_err);
+ DH_free(dh);
+ return NULL;
+}
+
+/* Note return value shenanigan. */
+int dh_check(DH *dh) {
+ int err;
+
+ return (DH_check(dh, &err)) ? 0 : err;
+}
+
+PyObject *dh_compute_key(DH *dh, PyObject *pubkey) {
+ const void *pkbuf;
+ int pklen = 0, klen;
+ void *key;
+ BIGNUM *pk;
+ PyObject *ret;
+
+ if (m2_PyObject_AsReadBufferInt(pubkey, &pkbuf, &pklen) == -1)
+ return NULL;
+
+ if (!(pk = BN_mpi2bn((unsigned char *)pkbuf, pklen, NULL))) {
+ m2_PyErr_Msg(_dh_err);
+ return NULL;
+ }
+ if (!(key = PyMem_Malloc(DH_size(dh)))) {
+ BN_free(pk);
+ PyErr_SetString(PyExc_MemoryError, "dh_compute_key");
+ return NULL;
+ }
+ if ((klen = DH_compute_key((unsigned char *)key, pk, dh)) == -1) {
+ BN_free(pk);
+ PyMem_Free(key);
+ m2_PyErr_Msg(_dh_err);
+ return NULL;
+ }
+
+ ret = PyBytes_FromStringAndSize((const char *)key, klen);
+
+ BN_free(pk);
+ PyMem_Free(key);
+ return ret;
+}
+
+PyObject *dh_get_p(DH *dh) {
+ const BIGNUM* p = NULL;
+ DH_get0_pqg(dh, &p, NULL, NULL);
+ if (!p) {
+ PyErr_SetString(_dh_err, "'p' is unset");
+ return NULL;
+ }
+ return bn_to_mpi(p);
+}
+
+PyObject *dh_get_g(DH *dh) {
+ const BIGNUM* g = NULL;
+ DH_get0_pqg(dh, NULL, NULL, &g);
+ if (!g) {
+ PyErr_SetString(_dh_err, "'g' is unset");
+ return NULL;
+ }
+ return bn_to_mpi(g);
+}
+
+PyObject *dh_get_pub(DH *dh) {
+ const BIGNUM* pub_key = NULL;
+ DH_get0_key(dh, &pub_key, NULL);
+ if (!pub_key) {
+ PyErr_SetString(_dh_err, "'pub' is unset");
+ return NULL;
+ }
+ return bn_to_mpi(pub_key);
+}
+
+PyObject *dh_get_priv(DH *dh) {
+ const BIGNUM* priv_key = NULL;
+ DH_get0_key(dh, NULL, &priv_key);
+ if (!priv_key) {
+ PyErr_SetString(_dh_err, "'priv' is unset");
+ return NULL;
+ }
+ return bn_to_mpi(priv_key);
+}
+
+PyObject *dh_set_pg(DH *dh, PyObject *pval, PyObject* gval) {
+ BIGNUM* p, *g;
+
+ if (!(p = m2_PyObject_AsBIGNUM(pval, _dh_err))
+ || !(g = m2_PyObject_AsBIGNUM(gval, _dh_err)))
+ return NULL;
+
+ if (!DH_set0_pqg(dh, p, NULL, g)) {
+ PyErr_SetString(_dh_err,
+ "Cannot set prime number or generator of Z_p for DH.");
+ BN_free(p);
+ BN_free(g);
+ return NULL;
+ }
+
+ Py_RETURN_NONE;
+}
+
+
+#include <openssl/bn.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/rsa.h>
+#include <openssl/opensslv.h>
+
+
+static PyObject *_rsa_err;
+
+void rsa_init(PyObject *rsa_err) {
+ Py_INCREF(rsa_err);
+ _rsa_err = rsa_err;
+}
+
+
+RSA *rsa_read_key(BIO *f, PyObject *pyfunc) {
+ RSA *rsa;
+
+ Py_INCREF(pyfunc);
+ Py_BEGIN_ALLOW_THREADS
+ rsa = PEM_read_bio_RSAPrivateKey(f, NULL, passphrase_callback, (void *)pyfunc);
+ Py_END_ALLOW_THREADS
+ Py_DECREF(pyfunc);
+ return rsa;
+}
+
+
+int rsa_write_key(RSA *rsa, BIO *f, EVP_CIPHER *cipher, PyObject *pyfunc) {
+ int ret;
+
+ Py_INCREF(pyfunc);
+ Py_BEGIN_ALLOW_THREADS
+ ret = PEM_write_bio_RSAPrivateKey(f, rsa, cipher, NULL, 0,
+ passphrase_callback, (void *)pyfunc);
+ Py_END_ALLOW_THREADS
+ Py_DECREF(pyfunc);
+ return ret;
+}
+
+
+int rsa_write_key_no_cipher(RSA *rsa, BIO *f, PyObject *pyfunc) {
+ int ret;
+
+ Py_INCREF(pyfunc);
+ Py_BEGIN_ALLOW_THREADS
+ ret = PEM_write_bio_RSAPrivateKey(f, rsa, NULL, NULL, 0,
+ passphrase_callback, (void *)pyfunc);
+ Py_END_ALLOW_THREADS
+ Py_DECREF(pyfunc);
+ return ret;
+}
+
+
+RSA *rsa_read_pub_key(BIO *f) {
+ return PEM_read_bio_RSA_PUBKEY(f, NULL, NULL, NULL);
+}
+
+
+int rsa_write_pub_key(RSA *rsa, BIO *f) {
+ return PEM_write_bio_RSA_PUBKEY(f, rsa);
+}
+
+PyObject *rsa_get_e(RSA *rsa) {
+ const BIGNUM* e = NULL;
+ RSA_get0_key(rsa, NULL, &e, NULL);
+ if (!e) {
+ PyErr_SetString(_rsa_err, "'e' is unset");
+ return NULL;
+ }
+ return bn_to_mpi(e);
+}
+
+PyObject *rsa_get_n(RSA *rsa) {
+ const BIGNUM* n = NULL;
+ RSA_get0_key(rsa, &n, NULL, NULL);
+ if (!n) {
+ PyErr_SetString(_rsa_err, "'n' is unset");
+ return NULL;
+ }
+ return bn_to_mpi(n);
+}
+
+PyObject *rsa_set_e(RSA *rsa, PyObject *eval) {
+ const BIGNUM* n_read = NULL;
+ BIGNUM* n = NULL;
+ BIGNUM* e;
+
+ if (!(e = m2_PyObject_AsBIGNUM(eval, _rsa_err))) {
+ return NULL;
+ }
+
+ /* n and e must be set at the same time so if e is unset, set it to zero */
+ RSA_get0_key(rsa, &n_read, NULL, NULL);
+ if (!n_read) {
+ n = BN_new();
+ }
+
+ if (RSA_set0_key(rsa, n, e, NULL) != 1) {
+ PyErr_SetString(_rsa_err, "Cannot set fields of RSA object.");
+ BN_free(e);
+ BN_free(n);
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
+
+PyObject *rsa_set_n(RSA *rsa, PyObject *nval) {
+ BIGNUM* n;
+ const BIGNUM* e_read = NULL;
+ BIGNUM* e = NULL;
+
+ if (!(n = m2_PyObject_AsBIGNUM(nval, _rsa_err))) {
+ return NULL;
+ }
+
+ /* n and e must be set at the same time so if e is unset, set it to zero */
+ RSA_get0_key(rsa, NULL, &e_read, NULL);
+ if (!e_read) {
+ e = BN_new();
+ }
+
+ if (RSA_set0_key(rsa, n, e, NULL) != 1) {
+ PyErr_SetString(_rsa_err, "Cannot set fields of RSA object.");
+ BN_free(n);
+ BN_free(e);
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
+
+PyObject *rsa_set_en(RSA *rsa, PyObject *eval, PyObject* nval) {
+ BIGNUM* e, *n;
+
+ if (!(e = m2_PyObject_AsBIGNUM(eval, _rsa_err)) ||
+ !(n = m2_PyObject_AsBIGNUM(nval, _rsa_err))) {
+ return NULL;
+ }
+
+ if (!RSA_set0_key(rsa, n, e, NULL)) {
+ PyErr_SetString(_rsa_err, "Cannot set fields of RSA object.");
+ BN_free(e);
+ BN_free(n);
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
+
+static BIGNUM* PyObject_Bin_AsBIGNUM(PyObject* value) {
+ BIGNUM* bn;
+ const void* vbuf;
+ int vlen = 0;
+
+ if (m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
+ return NULL;
+
+ if (!(bn = BN_bin2bn((unsigned char *)vbuf, vlen, NULL))) {
+ m2_PyErr_Msg(_rsa_err);
+ return NULL;
+ }
+
+ return bn;
+}
+
+PyObject *rsa_set_en_bin(RSA *rsa, PyObject *eval, PyObject* nval) {
+ BIGNUM* e, *n;
+
+ if (!(e = PyObject_Bin_AsBIGNUM(eval)) ||
+ !(n = PyObject_Bin_AsBIGNUM(nval))) {
+ return NULL;
+ }
+
+ if (!RSA_set0_key(rsa, e, n, NULL)) {
+ PyErr_SetString(_rsa_err, "Cannot set fields of RSA object.");
+ BN_free(e);
+ BN_free(n);
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
+
+PyObject *rsa_private_encrypt(RSA *rsa, PyObject *from, int padding) {
+ const void *fbuf;
+ void *tbuf;
+ int flen = 0, tlen;
+ PyObject *ret;
+
+ if (m2_PyObject_AsReadBufferInt(from, &fbuf, &flen) == -1)
+ return NULL;
+
+ if (!(tbuf = PyMem_Malloc(RSA_size(rsa)))) {
+ PyErr_SetString(PyExc_MemoryError, "rsa_private_encrypt");
+ return NULL;
+ }
+ tlen = RSA_private_encrypt(flen, (unsigned char *)fbuf,
+ (unsigned char *)tbuf, rsa, padding);
+ if (tlen == -1) {
+ m2_PyErr_Msg(_rsa_err);
+ PyMem_Free(tbuf);
+ return NULL;
+ }
+
+ ret = PyBytes_FromStringAndSize((const char *)tbuf, tlen);
+
+ PyMem_Free(tbuf);
+ return ret;
+}
+
+PyObject *rsa_public_decrypt(RSA *rsa, PyObject *from, int padding) {
+ const void *fbuf;
+ void *tbuf;
+ int flen = 0, tlen = 0;
+ PyObject *ret;
+
+ if (m2_PyObject_AsReadBufferInt(from, &fbuf, &flen) == -1)
+ return NULL;
+
+ /* OpenSSL docs are confused here: it says we only need buffer
+ * 'RSA_size()-11', but it is true only for RSA PKCS#1 type 1
+ * padding. For other uses we need to use different sizes. */
+ if (!(tbuf = PyMem_Malloc(RSA_size(rsa)))) {
+ PyErr_SetString(PyExc_MemoryError, "rsa_public_decrypt");
+ return NULL;
+ }
+ tlen = RSA_public_decrypt(flen, (unsigned char *)fbuf,
+ (unsigned char *)tbuf, rsa, padding);
+ if (tlen == -1) {
+ m2_PyErr_Msg(_rsa_err);
+ PyMem_Free(tbuf);
+ return NULL;
+ }
+
+ ret = PyBytes_FromStringAndSize((const char *)tbuf, tlen);
+
+ PyMem_Free(tbuf);
+ return ret;
+}
+
+PyObject *rsa_public_encrypt(RSA *rsa, PyObject *from, int padding) {
+ const void *fbuf;
+ void *tbuf;
+ int flen = 0, tlen;
+ PyObject *ret;
+
+ if (m2_PyObject_AsReadBufferInt(from, &fbuf, &flen) == -1)
+ return NULL;
+
+ if (!(tbuf = PyMem_Malloc(RSA_size(rsa)))) {
+ PyErr_SetString(PyExc_MemoryError, "rsa_public_encrypt");
+ return NULL;
+ }
+ tlen = RSA_public_encrypt(flen, (unsigned char *)fbuf,
+ (unsigned char *)tbuf, rsa, padding);
+ if (tlen == -1) {
+ m2_PyErr_Msg(_rsa_err);
+ PyMem_Free(tbuf);
+ return NULL;
+ }
+
+ ret = PyBytes_FromStringAndSize((const char *)tbuf, tlen);
+
+ PyMem_Free(tbuf);
+ return ret;
+}
+
+PyObject *rsa_private_decrypt(RSA *rsa, PyObject *from, int padding) {
+ const void *fbuf;
+ void *tbuf;
+ int flen = 0, tlen;
+ PyObject *ret;
+
+ if (m2_PyObject_AsReadBufferInt(from, &fbuf, &flen) == -1)
+ return NULL;
+
+ if (!(tbuf = PyMem_Malloc(RSA_size(rsa)))) {
+ PyErr_SetString(PyExc_MemoryError, "rsa_private_decrypt");
+ return NULL;
+ }
+ tlen = RSA_private_decrypt(flen, (unsigned char *)fbuf,
+ (unsigned char *)tbuf, rsa, padding);
+ if (tlen == -1) {
+ m2_PyErr_Msg(_rsa_err);
+ PyMem_Free(tbuf);
+ return NULL;
+ }
+ ret = PyBytes_FromStringAndSize((const char *)tbuf, tlen);
+
+ PyMem_Free(tbuf);
+ return ret;
+}
+
+#if OPENSSL_VERSION_NUMBER >= 0x0090708fL
+PyObject *rsa_padding_add_pkcs1_pss(RSA *rsa, PyObject *digest, EVP_MD *hash, int salt_length) {
+ const void *dbuf;
+ unsigned char *tbuf;
+ int dlen, result, tlen;
+ PyObject *ret;
+
+ if (m2_PyObject_AsReadBufferInt(digest, &dbuf, &dlen) == -1)
+ return NULL;
+
+ tlen = RSA_size(rsa);
+
+ if (!(tbuf = OPENSSL_malloc(tlen))) {
+ PyErr_SetString(PyExc_MemoryError, "rsa_padding_add_pkcs1_pss");
+ return NULL;
+ }
+ result = RSA_padding_add_PKCS1_PSS(
+ rsa,
+ tbuf,
+ (unsigned char *)dbuf,
+ hash,
+ salt_length);
+
+ if (result == -1) {
+ m2_PyErr_Msg(_rsa_err);
+ OPENSSL_cleanse(tbuf, tlen);
+ OPENSSL_free(tbuf);
+ return NULL;
+ }
+ ret = PyBytes_FromStringAndSize((const char *)tbuf, tlen);
+ OPENSSL_cleanse(tbuf, tlen);
+ OPENSSL_free(tbuf);
+ return ret;
+}
+
+int rsa_verify_pkcs1_pss(RSA *rsa, PyObject *digest, PyObject *signature, EVP_MD *hash, int salt_length) {
+ const void *dbuf;
+ const void *sbuf;
+ int dlen, slen, ret;
+
+ if (m2_PyObject_AsReadBufferInt(digest, &dbuf, &dlen) == -1) {
+ return 0;
+ }
+
+ if (m2_PyObject_AsReadBufferInt(signature, &sbuf, &slen) == -1) {
+ return 0;
+ }
+
+ ret = RSA_verify_PKCS1_PSS(
+ rsa,
+ (unsigned char *)dbuf,
+ hash,
+ (unsigned char *)sbuf,
+ salt_length);
+
+ return ret;
+}
+#endif
+
+PyObject *rsa_sign(RSA *rsa, PyObject *py_digest_string, int method_type) {
+ int digest_len = 0;
+ int buf_len = 0;
+ int ret = 0;
+ unsigned int real_buf_len = 0;
+ char *digest_string = NULL;
+ unsigned char * sign_buf = NULL;
+ PyObject *signature;
+
+ ret = m2_PyString_AsStringAndSizeInt(py_digest_string, &digest_string,
+ &digest_len);
+ if (ret == -1) {
+ /* PyString_AsStringAndSize raises the correct exceptions. */
+ return NULL;
+ }
+
+ buf_len = RSA_size(rsa);
+ sign_buf = (unsigned char *)PyMem_Malloc(buf_len);
+ ret = RSA_sign(method_type, (const unsigned char *)digest_string, digest_len,
+ sign_buf, &real_buf_len, rsa);
+
+ if (!ret) {
+ m2_PyErr_Msg(_rsa_err);
+ PyMem_Free(sign_buf);
+ return NULL;
+ }
+
+ signature = PyBytes_FromStringAndSize((const char*) sign_buf, buf_len);
+
+ PyMem_Free(sign_buf);
+ return signature;
+}
+
+int rsa_verify(RSA *rsa, PyObject *py_verify_string, PyObject* py_sign_string, int method_type){
+ int ret = 0;
+ char * sign_string = NULL;
+ char * verify_string = NULL;
+ int verify_len = 0;
+ int sign_len = 0;
+
+ ret = m2_PyString_AsStringAndSizeInt(py_verify_string, &verify_string,
+ &verify_len);
+ if (ret == -1) {
+ /* PyString_AsStringAndSize raises the correct exceptions. */
+ return 0;
+ }
+ ret = m2_PyString_AsStringAndSizeInt(py_sign_string, &sign_string,
+ &sign_len);
+ if (ret == -1) {
+ return 0;
+ }
+
+ ret = RSA_verify(method_type, (unsigned char *) verify_string,
+ verify_len, (unsigned char *) sign_string,
+ sign_len, rsa);
+ if (!ret) {
+ m2_PyErr_Msg(_rsa_err);
+ return 0;
+ }
+ return ret;
+}
+
+PyObject *rsa_generate_key(int bits, unsigned long e, PyObject *pyfunc) {
+ RSA *rsa;
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+ BN_GENCB *gencb;
+ BIGNUM *e_big;
+ int ret;
+
+ if ((e_big=BN_new()) == NULL) {
+ m2_PyErr_Msg(_rsa_err);
+ return NULL;
+ }
+
+ if (BN_set_word(e_big, e) == 0) {
+ m2_PyErr_Msg(_rsa_err);
+ BN_free(e_big);
+ return NULL;
+ }
+
+ if ((gencb=BN_GENCB_new()) == NULL) {
+ m2_PyErr_Msg(_rsa_err);
+ BN_free(e_big);
+ return NULL;
+ }
+
+ if ((rsa = RSA_new()) == NULL) {
+ m2_PyErr_Msg(_rsa_err);
+ BN_free(e_big);
+ BN_GENCB_free(gencb);
+ return NULL;
+ }
+
+ BN_GENCB_set(gencb, bn_gencb_callback, (void *) pyfunc);
+
+ Py_INCREF(pyfunc);
+ ret = RSA_generate_key_ex(rsa, bits, e_big, gencb);
+ BN_free(e_big);
+ BN_GENCB_free(gencb);
+ Py_DECREF(pyfunc);
+
+ if (ret)
+ return SWIG_NewPointerObj((void *)rsa, SWIGTYPE_p_RSA, 0);
+
+ m2_PyErr_Msg(_rsa_err);
+ RSA_free(rsa);
+ return NULL;
+}
+
+int rsa_type_check(RSA *rsa) {
+ return 1;
+}
+
+int rsa_check_pub_key(RSA *rsa) {
+ const BIGNUM* n, *e;
+ RSA_get0_key(rsa, &n, &e, NULL);
+ return n && e;
+}
+
+
+int rsa_write_key_der(RSA *rsa, BIO *bio) {
+ return i2d_RSAPrivateKey_bio(bio, rsa);
+}
+
+
+#include <openssl/bn.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/dsa.h>
+
+PyObject *dsa_sig_get_r(DSA_SIG *dsa_sig) {
+ const BIGNUM* pr;
+ DSA_SIG_get0(dsa_sig, &pr, NULL);
+ return bn_to_mpi(pr);
+}
+
+PyObject *dsa_sig_get_s(DSA_SIG *dsa_sig) {
+ const BIGNUM* qs;
+ DSA_SIG_get0(dsa_sig, NULL, &qs);
+ return bn_to_mpi(qs);
+}
+
+
+static PyObject *_dsa_err;
+
+void dsa_init(PyObject *dsa_err) {
+ Py_INCREF(dsa_err);
+ _dsa_err = dsa_err;
+}
+
+
+DSA *dsa_generate_parameters(int bits, PyObject *pyfunc) {
+ DSA *dsa;
+ BN_GENCB *gencb;
+ int ret;
+
+ if ((gencb=BN_GENCB_new()) == NULL) {
+ m2_PyErr_Msg(_dh_err);
+ return NULL;
+ }
+
+ if ((dsa = DSA_new()) == NULL) {
+ m2_PyErr_Msg(_dsa_err);
+ BN_GENCB_free(gencb);
+ return NULL;
+ }
+
+ BN_GENCB_set(gencb, bn_gencb_callback, (void *) pyfunc);
+
+ Py_INCREF(pyfunc);
+ ret = DSA_generate_parameters_ex(dsa, bits, NULL, 0, NULL, NULL,
+ gencb);
+ Py_DECREF(pyfunc);
+ BN_GENCB_free(gencb);
+
+ if (ret)
+ return dsa;
+
+ m2_PyErr_Msg(_dsa_err);
+ DSA_free(dsa);
+ return NULL;
+}
+
+DSA *dsa_read_params(BIO *f, PyObject *pyfunc) {
+ DSA *ret;
+
+ Py_INCREF(pyfunc);
+ Py_BEGIN_ALLOW_THREADS
+ ret = PEM_read_bio_DSAparams(f, NULL, passphrase_callback, (void *)pyfunc);
+ Py_END_ALLOW_THREADS
+ Py_DECREF(pyfunc);
+
+ if (ret == NULL) {
+ m2_PyErr_Msg(_dsa_err);
+ }
+
+ return ret;
+}
+
+DSA *dsa_read_key(BIO *f, PyObject *pyfunc) {
+ DSA *ret;
+
+ Py_INCREF(pyfunc);
+ Py_BEGIN_ALLOW_THREADS
+ ret = PEM_read_bio_DSAPrivateKey(f, NULL, passphrase_callback, (void *)pyfunc);
+ Py_END_ALLOW_THREADS
+ Py_DECREF(pyfunc);
+
+ if (ret == NULL) {
+ m2_PyErr_Msg(_dsa_err);
+ }
+
+ return ret;
+}
+
+DSA *dsa_read_pub_key(BIO *f, PyObject *pyfunc) {
+ DSA *ret;
+
+ Py_INCREF(pyfunc);
+ Py_BEGIN_ALLOW_THREADS
+ ret = PEM_read_bio_DSA_PUBKEY(f, NULL, passphrase_callback, (void *)pyfunc);
+ Py_END_ALLOW_THREADS
+ Py_DECREF(pyfunc);
+
+ if (ret == NULL) {
+ m2_PyErr_Msg(_dsa_err);
+ }
+
+ return ret;
+}
+
+
+PyObject *dsa_get_p(DSA *dsa) {
+ const BIGNUM* p = NULL;
+ DSA_get0_pqg(dsa, &p, NULL, NULL);
+ if (!p) {
+ PyErr_SetString(_dsa_err, "'p' is unset");
+ return NULL;
+ }
+ return bn_to_mpi(p);
+}
+
+PyObject *dsa_get_q(DSA *dsa) {
+ const BIGNUM* q = NULL;
+ DSA_get0_pqg(dsa, NULL, &q, NULL);
+ if (!q) {
+ PyErr_SetString(_dsa_err, "'q' is unset");
+ return NULL;
+ }
+ return bn_to_mpi(q);
+}
+
+PyObject *dsa_get_g(DSA *dsa) {
+ const BIGNUM* g = NULL;
+ DSA_get0_pqg(dsa, NULL, NULL, &g);
+ if (!g) {
+ PyErr_SetString(_dsa_err, "'g' is unset");
+ return NULL;
+ }
+ return bn_to_mpi(g);
+}
+
+PyObject *dsa_get_pub(DSA *dsa) {
+ const BIGNUM* pub_key = NULL;
+ DSA_get0_key(dsa, &pub_key, NULL);
+ if (!pub_key) {
+ PyErr_SetString(_dsa_err, "'pub' is unset");
+ return NULL;
+ }
+ return bn_to_mpi(pub_key);
+}
+
+PyObject *dsa_get_priv(DSA *dsa) {
+ const BIGNUM* priv_key = NULL;
+ DSA_get0_key(dsa, NULL, &priv_key);
+ if (!priv_key) {
+ PyErr_SetString(_dsa_err, "'priv' is unset");
+ return NULL;
+ }
+ return bn_to_mpi(priv_key);
+}
+
+PyObject *dsa_set_pqg(DSA *dsa, PyObject *pval, PyObject* qval, PyObject* gval) {
+ BIGNUM* p, *q, *g;
+
+ if (!(p = m2_PyObject_AsBIGNUM(pval, _dsa_err))
+ || !(q = m2_PyObject_AsBIGNUM(qval, _dsa_err))
+ || !(g = m2_PyObject_AsBIGNUM(gval, _dsa_err)))
+ return NULL;
+
+ if (!DSA_set0_pqg(dsa, p, q, g)) {
+ PyErr_SetString(
+ _dsa_err,
+ "Cannot set prime number, subprime, or generator of subgroup for DSA.");
+ BN_free(p);
+ BN_free(q);
+ BN_free(g);
+ return NULL;
+ }
+
+ Py_RETURN_NONE;
+ }
+
+PyObject *dsa_set_pub(DSA *dsa, PyObject *value) {
+ BIGNUM *bn;
+ const void *vbuf;
+ int vlen = 0;
+
+ if (m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
+ return NULL;
+
+ if (!(bn = BN_mpi2bn((unsigned char *)vbuf, vlen, NULL))) {
+ m2_PyErr_Msg(_dsa_err);
+ return NULL;
+ }
+ if (!DSA_set0_key(dsa, bn, NULL)) {
+ BN_free(bn);
+ PyErr_SetString(_dsa_err, "Cannot set private and public key for DSA.");
+ }
+ Py_RETURN_NONE;
+}
+
+
+int dsa_write_params_bio(DSA* dsa, BIO* f) {
+ return PEM_write_bio_DSAparams(f, dsa);
+}
+
+
+int dsa_write_key_bio(DSA* dsa, BIO* f, EVP_CIPHER *cipher, PyObject *pyfunc) {
+ int ret;
+
+ Py_INCREF(pyfunc);
+ Py_BEGIN_ALLOW_THREADS
+ ret = PEM_write_bio_DSAPrivateKey(f, dsa, cipher, NULL, 0,
+ passphrase_callback, (void *)pyfunc);
+ Py_END_ALLOW_THREADS
+ Py_DECREF(pyfunc);
+ return ret;
+}
+
+
+int dsa_write_key_bio_no_cipher(DSA* dsa, BIO* f, PyObject *pyfunc) {
+ int ret;
+
+ Py_INCREF(pyfunc);
+ Py_BEGIN_ALLOW_THREADS
+ ret = PEM_write_bio_DSAPrivateKey(f, dsa, NULL, NULL, 0,
+ passphrase_callback, (void *)pyfunc);
+ Py_END_ALLOW_THREADS
+ Py_DECREF(pyfunc);
+ return ret;
+}
+
+
+int dsa_write_pub_key_bio(DSA* dsa, BIO* f) {
+ return PEM_write_bio_DSA_PUBKEY(f, dsa);
+}
+
+
+PyObject *dsa_sign(DSA *dsa, PyObject *value) {
+ const void *vbuf;
+ int vlen = 0;
+ PyObject *tuple;
+ DSA_SIG *sig;
+
+ if (m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
+ return NULL;
+
+ if (!(sig = DSA_do_sign(vbuf, vlen, dsa))) {
+ m2_PyErr_Msg(_dsa_err);
+ return NULL;
+ }
+ if (!(tuple = PyTuple_New(2))) {
+ DSA_SIG_free(sig);
+ PyErr_SetString(PyExc_RuntimeError, "PyTuple_New() fails");
+ return NULL;
+ }
+ PyTuple_SET_ITEM(tuple, 0, dsa_sig_get_r(sig));
+ PyTuple_SET_ITEM(tuple, 1, dsa_sig_get_s(sig));
+ DSA_SIG_free(sig);
+ return tuple;
+}
+
+int dsa_verify(DSA *dsa, PyObject *value, PyObject *r, PyObject *s) {
+ const void *vbuf, *rbuf, *sbuf;
+ int vlen = 0, rlen = 0, slen = 0;
+ DSA_SIG *sig;
+ BIGNUM* pr, *ps;
+ int ret;
+
+ if ((m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
+ || (m2_PyObject_AsReadBufferInt(r, &rbuf, &rlen) == -1)
+ || (m2_PyObject_AsReadBufferInt(s, &sbuf, &slen) == -1))
+ return -1;
+
+ if (!(sig = DSA_SIG_new())) {
+ m2_PyErr_Msg(_dsa_err);
+ return -1;
+ }
+ if (!(pr = BN_mpi2bn((unsigned char *)rbuf, rlen, NULL))) {
+ m2_PyErr_Msg(_dsa_err);
+ DSA_SIG_free(sig);
+ return -1;
+ }
+ if (!(ps = BN_mpi2bn((unsigned char *)sbuf, slen, NULL))) {
+ m2_PyErr_Msg(_dsa_err);
+ DSA_SIG_free(sig);
+ BN_free(pr);
+ return -1;
+ }
+ if (!DSA_SIG_set0(sig, pr, ps)) {
+ m2_PyErr_Msg(_dsa_err);
+ DSA_SIG_free(sig);
+ BN_free(pr);
+ BN_free(ps);
+ return -1;
+ }
+
+ ret = DSA_do_verify(vbuf, vlen, sig, dsa);
+ DSA_SIG_free(sig);
+ if (ret == -1)
+ m2_PyErr_Msg(_dsa_err);
+ return ret;
+}
+
+PyObject *dsa_sign_asn1(DSA *dsa, PyObject *value) {
+ const void *vbuf;
+ int vlen = 0;
+ void *sigbuf;
+ unsigned int siglen;
+ PyObject *ret;
+
+ if (m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
+ return NULL;
+
+ if (!(sigbuf = PyMem_Malloc(DSA_size(dsa)))) {
+ PyErr_SetString(PyExc_MemoryError, "dsa_sign_asn1");
+ return NULL;
+ }
+ if (!DSA_sign(0, vbuf, vlen, (unsigned char *)sigbuf, &siglen, dsa)) {
+ m2_PyErr_Msg(_dsa_err);
+ PyMem_Free(sigbuf);
+ return NULL;
+ }
+
+ ret = PyBytes_FromStringAndSize(sigbuf, siglen);
+
+ PyMem_Free(sigbuf);
+ return ret;
+}
+
+int dsa_verify_asn1(DSA *dsa, PyObject *value, PyObject *sig) {
+ const void *vbuf;
+ void *sbuf;
+ int vlen = 0, slen = 0, ret = 0;
+
+ if ((m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
+ || (m2_PyObject_AsReadBufferInt(sig, (const void **)&sbuf, &slen)
+ == -1))
+ return -1;
+
+ if ((ret = DSA_verify(0, vbuf, vlen, sbuf, slen, dsa)) == -1)
+ m2_PyErr_Msg(_dsa_err);
+ return ret;
+}
+
+int dsa_check_key(DSA *dsa) {
+ const BIGNUM* pub_key, *priv_key;
+ DSA_get0_key(dsa, &pub_key, &priv_key);
+ return pub_key != NULL && priv_key != NULL;
+}
+
+int dsa_check_pub_key(DSA *dsa) {
+ const BIGNUM* pub_key;
+ DSA_get0_key(dsa, &pub_key, NULL);
+ return pub_key ? 1 : 0;
+}
+
+int dsa_keylen(DSA *dsa) {
+ const BIGNUM* p;
+ DSA_get0_pqg(dsa, &p, NULL, NULL);
+ return BN_num_bits(p);
+}
+
+int dsa_type_check(DSA *dsa) {
+ return 1;
+}
+
+
+#include <pythread.h>
+#include <limits.h>
+#include <openssl/bio.h>
+#include <openssl/dh.h>
+#include <openssl/ssl.h>
+#include <openssl/tls1.h>
+#include <openssl/x509.h>
+#ifdef _WIN32
+#include <WinSock2.h>
+#include <Windows.h>
+#pragma comment(lib, "Ws2_32")
+typedef unsigned __int64 uint64_t;
+#else
+#include <poll.h>
+#include <sys/time.h>
+#endif
+
+
+static PyObject *_ssl_err;
+static PyObject *_ssl_timeout_err;
+
+void ssl_init(PyObject *ssl_err, PyObject *ssl_timeout_err) {
+ SSL_library_init();
+ SSL_load_error_strings();
+ Py_INCREF(ssl_err);
+ Py_INCREF(ssl_timeout_err);
+ _ssl_err = ssl_err;
+ _ssl_timeout_err = ssl_timeout_err;
+}
+
+const SSL_METHOD *tlsv1_method(void) {
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ PyErr_WarnEx(PyExc_DeprecationWarning,
+ "Function TLSv1_method has been deprecated.", 1);
+#endif
+ return TLSv1_method();
+}
+
+void ssl_ctx_passphrase_callback(SSL_CTX *ctx, PyObject *pyfunc) {
+ SSL_CTX_set_default_passwd_cb(ctx, passphrase_callback);
+ SSL_CTX_set_default_passwd_cb_userdata(ctx, (void *)pyfunc);
+ Py_INCREF(pyfunc);
+}
+
+int ssl_ctx_use_x509(SSL_CTX *ctx, X509 *x) {
+ int i;
+
+ if (!(i = SSL_CTX_use_certificate(ctx, x))) {
+ m2_PyErr_Msg(_ssl_err);
+ return -1;
+ }
+ return i;
+
+}
+
+int ssl_ctx_use_cert(SSL_CTX *ctx, char *file) {
+ int i;
+
+ if (!(i = SSL_CTX_use_certificate_file(ctx, file, SSL_FILETYPE_PEM))) {
+ m2_PyErr_Msg(_ssl_err);
+ return -1;
+ }
+ return i;
+}
+
+int ssl_ctx_use_cert_chain(SSL_CTX *ctx, char *file) {
+ int i;
+
+ if (!(i = SSL_CTX_use_certificate_chain_file(ctx, file))) {
+ m2_PyErr_Msg(_ssl_err);
+ return -1;
+ }
+ return i;
+}
+
+
+int ssl_ctx_use_privkey(SSL_CTX *ctx, char *file) {
+ int i;
+
+ if (!(i = SSL_CTX_use_PrivateKey_file(ctx, file, SSL_FILETYPE_PEM))) {
+ m2_PyErr_Msg(_ssl_err);
+ return -1;
+ }
+ return i;
+}
+
+int ssl_ctx_use_rsa_privkey(SSL_CTX *ctx, RSA *rsakey) {
+ int i;
+
+ if (!(i = SSL_CTX_use_RSAPrivateKey(ctx, rsakey))) {
+ m2_PyErr_Msg(_ssl_err);
+ return -1;
+ }
+ return i;
+}
+
+int ssl_ctx_use_pkey_privkey(SSL_CTX *ctx, EVP_PKEY *pkey) {
+ int i;
+
+ if (!(i = SSL_CTX_use_PrivateKey(ctx, pkey))) {
+ m2_PyErr_Msg(_ssl_err);
+ return -1;
+ }
+ return i;
+}
+
+
+int ssl_ctx_check_privkey(SSL_CTX *ctx) {
+ int ret;
+
+ if (!(ret = SSL_CTX_check_private_key(ctx))) {
+ m2_PyErr_Msg(_ssl_err);
+ return -1;
+ }
+ return ret;
+}
+
+void ssl_ctx_set_client_CA_list_from_file(SSL_CTX *ctx, const char *ca_file) {
+ SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(ca_file));
+}
+
+void ssl_ctx_set_verify_default(SSL_CTX *ctx, int mode) {
+ SSL_CTX_set_verify(ctx, mode, NULL);
+}
+
+void ssl_ctx_set_verify(SSL_CTX *ctx, int mode, PyObject *pyfunc) {
+ Py_XDECREF(ssl_verify_cb_func);
+ Py_INCREF(pyfunc);
+ ssl_verify_cb_func = pyfunc;
+ SSL_CTX_set_verify(ctx, mode, ssl_verify_callback);
+}
+
+int ssl_ctx_set_session_id_context(SSL_CTX *ctx, PyObject *sid_ctx) {
+ const void *buf;
+ int len = 0;
+
+ if (m2_PyObject_AsReadBufferInt(sid_ctx, &buf, &len) == -1)
+ return -1;
+
+ return SSL_CTX_set_session_id_context(ctx, buf, len);
+}
+
+void ssl_ctx_set_info_callback(SSL_CTX *ctx, PyObject *pyfunc) {
+ Py_XDECREF(ssl_info_cb_func);
+ Py_INCREF(pyfunc);
+ ssl_info_cb_func = pyfunc;
+ SSL_CTX_set_info_callback(ctx, ssl_info_callback);
+}
+
+long ssl_ctx_set_tmp_dh(SSL_CTX *ctx, DH* dh) {
+ return SSL_CTX_set_tmp_dh(ctx, dh);
+}
+
+void ssl_ctx_set_tmp_dh_callback(SSL_CTX *ctx, PyObject *pyfunc) {
+ Py_XDECREF(ssl_set_tmp_dh_cb_func);
+ Py_INCREF(pyfunc);
+ ssl_set_tmp_dh_cb_func = pyfunc;
+ SSL_CTX_set_tmp_dh_callback(ctx, ssl_set_tmp_dh_callback);
+}
+
+long ssl_ctx_set_tmp_rsa(SSL_CTX *ctx, RSA* rsa) {
+ return SSL_CTX_set_tmp_rsa(ctx, rsa);
+}
+
+void ssl_ctx_set_tmp_rsa_callback(SSL_CTX *ctx, PyObject *pyfunc) {
+ Py_XDECREF(ssl_set_tmp_rsa_cb_func);
+ Py_INCREF(pyfunc);
+ ssl_set_tmp_rsa_cb_func = pyfunc;
+ SSL_CTX_set_tmp_rsa_callback(ctx, ssl_set_tmp_rsa_callback);
+}
+
+int ssl_ctx_load_verify_locations(SSL_CTX *ctx, const char *cafile, const char *capath) {
+ return SSL_CTX_load_verify_locations(ctx, cafile, capath);
+}
+
+/* SSL_CTX_set_options is a macro. */
+long ssl_ctx_set_options(SSL_CTX *ctx, long op) {
+ return SSL_CTX_set_options(ctx, op);
+}
+
+int bio_set_ssl(BIO *bio, SSL *ssl, int flag) {
+ SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
+ return BIO_ctrl(bio, BIO_C_SET_SSL, flag, (char *)ssl);
+}
+
+long ssl_set_mode(SSL *ssl, long mode) {
+ return SSL_set_mode(ssl, mode);
+}
+
+long ssl_get_mode(SSL *ssl) {
+ return SSL_get_mode(ssl);
+}
+
+int ssl_set_tlsext_host_name(SSL *ssl, const char *name) {
+ long l;
+
+ if (!(l = SSL_set_tlsext_host_name(ssl, name))) {
+ m2_PyErr_Msg(_ssl_err);
+ return -1;
+ }
+ /* Return an "int" to match the 'typemap(out) int' in _lib.i */
+ return 1;
+}
+
+void ssl_set_client_CA_list_from_file(SSL *ssl, const char *ca_file) {
+ SSL_set_client_CA_list(ssl, SSL_load_client_CA_file(ca_file));
+}
+
+void ssl_set_client_CA_list_from_context(SSL *ssl, SSL_CTX *ctx) {
+ SSL_set_client_CA_list(ssl, SSL_CTX_get_client_CA_list(ctx));
+}
+
+int ssl_set_session_id_context(SSL *ssl, PyObject *sid_ctx) {
+ const void *buf;
+ int len = 0;
+
+ if (m2_PyObject_AsReadBufferInt(sid_ctx, &buf, &len) == -1)
+ return -1;
+
+ return SSL_set_session_id_context(ssl, buf, len);
+}
+
+int ssl_set_fd(SSL *ssl, int fd) {
+ int ret;
+
+ if (!(ret = SSL_set_fd(ssl, fd))) {
+ m2_PyErr_Msg(_ssl_err);
+ return -1;
+ }
+ return ret;
+}
+
+static void ssl_handle_error(int ssl_err, int ret) {
+ int err;
+
+ switch (ssl_err) {
+ case SSL_ERROR_SSL:
+ PyErr_SetString(_ssl_err,
+ ERR_reason_error_string(ERR_get_error()));
+ break;
+ case SSL_ERROR_SYSCALL:
+ err = ERR_get_error();
+ if (err)
+ PyErr_SetString(_ssl_err, ERR_reason_error_string(err));
+ else if (ret == 0)
+ PyErr_SetString(_ssl_err, "unexpected eof");
+ else if (ret == -1)
+ PyErr_SetFromErrno(_ssl_err);
+ else
+ assert(0);
+ break;
+ default:
+ PyErr_SetString(_ssl_err, "unexpected SSL error");
+ }
+}
+
+#ifdef _WIN32
+/* http://stackoverflow.com/questions/10905892/equivalent-of-gettimeday-for-windows */
+int gettimeofday(struct timeval *tp, void *tzp)
+{
+ // Note: some broken versions only have 8 trailing zero's, the correct epoch has 9 trailing zero's
+ static const uint64_t EPOCH = ((uint64_t) 116444736000000000ULL);
+
+ SYSTEMTIME system_time;
+ FILETIME file_time;
+ uint64_t time;
+
+ GetSystemTime( &system_time );
+ SystemTimeToFileTime( &system_time, &file_time );
+ time = ((uint64_t)file_time.dwLowDateTime ) ;
+ time += ((uint64_t)file_time.dwHighDateTime) << 32;
+
+ tp->tv_sec = (long) ((time - EPOCH) / 10000000L);
+ tp->tv_usec = (long) (system_time.wMilliseconds * 1000);
+ return 0;
+}
+#endif
+
+static int ssl_sleep_with_timeout(SSL *ssl, const struct timeval *start,
+ double timeout, int ssl_err) {
+#ifdef _WIN32
+WSAPOLLFD fd;
+#else
+struct pollfd fd;
+#endif
+ struct timeval tv;
+ int ms, tmp;
+
+ assert(timeout > 0);
+ again:
+ gettimeofday(&tv, NULL);
+ /* tv >= start */
+ if ((timeout + start->tv_sec - tv.tv_sec) > INT_MAX / 1000)
+ ms = -1;
+ else {
+ int fract;
+
+ ms = ((start->tv_sec + (int)timeout) - tv.tv_sec) * 1000;
+ fract = (int)((start->tv_usec + (timeout - (int)timeout) * 1000000
+ - tv.tv_usec + 999) / 1000);
+ if (ms > 0 && fract > INT_MAX - ms)
+ ms = -1;
+ else {
+ ms += fract;
+ if (ms <= 0)
+ goto timeout;
+ }
+ }
+ switch (ssl_err) {
+ case SSL_ERROR_WANT_READ:
+ fd.fd = SSL_get_rfd(ssl);
+ fd.events = POLLIN;
+ break;
+
+ case SSL_ERROR_WANT_WRITE:
+ fd.fd = SSL_get_wfd(ssl);
+ fd.events = POLLOUT;
+ break;
+
+ case SSL_ERROR_WANT_X509_LOOKUP:
+ return 0; /* FIXME: is this correct? */
+
+ default:
+ assert(0);
+ }
+ if (fd.fd == -1) {
+ PyErr_SetString(_ssl_err, "timeout on a non-FD SSL");
+ return -1;
+ }
+ Py_BEGIN_ALLOW_THREADS
+#ifdef _WIN32
+ tmp = WSAPoll(&fd, 1, ms);
+#else
+ tmp = poll(&fd, 1, ms);
+#endif
+ Py_END_ALLOW_THREADS
+ switch (tmp) {
+ case 1:
+ return 0;
+ case 0:
+ goto timeout;
+ case -1:
+#ifdef _WIN32
+ if (WSAGetLastError() == EINTR)
+#else
+ if (errno == EINTR)
+#endif
+ goto again;
+ PyErr_SetFromErrno(_ssl_err);
+ return -1;
+ }
+ return 0;
+
+ timeout:
+ PyErr_SetString(_ssl_timeout_err, "timed out");
+ return -1;
+}
+
+PyObject *ssl_accept(SSL *ssl, double timeout) {
+ PyObject *obj = NULL;
+ int r, ssl_err;
+ struct timeval tv;
+
+ if (timeout > 0)
+ gettimeofday(&tv, NULL);
+ again:
+ Py_BEGIN_ALLOW_THREADS
+ r = SSL_accept(ssl);
+ ssl_err = SSL_get_error(ssl, r);
+ Py_END_ALLOW_THREADS
+
+
+ switch (ssl_err) {
+ case SSL_ERROR_NONE:
+ case SSL_ERROR_ZERO_RETURN:
+ obj = PyLong_FromLong((long)1);
+ break;
+ case SSL_ERROR_WANT_WRITE:
+ case SSL_ERROR_WANT_READ:
+ if (timeout <= 0) {
+ obj = PyLong_FromLong((long)0);
+ break;
+ }
+ if (ssl_sleep_with_timeout(ssl, &tv, timeout, ssl_err) == 0)
+ goto again;
+ obj = NULL;
+ break;
+ case SSL_ERROR_SSL:
+ case SSL_ERROR_SYSCALL:
+ ssl_handle_error(ssl_err, r);
+ obj = NULL;
+ break;
+ }
+
+
+ return obj;
+}
+
+PyObject *ssl_connect(SSL *ssl, double timeout) {
+ PyObject *obj = NULL;
+ int r, ssl_err;
+ struct timeval tv;
+
+ if (timeout > 0)
+ gettimeofday(&tv, NULL);
+ again:
+ Py_BEGIN_ALLOW_THREADS
+ r = SSL_connect(ssl);
+ ssl_err = SSL_get_error(ssl, r);
+ Py_END_ALLOW_THREADS
+
+
+ switch (ssl_err) {
+ case SSL_ERROR_NONE:
+ case SSL_ERROR_ZERO_RETURN:
+ obj = PyLong_FromLong((long)1);
+ break;
+ case SSL_ERROR_WANT_WRITE:
+ case SSL_ERROR_WANT_READ:
+ if (timeout <= 0) {
+ obj = PyLong_FromLong((long)0);
+ break;
+ }
+ if (ssl_sleep_with_timeout(ssl, &tv, timeout, ssl_err) == 0)
+ goto again;
+ obj = NULL;
+ break;
+ case SSL_ERROR_SSL:
+ case SSL_ERROR_SYSCALL:
+ ssl_handle_error(ssl_err, r);
+ obj = NULL;
+ break;
+ }
+
+
+ return obj;
+}
+
+void ssl_set_shutdown1(SSL *ssl, int mode) {
+ SSL_set_shutdown(ssl, mode);
+}
+
+PyObject *ssl_read(SSL *ssl, int num, double timeout) {
+ PyObject *obj = NULL;
+ void *buf;
+ int r;
+ struct timeval tv;
+
+ if (!(buf = PyMem_Malloc(num))) {
+ PyErr_SetString(PyExc_MemoryError, "ssl_read");
+ return NULL;
+ }
+
+
+ if (timeout > 0)
+ gettimeofday(&tv, NULL);
+ again:
+ Py_BEGIN_ALLOW_THREADS
+ r = SSL_read(ssl, buf, num);
+ Py_END_ALLOW_THREADS
+
+ if (r >= 0) {
+ buf = PyMem_Realloc(buf, r);
+ obj = PyBytes_FromStringAndSize(buf, r);
+ } else {
+ int ssl_err;
+
+ ssl_err = SSL_get_error(ssl, r);
+ switch (ssl_err) {
+ case SSL_ERROR_NONE:
+ case SSL_ERROR_ZERO_RETURN:
+ assert(0);
+
+ case SSL_ERROR_WANT_WRITE:
+ case SSL_ERROR_WANT_READ:
+ case SSL_ERROR_WANT_X509_LOOKUP:
+ if (timeout <= 0) {
+ Py_INCREF(Py_None);
+ obj = Py_None;
+ break;
+ }
+ if (ssl_sleep_with_timeout(ssl, &tv, timeout, ssl_err) == 0)
+ goto again;
+ obj = NULL;
+ break;
+ case SSL_ERROR_SSL:
+ case SSL_ERROR_SYSCALL:
+ ssl_handle_error(ssl_err, r);
+ obj = NULL;
+ break;
+ }
+ }
+ PyMem_Free(buf);
+
+
+ return obj;
+}
+
+PyObject *ssl_read_nbio(SSL *ssl, int num) {
+ PyObject *obj = NULL;
+ void *buf;
+ int r, err;
+
+
+ if (!(buf = PyMem_Malloc(num))) {
+ PyErr_SetString(PyExc_MemoryError, "ssl_read");
+ return NULL;
+ }
+
+
+ Py_BEGIN_ALLOW_THREADS
+ r = SSL_read(ssl, buf, num);
+ Py_END_ALLOW_THREADS
+
+
+ switch (SSL_get_error(ssl, r)) {
+ case SSL_ERROR_NONE:
+ case SSL_ERROR_ZERO_RETURN:
+ buf = PyMem_Realloc(buf, r);
+
+ obj = PyBytes_FromStringAndSize(buf, r);
+
+ break;
+ case SSL_ERROR_WANT_WRITE:
+ case SSL_ERROR_WANT_READ:
+ case SSL_ERROR_WANT_X509_LOOKUP:
+ Py_INCREF(Py_None);
+ obj = Py_None;
+ break;
+ case SSL_ERROR_SSL:
+ m2_PyErr_Msg(_ssl_err);
+ obj = NULL;
+ break;
+ case SSL_ERROR_SYSCALL:
+ err = ERR_get_error();
+ if (err)
+ PyErr_SetString(_ssl_err, ERR_reason_error_string(err));
+ else if (r == 0)
+ PyErr_SetString(_ssl_err, "unexpected eof");
+ else if (r == -1)
+ PyErr_SetFromErrno(_ssl_err);
+ obj = NULL;
+ break;
+ }
+ PyMem_Free(buf);
+
+
+ return obj;
+}
+
+int ssl_write(SSL *ssl, PyObject *blob, double timeout) {
+ Py_buffer buf;
+ int r, ssl_err, ret;
+ struct timeval tv;
+
+
+ if (m2_PyObject_GetBufferInt(blob, &buf, PyBUF_CONTIG_RO) == -1) {
+ return -1;
+ }
+
+ if (timeout > 0)
+ gettimeofday(&tv, NULL);
+ again:
+ Py_BEGIN_ALLOW_THREADS
+ r = SSL_write(ssl, buf.buf, buf.len);
+ ssl_err = SSL_get_error(ssl, r);
+ Py_END_ALLOW_THREADS
+
+
+ switch (ssl_err) {
+ case SSL_ERROR_NONE:
+ case SSL_ERROR_ZERO_RETURN:
+ ret = r;
+ break;
+ case SSL_ERROR_WANT_WRITE:
+ case SSL_ERROR_WANT_READ:
+ case SSL_ERROR_WANT_X509_LOOKUP:
+ if (timeout <= 0) {
+ ret = -1;
+ break;
+ }
+ if (ssl_sleep_with_timeout(ssl, &tv, timeout, ssl_err) == 0)
+ goto again;
+ ret = -1;
+ break;
+ case SSL_ERROR_SSL:
+ case SSL_ERROR_SYSCALL:
+ ssl_handle_error(ssl_err, r);
+ default:
+ ret = -1;
+ }
+
+ m2_PyBuffer_Release(blob, &buf);
+ return ret;
+}
+
+int ssl_write_nbio(SSL *ssl, PyObject *blob) {
+ Py_buffer buf;
+ int r, err, ret;
+
+
+ if (m2_PyObject_GetBufferInt(blob, &buf, PyBUF_CONTIG_RO) == -1) {
+ return -1;
+ }
+
+
+ Py_BEGIN_ALLOW_THREADS
+ r = SSL_write(ssl, buf.buf, buf.len);
+ Py_END_ALLOW_THREADS
+
+
+ switch (SSL_get_error(ssl, r)) {
+ case SSL_ERROR_NONE:
+ case SSL_ERROR_ZERO_RETURN:
+ ret = r;
+ break;
+ case SSL_ERROR_WANT_WRITE:
+ case SSL_ERROR_WANT_READ:
+ case SSL_ERROR_WANT_X509_LOOKUP:
+ ret = -1;
+ break;
+ case SSL_ERROR_SSL:
+ ret = -1;
+ break;
+ case SSL_ERROR_SYSCALL:
+ err = ERR_get_error();
+ if (err)
+ PyErr_SetString(_ssl_err, ERR_reason_error_string(err));
+ else if (r == 0)
+ PyErr_SetString(_ssl_err, "unexpected eof");
+ else if (r == -1)
+ PyErr_SetFromErrno(_ssl_err);
+ default:
+ ret = -1;
+ }
+
+ m2_PyBuffer_Release(blob, &buf);
+ return ret;
+}
+
+int ssl_cipher_get_bits(SSL_CIPHER *c) {
+ return SSL_CIPHER_get_bits(c, NULL);
+}
+
+int sk_ssl_cipher_num(STACK_OF(SSL_CIPHER) *stack) {
+ return sk_SSL_CIPHER_num(stack);
+}
+
+const SSL_CIPHER *sk_ssl_cipher_value(STACK_OF(SSL_CIPHER) *stack, int idx) {
+ return sk_SSL_CIPHER_value(stack, idx);
+}
+
+STACK_OF(X509) *ssl_get_peer_cert_chain(SSL *ssl) {
+ return SSL_get_peer_cert_chain(ssl);
+}
+
+int sk_x509_num(STACK_OF(X509) *stack) {
+ return sk_X509_num(stack);
+}
+
+X509 *sk_x509_value(STACK_OF(X509) *stack, int idx) {
+ return sk_X509_value(stack, idx);
+}
+
+
+void i2d_ssl_session(BIO *bio, SSL_SESSION *sess) {
+ i2d_SSL_SESSION_bio(bio, sess);
+}
+
+
+SSL_SESSION *ssl_session_read_pem(BIO *bio) {
+ return PEM_read_bio_SSL_SESSION(bio, NULL, NULL, NULL);
+}
+
+
+int ssl_session_write_pem(SSL_SESSION *sess, BIO *bio) {
+ return PEM_write_bio_SSL_SESSION(bio, sess);
+}
+
+int ssl_ctx_set_session_cache_mode(SSL_CTX *ctx, int mode)
+{
+ return SSL_CTX_set_session_cache_mode(ctx, mode);
+}
+
+int ssl_ctx_get_session_cache_mode(SSL_CTX *ctx)
+{
+ return SSL_CTX_get_session_cache_mode(ctx);
+}
+
+static long ssl_ctx_set_cache_size(SSL_CTX *ctx, long arg)
+{
+ return SSL_CTX_sess_set_cache_size(ctx, arg);
+}
+
+int ssl_is_init_finished(SSL *ssl)
+{
+ return SSL_is_init_finished(ssl);
+}
+
+
+#include <openssl/asn1.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+#include <openssl/asn1t.h>
+
+typedef STACK_OF(X509) SEQ_CERT;
+
+ASN1_ITEM_TEMPLATE(SEQ_CERT) =
+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, SeqCert, X509)
+ASN1_ITEM_TEMPLATE_END(SEQ_CERT)
+
+IMPLEMENT_ASN1_FUNCTIONS(SEQ_CERT)
+
+
+X509 *x509_read_pem(BIO *bio) {
+ return PEM_read_bio_X509(bio, NULL, NULL, NULL);
+}
+
+
+X509 *d2i_x509(BIO *bio) {
+ return d2i_X509_bio(bio, NULL);
+}
+
+
+static PyObject *_x509_err;
+
+void x509_init(PyObject *x509_err) {
+ Py_INCREF(x509_err);
+ _x509_err = x509_err;
+}
+
+
+X509_REQ *d2i_x509_req(BIO *bio) {
+ return d2i_X509_REQ_bio(bio, NULL);
+}
+
+
+X509_REQ *x509_req_read_pem(BIO *bio) {
+ return PEM_read_bio_X509_REQ(bio, NULL, NULL, NULL);
+}
+
+
+PyObject *i2d_x509(X509 *x) {
+ int len;
+ PyObject *ret = NULL;
+ unsigned char *buf = NULL;
+ len = i2d_X509(x, &buf);
+ if (len < 0) {
+ m2_PyErr_Msg(_x509_err);
+ }
+ else {
+
+ ret = PyBytes_FromStringAndSize((char*)buf, len);
+
+ OPENSSL_free(buf);
+ }
+ return ret;
+}
+
+
+int x509_req_write_pem(BIO *bio, X509_REQ *x) {
+ return PEM_write_bio_X509_REQ(bio, x);
+}
+
+
+X509_CRL *x509_crl_read_pem(BIO *bio) {
+ return PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL);
+}
+
+
+/* X509_set_version() is a macro. */
+int x509_set_version(X509 *x, long version) {
+ return X509_set_version(x, version);
+}
+
+/* X509_get_version() is a macro. */
+long x509_get_version(X509 *x) {
+ return X509_get_version(x);
+}
+
+/* X509_set_notBefore() is a macro. */
+int x509_set_not_before(X509 *x, ASN1_TIME *tm) {
+ return X509_set_notBefore(x, tm);
+}
+
+/* X509_get_notBefore() is a macro. */
+ASN1_TIME *x509_get_not_before(X509 *x) {
+ return X509_get_notBefore(x);
+}
+
+/* X509_set_notAfter() is a macro. */
+int x509_set_not_after(X509 *x, ASN1_TIME *tm) {
+ return X509_set_notAfter(x, tm);
+}
+
+/* X509_get_notAfter() is a macro. */
+ASN1_TIME *x509_get_not_after(X509 *x) {
+ return X509_get_notAfter(x);
+}
+
+int x509_sign(X509 *x, EVP_PKEY *pkey, EVP_MD *md) {
+ return X509_sign(x, pkey, md);
+}
+
+/* x509_gmtime_adj() is a macro. */
+ASN1_TIME *x509_gmtime_adj(ASN1_TIME *s, long adj) {
+ return X509_gmtime_adj(s, adj);
+}
+
+PyObject *x509_name_by_nid(X509_NAME *name, int nid) {
+ void *buf;
+ int len, xlen;
+ PyObject *ret;
+
+ if ((len = X509_NAME_get_text_by_NID(name, nid, NULL, 0)) == -1) {
+ Py_RETURN_NONE;
+ }
+ len++;
+ if (!(buf = PyMem_Malloc(len))) {
+ PyErr_SetString(PyExc_MemoryError, "x509_name_by_nid");
+ return NULL;
+ }
+ xlen = X509_NAME_get_text_by_NID(name, nid, buf, len);
+
+ ret = PyBytes_FromStringAndSize(buf, xlen);
+
+ PyMem_Free(buf);
+ return ret;
+}
+
+int x509_name_set_by_nid(X509_NAME *name, int nid, PyObject *obj) {
+ return X509_NAME_add_entry_by_NID(name, nid, MBSTRING_ASC, (unsigned char *)PyBytes_AsString(obj), -1, -1, 0);
+}
+
+/* x509_name_add_entry_by_txt */
+int x509_name_add_entry_by_txt(X509_NAME *name, char *field, int type, char *bytes, int len, int loc, int set) {
+ return X509_NAME_add_entry_by_txt(name, field, type, (unsigned char *)bytes, len, loc, set);
+}
+
+PyObject *x509_name_get_der(X509_NAME *name) {
+ const char* pder="";
+ size_t pderlen;
+ i2d_X509_NAME(name, 0);
+ if (!X509_NAME_get0_der(name, (const unsigned char **)pder, &pderlen)) {
+ m2_PyErr_Msg(_x509_err);
+ return NULL;
+ }
+ return PyBytes_FromStringAndSize(pder, pderlen);
+}
+
+/* sk_X509_free() is a macro. */
+void sk_x509_free(STACK_OF(X509) *stack) {
+ sk_X509_free(stack);
+}
+
+/* sk_X509_push() is a macro. */
+int sk_x509_push(STACK_OF(X509) *stack, X509 *x509) {
+ return sk_X509_push(stack, x509);
+}
+
+/* sk_X509_pop() is a macro. */
+X509 *sk_x509_pop(STACK_OF(X509) *stack) {
+ return sk_X509_pop(stack);
+}
+
+
+int x509_store_load_locations(X509_STORE *store, const char *file) {
+ int locations = 0;
+
+ if ((locations = X509_STORE_load_locations(store, file, NULL)) < 1) {
+ m2_PyErr_Msg(_x509_err);
+ }
+ return locations;
+}
+
+int x509_type_check(X509 *x509) {
+ return 1;
+}
+
+int x509_name_type_check(X509_NAME *name) {
+ return 1;
+}
+
+X509_NAME *x509_req_get_subject_name(X509_REQ *x) {
+ return X509_REQ_get_subject_name(x);
+}
+
+long x509_req_get_version(X509_REQ *x) {
+ return X509_REQ_get_version(x);
+}
+
+int x509_req_set_version(X509_REQ *x, long version) {
+ return X509_REQ_set_version(x, version);
+}
+
+int x509_req_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts) {
+ return X509_REQ_add_extensions(req, exts);
+}
+
+X509_NAME_ENTRY *x509_name_entry_create_by_txt(X509_NAME_ENTRY **ne, char *field, int type, char *bytes, int len) {
+ return X509_NAME_ENTRY_create_by_txt( ne, field, type, (unsigned char *)bytes, len);
+}
+
+
+X509V3_CTX *
+x509v3_set_nconf(void) {
+ X509V3_CTX * ctx;
+ CONF *conf = NCONF_new(NULL);
+
+ if (!(ctx=(X509V3_CTX *)PyMem_Malloc(sizeof(X509V3_CTX)))) {
+ PyErr_SetString(PyExc_MemoryError, "x509v3_set_nconf");
+ return NULL;
+ }
+ /* X509V3_set_nconf does not generate any error signs at all. */
+ X509V3_set_nconf(ctx, conf);
+ return ctx;
+}
+
+
+X509_EXTENSION *
+x509v3_ext_conf(void *conf, X509V3_CTX *ctx, char *name, char *value) {
+ X509_EXTENSION * ext = NULL;
+ ext = X509V3_EXT_conf(conf, ctx, name, value);
+ PyMem_Free(ctx);
+ return ext;
+}
+
+
+/* X509_EXTENSION_free() might be a macro, didn't find definition. */
+void x509_extension_free(X509_EXTENSION *ext) {
+ X509_EXTENSION_free(ext);
+}
+
+PyObject *x509_extension_get_name(X509_EXTENSION *ext) {
+ PyObject * ext_name;
+ const char * ext_name_str;
+ ext_name_str = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext)));
+ if (!ext_name_str) {
+ m2_PyErr_Msg(_x509_err);
+ return NULL;
+ }
+ ext_name = PyBytes_FromStringAndSize(ext_name_str, strlen(ext_name_str));
+ return ext_name;
+}
+
+/* sk_X509_EXTENSION_new_null is a macro. */
+STACK_OF(X509_EXTENSION) *sk_x509_extension_new_null(void) {
+ return sk_X509_EXTENSION_new_null();
+}
+
+/* sk_X509_EXTENSION_free() is a macro. */
+void sk_x509_extension_free(STACK_OF(X509_EXTENSION) *stack) {
+ sk_X509_EXTENSION_free(stack);
+}
+
+/* sk_X509_EXTENSION_push() is a macro. */
+int sk_x509_extension_push(STACK_OF(X509_EXTENSION) *stack, X509_EXTENSION *x509_ext) {
+ return sk_X509_EXTENSION_push(stack, x509_ext);
+}
+
+/* sk_X509_EXTENSION_pop() is a macro. */
+X509_EXTENSION *sk_x509_extension_pop(STACK_OF(X509_EXTENSION) *stack) {
+ return sk_X509_EXTENSION_pop(stack);
+}
+
+/* sk_X509_EXTENSION_num() is a macro. */
+int sk_x509_extension_num(STACK_OF(X509_EXTENSION) *stack) {
+ return sk_X509_EXTENSION_num(stack);
+}
+
+/* sk_X509_EXTENSION_value() is a macro. */
+X509_EXTENSION *sk_x509_extension_value(STACK_OF(X509_EXTENSION) *stack, int i) {
+ return sk_X509_EXTENSION_value(stack, i);
+}
+
+/* X509_STORE_CTX_get_app_data is a macro. */
+void *x509_store_ctx_get_app_data(X509_STORE_CTX *ctx) {
+ return X509_STORE_CTX_get_app_data(ctx);
+}
+
+/* X509_STORE_CTX_get_app_data is a macro. */
+void *x509_store_ctx_get_ex_data(X509_STORE_CTX *ctx, int idx) {
+ return X509_STORE_CTX_get_ex_data(ctx, idx);
+}
+
+void x509_store_set_verify_cb(X509_STORE *store, PyObject *pyfunc) {
+ Py_XDECREF(x509_store_verify_cb_func);
+ Py_INCREF(pyfunc);
+ x509_store_verify_cb_func = pyfunc;
+ X509_STORE_set_verify_cb(store, x509_store_verify_callback);
+}
+
+
+STACK_OF(X509) *
+make_stack_from_der_sequence(PyObject * pyEncodedString){
+ STACK_OF(X509) *certs;
+ Py_ssize_t encoded_string_len;
+ char *encoded_string;
+ const unsigned char *tmp_str;
+
+ encoded_string_len = PyBytes_Size(pyEncodedString);
+
+ if (encoded_string_len > INT_MAX) {
+ PyErr_Format(_x509_err, "object too large");
+ return NULL;
+ }
+
+ encoded_string = PyBytes_AsString(pyEncodedString);
+
+ if (!encoded_string) {
+ PyErr_SetString(_x509_err,
+ "Cannot convert Python Bytes to (char *).");
+ return NULL;
+ }
+
+ tmp_str = (unsigned char *)encoded_string;
+ certs = d2i_SEQ_CERT(NULL, &tmp_str, encoded_string_len);
+ if (certs == NULL) {
+ PyErr_SetString(_x509_err, "Generating STACK_OF(X509) failed.");
+ return NULL;
+ }
+ return certs;
+}
+
+/* sk_X509_new_null() is a macro returning "STACK_OF(X509) *". */
+STACK_OF(X509) *sk_x509_new_null(void) {
+ return sk_X509_new_null();
+}
+
+
+PyObject *
+get_der_encoding_stack(STACK_OF(X509) *stack){
+ PyObject * encodedString;
+
+ unsigned char * encoding = NULL;
+ int len;
+
+ len = i2d_SEQ_CERT(stack, &encoding);
+ if (!encoding) {
+ m2_PyErr_Msg(_x509_err);
+ return NULL;
+ }
+
+ encodedString = PyBytes_FromStringAndSize((const char *)encoding, len);
+
+ if (encoding)
+ OPENSSL_free(encoding);
+
+ return encodedString;
+}
+
+
+
+char *x509_name_oneline(X509_NAME *x) {
+ return X509_NAME_oneline(x, NULL, 0);
+}
+
+
+#include <openssl/asn1.h>
+
+
+/* ASN1_TIME_set_string () is a macro */
+int asn1_time_type_check(ASN1_TIME *ASN1_TIME) {
+ return 1;
+}
+
+PyObject *asn1_integer_get(ASN1_INTEGER *asn1) {
+ BIGNUM *bn;
+ PyObject *ret;
+ char *hex;
+
+ bn = ASN1_INTEGER_to_BN(asn1, NULL);
+
+ if (!bn){
+ m2_PyErr_Msg(PyExc_RuntimeError);
+ return NULL;
+ }
+
+ hex = BN_bn2hex(bn);
+
+ if (!hex){
+ m2_PyErr_Msg(PyExc_RuntimeError);
+ BN_free(bn);
+ return NULL;
+ }
+
+ BN_free(bn);
+
+ ret = PyLong_FromString(hex, NULL, 16);
+
+ OPENSSL_free(hex);
+
+ return ret;
+}
+
+int asn1_integer_set(ASN1_INTEGER *asn1, PyObject *value) {
+ BIGNUM *bn = NULL;
+ PyObject *fmt, *args, *hex;
+
+/* Despite all hopes to the contrary, we cannot survive here with
+ * PyLong_AsLong shims as provided in
+ * /usr/include/python2.7/longobject.h.
+ */
+#if PY_MAJOR_VERSION >= 3
+ if (PyLong_Check(value))
+ return ASN1_INTEGER_set(asn1, PyLong_AsLong(value));
+#else
+ if (PyInt_Check(value))
+ return ASN1_INTEGER_set(asn1, PyInt_AS_LONG(value));
+#endif // PY_MAJOR_VERSION >= 3
+
+ if (!PyLong_Check(value)){
+ PyErr_SetString(PyExc_TypeError, "expected int or long");
+ return 0;
+ }
+
+ fmt = PyString_FromString("%x");
+
+ if (!fmt)
+ return 0;
+
+ args = PyTuple_New(1);
+
+ if (!args){
+ Py_DECREF(fmt);
+ PyErr_SetString(PyExc_RuntimeError, "PyTuple_New() failed");
+ return 0;
+ }
+
+ Py_INCREF(value);
+ PyTuple_SET_ITEM(args, 0, value);
+ hex = PyString_Format(fmt, args);
+
+ if (!hex){
+ PyErr_SetString(PyExc_RuntimeError, "PyString_Format() failed");
+ Py_DECREF(fmt);
+ Py_DECREF(args);
+ return 0;
+ }
+
+ Py_DECREF(fmt);
+ Py_DECREF(args);
+
+ if (BN_hex2bn(&bn, PyString_AsString(hex)) <= 0){
+ m2_PyErr_Msg(PyExc_RuntimeError);
+ Py_DECREF(hex);
+ return 0;
+ }
+
+ Py_DECREF(hex);
+
+ if (!BN_to_ASN1_INTEGER(bn, asn1)){
+ m2_PyErr_Msg(PyExc_RuntimeError);
+ BN_free(bn);
+ return 0;
+ }
+
+ BN_free(bn);
+
+ return 1;
+}
+
+
+
+#include <openssl/bio.h>
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/pkcs7.h>
+
+
+static PyObject *_pkcs7_err, *_smime_err;
+
+void pkcs7_init(PyObject *pkcs7_err) {
+ Py_INCREF(pkcs7_err);
+ _pkcs7_err = pkcs7_err;
+}
+
+void smime_init(PyObject *smime_err) {
+ Py_INCREF(smime_err);
+ _smime_err = smime_err;
+}
+
+
+PyObject *pkcs7_decrypt(PKCS7 *pkcs7, EVP_PKEY *pkey, X509 *cert, int flags) {
+ int outlen;
+ char *outbuf;
+ BIO *bio;
+ PyObject *ret;
+
+ if (!(bio=BIO_new(BIO_s_mem()))) {
+ PyErr_SetString(PyExc_MemoryError, "pkcs7_decrypt");
+ return NULL;
+ }
+ if (!PKCS7_decrypt(pkcs7, pkey, cert, bio, flags)) {
+ m2_PyErr_Msg(_pkcs7_err);
+ BIO_free(bio);
+ return NULL;
+ }
+ outlen = BIO_ctrl_pending(bio);
+ if (!(outbuf=(char *)PyMem_Malloc(outlen))) {
+ PyErr_SetString(PyExc_MemoryError, "pkcs7_decrypt");
+ BIO_free(bio);
+ return NULL;
+ }
+ BIO_read(bio, outbuf, outlen);
+
+ ret = PyBytes_FromStringAndSize(outbuf, outlen);
+
+ BIO_free(bio);
+ PyMem_Free(outbuf);
+ return ret;
+}
+
+
+PKCS7 *pkcs7_encrypt(STACK_OF(X509) *stack, BIO *bio, EVP_CIPHER *cipher, int flags) {
+ return PKCS7_encrypt(stack, bio, cipher, flags);
+}
+
+
+
+PKCS7 *pkcs7_sign1(X509 *x509, EVP_PKEY *pkey, STACK_OF(X509) *stack, BIO *bio, EVP_MD *hash, int flags) {
+
+ PKCS7 *p7 = PKCS7_sign(NULL, NULL, stack, bio, flags | PKCS7_STREAM);
+ if (p7 == NULL) {
+ return NULL;
+ }
+ if (PKCS7_sign_add_signer(p7, x509, pkey, hash, flags) == NULL) {
+ return NULL;
+ }
+ if (PKCS7_final(p7, bio, flags) != 1) {
+ return NULL;
+ }
+ return p7;
+}
+
+
+PKCS7 *pkcs7_sign0(X509 *x509, EVP_PKEY *pkey, BIO *bio, EVP_MD *hash, int flags) {
+ return pkcs7_sign1(x509, pkey, NULL, bio, hash, flags);
+}
+
+
+PKCS7 *pkcs7_read_bio(BIO *bio) {
+ return PEM_read_bio_PKCS7(bio, NULL, NULL, NULL);
+}
+
+
+PKCS7 *pkcs7_read_bio_der(BIO *bio) {
+ return d2i_PKCS7_bio(bio, NULL);
+}
+
+
+PyObject *pkcs7_verify1(PKCS7 *pkcs7, STACK_OF(X509) *stack, X509_STORE *store, BIO *data, int flags) {
+ int res, outlen;
+ char *outbuf;
+ BIO *bio;
+ PyObject *ret;
+
+ if (!(bio=BIO_new(BIO_s_mem()))) {
+ PyErr_SetString(PyExc_MemoryError, "pkcs7_verify1");
+ return NULL;
+ }
+ Py_BEGIN_ALLOW_THREADS
+ res = PKCS7_verify(pkcs7, stack, store, data, bio, flags);
+ Py_END_ALLOW_THREADS
+ if (!res) {
+ m2_PyErr_Msg(_pkcs7_err);
+ BIO_free(bio);
+ return NULL;
+ }
+ outlen = BIO_ctrl_pending(bio);
+ if (!(outbuf=(char *)PyMem_Malloc(outlen))) {
+ PyErr_SetString(PyExc_MemoryError, "pkcs7_verify1");
+ BIO_free(bio);
+ return NULL;
+ }
+ BIO_read(bio, outbuf, outlen);
+
+ ret = PyBytes_FromStringAndSize(outbuf, outlen);
+
+ BIO_free(bio);
+ PyMem_Free(outbuf);
+ return ret;
+}
+
+PyObject *pkcs7_verify0(PKCS7 *pkcs7, STACK_OF(X509) *stack, X509_STORE *store, int flags) {
+ return pkcs7_verify1(pkcs7, stack, store, NULL, flags);
+}
+
+
+int smime_write_pkcs7_multi(BIO *bio, PKCS7 *pkcs7, BIO *data, int flags) {
+ return SMIME_write_PKCS7(bio, pkcs7, data, flags | PKCS7_DETACHED);
+}
+
+
+int smime_write_pkcs7(BIO *bio, PKCS7 *pkcs7, int flags) {
+ return SMIME_write_PKCS7(bio, pkcs7, NULL, flags);
+}
+
+PyObject *smime_read_pkcs7(BIO *bio) {
+ BIO *bcont = NULL;
+ PKCS7 *p7;
+ PyObject *tuple, *_p7, *_BIO;
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+
+ if (BIO_method_type(bio) == BIO_TYPE_MEM) {
+ /* OpenSSL FAQ explains that this is needed for mem BIO to return EOF,
+ * like file BIO does. Might need to do this for more mem BIOs but
+ * not sure if that is safe, so starting with just this single place.
+ */
+ BIO_set_mem_eof_return(bio, 0);
+ }
+
+ Py_BEGIN_ALLOW_THREADS
+ p7=SMIME_read_PKCS7(bio, &bcont);
+ Py_END_ALLOW_THREADS
+ if (!p7) {
+ m2_PyErr_Msg(_smime_err);
+ return NULL;
+ }
+ if (!(tuple=PyTuple_New(2))) {
+ PyErr_SetString(PyExc_RuntimeError, "PyTuple_New() fails");
+ return NULL;
+ }
+ _p7 = SWIG_NewPointerObj((void *)p7, SWIGTYPE_p_PKCS7, 0);
+ PyTuple_SET_ITEM(tuple, 0, _p7);
+ if (!bcont) {
+ Py_INCREF(Py_None);
+ PyTuple_SET_ITEM(tuple, 1, Py_None);
+ } else {
+ _BIO = SWIG_NewPointerObj((void *)bcont, SWIGTYPE_p_BIO, 0);
+ PyTuple_SET_ITEM(tuple, 1, _BIO);
+ }
+ return tuple;
+}
+
+
+int pkcs7_write_bio(PKCS7 *pkcs7, BIO* bio) {
+ return PEM_write_bio_PKCS7(bio, pkcs7);
+}
+
+
+int pkcs7_write_bio_der(PKCS7 *pkcs7, BIO *bio) {
+ return i2d_PKCS7_bio(bio, pkcs7);
+}
+
+int pkcs7_type_nid(PKCS7 *pkcs7) {
+ return OBJ_obj2nid(pkcs7->type);
+}
+
+const char *pkcs7_type_sn(PKCS7 *pkcs7) {
+ return OBJ_nid2sn(OBJ_obj2nid(pkcs7->type));
+}
+
+
+int smime_crlf_copy(BIO *in, BIO *out) {
+ return SMIME_crlf_copy(in, out, PKCS7_TEXT);
+}
+
+/* return STACK_OF(X509)* */
+STACK_OF(X509) *pkcs7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags) {
+ return PKCS7_get0_signers(p7, certs, flags);
+}
+
+
+
+#include <openssl/x509v3.h>
+
+
+static PyObject *_util_err;
+
+void util_init(PyObject *util_err) {
+ Py_INCREF(util_err);
+ _util_err = util_err;
+}
+
+PyObject *util_hex_to_string(PyObject *blob) {
+ PyObject *obj;
+ const void *buf;
+ char *ret;
+ Py_ssize_t len;
+
+ if (PyObject_AsReadBuffer(blob, &buf, &len) == -1)
+ return NULL;
+
+ ret = hex_to_string((unsigned char *)buf, len);
+ if (!ret) {
+ m2_PyErr_Msg(_util_err);
+ return NULL;
+ }
+
+ obj = PyBytes_FromString(ret);
+
+ OPENSSL_free(ret);
+ return obj;
+}
+
+PyObject *util_string_to_hex(PyObject *blob) {
+ PyObject *obj;
+ const void *buf;
+ unsigned char *ret;
+ Py_ssize_t len0;
+ long len;
+
+ if (PyObject_AsReadBuffer(blob, &buf, &len0) == -1)
+ return NULL;
+
+ len = len0;
+ ret = string_to_hex((char *)buf, &len);
+ if (ret == NULL) {
+ m2_PyErr_Msg(_util_err);
+ return NULL;
+ }
+ obj = PyBytes_FromStringAndSize((char*)ret, len);
+ OPENSSL_free(ret);
+ return obj;
+}
+
+
+#include <openssl/bn.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/x509.h>
+#include <openssl/ecdsa.h>
+#include <openssl/ecdh.h>
+
+
+static PyObject *_ec_err;
+
+void ec_init(PyObject *ec_err) {
+ Py_INCREF(ec_err);
+ _ec_err = ec_err;
+}
+
+PyObject *ec_get_builtin_curves(void) {
+ /* size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t
+ * nitems); */
+ EC_builtin_curve *curves;
+ Py_ssize_t ret_curves = 0;
+ size_t num_curves = EC_get_builtin_curves(NULL, 0);
+ PyObject *ret_tuple = NULL;
+ PyObject *ret_dict = NULL;
+ Py_ssize_t i;
+ const char *comment;
+ const char *sname;
+
+ if (!(curves = PyMem_Malloc(num_curves * sizeof(EC_builtin_curve)))) {
+ PyErr_SetString(PyExc_MemoryError, "ec_get_builtin_curves");
+ return NULL;
+ }
+
+ ret_curves = (Py_ssize_t)EC_get_builtin_curves(curves, num_curves);
+
+ if (!(ret_tuple = PyTuple_New(ret_curves))) {
+ PyErr_SetString(PyExc_MemoryError, "ec_get_builtin_curves");
+ return NULL;
+ }
+
+ for (i = 0; i < ret_curves; i++) {
+ if (!(ret_dict = PyDict_New())) {
+ PyErr_SetString(PyExc_MemoryError, "ec_get_builtin_curves");
+ return NULL;
+ }
+
+ comment = curves[i].comment;
+ sname = OBJ_nid2sn(curves[i].nid);
+ if (sname == NULL)
+ sname = "";
+
+ PyDict_SetItemString(ret_dict, "NID",
+ PyLong_FromLong((long)curves[i].nid));
+ PyDict_SetItemString(ret_dict, "sname",
+ PyString_FromString(sname));
+ PyDict_SetItemString(ret_dict, "comment",
+ PyString_FromString(comment));
+
+ PyTuple_SET_ITEM(ret_tuple, i, ret_dict);
+
+ }
+
+ PyMem_Free(curves);
+
+ return ret_tuple;
+}
+
+EC_KEY* ec_key_new_by_curve_name(int nid)
+{
+ EC_KEY *key;
+ EC_GROUP *group;
+ int ret =0;
+ point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED;
+ int asn1_flag = OPENSSL_EC_NAMED_CURVE;
+
+ /* If I simply do "return EC_KEY_new_by_curve_name(nid);"
+ * I get large public keys (222 vs 84 bytes for sect233k1 curve).
+ * I don't know why that is, but 'openssl ecparam -genkey ...' sets
+ * the ASN.1 flag and the point conversion form, and gets the
+ * small pub keys. So let's do that too.
+ */
+ key = EC_KEY_new();
+ if (!key) {
+ PyErr_SetString(PyExc_MemoryError, "ec_key_new_by_curve_name");
+ return NULL;
+ }
+ group = EC_GROUP_new_by_curve_name(nid);
+ if (!group) {
+ m2_PyErr_Msg(_ec_err);
+ EC_KEY_free(key);
+ return NULL;
+ }
+ EC_GROUP_set_asn1_flag(group, asn1_flag);
+ EC_GROUP_set_point_conversion_form(group, form);
+ ret = EC_KEY_set_group(key, group);
+ EC_GROUP_free(group);
+ if (ret == 0)
+ {
+ /* EC_KEY_set_group only returns 0 or 1, and does not set error. */
+ PyErr_SetString(_ec_err, "cannot set key's group");
+ EC_KEY_free(key);
+ return NULL;
+ }
+
+ return key;
+}
+
+PyObject *ec_key_get_public_der(EC_KEY *key) {
+ char *src=NULL;
+ int src_len=0;
+ PyObject *pyo=NULL;
+
+ /* Convert to binary */
+ src_len = i2d_EC_PUBKEY( key, (unsigned char**)&src );
+ if (src_len < 0)
+ {
+ m2_PyErr_Msg(_ec_err);
+ return NULL;
+ }
+ /* Create a PyBuffer containing a copy of the binary,
+ * to simplify memory deallocation
+ */
+ pyo = PyBytes_FromStringAndSize( src, src_len );
+
+ OPENSSL_free(src);
+
+ return pyo;
+}
+
+PyObject *ec_key_get_public_key(EC_KEY *key) {
+ char *src=NULL;
+ int src_len=0;
+ PyObject *pyo=NULL;
+
+ /* Convert to binary */
+ src_len = i2o_ECPublicKey(key, (unsigned char**)&src);
+ if (src_len < 0)
+ {
+ m2_PyErr_Msg(_ec_err);
+ return NULL;
+ }
+
+ pyo = PyBytes_FromStringAndSize( src, src_len );
+
+ OPENSSL_free(src);
+
+ return pyo;
+}
+
+
+
+EC_KEY *ec_key_read_pubkey(BIO *f) {
+ return PEM_read_bio_EC_PUBKEY(f, NULL, NULL, NULL);
+}
+
+
+int ec_key_write_pubkey(EC_KEY *key, BIO *f) {
+ return PEM_write_bio_EC_PUBKEY(f, key );
+}
+
+
+EC_KEY *ec_key_read_bio(BIO *f, PyObject *pyfunc) {
+ EC_KEY *ret;
+
+ Py_INCREF(pyfunc);
+ Py_BEGIN_ALLOW_THREADS
+ ret = PEM_read_bio_ECPrivateKey(f, NULL, passphrase_callback, (void *)pyfunc);
+ Py_END_ALLOW_THREADS
+ Py_DECREF(pyfunc);
+ return ret;
+}
+
+
+int ec_key_write_bio(EC_KEY *key, BIO *f, EVP_CIPHER *cipher, PyObject *pyfunc) {
+ int ret;
+
+ Py_INCREF(pyfunc);
+ Py_BEGIN_ALLOW_THREADS
+ ret = PEM_write_bio_ECPrivateKey(f, key, cipher, NULL, 0,
+ passphrase_callback, (void *)pyfunc);
+ Py_END_ALLOW_THREADS
+ Py_DECREF(pyfunc);
+ return ret;
+}
+
+
+int ec_key_write_bio_no_cipher(EC_KEY *key, BIO *f, PyObject *pyfunc) {
+ int ret;
+
+ Py_INCREF(pyfunc);
+ Py_BEGIN_ALLOW_THREADS
+ ret = PEM_write_bio_ECPrivateKey(f, key, NULL, NULL, 0,
+ passphrase_callback, (void *)pyfunc);
+ Py_END_ALLOW_THREADS
+ Py_DECREF(pyfunc);
+ return ret;
+}
+
+
+PyObject *ecdsa_sig_get_r(ECDSA_SIG *ecdsa_sig) {
+ const BIGNUM* pr;
+ ECDSA_SIG_get0(ecdsa_sig, &pr, NULL);
+ return bn_to_mpi(pr);
+}
+
+PyObject *ecdsa_sig_get_s(ECDSA_SIG *ecdsa_sig) {
+ const BIGNUM* ps;
+ ECDSA_SIG_get0(ecdsa_sig, NULL, &ps);
+ return bn_to_mpi(ps);
+}
+
+PyObject *ecdsa_sign(EC_KEY *key, PyObject *value) {
+ const void *vbuf;
+ int vlen = 0;
+ PyObject *tuple;
+ ECDSA_SIG *sig;
+
+ if (m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
+ return NULL;
+
+ if (!(sig = ECDSA_do_sign(vbuf, vlen, key))) {
+ m2_PyErr_Msg(_ec_err);
+ return NULL;
+ }
+ if (!(tuple = PyTuple_New(2))) {
+ ECDSA_SIG_free(sig);
+ PyErr_SetString(PyExc_RuntimeError, "PyTuple_New() fails");
+ return NULL;
+ }
+ PyTuple_SET_ITEM(tuple, 0, ecdsa_sig_get_r(sig));
+ PyTuple_SET_ITEM(tuple, 1, ecdsa_sig_get_s(sig));
+ ECDSA_SIG_free(sig);
+ return tuple;
+}
+
+int ecdsa_verify(EC_KEY *key, PyObject *value, PyObject *r, PyObject *s) {
+ const void *vbuf, *rbuf, *sbuf;
+ int vlen = 0, rlen = 0, slen = 0;
+ ECDSA_SIG *sig;
+ int ret;
+ BIGNUM* pr, *ps;
+
+ if ((m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
+ || (m2_PyObject_AsReadBufferInt(r, &rbuf, &rlen) == -1)
+ || (m2_PyObject_AsReadBufferInt(s, &sbuf, &slen) == -1))
+ return -1;
+
+ if (!(pr = BN_mpi2bn((unsigned char *)rbuf, rlen, NULL))) {
+ m2_PyErr_Msg(_ec_err);
+ return -1;
+ }
+ if (!(ps = BN_mpi2bn((unsigned char *)sbuf, slen, NULL))) {
+ m2_PyErr_Msg(_ec_err);
+ BN_free(pr);
+ return -1;
+ }
+
+ if (!(sig = ECDSA_SIG_new())) {
+ m2_PyErr_Msg(_ec_err);
+ BN_free(pr);
+ BN_free(ps);
+ return -1;
+ }
+ if (!ECDSA_SIG_set0(sig, pr, ps)) {
+ PyErr_SetString(_ec_err, "Cannot set r and s fields of ECDSA_SIG.");
+ ECDSA_SIG_free(sig);
+ BN_free(pr);
+ BN_free(ps);
+ return -1;
+ }
+ ret = ECDSA_do_verify(vbuf, vlen, sig, key);
+ ECDSA_SIG_free(sig);
+ if (ret == -1)
+ m2_PyErr_Msg(_ec_err);
+ return ret;
+}
+
+
+PyObject *ecdsa_sign_asn1(EC_KEY *key, PyObject *value) {
+ const void *vbuf;
+ int vlen = 0;
+ void *sigbuf;
+ unsigned int siglen;
+ PyObject *ret;
+
+ if (m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
+ return NULL;
+
+ if (!(sigbuf = PyMem_Malloc(ECDSA_size(key)))) {
+ PyErr_SetString(PyExc_MemoryError, "ecdsa_sign_asn1");
+ return NULL;
+ }
+ if (!ECDSA_sign(0, vbuf, vlen, (unsigned char *)sigbuf, &siglen, key)) {
+ m2_PyErr_Msg(_ec_err);
+ PyMem_Free(sigbuf);
+ return NULL;
+ }
+ ret = PyBytes_FromStringAndSize(sigbuf, siglen);
+
+ PyMem_Free(sigbuf);
+ return ret;
+}
+
+
+int ecdsa_verify_asn1(EC_KEY *key, PyObject *value, PyObject *sig) {
+ const void *vbuf;
+ void *sbuf;
+ int vlen = 0, slen = 0, ret;
+
+ if ((m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
+ || (m2_PyObject_AsReadBufferInt(sig, (const void **)&sbuf, &slen)
+ == -1))
+ return -1;
+
+ if ((ret = ECDSA_verify(0, vbuf, vlen, sbuf, slen, key)) == -1)
+ m2_PyErr_Msg(_ec_err);
+ return ret;
+}
+
+PyObject *ecdh_compute_key(EC_KEY *keypairA, EC_KEY *pubkeyB) {
+ int sharedkeylen;
+ void *sharedkey;
+ const EC_POINT *pkpointB;
+ PyObject *ret;
+ const EC_GROUP* groupA;
+
+ if ((pkpointB = EC_KEY_get0_public_key(pubkeyB)) == NULL)
+ {
+ PyErr_SetString(_ec_err, "Cannot get the public key of EC_KEY object.");
+ return NULL;
+ }
+
+ groupA = EC_KEY_get0_group(keypairA);
+ sharedkeylen = (EC_GROUP_get_degree(groupA) + 7)/8;
+
+ if (!(sharedkey = PyMem_Malloc(sharedkeylen))) {
+ PyErr_SetString(PyExc_MemoryError, "ecdh_compute_key");
+ return NULL;
+ }
+ if ((sharedkeylen = ECDH_compute_key((unsigned char *)sharedkey, sharedkeylen, pkpointB, keypairA, NULL)) == -1) {
+ m2_PyErr_Msg(_ec_err);
+ PyMem_Free(sharedkey);
+ return NULL;
+ }
+
+ ret = PyBytes_FromStringAndSize((const char *)sharedkey, sharedkeylen);
+
+ PyMem_Free(sharedkey);
+
+ return ret;
+}
+
+
+EC_KEY* ec_key_from_pubkey_der(PyObject *pubkey) {
+ const void *keypairbuf;
+ Py_ssize_t keypairbuflen;
+ const unsigned char *tempBuf;
+ EC_KEY *keypair;
+
+ if (PyObject_AsReadBuffer(pubkey, &keypairbuf, &keypairbuflen) == -1)
+ {
+ return NULL;
+ }
+
+ tempBuf = (const unsigned char *)keypairbuf;
+ if ((keypair = d2i_EC_PUBKEY( NULL, &tempBuf, keypairbuflen)) == 0)
+ {
+ m2_PyErr_Msg(_ec_err);
+ return NULL;
+ }
+ return keypair;
+}
+
+EC_KEY* ec_key_from_pubkey_params(int nid, PyObject *pubkey) {
+ const void *keypairbuf;
+ Py_ssize_t keypairbuflen;
+ const unsigned char *tempBuf;
+ EC_KEY *keypair;
+
+ if (PyObject_AsReadBuffer(pubkey, &keypairbuf, &keypairbuflen) == -1)
+ {
+ return NULL;
+ }
+
+ keypair = ec_key_new_by_curve_name(nid);
+ if (!keypair) {
+ m2_PyErr_Msg(_ec_err);
+ return NULL;
+ }
+
+ tempBuf = (const unsigned char *)keypairbuf;
+ if ((o2i_ECPublicKey( &keypair, &tempBuf, keypairbuflen)) == 0)
+ {
+ m2_PyErr_Msg(_ec_err);
+ return NULL;
+ }
+ return keypair;
+}
+
+
+// According to [SEC2] the degree of the group is defined as EC key length
+int ec_key_keylen(EC_KEY *key) {
+ const EC_GROUP *group = EC_KEY_get0_group(key);
+ return EC_GROUP_get_degree(group);
+}
+
+int ec_key_type_check(EC_KEY *key) {
+ return 1;
+}
+
+
+#include <openssl/engine.h>
+#include <openssl/ui.h>
+#include <stdio.h>
+
+
+
+/*
+ * Code from engine-pkcs11 1.4.0 in engine-pkcs11.c
+ *
+
+99 static char *get_pin(UI_METHOD * ui_method, void *callback_data, char *sc_pin,
+100 int maxlen)
+101 {
+102 UI *ui;
+103 struct {
+104 const void *password;
+105 const char *prompt_info;
+106 } *mycb = callback_data;
+107
+108 if (mycb->password) {
+109 sc_pin = set_pin(mycb->password);
+110 return sc_pin;
+111 }
+
+ *
+ * So callback_data need to be always provided and have fixed type.
+ * UI method still may be NULL.
+ *
+ * Following functions allocate and free callback data structure with
+ * optional password set.
+ */
+
+typedef struct {
+ char * password;
+ char * prompt;
+} _cbd_t;
+
+void * engine_pkcs11_data_new(const char *pin) {
+ _cbd_t * cb = (_cbd_t *) PyMem_Malloc(sizeof(_cbd_t));
+ if (!cb) {
+ PyErr_SetString(PyExc_MemoryError, "engine_pkcs11_data_new");
+ return NULL;
+ }
+ cb->password = NULL;
+ if (pin) {
+ size_t size = strlen(pin);
+ cb->password = (char *) PyMem_Malloc(size + 1);
+ if (!cb->password) {
+ PyErr_SetString(PyExc_MemoryError, "engine_pkcs11_data_new");
+ PyMem_Free(cb);
+ return NULL;
+ }
+ memcpy(cb->password, pin, size + 1);
+ }
+ cb->prompt = NULL;
+ return cb;
+}
+
+void engine_pkcs11_data_free(void * vcb) {
+ _cbd_t * cb = (_cbd_t *) vcb;
+ if (!cb)
+ return;
+ if (cb->password)
+ PyMem_Free(cb->password);
+ PyMem_Free(cb);
+}
+
+
+
+static PyObject *_engine_err;
+
+void engine_init_error(PyObject *engine_err) {
+ Py_INCREF(engine_err);
+ _engine_err = engine_err;
+}
+
+X509 * engine_load_certificate(ENGINE *e, const char * slot) {
+ struct {
+ const char * slot;
+ X509 * cert;
+ } cbd;
+ cbd.slot = slot;
+ cbd.cert = NULL;
+ if (!ENGINE_ctrl_cmd(e, "LOAD_CERT_CTRL", 0, &cbd, NULL, 0)) {
+ PyErr_SetString(_engine_err, "cannot load certificate");
+ return NULL;
+ }
+ return cbd.cert;
+}
+
+
+#include <openssl/objects.h>
+
+
+/*
+ From the manpage for OBJ_obt2txt ():
+ BUGS
+ OBJ_obj2txt() is awkward and messy to use: it doesn’t follow the
+ convention of other OpenSSL functions where the buffer can be set
+ to NULL to determine the amount of data that should be written.
+ Instead buf must point to a valid buffer and buf_len should be set
+ to a positive value. A buffer length of 80 should be more than
+ enough to handle any OID encountered in practice.
+
+ The first call to OBJ_obj2txt () therefore passes a non-NULL dummy
+ buffer. This wart is reportedly removed in OpenSSL 0.9.8b, although
+ the manpage has not been updated.
+
+ OBJ_obj2txt always prints \0 at the end. But the return value
+ is the number of "good" bytes written. So memory is allocated for
+ len + 1 bytes but only len bytes are marshalled to python.
+*/
+PyObject *obj_obj2txt(const ASN1_OBJECT *obj, int no_name)
+{
+ int len;
+ PyObject *ret;
+ char *buf;
+ char dummy[1];
+
+ len = OBJ_obj2txt(dummy, 1, obj, no_name);
+ if (len < 0) {
+ m2_PyErr_Msg(PyExc_RuntimeError);
+ return NULL;
+ } else if (len == 0) {
+ /* XXX: For OpenSSL prior to 0.9.8b.
+
+ Changes between 0.9.8a and 0.9.8b [04 May 2006]
+ ...
+ *) Several fixes and enhancements to the OID generation code. The old code
+ sometimes allowed invalid OIDs (1.X for X >= 40 for example), couldn't
+ handle numbers larger than ULONG_MAX, truncated printing and had a
+ non standard OBJ_obj2txt() behaviour.
+ [Steve Henson]
+ */
+
+ len = 80;
+ }
+
+ buf = PyMem_Malloc(len + 1);
+ len = OBJ_obj2txt(buf, len + 1, obj, no_name);
+
+ ret = PyBytes_FromStringAndSize(buf, len);
+
+ PyMem_Free(buf);
+
+ return ret;
+}
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+SWIGINTERN PyObject *_wrap__STACK_num_set(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ struct stack_st *arg1 = (struct stack_st *) 0 ;
+ int arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj1 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"_STACK_num_set",1,1,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_stack_st, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "_STACK_num_set" "', argument " "1"" of type '" "struct stack_st *""'");
+ }
+ arg1 = (struct stack_st *)(argp1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "_STACK_num_set" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ if (arg1) (arg1)->num = arg2;
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap__STACK_num_get(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ struct stack_st *arg1 = (struct stack_st *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int result;
+
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_stack_st, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "_STACK_num_get" "', argument " "1"" of type '" "struct stack_st *""'");
+ }
+ arg1 = (struct stack_st *)(argp1);
+ result = (int) ((arg1)->num);
+ resultobj = SWIG_From_int((int)(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap__STACK_data_set(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ struct stack_st *arg1 = (struct stack_st *) 0 ;
+ char **arg2 = (char **) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj1 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"_STACK_data_set",1,1,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_stack_st, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "_STACK_data_set" "', argument " "1"" of type '" "struct stack_st *""'");
+ }
+ arg1 = (struct stack_st *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_p_char, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "_STACK_data_set" "', argument " "2"" of type '" "char **""'");
+ }
+ arg2 = (char **)(argp2);
+ if (arg1) (arg1)->data = arg2;
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap__STACK_data_get(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ struct stack_st *arg1 = (struct stack_st *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ char **result = 0 ;
+
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_stack_st, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "_STACK_data_get" "', argument " "1"" of type '" "struct stack_st *""'");
+ }
+ arg1 = (struct stack_st *)(argp1);
+ result = (char **) ((arg1)->data);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_p_char, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap__STACK_sorted_set(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ struct stack_st *arg1 = (struct stack_st *) 0 ;
+ int arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj1 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"_STACK_sorted_set",1,1,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_stack_st, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "_STACK_sorted_set" "', argument " "1"" of type '" "struct stack_st *""'");
+ }
+ arg1 = (struct stack_st *)(argp1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "_STACK_sorted_set" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ if (arg1) (arg1)->sorted = arg2;
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap__STACK_sorted_get(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ struct stack_st *arg1 = (struct stack_st *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int result;
+
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_stack_st, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "_STACK_sorted_get" "', argument " "1"" of type '" "struct stack_st *""'");
+ }
+ arg1 = (struct stack_st *)(argp1);
+ result = (int) ((arg1)->sorted);
+ resultobj = SWIG_From_int((int)(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap__STACK_num_alloc_set(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ struct stack_st *arg1 = (struct stack_st *) 0 ;
+ int arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj1 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"_STACK_num_alloc_set",1,1,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_stack_st, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "_STACK_num_alloc_set" "', argument " "1"" of type '" "struct stack_st *""'");
+ }
+ arg1 = (struct stack_st *)(argp1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "_STACK_num_alloc_set" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ if (arg1) (arg1)->num_alloc = arg2;
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap__STACK_num_alloc_get(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ struct stack_st *arg1 = (struct stack_st *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int result;
+
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_stack_st, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "_STACK_num_alloc_get" "', argument " "1"" of type '" "struct stack_st *""'");
+ }
+ arg1 = (struct stack_st *)(argp1);
+ result = (int) ((arg1)->num_alloc);
+ resultobj = SWIG_From_int((int)(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap__STACK_comp_set(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ struct stack_st *arg1 = (struct stack_st *) 0 ;
+ int (*arg2)(void const *,void const *) = (int (*)(void const *,void const *)) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj1 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"_STACK_comp_set",1,1,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_stack_st, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "_STACK_comp_set" "', argument " "1"" of type '" "struct stack_st *""'");
+ }
+ arg1 = (struct stack_st *)(argp1);
+ {
+ int res = SWIG_ConvertFunctionPtr(obj1, (void**)(&arg2), SWIGTYPE_p_f_p_q_const__void_p_q_const__void__int);
+ if (!SWIG_IsOK(res)) {
+ SWIG_exception_fail(SWIG_ArgError(res), "in method '" "_STACK_comp_set" "', argument " "2"" of type '" "int (*)(void const *,void const *)""'");
+ }
+ }
+ if (arg1) (arg1)->comp = arg2;
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap__STACK_comp_get(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ struct stack_st *arg1 = (struct stack_st *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int (*result)(void const *,void const *) = 0 ;
+
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_stack_st, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "_STACK_comp_get" "', argument " "1"" of type '" "struct stack_st *""'");
+ }
+ arg1 = (struct stack_st *)(argp1);
+ result = (int (*)(void const *,void const *)) ((arg1)->comp);
+ resultobj = SWIG_NewFunctionPtrObj((void *)(result), SWIGTYPE_p_f_p_q_const__void_p_q_const__void__int);
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN int _wrap_new__STACK(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ struct stack_st *result = 0 ;
+
+ result = (struct stack_st *)calloc(1, sizeof(struct stack_st));
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_stack_st, SWIG_BUILTIN_INIT | 0 );
+ return resultobj == Py_None ? -1 : 0;
+fail:
+ return -1;
+}
+
+
+SWIGINTERN PyObject *_wrap_delete__STACK(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ struct stack_st *arg1 = (struct stack_st *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_stack_st, SWIG_POINTER_DISOWN | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete__STACK" "', argument " "1"" of type '" "struct stack_st *""'");
+ }
+ arg1 = (struct stack_st *)(argp1);
+ free((char *) arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_sk_num(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ _STACK *arg1 = (_STACK *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"sk_num",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_stack_st, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "sk_num" "', argument " "1"" of type '" "_STACK const *""'");
+ }
+ arg1 = (_STACK *)(argp1);
+ result = (int)sk_num((struct stack_st const *)arg1);
+ resultobj = SWIG_From_int((int)(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_sk_value(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ _STACK *arg1 = (_STACK *) 0 ;
+ int arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ void *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"sk_value",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_stack_st, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "sk_value" "', argument " "1"" of type '" "_STACK const *""'");
+ }
+ arg1 = (_STACK *)(argp1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "sk_value" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ result = (void *)sk_value((struct stack_st const *)arg1,arg2);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_void, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_sk_set(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ _STACK *arg1 = (_STACK *) 0 ;
+ int arg2 ;
+ void *arg3 = (void *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ int res3 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ void *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"sk_set",3,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_stack_st, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "sk_set" "', argument " "1"" of type '" "_STACK *""'");
+ }
+ arg1 = (_STACK *)(argp1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "sk_set" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ res3 = SWIG_ConvertPtr(obj2,SWIG_as_voidptrptr(&arg3), 0, 0);
+ if (!SWIG_IsOK(res3)) {
+ SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "sk_set" "', argument " "3"" of type '" "void *""'");
+ }
+ result = (void *)sk_set(arg1,arg2,arg3);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_void, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_sk_new(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ int (*arg1)(void const *,void const *) = (int (*)(void const *,void const *)) 0 ;
+ PyObject * obj0 = 0 ;
+ _STACK *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"sk_new",1,1,&obj0)) SWIG_fail;
+ {
+ int res = SWIG_ConvertFunctionPtr(obj0, (void**)(&arg1), SWIGTYPE_p_f_p_q_const__void_p_q_const__void__int);
+ if (!SWIG_IsOK(res)) {
+ SWIG_exception_fail(SWIG_ArgError(res), "in method '" "sk_new" "', argument " "1"" of type '" "int (*)(void const *,void const *)""'");
+ }
+ }
+ result = (_STACK *)sk_new(arg1);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_stack_st, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_sk_new_null(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ _STACK *result = 0 ;
+
+ result = (_STACK *)sk_new_null();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_stack_st, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_sk_free(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ _STACK *arg1 = (_STACK *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"sk_free",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_stack_st, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "sk_free" "', argument " "1"" of type '" "_STACK *""'");
+ }
+ arg1 = (_STACK *)(argp1);
+ sk_free(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_sk_pop_free(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ _STACK *arg1 = (_STACK *) 0 ;
+ void (*arg2)(void *) = (void (*)(void *)) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"sk_pop_free",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_stack_st, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "sk_pop_free" "', argument " "1"" of type '" "_STACK *""'");
+ }
+ arg1 = (_STACK *)(argp1);
+ {
+ int res = SWIG_ConvertFunctionPtr(obj1, (void**)(&arg2), SWIGTYPE_p_f_p_void__void);
+ if (!SWIG_IsOK(res)) {
+ SWIG_exception_fail(SWIG_ArgError(res), "in method '" "sk_pop_free" "', argument " "2"" of type '" "void (*)(void *)""'");
+ }
+ }
+ sk_pop_free(arg1,arg2);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_sk_deep_copy(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ _STACK *arg1 = (_STACK *) 0 ;
+ void *(*arg2)(void *) = (void *(*)(void *)) 0 ;
+ void (*arg3)(void *) = (void (*)(void *)) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ _STACK *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"sk_deep_copy",3,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_stack_st, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "sk_deep_copy" "', argument " "1"" of type '" "_STACK *""'");
+ }
+ arg1 = (_STACK *)(argp1);
+ {
+ int res = SWIG_ConvertFunctionPtr(obj1, (void**)(&arg2), SWIGTYPE_p_f_p_void__p_void);
+ if (!SWIG_IsOK(res)) {
+ SWIG_exception_fail(SWIG_ArgError(res), "in method '" "sk_deep_copy" "', argument " "2"" of type '" "void *(*)(void *)""'");
+ }
+ }
+ {
+ int res = SWIG_ConvertFunctionPtr(obj2, (void**)(&arg3), SWIGTYPE_p_f_p_void__void);
+ if (!SWIG_IsOK(res)) {
+ SWIG_exception_fail(SWIG_ArgError(res), "in method '" "sk_deep_copy" "', argument " "3"" of type '" "void (*)(void *)""'");
+ }
+ }
+ result = (_STACK *)sk_deep_copy(arg1,arg2,arg3);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_stack_st, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_sk_insert(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ _STACK *arg1 = (_STACK *) 0 ;
+ void *arg2 = (void *) 0 ;
+ int arg3 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ int val3 ;
+ int ecode3 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"sk_insert",3,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_stack_st, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "sk_insert" "', argument " "1"" of type '" "_STACK *""'");
+ }
+ arg1 = (_STACK *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1,SWIG_as_voidptrptr(&arg2), 0, 0);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "sk_insert" "', argument " "2"" of type '" "void *""'");
+ }
+ ecode3 = SWIG_AsVal_int(obj2, &val3);
+ if (!SWIG_IsOK(ecode3)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "sk_insert" "', argument " "3"" of type '" "int""'");
+ }
+ arg3 = (int)(val3);
+ result = (int)sk_insert(arg1,arg2,arg3);
+ resultobj = SWIG_From_int((int)(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_sk_delete(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ _STACK *arg1 = (_STACK *) 0 ;
+ int arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ void *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"sk_delete",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_stack_st, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "sk_delete" "', argument " "1"" of type '" "_STACK *""'");
+ }
+ arg1 = (_STACK *)(argp1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "sk_delete" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ result = (void *)sk_delete(arg1,arg2);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_void, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_sk_delete_ptr(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ _STACK *arg1 = (_STACK *) 0 ;
+ void *arg2 = (void *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ void *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"sk_delete_ptr",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_stack_st, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "sk_delete_ptr" "', argument " "1"" of type '" "_STACK *""'");
+ }
+ arg1 = (_STACK *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1,SWIG_as_voidptrptr(&arg2), 0, 0);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "sk_delete_ptr" "', argument " "2"" of type '" "void *""'");
+ }
+ result = (void *)sk_delete_ptr(arg1,arg2);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_void, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_sk_find(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ _STACK *arg1 = (_STACK *) 0 ;
+ void *arg2 = (void *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"sk_find",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_stack_st, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "sk_find" "', argument " "1"" of type '" "_STACK *""'");
+ }
+ arg1 = (_STACK *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1,SWIG_as_voidptrptr(&arg2), 0, 0);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "sk_find" "', argument " "2"" of type '" "void *""'");
+ }
+ result = (int)sk_find(arg1,arg2);
+ resultobj = SWIG_From_int((int)(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_sk_find_ex(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ _STACK *arg1 = (_STACK *) 0 ;
+ void *arg2 = (void *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"sk_find_ex",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_stack_st, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "sk_find_ex" "', argument " "1"" of type '" "_STACK *""'");
+ }
+ arg1 = (_STACK *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1,SWIG_as_voidptrptr(&arg2), 0, 0);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "sk_find_ex" "', argument " "2"" of type '" "void *""'");
+ }
+ result = (int)sk_find_ex(arg1,arg2);
+ resultobj = SWIG_From_int((int)(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_sk_push(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ _STACK *arg1 = (_STACK *) 0 ;
+ void *arg2 = (void *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"sk_push",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_stack_st, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "sk_push" "', argument " "1"" of type '" "_STACK *""'");
+ }
+ arg1 = (_STACK *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1,SWIG_as_voidptrptr(&arg2), 0, 0);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "sk_push" "', argument " "2"" of type '" "void *""'");
+ }
+ result = (int)sk_push(arg1,arg2);
+ resultobj = SWIG_From_int((int)(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_sk_unshift(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ _STACK *arg1 = (_STACK *) 0 ;
+ void *arg2 = (void *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"sk_unshift",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_stack_st, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "sk_unshift" "', argument " "1"" of type '" "_STACK *""'");
+ }
+ arg1 = (_STACK *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1,SWIG_as_voidptrptr(&arg2), 0, 0);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "sk_unshift" "', argument " "2"" of type '" "void *""'");
+ }
+ result = (int)sk_unshift(arg1,arg2);
+ resultobj = SWIG_From_int((int)(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_sk_shift(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ _STACK *arg1 = (_STACK *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ void *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"sk_shift",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_stack_st, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "sk_shift" "', argument " "1"" of type '" "_STACK *""'");
+ }
+ arg1 = (_STACK *)(argp1);
+ result = (void *)sk_shift(arg1);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_void, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_sk_pop(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ _STACK *arg1 = (_STACK *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ void *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"sk_pop",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_stack_st, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "sk_pop" "', argument " "1"" of type '" "_STACK *""'");
+ }
+ arg1 = (_STACK *)(argp1);
+ result = (void *)sk_pop(arg1);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_void, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_sk_zero(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ _STACK *arg1 = (_STACK *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"sk_zero",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_stack_st, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "sk_zero" "', argument " "1"" of type '" "_STACK *""'");
+ }
+ arg1 = (_STACK *)(argp1);
+ sk_zero(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_sk_set_cmp_func(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ _STACK *arg1 = (_STACK *) 0 ;
+ int (*arg2)(void const *,void const *) = (int (*)(void const *,void const *)) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int (*result)(void const *,void const *) = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"sk_set_cmp_func",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_stack_st, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "sk_set_cmp_func" "', argument " "1"" of type '" "_STACK *""'");
+ }
+ arg1 = (_STACK *)(argp1);
+ {
+ int res = SWIG_ConvertFunctionPtr(obj1, (void**)(&arg2), SWIGTYPE_p_f_p_q_const__void_p_q_const__void__int);
+ if (!SWIG_IsOK(res)) {
+ SWIG_exception_fail(SWIG_ArgError(res), "in method '" "sk_set_cmp_func" "', argument " "2"" of type '" "int (*)(void const *,void const *)""'");
+ }
+ }
+ result = (int (*)(void const *,void const *))sk_set_cmp_func(arg1,arg2);
+ resultobj = SWIG_NewFunctionPtrObj((void *)(result), SWIGTYPE_p_f_p_q_const__void_p_q_const__void__int);
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_sk_dup(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ _STACK *arg1 = (_STACK *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ _STACK *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"sk_dup",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_stack_st, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "sk_dup" "', argument " "1"" of type '" "_STACK *""'");
+ }
+ arg1 = (_STACK *)(argp1);
+ result = (_STACK *)sk_dup(arg1);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_stack_st, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_sk_sort(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ _STACK *arg1 = (_STACK *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"sk_sort",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_stack_st, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "sk_sort" "', argument " "1"" of type '" "_STACK *""'");
+ }
+ arg1 = (_STACK *)(argp1);
+ sk_sort(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_sk_is_sorted(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ _STACK *arg1 = (_STACK *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"sk_is_sorted",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_stack_st, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "sk_is_sorted" "', argument " "1"" of type '" "_STACK const *""'");
+ }
+ arg1 = (_STACK *)(argp1);
+ result = (int)sk_is_sorted((struct stack_st const *)arg1);
+ resultobj = SWIG_From_int((int)(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_stack_st_OPENSSL_STRING_stack_set(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ struct stack_st_OPENSSL_STRING *arg1 = (struct stack_st_OPENSSL_STRING *) 0 ;
+ _STACK *arg2 = (_STACK *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj1 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"stack_st_OPENSSL_STRING_stack_set",1,1,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_stack_st_OPENSSL_STRING, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "stack_st_OPENSSL_STRING_stack_set" "', argument " "1"" of type '" "struct stack_st_OPENSSL_STRING *""'");
+ }
+ arg1 = (struct stack_st_OPENSSL_STRING *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_stack_st, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "stack_st_OPENSSL_STRING_stack_set" "', argument " "2"" of type '" "_STACK *""'");
+ }
+ arg2 = (_STACK *)(argp2);
+ if (arg1) (arg1)->stack = *arg2;
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_stack_st_OPENSSL_STRING_stack_get(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ struct stack_st_OPENSSL_STRING *arg1 = (struct stack_st_OPENSSL_STRING *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ _STACK *result = 0 ;
+
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_stack_st_OPENSSL_STRING, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "stack_st_OPENSSL_STRING_stack_get" "', argument " "1"" of type '" "struct stack_st_OPENSSL_STRING *""'");
+ }
+ arg1 = (struct stack_st_OPENSSL_STRING *)(argp1);
+ result = (_STACK *)& ((arg1)->stack);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_stack_st, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN int _wrap_new_stack_st_OPENSSL_STRING(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ struct stack_st_OPENSSL_STRING *result = 0 ;
+
+ result = (struct stack_st_OPENSSL_STRING *)calloc(1, sizeof(struct stack_st_OPENSSL_STRING));
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_stack_st_OPENSSL_STRING, SWIG_BUILTIN_INIT | 0 );
+ return resultobj == Py_None ? -1 : 0;
+fail:
+ return -1;
+}
+
+
+SWIGINTERN PyObject *_wrap_delete_stack_st_OPENSSL_STRING(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ struct stack_st_OPENSSL_STRING *arg1 = (struct stack_st_OPENSSL_STRING *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_stack_st_OPENSSL_STRING, SWIG_POINTER_DISOWN | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_stack_st_OPENSSL_STRING" "', argument " "1"" of type '" "struct stack_st_OPENSSL_STRING *""'");
+ }
+ arg1 = (struct stack_st_OPENSSL_STRING *)(argp1);
+ free((char *) arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_stack_st_OPENSSL_BLOCK_stack_set(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ struct stack_st_OPENSSL_BLOCK *arg1 = (struct stack_st_OPENSSL_BLOCK *) 0 ;
+ _STACK *arg2 = (_STACK *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj1 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"stack_st_OPENSSL_BLOCK_stack_set",1,1,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_stack_st_OPENSSL_BLOCK, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "stack_st_OPENSSL_BLOCK_stack_set" "', argument " "1"" of type '" "struct stack_st_OPENSSL_BLOCK *""'");
+ }
+ arg1 = (struct stack_st_OPENSSL_BLOCK *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_stack_st, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "stack_st_OPENSSL_BLOCK_stack_set" "', argument " "2"" of type '" "_STACK *""'");
+ }
+ arg2 = (_STACK *)(argp2);
+ if (arg1) (arg1)->stack = *arg2;
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_stack_st_OPENSSL_BLOCK_stack_get(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ struct stack_st_OPENSSL_BLOCK *arg1 = (struct stack_st_OPENSSL_BLOCK *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ _STACK *result = 0 ;
+
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_stack_st_OPENSSL_BLOCK, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "stack_st_OPENSSL_BLOCK_stack_get" "', argument " "1"" of type '" "struct stack_st_OPENSSL_BLOCK *""'");
+ }
+ arg1 = (struct stack_st_OPENSSL_BLOCK *)(argp1);
+ result = (_STACK *)& ((arg1)->stack);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_stack_st, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN int _wrap_new_stack_st_OPENSSL_BLOCK(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ struct stack_st_OPENSSL_BLOCK *result = 0 ;
+
+ result = (struct stack_st_OPENSSL_BLOCK *)calloc(1, sizeof(struct stack_st_OPENSSL_BLOCK));
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_stack_st_OPENSSL_BLOCK, SWIG_BUILTIN_INIT | 0 );
+ return resultobj == Py_None ? -1 : 0;
+fail:
+ return -1;
+}
+
+
+SWIGINTERN PyObject *_wrap_delete_stack_st_OPENSSL_BLOCK(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ struct stack_st_OPENSSL_BLOCK *arg1 = (struct stack_st_OPENSSL_BLOCK *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_stack_st_OPENSSL_BLOCK, SWIG_POINTER_DISOWN | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_stack_st_OPENSSL_BLOCK" "', argument " "1"" of type '" "struct stack_st_OPENSSL_BLOCK *""'");
+ }
+ arg1 = (struct stack_st_OPENSSL_BLOCK *)(argp1);
+ free((char *) arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_threading_init(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+
+ threading_init();
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_threading_cleanup(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+
+ threading_cleanup();
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_lib_init(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+
+ lib_init();
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bn_to_mpi(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIGNUM *arg1 = (BIGNUM *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"bn_to_mpi",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIGNUM, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bn_to_mpi" "', argument " "1"" of type '" "BIGNUM const *""'");
+ }
+ arg1 = (BIGNUM *)(argp1);
+ result = (PyObject *)bn_to_mpi((BIGNUM const *)arg1);
+ resultobj = result;
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_mpi_to_bn(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ PyObject *arg1 = (PyObject *) 0 ;
+ PyObject * obj0 = 0 ;
+ BIGNUM *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"mpi_to_bn",1,1,&obj0)) SWIG_fail;
+ arg1 = obj0;
+ result = (BIGNUM *)mpi_to_bn(arg1);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_BIGNUM, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bn_to_bin(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIGNUM *arg1 = (BIGNUM *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"bn_to_bin",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIGNUM, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bn_to_bin" "', argument " "1"" of type '" "BIGNUM *""'");
+ }
+ arg1 = (BIGNUM *)(argp1);
+ result = (PyObject *)bn_to_bin(arg1);
+ resultobj = result;
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bin_to_bn(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ PyObject *arg1 = (PyObject *) 0 ;
+ PyObject * obj0 = 0 ;
+ BIGNUM *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"bin_to_bn",1,1,&obj0)) SWIG_fail;
+ arg1 = obj0;
+ result = (BIGNUM *)bin_to_bn(arg1);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_BIGNUM, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bn_to_hex(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIGNUM *arg1 = (BIGNUM *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"bn_to_hex",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIGNUM, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bn_to_hex" "', argument " "1"" of type '" "BIGNUM *""'");
+ }
+ arg1 = (BIGNUM *)(argp1);
+ result = (PyObject *)bn_to_hex(arg1);
+ resultobj = result;
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_hex_to_bn(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ PyObject *arg1 = (PyObject *) 0 ;
+ PyObject * obj0 = 0 ;
+ BIGNUM *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"hex_to_bn",1,1,&obj0)) SWIG_fail;
+ arg1 = obj0;
+ result = (BIGNUM *)hex_to_bn(arg1);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_BIGNUM, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_dec_to_bn(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ PyObject *arg1 = (PyObject *) 0 ;
+ PyObject * obj0 = 0 ;
+ BIGNUM *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"dec_to_bn",1,1,&obj0)) SWIG_fail;
+ arg1 = obj0;
+ result = (BIGNUM *)dec_to_bn(arg1);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_BIGNUM, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_err_print_errors(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"err_print_errors",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "err_print_errors" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ ERR_print_errors(arg1);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_err_get_error(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ unsigned long result;
+
+ result = (unsigned long)ERR_get_error();
+ resultobj = SWIG_From_unsigned_SS_long((unsigned long)(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_err_peek_error(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ unsigned long result;
+
+ result = (unsigned long)ERR_peek_error();
+ resultobj = SWIG_From_unsigned_SS_long((unsigned long)(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_err_lib_error_string(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ unsigned long arg1 ;
+ unsigned long val1 ;
+ int ecode1 = 0 ;
+ PyObject * obj0 = 0 ;
+ char *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"err_lib_error_string",1,1,&obj0)) SWIG_fail;
+ ecode1 = SWIG_AsVal_unsigned_SS_long(obj0, &val1);
+ if (!SWIG_IsOK(ecode1)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "err_lib_error_string" "', argument " "1"" of type '" "unsigned long""'");
+ }
+ arg1 = (unsigned long)(val1);
+ result = (char *)ERR_lib_error_string(arg1);
+ resultobj = SWIG_FromCharPtr((const char *)result);
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_err_func_error_string(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ unsigned long arg1 ;
+ unsigned long val1 ;
+ int ecode1 = 0 ;
+ PyObject * obj0 = 0 ;
+ char *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"err_func_error_string",1,1,&obj0)) SWIG_fail;
+ ecode1 = SWIG_AsVal_unsigned_SS_long(obj0, &val1);
+ if (!SWIG_IsOK(ecode1)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "err_func_error_string" "', argument " "1"" of type '" "unsigned long""'");
+ }
+ arg1 = (unsigned long)(val1);
+ result = (char *)ERR_func_error_string(arg1);
+ resultobj = SWIG_FromCharPtr((const char *)result);
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_err_reason_error_string(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ unsigned long arg1 ;
+ unsigned long val1 ;
+ int ecode1 = 0 ;
+ PyObject * obj0 = 0 ;
+ char *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"err_reason_error_string",1,1,&obj0)) SWIG_fail;
+ ecode1 = SWIG_AsVal_unsigned_SS_long(obj0, &val1);
+ if (!SWIG_IsOK(ecode1)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "err_reason_error_string" "', argument " "1"" of type '" "unsigned long""'");
+ }
+ arg1 = (unsigned long)(val1);
+ result = (char *)ERR_reason_error_string(arg1);
+ resultobj = SWIG_FromCharPtr((const char *)result);
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bio_s_bio(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO_METHOD *result = 0 ;
+
+ result = (BIO_METHOD *)BIO_s_bio();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_BIO_METHOD, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bio_s_mem(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO_METHOD *result = 0 ;
+
+ result = (BIO_METHOD *)BIO_s_mem();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_BIO_METHOD, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bio_s_socket(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO_METHOD *result = 0 ;
+
+ result = (BIO_METHOD *)BIO_s_socket();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_BIO_METHOD, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bio_f_ssl(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO_METHOD *result = 0 ;
+
+ result = (BIO_METHOD *)BIO_f_ssl();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_BIO_METHOD, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bio_f_buffer(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO_METHOD *result = 0 ;
+
+ result = (BIO_METHOD *)BIO_f_buffer();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_BIO_METHOD, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bio_f_cipher(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO_METHOD *result = 0 ;
+
+ result = (BIO_METHOD *)BIO_f_cipher();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_BIO_METHOD, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bio_new(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO_METHOD *arg1 = (BIO_METHOD *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ BIO *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"bio_new",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO_METHOD, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bio_new" "', argument " "1"" of type '" "BIO_METHOD *""'");
+ }
+ arg1 = (BIO_METHOD *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (BIO *)BIO_new(arg1);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_BIO, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bio_new_socket(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ int arg1 ;
+ int arg2 ;
+ int val1 ;
+ int ecode1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ BIO *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"bio_new_socket",2,2,&obj0,&obj1)) SWIG_fail;
+ ecode1 = SWIG_AsVal_int(obj0, &val1);
+ if (!SWIG_IsOK(ecode1)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "bio_new_socket" "', argument " "1"" of type '" "int""'");
+ }
+ arg1 = (int)(val1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "bio_new_socket" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ result = (BIO *)BIO_new_socket(arg1,arg2);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_BIO, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bio_free_all(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"bio_free_all",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bio_free_all" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ BIO_free_all(arg1);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bio_dup_chain(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ BIO *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"bio_dup_chain",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bio_dup_chain" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (BIO *)BIO_dup_chain(arg1);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_BIO, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bio_push(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ BIO *arg2 = (BIO *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ BIO *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"bio_push",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bio_push" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "bio_push" "', argument " "2"" of type '" "BIO *""'");
+ }
+ arg2 = (BIO *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (BIO *)BIO_push(arg1,arg2);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_BIO, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bio_pop(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ BIO *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"bio_pop",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bio_pop" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (BIO *)BIO_pop(arg1);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_BIO, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bio_eof(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"bio_eof",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bio_eof" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)BIO_eof(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN int Swig_var__bio_err_set(PyObject *_val) {
+ {
+ void *argp = 0;
+ int res = SWIG_ConvertPtr(_val, &argp, SWIGTYPE_p_PyObject, 0 );
+ if (!SWIG_IsOK(res)) {
+ SWIG_exception_fail(SWIG_ArgError(res), "in variable '""_bio_err""' of type '""PyObject *""'");
+ }
+ _bio_err = (PyObject *)(argp);
+ }
+ return 0;
+fail:
+ return 1;
+}
+
+
+SWIGINTERN PyObject *Swig_var__bio_err_get(void) {
+ PyObject *pyobj = 0;
+ PyObject *self = 0;
+
+ (void)self;
+ pyobj = SWIG_NewPointerObj(SWIG_as_voidptr(_bio_err), SWIGTYPE_p_PyObject, 0 );
+ return pyobj;
+}
+
+
+SWIGINTERN PyObject *_wrap_pyfd_init(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+
+ pyfd_init();
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bio_init(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ PyObject *arg1 = (PyObject *) 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"bio_init",1,1,&obj0)) SWIG_fail;
+ {
+ arg1=obj0;
+ }
+ bio_init(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bio_free(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"bio_free",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bio_free" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)bio_free(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bio_new_file(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ char *arg1 = (char *) 0 ;
+ char *arg2 = (char *) 0 ;
+ int res1 ;
+ char *buf1 = 0 ;
+ int alloc1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ int alloc2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ BIO *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"bio_new_file",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bio_new_file" "', argument " "1"" of type '" "char const *""'");
+ }
+ arg1 = (char *)(buf1);
+ res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "bio_new_file" "', argument " "2"" of type '" "char const *""'");
+ }
+ arg2 = (char *)(buf2);
+ result = (BIO *)bio_new_file((char const *)arg1,(char const *)arg2);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_BIO, 0 | 0 );
+ if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return resultobj;
+fail:
+ if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bio_new_pyfile(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ PyObject *arg1 = (PyObject *) 0 ;
+ int arg2 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ BIO *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"bio_new_pyfile",2,2,&obj0,&obj1)) SWIG_fail;
+ {
+ arg1=obj0;
+ }
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "bio_new_pyfile" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ result = (BIO *)bio_new_pyfile(arg1,arg2);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_BIO, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bio_read(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ int arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"bio_read",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bio_read" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "bio_read" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)bio_read(arg1,arg2);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bio_gets(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ int arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"bio_gets",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bio_gets" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "bio_gets" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)bio_gets(arg1,arg2);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bio_write(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"bio_write",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bio_write" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ {
+ arg2=obj1;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)bio_write(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bio_ctrl_pending(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"bio_ctrl_pending",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bio_ctrl_pending" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)bio_ctrl_pending(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bio_ctrl_wpending(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"bio_ctrl_wpending",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bio_ctrl_wpending" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)bio_ctrl_wpending(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bio_ctrl_get_write_guarantee(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"bio_ctrl_get_write_guarantee",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bio_ctrl_get_write_guarantee" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)bio_ctrl_get_write_guarantee(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bio_reset(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"bio_reset",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bio_reset" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)bio_reset(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bio_flush(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"bio_flush",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bio_flush" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ result = (int)bio_flush(arg1);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bio_seek(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ int arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"bio_seek",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bio_seek" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "bio_seek" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)bio_seek(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bio_tell(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"bio_tell",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bio_tell" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)bio_tell(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bio_set_flags(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ int arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"bio_set_flags",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bio_set_flags" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "bio_set_flags" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ bio_set_flags(arg1,arg2);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bio_get_flags(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"bio_get_flags",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bio_get_flags" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)bio_get_flags(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bio_set_cipher(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ EVP_CIPHER *arg2 = (EVP_CIPHER *) 0 ;
+ PyObject *arg3 = (PyObject *) 0 ;
+ PyObject *arg4 = (PyObject *) 0 ;
+ int arg5 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ int val5 ;
+ int ecode5 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject * obj3 = 0 ;
+ PyObject * obj4 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"bio_set_cipher",5,5,&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bio_set_cipher" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_EVP_CIPHER, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "bio_set_cipher" "', argument " "2"" of type '" "EVP_CIPHER *""'");
+ }
+ arg2 = (EVP_CIPHER *)(argp2);
+ {
+ arg3=obj2;
+ }
+ {
+ arg4=obj3;
+ }
+ ecode5 = SWIG_AsVal_int(obj4, &val5);
+ if (!SWIG_IsOK(ecode5)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "bio_set_cipher" "', argument " "5"" of type '" "int""'");
+ }
+ arg5 = (int)(val5);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)bio_set_cipher(arg1,arg2,arg3,arg4,arg5);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bio_set_mem_eof_return(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ int arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"bio_set_mem_eof_return",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bio_set_mem_eof_return" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "bio_set_mem_eof_return" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)bio_set_mem_eof_return(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bio_get_fd(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"bio_get_fd",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bio_get_fd" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)bio_get_fd(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bio_do_handshake(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"bio_do_handshake",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bio_do_handshake" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ result = (int)bio_do_handshake(arg1);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bio_make_bio_pair(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ BIO *arg2 = (BIO *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"bio_make_bio_pair",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bio_make_bio_pair" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "bio_make_bio_pair" "', argument " "2"" of type '" "BIO *""'");
+ }
+ arg2 = (BIO *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)bio_make_bio_pair(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bio_set_write_buf_size(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ size_t arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ size_t val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"bio_set_write_buf_size",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bio_set_write_buf_size" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ ecode2 = SWIG_AsVal_size_t(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "bio_set_write_buf_size" "', argument " "2"" of type '" "size_t""'");
+ }
+ arg2 = (size_t)(val2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)bio_set_write_buf_size(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bio_should_retry(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"bio_should_retry",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bio_should_retry" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)bio_should_retry(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bio_should_read(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"bio_should_read",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bio_should_read" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)bio_should_read(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bio_should_write(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"bio_should_write",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bio_should_write" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)bio_should_write(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_BIO_meth_new(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ int arg1 ;
+ char *arg2 = (char *) 0 ;
+ int val1 ;
+ int ecode1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ int alloc2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ BIO_METHOD *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"BIO_meth_new",2,2,&obj0,&obj1)) SWIG_fail;
+ ecode1 = SWIG_AsVal_int(obj0, &val1);
+ if (!SWIG_IsOK(ecode1)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "BIO_meth_new" "', argument " "1"" of type '" "int""'");
+ }
+ arg1 = (int)(val1);
+ res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "BIO_meth_new" "', argument " "2"" of type '" "char const *""'");
+ }
+ arg2 = (char *)(buf2);
+ result = (BIO_METHOD *)BIO_meth_new(arg1,(char const *)arg2);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_BIO_METHOD, 0 | 0 );
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return resultobj;
+fail:
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_BIO_meth_free(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO_METHOD *arg1 = (BIO_METHOD *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"BIO_meth_free",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO_METHOD, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "BIO_meth_free" "', argument " "1"" of type '" "BIO_METHOD *""'");
+ }
+ arg1 = (BIO_METHOD *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ BIO_meth_free(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_BIO_PYFD_CTX_fd_set(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ struct pyfd_struct *arg1 = (struct pyfd_struct *) 0 ;
+ int arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj1 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"BIO_PYFD_CTX_fd_set",1,1,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_pyfd_struct, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "BIO_PYFD_CTX_fd_set" "', argument " "1"" of type '" "struct pyfd_struct *""'");
+ }
+ arg1 = (struct pyfd_struct *)(argp1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "BIO_PYFD_CTX_fd_set" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ if (arg1) (arg1)->fd = arg2;
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_BIO_PYFD_CTX_fd_get(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ struct pyfd_struct *arg1 = (struct pyfd_struct *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int result;
+
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_pyfd_struct, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "BIO_PYFD_CTX_fd_get" "', argument " "1"" of type '" "struct pyfd_struct *""'");
+ }
+ arg1 = (struct pyfd_struct *)(argp1);
+ result = (int) ((arg1)->fd);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN int _wrap_new_BIO_PYFD_CTX(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ struct pyfd_struct *result = 0 ;
+
+ result = (struct pyfd_struct *)calloc(1, sizeof(struct pyfd_struct));
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_pyfd_struct, SWIG_BUILTIN_INIT | 0 );
+ return resultobj == Py_None ? -1 : 0;
+fail:
+ return -1;
+}
+
+
+SWIGINTERN PyObject *_wrap_delete_BIO_PYFD_CTX(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ struct pyfd_struct *arg1 = (struct pyfd_struct *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_pyfd_struct, SWIG_POINTER_DISOWN | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_BIO_PYFD_CTX" "', argument " "1"" of type '" "struct pyfd_struct *""'");
+ }
+ arg1 = (struct pyfd_struct *)(argp1);
+ free((char *) arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN int Swig_var_methods_fdp_set(PyObject *_val) {
+ {
+ void *argp = 0;
+ int res = SWIG_ConvertPtr(_val, &argp, SWIGTYPE_p_BIO_METHOD, 0 );
+ if (!SWIG_IsOK(res)) {
+ SWIG_exception_fail(SWIG_ArgError(res), "in variable '""methods_fdp""' of type '""BIO_METHOD *""'");
+ }
+ methods_fdp = (BIO_METHOD *)(argp);
+ }
+ return 0;
+fail:
+ return 1;
+}
+
+
+SWIGINTERN PyObject *Swig_var_methods_fdp_get(void) {
+ PyObject *pyobj = 0;
+ PyObject *self = 0;
+
+ (void)self;
+ pyobj = SWIG_NewPointerObj(SWIG_as_voidptr(methods_fdp), SWIGTYPE_p_BIO_METHOD, 0 );
+ return pyobj;
+}
+
+
+SWIGINTERN PyObject *_wrap_pyfd_write(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ char *arg2 = (char *) 0 ;
+ int arg3 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ int alloc2 = 0 ;
+ int val3 ;
+ int ecode3 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"pyfd_write",3,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "pyfd_write" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "pyfd_write" "', argument " "2"" of type '" "char const *""'");
+ }
+ arg2 = (char *)(buf2);
+ ecode3 = SWIG_AsVal_int(obj2, &val3);
+ if (!SWIG_IsOK(ecode3)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "pyfd_write" "', argument " "3"" of type '" "int""'");
+ }
+ arg3 = (int)(val3);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)pyfd_write(arg1,(char const *)arg2,arg3);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return resultobj;
+fail:
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_pyfd_read(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ char *arg2 = (char *) 0 ;
+ int arg3 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ int alloc2 = 0 ;
+ int val3 ;
+ int ecode3 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"pyfd_read",3,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "pyfd_read" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "pyfd_read" "', argument " "2"" of type '" "char *""'");
+ }
+ arg2 = (char *)(buf2);
+ ecode3 = SWIG_AsVal_int(obj2, &val3);
+ if (!SWIG_IsOK(ecode3)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "pyfd_read" "', argument " "3"" of type '" "int""'");
+ }
+ arg3 = (int)(val3);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)pyfd_read(arg1,arg2,arg3);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return resultobj;
+fail:
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_pyfd_puts(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ char *arg2 = (char *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ int alloc2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"pyfd_puts",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "pyfd_puts" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "pyfd_puts" "', argument " "2"" of type '" "char const *""'");
+ }
+ arg2 = (char *)(buf2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)pyfd_puts(arg1,(char const *)arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return resultobj;
+fail:
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_pyfd_gets(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ char *arg2 = (char *) 0 ;
+ int arg3 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ int alloc2 = 0 ;
+ int val3 ;
+ int ecode3 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"pyfd_gets",3,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "pyfd_gets" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "pyfd_gets" "', argument " "2"" of type '" "char *""'");
+ }
+ arg2 = (char *)(buf2);
+ ecode3 = SWIG_AsVal_int(obj2, &val3);
+ if (!SWIG_IsOK(ecode3)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "pyfd_gets" "', argument " "3"" of type '" "int""'");
+ }
+ arg3 = (int)(val3);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)pyfd_gets(arg1,arg2,arg3);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return resultobj;
+fail:
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_pyfd_new(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"pyfd_new",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "pyfd_new" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)pyfd_new(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_pyfd_free(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"pyfd_free",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "pyfd_free" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)pyfd_free(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_pyfd_ctrl(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ int arg2 ;
+ long arg3 ;
+ void *arg4 = (void *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ long val3 ;
+ int ecode3 = 0 ;
+ int res4 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject * obj3 = 0 ;
+ long result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"pyfd_ctrl",4,4,&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "pyfd_ctrl" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "pyfd_ctrl" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ ecode3 = SWIG_AsVal_long(obj2, &val3);
+ if (!SWIG_IsOK(ecode3)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "pyfd_ctrl" "', argument " "3"" of type '" "long""'");
+ }
+ arg3 = (long)(val3);
+ res4 = SWIG_ConvertPtr(obj3,SWIG_as_voidptrptr(&arg4), 0, 0);
+ if (!SWIG_IsOK(res4)) {
+ SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "pyfd_ctrl" "', argument " "4"" of type '" "void *""'");
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (long)pyfd_ctrl(arg1,arg2,arg3,arg4);
+ resultobj = SWIG_From_long((long)(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bio_new_pyfd(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ int arg1 ;
+ int arg2 ;
+ int val1 ;
+ int ecode1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ BIO *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"bio_new_pyfd",2,2,&obj0,&obj1)) SWIG_fail;
+ ecode1 = SWIG_AsVal_int(obj0, &val1);
+ if (!SWIG_IsOK(ecode1)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "bio_new_pyfd" "', argument " "1"" of type '" "int""'");
+ }
+ arg1 = (int)(val1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "bio_new_pyfd" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ result = (BIO *)BIO_new_pyfd(arg1,arg2);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_BIO, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bn_rand(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ int arg1 ;
+ int arg2 ;
+ int arg3 ;
+ int val1 ;
+ int ecode1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ int val3 ;
+ int ecode3 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"bn_rand",3,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ ecode1 = SWIG_AsVal_int(obj0, &val1);
+ if (!SWIG_IsOK(ecode1)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "bn_rand" "', argument " "1"" of type '" "int""'");
+ }
+ arg1 = (int)(val1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "bn_rand" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ ecode3 = SWIG_AsVal_int(obj2, &val3);
+ if (!SWIG_IsOK(ecode3)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "bn_rand" "', argument " "3"" of type '" "int""'");
+ }
+ arg3 = (int)(val3);
+ result = (PyObject *)bn_rand(arg1,arg2,arg3);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bn_rand_range(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ PyObject *arg1 = (PyObject *) 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"bn_rand_range",1,1,&obj0)) SWIG_fail;
+ {
+ arg1=obj0;
+ }
+ result = (PyObject *)bn_rand_range(arg1);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rand_file_name__SWIG_0(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ char *arg1 = (char *) 0 ;
+ size_t arg2 ;
+ int res1 ;
+ char *buf1 = 0 ;
+ int alloc1 = 0 ;
+ size_t val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ char *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"rand_file_name",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "rand_file_name" "', argument " "1"" of type '" "char *""'");
+ }
+ arg1 = (char *)(buf1);
+ ecode2 = SWIG_AsVal_size_t(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "rand_file_name" "', argument " "2"" of type '" "size_t""'");
+ }
+ arg2 = (size_t)(val2);
+ result = (char *)RAND_file_name(arg1,arg2);
+ resultobj = SWIG_FromCharPtr((const char *)result);
+ if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
+ return resultobj;
+fail:
+ if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rand_load_file(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ char *arg1 = (char *) 0 ;
+ long arg2 ;
+ int res1 ;
+ char *buf1 = 0 ;
+ int alloc1 = 0 ;
+ long val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"rand_load_file",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "rand_load_file" "', argument " "1"" of type '" "char const *""'");
+ }
+ arg1 = (char *)(buf1);
+ ecode2 = SWIG_AsVal_long(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "rand_load_file" "', argument " "2"" of type '" "long""'");
+ }
+ arg2 = (long)(val2);
+ result = (int)RAND_load_file((char const *)arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
+ return resultobj;
+fail:
+ if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rand_save_file(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ char *arg1 = (char *) 0 ;
+ int res1 ;
+ char *buf1 = 0 ;
+ int alloc1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"rand_save_file",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "rand_save_file" "', argument " "1"" of type '" "char const *""'");
+ }
+ arg1 = (char *)(buf1);
+ result = (int)RAND_write_file((char const *)arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
+ return resultobj;
+fail:
+ if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rand_poll(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ int result;
+
+ result = (int)RAND_poll();
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rand_status(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ int result;
+
+ result = (int)RAND_status();
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rand_cleanup(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+
+ RAND_cleanup();
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN int Swig_var__rand_err_set(PyObject *_val) {
+ {
+ void *argp = 0;
+ int res = SWIG_ConvertPtr(_val, &argp, SWIGTYPE_p_PyObject, 0 );
+ if (!SWIG_IsOK(res)) {
+ SWIG_exception_fail(SWIG_ArgError(res), "in variable '""_rand_err""' of type '""PyObject *""'");
+ }
+ _rand_err = (PyObject *)(argp);
+ }
+ return 0;
+fail:
+ return 1;
+}
+
+
+SWIGINTERN PyObject *Swig_var__rand_err_get(void) {
+ PyObject *pyobj = 0;
+ PyObject *self = 0;
+
+ (void)self;
+ pyobj = SWIG_NewPointerObj(SWIG_as_voidptr(_rand_err), SWIGTYPE_p_PyObject, 0 );
+ return pyobj;
+}
+
+
+SWIGINTERN PyObject *_wrap_rand_init(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ PyObject *arg1 = (PyObject *) 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"rand_init",1,1,&obj0)) SWIG_fail;
+ {
+ arg1=obj0;
+ }
+ rand_init(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rand_seed(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ PyObject *arg1 = (PyObject *) 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"rand_seed",1,1,&obj0)) SWIG_fail;
+ {
+ arg1=obj0;
+ }
+ result = (PyObject *)rand_seed(arg1);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rand_add(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ PyObject *arg1 = (PyObject *) 0 ;
+ double arg2 ;
+ double val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"rand_add",2,2,&obj0,&obj1)) SWIG_fail;
+ {
+ arg1=obj0;
+ }
+ ecode2 = SWIG_AsVal_double(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "rand_add" "', argument " "2"" of type '" "double""'");
+ }
+ arg2 = (double)(val2);
+ result = (PyObject *)rand_add(arg1,arg2);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rand_bytes(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ int arg1 ;
+ int val1 ;
+ int ecode1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"rand_bytes",1,1,&obj0)) SWIG_fail;
+ ecode1 = SWIG_AsVal_int(obj0, &val1);
+ if (!SWIG_IsOK(ecode1)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "rand_bytes" "', argument " "1"" of type '" "int""'");
+ }
+ arg1 = (int)(val1);
+ result = (PyObject *)rand_bytes(arg1);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rand_pseudo_bytes(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ int arg1 ;
+ int val1 ;
+ int ecode1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"rand_pseudo_bytes",1,1,&obj0)) SWIG_fail;
+ ecode1 = SWIG_AsVal_int(obj0, &val1);
+ if (!SWIG_IsOK(ecode1)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "rand_pseudo_bytes" "', argument " "1"" of type '" "int""'");
+ }
+ arg1 = (int)(val1);
+ result = (PyObject *)rand_pseudo_bytes(arg1);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rand_file_name__SWIG_1(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ PyObject *result = 0 ;
+
+ result = (PyObject *)rand_file_name();
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rand_file_name(PyObject *self, PyObject *args) {
+ int argc;
+ PyObject *argv[3];
+ int ii;
+
+ if (!PyTuple_Check(args)) SWIG_fail;
+ argc = args ? (int)PyObject_Length(args) : 0;
+ for (ii = 0; (ii < 2) && (ii < argc); ii++) {
+ argv[ii] = PyTuple_GET_ITEM(args,ii);
+ }
+ if (argc == 0) {
+ return _wrap_rand_file_name__SWIG_1(self, args);
+ }
+ if (argc == 2) {
+ int _v;
+ int res = SWIG_AsCharPtrAndSize(argv[0], 0, NULL, 0);
+ _v = SWIG_CheckState(res);
+ if (_v) {
+ {
+ int res = SWIG_AsVal_size_t(argv[1], NULL);
+ _v = SWIG_CheckState(res);
+ }
+ if (_v) {
+ return _wrap_rand_file_name__SWIG_0(self, args);
+ }
+ }
+ }
+
+fail:
+ SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'rand_file_name'.\n"
+ " Possible C/C++ prototypes are:\n"
+ " RAND_file_name(char *,size_t)\n"
+ " rand_file_name()\n");
+ return 0;
+}
+
+
+SWIGINTERN PyObject *_wrap_rand_screen(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+
+ rand_screen();
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rand_win32_event(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ unsigned int arg1 ;
+ int arg2 ;
+ long arg3 ;
+ unsigned int val1 ;
+ int ecode1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ long val3 ;
+ int ecode3 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"rand_win32_event",3,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ ecode1 = SWIG_AsVal_unsigned_SS_int(obj0, &val1);
+ if (!SWIG_IsOK(ecode1)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "rand_win32_event" "', argument " "1"" of type '" "unsigned int""'");
+ }
+ arg1 = (unsigned int)(val1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "rand_win32_event" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ ecode3 = SWIG_AsVal_long(obj2, &val3);
+ if (!SWIG_IsOK(ecode3)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "rand_win32_event" "', argument " "3"" of type '" "long""'");
+ }
+ arg3 = (long)(val3);
+ result = (int)rand_win32_event(arg1,arg2,arg3);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_md5(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_MD *result = 0 ;
+
+ result = (EVP_MD *)EVP_md5();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_MD, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_sha1(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_MD *result = 0 ;
+
+ result = (EVP_MD *)EVP_sha1();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_MD, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ripemd160(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_MD *result = 0 ;
+
+ result = (EVP_MD *)EVP_ripemd160();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_MD, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_sha224(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_MD *result = 0 ;
+
+ result = (EVP_MD *)EVP_sha224();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_MD, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_sha256(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_MD *result = 0 ;
+
+ result = (EVP_MD *)EVP_sha256();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_MD, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_sha384(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_MD *result = 0 ;
+
+ result = (EVP_MD *)EVP_sha384();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_MD, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_sha512(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_MD *result = 0 ;
+
+ result = (EVP_MD *)EVP_sha512();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_MD, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_digest_init(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_MD_CTX *arg1 = (EVP_MD_CTX *) 0 ;
+ EVP_MD *arg2 = (EVP_MD *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"digest_init",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_EVP_MD_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "digest_init" "', argument " "1"" of type '" "EVP_MD_CTX *""'");
+ }
+ arg1 = (EVP_MD_CTX *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_EVP_MD, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "digest_init" "', argument " "2"" of type '" "EVP_MD const *""'");
+ }
+ arg2 = (EVP_MD *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)EVP_DigestInit(arg1,(EVP_MD const *)arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_des_ecb(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_CIPHER *result = 0 ;
+
+ result = (EVP_CIPHER *)EVP_des_ecb();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_CIPHER, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_des_ede_ecb(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_CIPHER *result = 0 ;
+
+ result = (EVP_CIPHER *)EVP_des_ede();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_CIPHER, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_des_ede3_ecb(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_CIPHER *result = 0 ;
+
+ result = (EVP_CIPHER *)EVP_des_ede3();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_CIPHER, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_des_cbc(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_CIPHER *result = 0 ;
+
+ result = (EVP_CIPHER *)EVP_des_cbc();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_CIPHER, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_des_ede_cbc(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_CIPHER *result = 0 ;
+
+ result = (EVP_CIPHER *)EVP_des_ede_cbc();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_CIPHER, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_des_ede3_cbc(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_CIPHER *result = 0 ;
+
+ result = (EVP_CIPHER *)EVP_des_ede3_cbc();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_CIPHER, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_des_cfb(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_CIPHER *result = 0 ;
+
+ result = (EVP_CIPHER *)EVP_des_cfb();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_CIPHER, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_des_ede_cfb(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_CIPHER *result = 0 ;
+
+ result = (EVP_CIPHER *)EVP_des_ede_cfb();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_CIPHER, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_des_ede3_cfb(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_CIPHER *result = 0 ;
+
+ result = (EVP_CIPHER *)EVP_des_ede3_cfb();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_CIPHER, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_des_ofb(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_CIPHER *result = 0 ;
+
+ result = (EVP_CIPHER *)EVP_des_ofb();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_CIPHER, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_des_ede_ofb(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_CIPHER *result = 0 ;
+
+ result = (EVP_CIPHER *)EVP_des_ede_ofb();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_CIPHER, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_des_ede3_ofb(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_CIPHER *result = 0 ;
+
+ result = (EVP_CIPHER *)EVP_des_ede3_ofb();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_CIPHER, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bf_ecb(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_CIPHER *result = 0 ;
+
+ result = (EVP_CIPHER *)EVP_bf_ecb();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_CIPHER, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bf_cbc(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_CIPHER *result = 0 ;
+
+ result = (EVP_CIPHER *)EVP_bf_cbc();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_CIPHER, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bf_cfb(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_CIPHER *result = 0 ;
+
+ result = (EVP_CIPHER *)EVP_bf_cfb();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_CIPHER, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bf_ofb(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_CIPHER *result = 0 ;
+
+ result = (EVP_CIPHER *)EVP_bf_ofb();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_CIPHER, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_cast5_ecb(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_CIPHER *result = 0 ;
+
+ result = (EVP_CIPHER *)EVP_cast5_ecb();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_CIPHER, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_cast5_cbc(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_CIPHER *result = 0 ;
+
+ result = (EVP_CIPHER *)EVP_cast5_cbc();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_CIPHER, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_cast5_cfb(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_CIPHER *result = 0 ;
+
+ result = (EVP_CIPHER *)EVP_cast5_cfb();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_CIPHER, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_cast5_ofb(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_CIPHER *result = 0 ;
+
+ result = (EVP_CIPHER *)EVP_cast5_ofb();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_CIPHER, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rc4(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_CIPHER *result = 0 ;
+
+ result = (EVP_CIPHER *)EVP_rc4();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_CIPHER, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rc2_40_cbc(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_CIPHER *result = 0 ;
+
+ result = (EVP_CIPHER *)EVP_rc2_40_cbc();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_CIPHER, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_aes_128_ecb(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_CIPHER *result = 0 ;
+
+ result = (EVP_CIPHER *)EVP_aes_128_ecb();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_CIPHER, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_aes_128_cbc(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_CIPHER *result = 0 ;
+
+ result = (EVP_CIPHER *)EVP_aes_128_cbc();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_CIPHER, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_aes_128_cfb(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_CIPHER *result = 0 ;
+
+ result = (EVP_CIPHER *)EVP_aes_128_cfb();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_CIPHER, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_aes_128_ofb(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_CIPHER *result = 0 ;
+
+ result = (EVP_CIPHER *)EVP_aes_128_ofb();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_CIPHER, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_aes_128_ctr(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_CIPHER *result = 0 ;
+
+ result = (EVP_CIPHER *)EVP_aes_128_ctr();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_CIPHER, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_aes_192_ecb(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_CIPHER *result = 0 ;
+
+ result = (EVP_CIPHER *)EVP_aes_192_ecb();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_CIPHER, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_aes_192_cbc(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_CIPHER *result = 0 ;
+
+ result = (EVP_CIPHER *)EVP_aes_192_cbc();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_CIPHER, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_aes_192_cfb(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_CIPHER *result = 0 ;
+
+ result = (EVP_CIPHER *)EVP_aes_192_cfb();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_CIPHER, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_aes_192_ofb(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_CIPHER *result = 0 ;
+
+ result = (EVP_CIPHER *)EVP_aes_192_ofb();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_CIPHER, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_aes_192_ctr(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_CIPHER *result = 0 ;
+
+ result = (EVP_CIPHER *)EVP_aes_192_ctr();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_CIPHER, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_aes_256_ecb(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_CIPHER *result = 0 ;
+
+ result = (EVP_CIPHER *)EVP_aes_256_ecb();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_CIPHER, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_aes_256_cbc(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_CIPHER *result = 0 ;
+
+ result = (EVP_CIPHER *)EVP_aes_256_cbc();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_CIPHER, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_aes_256_cfb(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_CIPHER *result = 0 ;
+
+ result = (EVP_CIPHER *)EVP_aes_256_cfb();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_CIPHER, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_aes_256_ofb(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_CIPHER *result = 0 ;
+
+ result = (EVP_CIPHER *)EVP_aes_256_ofb();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_CIPHER, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_aes_256_ctr(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_CIPHER *result = 0 ;
+
+ result = (EVP_CIPHER *)EVP_aes_256_ctr();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_CIPHER, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_cipher_set_padding(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_CIPHER_CTX *arg1 = (EVP_CIPHER_CTX *) 0 ;
+ int arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"cipher_set_padding",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_EVP_CIPHER_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "cipher_set_padding" "', argument " "1"" of type '" "EVP_CIPHER_CTX *""'");
+ }
+ arg1 = (EVP_CIPHER_CTX *)(argp1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "cipher_set_padding" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)EVP_CIPHER_CTX_set_padding(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_pkey_free(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_PKEY *arg1 = (EVP_PKEY *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"pkey_free",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_EVP_PKEY, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "pkey_free" "', argument " "1"" of type '" "EVP_PKEY *""'");
+ }
+ arg1 = (EVP_PKEY *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ EVP_PKEY_free(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_pkey_assign(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_PKEY *arg1 = (EVP_PKEY *) 0 ;
+ int arg2 ;
+ char *arg3 = (char *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ int res3 ;
+ char *buf3 = 0 ;
+ int alloc3 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"pkey_assign",3,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_EVP_PKEY, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "pkey_assign" "', argument " "1"" of type '" "EVP_PKEY *""'");
+ }
+ arg1 = (EVP_PKEY *)(argp1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "pkey_assign" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ res3 = SWIG_AsCharPtrAndSize(obj2, &buf3, NULL, &alloc3);
+ if (!SWIG_IsOK(res3)) {
+ SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "pkey_assign" "', argument " "3"" of type '" "char *""'");
+ }
+ arg3 = (char *)(buf3);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)EVP_PKEY_assign(arg1,arg2,arg3);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ if (alloc3 == SWIG_NEWOBJ) free((char*)buf3);
+ return resultobj;
+fail:
+ if (alloc3 == SWIG_NEWOBJ) free((char*)buf3);
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_pkey_assign_ec(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_PKEY *arg1 = (EVP_PKEY *) 0 ;
+ EC_KEY *arg2 = (EC_KEY *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"pkey_assign_ec",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_EVP_PKEY, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "pkey_assign_ec" "', argument " "1"" of type '" "EVP_PKEY *""'");
+ }
+ arg1 = (EVP_PKEY *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_EC_KEY, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "pkey_assign_ec" "', argument " "2"" of type '" "EC_KEY *""'");
+ }
+ arg2 = (EC_KEY *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)EVP_PKEY_assign_EC_KEY(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_pkey_set1_rsa(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_PKEY *arg1 = (EVP_PKEY *) 0 ;
+ RSA *arg2 = (RSA *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"pkey_set1_rsa",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_EVP_PKEY, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "pkey_set1_rsa" "', argument " "1"" of type '" "EVP_PKEY *""'");
+ }
+ arg1 = (EVP_PKEY *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_RSA, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "pkey_set1_rsa" "', argument " "2"" of type '" "RSA *""'");
+ }
+ arg2 = (RSA *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)EVP_PKEY_set1_RSA(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_sign_init(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_MD_CTX *arg1 = (EVP_MD_CTX *) 0 ;
+ EVP_MD *arg2 = (EVP_MD *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"sign_init",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_EVP_MD_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "sign_init" "', argument " "1"" of type '" "EVP_MD_CTX *""'");
+ }
+ arg1 = (EVP_MD_CTX *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_EVP_MD, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "sign_init" "', argument " "2"" of type '" "EVP_MD const *""'");
+ }
+ arg2 = (EVP_MD *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)EVP_SignInit(arg1,(EVP_MD const *)arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_verify_init(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_MD_CTX *arg1 = (EVP_MD_CTX *) 0 ;
+ EVP_MD *arg2 = (EVP_MD *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"verify_init",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_EVP_MD_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "verify_init" "', argument " "1"" of type '" "EVP_MD_CTX *""'");
+ }
+ arg1 = (EVP_MD_CTX *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_EVP_MD, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "verify_init" "', argument " "2"" of type '" "EVP_MD const *""'");
+ }
+ arg2 = (EVP_MD *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)EVP_VerifyInit(arg1,(EVP_MD const *)arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_pkey_size(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_PKEY *arg1 = (EVP_PKEY *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"pkey_size",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_EVP_PKEY, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "pkey_size" "', argument " "1"" of type '" "EVP_PKEY *""'");
+ }
+ arg1 = (EVP_PKEY *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)EVP_PKEY_size(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN int Swig_var__evp_err_set(PyObject *_val) {
+ {
+ void *argp = 0;
+ int res = SWIG_ConvertPtr(_val, &argp, SWIGTYPE_p_PyObject, 0 );
+ if (!SWIG_IsOK(res)) {
+ SWIG_exception_fail(SWIG_ArgError(res), "in variable '""_evp_err""' of type '""PyObject *""'");
+ }
+ _evp_err = (PyObject *)(argp);
+ }
+ return 0;
+fail:
+ return 1;
+}
+
+
+SWIGINTERN PyObject *Swig_var__evp_err_get(void) {
+ PyObject *pyobj = 0;
+ PyObject *self = 0;
+
+ (void)self;
+ pyobj = SWIG_NewPointerObj(SWIG_as_voidptr(_evp_err), SWIGTYPE_p_PyObject, 0 );
+ return pyobj;
+}
+
+
+SWIGINTERN PyObject *_wrap_evp_init(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ PyObject *arg1 = (PyObject *) 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"evp_init",1,1,&obj0)) SWIG_fail;
+ {
+ arg1=obj0;
+ }
+ evp_init(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_pkey_get1_rsa(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_PKEY *arg1 = (EVP_PKEY *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ RSA *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"pkey_get1_rsa",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_EVP_PKEY, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "pkey_get1_rsa" "', argument " "1"" of type '" "EVP_PKEY *""'");
+ }
+ arg1 = (EVP_PKEY *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (RSA *)pkey_get1_rsa(arg1);
+ {
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+
+ if (result != NULL)
+ resultobj = SWIG_NewPointerObj(result, SWIGTYPE_p_RSA, 0);
+ else {
+ resultobj = NULL;
+ }
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_pkcs5_pbkdf2_hmac_sha1(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ PyObject *arg1 = (PyObject *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ int arg3 ;
+ int arg4 ;
+ int val3 ;
+ int ecode3 = 0 ;
+ int val4 ;
+ int ecode4 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject * obj3 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"pkcs5_pbkdf2_hmac_sha1",4,4,&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
+ {
+ arg1=obj0;
+ }
+ {
+ arg2=obj1;
+ }
+ ecode3 = SWIG_AsVal_int(obj2, &val3);
+ if (!SWIG_IsOK(ecode3)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "pkcs5_pbkdf2_hmac_sha1" "', argument " "3"" of type '" "int""'");
+ }
+ arg3 = (int)(val3);
+ ecode4 = SWIG_AsVal_int(obj3, &val4);
+ if (!SWIG_IsOK(ecode4)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "pkcs5_pbkdf2_hmac_sha1" "', argument " "4"" of type '" "int""'");
+ }
+ arg4 = (int)(val4);
+ result = (PyObject *)pkcs5_pbkdf2_hmac_sha1(arg1,arg2,arg3,arg4);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_md_ctx_new(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_MD_CTX *result = 0 ;
+
+ result = (EVP_MD_CTX *)md_ctx_new();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_MD_CTX, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_md_ctx_free(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_MD_CTX *arg1 = (EVP_MD_CTX *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"md_ctx_free",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_EVP_MD_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "md_ctx_free" "', argument " "1"" of type '" "EVP_MD_CTX *""'");
+ }
+ arg1 = (EVP_MD_CTX *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ md_ctx_free(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_digest_update(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_MD_CTX *arg1 = (EVP_MD_CTX *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"digest_update",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_EVP_MD_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "digest_update" "', argument " "1"" of type '" "EVP_MD_CTX *""'");
+ }
+ arg1 = (EVP_MD_CTX *)(argp1);
+ {
+ arg2=obj1;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)digest_update(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_digest_final(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_MD_CTX *arg1 = (EVP_MD_CTX *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"digest_final",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_EVP_MD_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "digest_final" "', argument " "1"" of type '" "EVP_MD_CTX *""'");
+ }
+ arg1 = (EVP_MD_CTX *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)digest_final(arg1);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_hmac_ctx_new(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ HMAC_CTX *result = 0 ;
+
+ result = (HMAC_CTX *)hmac_ctx_new();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_HMAC_CTX, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_hmac_ctx_free(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ HMAC_CTX *arg1 = (HMAC_CTX *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"hmac_ctx_free",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_HMAC_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "hmac_ctx_free" "', argument " "1"" of type '" "HMAC_CTX *""'");
+ }
+ arg1 = (HMAC_CTX *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ hmac_ctx_free(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_hmac_init(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ HMAC_CTX *arg1 = (HMAC_CTX *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ EVP_MD *arg3 = (EVP_MD *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp3 = 0 ;
+ int res3 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"hmac_init",3,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_HMAC_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "hmac_init" "', argument " "1"" of type '" "HMAC_CTX *""'");
+ }
+ arg1 = (HMAC_CTX *)(argp1);
+ {
+ arg2=obj1;
+ }
+ res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_EVP_MD, 0 | 0 );
+ if (!SWIG_IsOK(res3)) {
+ SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "hmac_init" "', argument " "3"" of type '" "EVP_MD const *""'");
+ }
+ arg3 = (EVP_MD *)(argp3);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg3) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)hmac_init(arg1,arg2,(EVP_MD const *)arg3);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_hmac_update(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ HMAC_CTX *arg1 = (HMAC_CTX *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"hmac_update",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_HMAC_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "hmac_update" "', argument " "1"" of type '" "HMAC_CTX *""'");
+ }
+ arg1 = (HMAC_CTX *)(argp1);
+ {
+ arg2=obj1;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)hmac_update(arg1,arg2);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_hmac_final(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ HMAC_CTX *arg1 = (HMAC_CTX *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"hmac_final",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_HMAC_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "hmac_final" "', argument " "1"" of type '" "HMAC_CTX *""'");
+ }
+ arg1 = (HMAC_CTX *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)hmac_final(arg1);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_hmac(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ PyObject *arg1 = (PyObject *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ EVP_MD *arg3 = (EVP_MD *) 0 ;
+ void *argp3 = 0 ;
+ int res3 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"hmac",3,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ {
+ arg1=obj0;
+ }
+ {
+ arg2=obj1;
+ }
+ res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_EVP_MD, 0 | 0 );
+ if (!SWIG_IsOK(res3)) {
+ SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "hmac" "', argument " "3"" of type '" "EVP_MD const *""'");
+ }
+ arg3 = (EVP_MD *)(argp3);
+ {
+ if (!arg3) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)hmac(arg1,arg2,(EVP_MD const *)arg3);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_cipher_ctx_new(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_CIPHER_CTX *result = 0 ;
+
+ result = (EVP_CIPHER_CTX *)cipher_ctx_new();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_CIPHER_CTX, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_cipher_ctx_free(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_CIPHER_CTX *arg1 = (EVP_CIPHER_CTX *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"cipher_ctx_free",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_EVP_CIPHER_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "cipher_ctx_free" "', argument " "1"" of type '" "EVP_CIPHER_CTX *""'");
+ }
+ arg1 = (EVP_CIPHER_CTX *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ cipher_ctx_free(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bytes_to_key(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_CIPHER *arg1 = (EVP_CIPHER *) 0 ;
+ EVP_MD *arg2 = (EVP_MD *) 0 ;
+ PyObject *arg3 = (PyObject *) 0 ;
+ PyObject *arg4 = (PyObject *) 0 ;
+ PyObject *arg5 = (PyObject *) 0 ;
+ int arg6 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ int val6 ;
+ int ecode6 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject * obj3 = 0 ;
+ PyObject * obj4 = 0 ;
+ PyObject * obj5 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"bytes_to_key",6,6,&obj0,&obj1,&obj2,&obj3,&obj4,&obj5)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_EVP_CIPHER, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bytes_to_key" "', argument " "1"" of type '" "EVP_CIPHER const *""'");
+ }
+ arg1 = (EVP_CIPHER *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_EVP_MD, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "bytes_to_key" "', argument " "2"" of type '" "EVP_MD *""'");
+ }
+ arg2 = (EVP_MD *)(argp2);
+ {
+ arg3=obj2;
+ }
+ {
+ arg4=obj3;
+ }
+ {
+ arg5=obj4;
+ }
+ ecode6 = SWIG_AsVal_int(obj5, &val6);
+ if (!SWIG_IsOK(ecode6)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "bytes_to_key" "', argument " "6"" of type '" "int""'");
+ }
+ arg6 = (int)(val6);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)bytes_to_key((EVP_CIPHER const *)arg1,arg2,arg3,arg4,arg5,arg6);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_cipher_init(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_CIPHER_CTX *arg1 = (EVP_CIPHER_CTX *) 0 ;
+ EVP_CIPHER *arg2 = (EVP_CIPHER *) 0 ;
+ PyObject *arg3 = (PyObject *) 0 ;
+ PyObject *arg4 = (PyObject *) 0 ;
+ int arg5 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ int val5 ;
+ int ecode5 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject * obj3 = 0 ;
+ PyObject * obj4 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"cipher_init",5,5,&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_EVP_CIPHER_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "cipher_init" "', argument " "1"" of type '" "EVP_CIPHER_CTX *""'");
+ }
+ arg1 = (EVP_CIPHER_CTX *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_EVP_CIPHER, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "cipher_init" "', argument " "2"" of type '" "EVP_CIPHER const *""'");
+ }
+ arg2 = (EVP_CIPHER *)(argp2);
+ {
+ arg3=obj2;
+ }
+ {
+ arg4=obj3;
+ }
+ ecode5 = SWIG_AsVal_int(obj4, &val5);
+ if (!SWIG_IsOK(ecode5)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "cipher_init" "', argument " "5"" of type '" "int""'");
+ }
+ arg5 = (int)(val5);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)cipher_init(arg1,(EVP_CIPHER const *)arg2,arg3,arg4,arg5);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_cipher_update(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_CIPHER_CTX *arg1 = (EVP_CIPHER_CTX *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"cipher_update",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_EVP_CIPHER_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "cipher_update" "', argument " "1"" of type '" "EVP_CIPHER_CTX *""'");
+ }
+ arg1 = (EVP_CIPHER_CTX *)(argp1);
+ {
+ arg2=obj1;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)cipher_update(arg1,arg2);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_cipher_final(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_CIPHER_CTX *arg1 = (EVP_CIPHER_CTX *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"cipher_final",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_EVP_CIPHER_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "cipher_final" "', argument " "1"" of type '" "EVP_CIPHER_CTX *""'");
+ }
+ arg1 = (EVP_CIPHER_CTX *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)cipher_final(arg1);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_sign_update(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_MD_CTX *arg1 = (EVP_MD_CTX *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"sign_update",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_EVP_MD_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "sign_update" "', argument " "1"" of type '" "EVP_MD_CTX *""'");
+ }
+ arg1 = (EVP_MD_CTX *)(argp1);
+ {
+ arg2=obj1;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)sign_update(arg1,arg2);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_sign_final(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_MD_CTX *arg1 = (EVP_MD_CTX *) 0 ;
+ EVP_PKEY *arg2 = (EVP_PKEY *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"sign_final",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_EVP_MD_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "sign_final" "', argument " "1"" of type '" "EVP_MD_CTX *""'");
+ }
+ arg1 = (EVP_MD_CTX *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_EVP_PKEY, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "sign_final" "', argument " "2"" of type '" "EVP_PKEY *""'");
+ }
+ arg2 = (EVP_PKEY *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)sign_final(arg1,arg2);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_verify_update(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_MD_CTX *arg1 = (EVP_MD_CTX *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"verify_update",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_EVP_MD_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "verify_update" "', argument " "1"" of type '" "EVP_MD_CTX *""'");
+ }
+ arg1 = (EVP_MD_CTX *)(argp1);
+ {
+ arg2=obj1;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)verify_update(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_verify_final(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_MD_CTX *arg1 = (EVP_MD_CTX *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ EVP_PKEY *arg3 = (EVP_PKEY *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp3 = 0 ;
+ int res3 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"verify_final",3,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_EVP_MD_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "verify_final" "', argument " "1"" of type '" "EVP_MD_CTX *""'");
+ }
+ arg1 = (EVP_MD_CTX *)(argp1);
+ {
+ arg2=obj1;
+ }
+ res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_EVP_PKEY, 0 | 0 );
+ if (!SWIG_IsOK(res3)) {
+ SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "verify_final" "', argument " "3"" of type '" "EVP_PKEY *""'");
+ }
+ arg3 = (EVP_PKEY *)(argp3);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg3) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)verify_final(arg1,arg2,arg3);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_get_digestbyname(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ char *arg1 = (char *) 0 ;
+ int res1 ;
+ char *buf1 = 0 ;
+ int alloc1 = 0 ;
+ PyObject * obj0 = 0 ;
+ EVP_MD *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"get_digestbyname",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "get_digestbyname" "', argument " "1"" of type '" "char const *""'");
+ }
+ arg1 = (char *)(buf1);
+ result = (EVP_MD *)get_digestbyname((char const *)arg1);
+ {
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+
+ if (result != NULL)
+ resultobj = SWIG_NewPointerObj(result, SWIGTYPE_p_EVP_MD, 0);
+ else {
+ resultobj = NULL;
+ }
+ }
+ if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
+ return resultobj;
+fail:
+ if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_pkey_write_pem_no_cipher(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_PKEY *arg1 = (EVP_PKEY *) 0 ;
+ BIO *arg2 = (BIO *) 0 ;
+ PyObject *arg3 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"pkey_write_pem_no_cipher",3,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_EVP_PKEY, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "pkey_write_pem_no_cipher" "', argument " "1"" of type '" "EVP_PKEY *""'");
+ }
+ arg1 = (EVP_PKEY *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "pkey_write_pem_no_cipher" "', argument " "2"" of type '" "BIO *""'");
+ }
+ arg2 = (BIO *)(argp2);
+ {
+ if (!PyCallable_Check(obj2)) {
+ PyErr_SetString(PyExc_TypeError, "expected PyCallable");
+ return NULL;
+ }
+ arg3=obj2;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)pkey_write_pem_no_cipher(arg1,arg2,arg3);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_pkey_write_pem(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_PKEY *arg1 = (EVP_PKEY *) 0 ;
+ BIO *arg2 = (BIO *) 0 ;
+ EVP_CIPHER *arg3 = (EVP_CIPHER *) 0 ;
+ PyObject *arg4 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ void *argp3 = 0 ;
+ int res3 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject * obj3 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"pkey_write_pem",4,4,&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_EVP_PKEY, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "pkey_write_pem" "', argument " "1"" of type '" "EVP_PKEY *""'");
+ }
+ arg1 = (EVP_PKEY *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "pkey_write_pem" "', argument " "2"" of type '" "BIO *""'");
+ }
+ arg2 = (BIO *)(argp2);
+ res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_EVP_CIPHER, 0 | 0 );
+ if (!SWIG_IsOK(res3)) {
+ SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "pkey_write_pem" "', argument " "3"" of type '" "EVP_CIPHER *""'");
+ }
+ arg3 = (EVP_CIPHER *)(argp3);
+ {
+ if (!PyCallable_Check(obj3)) {
+ PyErr_SetString(PyExc_TypeError, "expected PyCallable");
+ return NULL;
+ }
+ arg4=obj3;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg3) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)pkey_write_pem(arg1,arg2,arg3,arg4);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_pkey_new(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_PKEY *result = 0 ;
+
+ result = (EVP_PKEY *)pkey_new();
+ {
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+
+ if (result != NULL)
+ resultobj = SWIG_NewPointerObj(result, SWIGTYPE_p_EVP_PKEY, 0);
+ else {
+ resultobj = NULL;
+ }
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_pkey_read_pem(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ EVP_PKEY *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"pkey_read_pem",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "pkey_read_pem" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ {
+ if (!PyCallable_Check(obj1)) {
+ PyErr_SetString(PyExc_TypeError, "expected PyCallable");
+ return NULL;
+ }
+ arg2=obj1;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (EVP_PKEY *)pkey_read_pem(arg1,arg2);
+ {
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+
+ if (result != NULL)
+ resultobj = SWIG_NewPointerObj(result, SWIGTYPE_p_EVP_PKEY, 0);
+ else {
+ resultobj = NULL;
+ }
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_pkey_read_pem_pubkey(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ EVP_PKEY *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"pkey_read_pem_pubkey",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "pkey_read_pem_pubkey" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ {
+ if (!PyCallable_Check(obj1)) {
+ PyErr_SetString(PyExc_TypeError, "expected PyCallable");
+ return NULL;
+ }
+ arg2=obj1;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (EVP_PKEY *)pkey_read_pem_pubkey(arg1,arg2);
+ {
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+
+ if (result != NULL)
+ resultobj = SWIG_NewPointerObj(result, SWIGTYPE_p_EVP_PKEY, 0);
+ else {
+ resultobj = NULL;
+ }
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_pkey_assign_rsa(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_PKEY *arg1 = (EVP_PKEY *) 0 ;
+ RSA *arg2 = (RSA *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"pkey_assign_rsa",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_EVP_PKEY, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "pkey_assign_rsa" "', argument " "1"" of type '" "EVP_PKEY *""'");
+ }
+ arg1 = (EVP_PKEY *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_RSA, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "pkey_assign_rsa" "', argument " "2"" of type '" "RSA *""'");
+ }
+ arg2 = (RSA *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)pkey_assign_rsa(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_pkey_as_der(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_PKEY *arg1 = (EVP_PKEY *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"pkey_as_der",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_EVP_PKEY, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "pkey_as_der" "', argument " "1"" of type '" "EVP_PKEY *""'");
+ }
+ arg1 = (EVP_PKEY *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)pkey_as_der(arg1);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_pkey_get_modulus(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EVP_PKEY *arg1 = (EVP_PKEY *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"pkey_get_modulus",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_EVP_PKEY, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "pkey_get_modulus" "', argument " "1"" of type '" "EVP_PKEY *""'");
+ }
+ arg1 = (EVP_PKEY *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)pkey_get_modulus(arg1);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_aes_new(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ AES_KEY *result = 0 ;
+
+ result = (AES_KEY *)aes_new();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_AES_KEY, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_AES_free(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ AES_KEY *arg1 = (AES_KEY *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"AES_free",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_AES_KEY, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "AES_free" "', argument " "1"" of type '" "AES_KEY *""'");
+ }
+ arg1 = (AES_KEY *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ AES_free(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_AES_set_key(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ AES_KEY *arg1 = (AES_KEY *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ int arg3 ;
+ int arg4 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val3 ;
+ int ecode3 = 0 ;
+ int val4 ;
+ int ecode4 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject * obj3 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"AES_set_key",4,4,&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_AES_KEY, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "AES_set_key" "', argument " "1"" of type '" "AES_KEY *""'");
+ }
+ arg1 = (AES_KEY *)(argp1);
+ {
+ arg2=obj1;
+ }
+ ecode3 = SWIG_AsVal_int(obj2, &val3);
+ if (!SWIG_IsOK(ecode3)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "AES_set_key" "', argument " "3"" of type '" "int""'");
+ }
+ arg3 = (int)(val3);
+ ecode4 = SWIG_AsVal_int(obj3, &val4);
+ if (!SWIG_IsOK(ecode4)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "AES_set_key" "', argument " "4"" of type '" "int""'");
+ }
+ arg4 = (int)(val4);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)AES_set_key(arg1,arg2,arg3,arg4);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_AES_crypt(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ AES_KEY *arg1 = (AES_KEY *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ int arg3 ;
+ int arg4 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val3 ;
+ int ecode3 = 0 ;
+ int val4 ;
+ int ecode4 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject * obj3 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"AES_crypt",4,4,&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_AES_KEY, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "AES_crypt" "', argument " "1"" of type '" "AES_KEY const *""'");
+ }
+ arg1 = (AES_KEY *)(argp1);
+ {
+ arg2=obj1;
+ }
+ ecode3 = SWIG_AsVal_int(obj2, &val3);
+ if (!SWIG_IsOK(ecode3)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "AES_crypt" "', argument " "3"" of type '" "int""'");
+ }
+ arg3 = (int)(val3);
+ ecode4 = SWIG_AsVal_int(obj3, &val4);
+ if (!SWIG_IsOK(ecode4)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "AES_crypt" "', argument " "4"" of type '" "int""'");
+ }
+ arg4 = (int)(val4);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)AES_crypt((AES_KEY const *)arg1,arg2,arg3,arg4);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_AES_type_check(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ AES_KEY *arg1 = (AES_KEY *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"AES_type_check",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_AES_KEY, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "AES_type_check" "', argument " "1"" of type '" "AES_KEY *""'");
+ }
+ arg1 = (AES_KEY *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)AES_type_check(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rc4_new(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ RC4_KEY *result = 0 ;
+
+ result = (RC4_KEY *)rc4_new();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_RC4_KEY, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rc4_free(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ RC4_KEY *arg1 = (RC4_KEY *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"rc4_free",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_RC4_KEY, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "rc4_free" "', argument " "1"" of type '" "RC4_KEY *""'");
+ }
+ arg1 = (RC4_KEY *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ rc4_free(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rc4_set_key(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ RC4_KEY *arg1 = (RC4_KEY *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"rc4_set_key",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_RC4_KEY, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "rc4_set_key" "', argument " "1"" of type '" "RC4_KEY *""'");
+ }
+ arg1 = (RC4_KEY *)(argp1);
+ {
+ arg2=obj1;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)rc4_set_key(arg1,arg2);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rc4_update(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ RC4_KEY *arg1 = (RC4_KEY *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"rc4_update",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_RC4_KEY, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "rc4_update" "', argument " "1"" of type '" "RC4_KEY *""'");
+ }
+ arg1 = (RC4_KEY *)(argp1);
+ {
+ arg2=obj1;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)rc4_update(arg1,arg2);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rc4_type_check(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ RC4_KEY *arg1 = (RC4_KEY *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"rc4_type_check",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_RC4_KEY, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "rc4_type_check" "', argument " "1"" of type '" "RC4_KEY *""'");
+ }
+ arg1 = (RC4_KEY *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)rc4_type_check(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_dh_new(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ DH *result = 0 ;
+
+ result = (DH *)DH_new();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_DH, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_dh_free(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ DH *arg1 = (DH *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"dh_free",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_DH, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "dh_free" "', argument " "1"" of type '" "DH *""'");
+ }
+ arg1 = (DH *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ DH_free(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_dh_size(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ DH *arg1 = (DH *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"dh_size",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_DH, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "dh_size" "', argument " "1"" of type '" "DH const *""'");
+ }
+ arg1 = (DH *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)DH_size((DH const *)arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_dh_generate_key(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ DH *arg1 = (DH *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"dh_generate_key",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_DH, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "dh_generate_key" "', argument " "1"" of type '" "DH *""'");
+ }
+ arg1 = (DH *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)DH_generate_key(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_dhparams_print(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ DH *arg2 = (DH *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"dhparams_print",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "dhparams_print" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_DH, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "dhparams_print" "', argument " "2"" of type '" "DH const *""'");
+ }
+ arg2 = (DH *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ result = (int)DHparams_print(arg1,(DH const *)arg2);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN int Swig_var__dh_err_set(PyObject *_val) {
+ {
+ void *argp = 0;
+ int res = SWIG_ConvertPtr(_val, &argp, SWIGTYPE_p_PyObject, 0 );
+ if (!SWIG_IsOK(res)) {
+ SWIG_exception_fail(SWIG_ArgError(res), "in variable '""_dh_err""' of type '""PyObject *""'");
+ }
+ _dh_err = (PyObject *)(argp);
+ }
+ return 0;
+fail:
+ return 1;
+}
+
+
+SWIGINTERN PyObject *Swig_var__dh_err_get(void) {
+ PyObject *pyobj = 0;
+ PyObject *self = 0;
+
+ (void)self;
+ pyobj = SWIG_NewPointerObj(SWIG_as_voidptr(_dh_err), SWIGTYPE_p_PyObject, 0 );
+ return pyobj;
+}
+
+
+SWIGINTERN PyObject *_wrap_dh_init(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ PyObject *arg1 = (PyObject *) 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"dh_init",1,1,&obj0)) SWIG_fail;
+ {
+ arg1=obj0;
+ }
+ dh_init(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_dh_type_check(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ DH *arg1 = (DH *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"dh_type_check",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_DH, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "dh_type_check" "', argument " "1"" of type '" "DH *""'");
+ }
+ arg1 = (DH *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)dh_type_check(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_dh_read_parameters(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ DH *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"dh_read_parameters",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "dh_read_parameters" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ result = (DH *)dh_read_parameters(arg1);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_DH, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_dh_generate_parameters(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ int arg1 ;
+ int arg2 ;
+ PyObject *arg3 = (PyObject *) 0 ;
+ int val1 ;
+ int ecode1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ DH *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"dh_generate_parameters",3,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ ecode1 = SWIG_AsVal_int(obj0, &val1);
+ if (!SWIG_IsOK(ecode1)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "dh_generate_parameters" "', argument " "1"" of type '" "int""'");
+ }
+ arg1 = (int)(val1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "dh_generate_parameters" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ {
+ if (!PyCallable_Check(obj2)) {
+ PyErr_SetString(PyExc_TypeError, "expected PyCallable");
+ return NULL;
+ }
+ arg3=obj2;
+ }
+ result = (DH *)dh_generate_parameters(arg1,arg2,arg3);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_DH, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_dh_check(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ DH *arg1 = (DH *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"dh_check",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_DH, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "dh_check" "', argument " "1"" of type '" "DH *""'");
+ }
+ arg1 = (DH *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)dh_check(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_dh_compute_key(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ DH *arg1 = (DH *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"dh_compute_key",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_DH, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "dh_compute_key" "', argument " "1"" of type '" "DH *""'");
+ }
+ arg1 = (DH *)(argp1);
+ {
+ arg2=obj1;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)dh_compute_key(arg1,arg2);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_dh_get_p(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ DH *arg1 = (DH *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"dh_get_p",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_DH, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "dh_get_p" "', argument " "1"" of type '" "DH *""'");
+ }
+ arg1 = (DH *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)dh_get_p(arg1);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_dh_get_g(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ DH *arg1 = (DH *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"dh_get_g",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_DH, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "dh_get_g" "', argument " "1"" of type '" "DH *""'");
+ }
+ arg1 = (DH *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)dh_get_g(arg1);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_dh_get_pub(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ DH *arg1 = (DH *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"dh_get_pub",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_DH, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "dh_get_pub" "', argument " "1"" of type '" "DH *""'");
+ }
+ arg1 = (DH *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)dh_get_pub(arg1);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_dh_get_priv(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ DH *arg1 = (DH *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"dh_get_priv",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_DH, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "dh_get_priv" "', argument " "1"" of type '" "DH *""'");
+ }
+ arg1 = (DH *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)dh_get_priv(arg1);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_dh_set_pg(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ DH *arg1 = (DH *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ PyObject *arg3 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"dh_set_pg",3,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_DH, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "dh_set_pg" "', argument " "1"" of type '" "DH *""'");
+ }
+ arg1 = (DH *)(argp1);
+ {
+ arg2=obj1;
+ }
+ {
+ arg3=obj2;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)dh_set_pg(arg1,arg2,arg3);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rsa_size(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ RSA *arg1 = (RSA *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"rsa_size",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_RSA, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "rsa_size" "', argument " "1"" of type '" "RSA const *""'");
+ }
+ arg1 = (RSA *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)RSA_size((RSA const *)arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rsa_new(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ RSA *result = 0 ;
+
+ result = (RSA *)RSA_new();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_RSA, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rsa_free(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ RSA *arg1 = (RSA *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"rsa_free",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_RSA, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "rsa_free" "', argument " "1"" of type '" "RSA *""'");
+ }
+ arg1 = (RSA *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ RSA_free(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rsa_check_key(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ RSA *arg1 = (RSA *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"rsa_check_key",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_RSA, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "rsa_check_key" "', argument " "1"" of type '" "RSA const *""'");
+ }
+ arg1 = (RSA *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)RSA_check_key((RSA const *)arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN int Swig_var__rsa_err_set(PyObject *_val) {
+ {
+ void *argp = 0;
+ int res = SWIG_ConvertPtr(_val, &argp, SWIGTYPE_p_PyObject, 0 );
+ if (!SWIG_IsOK(res)) {
+ SWIG_exception_fail(SWIG_ArgError(res), "in variable '""_rsa_err""' of type '""PyObject *""'");
+ }
+ _rsa_err = (PyObject *)(argp);
+ }
+ return 0;
+fail:
+ return 1;
+}
+
+
+SWIGINTERN PyObject *Swig_var__rsa_err_get(void) {
+ PyObject *pyobj = 0;
+ PyObject *self = 0;
+
+ (void)self;
+ pyobj = SWIG_NewPointerObj(SWIG_as_voidptr(_rsa_err), SWIGTYPE_p_PyObject, 0 );
+ return pyobj;
+}
+
+
+SWIGINTERN PyObject *_wrap_rsa_init(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ PyObject *arg1 = (PyObject *) 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"rsa_init",1,1,&obj0)) SWIG_fail;
+ {
+ arg1=obj0;
+ }
+ rsa_init(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rsa_read_key(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ RSA *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"rsa_read_key",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "rsa_read_key" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ {
+ if (!PyCallable_Check(obj1)) {
+ PyErr_SetString(PyExc_TypeError, "expected PyCallable");
+ return NULL;
+ }
+ arg2=obj1;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (RSA *)rsa_read_key(arg1,arg2);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_RSA, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rsa_write_key(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ RSA *arg1 = (RSA *) 0 ;
+ BIO *arg2 = (BIO *) 0 ;
+ EVP_CIPHER *arg3 = (EVP_CIPHER *) 0 ;
+ PyObject *arg4 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ void *argp3 = 0 ;
+ int res3 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject * obj3 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"rsa_write_key",4,4,&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_RSA, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "rsa_write_key" "', argument " "1"" of type '" "RSA *""'");
+ }
+ arg1 = (RSA *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "rsa_write_key" "', argument " "2"" of type '" "BIO *""'");
+ }
+ arg2 = (BIO *)(argp2);
+ res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_EVP_CIPHER, 0 | 0 );
+ if (!SWIG_IsOK(res3)) {
+ SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "rsa_write_key" "', argument " "3"" of type '" "EVP_CIPHER *""'");
+ }
+ arg3 = (EVP_CIPHER *)(argp3);
+ {
+ if (!PyCallable_Check(obj3)) {
+ PyErr_SetString(PyExc_TypeError, "expected PyCallable");
+ return NULL;
+ }
+ arg4=obj3;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg3) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg4) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)rsa_write_key(arg1,arg2,arg3,arg4);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rsa_write_key_no_cipher(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ RSA *arg1 = (RSA *) 0 ;
+ BIO *arg2 = (BIO *) 0 ;
+ PyObject *arg3 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"rsa_write_key_no_cipher",3,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_RSA, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "rsa_write_key_no_cipher" "', argument " "1"" of type '" "RSA *""'");
+ }
+ arg1 = (RSA *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "rsa_write_key_no_cipher" "', argument " "2"" of type '" "BIO *""'");
+ }
+ arg2 = (BIO *)(argp2);
+ {
+ if (!PyCallable_Check(obj2)) {
+ PyErr_SetString(PyExc_TypeError, "expected PyCallable");
+ return NULL;
+ }
+ arg3=obj2;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg3) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)rsa_write_key_no_cipher(arg1,arg2,arg3);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rsa_read_pub_key(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ RSA *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"rsa_read_pub_key",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "rsa_read_pub_key" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ result = (RSA *)rsa_read_pub_key(arg1);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_RSA, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rsa_write_pub_key(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ RSA *arg1 = (RSA *) 0 ;
+ BIO *arg2 = (BIO *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"rsa_write_pub_key",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_RSA, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "rsa_write_pub_key" "', argument " "1"" of type '" "RSA *""'");
+ }
+ arg1 = (RSA *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "rsa_write_pub_key" "', argument " "2"" of type '" "BIO *""'");
+ }
+ arg2 = (BIO *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ result = (int)rsa_write_pub_key(arg1,arg2);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rsa_get_e(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ RSA *arg1 = (RSA *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"rsa_get_e",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_RSA, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "rsa_get_e" "', argument " "1"" of type '" "RSA *""'");
+ }
+ arg1 = (RSA *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)rsa_get_e(arg1);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rsa_get_n(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ RSA *arg1 = (RSA *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"rsa_get_n",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_RSA, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "rsa_get_n" "', argument " "1"" of type '" "RSA *""'");
+ }
+ arg1 = (RSA *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)rsa_get_n(arg1);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rsa_set_e(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ RSA *arg1 = (RSA *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"rsa_set_e",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_RSA, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "rsa_set_e" "', argument " "1"" of type '" "RSA *""'");
+ }
+ arg1 = (RSA *)(argp1);
+ {
+ arg2=obj1;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)rsa_set_e(arg1,arg2);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rsa_set_n(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ RSA *arg1 = (RSA *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"rsa_set_n",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_RSA, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "rsa_set_n" "', argument " "1"" of type '" "RSA *""'");
+ }
+ arg1 = (RSA *)(argp1);
+ {
+ arg2=obj1;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)rsa_set_n(arg1,arg2);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rsa_set_en(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ RSA *arg1 = (RSA *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ PyObject *arg3 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"rsa_set_en",3,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_RSA, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "rsa_set_en" "', argument " "1"" of type '" "RSA *""'");
+ }
+ arg1 = (RSA *)(argp1);
+ {
+ arg2=obj1;
+ }
+ {
+ arg3=obj2;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)rsa_set_en(arg1,arg2,arg3);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_PyObject_Bin_AsBIGNUM(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ PyObject *arg1 = (PyObject *) 0 ;
+ PyObject * obj0 = 0 ;
+ BIGNUM *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"PyObject_Bin_AsBIGNUM",1,1,&obj0)) SWIG_fail;
+ {
+ arg1=obj0;
+ }
+ result = (BIGNUM *)PyObject_Bin_AsBIGNUM(arg1);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_BIGNUM, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rsa_set_en_bin(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ RSA *arg1 = (RSA *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ PyObject *arg3 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"rsa_set_en_bin",3,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_RSA, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "rsa_set_en_bin" "', argument " "1"" of type '" "RSA *""'");
+ }
+ arg1 = (RSA *)(argp1);
+ {
+ arg2=obj1;
+ }
+ {
+ arg3=obj2;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)rsa_set_en_bin(arg1,arg2,arg3);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rsa_private_encrypt(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ RSA *arg1 = (RSA *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ int arg3 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val3 ;
+ int ecode3 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"rsa_private_encrypt",3,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_RSA, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "rsa_private_encrypt" "', argument " "1"" of type '" "RSA *""'");
+ }
+ arg1 = (RSA *)(argp1);
+ {
+ arg2=obj1;
+ }
+ ecode3 = SWIG_AsVal_int(obj2, &val3);
+ if (!SWIG_IsOK(ecode3)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "rsa_private_encrypt" "', argument " "3"" of type '" "int""'");
+ }
+ arg3 = (int)(val3);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)rsa_private_encrypt(arg1,arg2,arg3);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rsa_public_decrypt(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ RSA *arg1 = (RSA *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ int arg3 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val3 ;
+ int ecode3 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"rsa_public_decrypt",3,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_RSA, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "rsa_public_decrypt" "', argument " "1"" of type '" "RSA *""'");
+ }
+ arg1 = (RSA *)(argp1);
+ {
+ arg2=obj1;
+ }
+ ecode3 = SWIG_AsVal_int(obj2, &val3);
+ if (!SWIG_IsOK(ecode3)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "rsa_public_decrypt" "', argument " "3"" of type '" "int""'");
+ }
+ arg3 = (int)(val3);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)rsa_public_decrypt(arg1,arg2,arg3);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rsa_public_encrypt(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ RSA *arg1 = (RSA *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ int arg3 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val3 ;
+ int ecode3 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"rsa_public_encrypt",3,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_RSA, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "rsa_public_encrypt" "', argument " "1"" of type '" "RSA *""'");
+ }
+ arg1 = (RSA *)(argp1);
+ {
+ arg2=obj1;
+ }
+ ecode3 = SWIG_AsVal_int(obj2, &val3);
+ if (!SWIG_IsOK(ecode3)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "rsa_public_encrypt" "', argument " "3"" of type '" "int""'");
+ }
+ arg3 = (int)(val3);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)rsa_public_encrypt(arg1,arg2,arg3);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rsa_private_decrypt(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ RSA *arg1 = (RSA *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ int arg3 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val3 ;
+ int ecode3 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"rsa_private_decrypt",3,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_RSA, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "rsa_private_decrypt" "', argument " "1"" of type '" "RSA *""'");
+ }
+ arg1 = (RSA *)(argp1);
+ {
+ arg2=obj1;
+ }
+ ecode3 = SWIG_AsVal_int(obj2, &val3);
+ if (!SWIG_IsOK(ecode3)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "rsa_private_decrypt" "', argument " "3"" of type '" "int""'");
+ }
+ arg3 = (int)(val3);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)rsa_private_decrypt(arg1,arg2,arg3);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rsa_padding_add_pkcs1_pss(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ RSA *arg1 = (RSA *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ EVP_MD *arg3 = (EVP_MD *) 0 ;
+ int arg4 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp3 = 0 ;
+ int res3 = 0 ;
+ int val4 ;
+ int ecode4 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject * obj3 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"rsa_padding_add_pkcs1_pss",4,4,&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_RSA, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "rsa_padding_add_pkcs1_pss" "', argument " "1"" of type '" "RSA *""'");
+ }
+ arg1 = (RSA *)(argp1);
+ {
+ arg2=obj1;
+ }
+ res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_EVP_MD, 0 | 0 );
+ if (!SWIG_IsOK(res3)) {
+ SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "rsa_padding_add_pkcs1_pss" "', argument " "3"" of type '" "EVP_MD *""'");
+ }
+ arg3 = (EVP_MD *)(argp3);
+ ecode4 = SWIG_AsVal_int(obj3, &val4);
+ if (!SWIG_IsOK(ecode4)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "rsa_padding_add_pkcs1_pss" "', argument " "4"" of type '" "int""'");
+ }
+ arg4 = (int)(val4);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg3) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)rsa_padding_add_pkcs1_pss(arg1,arg2,arg3,arg4);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rsa_verify_pkcs1_pss(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ RSA *arg1 = (RSA *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ PyObject *arg3 = (PyObject *) 0 ;
+ EVP_MD *arg4 = (EVP_MD *) 0 ;
+ int arg5 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp4 = 0 ;
+ int res4 = 0 ;
+ int val5 ;
+ int ecode5 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject * obj3 = 0 ;
+ PyObject * obj4 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"rsa_verify_pkcs1_pss",5,5,&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_RSA, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "rsa_verify_pkcs1_pss" "', argument " "1"" of type '" "RSA *""'");
+ }
+ arg1 = (RSA *)(argp1);
+ {
+ arg2=obj1;
+ }
+ {
+ arg3=obj2;
+ }
+ res4 = SWIG_ConvertPtr(obj3, &argp4,SWIGTYPE_p_EVP_MD, 0 | 0 );
+ if (!SWIG_IsOK(res4)) {
+ SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "rsa_verify_pkcs1_pss" "', argument " "4"" of type '" "EVP_MD *""'");
+ }
+ arg4 = (EVP_MD *)(argp4);
+ ecode5 = SWIG_AsVal_int(obj4, &val5);
+ if (!SWIG_IsOK(ecode5)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "rsa_verify_pkcs1_pss" "', argument " "5"" of type '" "int""'");
+ }
+ arg5 = (int)(val5);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg4) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)rsa_verify_pkcs1_pss(arg1,arg2,arg3,arg4,arg5);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rsa_sign(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ RSA *arg1 = (RSA *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ int arg3 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val3 ;
+ int ecode3 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"rsa_sign",3,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_RSA, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "rsa_sign" "', argument " "1"" of type '" "RSA *""'");
+ }
+ arg1 = (RSA *)(argp1);
+ {
+ arg2=obj1;
+ }
+ ecode3 = SWIG_AsVal_int(obj2, &val3);
+ if (!SWIG_IsOK(ecode3)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "rsa_sign" "', argument " "3"" of type '" "int""'");
+ }
+ arg3 = (int)(val3);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)rsa_sign(arg1,arg2,arg3);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rsa_verify(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ RSA *arg1 = (RSA *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ PyObject *arg3 = (PyObject *) 0 ;
+ int arg4 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val4 ;
+ int ecode4 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject * obj3 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"rsa_verify",4,4,&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_RSA, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "rsa_verify" "', argument " "1"" of type '" "RSA *""'");
+ }
+ arg1 = (RSA *)(argp1);
+ {
+ arg2=obj1;
+ }
+ {
+ arg3=obj2;
+ }
+ ecode4 = SWIG_AsVal_int(obj3, &val4);
+ if (!SWIG_IsOK(ecode4)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "rsa_verify" "', argument " "4"" of type '" "int""'");
+ }
+ arg4 = (int)(val4);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)rsa_verify(arg1,arg2,arg3,arg4);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rsa_generate_key(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ int arg1 ;
+ unsigned long arg2 ;
+ PyObject *arg3 = (PyObject *) 0 ;
+ int val1 ;
+ int ecode1 = 0 ;
+ unsigned long val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"rsa_generate_key",3,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ ecode1 = SWIG_AsVal_int(obj0, &val1);
+ if (!SWIG_IsOK(ecode1)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "rsa_generate_key" "', argument " "1"" of type '" "int""'");
+ }
+ arg1 = (int)(val1);
+ ecode2 = SWIG_AsVal_unsigned_SS_long(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "rsa_generate_key" "', argument " "2"" of type '" "unsigned long""'");
+ }
+ arg2 = (unsigned long)(val2);
+ {
+ if (!PyCallable_Check(obj2)) {
+ PyErr_SetString(PyExc_TypeError, "expected PyCallable");
+ return NULL;
+ }
+ arg3=obj2;
+ }
+ {
+ if (!arg3) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)rsa_generate_key(arg1,arg2,arg3);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rsa_type_check(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ RSA *arg1 = (RSA *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"rsa_type_check",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_RSA, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "rsa_type_check" "', argument " "1"" of type '" "RSA *""'");
+ }
+ arg1 = (RSA *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)rsa_type_check(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rsa_check_pub_key(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ RSA *arg1 = (RSA *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"rsa_check_pub_key",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_RSA, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "rsa_check_pub_key" "', argument " "1"" of type '" "RSA *""'");
+ }
+ arg1 = (RSA *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)rsa_check_pub_key(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_rsa_write_key_der(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ RSA *arg1 = (RSA *) 0 ;
+ BIO *arg2 = (BIO *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"rsa_write_key_der",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_RSA, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "rsa_write_key_der" "', argument " "1"" of type '" "RSA *""'");
+ }
+ arg1 = (RSA *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "rsa_write_key_der" "', argument " "2"" of type '" "BIO *""'");
+ }
+ arg2 = (BIO *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ result = (int)rsa_write_key_der(arg1,arg2);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_dsa_new(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ DSA *result = 0 ;
+
+ result = (DSA *)DSA_new();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_DSA, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_dsa_free(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ DSA *arg1 = (DSA *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"dsa_free",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_DSA, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "dsa_free" "', argument " "1"" of type '" "DSA *""'");
+ }
+ arg1 = (DSA *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ DSA_free(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_dsa_size(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ DSA *arg1 = (DSA *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"dsa_size",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_DSA, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "dsa_size" "', argument " "1"" of type '" "DSA const *""'");
+ }
+ arg1 = (DSA *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)DSA_size((DSA const *)arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_dsa_gen_key(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ DSA *arg1 = (DSA *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"dsa_gen_key",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_DSA, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "dsa_gen_key" "', argument " "1"" of type '" "DSA *""'");
+ }
+ arg1 = (DSA *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)DSA_generate_key(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN int Swig_var__dsa_err_set(PyObject *_val) {
+ {
+ void *argp = 0;
+ int res = SWIG_ConvertPtr(_val, &argp, SWIGTYPE_p_PyObject, 0 );
+ if (!SWIG_IsOK(res)) {
+ SWIG_exception_fail(SWIG_ArgError(res), "in variable '""_dsa_err""' of type '""PyObject *""'");
+ }
+ _dsa_err = (PyObject *)(argp);
+ }
+ return 0;
+fail:
+ return 1;
+}
+
+
+SWIGINTERN PyObject *Swig_var__dsa_err_get(void) {
+ PyObject *pyobj = 0;
+ PyObject *self = 0;
+
+ (void)self;
+ pyobj = SWIG_NewPointerObj(SWIG_as_voidptr(_dsa_err), SWIGTYPE_p_PyObject, 0 );
+ return pyobj;
+}
+
+
+SWIGINTERN PyObject *_wrap_dsa_init(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ PyObject *arg1 = (PyObject *) 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"dsa_init",1,1,&obj0)) SWIG_fail;
+ {
+ arg1=obj0;
+ }
+ dsa_init(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_dsa_generate_parameters(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ int arg1 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ int val1 ;
+ int ecode1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ DSA *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"dsa_generate_parameters",2,2,&obj0,&obj1)) SWIG_fail;
+ ecode1 = SWIG_AsVal_int(obj0, &val1);
+ if (!SWIG_IsOK(ecode1)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "dsa_generate_parameters" "', argument " "1"" of type '" "int""'");
+ }
+ arg1 = (int)(val1);
+ {
+ if (!PyCallable_Check(obj1)) {
+ PyErr_SetString(PyExc_TypeError, "expected PyCallable");
+ return NULL;
+ }
+ arg2=obj1;
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (DSA *)dsa_generate_parameters(arg1,arg2);
+ {
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+
+ if (result != NULL)
+ resultobj = SWIG_NewPointerObj(result, SWIGTYPE_p_DSA, 0);
+ else {
+ resultobj = NULL;
+ }
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_dsa_read_params(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ DSA *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"dsa_read_params",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "dsa_read_params" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ {
+ if (!PyCallable_Check(obj1)) {
+ PyErr_SetString(PyExc_TypeError, "expected PyCallable");
+ return NULL;
+ }
+ arg2=obj1;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (DSA *)dsa_read_params(arg1,arg2);
+ {
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+
+ if (result != NULL)
+ resultobj = SWIG_NewPointerObj(result, SWIGTYPE_p_DSA, 0);
+ else {
+ resultobj = NULL;
+ }
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_dsa_read_key(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ DSA *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"dsa_read_key",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "dsa_read_key" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ {
+ if (!PyCallable_Check(obj1)) {
+ PyErr_SetString(PyExc_TypeError, "expected PyCallable");
+ return NULL;
+ }
+ arg2=obj1;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (DSA *)dsa_read_key(arg1,arg2);
+ {
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+
+ if (result != NULL)
+ resultobj = SWIG_NewPointerObj(result, SWIGTYPE_p_DSA, 0);
+ else {
+ resultobj = NULL;
+ }
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_dsa_read_pub_key(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ DSA *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"dsa_read_pub_key",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "dsa_read_pub_key" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ {
+ if (!PyCallable_Check(obj1)) {
+ PyErr_SetString(PyExc_TypeError, "expected PyCallable");
+ return NULL;
+ }
+ arg2=obj1;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (DSA *)dsa_read_pub_key(arg1,arg2);
+ {
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+
+ if (result != NULL)
+ resultobj = SWIG_NewPointerObj(result, SWIGTYPE_p_DSA, 0);
+ else {
+ resultobj = NULL;
+ }
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_dsa_get_p(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ DSA *arg1 = (DSA *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"dsa_get_p",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_DSA, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "dsa_get_p" "', argument " "1"" of type '" "DSA *""'");
+ }
+ arg1 = (DSA *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)dsa_get_p(arg1);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_dsa_get_q(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ DSA *arg1 = (DSA *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"dsa_get_q",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_DSA, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "dsa_get_q" "', argument " "1"" of type '" "DSA *""'");
+ }
+ arg1 = (DSA *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)dsa_get_q(arg1);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_dsa_get_g(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ DSA *arg1 = (DSA *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"dsa_get_g",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_DSA, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "dsa_get_g" "', argument " "1"" of type '" "DSA *""'");
+ }
+ arg1 = (DSA *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)dsa_get_g(arg1);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_dsa_get_pub(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ DSA *arg1 = (DSA *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"dsa_get_pub",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_DSA, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "dsa_get_pub" "', argument " "1"" of type '" "DSA *""'");
+ }
+ arg1 = (DSA *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)dsa_get_pub(arg1);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_dsa_get_priv(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ DSA *arg1 = (DSA *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"dsa_get_priv",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_DSA, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "dsa_get_priv" "', argument " "1"" of type '" "DSA *""'");
+ }
+ arg1 = (DSA *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)dsa_get_priv(arg1);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_dsa_set_pqg(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ DSA *arg1 = (DSA *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ PyObject *arg3 = (PyObject *) 0 ;
+ PyObject *arg4 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject * obj3 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"dsa_set_pqg",4,4,&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_DSA, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "dsa_set_pqg" "', argument " "1"" of type '" "DSA *""'");
+ }
+ arg1 = (DSA *)(argp1);
+ {
+ arg2=obj1;
+ }
+ {
+ arg3=obj2;
+ }
+ {
+ arg4=obj3;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)dsa_set_pqg(arg1,arg2,arg3,arg4);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_dsa_set_pub(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ DSA *arg1 = (DSA *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"dsa_set_pub",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_DSA, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "dsa_set_pub" "', argument " "1"" of type '" "DSA *""'");
+ }
+ arg1 = (DSA *)(argp1);
+ {
+ arg2=obj1;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)dsa_set_pub(arg1,arg2);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_dsa_write_params_bio(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ DSA *arg1 = (DSA *) 0 ;
+ BIO *arg2 = (BIO *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"dsa_write_params_bio",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_DSA, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "dsa_write_params_bio" "', argument " "1"" of type '" "DSA *""'");
+ }
+ arg1 = (DSA *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "dsa_write_params_bio" "', argument " "2"" of type '" "BIO *""'");
+ }
+ arg2 = (BIO *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ result = (int)dsa_write_params_bio(arg1,arg2);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_dsa_write_key_bio(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ DSA *arg1 = (DSA *) 0 ;
+ BIO *arg2 = (BIO *) 0 ;
+ EVP_CIPHER *arg3 = (EVP_CIPHER *) 0 ;
+ PyObject *arg4 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ void *argp3 = 0 ;
+ int res3 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject * obj3 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"dsa_write_key_bio",4,4,&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_DSA, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "dsa_write_key_bio" "', argument " "1"" of type '" "DSA *""'");
+ }
+ arg1 = (DSA *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "dsa_write_key_bio" "', argument " "2"" of type '" "BIO *""'");
+ }
+ arg2 = (BIO *)(argp2);
+ res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_EVP_CIPHER, 0 | 0 );
+ if (!SWIG_IsOK(res3)) {
+ SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "dsa_write_key_bio" "', argument " "3"" of type '" "EVP_CIPHER *""'");
+ }
+ arg3 = (EVP_CIPHER *)(argp3);
+ {
+ if (!PyCallable_Check(obj3)) {
+ PyErr_SetString(PyExc_TypeError, "expected PyCallable");
+ return NULL;
+ }
+ arg4=obj3;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg3) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg4) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)dsa_write_key_bio(arg1,arg2,arg3,arg4);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_dsa_write_key_bio_no_cipher(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ DSA *arg1 = (DSA *) 0 ;
+ BIO *arg2 = (BIO *) 0 ;
+ PyObject *arg3 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"dsa_write_key_bio_no_cipher",3,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_DSA, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "dsa_write_key_bio_no_cipher" "', argument " "1"" of type '" "DSA *""'");
+ }
+ arg1 = (DSA *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "dsa_write_key_bio_no_cipher" "', argument " "2"" of type '" "BIO *""'");
+ }
+ arg2 = (BIO *)(argp2);
+ {
+ if (!PyCallable_Check(obj2)) {
+ PyErr_SetString(PyExc_TypeError, "expected PyCallable");
+ return NULL;
+ }
+ arg3=obj2;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg3) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)dsa_write_key_bio_no_cipher(arg1,arg2,arg3);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_dsa_write_pub_key_bio(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ DSA *arg1 = (DSA *) 0 ;
+ BIO *arg2 = (BIO *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"dsa_write_pub_key_bio",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_DSA, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "dsa_write_pub_key_bio" "', argument " "1"" of type '" "DSA *""'");
+ }
+ arg1 = (DSA *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "dsa_write_pub_key_bio" "', argument " "2"" of type '" "BIO *""'");
+ }
+ arg2 = (BIO *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ result = (int)dsa_write_pub_key_bio(arg1,arg2);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_dsa_sign(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ DSA *arg1 = (DSA *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"dsa_sign",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_DSA, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "dsa_sign" "', argument " "1"" of type '" "DSA *""'");
+ }
+ arg1 = (DSA *)(argp1);
+ {
+ arg2=obj1;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)dsa_sign(arg1,arg2);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_dsa_verify(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ DSA *arg1 = (DSA *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ PyObject *arg3 = (PyObject *) 0 ;
+ PyObject *arg4 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject * obj3 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"dsa_verify",4,4,&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_DSA, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "dsa_verify" "', argument " "1"" of type '" "DSA *""'");
+ }
+ arg1 = (DSA *)(argp1);
+ {
+ arg2=obj1;
+ }
+ {
+ arg3=obj2;
+ }
+ {
+ arg4=obj3;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)dsa_verify(arg1,arg2,arg3,arg4);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_dsa_sign_asn1(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ DSA *arg1 = (DSA *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"dsa_sign_asn1",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_DSA, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "dsa_sign_asn1" "', argument " "1"" of type '" "DSA *""'");
+ }
+ arg1 = (DSA *)(argp1);
+ {
+ arg2=obj1;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)dsa_sign_asn1(arg1,arg2);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_dsa_verify_asn1(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ DSA *arg1 = (DSA *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ PyObject *arg3 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"dsa_verify_asn1",3,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_DSA, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "dsa_verify_asn1" "', argument " "1"" of type '" "DSA *""'");
+ }
+ arg1 = (DSA *)(argp1);
+ {
+ arg2=obj1;
+ }
+ {
+ arg3=obj2;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)dsa_verify_asn1(arg1,arg2,arg3);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_dsa_check_key(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ DSA *arg1 = (DSA *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"dsa_check_key",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_DSA, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "dsa_check_key" "', argument " "1"" of type '" "DSA *""'");
+ }
+ arg1 = (DSA *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)dsa_check_key(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_dsa_check_pub_key(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ DSA *arg1 = (DSA *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"dsa_check_pub_key",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_DSA, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "dsa_check_pub_key" "', argument " "1"" of type '" "DSA *""'");
+ }
+ arg1 = (DSA *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)dsa_check_pub_key(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_dsa_keylen(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ DSA *arg1 = (DSA *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"dsa_keylen",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_DSA, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "dsa_keylen" "', argument " "1"" of type '" "DSA *""'");
+ }
+ arg1 = (DSA *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)dsa_keylen(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_dsa_type_check(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ DSA *arg1 = (DSA *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"dsa_type_check",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_DSA, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "dsa_type_check" "', argument " "1"" of type '" "DSA *""'");
+ }
+ arg1 = (DSA *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)dsa_type_check(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_get_ciphers(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL *arg1 = (SSL *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ struct stack_st_SSL_CIPHER *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_get_ciphers",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_get_ciphers" "', argument " "1"" of type '" "SSL const *""'");
+ }
+ arg1 = (SSL *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (struct stack_st_SSL_CIPHER *)SSL_get_ciphers((SSL const *)arg1);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_stack_st_SSL_CIPHER, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_get_version(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL *arg1 = (SSL *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ char *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_get_version",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_get_version" "', argument " "1"" of type '" "SSL const *""'");
+ }
+ arg1 = (SSL *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (char *)SSL_get_version((SSL const *)arg1);
+ resultobj = SWIG_FromCharPtr((const char *)result);
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_get_error(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL *arg1 = (SSL *) 0 ;
+ int arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_get_error",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_get_error" "', argument " "1"" of type '" "SSL const *""'");
+ }
+ arg1 = (SSL *)(argp1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ssl_get_error" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)SSL_get_error((SSL const *)arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_get_state(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL *arg1 = (SSL *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ char *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_get_state",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_get_state" "', argument " "1"" of type '" "SSL const *""'");
+ }
+ arg1 = (SSL *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (char *)SSL_state_string((SSL const *)arg1);
+ resultobj = SWIG_FromCharPtr((const char *)result);
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_get_state_v(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL *arg1 = (SSL *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ char *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_get_state_v",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_get_state_v" "', argument " "1"" of type '" "SSL const *""'");
+ }
+ arg1 = (SSL *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (char *)SSL_state_string_long((SSL const *)arg1);
+ resultobj = SWIG_FromCharPtr((const char *)result);
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_get_alert_type(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ int arg1 ;
+ int val1 ;
+ int ecode1 = 0 ;
+ PyObject * obj0 = 0 ;
+ char *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_get_alert_type",1,1,&obj0)) SWIG_fail;
+ ecode1 = SWIG_AsVal_int(obj0, &val1);
+ if (!SWIG_IsOK(ecode1)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "ssl_get_alert_type" "', argument " "1"" of type '" "int""'");
+ }
+ arg1 = (int)(val1);
+ result = (char *)SSL_alert_type_string(arg1);
+ resultobj = SWIG_FromCharPtr((const char *)result);
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_get_alert_type_v(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ int arg1 ;
+ int val1 ;
+ int ecode1 = 0 ;
+ PyObject * obj0 = 0 ;
+ char *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_get_alert_type_v",1,1,&obj0)) SWIG_fail;
+ ecode1 = SWIG_AsVal_int(obj0, &val1);
+ if (!SWIG_IsOK(ecode1)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "ssl_get_alert_type_v" "', argument " "1"" of type '" "int""'");
+ }
+ arg1 = (int)(val1);
+ result = (char *)SSL_alert_type_string_long(arg1);
+ resultobj = SWIG_FromCharPtr((const char *)result);
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_get_alert_desc(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ int arg1 ;
+ int val1 ;
+ int ecode1 = 0 ;
+ PyObject * obj0 = 0 ;
+ char *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_get_alert_desc",1,1,&obj0)) SWIG_fail;
+ ecode1 = SWIG_AsVal_int(obj0, &val1);
+ if (!SWIG_IsOK(ecode1)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "ssl_get_alert_desc" "', argument " "1"" of type '" "int""'");
+ }
+ arg1 = (int)(val1);
+ result = (char *)SSL_alert_desc_string(arg1);
+ resultobj = SWIG_FromCharPtr((const char *)result);
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_get_alert_desc_v(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ int arg1 ;
+ int val1 ;
+ int ecode1 = 0 ;
+ PyObject * obj0 = 0 ;
+ char *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_get_alert_desc_v",1,1,&obj0)) SWIG_fail;
+ ecode1 = SWIG_AsVal_int(obj0, &val1);
+ if (!SWIG_IsOK(ecode1)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "ssl_get_alert_desc_v" "', argument " "1"" of type '" "int""'");
+ }
+ arg1 = (int)(val1);
+ result = (char *)SSL_alert_desc_string_long(arg1);
+ resultobj = SWIG_FromCharPtr((const char *)result);
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_sslv23_method(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL_METHOD *result = 0 ;
+
+ result = (SSL_METHOD *)SSLv23_method();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_SSL_METHOD, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_ctx_new(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL_METHOD *arg1 = (SSL_METHOD *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ SSL_CTX *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_ctx_new",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL_METHOD, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_ctx_new" "', argument " "1"" of type '" "SSL_METHOD *""'");
+ }
+ arg1 = (SSL_METHOD *)(argp1);
+ result = (SSL_CTX *)SSL_CTX_new(arg1);
+ {
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+
+ if (result != NULL)
+ resultobj = SWIG_NewPointerObj(result, SWIGTYPE_p_SSL_CTX, 0);
+ else {
+ m2_PyErr_Msg(_ssl_err);
+ resultobj = NULL;
+ }
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_ctx_free(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL_CTX *arg1 = (SSL_CTX *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_ctx_free",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_ctx_free" "', argument " "1"" of type '" "SSL_CTX *""'");
+ }
+ arg1 = (SSL_CTX *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ SSL_CTX_free(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_ctx_set_verify_depth(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL_CTX *arg1 = (SSL_CTX *) 0 ;
+ int arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_ctx_set_verify_depth",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_ctx_set_verify_depth" "', argument " "1"" of type '" "SSL_CTX *""'");
+ }
+ arg1 = (SSL_CTX *)(argp1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ssl_ctx_set_verify_depth" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ SSL_CTX_set_verify_depth(arg1,arg2);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_ctx_get_verify_depth(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL_CTX *arg1 = (SSL_CTX *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_ctx_get_verify_depth",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_ctx_get_verify_depth" "', argument " "1"" of type '" "SSL_CTX const *""'");
+ }
+ arg1 = (SSL_CTX *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)SSL_CTX_get_verify_depth((SSL_CTX const *)arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_ctx_get_verify_mode(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL_CTX *arg1 = (SSL_CTX *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_ctx_get_verify_mode",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_ctx_get_verify_mode" "', argument " "1"" of type '" "SSL_CTX const *""'");
+ }
+ arg1 = (SSL_CTX *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)SSL_CTX_get_verify_mode((SSL_CTX const *)arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_ctx_set_cipher_list(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL_CTX *arg1 = (SSL_CTX *) 0 ;
+ char *arg2 = (char *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ int alloc2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_ctx_set_cipher_list",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_ctx_set_cipher_list" "', argument " "1"" of type '" "SSL_CTX *""'");
+ }
+ arg1 = (SSL_CTX *)(argp1);
+ res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ssl_ctx_set_cipher_list" "', argument " "2"" of type '" "char const *""'");
+ }
+ arg2 = (char *)(buf2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)SSL_CTX_set_cipher_list(arg1,(char const *)arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return resultobj;
+fail:
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_ctx_add_session(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL_CTX *arg1 = (SSL_CTX *) 0 ;
+ SSL_SESSION *arg2 = (SSL_SESSION *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_ctx_add_session",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_ctx_add_session" "', argument " "1"" of type '" "SSL_CTX *""'");
+ }
+ arg1 = (SSL_CTX *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_SSL_SESSION, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ssl_ctx_add_session" "', argument " "2"" of type '" "SSL_SESSION *""'");
+ }
+ arg2 = (SSL_SESSION *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)SSL_CTX_add_session(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_ctx_remove_session(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL_CTX *arg1 = (SSL_CTX *) 0 ;
+ SSL_SESSION *arg2 = (SSL_SESSION *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_ctx_remove_session",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_ctx_remove_session" "', argument " "1"" of type '" "SSL_CTX *""'");
+ }
+ arg1 = (SSL_CTX *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_SSL_SESSION, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ssl_ctx_remove_session" "', argument " "2"" of type '" "SSL_SESSION *""'");
+ }
+ arg2 = (SSL_SESSION *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)SSL_CTX_remove_session(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_ctx_set_session_timeout(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL_CTX *arg1 = (SSL_CTX *) 0 ;
+ long arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ long val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ long result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_ctx_set_session_timeout",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_ctx_set_session_timeout" "', argument " "1"" of type '" "SSL_CTX *""'");
+ }
+ arg1 = (SSL_CTX *)(argp1);
+ ecode2 = SWIG_AsVal_long(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ssl_ctx_set_session_timeout" "', argument " "2"" of type '" "long""'");
+ }
+ arg2 = (long)(val2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (long)SSL_CTX_set_timeout(arg1,arg2);
+ resultobj = SWIG_From_long((long)(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_ctx_get_session_timeout(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL_CTX *arg1 = (SSL_CTX *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ long result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_ctx_get_session_timeout",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_ctx_get_session_timeout" "', argument " "1"" of type '" "SSL_CTX const *""'");
+ }
+ arg1 = (SSL_CTX *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (long)SSL_CTX_get_timeout((SSL_CTX const *)arg1);
+ resultobj = SWIG_From_long((long)(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_ctx_get_cert_store(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL_CTX *arg1 = (SSL_CTX *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ X509_STORE *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_ctx_get_cert_store",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_ctx_get_cert_store" "', argument " "1"" of type '" "SSL_CTX const *""'");
+ }
+ arg1 = (SSL_CTX *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (X509_STORE *)SSL_CTX_get_cert_store((SSL_CTX const *)arg1);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_X509_STORE, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_ctx_set_default_verify_paths(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL_CTX *arg1 = (SSL_CTX *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_ctx_set_default_verify_paths",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_ctx_set_default_verify_paths" "', argument " "1"" of type '" "SSL_CTX *""'");
+ }
+ arg1 = (SSL_CTX *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)SSL_CTX_set_default_verify_paths(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_get_ex_data_x509_store_ctx_idx(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ int result;
+
+ result = (int)SSL_get_ex_data_X509_STORE_CTX_idx();
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bio_new_ssl(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL_CTX *arg1 = (SSL_CTX *) 0 ;
+ int arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ BIO *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"bio_new_ssl",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bio_new_ssl" "', argument " "1"" of type '" "SSL_CTX *""'");
+ }
+ arg1 = (SSL_CTX *)(argp1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "bio_new_ssl" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (BIO *)BIO_new_ssl(arg1,arg2);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_BIO, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_new(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL_CTX *arg1 = (SSL_CTX *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ SSL *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_new",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_new" "', argument " "1"" of type '" "SSL_CTX *""'");
+ }
+ arg1 = (SSL_CTX *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (SSL *)SSL_new(arg1);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_SSL, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_free(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL *arg1 = (SSL *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_free",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_free" "', argument " "1"" of type '" "SSL *""'");
+ }
+ arg1 = (SSL *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ SSL_free(arg1);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_dup(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL *arg1 = (SSL *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ SSL *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_dup",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_dup" "', argument " "1"" of type '" "SSL *""'");
+ }
+ arg1 = (SSL *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (SSL *)SSL_dup(arg1);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_SSL, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_set_bio(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL *arg1 = (SSL *) 0 ;
+ BIO *arg2 = (BIO *) 0 ;
+ BIO *arg3 = (BIO *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ void *argp3 = 0 ;
+ int res3 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_set_bio",3,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_set_bio" "', argument " "1"" of type '" "SSL *""'");
+ }
+ arg1 = (SSL *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ssl_set_bio" "', argument " "2"" of type '" "BIO *""'");
+ }
+ arg2 = (BIO *)(argp2);
+ res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res3)) {
+ SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "ssl_set_bio" "', argument " "3"" of type '" "BIO *""'");
+ }
+ arg3 = (BIO *)(argp3);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg3) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ SSL_set_bio(arg1,arg2,arg3);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_set_accept_state(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL *arg1 = (SSL *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_set_accept_state",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_set_accept_state" "', argument " "1"" of type '" "SSL *""'");
+ }
+ arg1 = (SSL *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ SSL_set_accept_state(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_set_connect_state(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL *arg1 = (SSL *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_set_connect_state",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_set_connect_state" "', argument " "1"" of type '" "SSL *""'");
+ }
+ arg1 = (SSL *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ SSL_set_connect_state(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_get_shutdown(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL *arg1 = (SSL *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_get_shutdown",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_get_shutdown" "', argument " "1"" of type '" "SSL const *""'");
+ }
+ arg1 = (SSL *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)SSL_get_shutdown((SSL const *)arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_set_shutdown(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL *arg1 = (SSL *) 0 ;
+ int arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_set_shutdown",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_set_shutdown" "', argument " "1"" of type '" "SSL *""'");
+ }
+ arg1 = (SSL *)(argp1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ssl_set_shutdown" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ SSL_set_shutdown(arg1,arg2);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_shutdown(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL *arg1 = (SSL *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_shutdown",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_shutdown" "', argument " "1"" of type '" "SSL *""'");
+ }
+ arg1 = (SSL *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ result = (int)SSL_shutdown(arg1);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_clear(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL *arg1 = (SSL *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_clear",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_clear" "', argument " "1"" of type '" "SSL *""'");
+ }
+ arg1 = (SSL *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)SSL_clear(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_do_handshake(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL *arg1 = (SSL *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_do_handshake",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_do_handshake" "', argument " "1"" of type '" "SSL *""'");
+ }
+ arg1 = (SSL *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ result = (int)SSL_do_handshake(arg1);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_renegotiate(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL *arg1 = (SSL *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_renegotiate",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_renegotiate" "', argument " "1"" of type '" "SSL *""'");
+ }
+ arg1 = (SSL *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ result = (int)SSL_renegotiate(arg1);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_pending(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL *arg1 = (SSL *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_pending",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_pending" "', argument " "1"" of type '" "SSL const *""'");
+ }
+ arg1 = (SSL *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)SSL_pending((SSL const *)arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_get_peer_cert(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL *arg1 = (SSL *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ X509 *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_get_peer_cert",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_get_peer_cert" "', argument " "1"" of type '" "SSL const *""'");
+ }
+ arg1 = (SSL *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (X509 *)SSL_get_peer_certificate((SSL const *)arg1);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_X509, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_get_current_cipher(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL *arg1 = (SSL *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ SSL_CIPHER *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_get_current_cipher",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_get_current_cipher" "', argument " "1"" of type '" "SSL const *""'");
+ }
+ arg1 = (SSL *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (SSL_CIPHER *)SSL_get_current_cipher((SSL const *)arg1);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_SSL_CIPHER, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_get_verify_mode(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL *arg1 = (SSL *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_get_verify_mode",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_get_verify_mode" "', argument " "1"" of type '" "SSL const *""'");
+ }
+ arg1 = (SSL *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)SSL_get_verify_mode((SSL const *)arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_get_verify_depth(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL *arg1 = (SSL *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_get_verify_depth",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_get_verify_depth" "', argument " "1"" of type '" "SSL const *""'");
+ }
+ arg1 = (SSL *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)SSL_get_verify_depth((SSL const *)arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_get_verify_result(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL *arg1 = (SSL *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ long result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_get_verify_result",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_get_verify_result" "', argument " "1"" of type '" "SSL const *""'");
+ }
+ arg1 = (SSL *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (long)SSL_get_verify_result((SSL const *)arg1);
+ resultobj = SWIG_From_long((long)(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_get_ssl_ctx(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL *arg1 = (SSL *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ SSL_CTX *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_get_ssl_ctx",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_get_ssl_ctx" "', argument " "1"" of type '" "SSL const *""'");
+ }
+ arg1 = (SSL *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (SSL_CTX *)SSL_get_SSL_CTX((SSL const *)arg1);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_SSL_CTX, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_get_default_session_timeout(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL *arg1 = (SSL *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ long result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_get_default_session_timeout",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_get_default_session_timeout" "', argument " "1"" of type '" "SSL const *""'");
+ }
+ arg1 = (SSL *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (long)SSL_get_default_timeout((SSL const *)arg1);
+ resultobj = SWIG_From_long((long)(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_set_cipher_list(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL *arg1 = (SSL *) 0 ;
+ char *arg2 = (char *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ int alloc2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_set_cipher_list",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_set_cipher_list" "', argument " "1"" of type '" "SSL *""'");
+ }
+ arg1 = (SSL *)(argp1);
+ res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ssl_set_cipher_list" "', argument " "2"" of type '" "char const *""'");
+ }
+ arg2 = (char *)(buf2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)SSL_set_cipher_list(arg1,(char const *)arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return resultobj;
+fail:
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_get_cipher_list(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL *arg1 = (SSL *) 0 ;
+ int arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ char *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_get_cipher_list",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_get_cipher_list" "', argument " "1"" of type '" "SSL const *""'");
+ }
+ arg1 = (SSL *)(argp1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ssl_get_cipher_list" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (char *)SSL_get_cipher_list((SSL const *)arg1,arg2);
+ resultobj = SWIG_FromCharPtr((const char *)result);
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_cipher_get_name(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL_CIPHER *arg1 = (SSL_CIPHER *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ char *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_cipher_get_name",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL_CIPHER, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_cipher_get_name" "', argument " "1"" of type '" "SSL_CIPHER const *""'");
+ }
+ arg1 = (SSL_CIPHER *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (char *)SSL_CIPHER_get_name((SSL_CIPHER const *)arg1);
+ resultobj = SWIG_FromCharPtr((const char *)result);
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_cipher_get_version(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL_CIPHER *arg1 = (SSL_CIPHER *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ char *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_cipher_get_version",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL_CIPHER, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_cipher_get_version" "', argument " "1"" of type '" "SSL_CIPHER const *""'");
+ }
+ arg1 = (SSL_CIPHER *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (char *)SSL_CIPHER_get_version((SSL_CIPHER const *)arg1);
+ resultobj = SWIG_FromCharPtr((const char *)result);
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_get_session(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL *arg1 = (SSL *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ SSL_SESSION *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_get_session",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_get_session" "', argument " "1"" of type '" "SSL const *""'");
+ }
+ arg1 = (SSL *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (SSL_SESSION *)SSL_get_session((SSL const *)arg1);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_SSL_SESSION, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_get1_session(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL *arg1 = (SSL *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ SSL_SESSION *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_get1_session",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_get1_session" "', argument " "1"" of type '" "SSL *""'");
+ }
+ arg1 = (SSL *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (SSL_SESSION *)SSL_get1_session(arg1);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_SSL_SESSION, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_set_session(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL *arg1 = (SSL *) 0 ;
+ SSL_SESSION *arg2 = (SSL_SESSION *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_set_session",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_set_session" "', argument " "1"" of type '" "SSL *""'");
+ }
+ arg1 = (SSL *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_SSL_SESSION, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ssl_set_session" "', argument " "2"" of type '" "SSL_SESSION *""'");
+ }
+ arg2 = (SSL_SESSION *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)SSL_set_session(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_session_free(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL_SESSION *arg1 = (SSL_SESSION *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_session_free",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL_SESSION, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_session_free" "', argument " "1"" of type '" "SSL_SESSION *""'");
+ }
+ arg1 = (SSL_SESSION *)(argp1);
+ SSL_SESSION_free(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_session_print(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ SSL_SESSION *arg2 = (SSL_SESSION *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_session_print",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_session_print" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_SSL_SESSION, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ssl_session_print" "', argument " "2"" of type '" "SSL_SESSION const *""'");
+ }
+ arg2 = (SSL_SESSION *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ result = (int)SSL_SESSION_print(arg1,(SSL_SESSION const *)arg2);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_session_set_timeout(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL_SESSION *arg1 = (SSL_SESSION *) 0 ;
+ long arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ long val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ long result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_session_set_timeout",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL_SESSION, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_session_set_timeout" "', argument " "1"" of type '" "SSL_SESSION *""'");
+ }
+ arg1 = (SSL_SESSION *)(argp1);
+ ecode2 = SWIG_AsVal_long(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ssl_session_set_timeout" "', argument " "2"" of type '" "long""'");
+ }
+ arg2 = (long)(val2);
+ result = (long)SSL_SESSION_set_timeout(arg1,arg2);
+ resultobj = SWIG_From_long((long)(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_session_get_timeout(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL_SESSION *arg1 = (SSL_SESSION *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ long result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_session_get_timeout",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL_SESSION, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_session_get_timeout" "', argument " "1"" of type '" "SSL_SESSION const *""'");
+ }
+ arg1 = (SSL_SESSION *)(argp1);
+ result = (long)SSL_SESSION_get_timeout((SSL_SESSION const *)arg1);
+ resultobj = SWIG_From_long((long)(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_accept(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL *arg1 = (SSL *) 0 ;
+ double arg2 = (double) -1 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ double val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_accept",1,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_accept" "', argument " "1"" of type '" "SSL *""'");
+ }
+ arg1 = (SSL *)(argp1);
+ if (obj1) {
+ ecode2 = SWIG_AsVal_double(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ssl_accept" "', argument " "2"" of type '" "double""'");
+ }
+ arg2 = (double)(val2);
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)ssl_accept(arg1,arg2);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_connect(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL *arg1 = (SSL *) 0 ;
+ double arg2 = (double) -1 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ double val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_connect",1,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_connect" "', argument " "1"" of type '" "SSL *""'");
+ }
+ arg1 = (SSL *)(argp1);
+ if (obj1) {
+ ecode2 = SWIG_AsVal_double(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ssl_connect" "', argument " "2"" of type '" "double""'");
+ }
+ arg2 = (double)(val2);
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)ssl_connect(arg1,arg2);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_read(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL *arg1 = (SSL *) 0 ;
+ int arg2 ;
+ double arg3 = (double) -1 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ double val3 ;
+ int ecode3 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_read",2,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_read" "', argument " "1"" of type '" "SSL *""'");
+ }
+ arg1 = (SSL *)(argp1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ssl_read" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ if (obj2) {
+ ecode3 = SWIG_AsVal_double(obj2, &val3);
+ if (!SWIG_IsOK(ecode3)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "ssl_read" "', argument " "3"" of type '" "double""'");
+ }
+ arg3 = (double)(val3);
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)ssl_read(arg1,arg2,arg3);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_write(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL *arg1 = (SSL *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ double arg3 = (double) -1 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ double val3 ;
+ int ecode3 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_write",2,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_write" "', argument " "1"" of type '" "SSL *""'");
+ }
+ arg1 = (SSL *)(argp1);
+ {
+ arg2=obj1;
+ }
+ if (obj2) {
+ ecode3 = SWIG_AsVal_double(obj2, &val3);
+ if (!SWIG_IsOK(ecode3)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "ssl_write" "', argument " "3"" of type '" "double""'");
+ }
+ arg3 = (double)(val3);
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)ssl_write(arg1,arg2,arg3);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN int Swig_var__ssl_err_set(PyObject *_val) {
+ {
+ void *argp = 0;
+ int res = SWIG_ConvertPtr(_val, &argp, SWIGTYPE_p_PyObject, 0 );
+ if (!SWIG_IsOK(res)) {
+ SWIG_exception_fail(SWIG_ArgError(res), "in variable '""_ssl_err""' of type '""PyObject *""'");
+ }
+ _ssl_err = (PyObject *)(argp);
+ }
+ return 0;
+fail:
+ return 1;
+}
+
+
+SWIGINTERN PyObject *Swig_var__ssl_err_get(void) {
+ PyObject *pyobj = 0;
+ PyObject *self = 0;
+
+ (void)self;
+ pyobj = SWIG_NewPointerObj(SWIG_as_voidptr(_ssl_err), SWIGTYPE_p_PyObject, 0 );
+ return pyobj;
+}
+
+
+SWIGINTERN int Swig_var__ssl_timeout_err_set(PyObject *_val) {
+ {
+ void *argp = 0;
+ int res = SWIG_ConvertPtr(_val, &argp, SWIGTYPE_p_PyObject, 0 );
+ if (!SWIG_IsOK(res)) {
+ SWIG_exception_fail(SWIG_ArgError(res), "in variable '""_ssl_timeout_err""' of type '""PyObject *""'");
+ }
+ _ssl_timeout_err = (PyObject *)(argp);
+ }
+ return 0;
+fail:
+ return 1;
+}
+
+
+SWIGINTERN PyObject *Swig_var__ssl_timeout_err_get(void) {
+ PyObject *pyobj = 0;
+ PyObject *self = 0;
+
+ (void)self;
+ pyobj = SWIG_NewPointerObj(SWIG_as_voidptr(_ssl_timeout_err), SWIGTYPE_p_PyObject, 0 );
+ return pyobj;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_init(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ PyObject *arg1 = (PyObject *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_init",2,2,&obj0,&obj1)) SWIG_fail;
+ {
+ arg1=obj0;
+ }
+ {
+ arg2=obj1;
+ }
+ ssl_init(arg1,arg2);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_tlsv1_method(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL_METHOD *result = 0 ;
+
+ result = (SSL_METHOD *)tlsv1_method();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_SSL_METHOD, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_ctx_passphrase_callback(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL_CTX *arg1 = (SSL_CTX *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_ctx_passphrase_callback",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_ctx_passphrase_callback" "', argument " "1"" of type '" "SSL_CTX *""'");
+ }
+ arg1 = (SSL_CTX *)(argp1);
+ {
+ if (!PyCallable_Check(obj1)) {
+ PyErr_SetString(PyExc_TypeError, "expected PyCallable");
+ return NULL;
+ }
+ arg2=obj1;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ ssl_ctx_passphrase_callback(arg1,arg2);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_ctx_use_x509(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL_CTX *arg1 = (SSL_CTX *) 0 ;
+ X509 *arg2 = (X509 *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_ctx_use_x509",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_ctx_use_x509" "', argument " "1"" of type '" "SSL_CTX *""'");
+ }
+ arg1 = (SSL_CTX *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_X509, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ssl_ctx_use_x509" "', argument " "2"" of type '" "X509 *""'");
+ }
+ arg2 = (X509 *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)ssl_ctx_use_x509(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_ctx_use_cert(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL_CTX *arg1 = (SSL_CTX *) 0 ;
+ char *arg2 = (char *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ int alloc2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_ctx_use_cert",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_ctx_use_cert" "', argument " "1"" of type '" "SSL_CTX *""'");
+ }
+ arg1 = (SSL_CTX *)(argp1);
+ res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ssl_ctx_use_cert" "', argument " "2"" of type '" "char *""'");
+ }
+ arg2 = (char *)(buf2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)ssl_ctx_use_cert(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return resultobj;
+fail:
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_ctx_use_cert_chain(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL_CTX *arg1 = (SSL_CTX *) 0 ;
+ char *arg2 = (char *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ int alloc2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_ctx_use_cert_chain",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_ctx_use_cert_chain" "', argument " "1"" of type '" "SSL_CTX *""'");
+ }
+ arg1 = (SSL_CTX *)(argp1);
+ res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ssl_ctx_use_cert_chain" "', argument " "2"" of type '" "char *""'");
+ }
+ arg2 = (char *)(buf2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)ssl_ctx_use_cert_chain(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return resultobj;
+fail:
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_ctx_use_privkey(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL_CTX *arg1 = (SSL_CTX *) 0 ;
+ char *arg2 = (char *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ int alloc2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_ctx_use_privkey",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_ctx_use_privkey" "', argument " "1"" of type '" "SSL_CTX *""'");
+ }
+ arg1 = (SSL_CTX *)(argp1);
+ res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ssl_ctx_use_privkey" "', argument " "2"" of type '" "char *""'");
+ }
+ arg2 = (char *)(buf2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)ssl_ctx_use_privkey(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return resultobj;
+fail:
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_ctx_use_rsa_privkey(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL_CTX *arg1 = (SSL_CTX *) 0 ;
+ RSA *arg2 = (RSA *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_ctx_use_rsa_privkey",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_ctx_use_rsa_privkey" "', argument " "1"" of type '" "SSL_CTX *""'");
+ }
+ arg1 = (SSL_CTX *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_RSA, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ssl_ctx_use_rsa_privkey" "', argument " "2"" of type '" "RSA *""'");
+ }
+ arg2 = (RSA *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)ssl_ctx_use_rsa_privkey(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_ctx_use_pkey_privkey(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL_CTX *arg1 = (SSL_CTX *) 0 ;
+ EVP_PKEY *arg2 = (EVP_PKEY *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_ctx_use_pkey_privkey",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_ctx_use_pkey_privkey" "', argument " "1"" of type '" "SSL_CTX *""'");
+ }
+ arg1 = (SSL_CTX *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_EVP_PKEY, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ssl_ctx_use_pkey_privkey" "', argument " "2"" of type '" "EVP_PKEY *""'");
+ }
+ arg2 = (EVP_PKEY *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)ssl_ctx_use_pkey_privkey(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_ctx_check_privkey(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL_CTX *arg1 = (SSL_CTX *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_ctx_check_privkey",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_ctx_check_privkey" "', argument " "1"" of type '" "SSL_CTX *""'");
+ }
+ arg1 = (SSL_CTX *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)ssl_ctx_check_privkey(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_ctx_set_client_CA_list_from_file(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL_CTX *arg1 = (SSL_CTX *) 0 ;
+ char *arg2 = (char *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ int alloc2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_ctx_set_client_CA_list_from_file",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_ctx_set_client_CA_list_from_file" "', argument " "1"" of type '" "SSL_CTX *""'");
+ }
+ arg1 = (SSL_CTX *)(argp1);
+ res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ssl_ctx_set_client_CA_list_from_file" "', argument " "2"" of type '" "char const *""'");
+ }
+ arg2 = (char *)(buf2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ ssl_ctx_set_client_CA_list_from_file(arg1,(char const *)arg2);
+ resultobj = SWIG_Py_Void();
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return resultobj;
+fail:
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_ctx_set_verify_default(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL_CTX *arg1 = (SSL_CTX *) 0 ;
+ int arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_ctx_set_verify_default",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_ctx_set_verify_default" "', argument " "1"" of type '" "SSL_CTX *""'");
+ }
+ arg1 = (SSL_CTX *)(argp1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ssl_ctx_set_verify_default" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ ssl_ctx_set_verify_default(arg1,arg2);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_ctx_set_verify(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL_CTX *arg1 = (SSL_CTX *) 0 ;
+ int arg2 ;
+ PyObject *arg3 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_ctx_set_verify",3,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_ctx_set_verify" "', argument " "1"" of type '" "SSL_CTX *""'");
+ }
+ arg1 = (SSL_CTX *)(argp1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ssl_ctx_set_verify" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ {
+ if (!PyCallable_Check(obj2)) {
+ PyErr_SetString(PyExc_TypeError, "expected PyCallable");
+ return NULL;
+ }
+ arg3=obj2;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg3) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ ssl_ctx_set_verify(arg1,arg2,arg3);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_ctx_set_session_id_context(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL_CTX *arg1 = (SSL_CTX *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_ctx_set_session_id_context",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_ctx_set_session_id_context" "', argument " "1"" of type '" "SSL_CTX *""'");
+ }
+ arg1 = (SSL_CTX *)(argp1);
+ {
+ arg2=obj1;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)ssl_ctx_set_session_id_context(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_ctx_set_info_callback(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL_CTX *arg1 = (SSL_CTX *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_ctx_set_info_callback",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_ctx_set_info_callback" "', argument " "1"" of type '" "SSL_CTX *""'");
+ }
+ arg1 = (SSL_CTX *)(argp1);
+ {
+ if (!PyCallable_Check(obj1)) {
+ PyErr_SetString(PyExc_TypeError, "expected PyCallable");
+ return NULL;
+ }
+ arg2=obj1;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ ssl_ctx_set_info_callback(arg1,arg2);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_ctx_set_tmp_dh(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL_CTX *arg1 = (SSL_CTX *) 0 ;
+ DH *arg2 = (DH *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ long result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_ctx_set_tmp_dh",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_ctx_set_tmp_dh" "', argument " "1"" of type '" "SSL_CTX *""'");
+ }
+ arg1 = (SSL_CTX *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_DH, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ssl_ctx_set_tmp_dh" "', argument " "2"" of type '" "DH *""'");
+ }
+ arg2 = (DH *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (long)ssl_ctx_set_tmp_dh(arg1,arg2);
+ resultobj = SWIG_From_long((long)(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_ctx_set_tmp_dh_callback(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL_CTX *arg1 = (SSL_CTX *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_ctx_set_tmp_dh_callback",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_ctx_set_tmp_dh_callback" "', argument " "1"" of type '" "SSL_CTX *""'");
+ }
+ arg1 = (SSL_CTX *)(argp1);
+ {
+ if (!PyCallable_Check(obj1)) {
+ PyErr_SetString(PyExc_TypeError, "expected PyCallable");
+ return NULL;
+ }
+ arg2=obj1;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ ssl_ctx_set_tmp_dh_callback(arg1,arg2);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_ctx_set_tmp_rsa(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL_CTX *arg1 = (SSL_CTX *) 0 ;
+ RSA *arg2 = (RSA *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ long result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_ctx_set_tmp_rsa",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_ctx_set_tmp_rsa" "', argument " "1"" of type '" "SSL_CTX *""'");
+ }
+ arg1 = (SSL_CTX *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_RSA, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ssl_ctx_set_tmp_rsa" "', argument " "2"" of type '" "RSA *""'");
+ }
+ arg2 = (RSA *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (long)ssl_ctx_set_tmp_rsa(arg1,arg2);
+ resultobj = SWIG_From_long((long)(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_ctx_set_tmp_rsa_callback(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL_CTX *arg1 = (SSL_CTX *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_ctx_set_tmp_rsa_callback",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_ctx_set_tmp_rsa_callback" "', argument " "1"" of type '" "SSL_CTX *""'");
+ }
+ arg1 = (SSL_CTX *)(argp1);
+ {
+ if (!PyCallable_Check(obj1)) {
+ PyErr_SetString(PyExc_TypeError, "expected PyCallable");
+ return NULL;
+ }
+ arg2=obj1;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ ssl_ctx_set_tmp_rsa_callback(arg1,arg2);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_ctx_load_verify_locations(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL_CTX *arg1 = (SSL_CTX *) 0 ;
+ char *arg2 = (char *) 0 ;
+ char *arg3 = (char *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ int alloc2 = 0 ;
+ int res3 ;
+ char *buf3 = 0 ;
+ int alloc3 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_ctx_load_verify_locations",3,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_ctx_load_verify_locations" "', argument " "1"" of type '" "SSL_CTX *""'");
+ }
+ arg1 = (SSL_CTX *)(argp1);
+ res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ssl_ctx_load_verify_locations" "', argument " "2"" of type '" "char const *""'");
+ }
+ arg2 = (char *)(buf2);
+ res3 = SWIG_AsCharPtrAndSize(obj2, &buf3, NULL, &alloc3);
+ if (!SWIG_IsOK(res3)) {
+ SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "ssl_ctx_load_verify_locations" "', argument " "3"" of type '" "char const *""'");
+ }
+ arg3 = (char *)(buf3);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)ssl_ctx_load_verify_locations(arg1,(char const *)arg2,(char const *)arg3);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ if (alloc3 == SWIG_NEWOBJ) free((char*)buf3);
+ return resultobj;
+fail:
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ if (alloc3 == SWIG_NEWOBJ) free((char*)buf3);
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_ctx_set_options(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL_CTX *arg1 = (SSL_CTX *) 0 ;
+ long arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ long val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ long result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_ctx_set_options",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_ctx_set_options" "', argument " "1"" of type '" "SSL_CTX *""'");
+ }
+ arg1 = (SSL_CTX *)(argp1);
+ ecode2 = SWIG_AsVal_long(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ssl_ctx_set_options" "', argument " "2"" of type '" "long""'");
+ }
+ arg2 = (long)(val2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (long)ssl_ctx_set_options(arg1,arg2);
+ resultobj = SWIG_From_long((long)(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bio_set_ssl(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ SSL *arg2 = (SSL *) 0 ;
+ int arg3 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ int val3 ;
+ int ecode3 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"bio_set_ssl",3,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bio_set_ssl" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "bio_set_ssl" "', argument " "2"" of type '" "SSL *""'");
+ }
+ arg2 = (SSL *)(argp2);
+ ecode3 = SWIG_AsVal_int(obj2, &val3);
+ if (!SWIG_IsOK(ecode3)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "bio_set_ssl" "', argument " "3"" of type '" "int""'");
+ }
+ arg3 = (int)(val3);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)bio_set_ssl(arg1,arg2,arg3);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_set_mode(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL *arg1 = (SSL *) 0 ;
+ long arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ long val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ long result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_set_mode",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_set_mode" "', argument " "1"" of type '" "SSL *""'");
+ }
+ arg1 = (SSL *)(argp1);
+ ecode2 = SWIG_AsVal_long(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ssl_set_mode" "', argument " "2"" of type '" "long""'");
+ }
+ arg2 = (long)(val2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (long)ssl_set_mode(arg1,arg2);
+ resultobj = SWIG_From_long((long)(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_get_mode(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL *arg1 = (SSL *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ long result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_get_mode",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_get_mode" "', argument " "1"" of type '" "SSL *""'");
+ }
+ arg1 = (SSL *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (long)ssl_get_mode(arg1);
+ resultobj = SWIG_From_long((long)(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_set_tlsext_host_name(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL *arg1 = (SSL *) 0 ;
+ char *arg2 = (char *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ int alloc2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_set_tlsext_host_name",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_set_tlsext_host_name" "', argument " "1"" of type '" "SSL *""'");
+ }
+ arg1 = (SSL *)(argp1);
+ res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ssl_set_tlsext_host_name" "', argument " "2"" of type '" "char const *""'");
+ }
+ arg2 = (char *)(buf2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)ssl_set_tlsext_host_name(arg1,(char const *)arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return resultobj;
+fail:
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_set_client_CA_list_from_file(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL *arg1 = (SSL *) 0 ;
+ char *arg2 = (char *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ int alloc2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_set_client_CA_list_from_file",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_set_client_CA_list_from_file" "', argument " "1"" of type '" "SSL *""'");
+ }
+ arg1 = (SSL *)(argp1);
+ res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ssl_set_client_CA_list_from_file" "', argument " "2"" of type '" "char const *""'");
+ }
+ arg2 = (char *)(buf2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ ssl_set_client_CA_list_from_file(arg1,(char const *)arg2);
+ resultobj = SWIG_Py_Void();
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return resultobj;
+fail:
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_set_client_CA_list_from_context(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL *arg1 = (SSL *) 0 ;
+ SSL_CTX *arg2 = (SSL_CTX *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_set_client_CA_list_from_context",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_set_client_CA_list_from_context" "', argument " "1"" of type '" "SSL *""'");
+ }
+ arg1 = (SSL *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_SSL_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ssl_set_client_CA_list_from_context" "', argument " "2"" of type '" "SSL_CTX *""'");
+ }
+ arg2 = (SSL_CTX *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ ssl_set_client_CA_list_from_context(arg1,arg2);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_set_session_id_context(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL *arg1 = (SSL *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_set_session_id_context",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_set_session_id_context" "', argument " "1"" of type '" "SSL *""'");
+ }
+ arg1 = (SSL *)(argp1);
+ {
+ arg2=obj1;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)ssl_set_session_id_context(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_set_fd(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL *arg1 = (SSL *) 0 ;
+ int arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_set_fd",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_set_fd" "', argument " "1"" of type '" "SSL *""'");
+ }
+ arg1 = (SSL *)(argp1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ssl_set_fd" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)ssl_set_fd(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_set_shutdown1(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL *arg1 = (SSL *) 0 ;
+ int arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_set_shutdown1",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_set_shutdown1" "', argument " "1"" of type '" "SSL *""'");
+ }
+ arg1 = (SSL *)(argp1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ssl_set_shutdown1" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ ssl_set_shutdown1(arg1,arg2);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_read_nbio(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL *arg1 = (SSL *) 0 ;
+ int arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_read_nbio",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_read_nbio" "', argument " "1"" of type '" "SSL *""'");
+ }
+ arg1 = (SSL *)(argp1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ssl_read_nbio" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)ssl_read_nbio(arg1,arg2);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_write_nbio(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL *arg1 = (SSL *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_write_nbio",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_write_nbio" "', argument " "1"" of type '" "SSL *""'");
+ }
+ arg1 = (SSL *)(argp1);
+ {
+ arg2=obj1;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)ssl_write_nbio(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_cipher_get_bits(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL_CIPHER *arg1 = (SSL_CIPHER *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_cipher_get_bits",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL_CIPHER, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_cipher_get_bits" "', argument " "1"" of type '" "SSL_CIPHER *""'");
+ }
+ arg1 = (SSL_CIPHER *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)ssl_cipher_get_bits(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_sk_ssl_cipher_num(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ struct stack_st_SSL_CIPHER *arg1 = (struct stack_st_SSL_CIPHER *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"sk_ssl_cipher_num",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_stack_st_SSL_CIPHER, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "sk_ssl_cipher_num" "', argument " "1"" of type '" "struct stack_st_SSL_CIPHER *""'");
+ }
+ arg1 = (struct stack_st_SSL_CIPHER *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)sk_ssl_cipher_num(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_sk_ssl_cipher_value(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ struct stack_st_SSL_CIPHER *arg1 = (struct stack_st_SSL_CIPHER *) 0 ;
+ int arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ SSL_CIPHER *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"sk_ssl_cipher_value",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_stack_st_SSL_CIPHER, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "sk_ssl_cipher_value" "', argument " "1"" of type '" "struct stack_st_SSL_CIPHER *""'");
+ }
+ arg1 = (struct stack_st_SSL_CIPHER *)(argp1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "sk_ssl_cipher_value" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (SSL_CIPHER *)sk_ssl_cipher_value(arg1,arg2);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_SSL_CIPHER, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_get_peer_cert_chain(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL *arg1 = (SSL *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ struct stack_st_X509 *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_get_peer_cert_chain",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_get_peer_cert_chain" "', argument " "1"" of type '" "SSL *""'");
+ }
+ arg1 = (SSL *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (struct stack_st_X509 *)ssl_get_peer_cert_chain(arg1);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_stack_st_X509, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_sk_x509_num(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ struct stack_st_X509 *arg1 = (struct stack_st_X509 *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"sk_x509_num",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_stack_st_X509, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "sk_x509_num" "', argument " "1"" of type '" "struct stack_st_X509 *""'");
+ }
+ arg1 = (struct stack_st_X509 *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)sk_x509_num(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_sk_x509_value(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ struct stack_st_X509 *arg1 = (struct stack_st_X509 *) 0 ;
+ int arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ X509 *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"sk_x509_value",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_stack_st_X509, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "sk_x509_value" "', argument " "1"" of type '" "struct stack_st_X509 *""'");
+ }
+ arg1 = (struct stack_st_X509 *)(argp1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "sk_x509_value" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (X509 *)sk_x509_value(arg1,arg2);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_X509, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_i2d_ssl_session(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ SSL_SESSION *arg2 = (SSL_SESSION *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"i2d_ssl_session",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "i2d_ssl_session" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_SSL_SESSION, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "i2d_ssl_session" "', argument " "2"" of type '" "SSL_SESSION *""'");
+ }
+ arg2 = (SSL_SESSION *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ i2d_ssl_session(arg1,arg2);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_session_read_pem(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ SSL_SESSION *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_session_read_pem",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_session_read_pem" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ result = (SSL_SESSION *)ssl_session_read_pem(arg1);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ {
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+
+ if (result != NULL)
+ resultobj = SWIG_NewPointerObj(result, SWIGTYPE_p_SSL_SESSION, 0);
+ else {
+ m2_PyErr_Msg(_ssl_err);
+ resultobj = NULL;
+ }
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_session_write_pem(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL_SESSION *arg1 = (SSL_SESSION *) 0 ;
+ BIO *arg2 = (BIO *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_session_write_pem",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL_SESSION, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_session_write_pem" "', argument " "1"" of type '" "SSL_SESSION *""'");
+ }
+ arg1 = (SSL_SESSION *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ssl_session_write_pem" "', argument " "2"" of type '" "BIO *""'");
+ }
+ arg2 = (BIO *)(argp2);
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ result = (int)ssl_session_write_pem(arg1,arg2);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_ctx_set_session_cache_mode(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL_CTX *arg1 = (SSL_CTX *) 0 ;
+ int arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_ctx_set_session_cache_mode",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_ctx_set_session_cache_mode" "', argument " "1"" of type '" "SSL_CTX *""'");
+ }
+ arg1 = (SSL_CTX *)(argp1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ssl_ctx_set_session_cache_mode" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)ssl_ctx_set_session_cache_mode(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_ctx_get_session_cache_mode(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL_CTX *arg1 = (SSL_CTX *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_ctx_get_session_cache_mode",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_ctx_get_session_cache_mode" "', argument " "1"" of type '" "SSL_CTX *""'");
+ }
+ arg1 = (SSL_CTX *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)ssl_ctx_get_session_cache_mode(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_ctx_set_cache_size(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL_CTX *arg1 = (SSL_CTX *) 0 ;
+ long arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ long val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ long result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_ctx_set_cache_size",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_ctx_set_cache_size" "', argument " "1"" of type '" "SSL_CTX *""'");
+ }
+ arg1 = (SSL_CTX *)(argp1);
+ ecode2 = SWIG_AsVal_long(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ssl_ctx_set_cache_size" "', argument " "2"" of type '" "long""'");
+ }
+ arg2 = (long)(val2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (long)ssl_ctx_set_cache_size(arg1,arg2);
+ resultobj = SWIG_From_long((long)(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ssl_is_init_finished(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ SSL *arg1 = (SSL *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ssl_is_init_finished",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SSL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ssl_is_init_finished" "', argument " "1"" of type '" "SSL *""'");
+ }
+ arg1 = (SSL *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)ssl_is_init_finished(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_check_ca(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509 *arg1 = (X509 *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_check_ca",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_check_ca" "', argument " "1"" of type '" "X509 *""'");
+ }
+ arg1 = (X509 *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)X509_check_ca(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_new(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509 *result = 0 ;
+
+ result = (X509 *)X509_new();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_X509, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_dup(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509 *arg1 = (X509 *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ X509 *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_dup",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_dup" "', argument " "1"" of type '" "X509 *""'");
+ }
+ arg1 = (X509 *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (X509 *)X509_dup(arg1);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_X509, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_free(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509 *arg1 = (X509 *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_free",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_free" "', argument " "1"" of type '" "X509 *""'");
+ }
+ arg1 = (X509 *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ X509_free(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_crl_free(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_CRL *arg1 = (X509_CRL *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_crl_free",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_CRL, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_crl_free" "', argument " "1"" of type '" "X509_CRL *""'");
+ }
+ arg1 = (X509_CRL *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ X509_CRL_free(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_crl_new(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_CRL *result = 0 ;
+
+ result = (X509_CRL *)X509_CRL_new();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_X509_CRL, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_print(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ X509 *arg2 = (X509 *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_print",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_print" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_X509, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "x509_print" "', argument " "2"" of type '" "X509 *""'");
+ }
+ arg2 = (X509 *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ result = (int)X509_print(arg1,arg2);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_crl_print(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ X509_CRL *arg2 = (X509_CRL *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_crl_print",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_crl_print" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_X509_CRL, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "x509_crl_print" "', argument " "2"" of type '" "X509_CRL *""'");
+ }
+ arg2 = (X509_CRL *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ result = (int)X509_CRL_print(arg1,arg2);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_get_serial_number(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509 *arg1 = (X509 *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ ASN1_INTEGER *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_get_serial_number",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_get_serial_number" "', argument " "1"" of type '" "X509 *""'");
+ }
+ arg1 = (X509 *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (ASN1_INTEGER *)X509_get_serialNumber(arg1);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ASN1_INTEGER, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_set_serial_number(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509 *arg1 = (X509 *) 0 ;
+ ASN1_INTEGER *arg2 = (ASN1_INTEGER *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_set_serial_number",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_set_serial_number" "', argument " "1"" of type '" "X509 *""'");
+ }
+ arg1 = (X509 *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_ASN1_INTEGER, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "x509_set_serial_number" "', argument " "2"" of type '" "ASN1_INTEGER *""'");
+ }
+ arg2 = (ASN1_INTEGER *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)X509_set_serialNumber(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_get_pubkey(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509 *arg1 = (X509 *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ EVP_PKEY *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_get_pubkey",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_get_pubkey" "', argument " "1"" of type '" "X509 *""'");
+ }
+ arg1 = (X509 *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (EVP_PKEY *)X509_get_pubkey(arg1);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_PKEY, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_set_pubkey(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509 *arg1 = (X509 *) 0 ;
+ EVP_PKEY *arg2 = (EVP_PKEY *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_set_pubkey",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_set_pubkey" "', argument " "1"" of type '" "X509 *""'");
+ }
+ arg1 = (X509 *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_EVP_PKEY, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "x509_set_pubkey" "', argument " "2"" of type '" "EVP_PKEY *""'");
+ }
+ arg2 = (EVP_PKEY *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)X509_set_pubkey(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_get_issuer_name(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509 *arg1 = (X509 *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ X509_NAME *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_get_issuer_name",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_get_issuer_name" "', argument " "1"" of type '" "X509 *""'");
+ }
+ arg1 = (X509 *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (X509_NAME *)X509_get_issuer_name(arg1);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_X509_NAME, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_set_issuer_name(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509 *arg1 = (X509 *) 0 ;
+ X509_NAME *arg2 = (X509_NAME *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_set_issuer_name",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_set_issuer_name" "', argument " "1"" of type '" "X509 *""'");
+ }
+ arg1 = (X509 *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_X509_NAME, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "x509_set_issuer_name" "', argument " "2"" of type '" "X509_NAME *""'");
+ }
+ arg2 = (X509_NAME *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)X509_set_issuer_name(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_get_subject_name(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509 *arg1 = (X509 *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ X509_NAME *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_get_subject_name",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_get_subject_name" "', argument " "1"" of type '" "X509 *""'");
+ }
+ arg1 = (X509 *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (X509_NAME *)X509_get_subject_name(arg1);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_X509_NAME, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_set_subject_name(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509 *arg1 = (X509 *) 0 ;
+ X509_NAME *arg2 = (X509_NAME *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_set_subject_name",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_set_subject_name" "', argument " "1"" of type '" "X509 *""'");
+ }
+ arg1 = (X509 *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_X509_NAME, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "x509_set_subject_name" "', argument " "2"" of type '" "X509_NAME *""'");
+ }
+ arg2 = (X509_NAME *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)X509_set_subject_name(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_cmp_current_time(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ ASN1_TIME *arg1 = (ASN1_TIME *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_cmp_current_time",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ASN1_TIME, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_cmp_current_time" "', argument " "1"" of type '" "ASN1_TIME *""'");
+ }
+ arg1 = (ASN1_TIME *)(argp1);
+ result = (int)X509_cmp_current_time(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_check_purpose(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509 *arg1 = (X509 *) 0 ;
+ int arg2 ;
+ int arg3 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ int val3 ;
+ int ecode3 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_check_purpose",3,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_check_purpose" "', argument " "1"" of type '" "X509 *""'");
+ }
+ arg1 = (X509 *)(argp1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "x509_check_purpose" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ ecode3 = SWIG_AsVal_int(obj2, &val3);
+ if (!SWIG_IsOK(ecode3)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "x509_check_purpose" "', argument " "3"" of type '" "int""'");
+ }
+ arg3 = (int)(val3);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)X509_check_purpose(arg1,arg2,arg3);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_check_trust(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509 *arg1 = (X509 *) 0 ;
+ int arg2 ;
+ int arg3 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ int val3 ;
+ int ecode3 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_check_trust",3,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_check_trust" "', argument " "1"" of type '" "X509 *""'");
+ }
+ arg1 = (X509 *)(argp1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "x509_check_trust" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ ecode3 = SWIG_AsVal_int(obj2, &val3);
+ if (!SWIG_IsOK(ecode3)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "x509_check_trust" "', argument " "3"" of type '" "int""'");
+ }
+ arg3 = (int)(val3);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)X509_check_trust(arg1,arg2,arg3);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_write_pem(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ X509 *arg2 = (X509 *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_write_pem",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_write_pem" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_X509, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "x509_write_pem" "', argument " "2"" of type '" "X509 *""'");
+ }
+ arg2 = (X509 *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ result = (int)PEM_write_bio_X509(arg1,arg2);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_write_pem_file(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ FILE *arg1 = (FILE *) 0 ;
+ X509 *arg2 = (X509 *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_write_pem_file",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FILE, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_write_pem_file" "', argument " "1"" of type '" "FILE *""'");
+ }
+ arg1 = (FILE *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_X509, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "x509_write_pem_file" "', argument " "2"" of type '" "X509 *""'");
+ }
+ arg2 = (X509 *)(argp2);
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)PEM_write_X509(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_verify(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509 *arg1 = (X509 *) 0 ;
+ EVP_PKEY *arg2 = (EVP_PKEY *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_verify",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_verify" "', argument " "1"" of type '" "X509 *""'");
+ }
+ arg1 = (X509 *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_EVP_PKEY, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "x509_verify" "', argument " "2"" of type '" "EVP_PKEY *""'");
+ }
+ arg2 = (EVP_PKEY *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)X509_verify(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_get_verify_error(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ long arg1 ;
+ long val1 ;
+ int ecode1 = 0 ;
+ PyObject * obj0 = 0 ;
+ char *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_get_verify_error",1,1,&obj0)) SWIG_fail;
+ ecode1 = SWIG_AsVal_long(obj0, &val1);
+ if (!SWIG_IsOK(ecode1)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "x509_get_verify_error" "', argument " "1"" of type '" "long""'");
+ }
+ arg1 = (long)(val1);
+ result = (char *)X509_verify_cert_error_string(arg1);
+ resultobj = SWIG_FromCharPtr((const char *)result);
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_add_ext(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509 *arg1 = (X509 *) 0 ;
+ X509_EXTENSION *arg2 = (X509_EXTENSION *) 0 ;
+ int arg3 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ int val3 ;
+ int ecode3 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_add_ext",3,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_add_ext" "', argument " "1"" of type '" "X509 *""'");
+ }
+ arg1 = (X509 *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_X509_EXTENSION, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "x509_add_ext" "', argument " "2"" of type '" "X509_EXTENSION *""'");
+ }
+ arg2 = (X509_EXTENSION *)(argp2);
+ ecode3 = SWIG_AsVal_int(obj2, &val3);
+ if (!SWIG_IsOK(ecode3)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "x509_add_ext" "', argument " "3"" of type '" "int""'");
+ }
+ arg3 = (int)(val3);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)X509_add_ext(arg1,arg2,arg3);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_get_ext_count(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509 *arg1 = (X509 *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_get_ext_count",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_get_ext_count" "', argument " "1"" of type '" "X509 *""'");
+ }
+ arg1 = (X509 *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)X509_get_ext_count(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_get_ext(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509 *arg1 = (X509 *) 0 ;
+ int arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ X509_EXTENSION *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_get_ext",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_get_ext" "', argument " "1"" of type '" "X509 *""'");
+ }
+ arg1 = (X509 *)(argp1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "x509_get_ext" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (X509_EXTENSION *)X509_get_ext(arg1,arg2);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_X509_EXTENSION, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_ext_print(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ X509_EXTENSION *arg2 = (X509_EXTENSION *) 0 ;
+ unsigned long arg3 ;
+ int arg4 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ unsigned long val3 ;
+ int ecode3 = 0 ;
+ int val4 ;
+ int ecode4 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject * obj3 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_ext_print",4,4,&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_ext_print" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_X509_EXTENSION, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "x509_ext_print" "', argument " "2"" of type '" "X509_EXTENSION *""'");
+ }
+ arg2 = (X509_EXTENSION *)(argp2);
+ ecode3 = SWIG_AsVal_unsigned_SS_long(obj2, &val3);
+ if (!SWIG_IsOK(ecode3)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "x509_ext_print" "', argument " "3"" of type '" "unsigned long""'");
+ }
+ arg3 = (unsigned long)(val3);
+ ecode4 = SWIG_AsVal_int(obj3, &val4);
+ if (!SWIG_IsOK(ecode4)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "x509_ext_print" "', argument " "4"" of type '" "int""'");
+ }
+ arg4 = (int)(val4);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ result = (int)X509V3_EXT_print(arg1,arg2,arg3,arg4);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_name_new(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_NAME *result = 0 ;
+
+ result = (X509_NAME *)X509_NAME_new();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_X509_NAME, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_name_free(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_NAME *arg1 = (X509_NAME *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_name_free",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_NAME, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_name_free" "', argument " "1"" of type '" "X509_NAME *""'");
+ }
+ arg1 = (X509_NAME *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ X509_NAME_free(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_name_print(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ X509_NAME *arg2 = (X509_NAME *) 0 ;
+ int arg3 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ int val3 ;
+ int ecode3 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_name_print",3,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_name_print" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_X509_NAME, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "x509_name_print" "', argument " "2"" of type '" "X509_NAME *""'");
+ }
+ arg2 = (X509_NAME *)(argp2);
+ ecode3 = SWIG_AsVal_int(obj2, &val3);
+ if (!SWIG_IsOK(ecode3)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "x509_name_print" "', argument " "3"" of type '" "int""'");
+ }
+ arg3 = (int)(val3);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ result = (int)X509_NAME_print(arg1,arg2,arg3);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_name_get_entry(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_NAME *arg1 = (X509_NAME *) 0 ;
+ int arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ X509_NAME_ENTRY *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_name_get_entry",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_NAME, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_name_get_entry" "', argument " "1"" of type '" "X509_NAME *""'");
+ }
+ arg1 = (X509_NAME *)(argp1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "x509_name_get_entry" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (X509_NAME_ENTRY *)X509_NAME_get_entry(arg1,arg2);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_X509_NAME_ENTRY, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_name_entry_count(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_NAME *arg1 = (X509_NAME *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_name_entry_count",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_NAME, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_name_entry_count" "', argument " "1"" of type '" "X509_NAME *""'");
+ }
+ arg1 = (X509_NAME *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)X509_NAME_entry_count(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_name_delete_entry(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_NAME *arg1 = (X509_NAME *) 0 ;
+ int arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ X509_NAME_ENTRY *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_name_delete_entry",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_NAME, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_name_delete_entry" "', argument " "1"" of type '" "X509_NAME *""'");
+ }
+ arg1 = (X509_NAME *)(argp1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "x509_name_delete_entry" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (X509_NAME_ENTRY *)X509_NAME_delete_entry(arg1,arg2);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_X509_NAME_ENTRY, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_name_add_entry(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_NAME *arg1 = (X509_NAME *) 0 ;
+ X509_NAME_ENTRY *arg2 = (X509_NAME_ENTRY *) 0 ;
+ int arg3 ;
+ int arg4 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ int val3 ;
+ int ecode3 = 0 ;
+ int val4 ;
+ int ecode4 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject * obj3 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_name_add_entry",4,4,&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_NAME, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_name_add_entry" "', argument " "1"" of type '" "X509_NAME *""'");
+ }
+ arg1 = (X509_NAME *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_X509_NAME_ENTRY, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "x509_name_add_entry" "', argument " "2"" of type '" "X509_NAME_ENTRY *""'");
+ }
+ arg2 = (X509_NAME_ENTRY *)(argp2);
+ ecode3 = SWIG_AsVal_int(obj2, &val3);
+ if (!SWIG_IsOK(ecode3)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "x509_name_add_entry" "', argument " "3"" of type '" "int""'");
+ }
+ arg3 = (int)(val3);
+ ecode4 = SWIG_AsVal_int(obj3, &val4);
+ if (!SWIG_IsOK(ecode4)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "x509_name_add_entry" "', argument " "4"" of type '" "int""'");
+ }
+ arg4 = (int)(val4);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)X509_NAME_add_entry(arg1,arg2,arg3,arg4);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_name_add_entry_by_obj(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_NAME *arg1 = (X509_NAME *) 0 ;
+ ASN1_OBJECT *arg2 = (ASN1_OBJECT *) 0 ;
+ int arg3 ;
+ unsigned char *arg4 = (unsigned char *) 0 ;
+ int arg5 ;
+ int arg6 ;
+ int arg7 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ int val3 ;
+ int ecode3 = 0 ;
+ void *argp4 = 0 ;
+ int res4 = 0 ;
+ int val5 ;
+ int ecode5 = 0 ;
+ int val6 ;
+ int ecode6 = 0 ;
+ int val7 ;
+ int ecode7 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject * obj3 = 0 ;
+ PyObject * obj4 = 0 ;
+ PyObject * obj5 = 0 ;
+ PyObject * obj6 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_name_add_entry_by_obj",7,7,&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_NAME, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_name_add_entry_by_obj" "', argument " "1"" of type '" "X509_NAME *""'");
+ }
+ arg1 = (X509_NAME *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_ASN1_OBJECT, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "x509_name_add_entry_by_obj" "', argument " "2"" of type '" "ASN1_OBJECT *""'");
+ }
+ arg2 = (ASN1_OBJECT *)(argp2);
+ ecode3 = SWIG_AsVal_int(obj2, &val3);
+ if (!SWIG_IsOK(ecode3)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "x509_name_add_entry_by_obj" "', argument " "3"" of type '" "int""'");
+ }
+ arg3 = (int)(val3);
+ res4 = SWIG_ConvertPtr(obj3, &argp4,SWIGTYPE_p_unsigned_char, 0 | 0 );
+ if (!SWIG_IsOK(res4)) {
+ SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "x509_name_add_entry_by_obj" "', argument " "4"" of type '" "unsigned char *""'");
+ }
+ arg4 = (unsigned char *)(argp4);
+ ecode5 = SWIG_AsVal_int(obj4, &val5);
+ if (!SWIG_IsOK(ecode5)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "x509_name_add_entry_by_obj" "', argument " "5"" of type '" "int""'");
+ }
+ arg5 = (int)(val5);
+ ecode6 = SWIG_AsVal_int(obj5, &val6);
+ if (!SWIG_IsOK(ecode6)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "x509_name_add_entry_by_obj" "', argument " "6"" of type '" "int""'");
+ }
+ arg6 = (int)(val6);
+ ecode7 = SWIG_AsVal_int(obj6, &val7);
+ if (!SWIG_IsOK(ecode7)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "x509_name_add_entry_by_obj" "', argument " "7"" of type '" "int""'");
+ }
+ arg7 = (int)(val7);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)X509_NAME_add_entry_by_OBJ(arg1,arg2,arg3,arg4,arg5,arg6,arg7);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_name_add_entry_by_nid(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_NAME *arg1 = (X509_NAME *) 0 ;
+ int arg2 ;
+ int arg3 ;
+ unsigned char *arg4 = (unsigned char *) 0 ;
+ int arg5 ;
+ int arg6 ;
+ int arg7 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ int val3 ;
+ int ecode3 = 0 ;
+ void *argp4 = 0 ;
+ int res4 = 0 ;
+ int val5 ;
+ int ecode5 = 0 ;
+ int val6 ;
+ int ecode6 = 0 ;
+ int val7 ;
+ int ecode7 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject * obj3 = 0 ;
+ PyObject * obj4 = 0 ;
+ PyObject * obj5 = 0 ;
+ PyObject * obj6 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_name_add_entry_by_nid",7,7,&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_NAME, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_name_add_entry_by_nid" "', argument " "1"" of type '" "X509_NAME *""'");
+ }
+ arg1 = (X509_NAME *)(argp1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "x509_name_add_entry_by_nid" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ ecode3 = SWIG_AsVal_int(obj2, &val3);
+ if (!SWIG_IsOK(ecode3)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "x509_name_add_entry_by_nid" "', argument " "3"" of type '" "int""'");
+ }
+ arg3 = (int)(val3);
+ res4 = SWIG_ConvertPtr(obj3, &argp4,SWIGTYPE_p_unsigned_char, 0 | 0 );
+ if (!SWIG_IsOK(res4)) {
+ SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "x509_name_add_entry_by_nid" "', argument " "4"" of type '" "unsigned char *""'");
+ }
+ arg4 = (unsigned char *)(argp4);
+ ecode5 = SWIG_AsVal_int(obj4, &val5);
+ if (!SWIG_IsOK(ecode5)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "x509_name_add_entry_by_nid" "', argument " "5"" of type '" "int""'");
+ }
+ arg5 = (int)(val5);
+ ecode6 = SWIG_AsVal_int(obj5, &val6);
+ if (!SWIG_IsOK(ecode6)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "x509_name_add_entry_by_nid" "', argument " "6"" of type '" "int""'");
+ }
+ arg6 = (int)(val6);
+ ecode7 = SWIG_AsVal_int(obj6, &val7);
+ if (!SWIG_IsOK(ecode7)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "x509_name_add_entry_by_nid" "', argument " "7"" of type '" "int""'");
+ }
+ arg7 = (int)(val7);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)X509_NAME_add_entry_by_NID(arg1,arg2,arg3,arg4,arg5,arg6,arg7);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_name_print_ex(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ X509_NAME *arg2 = (X509_NAME *) 0 ;
+ int arg3 ;
+ unsigned long arg4 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ int val3 ;
+ int ecode3 = 0 ;
+ unsigned long val4 ;
+ int ecode4 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject * obj3 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_name_print_ex",4,4,&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_name_print_ex" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_X509_NAME, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "x509_name_print_ex" "', argument " "2"" of type '" "X509_NAME *""'");
+ }
+ arg2 = (X509_NAME *)(argp2);
+ ecode3 = SWIG_AsVal_int(obj2, &val3);
+ if (!SWIG_IsOK(ecode3)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "x509_name_print_ex" "', argument " "3"" of type '" "int""'");
+ }
+ arg3 = (int)(val3);
+ ecode4 = SWIG_AsVal_unsigned_SS_long(obj3, &val4);
+ if (!SWIG_IsOK(ecode4)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "x509_name_print_ex" "', argument " "4"" of type '" "unsigned long""'");
+ }
+ arg4 = (unsigned long)(val4);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ result = (int)X509_NAME_print_ex(arg1,arg2,arg3,arg4);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_name_hash(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_NAME *arg1 = (X509_NAME *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ unsigned long result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_name_hash",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_NAME, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_name_hash" "', argument " "1"" of type '" "X509_NAME *""'");
+ }
+ arg1 = (X509_NAME *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (unsigned long)X509_NAME_hash_old(arg1);
+ resultobj = SWIG_From_unsigned_SS_long((unsigned long)(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_name_get_index_by_nid(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_NAME *arg1 = (X509_NAME *) 0 ;
+ int arg2 ;
+ int arg3 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ int val3 ;
+ int ecode3 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_name_get_index_by_nid",3,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_NAME, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_name_get_index_by_nid" "', argument " "1"" of type '" "X509_NAME *""'");
+ }
+ arg1 = (X509_NAME *)(argp1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "x509_name_get_index_by_nid" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ ecode3 = SWIG_AsVal_int(obj2, &val3);
+ if (!SWIG_IsOK(ecode3)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "x509_name_get_index_by_nid" "', argument " "3"" of type '" "int""'");
+ }
+ arg3 = (int)(val3);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)X509_NAME_get_index_by_NID(arg1,arg2,arg3);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_name_entry_new(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_NAME_ENTRY *result = 0 ;
+
+ result = (X509_NAME_ENTRY *)X509_NAME_ENTRY_new();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_X509_NAME_ENTRY, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_name_entry_free(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_NAME_ENTRY *arg1 = (X509_NAME_ENTRY *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_name_entry_free",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_NAME_ENTRY, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_name_entry_free" "', argument " "1"" of type '" "X509_NAME_ENTRY *""'");
+ }
+ arg1 = (X509_NAME_ENTRY *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ X509_NAME_ENTRY_free(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_name_entry_create_by_nid(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_NAME_ENTRY **arg1 = (X509_NAME_ENTRY **) 0 ;
+ int arg2 ;
+ int arg3 ;
+ unsigned char *arg4 = (unsigned char *) 0 ;
+ int arg5 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ int val3 ;
+ int ecode3 = 0 ;
+ void *argp4 = 0 ;
+ int res4 = 0 ;
+ int val5 ;
+ int ecode5 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject * obj3 = 0 ;
+ PyObject * obj4 = 0 ;
+ X509_NAME_ENTRY *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_name_entry_create_by_nid",5,5,&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_p_X509_NAME_ENTRY, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_name_entry_create_by_nid" "', argument " "1"" of type '" "X509_NAME_ENTRY **""'");
+ }
+ arg1 = (X509_NAME_ENTRY **)(argp1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "x509_name_entry_create_by_nid" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ ecode3 = SWIG_AsVal_int(obj2, &val3);
+ if (!SWIG_IsOK(ecode3)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "x509_name_entry_create_by_nid" "', argument " "3"" of type '" "int""'");
+ }
+ arg3 = (int)(val3);
+ res4 = SWIG_ConvertPtr(obj3, &argp4,SWIGTYPE_p_unsigned_char, 0 | 0 );
+ if (!SWIG_IsOK(res4)) {
+ SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "x509_name_entry_create_by_nid" "', argument " "4"" of type '" "unsigned char *""'");
+ }
+ arg4 = (unsigned char *)(argp4);
+ ecode5 = SWIG_AsVal_int(obj4, &val5);
+ if (!SWIG_IsOK(ecode5)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "x509_name_entry_create_by_nid" "', argument " "5"" of type '" "int""'");
+ }
+ arg5 = (int)(val5);
+ result = (X509_NAME_ENTRY *)X509_NAME_ENTRY_create_by_NID(arg1,arg2,arg3,arg4,arg5);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_X509_NAME_ENTRY, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_name_entry_set_object(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_NAME_ENTRY *arg1 = (X509_NAME_ENTRY *) 0 ;
+ ASN1_OBJECT *arg2 = (ASN1_OBJECT *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_name_entry_set_object",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_NAME_ENTRY, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_name_entry_set_object" "', argument " "1"" of type '" "X509_NAME_ENTRY *""'");
+ }
+ arg1 = (X509_NAME_ENTRY *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_ASN1_OBJECT, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "x509_name_entry_set_object" "', argument " "2"" of type '" "ASN1_OBJECT *""'");
+ }
+ arg2 = (ASN1_OBJECT *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)X509_NAME_ENTRY_set_object(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_name_entry_get_object(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_NAME_ENTRY *arg1 = (X509_NAME_ENTRY *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ ASN1_OBJECT *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_name_entry_get_object",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_NAME_ENTRY, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_name_entry_get_object" "', argument " "1"" of type '" "X509_NAME_ENTRY *""'");
+ }
+ arg1 = (X509_NAME_ENTRY *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (ASN1_OBJECT *)X509_NAME_ENTRY_get_object(arg1);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ASN1_OBJECT, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_name_entry_get_data(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_NAME_ENTRY *arg1 = (X509_NAME_ENTRY *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ ASN1_STRING *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_name_entry_get_data",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_NAME_ENTRY, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_name_entry_get_data" "', argument " "1"" of type '" "X509_NAME_ENTRY *""'");
+ }
+ arg1 = (X509_NAME_ENTRY *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (ASN1_STRING *)X509_NAME_ENTRY_get_data(arg1);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ASN1_STRING, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_name_entry_set_data(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_NAME_ENTRY *arg1 = (X509_NAME_ENTRY *) 0 ;
+ int arg2 ;
+ unsigned char *arg3 = (unsigned char *) 0 ;
+ int arg4 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_name_entry_set_data",3,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_NAME_ENTRY, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_name_entry_set_data" "', argument " "1"" of type '" "X509_NAME_ENTRY *""'");
+ }
+ arg1 = (X509_NAME_ENTRY *)(argp1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "x509_name_entry_set_data" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ {
+ if (PyString_Check(obj2)) {
+ Py_ssize_t len;
+
+ arg3 = (unsigned char *)PyString_AsString(obj2);
+ len = PyString_Size(obj2);
+
+
+ if (len > INT_MAX) {
+ PyErr_SetString(_x509_err, "object too large");
+ return NULL;
+ }
+ arg4 = len;
+ } else {
+ PyErr_SetString(PyExc_TypeError, "expected string");
+ return NULL;
+ }
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)X509_NAME_ENTRY_set_data(arg1,arg2,(unsigned char const *)arg3,arg4);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_req_new(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_REQ *result = 0 ;
+
+ result = (X509_REQ *)X509_REQ_new();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_X509_REQ, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_req_free(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_REQ *arg1 = (X509_REQ *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_req_free",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_REQ, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_req_free" "', argument " "1"" of type '" "X509_REQ *""'");
+ }
+ arg1 = (X509_REQ *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ X509_REQ_free(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_req_print(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ X509_REQ *arg2 = (X509_REQ *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_req_print",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_req_print" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_X509_REQ, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "x509_req_print" "', argument " "2"" of type '" "X509_REQ *""'");
+ }
+ arg2 = (X509_REQ *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ result = (int)X509_REQ_print(arg1,arg2);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_req_get_pubkey(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_REQ *arg1 = (X509_REQ *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ EVP_PKEY *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_req_get_pubkey",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_REQ, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_req_get_pubkey" "', argument " "1"" of type '" "X509_REQ *""'");
+ }
+ arg1 = (X509_REQ *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (EVP_PKEY *)X509_REQ_get_pubkey(arg1);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_PKEY, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_req_set_pubkey(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_REQ *arg1 = (X509_REQ *) 0 ;
+ EVP_PKEY *arg2 = (EVP_PKEY *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_req_set_pubkey",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_REQ, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_req_set_pubkey" "', argument " "1"" of type '" "X509_REQ *""'");
+ }
+ arg1 = (X509_REQ *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_EVP_PKEY, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "x509_req_set_pubkey" "', argument " "2"" of type '" "EVP_PKEY *""'");
+ }
+ arg2 = (EVP_PKEY *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)X509_REQ_set_pubkey(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_req_set_subject_name(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_REQ *arg1 = (X509_REQ *) 0 ;
+ X509_NAME *arg2 = (X509_NAME *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_req_set_subject_name",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_REQ, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_req_set_subject_name" "', argument " "1"" of type '" "X509_REQ *""'");
+ }
+ arg1 = (X509_REQ *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_X509_NAME, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "x509_req_set_subject_name" "', argument " "2"" of type '" "X509_NAME *""'");
+ }
+ arg2 = (X509_NAME *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)X509_REQ_set_subject_name(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_req_verify(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_REQ *arg1 = (X509_REQ *) 0 ;
+ EVP_PKEY *arg2 = (EVP_PKEY *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_req_verify",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_REQ, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_req_verify" "', argument " "1"" of type '" "X509_REQ *""'");
+ }
+ arg1 = (X509_REQ *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_EVP_PKEY, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "x509_req_verify" "', argument " "2"" of type '" "EVP_PKEY *""'");
+ }
+ arg2 = (EVP_PKEY *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)X509_REQ_verify(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_req_sign(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_REQ *arg1 = (X509_REQ *) 0 ;
+ EVP_PKEY *arg2 = (EVP_PKEY *) 0 ;
+ EVP_MD *arg3 = (EVP_MD *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ void *argp3 = 0 ;
+ int res3 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_req_sign",3,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_REQ, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_req_sign" "', argument " "1"" of type '" "X509_REQ *""'");
+ }
+ arg1 = (X509_REQ *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_EVP_PKEY, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "x509_req_sign" "', argument " "2"" of type '" "EVP_PKEY *""'");
+ }
+ arg2 = (EVP_PKEY *)(argp2);
+ res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_EVP_MD, 0 | 0 );
+ if (!SWIG_IsOK(res3)) {
+ SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "x509_req_sign" "', argument " "3"" of type '" "EVP_MD const *""'");
+ }
+ arg3 = (EVP_MD *)(argp3);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg3) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)X509_REQ_sign(arg1,arg2,(EVP_MD const *)arg3);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_i2d_x509_bio(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ X509 *arg2 = (X509 *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"i2d_x509_bio",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "i2d_x509_bio" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_X509, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "i2d_x509_bio" "', argument " "2"" of type '" "X509 *""'");
+ }
+ arg2 = (X509 *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ result = (int)i2d_X509_bio(arg1,arg2);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_i2d_x509_req_bio(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ X509_REQ *arg2 = (X509_REQ *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"i2d_x509_req_bio",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "i2d_x509_req_bio" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_X509_REQ, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "i2d_x509_req_bio" "', argument " "2"" of type '" "X509_REQ *""'");
+ }
+ arg2 = (X509_REQ *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ result = (int)i2d_X509_REQ_bio(arg1,arg2);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_store_new(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_STORE *result = 0 ;
+
+ result = (X509_STORE *)X509_STORE_new();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_X509_STORE, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_store_free(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_STORE *arg1 = (X509_STORE *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_store_free",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_STORE, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_store_free" "', argument " "1"" of type '" "X509_STORE *""'");
+ }
+ arg1 = (X509_STORE *)(argp1);
+ X509_STORE_free(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_store_add_cert(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_STORE *arg1 = (X509_STORE *) 0 ;
+ X509 *arg2 = (X509 *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_store_add_cert",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_STORE, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_store_add_cert" "', argument " "1"" of type '" "X509_STORE *""'");
+ }
+ arg1 = (X509_STORE *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_X509, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "x509_store_add_cert" "', argument " "2"" of type '" "X509 *""'");
+ }
+ arg2 = (X509 *)(argp2);
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)X509_STORE_add_cert(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_store_set_verify_cb__SWIG_0(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_STORE *arg1 = (X509_STORE *) 0 ;
+ int (*arg2)(int,X509_STORE_CTX *) = (int (*)(int,X509_STORE_CTX *)) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_store_set_verify_cb",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_STORE, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_store_set_verify_cb" "', argument " "1"" of type '" "X509_STORE *""'");
+ }
+ arg1 = (X509_STORE *)(argp1);
+ {
+ int res = SWIG_ConvertFunctionPtr(obj1, (void**)(&arg2), SWIGTYPE_p_f_int_p_X509_STORE_CTX__int);
+ if (!SWIG_IsOK(res)) {
+ SWIG_exception_fail(SWIG_ArgError(res), "in method '" "x509_store_set_verify_cb" "', argument " "2"" of type '" "int (*)(int,X509_STORE_CTX *)""'");
+ }
+ }
+ X509_STORE_set_verify_cb(arg1,arg2);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_store_ctx_get_current_cert(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_STORE_CTX *arg1 = (X509_STORE_CTX *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ X509 *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_store_ctx_get_current_cert",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_STORE_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_store_ctx_get_current_cert" "', argument " "1"" of type '" "X509_STORE_CTX *""'");
+ }
+ arg1 = (X509_STORE_CTX *)(argp1);
+ result = (X509 *)X509_STORE_CTX_get_current_cert(arg1);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_X509, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_store_ctx_get_error(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_STORE_CTX *arg1 = (X509_STORE_CTX *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_store_ctx_get_error",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_STORE_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_store_ctx_get_error" "', argument " "1"" of type '" "X509_STORE_CTX *""'");
+ }
+ arg1 = (X509_STORE_CTX *)(argp1);
+ result = (int)X509_STORE_CTX_get_error(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_store_ctx_get_error_depth(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_STORE_CTX *arg1 = (X509_STORE_CTX *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_store_ctx_get_error_depth",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_STORE_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_store_ctx_get_error_depth" "', argument " "1"" of type '" "X509_STORE_CTX *""'");
+ }
+ arg1 = (X509_STORE_CTX *)(argp1);
+ result = (int)X509_STORE_CTX_get_error_depth(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_store_ctx_free(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_STORE_CTX *arg1 = (X509_STORE_CTX *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_store_ctx_free",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_STORE_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_store_ctx_free" "', argument " "1"" of type '" "X509_STORE_CTX *""'");
+ }
+ arg1 = (X509_STORE_CTX *)(argp1);
+ X509_STORE_CTX_free(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_store_ctx_get1_chain(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_STORE_CTX *arg1 = (X509_STORE_CTX *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ struct stack_st_X509 *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_store_ctx_get1_chain",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_STORE_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_store_ctx_get1_chain" "', argument " "1"" of type '" "X509_STORE_CTX *""'");
+ }
+ arg1 = (X509_STORE_CTX *)(argp1);
+ result = (struct stack_st_X509 *)X509_STORE_CTX_get1_chain(arg1);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_stack_st_X509, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_extension_get_critical(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_EXTENSION *arg1 = (X509_EXTENSION *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_extension_get_critical",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_EXTENSION, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_extension_get_critical" "', argument " "1"" of type '" "X509_EXTENSION *""'");
+ }
+ arg1 = (X509_EXTENSION *)(argp1);
+ result = (int)X509_EXTENSION_get_critical(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_extension_set_critical(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_EXTENSION *arg1 = (X509_EXTENSION *) 0 ;
+ int arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_extension_set_critical",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_EXTENSION, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_extension_set_critical" "', argument " "1"" of type '" "X509_EXTENSION *""'");
+ }
+ arg1 = (X509_EXTENSION *)(argp1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "x509_extension_set_critical" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ result = (int)X509_EXTENSION_set_critical(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_read_pem(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ X509 *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_read_pem",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_read_pem" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ result = (X509 *)x509_read_pem(arg1);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ {
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+
+ if (result != NULL)
+ resultobj = SWIG_NewPointerObj(result, SWIGTYPE_p_X509, 0);
+ else {
+ m2_PyErr_Msg(_x509_err);
+ resultobj = NULL;
+ }
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_d2i_x509(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ X509 *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"d2i_x509",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "d2i_x509" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ result = (X509 *)d2i_x509(arg1);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ {
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+
+ if (result != NULL)
+ resultobj = SWIG_NewPointerObj(result, SWIGTYPE_p_X509, 0);
+ else {
+ m2_PyErr_Msg(_x509_err);
+ resultobj = NULL;
+ }
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN int Swig_var__x509_err_set(PyObject *_val) {
+ {
+ void *argp = 0;
+ int res = SWIG_ConvertPtr(_val, &argp, SWIGTYPE_p_PyObject, 0 );
+ if (!SWIG_IsOK(res)) {
+ SWIG_exception_fail(SWIG_ArgError(res), "in variable '""_x509_err""' of type '""PyObject *""'");
+ }
+ _x509_err = (PyObject *)(argp);
+ }
+ return 0;
+fail:
+ return 1;
+}
+
+
+SWIGINTERN PyObject *Swig_var__x509_err_get(void) {
+ PyObject *pyobj = 0;
+ PyObject *self = 0;
+
+ (void)self;
+ pyobj = SWIG_NewPointerObj(SWIG_as_voidptr(_x509_err), SWIGTYPE_p_PyObject, 0 );
+ return pyobj;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_init(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ PyObject *arg1 = (PyObject *) 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_init",1,1,&obj0)) SWIG_fail;
+ {
+ arg1=obj0;
+ }
+ x509_init(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_d2i_x509_req(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ X509_REQ *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"d2i_x509_req",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "d2i_x509_req" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ result = (X509_REQ *)d2i_x509_req(arg1);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ {
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+
+ if (result != NULL)
+ resultobj = SWIG_NewPointerObj(result, SWIGTYPE_p_X509_REQ, 0);
+ else {
+ m2_PyErr_Msg(_x509_err);
+ resultobj = NULL;
+ }
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_req_read_pem(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ X509_REQ *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_req_read_pem",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_req_read_pem" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ result = (X509_REQ *)x509_req_read_pem(arg1);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ {
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+
+ if (result != NULL)
+ resultobj = SWIG_NewPointerObj(result, SWIGTYPE_p_X509_REQ, 0);
+ else {
+ m2_PyErr_Msg(_x509_err);
+ resultobj = NULL;
+ }
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_i2d_x509(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509 *arg1 = (X509 *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"i2d_x509",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "i2d_x509" "', argument " "1"" of type '" "X509 *""'");
+ }
+ arg1 = (X509 *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)i2d_x509(arg1);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_req_write_pem(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ X509_REQ *arg2 = (X509_REQ *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_req_write_pem",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_req_write_pem" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_X509_REQ, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "x509_req_write_pem" "', argument " "2"" of type '" "X509_REQ *""'");
+ }
+ arg2 = (X509_REQ *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ result = (int)x509_req_write_pem(arg1,arg2);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_crl_read_pem(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ X509_CRL *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_crl_read_pem",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_crl_read_pem" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ result = (X509_CRL *)x509_crl_read_pem(arg1);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ {
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+
+ if (result != NULL)
+ resultobj = SWIG_NewPointerObj(result, SWIGTYPE_p_X509_CRL, 0);
+ else {
+ m2_PyErr_Msg(_x509_err);
+ resultobj = NULL;
+ }
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_set_version(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509 *arg1 = (X509 *) 0 ;
+ long arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ long val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_set_version",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_set_version" "', argument " "1"" of type '" "X509 *""'");
+ }
+ arg1 = (X509 *)(argp1);
+ ecode2 = SWIG_AsVal_long(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "x509_set_version" "', argument " "2"" of type '" "long""'");
+ }
+ arg2 = (long)(val2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)x509_set_version(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_get_version(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509 *arg1 = (X509 *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ long result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_get_version",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_get_version" "', argument " "1"" of type '" "X509 *""'");
+ }
+ arg1 = (X509 *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (long)x509_get_version(arg1);
+ resultobj = SWIG_From_long((long)(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_set_not_before(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509 *arg1 = (X509 *) 0 ;
+ ASN1_TIME *arg2 = (ASN1_TIME *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_set_not_before",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_set_not_before" "', argument " "1"" of type '" "X509 *""'");
+ }
+ arg1 = (X509 *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_ASN1_TIME, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "x509_set_not_before" "', argument " "2"" of type '" "ASN1_TIME *""'");
+ }
+ arg2 = (ASN1_TIME *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)x509_set_not_before(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_get_not_before(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509 *arg1 = (X509 *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ ASN1_TIME *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_get_not_before",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_get_not_before" "', argument " "1"" of type '" "X509 *""'");
+ }
+ arg1 = (X509 *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (ASN1_TIME *)x509_get_not_before(arg1);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ASN1_TIME, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_set_not_after(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509 *arg1 = (X509 *) 0 ;
+ ASN1_TIME *arg2 = (ASN1_TIME *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_set_not_after",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_set_not_after" "', argument " "1"" of type '" "X509 *""'");
+ }
+ arg1 = (X509 *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_ASN1_TIME, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "x509_set_not_after" "', argument " "2"" of type '" "ASN1_TIME *""'");
+ }
+ arg2 = (ASN1_TIME *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)x509_set_not_after(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_get_not_after(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509 *arg1 = (X509 *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ ASN1_TIME *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_get_not_after",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_get_not_after" "', argument " "1"" of type '" "X509 *""'");
+ }
+ arg1 = (X509 *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (ASN1_TIME *)x509_get_not_after(arg1);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ASN1_TIME, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_sign(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509 *arg1 = (X509 *) 0 ;
+ EVP_PKEY *arg2 = (EVP_PKEY *) 0 ;
+ EVP_MD *arg3 = (EVP_MD *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ void *argp3 = 0 ;
+ int res3 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_sign",3,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_sign" "', argument " "1"" of type '" "X509 *""'");
+ }
+ arg1 = (X509 *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_EVP_PKEY, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "x509_sign" "', argument " "2"" of type '" "EVP_PKEY *""'");
+ }
+ arg2 = (EVP_PKEY *)(argp2);
+ res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_EVP_MD, 0 | 0 );
+ if (!SWIG_IsOK(res3)) {
+ SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "x509_sign" "', argument " "3"" of type '" "EVP_MD *""'");
+ }
+ arg3 = (EVP_MD *)(argp3);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg3) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)x509_sign(arg1,arg2,arg3);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_gmtime_adj(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ ASN1_TIME *arg1 = (ASN1_TIME *) 0 ;
+ long arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ long val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ ASN1_TIME *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_gmtime_adj",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ASN1_TIME, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_gmtime_adj" "', argument " "1"" of type '" "ASN1_TIME *""'");
+ }
+ arg1 = (ASN1_TIME *)(argp1);
+ ecode2 = SWIG_AsVal_long(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "x509_gmtime_adj" "', argument " "2"" of type '" "long""'");
+ }
+ arg2 = (long)(val2);
+ result = (ASN1_TIME *)x509_gmtime_adj(arg1,arg2);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ASN1_TIME, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_name_by_nid(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_NAME *arg1 = (X509_NAME *) 0 ;
+ int arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_name_by_nid",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_NAME, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_name_by_nid" "', argument " "1"" of type '" "X509_NAME *""'");
+ }
+ arg1 = (X509_NAME *)(argp1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "x509_name_by_nid" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)x509_name_by_nid(arg1,arg2);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_name_set_by_nid(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_NAME *arg1 = (X509_NAME *) 0 ;
+ int arg2 ;
+ PyObject *arg3 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_name_set_by_nid",3,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_NAME, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_name_set_by_nid" "', argument " "1"" of type '" "X509_NAME *""'");
+ }
+ arg1 = (X509_NAME *)(argp1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "x509_name_set_by_nid" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ {
+ arg3=obj2;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)x509_name_set_by_nid(arg1,arg2,arg3);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_name_add_entry_by_txt(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_NAME *arg1 = (X509_NAME *) 0 ;
+ char *arg2 = (char *) 0 ;
+ int arg3 ;
+ char *arg4 = (char *) 0 ;
+ int arg5 ;
+ int arg6 ;
+ int arg7 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ int alloc2 = 0 ;
+ int val3 ;
+ int ecode3 = 0 ;
+ int res4 ;
+ char *buf4 = 0 ;
+ int alloc4 = 0 ;
+ int val5 ;
+ int ecode5 = 0 ;
+ int val6 ;
+ int ecode6 = 0 ;
+ int val7 ;
+ int ecode7 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject * obj3 = 0 ;
+ PyObject * obj4 = 0 ;
+ PyObject * obj5 = 0 ;
+ PyObject * obj6 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_name_add_entry_by_txt",7,7,&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_NAME, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_name_add_entry_by_txt" "', argument " "1"" of type '" "X509_NAME *""'");
+ }
+ arg1 = (X509_NAME *)(argp1);
+ res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "x509_name_add_entry_by_txt" "', argument " "2"" of type '" "char *""'");
+ }
+ arg2 = (char *)(buf2);
+ ecode3 = SWIG_AsVal_int(obj2, &val3);
+ if (!SWIG_IsOK(ecode3)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "x509_name_add_entry_by_txt" "', argument " "3"" of type '" "int""'");
+ }
+ arg3 = (int)(val3);
+ res4 = SWIG_AsCharPtrAndSize(obj3, &buf4, NULL, &alloc4);
+ if (!SWIG_IsOK(res4)) {
+ SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "x509_name_add_entry_by_txt" "', argument " "4"" of type '" "char *""'");
+ }
+ arg4 = (char *)(buf4);
+ ecode5 = SWIG_AsVal_int(obj4, &val5);
+ if (!SWIG_IsOK(ecode5)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "x509_name_add_entry_by_txt" "', argument " "5"" of type '" "int""'");
+ }
+ arg5 = (int)(val5);
+ ecode6 = SWIG_AsVal_int(obj5, &val6);
+ if (!SWIG_IsOK(ecode6)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "x509_name_add_entry_by_txt" "', argument " "6"" of type '" "int""'");
+ }
+ arg6 = (int)(val6);
+ ecode7 = SWIG_AsVal_int(obj6, &val7);
+ if (!SWIG_IsOK(ecode7)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "x509_name_add_entry_by_txt" "', argument " "7"" of type '" "int""'");
+ }
+ arg7 = (int)(val7);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)x509_name_add_entry_by_txt(arg1,arg2,arg3,arg4,arg5,arg6,arg7);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ if (alloc4 == SWIG_NEWOBJ) free((char*)buf4);
+ return resultobj;
+fail:
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ if (alloc4 == SWIG_NEWOBJ) free((char*)buf4);
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_name_get_der(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_NAME *arg1 = (X509_NAME *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_name_get_der",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_NAME, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_name_get_der" "', argument " "1"" of type '" "X509_NAME *""'");
+ }
+ arg1 = (X509_NAME *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)x509_name_get_der(arg1);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_sk_x509_free(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ struct stack_st_X509 *arg1 = (struct stack_st_X509 *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"sk_x509_free",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_stack_st_X509, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "sk_x509_free" "', argument " "1"" of type '" "struct stack_st_X509 *""'");
+ }
+ arg1 = (struct stack_st_X509 *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ sk_x509_free(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_sk_x509_push(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ struct stack_st_X509 *arg1 = (struct stack_st_X509 *) 0 ;
+ X509 *arg2 = (X509 *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"sk_x509_push",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_stack_st_X509, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "sk_x509_push" "', argument " "1"" of type '" "struct stack_st_X509 *""'");
+ }
+ arg1 = (struct stack_st_X509 *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_X509, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "sk_x509_push" "', argument " "2"" of type '" "X509 *""'");
+ }
+ arg2 = (X509 *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)sk_x509_push(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_sk_x509_pop(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ struct stack_st_X509 *arg1 = (struct stack_st_X509 *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ X509 *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"sk_x509_pop",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_stack_st_X509, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "sk_x509_pop" "', argument " "1"" of type '" "struct stack_st_X509 *""'");
+ }
+ arg1 = (struct stack_st_X509 *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (X509 *)sk_x509_pop(arg1);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_X509, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_store_load_locations(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_STORE *arg1 = (X509_STORE *) 0 ;
+ char *arg2 = (char *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ int alloc2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_store_load_locations",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_STORE, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_store_load_locations" "', argument " "1"" of type '" "X509_STORE *""'");
+ }
+ arg1 = (X509_STORE *)(argp1);
+ res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "x509_store_load_locations" "', argument " "2"" of type '" "char const *""'");
+ }
+ arg2 = (char *)(buf2);
+ result = (int)x509_store_load_locations(arg1,(char const *)arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return resultobj;
+fail:
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_type_check(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509 *arg1 = (X509 *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_type_check",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_type_check" "', argument " "1"" of type '" "X509 *""'");
+ }
+ arg1 = (X509 *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)x509_type_check(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_name_type_check(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_NAME *arg1 = (X509_NAME *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_name_type_check",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_NAME, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_name_type_check" "', argument " "1"" of type '" "X509_NAME *""'");
+ }
+ arg1 = (X509_NAME *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)x509_name_type_check(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_req_get_subject_name(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_REQ *arg1 = (X509_REQ *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ X509_NAME *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_req_get_subject_name",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_REQ, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_req_get_subject_name" "', argument " "1"" of type '" "X509_REQ *""'");
+ }
+ arg1 = (X509_REQ *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (X509_NAME *)x509_req_get_subject_name(arg1);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_X509_NAME, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_req_get_version(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_REQ *arg1 = (X509_REQ *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ long result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_req_get_version",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_REQ, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_req_get_version" "', argument " "1"" of type '" "X509_REQ *""'");
+ }
+ arg1 = (X509_REQ *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (long)x509_req_get_version(arg1);
+ resultobj = SWIG_From_long((long)(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_req_set_version(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_REQ *arg1 = (X509_REQ *) 0 ;
+ long arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ long val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_req_set_version",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_REQ, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_req_set_version" "', argument " "1"" of type '" "X509_REQ *""'");
+ }
+ arg1 = (X509_REQ *)(argp1);
+ ecode2 = SWIG_AsVal_long(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "x509_req_set_version" "', argument " "2"" of type '" "long""'");
+ }
+ arg2 = (long)(val2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)x509_req_set_version(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_req_add_extensions(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_REQ *arg1 = (X509_REQ *) 0 ;
+ struct stack_st_X509_EXTENSION *arg2 = (struct stack_st_X509_EXTENSION *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_req_add_extensions",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_REQ, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_req_add_extensions" "', argument " "1"" of type '" "X509_REQ *""'");
+ }
+ arg1 = (X509_REQ *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_stack_st_X509_EXTENSION, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "x509_req_add_extensions" "', argument " "2"" of type '" "struct stack_st_X509_EXTENSION *""'");
+ }
+ arg2 = (struct stack_st_X509_EXTENSION *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)x509_req_add_extensions(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_name_entry_create_by_txt(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_NAME_ENTRY **arg1 = (X509_NAME_ENTRY **) 0 ;
+ char *arg2 = (char *) 0 ;
+ int arg3 ;
+ char *arg4 = (char *) 0 ;
+ int arg5 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ int alloc2 = 0 ;
+ int val3 ;
+ int ecode3 = 0 ;
+ int res4 ;
+ char *buf4 = 0 ;
+ int alloc4 = 0 ;
+ int val5 ;
+ int ecode5 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject * obj3 = 0 ;
+ PyObject * obj4 = 0 ;
+ X509_NAME_ENTRY *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_name_entry_create_by_txt",5,5,&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_p_X509_NAME_ENTRY, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_name_entry_create_by_txt" "', argument " "1"" of type '" "X509_NAME_ENTRY **""'");
+ }
+ arg1 = (X509_NAME_ENTRY **)(argp1);
+ res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "x509_name_entry_create_by_txt" "', argument " "2"" of type '" "char *""'");
+ }
+ arg2 = (char *)(buf2);
+ ecode3 = SWIG_AsVal_int(obj2, &val3);
+ if (!SWIG_IsOK(ecode3)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "x509_name_entry_create_by_txt" "', argument " "3"" of type '" "int""'");
+ }
+ arg3 = (int)(val3);
+ res4 = SWIG_AsCharPtrAndSize(obj3, &buf4, NULL, &alloc4);
+ if (!SWIG_IsOK(res4)) {
+ SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "x509_name_entry_create_by_txt" "', argument " "4"" of type '" "char *""'");
+ }
+ arg4 = (char *)(buf4);
+ ecode5 = SWIG_AsVal_int(obj4, &val5);
+ if (!SWIG_IsOK(ecode5)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "x509_name_entry_create_by_txt" "', argument " "5"" of type '" "int""'");
+ }
+ arg5 = (int)(val5);
+ result = (X509_NAME_ENTRY *)x509_name_entry_create_by_txt(arg1,arg2,arg3,arg4,arg5);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_X509_NAME_ENTRY, 0 | 0 );
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ if (alloc4 == SWIG_NEWOBJ) free((char*)buf4);
+ return resultobj;
+fail:
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ if (alloc4 == SWIG_NEWOBJ) free((char*)buf4);
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509v3_set_nconf(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509V3_CTX *result = 0 ;
+
+ result = (X509V3_CTX *)x509v3_set_nconf();
+ {
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+
+ if (result != NULL)
+ resultobj = SWIG_NewPointerObj(result, SWIGTYPE_p_X509V3_CTX, 0);
+ else {
+ resultobj = NULL;
+ }
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509v3_ext_conf(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ void *arg1 = (void *) 0 ;
+ X509V3_CTX *arg2 = (X509V3_CTX *) 0 ;
+ char *arg3 = (char *) 0 ;
+ char *arg4 = (char *) 0 ;
+ int res1 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ int res3 ;
+ char *buf3 = 0 ;
+ int alloc3 = 0 ;
+ int res4 ;
+ char *buf4 = 0 ;
+ int alloc4 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject * obj3 = 0 ;
+ X509_EXTENSION *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509v3_ext_conf",4,4,&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0,SWIG_as_voidptrptr(&arg1), 0, 0);
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509v3_ext_conf" "', argument " "1"" of type '" "void *""'");
+ }
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_X509V3_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "x509v3_ext_conf" "', argument " "2"" of type '" "X509V3_CTX *""'");
+ }
+ arg2 = (X509V3_CTX *)(argp2);
+ res3 = SWIG_AsCharPtrAndSize(obj2, &buf3, NULL, &alloc3);
+ if (!SWIG_IsOK(res3)) {
+ SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "x509v3_ext_conf" "', argument " "3"" of type '" "char *""'");
+ }
+ arg3 = (char *)(buf3);
+ res4 = SWIG_AsCharPtrAndSize(obj3, &buf4, NULL, &alloc4);
+ if (!SWIG_IsOK(res4)) {
+ SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "x509v3_ext_conf" "', argument " "4"" of type '" "char *""'");
+ }
+ arg4 = (char *)(buf4);
+ result = (X509_EXTENSION *)x509v3_ext_conf(arg1,arg2,arg3,arg4);
+ {
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+
+ if (result != NULL)
+ resultobj = SWIG_NewPointerObj(result, SWIGTYPE_p_X509_EXTENSION, 0);
+ else {
+ m2_PyErr_Msg(_x509_err);
+ resultobj = NULL;
+ }
+ }
+ if (alloc3 == SWIG_NEWOBJ) free((char*)buf3);
+ if (alloc4 == SWIG_NEWOBJ) free((char*)buf4);
+ return resultobj;
+fail:
+ if (alloc3 == SWIG_NEWOBJ) free((char*)buf3);
+ if (alloc4 == SWIG_NEWOBJ) free((char*)buf4);
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_extension_free(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_EXTENSION *arg1 = (X509_EXTENSION *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_extension_free",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_EXTENSION, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_extension_free" "', argument " "1"" of type '" "X509_EXTENSION *""'");
+ }
+ arg1 = (X509_EXTENSION *)(argp1);
+ x509_extension_free(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_extension_get_name(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_EXTENSION *arg1 = (X509_EXTENSION *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_extension_get_name",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_EXTENSION, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_extension_get_name" "', argument " "1"" of type '" "X509_EXTENSION *""'");
+ }
+ arg1 = (X509_EXTENSION *)(argp1);
+ result = (PyObject *)x509_extension_get_name(arg1);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_sk_x509_extension_new_null(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ struct stack_st_X509_EXTENSION *result = 0 ;
+
+ result = (struct stack_st_X509_EXTENSION *)sk_x509_extension_new_null();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_stack_st_X509_EXTENSION, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_sk_x509_extension_free(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ struct stack_st_X509_EXTENSION *arg1 = (struct stack_st_X509_EXTENSION *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"sk_x509_extension_free",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_stack_st_X509_EXTENSION, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "sk_x509_extension_free" "', argument " "1"" of type '" "struct stack_st_X509_EXTENSION *""'");
+ }
+ arg1 = (struct stack_st_X509_EXTENSION *)(argp1);
+ sk_x509_extension_free(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_sk_x509_extension_push(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ struct stack_st_X509_EXTENSION *arg1 = (struct stack_st_X509_EXTENSION *) 0 ;
+ X509_EXTENSION *arg2 = (X509_EXTENSION *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"sk_x509_extension_push",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_stack_st_X509_EXTENSION, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "sk_x509_extension_push" "', argument " "1"" of type '" "struct stack_st_X509_EXTENSION *""'");
+ }
+ arg1 = (struct stack_st_X509_EXTENSION *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_X509_EXTENSION, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "sk_x509_extension_push" "', argument " "2"" of type '" "X509_EXTENSION *""'");
+ }
+ arg2 = (X509_EXTENSION *)(argp2);
+ result = (int)sk_x509_extension_push(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_sk_x509_extension_pop(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ struct stack_st_X509_EXTENSION *arg1 = (struct stack_st_X509_EXTENSION *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ X509_EXTENSION *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"sk_x509_extension_pop",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_stack_st_X509_EXTENSION, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "sk_x509_extension_pop" "', argument " "1"" of type '" "struct stack_st_X509_EXTENSION *""'");
+ }
+ arg1 = (struct stack_st_X509_EXTENSION *)(argp1);
+ result = (X509_EXTENSION *)sk_x509_extension_pop(arg1);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_X509_EXTENSION, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_sk_x509_extension_num(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ struct stack_st_X509_EXTENSION *arg1 = (struct stack_st_X509_EXTENSION *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"sk_x509_extension_num",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_stack_st_X509_EXTENSION, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "sk_x509_extension_num" "', argument " "1"" of type '" "struct stack_st_X509_EXTENSION *""'");
+ }
+ arg1 = (struct stack_st_X509_EXTENSION *)(argp1);
+ result = (int)sk_x509_extension_num(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_sk_x509_extension_value(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ struct stack_st_X509_EXTENSION *arg1 = (struct stack_st_X509_EXTENSION *) 0 ;
+ int arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ X509_EXTENSION *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"sk_x509_extension_value",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_stack_st_X509_EXTENSION, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "sk_x509_extension_value" "', argument " "1"" of type '" "struct stack_st_X509_EXTENSION *""'");
+ }
+ arg1 = (struct stack_st_X509_EXTENSION *)(argp1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "sk_x509_extension_value" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ result = (X509_EXTENSION *)sk_x509_extension_value(arg1,arg2);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_X509_EXTENSION, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_store_ctx_get_app_data(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_STORE_CTX *arg1 = (X509_STORE_CTX *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ void *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_store_ctx_get_app_data",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_STORE_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_store_ctx_get_app_data" "', argument " "1"" of type '" "X509_STORE_CTX *""'");
+ }
+ arg1 = (X509_STORE_CTX *)(argp1);
+ result = (void *)x509_store_ctx_get_app_data(arg1);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_void, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_store_ctx_get_ex_data(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_STORE_CTX *arg1 = (X509_STORE_CTX *) 0 ;
+ int arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ void *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_store_ctx_get_ex_data",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_STORE_CTX, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_store_ctx_get_ex_data" "', argument " "1"" of type '" "X509_STORE_CTX *""'");
+ }
+ arg1 = (X509_STORE_CTX *)(argp1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "x509_store_ctx_get_ex_data" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ result = (void *)x509_store_ctx_get_ex_data(arg1,arg2);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_void, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_store_set_verify_cb__SWIG_1(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_STORE *arg1 = (X509_STORE *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_store_set_verify_cb",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_STORE, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_store_set_verify_cb" "', argument " "1"" of type '" "X509_STORE *""'");
+ }
+ arg1 = (X509_STORE *)(argp1);
+ {
+ if (!PyCallable_Check(obj1)) {
+ PyErr_SetString(PyExc_TypeError, "expected PyCallable");
+ return NULL;
+ }
+ arg2=obj1;
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ x509_store_set_verify_cb(arg1,arg2);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_store_set_verify_cb(PyObject *self, PyObject *args) {
+ int argc;
+ PyObject *argv[3];
+ int ii;
+
+ if (!PyTuple_Check(args)) SWIG_fail;
+ argc = args ? (int)PyObject_Length(args) : 0;
+ for (ii = 0; (ii < 2) && (ii < argc); ii++) {
+ argv[ii] = PyTuple_GET_ITEM(args,ii);
+ }
+ if (argc == 2) {
+ int _v;
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_X509_STORE, 0);
+ _v = SWIG_CheckState(res);
+ if (_v) {
+ void *ptr = 0;
+ int res = SWIG_ConvertFunctionPtr(argv[1], &ptr, SWIGTYPE_p_f_int_p_X509_STORE_CTX__int);
+ _v = SWIG_CheckState(res);
+ if (_v) {
+ return _wrap_x509_store_set_verify_cb__SWIG_0(self, args);
+ }
+ }
+ }
+ if (argc == 2) {
+ int _v;
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_X509_STORE, 0);
+ _v = SWIG_CheckState(res);
+ if (_v) {
+ _v = (argv[1] != 0);
+ if (_v) {
+ return _wrap_x509_store_set_verify_cb__SWIG_1(self, args);
+ }
+ }
+ }
+
+fail:
+ SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'x509_store_set_verify_cb'.\n"
+ " Possible C/C++ prototypes are:\n"
+ " X509_STORE_set_verify_cb(X509_STORE *,int (*)(int,X509_STORE_CTX *))\n"
+ " x509_store_set_verify_cb(X509_STORE *,PyObject *)\n");
+ return 0;
+}
+
+
+SWIGINTERN PyObject *_wrap_make_stack_from_der_sequence(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ PyObject *arg1 = (PyObject *) 0 ;
+ PyObject * obj0 = 0 ;
+ struct stack_st_X509 *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"make_stack_from_der_sequence",1,1,&obj0)) SWIG_fail;
+ {
+ arg1=obj0;
+ }
+ result = (struct stack_st_X509 *)make_stack_from_der_sequence(arg1);
+ {
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+
+ if (result != NULL)
+ resultobj = SWIG_NewPointerObj(result, SWIGTYPE_p_stack_st_X509, 0);
+ else {
+ resultobj = NULL;
+ }
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_sk_x509_new_null(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ struct stack_st_X509 *result = 0 ;
+
+ result = (struct stack_st_X509 *)sk_x509_new_null();
+ {
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+
+ if (result != NULL)
+ resultobj = SWIG_NewPointerObj(result, SWIGTYPE_p_stack_st_X509, 0);
+ else {
+ resultobj = NULL;
+ }
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_get_der_encoding_stack(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ struct stack_st_X509 *arg1 = (struct stack_st_X509 *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"get_der_encoding_stack",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_stack_st_X509, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "get_der_encoding_stack" "', argument " "1"" of type '" "struct stack_st_X509 *""'");
+ }
+ arg1 = (struct stack_st_X509 *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)get_der_encoding_stack(arg1);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_x509_name_oneline(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509_NAME *arg1 = (X509_NAME *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ char *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"x509_name_oneline",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509_NAME, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "x509_name_oneline" "', argument " "1"" of type '" "X509_NAME *""'");
+ }
+ arg1 = (X509_NAME *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (char *)x509_name_oneline(arg1);
+ resultobj = SWIG_FromCharPtr((const char *)result);
+ {
+ if (result != NULL)
+ OPENSSL_free(result);
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_asn1_object_new(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ ASN1_OBJECT *result = 0 ;
+
+ result = (ASN1_OBJECT *)ASN1_OBJECT_new();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ASN1_OBJECT, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_asn1_object_create(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ int arg1 ;
+ unsigned char *arg2 = (unsigned char *) 0 ;
+ int arg3 ;
+ char *arg4 = (char *) 0 ;
+ char *arg5 = (char *) 0 ;
+ int val1 ;
+ int ecode1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ int val3 ;
+ int ecode3 = 0 ;
+ int res4 ;
+ char *buf4 = 0 ;
+ int alloc4 = 0 ;
+ int res5 ;
+ char *buf5 = 0 ;
+ int alloc5 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject * obj3 = 0 ;
+ PyObject * obj4 = 0 ;
+ ASN1_OBJECT *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"asn1_object_create",5,5,&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
+ ecode1 = SWIG_AsVal_int(obj0, &val1);
+ if (!SWIG_IsOK(ecode1)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "asn1_object_create" "', argument " "1"" of type '" "int""'");
+ }
+ arg1 = (int)(val1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_unsigned_char, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "asn1_object_create" "', argument " "2"" of type '" "unsigned char *""'");
+ }
+ arg2 = (unsigned char *)(argp2);
+ ecode3 = SWIG_AsVal_int(obj2, &val3);
+ if (!SWIG_IsOK(ecode3)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "asn1_object_create" "', argument " "3"" of type '" "int""'");
+ }
+ arg3 = (int)(val3);
+ res4 = SWIG_AsCharPtrAndSize(obj3, &buf4, NULL, &alloc4);
+ if (!SWIG_IsOK(res4)) {
+ SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "asn1_object_create" "', argument " "4"" of type '" "char const *""'");
+ }
+ arg4 = (char *)(buf4);
+ res5 = SWIG_AsCharPtrAndSize(obj4, &buf5, NULL, &alloc5);
+ if (!SWIG_IsOK(res5)) {
+ SWIG_exception_fail(SWIG_ArgError(res5), "in method '" "asn1_object_create" "', argument " "5"" of type '" "char const *""'");
+ }
+ arg5 = (char *)(buf5);
+ result = (ASN1_OBJECT *)ASN1_OBJECT_create(arg1,arg2,arg3,(char const *)arg4,(char const *)arg5);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ASN1_OBJECT, 0 | 0 );
+ if (alloc4 == SWIG_NEWOBJ) free((char*)buf4);
+ if (alloc5 == SWIG_NEWOBJ) free((char*)buf5);
+ return resultobj;
+fail:
+ if (alloc4 == SWIG_NEWOBJ) free((char*)buf4);
+ if (alloc5 == SWIG_NEWOBJ) free((char*)buf5);
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_asn1_object_free(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ ASN1_OBJECT *arg1 = (ASN1_OBJECT *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"asn1_object_free",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ASN1_OBJECT, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "asn1_object_free" "', argument " "1"" of type '" "ASN1_OBJECT *""'");
+ }
+ arg1 = (ASN1_OBJECT *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ ASN1_OBJECT_free(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_i2d_asn1_object(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ ASN1_OBJECT *arg1 = (ASN1_OBJECT *) 0 ;
+ unsigned char **arg2 = (unsigned char **) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"i2d_asn1_object",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ASN1_OBJECT, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "i2d_asn1_object" "', argument " "1"" of type '" "ASN1_OBJECT *""'");
+ }
+ arg1 = (ASN1_OBJECT *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_p_unsigned_char, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "i2d_asn1_object" "', argument " "2"" of type '" "unsigned char **""'");
+ }
+ arg2 = (unsigned char **)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)i2d_ASN1_OBJECT(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_d2i_asn1_object(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ ASN1_OBJECT **arg1 = (ASN1_OBJECT **) 0 ;
+ unsigned char **arg2 = (unsigned char **) 0 ;
+ long arg3 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ long val3 ;
+ int ecode3 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ ASN1_OBJECT *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"d2i_asn1_object",3,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_p_ASN1_OBJECT, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "d2i_asn1_object" "', argument " "1"" of type '" "ASN1_OBJECT **""'");
+ }
+ arg1 = (ASN1_OBJECT **)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_p_unsigned_char, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "d2i_asn1_object" "', argument " "2"" of type '" "unsigned char const **""'");
+ }
+ arg2 = (unsigned char **)(argp2);
+ ecode3 = SWIG_AsVal_long(obj2, &val3);
+ if (!SWIG_IsOK(ecode3)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "d2i_asn1_object" "', argument " "3"" of type '" "long""'");
+ }
+ arg3 = (long)(val3);
+ result = (ASN1_OBJECT *)d2i_ASN1_OBJECT(arg1,(unsigned char const **)arg2,arg3);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ASN1_OBJECT, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_asn1_bit_string_new(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ ASN1_BIT_STRING *result = 0 ;
+
+ result = (ASN1_BIT_STRING *)ASN1_BIT_STRING_new();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ASN1_BIT_STRING, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_asn1_string_new(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ ASN1_STRING *result = 0 ;
+
+ result = (ASN1_STRING *)ASN1_STRING_new();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ASN1_STRING, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_asn1_string_free(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ ASN1_STRING *arg1 = (ASN1_STRING *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"asn1_string_free",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ASN1_STRING, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "asn1_string_free" "', argument " "1"" of type '" "ASN1_STRING *""'");
+ }
+ arg1 = (ASN1_STRING *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ ASN1_STRING_free(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_asn1_string_set(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ ASN1_STRING *arg1 = (ASN1_STRING *) 0 ;
+ void *arg2 = (void *) 0 ;
+ int arg3 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"asn1_string_set",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ASN1_STRING, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "asn1_string_set" "', argument " "1"" of type '" "ASN1_STRING *""'");
+ }
+ arg1 = (ASN1_STRING *)(argp1);
+ {
+ if (PyBytes_Check(obj1)) {
+ Py_ssize_t len;
+
+ arg2 = PyBytes_AsString(obj1);
+ len = PyBytes_Size(obj1);
+
+ if (len > INT_MAX) {
+ PyErr_SetString(PyExc_ValueError, "object too large");
+ return NULL;
+ }
+ arg3 = len;
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError, "expected string");
+ return NULL;
+ }
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)ASN1_STRING_set(arg1,(void const *)arg2,arg3);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_asn1_string_print(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ ASN1_STRING *arg2 = (ASN1_STRING *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"asn1_string_print",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "asn1_string_print" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_ASN1_STRING, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "asn1_string_print" "', argument " "2"" of type '" "ASN1_STRING *""'");
+ }
+ arg2 = (ASN1_STRING *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ result = (int)ASN1_STRING_print(arg1,arg2);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_asn1_string_print_ex(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ ASN1_STRING *arg2 = (ASN1_STRING *) 0 ;
+ unsigned long arg3 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ unsigned long val3 ;
+ int ecode3 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"asn1_string_print_ex",3,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "asn1_string_print_ex" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_ASN1_STRING, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "asn1_string_print_ex" "', argument " "2"" of type '" "ASN1_STRING *""'");
+ }
+ arg2 = (ASN1_STRING *)(argp2);
+ ecode3 = SWIG_AsVal_unsigned_SS_long(obj2, &val3);
+ if (!SWIG_IsOK(ecode3)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "asn1_string_print_ex" "', argument " "3"" of type '" "unsigned long""'");
+ }
+ arg3 = (unsigned long)(val3);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ result = (int)ASN1_STRING_print_ex(arg1,arg2,arg3);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_asn1_time_new(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ ASN1_TIME *result = 0 ;
+
+ result = (ASN1_TIME *)ASN1_TIME_new();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ASN1_TIME, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_asn1_time_free(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ ASN1_TIME *arg1 = (ASN1_TIME *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"asn1_time_free",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ASN1_TIME, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "asn1_time_free" "', argument " "1"" of type '" "ASN1_TIME *""'");
+ }
+ arg1 = (ASN1_TIME *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ ASN1_TIME_free(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_asn1_time_check(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ ASN1_TIME *arg1 = (ASN1_TIME *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"asn1_time_check",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ASN1_TIME, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "asn1_time_check" "', argument " "1"" of type '" "ASN1_TIME *""'");
+ }
+ arg1 = (ASN1_TIME *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)ASN1_TIME_check(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_asn1_time_set(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ ASN1_TIME *arg1 = (ASN1_TIME *) 0 ;
+ long arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ long val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ ASN1_TIME *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"asn1_time_set",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ASN1_TIME, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "asn1_time_set" "', argument " "1"" of type '" "ASN1_TIME *""'");
+ }
+ arg1 = (ASN1_TIME *)(argp1);
+ ecode2 = SWIG_AsVal_long(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "asn1_time_set" "', argument " "2"" of type '" "long""'");
+ }
+ arg2 = (long)(val2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (ASN1_TIME *)ASN1_TIME_set(arg1,arg2);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ASN1_TIME, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_asn1_time_set_string(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ ASN1_TIME *arg1 = (ASN1_TIME *) 0 ;
+ char *arg2 = (char *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ int alloc2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"asn1_time_set_string",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ASN1_TIME, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "asn1_time_set_string" "', argument " "1"" of type '" "ASN1_TIME *""'");
+ }
+ arg1 = (ASN1_TIME *)(argp1);
+ res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "asn1_time_set_string" "', argument " "2"" of type '" "char const *""'");
+ }
+ arg2 = (char *)(buf2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)ASN1_TIME_set_string(arg1,(char const *)arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return resultobj;
+fail:
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_asn1_time_print(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ ASN1_TIME *arg2 = (ASN1_TIME *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"asn1_time_print",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "asn1_time_print" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_ASN1_TIME, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "asn1_time_print" "', argument " "2"" of type '" "ASN1_TIME *""'");
+ }
+ arg2 = (ASN1_TIME *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ result = (int)ASN1_TIME_print(arg1,arg2);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_asn1_integer_new(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ ASN1_INTEGER *result = 0 ;
+
+ result = (ASN1_INTEGER *)ASN1_INTEGER_new();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ASN1_INTEGER, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_asn1_integer_free(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ ASN1_INTEGER *arg1 = (ASN1_INTEGER *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"asn1_integer_free",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ASN1_INTEGER, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "asn1_integer_free" "', argument " "1"" of type '" "ASN1_INTEGER *""'");
+ }
+ arg1 = (ASN1_INTEGER *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ ASN1_INTEGER_free(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_asn1_integer_cmp(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ ASN1_INTEGER *arg1 = (ASN1_INTEGER *) 0 ;
+ ASN1_INTEGER *arg2 = (ASN1_INTEGER *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"asn1_integer_cmp",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ASN1_INTEGER, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "asn1_integer_cmp" "', argument " "1"" of type '" "ASN1_INTEGER *""'");
+ }
+ arg1 = (ASN1_INTEGER *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_ASN1_INTEGER, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "asn1_integer_cmp" "', argument " "2"" of type '" "ASN1_INTEGER *""'");
+ }
+ arg2 = (ASN1_INTEGER *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)ASN1_INTEGER_cmp(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_asn1_time_type_check(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ ASN1_TIME *arg1 = (ASN1_TIME *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"asn1_time_type_check",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ASN1_TIME, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "asn1_time_type_check" "', argument " "1"" of type '" "ASN1_TIME *""'");
+ }
+ arg1 = (ASN1_TIME *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)asn1_time_type_check(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_asn1_integer_get(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ ASN1_INTEGER *arg1 = (ASN1_INTEGER *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"asn1_integer_get",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ASN1_INTEGER, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "asn1_integer_get" "', argument " "1"" of type '" "ASN1_INTEGER *""'");
+ }
+ arg1 = (ASN1_INTEGER *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)asn1_integer_get(arg1);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_asn1_integer_set(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ ASN1_INTEGER *arg1 = (ASN1_INTEGER *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"asn1_integer_set",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ASN1_INTEGER, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "asn1_integer_set" "', argument " "1"" of type '" "ASN1_INTEGER *""'");
+ }
+ arg1 = (ASN1_INTEGER *)(argp1);
+ {
+ arg2=obj1;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)asn1_integer_set(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_pkcs7_new(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ PKCS7 *result = 0 ;
+
+ result = (PKCS7 *)PKCS7_new();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_PKCS7, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_pkcs7_free(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ PKCS7 *arg1 = (PKCS7 *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"pkcs7_free",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_PKCS7, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "pkcs7_free" "', argument " "1"" of type '" "PKCS7 *""'");
+ }
+ arg1 = (PKCS7 *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ PKCS7_free(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_pkcs7_add_certificate(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ PKCS7 *arg1 = (PKCS7 *) 0 ;
+ X509 *arg2 = (X509 *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"pkcs7_add_certificate",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_PKCS7, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "pkcs7_add_certificate" "', argument " "1"" of type '" "PKCS7 *""'");
+ }
+ arg1 = (PKCS7 *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_X509, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "pkcs7_add_certificate" "', argument " "2"" of type '" "X509 *""'");
+ }
+ arg2 = (X509 *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ PKCS7_add_certificate(arg1,arg2);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN int Swig_var__pkcs7_err_set(PyObject *_val) {
+ {
+ void *argp = 0;
+ int res = SWIG_ConvertPtr(_val, &argp, SWIGTYPE_p_PyObject, 0 );
+ if (!SWIG_IsOK(res)) {
+ SWIG_exception_fail(SWIG_ArgError(res), "in variable '""_pkcs7_err""' of type '""PyObject *""'");
+ }
+ _pkcs7_err = (PyObject *)(argp);
+ }
+ return 0;
+fail:
+ return 1;
+}
+
+
+SWIGINTERN PyObject *Swig_var__pkcs7_err_get(void) {
+ PyObject *pyobj = 0;
+ PyObject *self = 0;
+
+ (void)self;
+ pyobj = SWIG_NewPointerObj(SWIG_as_voidptr(_pkcs7_err), SWIGTYPE_p_PyObject, 0 );
+ return pyobj;
+}
+
+
+SWIGINTERN int Swig_var__smime_err_set(PyObject *_val) {
+ {
+ void *argp = 0;
+ int res = SWIG_ConvertPtr(_val, &argp, SWIGTYPE_p_PyObject, 0 );
+ if (!SWIG_IsOK(res)) {
+ SWIG_exception_fail(SWIG_ArgError(res), "in variable '""_smime_err""' of type '""PyObject *""'");
+ }
+ _smime_err = (PyObject *)(argp);
+ }
+ return 0;
+fail:
+ return 1;
+}
+
+
+SWIGINTERN PyObject *Swig_var__smime_err_get(void) {
+ PyObject *pyobj = 0;
+ PyObject *self = 0;
+
+ (void)self;
+ pyobj = SWIG_NewPointerObj(SWIG_as_voidptr(_smime_err), SWIGTYPE_p_PyObject, 0 );
+ return pyobj;
+}
+
+
+SWIGINTERN PyObject *_wrap_pkcs7_init(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ PyObject *arg1 = (PyObject *) 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"pkcs7_init",1,1,&obj0)) SWIG_fail;
+ {
+ arg1=obj0;
+ }
+ pkcs7_init(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_smime_init(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ PyObject *arg1 = (PyObject *) 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"smime_init",1,1,&obj0)) SWIG_fail;
+ {
+ arg1=obj0;
+ }
+ smime_init(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_pkcs7_decrypt(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ PKCS7 *arg1 = (PKCS7 *) 0 ;
+ EVP_PKEY *arg2 = (EVP_PKEY *) 0 ;
+ X509 *arg3 = (X509 *) 0 ;
+ int arg4 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ void *argp3 = 0 ;
+ int res3 = 0 ;
+ int val4 ;
+ int ecode4 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject * obj3 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"pkcs7_decrypt",4,4,&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_PKCS7, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "pkcs7_decrypt" "', argument " "1"" of type '" "PKCS7 *""'");
+ }
+ arg1 = (PKCS7 *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_EVP_PKEY, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "pkcs7_decrypt" "', argument " "2"" of type '" "EVP_PKEY *""'");
+ }
+ arg2 = (EVP_PKEY *)(argp2);
+ res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_X509, 0 | 0 );
+ if (!SWIG_IsOK(res3)) {
+ SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "pkcs7_decrypt" "', argument " "3"" of type '" "X509 *""'");
+ }
+ arg3 = (X509 *)(argp3);
+ ecode4 = SWIG_AsVal_int(obj3, &val4);
+ if (!SWIG_IsOK(ecode4)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "pkcs7_decrypt" "', argument " "4"" of type '" "int""'");
+ }
+ arg4 = (int)(val4);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg3) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)pkcs7_decrypt(arg1,arg2,arg3,arg4);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_pkcs7_encrypt(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ struct stack_st_X509 *arg1 = (struct stack_st_X509 *) 0 ;
+ BIO *arg2 = (BIO *) 0 ;
+ EVP_CIPHER *arg3 = (EVP_CIPHER *) 0 ;
+ int arg4 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ void *argp3 = 0 ;
+ int res3 = 0 ;
+ int val4 ;
+ int ecode4 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject * obj3 = 0 ;
+ PKCS7 *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"pkcs7_encrypt",4,4,&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_stack_st_X509, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "pkcs7_encrypt" "', argument " "1"" of type '" "struct stack_st_X509 *""'");
+ }
+ arg1 = (struct stack_st_X509 *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "pkcs7_encrypt" "', argument " "2"" of type '" "BIO *""'");
+ }
+ arg2 = (BIO *)(argp2);
+ res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_EVP_CIPHER, 0 | 0 );
+ if (!SWIG_IsOK(res3)) {
+ SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "pkcs7_encrypt" "', argument " "3"" of type '" "EVP_CIPHER *""'");
+ }
+ arg3 = (EVP_CIPHER *)(argp3);
+ ecode4 = SWIG_AsVal_int(obj3, &val4);
+ if (!SWIG_IsOK(ecode4)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "pkcs7_encrypt" "', argument " "4"" of type '" "int""'");
+ }
+ arg4 = (int)(val4);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg3) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ result = (PKCS7 *)pkcs7_encrypt(arg1,arg2,arg3,arg4);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ {
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+
+ if (result != NULL)
+ resultobj = SWIG_NewPointerObj(result, SWIGTYPE_p_PKCS7, 0);
+ else {
+ m2_PyErr_Msg(_smime_err);
+ resultobj = NULL;
+ }
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_pkcs7_sign1(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509 *arg1 = (X509 *) 0 ;
+ EVP_PKEY *arg2 = (EVP_PKEY *) 0 ;
+ struct stack_st_X509 *arg3 = (struct stack_st_X509 *) 0 ;
+ BIO *arg4 = (BIO *) 0 ;
+ EVP_MD *arg5 = (EVP_MD *) 0 ;
+ int arg6 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ void *argp3 = 0 ;
+ int res3 = 0 ;
+ void *argp4 = 0 ;
+ int res4 = 0 ;
+ void *argp5 = 0 ;
+ int res5 = 0 ;
+ int val6 ;
+ int ecode6 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject * obj3 = 0 ;
+ PyObject * obj4 = 0 ;
+ PyObject * obj5 = 0 ;
+ PKCS7 *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"pkcs7_sign1",6,6,&obj0,&obj1,&obj2,&obj3,&obj4,&obj5)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "pkcs7_sign1" "', argument " "1"" of type '" "X509 *""'");
+ }
+ arg1 = (X509 *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_EVP_PKEY, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "pkcs7_sign1" "', argument " "2"" of type '" "EVP_PKEY *""'");
+ }
+ arg2 = (EVP_PKEY *)(argp2);
+ res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_stack_st_X509, 0 | 0 );
+ if (!SWIG_IsOK(res3)) {
+ SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "pkcs7_sign1" "', argument " "3"" of type '" "struct stack_st_X509 *""'");
+ }
+ arg3 = (struct stack_st_X509 *)(argp3);
+ res4 = SWIG_ConvertPtr(obj3, &argp4,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res4)) {
+ SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "pkcs7_sign1" "', argument " "4"" of type '" "BIO *""'");
+ }
+ arg4 = (BIO *)(argp4);
+ res5 = SWIG_ConvertPtr(obj4, &argp5,SWIGTYPE_p_EVP_MD, 0 | 0 );
+ if (!SWIG_IsOK(res5)) {
+ SWIG_exception_fail(SWIG_ArgError(res5), "in method '" "pkcs7_sign1" "', argument " "5"" of type '" "EVP_MD *""'");
+ }
+ arg5 = (EVP_MD *)(argp5);
+ ecode6 = SWIG_AsVal_int(obj5, &val6);
+ if (!SWIG_IsOK(ecode6)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "pkcs7_sign1" "', argument " "6"" of type '" "int""'");
+ }
+ arg6 = (int)(val6);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg3) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg4) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg5) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ result = (PKCS7 *)pkcs7_sign1(arg1,arg2,arg3,arg4,arg5,arg6);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ {
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+
+ if (result != NULL)
+ resultobj = SWIG_NewPointerObj(result, SWIGTYPE_p_PKCS7, 0);
+ else {
+ m2_PyErr_Msg(_smime_err);
+ resultobj = NULL;
+ }
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_pkcs7_sign0(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ X509 *arg1 = (X509 *) 0 ;
+ EVP_PKEY *arg2 = (EVP_PKEY *) 0 ;
+ BIO *arg3 = (BIO *) 0 ;
+ EVP_MD *arg4 = (EVP_MD *) 0 ;
+ int arg5 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ void *argp3 = 0 ;
+ int res3 = 0 ;
+ void *argp4 = 0 ;
+ int res4 = 0 ;
+ int val5 ;
+ int ecode5 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject * obj3 = 0 ;
+ PyObject * obj4 = 0 ;
+ PKCS7 *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"pkcs7_sign0",5,5,&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_X509, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "pkcs7_sign0" "', argument " "1"" of type '" "X509 *""'");
+ }
+ arg1 = (X509 *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_EVP_PKEY, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "pkcs7_sign0" "', argument " "2"" of type '" "EVP_PKEY *""'");
+ }
+ arg2 = (EVP_PKEY *)(argp2);
+ res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res3)) {
+ SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "pkcs7_sign0" "', argument " "3"" of type '" "BIO *""'");
+ }
+ arg3 = (BIO *)(argp3);
+ res4 = SWIG_ConvertPtr(obj3, &argp4,SWIGTYPE_p_EVP_MD, 0 | 0 );
+ if (!SWIG_IsOK(res4)) {
+ SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "pkcs7_sign0" "', argument " "4"" of type '" "EVP_MD *""'");
+ }
+ arg4 = (EVP_MD *)(argp4);
+ ecode5 = SWIG_AsVal_int(obj4, &val5);
+ if (!SWIG_IsOK(ecode5)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "pkcs7_sign0" "', argument " "5"" of type '" "int""'");
+ }
+ arg5 = (int)(val5);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg3) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg4) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ result = (PKCS7 *)pkcs7_sign0(arg1,arg2,arg3,arg4,arg5);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ {
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+
+ if (result != NULL)
+ resultobj = SWIG_NewPointerObj(result, SWIGTYPE_p_PKCS7, 0);
+ else {
+ m2_PyErr_Msg(_smime_err);
+ resultobj = NULL;
+ }
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_pkcs7_read_bio(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PKCS7 *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"pkcs7_read_bio",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "pkcs7_read_bio" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ result = (PKCS7 *)pkcs7_read_bio(arg1);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ {
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+
+ if (result != NULL)
+ resultobj = SWIG_NewPointerObj(result, SWIGTYPE_p_PKCS7, 0);
+ else {
+ m2_PyErr_Msg(_pkcs7_err);
+ resultobj = NULL;
+ }
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_pkcs7_read_bio_der(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PKCS7 *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"pkcs7_read_bio_der",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "pkcs7_read_bio_der" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ result = (PKCS7 *)pkcs7_read_bio_der(arg1);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ {
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+
+ if (result != NULL)
+ resultobj = SWIG_NewPointerObj(result, SWIGTYPE_p_PKCS7, 0);
+ else {
+ m2_PyErr_Msg(_pkcs7_err);
+ resultobj = NULL;
+ }
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_pkcs7_verify1(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ PKCS7 *arg1 = (PKCS7 *) 0 ;
+ struct stack_st_X509 *arg2 = (struct stack_st_X509 *) 0 ;
+ X509_STORE *arg3 = (X509_STORE *) 0 ;
+ BIO *arg4 = (BIO *) 0 ;
+ int arg5 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ void *argp3 = 0 ;
+ int res3 = 0 ;
+ void *argp4 = 0 ;
+ int res4 = 0 ;
+ int val5 ;
+ int ecode5 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject * obj3 = 0 ;
+ PyObject * obj4 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"pkcs7_verify1",5,5,&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_PKCS7, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "pkcs7_verify1" "', argument " "1"" of type '" "PKCS7 *""'");
+ }
+ arg1 = (PKCS7 *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_stack_st_X509, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "pkcs7_verify1" "', argument " "2"" of type '" "struct stack_st_X509 *""'");
+ }
+ arg2 = (struct stack_st_X509 *)(argp2);
+ res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_X509_STORE, 0 | 0 );
+ if (!SWIG_IsOK(res3)) {
+ SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "pkcs7_verify1" "', argument " "3"" of type '" "X509_STORE *""'");
+ }
+ arg3 = (X509_STORE *)(argp3);
+ res4 = SWIG_ConvertPtr(obj3, &argp4,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res4)) {
+ SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "pkcs7_verify1" "', argument " "4"" of type '" "BIO *""'");
+ }
+ arg4 = (BIO *)(argp4);
+ ecode5 = SWIG_AsVal_int(obj4, &val5);
+ if (!SWIG_IsOK(ecode5)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "pkcs7_verify1" "', argument " "5"" of type '" "int""'");
+ }
+ arg5 = (int)(val5);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg4) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)pkcs7_verify1(arg1,arg2,arg3,arg4,arg5);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_pkcs7_verify0(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ PKCS7 *arg1 = (PKCS7 *) 0 ;
+ struct stack_st_X509 *arg2 = (struct stack_st_X509 *) 0 ;
+ X509_STORE *arg3 = (X509_STORE *) 0 ;
+ int arg4 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ void *argp3 = 0 ;
+ int res3 = 0 ;
+ int val4 ;
+ int ecode4 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject * obj3 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"pkcs7_verify0",4,4,&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_PKCS7, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "pkcs7_verify0" "', argument " "1"" of type '" "PKCS7 *""'");
+ }
+ arg1 = (PKCS7 *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_stack_st_X509, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "pkcs7_verify0" "', argument " "2"" of type '" "struct stack_st_X509 *""'");
+ }
+ arg2 = (struct stack_st_X509 *)(argp2);
+ res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_X509_STORE, 0 | 0 );
+ if (!SWIG_IsOK(res3)) {
+ SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "pkcs7_verify0" "', argument " "3"" of type '" "X509_STORE *""'");
+ }
+ arg3 = (X509_STORE *)(argp3);
+ ecode4 = SWIG_AsVal_int(obj3, &val4);
+ if (!SWIG_IsOK(ecode4)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "pkcs7_verify0" "', argument " "4"" of type '" "int""'");
+ }
+ arg4 = (int)(val4);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)pkcs7_verify0(arg1,arg2,arg3,arg4);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_smime_write_pkcs7_multi(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ PKCS7 *arg2 = (PKCS7 *) 0 ;
+ BIO *arg3 = (BIO *) 0 ;
+ int arg4 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ void *argp3 = 0 ;
+ int res3 = 0 ;
+ int val4 ;
+ int ecode4 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject * obj3 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"smime_write_pkcs7_multi",4,4,&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "smime_write_pkcs7_multi" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_PKCS7, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "smime_write_pkcs7_multi" "', argument " "2"" of type '" "PKCS7 *""'");
+ }
+ arg2 = (PKCS7 *)(argp2);
+ res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res3)) {
+ SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "smime_write_pkcs7_multi" "', argument " "3"" of type '" "BIO *""'");
+ }
+ arg3 = (BIO *)(argp3);
+ ecode4 = SWIG_AsVal_int(obj3, &val4);
+ if (!SWIG_IsOK(ecode4)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "smime_write_pkcs7_multi" "', argument " "4"" of type '" "int""'");
+ }
+ arg4 = (int)(val4);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg3) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ result = (int)smime_write_pkcs7_multi(arg1,arg2,arg3,arg4);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_smime_write_pkcs7(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ PKCS7 *arg2 = (PKCS7 *) 0 ;
+ int arg3 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ int val3 ;
+ int ecode3 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"smime_write_pkcs7",3,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "smime_write_pkcs7" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_PKCS7, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "smime_write_pkcs7" "', argument " "2"" of type '" "PKCS7 *""'");
+ }
+ arg2 = (PKCS7 *)(argp2);
+ ecode3 = SWIG_AsVal_int(obj2, &val3);
+ if (!SWIG_IsOK(ecode3)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "smime_write_pkcs7" "', argument " "3"" of type '" "int""'");
+ }
+ arg3 = (int)(val3);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ result = (int)smime_write_pkcs7(arg1,arg2,arg3);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_smime_read_pkcs7(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"smime_read_pkcs7",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "smime_read_pkcs7" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)smime_read_pkcs7(arg1);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_pkcs7_write_bio(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ PKCS7 *arg1 = (PKCS7 *) 0 ;
+ BIO *arg2 = (BIO *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"pkcs7_write_bio",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_PKCS7, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "pkcs7_write_bio" "', argument " "1"" of type '" "PKCS7 *""'");
+ }
+ arg1 = (PKCS7 *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "pkcs7_write_bio" "', argument " "2"" of type '" "BIO *""'");
+ }
+ arg2 = (BIO *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ result = (int)pkcs7_write_bio(arg1,arg2);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_pkcs7_write_bio_der(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ PKCS7 *arg1 = (PKCS7 *) 0 ;
+ BIO *arg2 = (BIO *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"pkcs7_write_bio_der",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_PKCS7, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "pkcs7_write_bio_der" "', argument " "1"" of type '" "PKCS7 *""'");
+ }
+ arg1 = (PKCS7 *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "pkcs7_write_bio_der" "', argument " "2"" of type '" "BIO *""'");
+ }
+ arg2 = (BIO *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ result = (int)pkcs7_write_bio_der(arg1,arg2);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_pkcs7_type_nid(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ PKCS7 *arg1 = (PKCS7 *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"pkcs7_type_nid",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_PKCS7, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "pkcs7_type_nid" "', argument " "1"" of type '" "PKCS7 *""'");
+ }
+ arg1 = (PKCS7 *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)pkcs7_type_nid(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_pkcs7_type_sn(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ PKCS7 *arg1 = (PKCS7 *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ char *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"pkcs7_type_sn",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_PKCS7, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "pkcs7_type_sn" "', argument " "1"" of type '" "PKCS7 *""'");
+ }
+ arg1 = (PKCS7 *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (char *)pkcs7_type_sn(arg1);
+ resultobj = SWIG_FromCharPtr((const char *)result);
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_smime_crlf_copy(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ BIO *arg2 = (BIO *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"smime_crlf_copy",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "smime_crlf_copy" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "smime_crlf_copy" "', argument " "2"" of type '" "BIO *""'");
+ }
+ arg2 = (BIO *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ result = (int)smime_crlf_copy(arg1,arg2);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_pkcs7_get0_signers(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ PKCS7 *arg1 = (PKCS7 *) 0 ;
+ struct stack_st_X509 *arg2 = (struct stack_st_X509 *) 0 ;
+ int arg3 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ int val3 ;
+ int ecode3 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ struct stack_st_X509 *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"pkcs7_get0_signers",3,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_PKCS7, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "pkcs7_get0_signers" "', argument " "1"" of type '" "PKCS7 *""'");
+ }
+ arg1 = (PKCS7 *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_stack_st_X509, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "pkcs7_get0_signers" "', argument " "2"" of type '" "struct stack_st_X509 *""'");
+ }
+ arg2 = (struct stack_st_X509 *)(argp2);
+ ecode3 = SWIG_AsVal_int(obj2, &val3);
+ if (!SWIG_IsOK(ecode3)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "pkcs7_get0_signers" "', argument " "3"" of type '" "int""'");
+ }
+ arg3 = (int)(val3);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (struct stack_st_X509 *)pkcs7_get0_signers(arg1,arg2,arg3);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_stack_st_X509, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN int Swig_var__util_err_set(PyObject *_val) {
+ {
+ void *argp = 0;
+ int res = SWIG_ConvertPtr(_val, &argp, SWIGTYPE_p_PyObject, 0 );
+ if (!SWIG_IsOK(res)) {
+ SWIG_exception_fail(SWIG_ArgError(res), "in variable '""_util_err""' of type '""PyObject *""'");
+ }
+ _util_err = (PyObject *)(argp);
+ }
+ return 0;
+fail:
+ return 1;
+}
+
+
+SWIGINTERN PyObject *Swig_var__util_err_get(void) {
+ PyObject *pyobj = 0;
+ PyObject *self = 0;
+
+ (void)self;
+ pyobj = SWIG_NewPointerObj(SWIG_as_voidptr(_util_err), SWIGTYPE_p_PyObject, 0 );
+ return pyobj;
+}
+
+
+SWIGINTERN PyObject *_wrap_util_init(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ PyObject *arg1 = (PyObject *) 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"util_init",1,1,&obj0)) SWIG_fail;
+ {
+ arg1=obj0;
+ }
+ util_init(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_util_hex_to_string(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ PyObject *arg1 = (PyObject *) 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"util_hex_to_string",1,1,&obj0)) SWIG_fail;
+ {
+ arg1=obj0;
+ }
+ result = (PyObject *)util_hex_to_string(arg1);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_util_string_to_hex(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ PyObject *arg1 = (PyObject *) 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"util_string_to_hex",1,1,&obj0)) SWIG_fail;
+ {
+ arg1=obj0;
+ }
+ result = (PyObject *)util_string_to_hex(arg1);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ec_key_new(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EC_KEY *result = 0 ;
+
+ result = (EC_KEY *)EC_KEY_new();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EC_KEY, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ec_key_free(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EC_KEY *arg1 = (EC_KEY *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ec_key_free",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_EC_KEY, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ec_key_free" "', argument " "1"" of type '" "EC_KEY *""'");
+ }
+ arg1 = (EC_KEY *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ EC_KEY_free(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ec_key_size(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EC_KEY *arg1 = (EC_KEY *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ec_key_size",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_EC_KEY, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ec_key_size" "', argument " "1"" of type '" "EC_KEY const *""'");
+ }
+ arg1 = (EC_KEY *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)ECDSA_size((EC_KEY const *)arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ec_key_gen_key(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EC_KEY *arg1 = (EC_KEY *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ec_key_gen_key",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_EC_KEY, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ec_key_gen_key" "', argument " "1"" of type '" "EC_KEY *""'");
+ }
+ arg1 = (EC_KEY *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)EC_KEY_generate_key(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ec_key_check_key(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EC_KEY *arg1 = (EC_KEY *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ec_key_check_key",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_EC_KEY, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ec_key_check_key" "', argument " "1"" of type '" "EC_KEY const *""'");
+ }
+ arg1 = (EC_KEY *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)EC_KEY_check_key((EC_KEY const *)arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN int Swig_var__ec_err_set(PyObject *_val) {
+ {
+ void *argp = 0;
+ int res = SWIG_ConvertPtr(_val, &argp, SWIGTYPE_p_PyObject, 0 );
+ if (!SWIG_IsOK(res)) {
+ SWIG_exception_fail(SWIG_ArgError(res), "in variable '""_ec_err""' of type '""PyObject *""'");
+ }
+ _ec_err = (PyObject *)(argp);
+ }
+ return 0;
+fail:
+ return 1;
+}
+
+
+SWIGINTERN PyObject *Swig_var__ec_err_get(void) {
+ PyObject *pyobj = 0;
+ PyObject *self = 0;
+
+ (void)self;
+ pyobj = SWIG_NewPointerObj(SWIG_as_voidptr(_ec_err), SWIGTYPE_p_PyObject, 0 );
+ return pyobj;
+}
+
+
+SWIGINTERN PyObject *_wrap_ec_init(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ PyObject *arg1 = (PyObject *) 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ec_init",1,1,&obj0)) SWIG_fail;
+ {
+ arg1=obj0;
+ }
+ ec_init(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ec_get_builtin_curves(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ PyObject *result = 0 ;
+
+ result = (PyObject *)ec_get_builtin_curves();
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ec_key_new_by_curve_name(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ int arg1 ;
+ int val1 ;
+ int ecode1 = 0 ;
+ PyObject * obj0 = 0 ;
+ EC_KEY *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ec_key_new_by_curve_name",1,1,&obj0)) SWIG_fail;
+ ecode1 = SWIG_AsVal_int(obj0, &val1);
+ if (!SWIG_IsOK(ecode1)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "ec_key_new_by_curve_name" "', argument " "1"" of type '" "int""'");
+ }
+ arg1 = (int)(val1);
+ result = (EC_KEY *)ec_key_new_by_curve_name(arg1);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EC_KEY, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ec_key_get_public_der(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EC_KEY *arg1 = (EC_KEY *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ec_key_get_public_der",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_EC_KEY, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ec_key_get_public_der" "', argument " "1"" of type '" "EC_KEY *""'");
+ }
+ arg1 = (EC_KEY *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)ec_key_get_public_der(arg1);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ec_key_get_public_key(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EC_KEY *arg1 = (EC_KEY *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ec_key_get_public_key",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_EC_KEY, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ec_key_get_public_key" "', argument " "1"" of type '" "EC_KEY *""'");
+ }
+ arg1 = (EC_KEY *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)ec_key_get_public_key(arg1);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ec_key_read_pubkey(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ EC_KEY *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ec_key_read_pubkey",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ec_key_read_pubkey" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ result = (EC_KEY *)ec_key_read_pubkey(arg1);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EC_KEY, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ec_key_write_pubkey(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EC_KEY *arg1 = (EC_KEY *) 0 ;
+ BIO *arg2 = (BIO *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ec_key_write_pubkey",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_EC_KEY, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ec_key_write_pubkey" "', argument " "1"" of type '" "EC_KEY *""'");
+ }
+ arg1 = (EC_KEY *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ec_key_write_pubkey" "', argument " "2"" of type '" "BIO *""'");
+ }
+ arg2 = (BIO *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ SWIG_PYTHON_THREAD_BEGIN_ALLOW;
+ result = (int)ec_key_write_pubkey(arg1,arg2);
+ SWIG_PYTHON_THREAD_END_ALLOW;
+ }
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ec_key_read_bio(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ BIO *arg1 = (BIO *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ EC_KEY *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ec_key_read_bio",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ec_key_read_bio" "', argument " "1"" of type '" "BIO *""'");
+ }
+ arg1 = (BIO *)(argp1);
+ {
+ if (!PyCallable_Check(obj1)) {
+ PyErr_SetString(PyExc_TypeError, "expected PyCallable");
+ return NULL;
+ }
+ arg2=obj1;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (EC_KEY *)ec_key_read_bio(arg1,arg2);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EC_KEY, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ec_key_write_bio(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EC_KEY *arg1 = (EC_KEY *) 0 ;
+ BIO *arg2 = (BIO *) 0 ;
+ EVP_CIPHER *arg3 = (EVP_CIPHER *) 0 ;
+ PyObject *arg4 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ void *argp3 = 0 ;
+ int res3 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject * obj3 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ec_key_write_bio",4,4,&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_EC_KEY, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ec_key_write_bio" "', argument " "1"" of type '" "EC_KEY *""'");
+ }
+ arg1 = (EC_KEY *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ec_key_write_bio" "', argument " "2"" of type '" "BIO *""'");
+ }
+ arg2 = (BIO *)(argp2);
+ res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_EVP_CIPHER, 0 | 0 );
+ if (!SWIG_IsOK(res3)) {
+ SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "ec_key_write_bio" "', argument " "3"" of type '" "EVP_CIPHER *""'");
+ }
+ arg3 = (EVP_CIPHER *)(argp3);
+ {
+ if (!PyCallable_Check(obj3)) {
+ PyErr_SetString(PyExc_TypeError, "expected PyCallable");
+ return NULL;
+ }
+ arg4=obj3;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg3) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg4) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)ec_key_write_bio(arg1,arg2,arg3,arg4);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ec_key_write_bio_no_cipher(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EC_KEY *arg1 = (EC_KEY *) 0 ;
+ BIO *arg2 = (BIO *) 0 ;
+ PyObject *arg3 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ec_key_write_bio_no_cipher",3,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_EC_KEY, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ec_key_write_bio_no_cipher" "', argument " "1"" of type '" "EC_KEY *""'");
+ }
+ arg1 = (EC_KEY *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_BIO, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ec_key_write_bio_no_cipher" "', argument " "2"" of type '" "BIO *""'");
+ }
+ arg2 = (BIO *)(argp2);
+ {
+ if (!PyCallable_Check(obj2)) {
+ PyErr_SetString(PyExc_TypeError, "expected PyCallable");
+ return NULL;
+ }
+ arg3=obj2;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg3) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)ec_key_write_bio_no_cipher(arg1,arg2,arg3);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ecdsa_sig_get_r(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ ECDSA_SIG *arg1 = (ECDSA_SIG *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ecdsa_sig_get_r",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ECDSA_SIG, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ecdsa_sig_get_r" "', argument " "1"" of type '" "ECDSA_SIG *""'");
+ }
+ arg1 = (ECDSA_SIG *)(argp1);
+ result = (PyObject *)ecdsa_sig_get_r(arg1);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ecdsa_sig_get_s(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ ECDSA_SIG *arg1 = (ECDSA_SIG *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ecdsa_sig_get_s",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ECDSA_SIG, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ecdsa_sig_get_s" "', argument " "1"" of type '" "ECDSA_SIG *""'");
+ }
+ arg1 = (ECDSA_SIG *)(argp1);
+ result = (PyObject *)ecdsa_sig_get_s(arg1);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ecdsa_sign(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EC_KEY *arg1 = (EC_KEY *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ecdsa_sign",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_EC_KEY, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ecdsa_sign" "', argument " "1"" of type '" "EC_KEY *""'");
+ }
+ arg1 = (EC_KEY *)(argp1);
+ {
+ arg2=obj1;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)ecdsa_sign(arg1,arg2);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ecdsa_verify(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EC_KEY *arg1 = (EC_KEY *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ PyObject *arg3 = (PyObject *) 0 ;
+ PyObject *arg4 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject * obj3 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ecdsa_verify",4,4,&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_EC_KEY, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ecdsa_verify" "', argument " "1"" of type '" "EC_KEY *""'");
+ }
+ arg1 = (EC_KEY *)(argp1);
+ {
+ arg2=obj1;
+ }
+ {
+ arg3=obj2;
+ }
+ {
+ arg4=obj3;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)ecdsa_verify(arg1,arg2,arg3,arg4);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ecdsa_sign_asn1(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EC_KEY *arg1 = (EC_KEY *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ecdsa_sign_asn1",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_EC_KEY, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ecdsa_sign_asn1" "', argument " "1"" of type '" "EC_KEY *""'");
+ }
+ arg1 = (EC_KEY *)(argp1);
+ {
+ arg2=obj1;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)ecdsa_sign_asn1(arg1,arg2);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ecdsa_verify_asn1(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EC_KEY *arg1 = (EC_KEY *) 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ PyObject *arg3 = (PyObject *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ecdsa_verify_asn1",3,3,&obj0,&obj1,&obj2)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_EC_KEY, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ecdsa_verify_asn1" "', argument " "1"" of type '" "EC_KEY *""'");
+ }
+ arg1 = (EC_KEY *)(argp1);
+ {
+ arg2=obj1;
+ }
+ {
+ arg3=obj2;
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)ecdsa_verify_asn1(arg1,arg2,arg3);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ecdh_compute_key(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EC_KEY *arg1 = (EC_KEY *) 0 ;
+ EC_KEY *arg2 = (EC_KEY *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ecdh_compute_key",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_EC_KEY, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ecdh_compute_key" "', argument " "1"" of type '" "EC_KEY *""'");
+ }
+ arg1 = (EC_KEY *)(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_EC_KEY, 0 | 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ecdh_compute_key" "', argument " "2"" of type '" "EC_KEY *""'");
+ }
+ arg2 = (EC_KEY *)(argp2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)ecdh_compute_key(arg1,arg2);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ec_key_from_pubkey_der(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ PyObject *arg1 = (PyObject *) 0 ;
+ PyObject * obj0 = 0 ;
+ EC_KEY *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ec_key_from_pubkey_der",1,1,&obj0)) SWIG_fail;
+ {
+ arg1=obj0;
+ }
+ result = (EC_KEY *)ec_key_from_pubkey_der(arg1);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EC_KEY, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ec_key_from_pubkey_params(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ int arg1 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ int val1 ;
+ int ecode1 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ EC_KEY *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ec_key_from_pubkey_params",2,2,&obj0,&obj1)) SWIG_fail;
+ ecode1 = SWIG_AsVal_int(obj0, &val1);
+ if (!SWIG_IsOK(ecode1)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "ec_key_from_pubkey_params" "', argument " "1"" of type '" "int""'");
+ }
+ arg1 = (int)(val1);
+ {
+ arg2=obj1;
+ }
+ result = (EC_KEY *)ec_key_from_pubkey_params(arg1,arg2);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EC_KEY, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ec_key_keylen(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EC_KEY *arg1 = (EC_KEY *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ec_key_keylen",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_EC_KEY, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ec_key_keylen" "', argument " "1"" of type '" "EC_KEY *""'");
+ }
+ arg1 = (EC_KEY *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)ec_key_keylen(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ec_key_type_check(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ EC_KEY *arg1 = (EC_KEY *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"ec_key_type_check",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_EC_KEY, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ec_key_type_check" "', argument " "1"" of type '" "EC_KEY *""'");
+ }
+ arg1 = (EC_KEY *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)ec_key_type_check(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_engine_load_builtin_engines(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+
+ ENGINE_load_builtin_engines();
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_engine_load_dynamic(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+
+ ENGINE_load_dynamic();
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_engine_load_openssl(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+
+ ENGINE_load_openssl();
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_engine_cleanup(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+
+ ENGINE_cleanup();
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_engine_new(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ ENGINE *result = 0 ;
+
+ result = (ENGINE *)ENGINE_new();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ENGINE, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_engine_by_id(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ char *arg1 = (char *) 0 ;
+ int res1 ;
+ char *buf1 = 0 ;
+ int alloc1 = 0 ;
+ PyObject * obj0 = 0 ;
+ ENGINE *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"engine_by_id",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "engine_by_id" "', argument " "1"" of type '" "char const *""'");
+ }
+ arg1 = (char *)(buf1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (ENGINE *)ENGINE_by_id((char const *)arg1);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ENGINE, 0 | 0 );
+ if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
+ return resultobj;
+fail:
+ if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_engine_free(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ ENGINE *arg1 = (ENGINE *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"engine_free",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ENGINE, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "engine_free" "', argument " "1"" of type '" "ENGINE *""'");
+ }
+ arg1 = (ENGINE *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)ENGINE_free(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_engine_init(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ ENGINE *arg1 = (ENGINE *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"engine_init",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ENGINE, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "engine_init" "', argument " "1"" of type '" "ENGINE *""'");
+ }
+ arg1 = (ENGINE *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)ENGINE_init(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_engine_finish(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ ENGINE *arg1 = (ENGINE *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"engine_finish",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ENGINE, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "engine_finish" "', argument " "1"" of type '" "ENGINE *""'");
+ }
+ arg1 = (ENGINE *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)ENGINE_finish(arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_engine_get_id(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ ENGINE *arg1 = (ENGINE *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ char *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"engine_get_id",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ENGINE, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "engine_get_id" "', argument " "1"" of type '" "ENGINE const *""'");
+ }
+ arg1 = (ENGINE *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (char *)ENGINE_get_id((ENGINE const *)arg1);
+ resultobj = SWIG_FromCharPtr((const char *)result);
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_engine_get_name(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ ENGINE *arg1 = (ENGINE *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ char *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"engine_get_name",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ENGINE, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "engine_get_name" "', argument " "1"" of type '" "ENGINE const *""'");
+ }
+ arg1 = (ENGINE *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (char *)ENGINE_get_name((ENGINE const *)arg1);
+ resultobj = SWIG_FromCharPtr((const char *)result);
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_engine_ctrl_cmd_string(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ ENGINE *arg1 = (ENGINE *) 0 ;
+ char *arg2 = (char *) 0 ;
+ char *arg3 = (char *) 0 ;
+ int arg4 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ int alloc2 = 0 ;
+ int res3 ;
+ char *buf3 = 0 ;
+ int alloc3 = 0 ;
+ int val4 ;
+ int ecode4 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject * obj3 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"engine_ctrl_cmd_string",4,4,&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ENGINE, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "engine_ctrl_cmd_string" "', argument " "1"" of type '" "ENGINE *""'");
+ }
+ arg1 = (ENGINE *)(argp1);
+ res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "engine_ctrl_cmd_string" "', argument " "2"" of type '" "char const *""'");
+ }
+ arg2 = (char *)(buf2);
+ res3 = SWIG_AsCharPtrAndSize(obj2, &buf3, NULL, &alloc3);
+ if (!SWIG_IsOK(res3)) {
+ SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "engine_ctrl_cmd_string" "', argument " "3"" of type '" "char const *""'");
+ }
+ arg3 = (char *)(buf3);
+ ecode4 = SWIG_AsVal_int(obj3, &val4);
+ if (!SWIG_IsOK(ecode4)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "engine_ctrl_cmd_string" "', argument " "4"" of type '" "int""'");
+ }
+ arg4 = (int)(val4);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)ENGINE_ctrl_cmd_string(arg1,(char const *)arg2,(char const *)arg3,arg4);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ if (alloc3 == SWIG_NEWOBJ) free((char*)buf3);
+ return resultobj;
+fail:
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ if (alloc3 == SWIG_NEWOBJ) free((char*)buf3);
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ui_openssl(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ UI_METHOD *result = 0 ;
+
+ result = (UI_METHOD *)UI_OpenSSL();
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_UI_METHOD, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap__cbd_t_password_set(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ _cbd_t *arg1 = (_cbd_t *) 0 ;
+ char *arg2 = (char *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ int alloc2 = 0 ;
+ PyObject * obj1 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"_cbd_t_password_set",1,1,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p__cbd_t, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "_cbd_t_password_set" "', argument " "1"" of type '" "_cbd_t *""'");
+ }
+ arg1 = (_cbd_t *)(argp1);
+ res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "_cbd_t_password_set" "', argument " "2"" of type '" "char *""'");
+ }
+ arg2 = (char *)(buf2);
+ if (arg1->password) free((char*)arg1->password);
+ if (arg2) {
+ size_t size = strlen((const char *)(arg2)) + 1;
+ arg1->password = (char *)(char *)memcpy((char *)malloc((size)*sizeof(char)), (const char *)(arg2), sizeof(char)*(size));
+ } else {
+ arg1->password = 0;
+ }
+ resultobj = SWIG_Py_Void();
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return resultobj;
+fail:
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap__cbd_t_password_get(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ _cbd_t *arg1 = (_cbd_t *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ char *result = 0 ;
+
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p__cbd_t, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "_cbd_t_password_get" "', argument " "1"" of type '" "_cbd_t *""'");
+ }
+ arg1 = (_cbd_t *)(argp1);
+ result = (char *) ((arg1)->password);
+ resultobj = SWIG_FromCharPtr((const char *)result);
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap__cbd_t_prompt_set(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ _cbd_t *arg1 = (_cbd_t *) 0 ;
+ char *arg2 = (char *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ int alloc2 = 0 ;
+ PyObject * obj1 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"_cbd_t_prompt_set",1,1,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p__cbd_t, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "_cbd_t_prompt_set" "', argument " "1"" of type '" "_cbd_t *""'");
+ }
+ arg1 = (_cbd_t *)(argp1);
+ res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "_cbd_t_prompt_set" "', argument " "2"" of type '" "char *""'");
+ }
+ arg2 = (char *)(buf2);
+ if (arg1->prompt) free((char*)arg1->prompt);
+ if (arg2) {
+ size_t size = strlen((const char *)(arg2)) + 1;
+ arg1->prompt = (char *)(char *)memcpy((char *)malloc((size)*sizeof(char)), (const char *)(arg2), sizeof(char)*(size));
+ } else {
+ arg1->prompt = 0;
+ }
+ resultobj = SWIG_Py_Void();
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return resultobj;
+fail:
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap__cbd_t_prompt_get(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ _cbd_t *arg1 = (_cbd_t *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ char *result = 0 ;
+
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p__cbd_t, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "_cbd_t_prompt_get" "', argument " "1"" of type '" "_cbd_t *""'");
+ }
+ arg1 = (_cbd_t *)(argp1);
+ result = (char *) ((arg1)->prompt);
+ resultobj = SWIG_FromCharPtr((const char *)result);
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN int _wrap_new__cbd_t(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ _cbd_t *result = 0 ;
+
+ result = (_cbd_t *)calloc(1, sizeof(_cbd_t));
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p__cbd_t, SWIG_BUILTIN_INIT | 0 );
+ return resultobj == Py_None ? -1 : 0;
+fail:
+ return -1;
+}
+
+
+SWIGINTERN PyObject *_wrap_delete__cbd_t(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ _cbd_t *arg1 = (_cbd_t *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p__cbd_t, SWIG_POINTER_DISOWN | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete__cbd_t" "', argument " "1"" of type '" "_cbd_t *""'");
+ }
+ arg1 = (_cbd_t *)(argp1);
+ free((char *) arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_engine_pkcs11_data_new(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ char *arg1 = (char *) 0 ;
+ int res1 ;
+ char *buf1 = 0 ;
+ int alloc1 = 0 ;
+ PyObject * obj0 = 0 ;
+ void *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"engine_pkcs11_data_new",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "engine_pkcs11_data_new" "', argument " "1"" of type '" "char const *""'");
+ }
+ arg1 = (char *)(buf1);
+ result = (void *)engine_pkcs11_data_new((char const *)arg1);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_void, 0 | 0 );
+ if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
+ return resultobj;
+fail:
+ if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_engine_pkcs11_data_free(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ void *arg1 = (void *) 0 ;
+ int res1 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"engine_pkcs11_data_free",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0,SWIG_as_voidptrptr(&arg1), 0, 0);
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "engine_pkcs11_data_free" "', argument " "1"" of type '" "void *""'");
+ }
+ engine_pkcs11_data_free(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_engine_load_private_key(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ ENGINE *arg1 = (ENGINE *) 0 ;
+ char *arg2 = (char *) 0 ;
+ UI_METHOD *arg3 = (UI_METHOD *) 0 ;
+ void *arg4 = (void *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ int alloc2 = 0 ;
+ void *argp3 = 0 ;
+ int res3 = 0 ;
+ int res4 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject * obj3 = 0 ;
+ EVP_PKEY *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"engine_load_private_key",4,4,&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ENGINE, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "engine_load_private_key" "', argument " "1"" of type '" "ENGINE *""'");
+ }
+ arg1 = (ENGINE *)(argp1);
+ res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "engine_load_private_key" "', argument " "2"" of type '" "char const *""'");
+ }
+ arg2 = (char *)(buf2);
+ res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_UI_METHOD, 0 | 0 );
+ if (!SWIG_IsOK(res3)) {
+ SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "engine_load_private_key" "', argument " "3"" of type '" "UI_METHOD *""'");
+ }
+ arg3 = (UI_METHOD *)(argp3);
+ res4 = SWIG_ConvertPtr(obj3,SWIG_as_voidptrptr(&arg4), 0, 0);
+ if (!SWIG_IsOK(res4)) {
+ SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "engine_load_private_key" "', argument " "4"" of type '" "void *""'");
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (EVP_PKEY *)ENGINE_load_private_key(arg1,(char const *)arg2,arg3,arg4);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_PKEY, 0 | 0 );
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return resultobj;
+fail:
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_engine_load_public_key(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ ENGINE *arg1 = (ENGINE *) 0 ;
+ char *arg2 = (char *) 0 ;
+ UI_METHOD *arg3 = (UI_METHOD *) 0 ;
+ void *arg4 = (void *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ int alloc2 = 0 ;
+ void *argp3 = 0 ;
+ int res3 = 0 ;
+ int res4 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject * obj3 = 0 ;
+ EVP_PKEY *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"engine_load_public_key",4,4,&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ENGINE, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "engine_load_public_key" "', argument " "1"" of type '" "ENGINE *""'");
+ }
+ arg1 = (ENGINE *)(argp1);
+ res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "engine_load_public_key" "', argument " "2"" of type '" "char const *""'");
+ }
+ arg2 = (char *)(buf2);
+ res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_UI_METHOD, 0 | 0 );
+ if (!SWIG_IsOK(res3)) {
+ SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "engine_load_public_key" "', argument " "3"" of type '" "UI_METHOD *""'");
+ }
+ arg3 = (UI_METHOD *)(argp3);
+ res4 = SWIG_ConvertPtr(obj3,SWIG_as_voidptrptr(&arg4), 0, 0);
+ if (!SWIG_IsOK(res4)) {
+ SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "engine_load_public_key" "', argument " "4"" of type '" "void *""'");
+ }
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (EVP_PKEY *)ENGINE_load_public_key(arg1,(char const *)arg2,arg3,arg4);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EVP_PKEY, 0 | 0 );
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return resultobj;
+fail:
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return NULL;
+}
+
+
+SWIGINTERN int Swig_var__engine_err_set(PyObject *_val) {
+ {
+ void *argp = 0;
+ int res = SWIG_ConvertPtr(_val, &argp, SWIGTYPE_p_PyObject, 0 );
+ if (!SWIG_IsOK(res)) {
+ SWIG_exception_fail(SWIG_ArgError(res), "in variable '""_engine_err""' of type '""PyObject *""'");
+ }
+ _engine_err = (PyObject *)(argp);
+ }
+ return 0;
+fail:
+ return 1;
+}
+
+
+SWIGINTERN PyObject *Swig_var__engine_err_get(void) {
+ PyObject *pyobj = 0;
+ PyObject *self = 0;
+
+ (void)self;
+ pyobj = SWIG_NewPointerObj(SWIG_as_voidptr(_engine_err), SWIGTYPE_p_PyObject, 0 );
+ return pyobj;
+}
+
+
+SWIGINTERN PyObject *_wrap_engine_init_error(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ PyObject *arg1 = (PyObject *) 0 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"engine_init_error",1,1,&obj0)) SWIG_fail;
+ {
+ arg1=obj0;
+ }
+ engine_init_error(arg1);
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_engine_load_certificate(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ ENGINE *arg1 = (ENGINE *) 0 ;
+ char *arg2 = (char *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ int alloc2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ X509 *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"engine_load_certificate",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ENGINE, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "engine_load_certificate" "', argument " "1"" of type '" "ENGINE *""'");
+ }
+ arg1 = (ENGINE *)(argp1);
+ res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "engine_load_certificate" "', argument " "2"" of type '" "char const *""'");
+ }
+ arg2 = (char *)(buf2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ {
+ if (!arg2) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (X509 *)engine_load_certificate(arg1,(char const *)arg2);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_X509, 0 | 0 );
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return resultobj;
+fail:
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_engine_set_default(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ ENGINE *arg1 = (ENGINE *) 0 ;
+ unsigned int arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ unsigned int val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"engine_set_default",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ENGINE, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "engine_set_default" "', argument " "1"" of type '" "ENGINE *""'");
+ }
+ arg1 = (ENGINE *)(argp1);
+ ecode2 = SWIG_AsVal_unsigned_SS_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "engine_set_default" "', argument " "2"" of type '" "unsigned int""'");
+ }
+ arg2 = (unsigned int)(val2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)ENGINE_set_default(arg1,arg2);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_obj_nid2obj(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ int arg1 ;
+ int val1 ;
+ int ecode1 = 0 ;
+ PyObject * obj0 = 0 ;
+ ASN1_OBJECT *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"obj_nid2obj",1,1,&obj0)) SWIG_fail;
+ ecode1 = SWIG_AsVal_int(obj0, &val1);
+ if (!SWIG_IsOK(ecode1)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "obj_nid2obj" "', argument " "1"" of type '" "int""'");
+ }
+ arg1 = (int)(val1);
+ result = (ASN1_OBJECT *)OBJ_nid2obj(arg1);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ASN1_OBJECT, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_obj_nid2ln(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ int arg1 ;
+ int val1 ;
+ int ecode1 = 0 ;
+ PyObject * obj0 = 0 ;
+ char *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"obj_nid2ln",1,1,&obj0)) SWIG_fail;
+ ecode1 = SWIG_AsVal_int(obj0, &val1);
+ if (!SWIG_IsOK(ecode1)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "obj_nid2ln" "', argument " "1"" of type '" "int""'");
+ }
+ arg1 = (int)(val1);
+ result = (char *)OBJ_nid2ln(arg1);
+ resultobj = SWIG_FromCharPtr((const char *)result);
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_obj_nid2sn(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ int arg1 ;
+ int val1 ;
+ int ecode1 = 0 ;
+ PyObject * obj0 = 0 ;
+ char *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"obj_nid2sn",1,1,&obj0)) SWIG_fail;
+ ecode1 = SWIG_AsVal_int(obj0, &val1);
+ if (!SWIG_IsOK(ecode1)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "obj_nid2sn" "', argument " "1"" of type '" "int""'");
+ }
+ arg1 = (int)(val1);
+ result = (char *)OBJ_nid2sn(arg1);
+ resultobj = SWIG_FromCharPtr((const char *)result);
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_obj_obj2nid(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ ASN1_OBJECT *arg1 = (ASN1_OBJECT *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"obj_obj2nid",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ASN1_OBJECT, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "obj_obj2nid" "', argument " "1"" of type '" "ASN1_OBJECT const *""'");
+ }
+ arg1 = (ASN1_OBJECT *)(argp1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)OBJ_obj2nid((ASN1_OBJECT const *)arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_obj_ln2nid(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ char *arg1 = (char *) 0 ;
+ int res1 ;
+ char *buf1 = 0 ;
+ int alloc1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"obj_ln2nid",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "obj_ln2nid" "', argument " "1"" of type '" "char const *""'");
+ }
+ arg1 = (char *)(buf1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)OBJ_ln2nid((char const *)arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
+ return resultobj;
+fail:
+ if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_obj_sn2nid(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ char *arg1 = (char *) 0 ;
+ int res1 ;
+ char *buf1 = 0 ;
+ int alloc1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"obj_sn2nid",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "obj_sn2nid" "', argument " "1"" of type '" "char const *""'");
+ }
+ arg1 = (char *)(buf1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)OBJ_sn2nid((char const *)arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
+ return resultobj;
+fail:
+ if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_obj_txt2nid(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ char *arg1 = (char *) 0 ;
+ int res1 ;
+ char *buf1 = 0 ;
+ int alloc1 = 0 ;
+ PyObject * obj0 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"obj_txt2nid",1,1,&obj0)) SWIG_fail;
+ res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "obj_txt2nid" "', argument " "1"" of type '" "char const *""'");
+ }
+ arg1 = (char *)(buf1);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)OBJ_txt2nid((char const *)arg1);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
+ return resultobj;
+fail:
+ if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_obj_txt2obj(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ char *arg1 = (char *) 0 ;
+ int arg2 ;
+ int res1 ;
+ char *buf1 = 0 ;
+ int alloc1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ ASN1_OBJECT *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"obj_txt2obj",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "obj_txt2obj" "', argument " "1"" of type '" "char const *""'");
+ }
+ arg1 = (char *)(buf1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "obj_txt2obj" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (ASN1_OBJECT *)OBJ_txt2obj((char const *)arg1,arg2);
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ASN1_OBJECT, 0 | 0 );
+ if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
+ return resultobj;
+fail:
+ if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap__obj_obj2txt(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ char *arg1 = (char *) 0 ;
+ int arg2 ;
+ ASN1_OBJECT *arg3 = (ASN1_OBJECT *) 0 ;
+ int arg4 ;
+ int res1 ;
+ char *buf1 = 0 ;
+ int alloc1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ void *argp3 = 0 ;
+ int res3 = 0 ;
+ int val4 ;
+ int ecode4 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject * obj3 = 0 ;
+ int result;
+
+ if(!PyArg_UnpackTuple(args,(char *)"_obj_obj2txt",4,4,&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
+ res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "_obj_obj2txt" "', argument " "1"" of type '" "char *""'");
+ }
+ arg1 = (char *)(buf1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "_obj_obj2txt" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_ASN1_OBJECT, 0 | 0 );
+ if (!SWIG_IsOK(res3)) {
+ SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "_obj_obj2txt" "', argument " "3"" of type '" "ASN1_OBJECT const *""'");
+ }
+ arg3 = (ASN1_OBJECT *)(argp3);
+ ecode4 = SWIG_AsVal_int(obj3, &val4);
+ if (!SWIG_IsOK(ecode4)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "_obj_obj2txt" "', argument " "4"" of type '" "int""'");
+ }
+ arg4 = (int)(val4);
+ {
+ if (!arg3) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (int)OBJ_obj2txt(arg1,arg2,(ASN1_OBJECT const *)arg3,arg4);
+ {
+ resultobj=PyLong_FromLong(result);
+ if (PyErr_Occurred()) SWIG_fail;
+ }
+ if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
+ return resultobj;
+fail:
+ if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_obj_obj2txt(PyObject *self, PyObject *args) {
+ PyObject *resultobj = 0;
+ ASN1_OBJECT *arg1 = (ASN1_OBJECT *) 0 ;
+ int arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject *result = 0 ;
+
+ if(!PyArg_UnpackTuple(args,(char *)"obj_obj2txt",2,2,&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ASN1_OBJECT, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "obj_obj2txt" "', argument " "1"" of type '" "ASN1_OBJECT const *""'");
+ }
+ arg1 = (ASN1_OBJECT *)(argp1);
+ ecode2 = SWIG_AsVal_int(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "obj_obj2txt" "', argument " "2"" of type '" "int""'");
+ }
+ arg2 = (int)(val2);
+ {
+ if (!arg1) {
+ SWIG_exception(SWIG_ValueError,"Received a NULL pointer.");
+ }
+ }
+ result = (PyObject *)obj_obj2txt((ASN1_OBJECT const *)arg1,arg2);
+ {
+ resultobj=result;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+static PyMethodDef SwigMethods[] = {
+ { (char *)"SWIG_PyInstanceMethod_New", (PyCFunction)SWIG_PyInstanceMethod_New, METH_O, NULL},
+ { (char *)"sk_num", _wrap_sk_num, METH_VARARGS, NULL},
+ { (char *)"sk_value", _wrap_sk_value, METH_VARARGS, NULL},
+ { (char *)"sk_set", _wrap_sk_set, METH_VARARGS, NULL},
+ { (char *)"sk_new", _wrap_sk_new, METH_VARARGS, NULL},
+ { (char *)"sk_new_null", _wrap_sk_new_null, METH_VARARGS, NULL},
+ { (char *)"sk_free", _wrap_sk_free, METH_VARARGS, NULL},
+ { (char *)"sk_pop_free", _wrap_sk_pop_free, METH_VARARGS, NULL},
+ { (char *)"sk_deep_copy", _wrap_sk_deep_copy, METH_VARARGS, NULL},
+ { (char *)"sk_insert", _wrap_sk_insert, METH_VARARGS, NULL},
+ { (char *)"sk_delete", _wrap_sk_delete, METH_VARARGS, NULL},
+ { (char *)"sk_delete_ptr", _wrap_sk_delete_ptr, METH_VARARGS, NULL},
+ { (char *)"sk_find", _wrap_sk_find, METH_VARARGS, NULL},
+ { (char *)"sk_find_ex", _wrap_sk_find_ex, METH_VARARGS, NULL},
+ { (char *)"sk_push", _wrap_sk_push, METH_VARARGS, NULL},
+ { (char *)"sk_unshift", _wrap_sk_unshift, METH_VARARGS, NULL},
+ { (char *)"sk_shift", _wrap_sk_shift, METH_VARARGS, NULL},
+ { (char *)"sk_pop", _wrap_sk_pop, METH_VARARGS, NULL},
+ { (char *)"sk_zero", _wrap_sk_zero, METH_VARARGS, NULL},
+ { (char *)"sk_set_cmp_func", _wrap_sk_set_cmp_func, METH_VARARGS, NULL},
+ { (char *)"sk_dup", _wrap_sk_dup, METH_VARARGS, NULL},
+ { (char *)"sk_sort", _wrap_sk_sort, METH_VARARGS, NULL},
+ { (char *)"sk_is_sorted", _wrap_sk_is_sorted, METH_VARARGS, NULL},
+ { (char *)"threading_init", _wrap_threading_init, METH_VARARGS, NULL},
+ { (char *)"threading_cleanup", _wrap_threading_cleanup, METH_VARARGS, NULL},
+ { (char *)"lib_init", _wrap_lib_init, METH_VARARGS, NULL},
+ { (char *)"bn_to_mpi", _wrap_bn_to_mpi, METH_VARARGS, NULL},
+ { (char *)"mpi_to_bn", _wrap_mpi_to_bn, METH_VARARGS, NULL},
+ { (char *)"bn_to_bin", _wrap_bn_to_bin, METH_VARARGS, NULL},
+ { (char *)"bin_to_bn", _wrap_bin_to_bn, METH_VARARGS, NULL},
+ { (char *)"bn_to_hex", _wrap_bn_to_hex, METH_VARARGS, NULL},
+ { (char *)"hex_to_bn", _wrap_hex_to_bn, METH_VARARGS, NULL},
+ { (char *)"dec_to_bn", _wrap_dec_to_bn, METH_VARARGS, NULL},
+ { (char *)"err_print_errors", _wrap_err_print_errors, METH_VARARGS, NULL},
+ { (char *)"err_get_error", _wrap_err_get_error, METH_VARARGS, NULL},
+ { (char *)"err_peek_error", _wrap_err_peek_error, METH_VARARGS, NULL},
+ { (char *)"err_lib_error_string", _wrap_err_lib_error_string, METH_VARARGS, NULL},
+ { (char *)"err_func_error_string", _wrap_err_func_error_string, METH_VARARGS, NULL},
+ { (char *)"err_reason_error_string", _wrap_err_reason_error_string, METH_VARARGS, NULL},
+ { (char *)"bio_s_bio", _wrap_bio_s_bio, METH_VARARGS, NULL},
+ { (char *)"bio_s_mem", _wrap_bio_s_mem, METH_VARARGS, NULL},
+ { (char *)"bio_s_socket", _wrap_bio_s_socket, METH_VARARGS, NULL},
+ { (char *)"bio_f_ssl", _wrap_bio_f_ssl, METH_VARARGS, NULL},
+ { (char *)"bio_f_buffer", _wrap_bio_f_buffer, METH_VARARGS, NULL},
+ { (char *)"bio_f_cipher", _wrap_bio_f_cipher, METH_VARARGS, NULL},
+ { (char *)"bio_new", _wrap_bio_new, METH_VARARGS, NULL},
+ { (char *)"bio_new_socket", _wrap_bio_new_socket, METH_VARARGS, NULL},
+ { (char *)"bio_free_all", _wrap_bio_free_all, METH_VARARGS, NULL},
+ { (char *)"bio_dup_chain", _wrap_bio_dup_chain, METH_VARARGS, NULL},
+ { (char *)"bio_push", _wrap_bio_push, METH_VARARGS, NULL},
+ { (char *)"bio_pop", _wrap_bio_pop, METH_VARARGS, NULL},
+ { (char *)"bio_eof", _wrap_bio_eof, METH_VARARGS, NULL},
+ { (char *)"pyfd_init", _wrap_pyfd_init, METH_VARARGS, NULL},
+ { (char *)"bio_init", _wrap_bio_init, METH_VARARGS, NULL},
+ { (char *)"bio_free", _wrap_bio_free, METH_VARARGS, NULL},
+ { (char *)"bio_new_file", _wrap_bio_new_file, METH_VARARGS, NULL},
+ { (char *)"bio_new_pyfile", _wrap_bio_new_pyfile, METH_VARARGS, NULL},
+ { (char *)"bio_read", _wrap_bio_read, METH_VARARGS, NULL},
+ { (char *)"bio_gets", _wrap_bio_gets, METH_VARARGS, NULL},
+ { (char *)"bio_write", _wrap_bio_write, METH_VARARGS, NULL},
+ { (char *)"bio_ctrl_pending", _wrap_bio_ctrl_pending, METH_VARARGS, NULL},
+ { (char *)"bio_ctrl_wpending", _wrap_bio_ctrl_wpending, METH_VARARGS, NULL},
+ { (char *)"bio_ctrl_get_write_guarantee", _wrap_bio_ctrl_get_write_guarantee, METH_VARARGS, NULL},
+ { (char *)"bio_reset", _wrap_bio_reset, METH_VARARGS, NULL},
+ { (char *)"bio_flush", _wrap_bio_flush, METH_VARARGS, NULL},
+ { (char *)"bio_seek", _wrap_bio_seek, METH_VARARGS, NULL},
+ { (char *)"bio_tell", _wrap_bio_tell, METH_VARARGS, NULL},
+ { (char *)"bio_set_flags", _wrap_bio_set_flags, METH_VARARGS, NULL},
+ { (char *)"bio_get_flags", _wrap_bio_get_flags, METH_VARARGS, NULL},
+ { (char *)"bio_set_cipher", _wrap_bio_set_cipher, METH_VARARGS, NULL},
+ { (char *)"bio_set_mem_eof_return", _wrap_bio_set_mem_eof_return, METH_VARARGS, NULL},
+ { (char *)"bio_get_fd", _wrap_bio_get_fd, METH_VARARGS, NULL},
+ { (char *)"bio_do_handshake", _wrap_bio_do_handshake, METH_VARARGS, NULL},
+ { (char *)"bio_make_bio_pair", _wrap_bio_make_bio_pair, METH_VARARGS, NULL},
+ { (char *)"bio_set_write_buf_size", _wrap_bio_set_write_buf_size, METH_VARARGS, NULL},
+ { (char *)"bio_should_retry", _wrap_bio_should_retry, METH_VARARGS, NULL},
+ { (char *)"bio_should_read", _wrap_bio_should_read, METH_VARARGS, NULL},
+ { (char *)"bio_should_write", _wrap_bio_should_write, METH_VARARGS, NULL},
+ { (char *)"BIO_meth_new", _wrap_BIO_meth_new, METH_VARARGS, NULL},
+ { (char *)"BIO_meth_free", _wrap_BIO_meth_free, METH_VARARGS, NULL},
+ { (char *)"pyfd_write", _wrap_pyfd_write, METH_VARARGS, NULL},
+ { (char *)"pyfd_read", _wrap_pyfd_read, METH_VARARGS, NULL},
+ { (char *)"pyfd_puts", _wrap_pyfd_puts, METH_VARARGS, NULL},
+ { (char *)"pyfd_gets", _wrap_pyfd_gets, METH_VARARGS, NULL},
+ { (char *)"pyfd_new", _wrap_pyfd_new, METH_VARARGS, NULL},
+ { (char *)"pyfd_free", _wrap_pyfd_free, METH_VARARGS, NULL},
+ { (char *)"pyfd_ctrl", _wrap_pyfd_ctrl, METH_VARARGS, NULL},
+ { (char *)"bio_new_pyfd", _wrap_bio_new_pyfd, METH_VARARGS, NULL},
+ { (char *)"bn_rand", _wrap_bn_rand, METH_VARARGS, NULL},
+ { (char *)"bn_rand_range", _wrap_bn_rand_range, METH_VARARGS, NULL},
+ { (char *)"rand_load_file", _wrap_rand_load_file, METH_VARARGS, NULL},
+ { (char *)"rand_save_file", _wrap_rand_save_file, METH_VARARGS, NULL},
+ { (char *)"rand_poll", _wrap_rand_poll, METH_VARARGS, NULL},
+ { (char *)"rand_status", _wrap_rand_status, METH_VARARGS, NULL},
+ { (char *)"rand_cleanup", _wrap_rand_cleanup, METH_VARARGS, NULL},
+ { (char *)"rand_init", _wrap_rand_init, METH_VARARGS, NULL},
+ { (char *)"rand_seed", _wrap_rand_seed, METH_VARARGS, NULL},
+ { (char *)"rand_add", _wrap_rand_add, METH_VARARGS, NULL},
+ { (char *)"rand_bytes", _wrap_rand_bytes, METH_VARARGS, NULL},
+ { (char *)"rand_pseudo_bytes", _wrap_rand_pseudo_bytes, METH_VARARGS, NULL},
+ { (char *)"rand_file_name", _wrap_rand_file_name, METH_VARARGS, NULL},
+ { (char *)"rand_screen", _wrap_rand_screen, METH_VARARGS, NULL},
+ { (char *)"rand_win32_event", _wrap_rand_win32_event, METH_VARARGS, NULL},
+ { (char *)"md5", _wrap_md5, METH_VARARGS, NULL},
+ { (char *)"sha1", _wrap_sha1, METH_VARARGS, NULL},
+ { (char *)"ripemd160", _wrap_ripemd160, METH_VARARGS, NULL},
+ { (char *)"sha224", _wrap_sha224, METH_VARARGS, NULL},
+ { (char *)"sha256", _wrap_sha256, METH_VARARGS, NULL},
+ { (char *)"sha384", _wrap_sha384, METH_VARARGS, NULL},
+ { (char *)"sha512", _wrap_sha512, METH_VARARGS, NULL},
+ { (char *)"digest_init", _wrap_digest_init, METH_VARARGS, NULL},
+ { (char *)"des_ecb", _wrap_des_ecb, METH_VARARGS, NULL},
+ { (char *)"des_ede_ecb", _wrap_des_ede_ecb, METH_VARARGS, NULL},
+ { (char *)"des_ede3_ecb", _wrap_des_ede3_ecb, METH_VARARGS, NULL},
+ { (char *)"des_cbc", _wrap_des_cbc, METH_VARARGS, NULL},
+ { (char *)"des_ede_cbc", _wrap_des_ede_cbc, METH_VARARGS, NULL},
+ { (char *)"des_ede3_cbc", _wrap_des_ede3_cbc, METH_VARARGS, NULL},
+ { (char *)"des_cfb", _wrap_des_cfb, METH_VARARGS, NULL},
+ { (char *)"des_ede_cfb", _wrap_des_ede_cfb, METH_VARARGS, NULL},
+ { (char *)"des_ede3_cfb", _wrap_des_ede3_cfb, METH_VARARGS, NULL},
+ { (char *)"des_ofb", _wrap_des_ofb, METH_VARARGS, NULL},
+ { (char *)"des_ede_ofb", _wrap_des_ede_ofb, METH_VARARGS, NULL},
+ { (char *)"des_ede3_ofb", _wrap_des_ede3_ofb, METH_VARARGS, NULL},
+ { (char *)"bf_ecb", _wrap_bf_ecb, METH_VARARGS, NULL},
+ { (char *)"bf_cbc", _wrap_bf_cbc, METH_VARARGS, NULL},
+ { (char *)"bf_cfb", _wrap_bf_cfb, METH_VARARGS, NULL},
+ { (char *)"bf_ofb", _wrap_bf_ofb, METH_VARARGS, NULL},
+ { (char *)"cast5_ecb", _wrap_cast5_ecb, METH_VARARGS, NULL},
+ { (char *)"cast5_cbc", _wrap_cast5_cbc, METH_VARARGS, NULL},
+ { (char *)"cast5_cfb", _wrap_cast5_cfb, METH_VARARGS, NULL},
+ { (char *)"cast5_ofb", _wrap_cast5_ofb, METH_VARARGS, NULL},
+ { (char *)"rc4", _wrap_rc4, METH_VARARGS, NULL},
+ { (char *)"rc2_40_cbc", _wrap_rc2_40_cbc, METH_VARARGS, NULL},
+ { (char *)"aes_128_ecb", _wrap_aes_128_ecb, METH_VARARGS, NULL},
+ { (char *)"aes_128_cbc", _wrap_aes_128_cbc, METH_VARARGS, NULL},
+ { (char *)"aes_128_cfb", _wrap_aes_128_cfb, METH_VARARGS, NULL},
+ { (char *)"aes_128_ofb", _wrap_aes_128_ofb, METH_VARARGS, NULL},
+ { (char *)"aes_128_ctr", _wrap_aes_128_ctr, METH_VARARGS, NULL},
+ { (char *)"aes_192_ecb", _wrap_aes_192_ecb, METH_VARARGS, NULL},
+ { (char *)"aes_192_cbc", _wrap_aes_192_cbc, METH_VARARGS, NULL},
+ { (char *)"aes_192_cfb", _wrap_aes_192_cfb, METH_VARARGS, NULL},
+ { (char *)"aes_192_ofb", _wrap_aes_192_ofb, METH_VARARGS, NULL},
+ { (char *)"aes_192_ctr", _wrap_aes_192_ctr, METH_VARARGS, NULL},
+ { (char *)"aes_256_ecb", _wrap_aes_256_ecb, METH_VARARGS, NULL},
+ { (char *)"aes_256_cbc", _wrap_aes_256_cbc, METH_VARARGS, NULL},
+ { (char *)"aes_256_cfb", _wrap_aes_256_cfb, METH_VARARGS, NULL},
+ { (char *)"aes_256_ofb", _wrap_aes_256_ofb, METH_VARARGS, NULL},
+ { (char *)"aes_256_ctr", _wrap_aes_256_ctr, METH_VARARGS, NULL},
+ { (char *)"cipher_set_padding", _wrap_cipher_set_padding, METH_VARARGS, NULL},
+ { (char *)"pkey_free", _wrap_pkey_free, METH_VARARGS, NULL},
+ { (char *)"pkey_assign", _wrap_pkey_assign, METH_VARARGS, NULL},
+ { (char *)"pkey_assign_ec", _wrap_pkey_assign_ec, METH_VARARGS, NULL},
+ { (char *)"pkey_set1_rsa", _wrap_pkey_set1_rsa, METH_VARARGS, NULL},
+ { (char *)"sign_init", _wrap_sign_init, METH_VARARGS, NULL},
+ { (char *)"verify_init", _wrap_verify_init, METH_VARARGS, NULL},
+ { (char *)"pkey_size", _wrap_pkey_size, METH_VARARGS, NULL},
+ { (char *)"evp_init", _wrap_evp_init, METH_VARARGS, NULL},
+ { (char *)"pkey_get1_rsa", _wrap_pkey_get1_rsa, METH_VARARGS, NULL},
+ { (char *)"pkcs5_pbkdf2_hmac_sha1", _wrap_pkcs5_pbkdf2_hmac_sha1, METH_VARARGS, NULL},
+ { (char *)"md_ctx_new", _wrap_md_ctx_new, METH_VARARGS, NULL},
+ { (char *)"md_ctx_free", _wrap_md_ctx_free, METH_VARARGS, NULL},
+ { (char *)"digest_update", _wrap_digest_update, METH_VARARGS, NULL},
+ { (char *)"digest_final", _wrap_digest_final, METH_VARARGS, NULL},
+ { (char *)"hmac_ctx_new", _wrap_hmac_ctx_new, METH_VARARGS, NULL},
+ { (char *)"hmac_ctx_free", _wrap_hmac_ctx_free, METH_VARARGS, NULL},
+ { (char *)"hmac_init", _wrap_hmac_init, METH_VARARGS, NULL},
+ { (char *)"hmac_update", _wrap_hmac_update, METH_VARARGS, NULL},
+ { (char *)"hmac_final", _wrap_hmac_final, METH_VARARGS, NULL},
+ { (char *)"hmac", _wrap_hmac, METH_VARARGS, NULL},
+ { (char *)"cipher_ctx_new", _wrap_cipher_ctx_new, METH_VARARGS, NULL},
+ { (char *)"cipher_ctx_free", _wrap_cipher_ctx_free, METH_VARARGS, NULL},
+ { (char *)"bytes_to_key", _wrap_bytes_to_key, METH_VARARGS, NULL},
+ { (char *)"cipher_init", _wrap_cipher_init, METH_VARARGS, NULL},
+ { (char *)"cipher_update", _wrap_cipher_update, METH_VARARGS, NULL},
+ { (char *)"cipher_final", _wrap_cipher_final, METH_VARARGS, NULL},
+ { (char *)"sign_update", _wrap_sign_update, METH_VARARGS, NULL},
+ { (char *)"sign_final", _wrap_sign_final, METH_VARARGS, NULL},
+ { (char *)"verify_update", _wrap_verify_update, METH_VARARGS, NULL},
+ { (char *)"verify_final", _wrap_verify_final, METH_VARARGS, NULL},
+ { (char *)"get_digestbyname", _wrap_get_digestbyname, METH_VARARGS, NULL},
+ { (char *)"pkey_write_pem_no_cipher", _wrap_pkey_write_pem_no_cipher, METH_VARARGS, NULL},
+ { (char *)"pkey_write_pem", _wrap_pkey_write_pem, METH_VARARGS, NULL},
+ { (char *)"pkey_new", _wrap_pkey_new, METH_VARARGS, NULL},
+ { (char *)"pkey_read_pem", _wrap_pkey_read_pem, METH_VARARGS, NULL},
+ { (char *)"pkey_read_pem_pubkey", _wrap_pkey_read_pem_pubkey, METH_VARARGS, NULL},
+ { (char *)"pkey_assign_rsa", _wrap_pkey_assign_rsa, METH_VARARGS, NULL},
+ { (char *)"pkey_as_der", _wrap_pkey_as_der, METH_VARARGS, NULL},
+ { (char *)"pkey_get_modulus", _wrap_pkey_get_modulus, METH_VARARGS, NULL},
+ { (char *)"aes_new", _wrap_aes_new, METH_VARARGS, NULL},
+ { (char *)"AES_free", _wrap_AES_free, METH_VARARGS, NULL},
+ { (char *)"AES_set_key", _wrap_AES_set_key, METH_VARARGS, NULL},
+ { (char *)"AES_crypt", _wrap_AES_crypt, METH_VARARGS, NULL},
+ { (char *)"AES_type_check", _wrap_AES_type_check, METH_VARARGS, NULL},
+ { (char *)"rc4_new", _wrap_rc4_new, METH_VARARGS, NULL},
+ { (char *)"rc4_free", _wrap_rc4_free, METH_VARARGS, NULL},
+ { (char *)"rc4_set_key", _wrap_rc4_set_key, METH_VARARGS, NULL},
+ { (char *)"rc4_update", _wrap_rc4_update, METH_VARARGS, NULL},
+ { (char *)"rc4_type_check", _wrap_rc4_type_check, METH_VARARGS, NULL},
+ { (char *)"dh_new", _wrap_dh_new, METH_VARARGS, NULL},
+ { (char *)"dh_free", _wrap_dh_free, METH_VARARGS, NULL},
+ { (char *)"dh_size", _wrap_dh_size, METH_VARARGS, NULL},
+ { (char *)"dh_generate_key", _wrap_dh_generate_key, METH_VARARGS, NULL},
+ { (char *)"dhparams_print", _wrap_dhparams_print, METH_VARARGS, NULL},
+ { (char *)"dh_init", _wrap_dh_init, METH_VARARGS, NULL},
+ { (char *)"dh_type_check", _wrap_dh_type_check, METH_VARARGS, NULL},
+ { (char *)"dh_read_parameters", _wrap_dh_read_parameters, METH_VARARGS, NULL},
+ { (char *)"dh_generate_parameters", _wrap_dh_generate_parameters, METH_VARARGS, NULL},
+ { (char *)"dh_check", _wrap_dh_check, METH_VARARGS, NULL},
+ { (char *)"dh_compute_key", _wrap_dh_compute_key, METH_VARARGS, NULL},
+ { (char *)"dh_get_p", _wrap_dh_get_p, METH_VARARGS, NULL},
+ { (char *)"dh_get_g", _wrap_dh_get_g, METH_VARARGS, NULL},
+ { (char *)"dh_get_pub", _wrap_dh_get_pub, METH_VARARGS, NULL},
+ { (char *)"dh_get_priv", _wrap_dh_get_priv, METH_VARARGS, NULL},
+ { (char *)"dh_set_pg", _wrap_dh_set_pg, METH_VARARGS, NULL},
+ { (char *)"rsa_size", _wrap_rsa_size, METH_VARARGS, NULL},
+ { (char *)"rsa_new", _wrap_rsa_new, METH_VARARGS, NULL},
+ { (char *)"rsa_free", _wrap_rsa_free, METH_VARARGS, NULL},
+ { (char *)"rsa_check_key", _wrap_rsa_check_key, METH_VARARGS, NULL},
+ { (char *)"rsa_init", _wrap_rsa_init, METH_VARARGS, NULL},
+ { (char *)"rsa_read_key", _wrap_rsa_read_key, METH_VARARGS, NULL},
+ { (char *)"rsa_write_key", _wrap_rsa_write_key, METH_VARARGS, NULL},
+ { (char *)"rsa_write_key_no_cipher", _wrap_rsa_write_key_no_cipher, METH_VARARGS, NULL},
+ { (char *)"rsa_read_pub_key", _wrap_rsa_read_pub_key, METH_VARARGS, NULL},
+ { (char *)"rsa_write_pub_key", _wrap_rsa_write_pub_key, METH_VARARGS, NULL},
+ { (char *)"rsa_get_e", _wrap_rsa_get_e, METH_VARARGS, NULL},
+ { (char *)"rsa_get_n", _wrap_rsa_get_n, METH_VARARGS, NULL},
+ { (char *)"rsa_set_e", _wrap_rsa_set_e, METH_VARARGS, NULL},
+ { (char *)"rsa_set_n", _wrap_rsa_set_n, METH_VARARGS, NULL},
+ { (char *)"rsa_set_en", _wrap_rsa_set_en, METH_VARARGS, NULL},
+ { (char *)"PyObject_Bin_AsBIGNUM", _wrap_PyObject_Bin_AsBIGNUM, METH_VARARGS, NULL},
+ { (char *)"rsa_set_en_bin", _wrap_rsa_set_en_bin, METH_VARARGS, NULL},
+ { (char *)"rsa_private_encrypt", _wrap_rsa_private_encrypt, METH_VARARGS, NULL},
+ { (char *)"rsa_public_decrypt", _wrap_rsa_public_decrypt, METH_VARARGS, NULL},
+ { (char *)"rsa_public_encrypt", _wrap_rsa_public_encrypt, METH_VARARGS, NULL},
+ { (char *)"rsa_private_decrypt", _wrap_rsa_private_decrypt, METH_VARARGS, NULL},
+ { (char *)"rsa_padding_add_pkcs1_pss", _wrap_rsa_padding_add_pkcs1_pss, METH_VARARGS, NULL},
+ { (char *)"rsa_verify_pkcs1_pss", _wrap_rsa_verify_pkcs1_pss, METH_VARARGS, NULL},
+ { (char *)"rsa_sign", _wrap_rsa_sign, METH_VARARGS, NULL},
+ { (char *)"rsa_verify", _wrap_rsa_verify, METH_VARARGS, NULL},
+ { (char *)"rsa_generate_key", _wrap_rsa_generate_key, METH_VARARGS, NULL},
+ { (char *)"rsa_type_check", _wrap_rsa_type_check, METH_VARARGS, NULL},
+ { (char *)"rsa_check_pub_key", _wrap_rsa_check_pub_key, METH_VARARGS, NULL},
+ { (char *)"rsa_write_key_der", _wrap_rsa_write_key_der, METH_VARARGS, NULL},
+ { (char *)"dsa_new", _wrap_dsa_new, METH_VARARGS, NULL},
+ { (char *)"dsa_free", _wrap_dsa_free, METH_VARARGS, NULL},
+ { (char *)"dsa_size", _wrap_dsa_size, METH_VARARGS, NULL},
+ { (char *)"dsa_gen_key", _wrap_dsa_gen_key, METH_VARARGS, NULL},
+ { (char *)"dsa_init", _wrap_dsa_init, METH_VARARGS, NULL},
+ { (char *)"dsa_generate_parameters", _wrap_dsa_generate_parameters, METH_VARARGS, NULL},
+ { (char *)"dsa_read_params", _wrap_dsa_read_params, METH_VARARGS, NULL},
+ { (char *)"dsa_read_key", _wrap_dsa_read_key, METH_VARARGS, NULL},
+ { (char *)"dsa_read_pub_key", _wrap_dsa_read_pub_key, METH_VARARGS, NULL},
+ { (char *)"dsa_get_p", _wrap_dsa_get_p, METH_VARARGS, NULL},
+ { (char *)"dsa_get_q", _wrap_dsa_get_q, METH_VARARGS, NULL},
+ { (char *)"dsa_get_g", _wrap_dsa_get_g, METH_VARARGS, NULL},
+ { (char *)"dsa_get_pub", _wrap_dsa_get_pub, METH_VARARGS, NULL},
+ { (char *)"dsa_get_priv", _wrap_dsa_get_priv, METH_VARARGS, NULL},
+ { (char *)"dsa_set_pqg", _wrap_dsa_set_pqg, METH_VARARGS, NULL},
+ { (char *)"dsa_set_pub", _wrap_dsa_set_pub, METH_VARARGS, NULL},
+ { (char *)"dsa_write_params_bio", _wrap_dsa_write_params_bio, METH_VARARGS, NULL},
+ { (char *)"dsa_write_key_bio", _wrap_dsa_write_key_bio, METH_VARARGS, NULL},
+ { (char *)"dsa_write_key_bio_no_cipher", _wrap_dsa_write_key_bio_no_cipher, METH_VARARGS, NULL},
+ { (char *)"dsa_write_pub_key_bio", _wrap_dsa_write_pub_key_bio, METH_VARARGS, NULL},
+ { (char *)"dsa_sign", _wrap_dsa_sign, METH_VARARGS, NULL},
+ { (char *)"dsa_verify", _wrap_dsa_verify, METH_VARARGS, NULL},
+ { (char *)"dsa_sign_asn1", _wrap_dsa_sign_asn1, METH_VARARGS, NULL},
+ { (char *)"dsa_verify_asn1", _wrap_dsa_verify_asn1, METH_VARARGS, NULL},
+ { (char *)"dsa_check_key", _wrap_dsa_check_key, METH_VARARGS, NULL},
+ { (char *)"dsa_check_pub_key", _wrap_dsa_check_pub_key, METH_VARARGS, NULL},
+ { (char *)"dsa_keylen", _wrap_dsa_keylen, METH_VARARGS, NULL},
+ { (char *)"dsa_type_check", _wrap_dsa_type_check, METH_VARARGS, NULL},
+ { (char *)"ssl_get_ciphers", _wrap_ssl_get_ciphers, METH_VARARGS, NULL},
+ { (char *)"ssl_get_version", _wrap_ssl_get_version, METH_VARARGS, NULL},
+ { (char *)"ssl_get_error", _wrap_ssl_get_error, METH_VARARGS, NULL},
+ { (char *)"ssl_get_state", _wrap_ssl_get_state, METH_VARARGS, NULL},
+ { (char *)"ssl_get_state_v", _wrap_ssl_get_state_v, METH_VARARGS, NULL},
+ { (char *)"ssl_get_alert_type", _wrap_ssl_get_alert_type, METH_VARARGS, NULL},
+ { (char *)"ssl_get_alert_type_v", _wrap_ssl_get_alert_type_v, METH_VARARGS, NULL},
+ { (char *)"ssl_get_alert_desc", _wrap_ssl_get_alert_desc, METH_VARARGS, NULL},
+ { (char *)"ssl_get_alert_desc_v", _wrap_ssl_get_alert_desc_v, METH_VARARGS, NULL},
+ { (char *)"sslv23_method", _wrap_sslv23_method, METH_VARARGS, NULL},
+ { (char *)"ssl_ctx_new", _wrap_ssl_ctx_new, METH_VARARGS, NULL},
+ { (char *)"ssl_ctx_free", _wrap_ssl_ctx_free, METH_VARARGS, NULL},
+ { (char *)"ssl_ctx_set_verify_depth", _wrap_ssl_ctx_set_verify_depth, METH_VARARGS, NULL},
+ { (char *)"ssl_ctx_get_verify_depth", _wrap_ssl_ctx_get_verify_depth, METH_VARARGS, NULL},
+ { (char *)"ssl_ctx_get_verify_mode", _wrap_ssl_ctx_get_verify_mode, METH_VARARGS, NULL},
+ { (char *)"ssl_ctx_set_cipher_list", _wrap_ssl_ctx_set_cipher_list, METH_VARARGS, NULL},
+ { (char *)"ssl_ctx_add_session", _wrap_ssl_ctx_add_session, METH_VARARGS, NULL},
+ { (char *)"ssl_ctx_remove_session", _wrap_ssl_ctx_remove_session, METH_VARARGS, NULL},
+ { (char *)"ssl_ctx_set_session_timeout", _wrap_ssl_ctx_set_session_timeout, METH_VARARGS, NULL},
+ { (char *)"ssl_ctx_get_session_timeout", _wrap_ssl_ctx_get_session_timeout, METH_VARARGS, NULL},
+ { (char *)"ssl_ctx_get_cert_store", _wrap_ssl_ctx_get_cert_store, METH_VARARGS, NULL},
+ { (char *)"ssl_ctx_set_default_verify_paths", _wrap_ssl_ctx_set_default_verify_paths, METH_VARARGS, NULL},
+ { (char *)"ssl_get_ex_data_x509_store_ctx_idx", _wrap_ssl_get_ex_data_x509_store_ctx_idx, METH_VARARGS, NULL},
+ { (char *)"bio_new_ssl", _wrap_bio_new_ssl, METH_VARARGS, NULL},
+ { (char *)"ssl_new", _wrap_ssl_new, METH_VARARGS, NULL},
+ { (char *)"ssl_free", _wrap_ssl_free, METH_VARARGS, NULL},
+ { (char *)"ssl_dup", _wrap_ssl_dup, METH_VARARGS, NULL},
+ { (char *)"ssl_set_bio", _wrap_ssl_set_bio, METH_VARARGS, NULL},
+ { (char *)"ssl_set_accept_state", _wrap_ssl_set_accept_state, METH_VARARGS, NULL},
+ { (char *)"ssl_set_connect_state", _wrap_ssl_set_connect_state, METH_VARARGS, NULL},
+ { (char *)"ssl_get_shutdown", _wrap_ssl_get_shutdown, METH_VARARGS, NULL},
+ { (char *)"ssl_set_shutdown", _wrap_ssl_set_shutdown, METH_VARARGS, NULL},
+ { (char *)"ssl_shutdown", _wrap_ssl_shutdown, METH_VARARGS, NULL},
+ { (char *)"ssl_clear", _wrap_ssl_clear, METH_VARARGS, NULL},
+ { (char *)"ssl_do_handshake", _wrap_ssl_do_handshake, METH_VARARGS, NULL},
+ { (char *)"ssl_renegotiate", _wrap_ssl_renegotiate, METH_VARARGS, NULL},
+ { (char *)"ssl_pending", _wrap_ssl_pending, METH_VARARGS, NULL},
+ { (char *)"ssl_get_peer_cert", _wrap_ssl_get_peer_cert, METH_VARARGS, NULL},
+ { (char *)"ssl_get_current_cipher", _wrap_ssl_get_current_cipher, METH_VARARGS, NULL},
+ { (char *)"ssl_get_verify_mode", _wrap_ssl_get_verify_mode, METH_VARARGS, NULL},
+ { (char *)"ssl_get_verify_depth", _wrap_ssl_get_verify_depth, METH_VARARGS, NULL},
+ { (char *)"ssl_get_verify_result", _wrap_ssl_get_verify_result, METH_VARARGS, NULL},
+ { (char *)"ssl_get_ssl_ctx", _wrap_ssl_get_ssl_ctx, METH_VARARGS, NULL},
+ { (char *)"ssl_get_default_session_timeout", _wrap_ssl_get_default_session_timeout, METH_VARARGS, NULL},
+ { (char *)"ssl_set_cipher_list", _wrap_ssl_set_cipher_list, METH_VARARGS, NULL},
+ { (char *)"ssl_get_cipher_list", _wrap_ssl_get_cipher_list, METH_VARARGS, NULL},
+ { (char *)"ssl_cipher_get_name", _wrap_ssl_cipher_get_name, METH_VARARGS, NULL},
+ { (char *)"ssl_cipher_get_version", _wrap_ssl_cipher_get_version, METH_VARARGS, NULL},
+ { (char *)"ssl_get_session", _wrap_ssl_get_session, METH_VARARGS, NULL},
+ { (char *)"ssl_get1_session", _wrap_ssl_get1_session, METH_VARARGS, NULL},
+ { (char *)"ssl_set_session", _wrap_ssl_set_session, METH_VARARGS, NULL},
+ { (char *)"ssl_session_free", _wrap_ssl_session_free, METH_VARARGS, NULL},
+ { (char *)"ssl_session_print", _wrap_ssl_session_print, METH_VARARGS, NULL},
+ { (char *)"ssl_session_set_timeout", _wrap_ssl_session_set_timeout, METH_VARARGS, NULL},
+ { (char *)"ssl_session_get_timeout", _wrap_ssl_session_get_timeout, METH_VARARGS, NULL},
+ { (char *)"ssl_accept", _wrap_ssl_accept, METH_VARARGS, NULL},
+ { (char *)"ssl_connect", _wrap_ssl_connect, METH_VARARGS, NULL},
+ { (char *)"ssl_read", _wrap_ssl_read, METH_VARARGS, NULL},
+ { (char *)"ssl_write", _wrap_ssl_write, METH_VARARGS, NULL},
+ { (char *)"ssl_init", _wrap_ssl_init, METH_VARARGS, NULL},
+ { (char *)"tlsv1_method", _wrap_tlsv1_method, METH_VARARGS, NULL},
+ { (char *)"ssl_ctx_passphrase_callback", _wrap_ssl_ctx_passphrase_callback, METH_VARARGS, NULL},
+ { (char *)"ssl_ctx_use_x509", _wrap_ssl_ctx_use_x509, METH_VARARGS, NULL},
+ { (char *)"ssl_ctx_use_cert", _wrap_ssl_ctx_use_cert, METH_VARARGS, NULL},
+ { (char *)"ssl_ctx_use_cert_chain", _wrap_ssl_ctx_use_cert_chain, METH_VARARGS, NULL},
+ { (char *)"ssl_ctx_use_privkey", _wrap_ssl_ctx_use_privkey, METH_VARARGS, NULL},
+ { (char *)"ssl_ctx_use_rsa_privkey", _wrap_ssl_ctx_use_rsa_privkey, METH_VARARGS, NULL},
+ { (char *)"ssl_ctx_use_pkey_privkey", _wrap_ssl_ctx_use_pkey_privkey, METH_VARARGS, NULL},
+ { (char *)"ssl_ctx_check_privkey", _wrap_ssl_ctx_check_privkey, METH_VARARGS, NULL},
+ { (char *)"ssl_ctx_set_client_CA_list_from_file", _wrap_ssl_ctx_set_client_CA_list_from_file, METH_VARARGS, NULL},
+ { (char *)"ssl_ctx_set_verify_default", _wrap_ssl_ctx_set_verify_default, METH_VARARGS, NULL},
+ { (char *)"ssl_ctx_set_verify", _wrap_ssl_ctx_set_verify, METH_VARARGS, NULL},
+ { (char *)"ssl_ctx_set_session_id_context", _wrap_ssl_ctx_set_session_id_context, METH_VARARGS, NULL},
+ { (char *)"ssl_ctx_set_info_callback", _wrap_ssl_ctx_set_info_callback, METH_VARARGS, NULL},
+ { (char *)"ssl_ctx_set_tmp_dh", _wrap_ssl_ctx_set_tmp_dh, METH_VARARGS, NULL},
+ { (char *)"ssl_ctx_set_tmp_dh_callback", _wrap_ssl_ctx_set_tmp_dh_callback, METH_VARARGS, NULL},
+ { (char *)"ssl_ctx_set_tmp_rsa", _wrap_ssl_ctx_set_tmp_rsa, METH_VARARGS, NULL},
+ { (char *)"ssl_ctx_set_tmp_rsa_callback", _wrap_ssl_ctx_set_tmp_rsa_callback, METH_VARARGS, NULL},
+ { (char *)"ssl_ctx_load_verify_locations", _wrap_ssl_ctx_load_verify_locations, METH_VARARGS, NULL},
+ { (char *)"ssl_ctx_set_options", _wrap_ssl_ctx_set_options, METH_VARARGS, NULL},
+ { (char *)"bio_set_ssl", _wrap_bio_set_ssl, METH_VARARGS, NULL},
+ { (char *)"ssl_set_mode", _wrap_ssl_set_mode, METH_VARARGS, NULL},
+ { (char *)"ssl_get_mode", _wrap_ssl_get_mode, METH_VARARGS, NULL},
+ { (char *)"ssl_set_tlsext_host_name", _wrap_ssl_set_tlsext_host_name, METH_VARARGS, NULL},
+ { (char *)"ssl_set_client_CA_list_from_file", _wrap_ssl_set_client_CA_list_from_file, METH_VARARGS, NULL},
+ { (char *)"ssl_set_client_CA_list_from_context", _wrap_ssl_set_client_CA_list_from_context, METH_VARARGS, NULL},
+ { (char *)"ssl_set_session_id_context", _wrap_ssl_set_session_id_context, METH_VARARGS, NULL},
+ { (char *)"ssl_set_fd", _wrap_ssl_set_fd, METH_VARARGS, NULL},
+ { (char *)"ssl_set_shutdown1", _wrap_ssl_set_shutdown1, METH_VARARGS, NULL},
+ { (char *)"ssl_read_nbio", _wrap_ssl_read_nbio, METH_VARARGS, NULL},
+ { (char *)"ssl_write_nbio", _wrap_ssl_write_nbio, METH_VARARGS, NULL},
+ { (char *)"ssl_cipher_get_bits", _wrap_ssl_cipher_get_bits, METH_VARARGS, NULL},
+ { (char *)"sk_ssl_cipher_num", _wrap_sk_ssl_cipher_num, METH_VARARGS, NULL},
+ { (char *)"sk_ssl_cipher_value", _wrap_sk_ssl_cipher_value, METH_VARARGS, NULL},
+ { (char *)"ssl_get_peer_cert_chain", _wrap_ssl_get_peer_cert_chain, METH_VARARGS, NULL},
+ { (char *)"sk_x509_num", _wrap_sk_x509_num, METH_VARARGS, NULL},
+ { (char *)"sk_x509_value", _wrap_sk_x509_value, METH_VARARGS, NULL},
+ { (char *)"i2d_ssl_session", _wrap_i2d_ssl_session, METH_VARARGS, NULL},
+ { (char *)"ssl_session_read_pem", _wrap_ssl_session_read_pem, METH_VARARGS, NULL},
+ { (char *)"ssl_session_write_pem", _wrap_ssl_session_write_pem, METH_VARARGS, NULL},
+ { (char *)"ssl_ctx_set_session_cache_mode", _wrap_ssl_ctx_set_session_cache_mode, METH_VARARGS, NULL},
+ { (char *)"ssl_ctx_get_session_cache_mode", _wrap_ssl_ctx_get_session_cache_mode, METH_VARARGS, NULL},
+ { (char *)"ssl_ctx_set_cache_size", _wrap_ssl_ctx_set_cache_size, METH_VARARGS, NULL},
+ { (char *)"ssl_is_init_finished", _wrap_ssl_is_init_finished, METH_VARARGS, NULL},
+ { (char *)"x509_check_ca", _wrap_x509_check_ca, METH_VARARGS, NULL},
+ { (char *)"x509_new", _wrap_x509_new, METH_VARARGS, NULL},
+ { (char *)"x509_dup", _wrap_x509_dup, METH_VARARGS, NULL},
+ { (char *)"x509_free", _wrap_x509_free, METH_VARARGS, NULL},
+ { (char *)"x509_crl_free", _wrap_x509_crl_free, METH_VARARGS, NULL},
+ { (char *)"x509_crl_new", _wrap_x509_crl_new, METH_VARARGS, NULL},
+ { (char *)"x509_print", _wrap_x509_print, METH_VARARGS, NULL},
+ { (char *)"x509_crl_print", _wrap_x509_crl_print, METH_VARARGS, NULL},
+ { (char *)"x509_get_serial_number", _wrap_x509_get_serial_number, METH_VARARGS, NULL},
+ { (char *)"x509_set_serial_number", _wrap_x509_set_serial_number, METH_VARARGS, NULL},
+ { (char *)"x509_get_pubkey", _wrap_x509_get_pubkey, METH_VARARGS, NULL},
+ { (char *)"x509_set_pubkey", _wrap_x509_set_pubkey, METH_VARARGS, NULL},
+ { (char *)"x509_get_issuer_name", _wrap_x509_get_issuer_name, METH_VARARGS, NULL},
+ { (char *)"x509_set_issuer_name", _wrap_x509_set_issuer_name, METH_VARARGS, NULL},
+ { (char *)"x509_get_subject_name", _wrap_x509_get_subject_name, METH_VARARGS, NULL},
+ { (char *)"x509_set_subject_name", _wrap_x509_set_subject_name, METH_VARARGS, NULL},
+ { (char *)"x509_cmp_current_time", _wrap_x509_cmp_current_time, METH_VARARGS, NULL},
+ { (char *)"x509_check_purpose", _wrap_x509_check_purpose, METH_VARARGS, NULL},
+ { (char *)"x509_check_trust", _wrap_x509_check_trust, METH_VARARGS, NULL},
+ { (char *)"x509_write_pem", _wrap_x509_write_pem, METH_VARARGS, NULL},
+ { (char *)"x509_write_pem_file", _wrap_x509_write_pem_file, METH_VARARGS, NULL},
+ { (char *)"x509_verify", _wrap_x509_verify, METH_VARARGS, NULL},
+ { (char *)"x509_get_verify_error", _wrap_x509_get_verify_error, METH_VARARGS, NULL},
+ { (char *)"x509_add_ext", _wrap_x509_add_ext, METH_VARARGS, NULL},
+ { (char *)"x509_get_ext_count", _wrap_x509_get_ext_count, METH_VARARGS, NULL},
+ { (char *)"x509_get_ext", _wrap_x509_get_ext, METH_VARARGS, NULL},
+ { (char *)"x509_ext_print", _wrap_x509_ext_print, METH_VARARGS, NULL},
+ { (char *)"x509_name_new", _wrap_x509_name_new, METH_VARARGS, NULL},
+ { (char *)"x509_name_free", _wrap_x509_name_free, METH_VARARGS, NULL},
+ { (char *)"x509_name_print", _wrap_x509_name_print, METH_VARARGS, NULL},
+ { (char *)"x509_name_get_entry", _wrap_x509_name_get_entry, METH_VARARGS, NULL},
+ { (char *)"x509_name_entry_count", _wrap_x509_name_entry_count, METH_VARARGS, NULL},
+ { (char *)"x509_name_delete_entry", _wrap_x509_name_delete_entry, METH_VARARGS, NULL},
+ { (char *)"x509_name_add_entry", _wrap_x509_name_add_entry, METH_VARARGS, NULL},
+ { (char *)"x509_name_add_entry_by_obj", _wrap_x509_name_add_entry_by_obj, METH_VARARGS, NULL},
+ { (char *)"x509_name_add_entry_by_nid", _wrap_x509_name_add_entry_by_nid, METH_VARARGS, NULL},
+ { (char *)"x509_name_print_ex", _wrap_x509_name_print_ex, METH_VARARGS, NULL},
+ { (char *)"x509_name_hash", _wrap_x509_name_hash, METH_VARARGS, NULL},
+ { (char *)"x509_name_get_index_by_nid", _wrap_x509_name_get_index_by_nid, METH_VARARGS, NULL},
+ { (char *)"x509_name_entry_new", _wrap_x509_name_entry_new, METH_VARARGS, NULL},
+ { (char *)"x509_name_entry_free", _wrap_x509_name_entry_free, METH_VARARGS, NULL},
+ { (char *)"x509_name_entry_create_by_nid", _wrap_x509_name_entry_create_by_nid, METH_VARARGS, NULL},
+ { (char *)"x509_name_entry_set_object", _wrap_x509_name_entry_set_object, METH_VARARGS, NULL},
+ { (char *)"x509_name_entry_get_object", _wrap_x509_name_entry_get_object, METH_VARARGS, NULL},
+ { (char *)"x509_name_entry_get_data", _wrap_x509_name_entry_get_data, METH_VARARGS, NULL},
+ { (char *)"x509_name_entry_set_data", _wrap_x509_name_entry_set_data, METH_VARARGS, NULL},
+ { (char *)"x509_req_new", _wrap_x509_req_new, METH_VARARGS, NULL},
+ { (char *)"x509_req_free", _wrap_x509_req_free, METH_VARARGS, NULL},
+ { (char *)"x509_req_print", _wrap_x509_req_print, METH_VARARGS, NULL},
+ { (char *)"x509_req_get_pubkey", _wrap_x509_req_get_pubkey, METH_VARARGS, NULL},
+ { (char *)"x509_req_set_pubkey", _wrap_x509_req_set_pubkey, METH_VARARGS, NULL},
+ { (char *)"x509_req_set_subject_name", _wrap_x509_req_set_subject_name, METH_VARARGS, NULL},
+ { (char *)"x509_req_verify", _wrap_x509_req_verify, METH_VARARGS, NULL},
+ { (char *)"x509_req_sign", _wrap_x509_req_sign, METH_VARARGS, NULL},
+ { (char *)"i2d_x509_bio", _wrap_i2d_x509_bio, METH_VARARGS, NULL},
+ { (char *)"i2d_x509_req_bio", _wrap_i2d_x509_req_bio, METH_VARARGS, NULL},
+ { (char *)"x509_store_new", _wrap_x509_store_new, METH_VARARGS, NULL},
+ { (char *)"x509_store_free", _wrap_x509_store_free, METH_VARARGS, NULL},
+ { (char *)"x509_store_add_cert", _wrap_x509_store_add_cert, METH_VARARGS, NULL},
+ { (char *)"x509_store_ctx_get_current_cert", _wrap_x509_store_ctx_get_current_cert, METH_VARARGS, NULL},
+ { (char *)"x509_store_ctx_get_error", _wrap_x509_store_ctx_get_error, METH_VARARGS, NULL},
+ { (char *)"x509_store_ctx_get_error_depth", _wrap_x509_store_ctx_get_error_depth, METH_VARARGS, NULL},
+ { (char *)"x509_store_ctx_free", _wrap_x509_store_ctx_free, METH_VARARGS, NULL},
+ { (char *)"x509_store_ctx_get1_chain", _wrap_x509_store_ctx_get1_chain, METH_VARARGS, NULL},
+ { (char *)"x509_extension_get_critical", _wrap_x509_extension_get_critical, METH_VARARGS, NULL},
+ { (char *)"x509_extension_set_critical", _wrap_x509_extension_set_critical, METH_VARARGS, NULL},
+ { (char *)"x509_read_pem", _wrap_x509_read_pem, METH_VARARGS, NULL},
+ { (char *)"d2i_x509", _wrap_d2i_x509, METH_VARARGS, NULL},
+ { (char *)"x509_init", _wrap_x509_init, METH_VARARGS, NULL},
+ { (char *)"d2i_x509_req", _wrap_d2i_x509_req, METH_VARARGS, NULL},
+ { (char *)"x509_req_read_pem", _wrap_x509_req_read_pem, METH_VARARGS, NULL},
+ { (char *)"i2d_x509", _wrap_i2d_x509, METH_VARARGS, NULL},
+ { (char *)"x509_req_write_pem", _wrap_x509_req_write_pem, METH_VARARGS, NULL},
+ { (char *)"x509_crl_read_pem", _wrap_x509_crl_read_pem, METH_VARARGS, NULL},
+ { (char *)"x509_set_version", _wrap_x509_set_version, METH_VARARGS, NULL},
+ { (char *)"x509_get_version", _wrap_x509_get_version, METH_VARARGS, NULL},
+ { (char *)"x509_set_not_before", _wrap_x509_set_not_before, METH_VARARGS, NULL},
+ { (char *)"x509_get_not_before", _wrap_x509_get_not_before, METH_VARARGS, NULL},
+ { (char *)"x509_set_not_after", _wrap_x509_set_not_after, METH_VARARGS, NULL},
+ { (char *)"x509_get_not_after", _wrap_x509_get_not_after, METH_VARARGS, NULL},
+ { (char *)"x509_sign", _wrap_x509_sign, METH_VARARGS, NULL},
+ { (char *)"x509_gmtime_adj", _wrap_x509_gmtime_adj, METH_VARARGS, NULL},
+ { (char *)"x509_name_by_nid", _wrap_x509_name_by_nid, METH_VARARGS, NULL},
+ { (char *)"x509_name_set_by_nid", _wrap_x509_name_set_by_nid, METH_VARARGS, NULL},
+ { (char *)"x509_name_add_entry_by_txt", _wrap_x509_name_add_entry_by_txt, METH_VARARGS, NULL},
+ { (char *)"x509_name_get_der", _wrap_x509_name_get_der, METH_VARARGS, NULL},
+ { (char *)"sk_x509_free", _wrap_sk_x509_free, METH_VARARGS, NULL},
+ { (char *)"sk_x509_push", _wrap_sk_x509_push, METH_VARARGS, NULL},
+ { (char *)"sk_x509_pop", _wrap_sk_x509_pop, METH_VARARGS, NULL},
+ { (char *)"x509_store_load_locations", _wrap_x509_store_load_locations, METH_VARARGS, NULL},
+ { (char *)"x509_type_check", _wrap_x509_type_check, METH_VARARGS, NULL},
+ { (char *)"x509_name_type_check", _wrap_x509_name_type_check, METH_VARARGS, NULL},
+ { (char *)"x509_req_get_subject_name", _wrap_x509_req_get_subject_name, METH_VARARGS, NULL},
+ { (char *)"x509_req_get_version", _wrap_x509_req_get_version, METH_VARARGS, NULL},
+ { (char *)"x509_req_set_version", _wrap_x509_req_set_version, METH_VARARGS, NULL},
+ { (char *)"x509_req_add_extensions", _wrap_x509_req_add_extensions, METH_VARARGS, NULL},
+ { (char *)"x509_name_entry_create_by_txt", _wrap_x509_name_entry_create_by_txt, METH_VARARGS, NULL},
+ { (char *)"x509v3_set_nconf", _wrap_x509v3_set_nconf, METH_VARARGS, NULL},
+ { (char *)"x509v3_ext_conf", _wrap_x509v3_ext_conf, METH_VARARGS, NULL},
+ { (char *)"x509_extension_free", _wrap_x509_extension_free, METH_VARARGS, NULL},
+ { (char *)"x509_extension_get_name", _wrap_x509_extension_get_name, METH_VARARGS, NULL},
+ { (char *)"sk_x509_extension_new_null", _wrap_sk_x509_extension_new_null, METH_VARARGS, NULL},
+ { (char *)"sk_x509_extension_free", _wrap_sk_x509_extension_free, METH_VARARGS, NULL},
+ { (char *)"sk_x509_extension_push", _wrap_sk_x509_extension_push, METH_VARARGS, NULL},
+ { (char *)"sk_x509_extension_pop", _wrap_sk_x509_extension_pop, METH_VARARGS, NULL},
+ { (char *)"sk_x509_extension_num", _wrap_sk_x509_extension_num, METH_VARARGS, NULL},
+ { (char *)"sk_x509_extension_value", _wrap_sk_x509_extension_value, METH_VARARGS, NULL},
+ { (char *)"x509_store_ctx_get_app_data", _wrap_x509_store_ctx_get_app_data, METH_VARARGS, NULL},
+ { (char *)"x509_store_ctx_get_ex_data", _wrap_x509_store_ctx_get_ex_data, METH_VARARGS, NULL},
+ { (char *)"x509_store_set_verify_cb", _wrap_x509_store_set_verify_cb, METH_VARARGS, NULL},
+ { (char *)"make_stack_from_der_sequence", _wrap_make_stack_from_der_sequence, METH_VARARGS, NULL},
+ { (char *)"sk_x509_new_null", _wrap_sk_x509_new_null, METH_VARARGS, NULL},
+ { (char *)"get_der_encoding_stack", _wrap_get_der_encoding_stack, METH_VARARGS, NULL},
+ { (char *)"x509_name_oneline", _wrap_x509_name_oneline, METH_VARARGS, NULL},
+ { (char *)"asn1_object_new", _wrap_asn1_object_new, METH_VARARGS, NULL},
+ { (char *)"asn1_object_create", _wrap_asn1_object_create, METH_VARARGS, NULL},
+ { (char *)"asn1_object_free", _wrap_asn1_object_free, METH_VARARGS, NULL},
+ { (char *)"i2d_asn1_object", _wrap_i2d_asn1_object, METH_VARARGS, NULL},
+ { (char *)"d2i_asn1_object", _wrap_d2i_asn1_object, METH_VARARGS, NULL},
+ { (char *)"asn1_bit_string_new", _wrap_asn1_bit_string_new, METH_VARARGS, NULL},
+ { (char *)"asn1_string_new", _wrap_asn1_string_new, METH_VARARGS, NULL},
+ { (char *)"asn1_string_free", _wrap_asn1_string_free, METH_VARARGS, NULL},
+ { (char *)"asn1_string_set", _wrap_asn1_string_set, METH_VARARGS, NULL},
+ { (char *)"asn1_string_print", _wrap_asn1_string_print, METH_VARARGS, NULL},
+ { (char *)"asn1_string_print_ex", _wrap_asn1_string_print_ex, METH_VARARGS, NULL},
+ { (char *)"asn1_time_new", _wrap_asn1_time_new, METH_VARARGS, NULL},
+ { (char *)"asn1_time_free", _wrap_asn1_time_free, METH_VARARGS, NULL},
+ { (char *)"asn1_time_check", _wrap_asn1_time_check, METH_VARARGS, NULL},
+ { (char *)"asn1_time_set", _wrap_asn1_time_set, METH_VARARGS, NULL},
+ { (char *)"asn1_time_set_string", _wrap_asn1_time_set_string, METH_VARARGS, NULL},
+ { (char *)"asn1_time_print", _wrap_asn1_time_print, METH_VARARGS, NULL},
+ { (char *)"asn1_integer_new", _wrap_asn1_integer_new, METH_VARARGS, NULL},
+ { (char *)"asn1_integer_free", _wrap_asn1_integer_free, METH_VARARGS, NULL},
+ { (char *)"asn1_integer_cmp", _wrap_asn1_integer_cmp, METH_VARARGS, NULL},
+ { (char *)"asn1_time_type_check", _wrap_asn1_time_type_check, METH_VARARGS, NULL},
+ { (char *)"asn1_integer_get", _wrap_asn1_integer_get, METH_VARARGS, NULL},
+ { (char *)"asn1_integer_set", _wrap_asn1_integer_set, METH_VARARGS, NULL},
+ { (char *)"pkcs7_new", _wrap_pkcs7_new, METH_VARARGS, NULL},
+ { (char *)"pkcs7_free", _wrap_pkcs7_free, METH_VARARGS, NULL},
+ { (char *)"pkcs7_add_certificate", _wrap_pkcs7_add_certificate, METH_VARARGS, NULL},
+ { (char *)"pkcs7_init", _wrap_pkcs7_init, METH_VARARGS, NULL},
+ { (char *)"smime_init", _wrap_smime_init, METH_VARARGS, NULL},
+ { (char *)"pkcs7_decrypt", _wrap_pkcs7_decrypt, METH_VARARGS, NULL},
+ { (char *)"pkcs7_encrypt", _wrap_pkcs7_encrypt, METH_VARARGS, NULL},
+ { (char *)"pkcs7_sign1", _wrap_pkcs7_sign1, METH_VARARGS, NULL},
+ { (char *)"pkcs7_sign0", _wrap_pkcs7_sign0, METH_VARARGS, NULL},
+ { (char *)"pkcs7_read_bio", _wrap_pkcs7_read_bio, METH_VARARGS, NULL},
+ { (char *)"pkcs7_read_bio_der", _wrap_pkcs7_read_bio_der, METH_VARARGS, NULL},
+ { (char *)"pkcs7_verify1", _wrap_pkcs7_verify1, METH_VARARGS, NULL},
+ { (char *)"pkcs7_verify0", _wrap_pkcs7_verify0, METH_VARARGS, NULL},
+ { (char *)"smime_write_pkcs7_multi", _wrap_smime_write_pkcs7_multi, METH_VARARGS, NULL},
+ { (char *)"smime_write_pkcs7", _wrap_smime_write_pkcs7, METH_VARARGS, NULL},
+ { (char *)"smime_read_pkcs7", _wrap_smime_read_pkcs7, METH_VARARGS, NULL},
+ { (char *)"pkcs7_write_bio", _wrap_pkcs7_write_bio, METH_VARARGS, NULL},
+ { (char *)"pkcs7_write_bio_der", _wrap_pkcs7_write_bio_der, METH_VARARGS, NULL},
+ { (char *)"pkcs7_type_nid", _wrap_pkcs7_type_nid, METH_VARARGS, NULL},
+ { (char *)"pkcs7_type_sn", _wrap_pkcs7_type_sn, METH_VARARGS, NULL},
+ { (char *)"smime_crlf_copy", _wrap_smime_crlf_copy, METH_VARARGS, NULL},
+ { (char *)"pkcs7_get0_signers", _wrap_pkcs7_get0_signers, METH_VARARGS, NULL},
+ { (char *)"util_init", _wrap_util_init, METH_VARARGS, NULL},
+ { (char *)"util_hex_to_string", _wrap_util_hex_to_string, METH_VARARGS, NULL},
+ { (char *)"util_string_to_hex", _wrap_util_string_to_hex, METH_VARARGS, NULL},
+ { (char *)"ec_key_new", _wrap_ec_key_new, METH_VARARGS, NULL},
+ { (char *)"ec_key_free", _wrap_ec_key_free, METH_VARARGS, NULL},
+ { (char *)"ec_key_size", _wrap_ec_key_size, METH_VARARGS, NULL},
+ { (char *)"ec_key_gen_key", _wrap_ec_key_gen_key, METH_VARARGS, NULL},
+ { (char *)"ec_key_check_key", _wrap_ec_key_check_key, METH_VARARGS, NULL},
+ { (char *)"ec_init", _wrap_ec_init, METH_VARARGS, NULL},
+ { (char *)"ec_get_builtin_curves", _wrap_ec_get_builtin_curves, METH_VARARGS, NULL},
+ { (char *)"ec_key_new_by_curve_name", _wrap_ec_key_new_by_curve_name, METH_VARARGS, NULL},
+ { (char *)"ec_key_get_public_der", _wrap_ec_key_get_public_der, METH_VARARGS, NULL},
+ { (char *)"ec_key_get_public_key", _wrap_ec_key_get_public_key, METH_VARARGS, NULL},
+ { (char *)"ec_key_read_pubkey", _wrap_ec_key_read_pubkey, METH_VARARGS, NULL},
+ { (char *)"ec_key_write_pubkey", _wrap_ec_key_write_pubkey, METH_VARARGS, NULL},
+ { (char *)"ec_key_read_bio", _wrap_ec_key_read_bio, METH_VARARGS, NULL},
+ { (char *)"ec_key_write_bio", _wrap_ec_key_write_bio, METH_VARARGS, NULL},
+ { (char *)"ec_key_write_bio_no_cipher", _wrap_ec_key_write_bio_no_cipher, METH_VARARGS, NULL},
+ { (char *)"ecdsa_sig_get_r", _wrap_ecdsa_sig_get_r, METH_VARARGS, NULL},
+ { (char *)"ecdsa_sig_get_s", _wrap_ecdsa_sig_get_s, METH_VARARGS, NULL},
+ { (char *)"ecdsa_sign", _wrap_ecdsa_sign, METH_VARARGS, NULL},
+ { (char *)"ecdsa_verify", _wrap_ecdsa_verify, METH_VARARGS, NULL},
+ { (char *)"ecdsa_sign_asn1", _wrap_ecdsa_sign_asn1, METH_VARARGS, NULL},
+ { (char *)"ecdsa_verify_asn1", _wrap_ecdsa_verify_asn1, METH_VARARGS, NULL},
+ { (char *)"ecdh_compute_key", _wrap_ecdh_compute_key, METH_VARARGS, NULL},
+ { (char *)"ec_key_from_pubkey_der", _wrap_ec_key_from_pubkey_der, METH_VARARGS, NULL},
+ { (char *)"ec_key_from_pubkey_params", _wrap_ec_key_from_pubkey_params, METH_VARARGS, NULL},
+ { (char *)"ec_key_keylen", _wrap_ec_key_keylen, METH_VARARGS, NULL},
+ { (char *)"ec_key_type_check", _wrap_ec_key_type_check, METH_VARARGS, NULL},
+ { (char *)"engine_load_builtin_engines", _wrap_engine_load_builtin_engines, METH_VARARGS, NULL},
+ { (char *)"engine_load_dynamic", _wrap_engine_load_dynamic, METH_VARARGS, NULL},
+ { (char *)"engine_load_openssl", _wrap_engine_load_openssl, METH_VARARGS, NULL},
+ { (char *)"engine_cleanup", _wrap_engine_cleanup, METH_VARARGS, NULL},
+ { (char *)"engine_new", _wrap_engine_new, METH_VARARGS, NULL},
+ { (char *)"engine_by_id", _wrap_engine_by_id, METH_VARARGS, NULL},
+ { (char *)"engine_free", _wrap_engine_free, METH_VARARGS, NULL},
+ { (char *)"engine_init", _wrap_engine_init, METH_VARARGS, NULL},
+ { (char *)"engine_finish", _wrap_engine_finish, METH_VARARGS, NULL},
+ { (char *)"engine_get_id", _wrap_engine_get_id, METH_VARARGS, NULL},
+ { (char *)"engine_get_name", _wrap_engine_get_name, METH_VARARGS, NULL},
+ { (char *)"engine_ctrl_cmd_string", _wrap_engine_ctrl_cmd_string, METH_VARARGS, NULL},
+ { (char *)"ui_openssl", _wrap_ui_openssl, METH_VARARGS, NULL},
+ { (char *)"engine_pkcs11_data_new", _wrap_engine_pkcs11_data_new, METH_VARARGS, NULL},
+ { (char *)"engine_pkcs11_data_free", _wrap_engine_pkcs11_data_free, METH_VARARGS, NULL},
+ { (char *)"engine_load_private_key", _wrap_engine_load_private_key, METH_VARARGS, NULL},
+ { (char *)"engine_load_public_key", _wrap_engine_load_public_key, METH_VARARGS, NULL},
+ { (char *)"engine_init_error", _wrap_engine_init_error, METH_VARARGS, NULL},
+ { (char *)"engine_load_certificate", _wrap_engine_load_certificate, METH_VARARGS, NULL},
+ { (char *)"engine_set_default", _wrap_engine_set_default, METH_VARARGS, NULL},
+ { (char *)"obj_nid2obj", _wrap_obj_nid2obj, METH_VARARGS, NULL},
+ { (char *)"obj_nid2ln", _wrap_obj_nid2ln, METH_VARARGS, NULL},
+ { (char *)"obj_nid2sn", _wrap_obj_nid2sn, METH_VARARGS, NULL},
+ { (char *)"obj_obj2nid", _wrap_obj_obj2nid, METH_VARARGS, NULL},
+ { (char *)"obj_ln2nid", _wrap_obj_ln2nid, METH_VARARGS, NULL},
+ { (char *)"obj_sn2nid", _wrap_obj_sn2nid, METH_VARARGS, NULL},
+ { (char *)"obj_txt2nid", _wrap_obj_txt2nid, METH_VARARGS, NULL},
+ { (char *)"obj_txt2obj", _wrap_obj_txt2obj, METH_VARARGS, NULL},
+ { (char *)"_obj_obj2txt", _wrap__obj_obj2txt, METH_VARARGS, NULL},
+ { (char *)"obj_obj2txt", _wrap_obj_obj2txt, METH_VARARGS, NULL},
+ { NULL, NULL, 0, NULL }
+};
+
+SWIGPY_DESTRUCTOR_CLOSURE(_wrap_delete__STACK)
+static SwigPyGetSet _STACK_num_alloc_getset = { _wrap__STACK_num_alloc_get, _wrap__STACK_num_alloc_set };
+static SwigPyGetSet _STACK_data_getset = { _wrap__STACK_data_get, _wrap__STACK_data_set };
+static SwigPyGetSet _STACK_comp_getset = { _wrap__STACK_comp_get, _wrap__STACK_comp_set };
+static SwigPyGetSet _STACK_sorted_getset = { _wrap__STACK_sorted_get, _wrap__STACK_sorted_set };
+static SwigPyGetSet _STACK_num_getset = { _wrap__STACK_num_get, _wrap__STACK_num_set };
+SWIGINTERN PyGetSetDef SwigPyBuiltin__stack_st_getset[] = {
+ { (char*) "num_alloc", (getter) SwigPyBuiltin_GetterClosure, (setter) SwigPyBuiltin_SetterClosure, (char*)"stack_st.num_alloc", (void*) &_STACK_num_alloc_getset }
+,
+ { (char*) "data", (getter) SwigPyBuiltin_GetterClosure, (setter) SwigPyBuiltin_SetterClosure, (char*)"stack_st.data", (void*) &_STACK_data_getset }
+,
+ { (char*) "comp", (getter) SwigPyBuiltin_GetterClosure, (setter) SwigPyBuiltin_SetterClosure, (char*)"stack_st.comp", (void*) &_STACK_comp_getset }
+,
+ { (char*) "sorted", (getter) SwigPyBuiltin_GetterClosure, (setter) SwigPyBuiltin_SetterClosure, (char*)"stack_st.sorted", (void*) &_STACK_sorted_getset }
+,
+ { (char*) "num", (getter) SwigPyBuiltin_GetterClosure, (setter) SwigPyBuiltin_SetterClosure, (char*)"stack_st.num", (void*) &_STACK_num_getset }
+,
+ {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
+};
+
+SWIGINTERN PyObject *
+SwigPyBuiltin__stack_st_richcompare(PyObject *self, PyObject *other, int op) {
+ PyObject *result = NULL;
+ PyObject *tuple = PyTuple_New(1);
+ assert(tuple);
+ PyTuple_SET_ITEM(tuple, 0, other);
+ Py_XINCREF(other);
+ if (!result) {
+ if (SwigPyObject_Check(self) && SwigPyObject_Check(other)) {
+ result = SwigPyObject_richcompare((SwigPyObject *)self, (SwigPyObject *)other, op);
+ } else {
+ result = Py_NotImplemented;
+ Py_INCREF(result);
+ }
+ }
+ Py_DECREF(tuple);
+ return result;
+}
+
+SWIGINTERN PyMethodDef SwigPyBuiltin__stack_st_methods[] = {
+ { NULL, NULL, 0, NULL } /* Sentinel */
+};
+
+static PyHeapTypeObject SwigPyBuiltin__stack_st_type = {
+ {
+#if PY_VERSION_HEX >= 0x03000000
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+#endif
+ "_STACK", /* tp_name */
+ sizeof(SwigPyObject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor) _wrap_delete__STACK_closure, /* tp_dealloc */
+ (printfunc) 0, /* tp_print */
+ (getattrfunc) 0, /* tp_getattr */
+ (setattrfunc) 0, /* tp_setattr */
+#if PY_VERSION_HEX >= 0x03000000
+ 0, /* tp_compare */
+#else
+ (cmpfunc) 0, /* tp_compare */
+#endif
+ (reprfunc) 0, /* tp_repr */
+ &SwigPyBuiltin__stack_st_type.as_number, /* tp_as_number */
+ &SwigPyBuiltin__stack_st_type.as_sequence, /* tp_as_sequence */
+ &SwigPyBuiltin__stack_st_type.as_mapping, /* tp_as_mapping */
+ (hashfunc) 0, /* tp_hash */
+ (ternaryfunc) 0, /* tp_call */
+ (reprfunc) 0, /* tp_str */
+ (getattrofunc) 0, /* tp_getattro */
+ (setattrofunc) 0, /* tp_setattro */
+ &SwigPyBuiltin__stack_st_type.as_buffer, /* tp_as_buffer */
+#if PY_VERSION_HEX >= 0x03000000
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+#else
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_CHECKTYPES, /* tp_flags */
+#endif
+ "::stack_st", /* tp_doc */
+ (traverseproc) 0, /* tp_traverse */
+ (inquiry) 0, /* tp_clear */
+ (richcmpfunc) SwigPyBuiltin__stack_st_richcompare, /* feature:python:tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ (getiterfunc) 0, /* tp_iter */
+ (iternextfunc) 0, /* tp_iternext */
+ SwigPyBuiltin__stack_st_methods, /* tp_methods */
+ 0, /* tp_members */
+ SwigPyBuiltin__stack_st_getset, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ (descrgetfunc) 0, /* tp_descr_get */
+ (descrsetfunc) 0, /* tp_descr_set */
+ (size_t)(((char*)&((SwigPyObject *) 64L)->dict) - (char*) 64L), /* tp_dictoffset */
+ (initproc) _wrap_new__STACK, /* tp_init */
+ (allocfunc) 0, /* tp_alloc */
+ (newfunc) 0, /* tp_new */
+ (freefunc) 0, /* tp_free */
+ (inquiry) 0, /* tp_is_gc */
+ (PyObject*) 0, /* tp_bases */
+ (PyObject*) 0, /* tp_mro */
+ (PyObject*) 0, /* tp_cache */
+ (PyObject*) 0, /* tp_subclasses */
+ (PyObject*) 0, /* tp_weaklist */
+ (destructor) 0, /* tp_del */
+#if PY_VERSION_HEX >= 0x02060000
+ (int) 0, /* tp_version_tag */
+#endif
+ },
+ {
+ (binaryfunc) 0, /* nb_add */
+ (binaryfunc) 0, /* nb_subtract */
+ (binaryfunc) 0, /* nb_multiply */
+#if PY_VERSION_HEX < 0x03000000
+ (binaryfunc) 0, /* nb_divide */
+#endif
+ (binaryfunc) 0, /* nb_remainder */
+ (binaryfunc) 0, /* nb_divmod */
+ (ternaryfunc) 0, /* nb_power */
+ (unaryfunc) 0, /* nb_negative */
+ (unaryfunc) 0, /* nb_positive */
+ (unaryfunc) 0, /* nb_absolute */
+ (inquiry) 0, /* nb_nonzero */
+ (unaryfunc) 0, /* nb_invert */
+ (binaryfunc) 0, /* nb_lshift */
+ (binaryfunc) 0, /* nb_rshift */
+ (binaryfunc) 0, /* nb_and */
+ (binaryfunc) 0, /* nb_xor */
+ (binaryfunc) 0, /* nb_or */
+#if PY_VERSION_HEX < 0x03000000
+ (coercion) 0, /* nb_coerce */
+#endif
+ (unaryfunc) 0, /* nb_int */
+#if PY_VERSION_HEX >= 0x03000000
+ (void*) 0, /* nb_reserved */
+#else
+ (unaryfunc) 0, /* nb_long */
+#endif
+ (unaryfunc) 0, /* nb_float */
+#if PY_VERSION_HEX < 0x03000000
+ (unaryfunc) 0, /* nb_oct */
+ (unaryfunc) 0, /* nb_hex */
+#endif
+ (binaryfunc) 0, /* nb_inplace_add */
+ (binaryfunc) 0, /* nb_inplace_subtract */
+ (binaryfunc) 0, /* nb_inplace_multiply */
+#if PY_VERSION_HEX < 0x03000000
+ (binaryfunc) 0, /* nb_inplace_divide */
+#endif
+ (binaryfunc) 0, /* nb_inplace_remainder */
+ (ternaryfunc) 0, /* nb_inplace_power */
+ (binaryfunc) 0, /* nb_inplace_lshift */
+ (binaryfunc) 0, /* nb_inplace_rshift */
+ (binaryfunc) 0, /* nb_inplace_and */
+ (binaryfunc) 0, /* nb_inplace_xor */
+ (binaryfunc) 0, /* nb_inplace_or */
+ (binaryfunc) 0, /* nb_floor_divide */
+ (binaryfunc) 0, /* nb_true_divide */
+ (binaryfunc) 0, /* nb_inplace_floor_divide */
+ (binaryfunc) 0, /* nb_inplace_true_divide */
+#if PY_VERSION_HEX >= 0x02050000
+ (unaryfunc) 0, /* nb_index */
+#endif
+ },
+ {
+ (lenfunc) 0, /* mp_length */
+ (binaryfunc) 0, /* mp_subscript */
+ (objobjargproc) 0, /* mp_ass_subscript */
+ },
+ {
+ (lenfunc) 0, /* sq_length */
+ (binaryfunc) 0, /* sq_concat */
+ (ssizeargfunc) 0, /* sq_repeat */
+ (ssizeargfunc) 0, /* sq_item */
+#if PY_VERSION_HEX >= 0x03000000
+ (void*) 0, /* was_sq_slice */
+#else
+ (ssizessizeargfunc) 0, /* sq_slice */
+#endif
+ (ssizeobjargproc) 0, /* sq_ass_item */
+#if PY_VERSION_HEX >= 0x03000000
+ (void*) 0, /* was_sq_ass_slice */
+#else
+ (ssizessizeobjargproc) 0, /* sq_ass_slice */
+#endif
+ (objobjproc) 0, /* sq_contains */
+ (binaryfunc) 0, /* sq_inplace_concat */
+ (ssizeargfunc) 0, /* sq_inplace_repeat */
+ },
+ {
+#if PY_VERSION_HEX < 0x03000000
+ (readbufferproc) 0, /* bf_getreadbuffer */
+ (writebufferproc) 0, /* bf_getwritebuffer */
+ (segcountproc) 0, /* bf_getsegcount */
+ (charbufferproc) 0, /* bf_getcharbuffer */
+#endif
+#if PY_VERSION_HEX >= 0x02060000
+ (getbufferproc) 0, /* bf_getbuffer */
+ (releasebufferproc) 0, /* bf_releasebuffer */
+#endif
+ },
+ (PyObject*) 0, /* ht_name */
+ (PyObject*) 0, /* ht_slots */
+};
+
+SWIGINTERN SwigPyClientData SwigPyBuiltin__stack_st_clientdata = {0, 0, 0, 0, 0, 0, (PyTypeObject *)&SwigPyBuiltin__stack_st_type};
+
+SWIGPY_DESTRUCTOR_CLOSURE(_wrap_delete_stack_st_OPENSSL_STRING)
+static SwigPyGetSet stack_st_OPENSSL_STRING_stack_getset = { _wrap_stack_st_OPENSSL_STRING_stack_get, _wrap_stack_st_OPENSSL_STRING_stack_set };
+SWIGINTERN PyGetSetDef SwigPyBuiltin__stack_st_OPENSSL_STRING_getset[] = {
+ { (char*) "stack", (getter) SwigPyBuiltin_GetterClosure, (setter) SwigPyBuiltin_SetterClosure, (char*)"stack_st_OPENSSL_STRING.stack", (void*) &stack_st_OPENSSL_STRING_stack_getset }
+,
+ {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
+};
+
+SWIGINTERN PyObject *
+SwigPyBuiltin__stack_st_OPENSSL_STRING_richcompare(PyObject *self, PyObject *other, int op) {
+ PyObject *result = NULL;
+ PyObject *tuple = PyTuple_New(1);
+ assert(tuple);
+ PyTuple_SET_ITEM(tuple, 0, other);
+ Py_XINCREF(other);
+ if (!result) {
+ if (SwigPyObject_Check(self) && SwigPyObject_Check(other)) {
+ result = SwigPyObject_richcompare((SwigPyObject *)self, (SwigPyObject *)other, op);
+ } else {
+ result = Py_NotImplemented;
+ Py_INCREF(result);
+ }
+ }
+ Py_DECREF(tuple);
+ return result;
+}
+
+SWIGINTERN PyMethodDef SwigPyBuiltin__stack_st_OPENSSL_STRING_methods[] = {
+ { NULL, NULL, 0, NULL } /* Sentinel */
+};
+
+static PyHeapTypeObject SwigPyBuiltin__stack_st_OPENSSL_STRING_type = {
+ {
+#if PY_VERSION_HEX >= 0x03000000
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+#endif
+ "stack_st_OPENSSL_STRING", /* tp_name */
+ sizeof(SwigPyObject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor) _wrap_delete_stack_st_OPENSSL_STRING_closure, /* tp_dealloc */
+ (printfunc) 0, /* tp_print */
+ (getattrfunc) 0, /* tp_getattr */
+ (setattrfunc) 0, /* tp_setattr */
+#if PY_VERSION_HEX >= 0x03000000
+ 0, /* tp_compare */
+#else
+ (cmpfunc) 0, /* tp_compare */
+#endif
+ (reprfunc) 0, /* tp_repr */
+ &SwigPyBuiltin__stack_st_OPENSSL_STRING_type.as_number, /* tp_as_number */
+ &SwigPyBuiltin__stack_st_OPENSSL_STRING_type.as_sequence, /* tp_as_sequence */
+ &SwigPyBuiltin__stack_st_OPENSSL_STRING_type.as_mapping, /* tp_as_mapping */
+ (hashfunc) 0, /* tp_hash */
+ (ternaryfunc) 0, /* tp_call */
+ (reprfunc) 0, /* tp_str */
+ (getattrofunc) 0, /* tp_getattro */
+ (setattrofunc) 0, /* tp_setattro */
+ &SwigPyBuiltin__stack_st_OPENSSL_STRING_type.as_buffer, /* tp_as_buffer */
+#if PY_VERSION_HEX >= 0x03000000
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+#else
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_CHECKTYPES, /* tp_flags */
+#endif
+ "::stack_st_OPENSSL_STRING", /* tp_doc */
+ (traverseproc) 0, /* tp_traverse */
+ (inquiry) 0, /* tp_clear */
+ (richcmpfunc) SwigPyBuiltin__stack_st_OPENSSL_STRING_richcompare, /* feature:python:tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ (getiterfunc) 0, /* tp_iter */
+ (iternextfunc) 0, /* tp_iternext */
+ SwigPyBuiltin__stack_st_OPENSSL_STRING_methods, /* tp_methods */
+ 0, /* tp_members */
+ SwigPyBuiltin__stack_st_OPENSSL_STRING_getset, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ (descrgetfunc) 0, /* tp_descr_get */
+ (descrsetfunc) 0, /* tp_descr_set */
+ (size_t)(((char*)&((SwigPyObject *) 64L)->dict) - (char*) 64L), /* tp_dictoffset */
+ (initproc) _wrap_new_stack_st_OPENSSL_STRING, /* tp_init */
+ (allocfunc) 0, /* tp_alloc */
+ (newfunc) 0, /* tp_new */
+ (freefunc) 0, /* tp_free */
+ (inquiry) 0, /* tp_is_gc */
+ (PyObject*) 0, /* tp_bases */
+ (PyObject*) 0, /* tp_mro */
+ (PyObject*) 0, /* tp_cache */
+ (PyObject*) 0, /* tp_subclasses */
+ (PyObject*) 0, /* tp_weaklist */
+ (destructor) 0, /* tp_del */
+#if PY_VERSION_HEX >= 0x02060000
+ (int) 0, /* tp_version_tag */
+#endif
+ },
+ {
+ (binaryfunc) 0, /* nb_add */
+ (binaryfunc) 0, /* nb_subtract */
+ (binaryfunc) 0, /* nb_multiply */
+#if PY_VERSION_HEX < 0x03000000
+ (binaryfunc) 0, /* nb_divide */
+#endif
+ (binaryfunc) 0, /* nb_remainder */
+ (binaryfunc) 0, /* nb_divmod */
+ (ternaryfunc) 0, /* nb_power */
+ (unaryfunc) 0, /* nb_negative */
+ (unaryfunc) 0, /* nb_positive */
+ (unaryfunc) 0, /* nb_absolute */
+ (inquiry) 0, /* nb_nonzero */
+ (unaryfunc) 0, /* nb_invert */
+ (binaryfunc) 0, /* nb_lshift */
+ (binaryfunc) 0, /* nb_rshift */
+ (binaryfunc) 0, /* nb_and */
+ (binaryfunc) 0, /* nb_xor */
+ (binaryfunc) 0, /* nb_or */
+#if PY_VERSION_HEX < 0x03000000
+ (coercion) 0, /* nb_coerce */
+#endif
+ (unaryfunc) 0, /* nb_int */
+#if PY_VERSION_HEX >= 0x03000000
+ (void*) 0, /* nb_reserved */
+#else
+ (unaryfunc) 0, /* nb_long */
+#endif
+ (unaryfunc) 0, /* nb_float */
+#if PY_VERSION_HEX < 0x03000000
+ (unaryfunc) 0, /* nb_oct */
+ (unaryfunc) 0, /* nb_hex */
+#endif
+ (binaryfunc) 0, /* nb_inplace_add */
+ (binaryfunc) 0, /* nb_inplace_subtract */
+ (binaryfunc) 0, /* nb_inplace_multiply */
+#if PY_VERSION_HEX < 0x03000000
+ (binaryfunc) 0, /* nb_inplace_divide */
+#endif
+ (binaryfunc) 0, /* nb_inplace_remainder */
+ (ternaryfunc) 0, /* nb_inplace_power */
+ (binaryfunc) 0, /* nb_inplace_lshift */
+ (binaryfunc) 0, /* nb_inplace_rshift */
+ (binaryfunc) 0, /* nb_inplace_and */
+ (binaryfunc) 0, /* nb_inplace_xor */
+ (binaryfunc) 0, /* nb_inplace_or */
+ (binaryfunc) 0, /* nb_floor_divide */
+ (binaryfunc) 0, /* nb_true_divide */
+ (binaryfunc) 0, /* nb_inplace_floor_divide */
+ (binaryfunc) 0, /* nb_inplace_true_divide */
+#if PY_VERSION_HEX >= 0x02050000
+ (unaryfunc) 0, /* nb_index */
+#endif
+ },
+ {
+ (lenfunc) 0, /* mp_length */
+ (binaryfunc) 0, /* mp_subscript */
+ (objobjargproc) 0, /* mp_ass_subscript */
+ },
+ {
+ (lenfunc) 0, /* sq_length */
+ (binaryfunc) 0, /* sq_concat */
+ (ssizeargfunc) 0, /* sq_repeat */
+ (ssizeargfunc) 0, /* sq_item */
+#if PY_VERSION_HEX >= 0x03000000
+ (void*) 0, /* was_sq_slice */
+#else
+ (ssizessizeargfunc) 0, /* sq_slice */
+#endif
+ (ssizeobjargproc) 0, /* sq_ass_item */
+#if PY_VERSION_HEX >= 0x03000000
+ (void*) 0, /* was_sq_ass_slice */
+#else
+ (ssizessizeobjargproc) 0, /* sq_ass_slice */
+#endif
+ (objobjproc) 0, /* sq_contains */
+ (binaryfunc) 0, /* sq_inplace_concat */
+ (ssizeargfunc) 0, /* sq_inplace_repeat */
+ },
+ {
+#if PY_VERSION_HEX < 0x03000000
+ (readbufferproc) 0, /* bf_getreadbuffer */
+ (writebufferproc) 0, /* bf_getwritebuffer */
+ (segcountproc) 0, /* bf_getsegcount */
+ (charbufferproc) 0, /* bf_getcharbuffer */
+#endif
+#if PY_VERSION_HEX >= 0x02060000
+ (getbufferproc) 0, /* bf_getbuffer */
+ (releasebufferproc) 0, /* bf_releasebuffer */
+#endif
+ },
+ (PyObject*) 0, /* ht_name */
+ (PyObject*) 0, /* ht_slots */
+};
+
+SWIGINTERN SwigPyClientData SwigPyBuiltin__stack_st_OPENSSL_STRING_clientdata = {0, 0, 0, 0, 0, 0, (PyTypeObject *)&SwigPyBuiltin__stack_st_OPENSSL_STRING_type};
+
+SWIGPY_DESTRUCTOR_CLOSURE(_wrap_delete_stack_st_OPENSSL_BLOCK)
+static SwigPyGetSet stack_st_OPENSSL_BLOCK_stack_getset = { _wrap_stack_st_OPENSSL_BLOCK_stack_get, _wrap_stack_st_OPENSSL_BLOCK_stack_set };
+SWIGINTERN PyGetSetDef SwigPyBuiltin__stack_st_OPENSSL_BLOCK_getset[] = {
+ { (char*) "stack", (getter) SwigPyBuiltin_GetterClosure, (setter) SwigPyBuiltin_SetterClosure, (char*)"stack_st_OPENSSL_BLOCK.stack", (void*) &stack_st_OPENSSL_BLOCK_stack_getset }
+,
+ {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
+};
+
+SWIGINTERN PyObject *
+SwigPyBuiltin__stack_st_OPENSSL_BLOCK_richcompare(PyObject *self, PyObject *other, int op) {
+ PyObject *result = NULL;
+ PyObject *tuple = PyTuple_New(1);
+ assert(tuple);
+ PyTuple_SET_ITEM(tuple, 0, other);
+ Py_XINCREF(other);
+ if (!result) {
+ if (SwigPyObject_Check(self) && SwigPyObject_Check(other)) {
+ result = SwigPyObject_richcompare((SwigPyObject *)self, (SwigPyObject *)other, op);
+ } else {
+ result = Py_NotImplemented;
+ Py_INCREF(result);
+ }
+ }
+ Py_DECREF(tuple);
+ return result;
+}
+
+SWIGINTERN PyMethodDef SwigPyBuiltin__stack_st_OPENSSL_BLOCK_methods[] = {
+ { NULL, NULL, 0, NULL } /* Sentinel */
+};
+
+static PyHeapTypeObject SwigPyBuiltin__stack_st_OPENSSL_BLOCK_type = {
+ {
+#if PY_VERSION_HEX >= 0x03000000
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+#endif
+ "stack_st_OPENSSL_BLOCK", /* tp_name */
+ sizeof(SwigPyObject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor) _wrap_delete_stack_st_OPENSSL_BLOCK_closure, /* tp_dealloc */
+ (printfunc) 0, /* tp_print */
+ (getattrfunc) 0, /* tp_getattr */
+ (setattrfunc) 0, /* tp_setattr */
+#if PY_VERSION_HEX >= 0x03000000
+ 0, /* tp_compare */
+#else
+ (cmpfunc) 0, /* tp_compare */
+#endif
+ (reprfunc) 0, /* tp_repr */
+ &SwigPyBuiltin__stack_st_OPENSSL_BLOCK_type.as_number, /* tp_as_number */
+ &SwigPyBuiltin__stack_st_OPENSSL_BLOCK_type.as_sequence, /* tp_as_sequence */
+ &SwigPyBuiltin__stack_st_OPENSSL_BLOCK_type.as_mapping, /* tp_as_mapping */
+ (hashfunc) 0, /* tp_hash */
+ (ternaryfunc) 0, /* tp_call */
+ (reprfunc) 0, /* tp_str */
+ (getattrofunc) 0, /* tp_getattro */
+ (setattrofunc) 0, /* tp_setattro */
+ &SwigPyBuiltin__stack_st_OPENSSL_BLOCK_type.as_buffer, /* tp_as_buffer */
+#if PY_VERSION_HEX >= 0x03000000
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+#else
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_CHECKTYPES, /* tp_flags */
+#endif
+ "::stack_st_OPENSSL_BLOCK", /* tp_doc */
+ (traverseproc) 0, /* tp_traverse */
+ (inquiry) 0, /* tp_clear */
+ (richcmpfunc) SwigPyBuiltin__stack_st_OPENSSL_BLOCK_richcompare, /* feature:python:tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ (getiterfunc) 0, /* tp_iter */
+ (iternextfunc) 0, /* tp_iternext */
+ SwigPyBuiltin__stack_st_OPENSSL_BLOCK_methods, /* tp_methods */
+ 0, /* tp_members */
+ SwigPyBuiltin__stack_st_OPENSSL_BLOCK_getset, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ (descrgetfunc) 0, /* tp_descr_get */
+ (descrsetfunc) 0, /* tp_descr_set */
+ (size_t)(((char*)&((SwigPyObject *) 64L)->dict) - (char*) 64L), /* tp_dictoffset */
+ (initproc) _wrap_new_stack_st_OPENSSL_BLOCK, /* tp_init */
+ (allocfunc) 0, /* tp_alloc */
+ (newfunc) 0, /* tp_new */
+ (freefunc) 0, /* tp_free */
+ (inquiry) 0, /* tp_is_gc */
+ (PyObject*) 0, /* tp_bases */
+ (PyObject*) 0, /* tp_mro */
+ (PyObject*) 0, /* tp_cache */
+ (PyObject*) 0, /* tp_subclasses */
+ (PyObject*) 0, /* tp_weaklist */
+ (destructor) 0, /* tp_del */
+#if PY_VERSION_HEX >= 0x02060000
+ (int) 0, /* tp_version_tag */
+#endif
+ },
+ {
+ (binaryfunc) 0, /* nb_add */
+ (binaryfunc) 0, /* nb_subtract */
+ (binaryfunc) 0, /* nb_multiply */
+#if PY_VERSION_HEX < 0x03000000
+ (binaryfunc) 0, /* nb_divide */
+#endif
+ (binaryfunc) 0, /* nb_remainder */
+ (binaryfunc) 0, /* nb_divmod */
+ (ternaryfunc) 0, /* nb_power */
+ (unaryfunc) 0, /* nb_negative */
+ (unaryfunc) 0, /* nb_positive */
+ (unaryfunc) 0, /* nb_absolute */
+ (inquiry) 0, /* nb_nonzero */
+ (unaryfunc) 0, /* nb_invert */
+ (binaryfunc) 0, /* nb_lshift */
+ (binaryfunc) 0, /* nb_rshift */
+ (binaryfunc) 0, /* nb_and */
+ (binaryfunc) 0, /* nb_xor */
+ (binaryfunc) 0, /* nb_or */
+#if PY_VERSION_HEX < 0x03000000
+ (coercion) 0, /* nb_coerce */
+#endif
+ (unaryfunc) 0, /* nb_int */
+#if PY_VERSION_HEX >= 0x03000000
+ (void*) 0, /* nb_reserved */
+#else
+ (unaryfunc) 0, /* nb_long */
+#endif
+ (unaryfunc) 0, /* nb_float */
+#if PY_VERSION_HEX < 0x03000000
+ (unaryfunc) 0, /* nb_oct */
+ (unaryfunc) 0, /* nb_hex */
+#endif
+ (binaryfunc) 0, /* nb_inplace_add */
+ (binaryfunc) 0, /* nb_inplace_subtract */
+ (binaryfunc) 0, /* nb_inplace_multiply */
+#if PY_VERSION_HEX < 0x03000000
+ (binaryfunc) 0, /* nb_inplace_divide */
+#endif
+ (binaryfunc) 0, /* nb_inplace_remainder */
+ (ternaryfunc) 0, /* nb_inplace_power */
+ (binaryfunc) 0, /* nb_inplace_lshift */
+ (binaryfunc) 0, /* nb_inplace_rshift */
+ (binaryfunc) 0, /* nb_inplace_and */
+ (binaryfunc) 0, /* nb_inplace_xor */
+ (binaryfunc) 0, /* nb_inplace_or */
+ (binaryfunc) 0, /* nb_floor_divide */
+ (binaryfunc) 0, /* nb_true_divide */
+ (binaryfunc) 0, /* nb_inplace_floor_divide */
+ (binaryfunc) 0, /* nb_inplace_true_divide */
+#if PY_VERSION_HEX >= 0x02050000
+ (unaryfunc) 0, /* nb_index */
+#endif
+ },
+ {
+ (lenfunc) 0, /* mp_length */
+ (binaryfunc) 0, /* mp_subscript */
+ (objobjargproc) 0, /* mp_ass_subscript */
+ },
+ {
+ (lenfunc) 0, /* sq_length */
+ (binaryfunc) 0, /* sq_concat */
+ (ssizeargfunc) 0, /* sq_repeat */
+ (ssizeargfunc) 0, /* sq_item */
+#if PY_VERSION_HEX >= 0x03000000
+ (void*) 0, /* was_sq_slice */
+#else
+ (ssizessizeargfunc) 0, /* sq_slice */
+#endif
+ (ssizeobjargproc) 0, /* sq_ass_item */
+#if PY_VERSION_HEX >= 0x03000000
+ (void*) 0, /* was_sq_ass_slice */
+#else
+ (ssizessizeobjargproc) 0, /* sq_ass_slice */
+#endif
+ (objobjproc) 0, /* sq_contains */
+ (binaryfunc) 0, /* sq_inplace_concat */
+ (ssizeargfunc) 0, /* sq_inplace_repeat */
+ },
+ {
+#if PY_VERSION_HEX < 0x03000000
+ (readbufferproc) 0, /* bf_getreadbuffer */
+ (writebufferproc) 0, /* bf_getwritebuffer */
+ (segcountproc) 0, /* bf_getsegcount */
+ (charbufferproc) 0, /* bf_getcharbuffer */
+#endif
+#if PY_VERSION_HEX >= 0x02060000
+ (getbufferproc) 0, /* bf_getbuffer */
+ (releasebufferproc) 0, /* bf_releasebuffer */
+#endif
+ },
+ (PyObject*) 0, /* ht_name */
+ (PyObject*) 0, /* ht_slots */
+};
+
+SWIGINTERN SwigPyClientData SwigPyBuiltin__stack_st_OPENSSL_BLOCK_clientdata = {0, 0, 0, 0, 0, 0, (PyTypeObject *)&SwigPyBuiltin__stack_st_OPENSSL_BLOCK_type};
+
+SWIGPY_DESTRUCTOR_CLOSURE(_wrap_delete_BIO_PYFD_CTX)
+static SwigPyGetSet BIO_PYFD_CTX_fd_getset = { _wrap_BIO_PYFD_CTX_fd_get, _wrap_BIO_PYFD_CTX_fd_set };
+SWIGINTERN PyGetSetDef SwigPyBuiltin__pyfd_struct_getset[] = {
+ { (char*) "fd", (getter) SwigPyBuiltin_GetterClosure, (setter) SwigPyBuiltin_SetterClosure, (char*)"pyfd_struct.fd", (void*) &BIO_PYFD_CTX_fd_getset }
+,
+ {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
+};
+
+SWIGINTERN PyObject *
+SwigPyBuiltin__pyfd_struct_richcompare(PyObject *self, PyObject *other, int op) {
+ PyObject *result = NULL;
+ PyObject *tuple = PyTuple_New(1);
+ assert(tuple);
+ PyTuple_SET_ITEM(tuple, 0, other);
+ Py_XINCREF(other);
+ if (!result) {
+ if (SwigPyObject_Check(self) && SwigPyObject_Check(other)) {
+ result = SwigPyObject_richcompare((SwigPyObject *)self, (SwigPyObject *)other, op);
+ } else {
+ result = Py_NotImplemented;
+ Py_INCREF(result);
+ }
+ }
+ Py_DECREF(tuple);
+ return result;
+}
+
+SWIGINTERN PyMethodDef SwigPyBuiltin__pyfd_struct_methods[] = {
+ { NULL, NULL, 0, NULL } /* Sentinel */
+};
+
+static PyHeapTypeObject SwigPyBuiltin__pyfd_struct_type = {
+ {
+#if PY_VERSION_HEX >= 0x03000000
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+#endif
+ "BIO_PYFD_CTX", /* tp_name */
+ sizeof(SwigPyObject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor) _wrap_delete_BIO_PYFD_CTX_closure, /* tp_dealloc */
+ (printfunc) 0, /* tp_print */
+ (getattrfunc) 0, /* tp_getattr */
+ (setattrfunc) 0, /* tp_setattr */
+#if PY_VERSION_HEX >= 0x03000000
+ 0, /* tp_compare */
+#else
+ (cmpfunc) 0, /* tp_compare */
+#endif
+ (reprfunc) 0, /* tp_repr */
+ &SwigPyBuiltin__pyfd_struct_type.as_number, /* tp_as_number */
+ &SwigPyBuiltin__pyfd_struct_type.as_sequence, /* tp_as_sequence */
+ &SwigPyBuiltin__pyfd_struct_type.as_mapping, /* tp_as_mapping */
+ (hashfunc) 0, /* tp_hash */
+ (ternaryfunc) 0, /* tp_call */
+ (reprfunc) 0, /* tp_str */
+ (getattrofunc) 0, /* tp_getattro */
+ (setattrofunc) 0, /* tp_setattro */
+ &SwigPyBuiltin__pyfd_struct_type.as_buffer, /* tp_as_buffer */
+#if PY_VERSION_HEX >= 0x03000000
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+#else
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_CHECKTYPES, /* tp_flags */
+#endif
+ "::pyfd_struct", /* tp_doc */
+ (traverseproc) 0, /* tp_traverse */
+ (inquiry) 0, /* tp_clear */
+ (richcmpfunc) SwigPyBuiltin__pyfd_struct_richcompare, /* feature:python:tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ (getiterfunc) 0, /* tp_iter */
+ (iternextfunc) 0, /* tp_iternext */
+ SwigPyBuiltin__pyfd_struct_methods, /* tp_methods */
+ 0, /* tp_members */
+ SwigPyBuiltin__pyfd_struct_getset, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ (descrgetfunc) 0, /* tp_descr_get */
+ (descrsetfunc) 0, /* tp_descr_set */
+ (size_t)(((char*)&((SwigPyObject *) 64L)->dict) - (char*) 64L), /* tp_dictoffset */
+ (initproc) _wrap_new_BIO_PYFD_CTX, /* tp_init */
+ (allocfunc) 0, /* tp_alloc */
+ (newfunc) 0, /* tp_new */
+ (freefunc) 0, /* tp_free */
+ (inquiry) 0, /* tp_is_gc */
+ (PyObject*) 0, /* tp_bases */
+ (PyObject*) 0, /* tp_mro */
+ (PyObject*) 0, /* tp_cache */
+ (PyObject*) 0, /* tp_subclasses */
+ (PyObject*) 0, /* tp_weaklist */
+ (destructor) 0, /* tp_del */
+#if PY_VERSION_HEX >= 0x02060000
+ (int) 0, /* tp_version_tag */
+#endif
+ },
+ {
+ (binaryfunc) 0, /* nb_add */
+ (binaryfunc) 0, /* nb_subtract */
+ (binaryfunc) 0, /* nb_multiply */
+#if PY_VERSION_HEX < 0x03000000
+ (binaryfunc) 0, /* nb_divide */
+#endif
+ (binaryfunc) 0, /* nb_remainder */
+ (binaryfunc) 0, /* nb_divmod */
+ (ternaryfunc) 0, /* nb_power */
+ (unaryfunc) 0, /* nb_negative */
+ (unaryfunc) 0, /* nb_positive */
+ (unaryfunc) 0, /* nb_absolute */
+ (inquiry) 0, /* nb_nonzero */
+ (unaryfunc) 0, /* nb_invert */
+ (binaryfunc) 0, /* nb_lshift */
+ (binaryfunc) 0, /* nb_rshift */
+ (binaryfunc) 0, /* nb_and */
+ (binaryfunc) 0, /* nb_xor */
+ (binaryfunc) 0, /* nb_or */
+#if PY_VERSION_HEX < 0x03000000
+ (coercion) 0, /* nb_coerce */
+#endif
+ (unaryfunc) 0, /* nb_int */
+#if PY_VERSION_HEX >= 0x03000000
+ (void*) 0, /* nb_reserved */
+#else
+ (unaryfunc) 0, /* nb_long */
+#endif
+ (unaryfunc) 0, /* nb_float */
+#if PY_VERSION_HEX < 0x03000000
+ (unaryfunc) 0, /* nb_oct */
+ (unaryfunc) 0, /* nb_hex */
+#endif
+ (binaryfunc) 0, /* nb_inplace_add */
+ (binaryfunc) 0, /* nb_inplace_subtract */
+ (binaryfunc) 0, /* nb_inplace_multiply */
+#if PY_VERSION_HEX < 0x03000000
+ (binaryfunc) 0, /* nb_inplace_divide */
+#endif
+ (binaryfunc) 0, /* nb_inplace_remainder */
+ (ternaryfunc) 0, /* nb_inplace_power */
+ (binaryfunc) 0, /* nb_inplace_lshift */
+ (binaryfunc) 0, /* nb_inplace_rshift */
+ (binaryfunc) 0, /* nb_inplace_and */
+ (binaryfunc) 0, /* nb_inplace_xor */
+ (binaryfunc) 0, /* nb_inplace_or */
+ (binaryfunc) 0, /* nb_floor_divide */
+ (binaryfunc) 0, /* nb_true_divide */
+ (binaryfunc) 0, /* nb_inplace_floor_divide */
+ (binaryfunc) 0, /* nb_inplace_true_divide */
+#if PY_VERSION_HEX >= 0x02050000
+ (unaryfunc) 0, /* nb_index */
+#endif
+ },
+ {
+ (lenfunc) 0, /* mp_length */
+ (binaryfunc) 0, /* mp_subscript */
+ (objobjargproc) 0, /* mp_ass_subscript */
+ },
+ {
+ (lenfunc) 0, /* sq_length */
+ (binaryfunc) 0, /* sq_concat */
+ (ssizeargfunc) 0, /* sq_repeat */
+ (ssizeargfunc) 0, /* sq_item */
+#if PY_VERSION_HEX >= 0x03000000
+ (void*) 0, /* was_sq_slice */
+#else
+ (ssizessizeargfunc) 0, /* sq_slice */
+#endif
+ (ssizeobjargproc) 0, /* sq_ass_item */
+#if PY_VERSION_HEX >= 0x03000000
+ (void*) 0, /* was_sq_ass_slice */
+#else
+ (ssizessizeobjargproc) 0, /* sq_ass_slice */
+#endif
+ (objobjproc) 0, /* sq_contains */
+ (binaryfunc) 0, /* sq_inplace_concat */
+ (ssizeargfunc) 0, /* sq_inplace_repeat */
+ },
+ {
+#if PY_VERSION_HEX < 0x03000000
+ (readbufferproc) 0, /* bf_getreadbuffer */
+ (writebufferproc) 0, /* bf_getwritebuffer */
+ (segcountproc) 0, /* bf_getsegcount */
+ (charbufferproc) 0, /* bf_getcharbuffer */
+#endif
+#if PY_VERSION_HEX >= 0x02060000
+ (getbufferproc) 0, /* bf_getbuffer */
+ (releasebufferproc) 0, /* bf_releasebuffer */
+#endif
+ },
+ (PyObject*) 0, /* ht_name */
+ (PyObject*) 0, /* ht_slots */
+};
+
+SWIGINTERN SwigPyClientData SwigPyBuiltin__pyfd_struct_clientdata = {0, 0, 0, 0, 0, 0, (PyTypeObject *)&SwigPyBuiltin__pyfd_struct_type};
+
+SWIGPY_DESTRUCTOR_CLOSURE(_wrap_delete__cbd_t)
+static SwigPyGetSet _cbd_t_password_getset = { _wrap__cbd_t_password_get, _wrap__cbd_t_password_set };
+static SwigPyGetSet _cbd_t_prompt_getset = { _wrap__cbd_t_prompt_get, _wrap__cbd_t_prompt_set };
+SWIGINTERN PyGetSetDef SwigPyBuiltin___cbd_t_getset[] = {
+ { (char*) "password", (getter) SwigPyBuiltin_GetterClosure, (setter) SwigPyBuiltin_SetterClosure, (char*)"_cbd_t.password", (void*) &_cbd_t_password_getset }
+,
+ { (char*) "prompt", (getter) SwigPyBuiltin_GetterClosure, (setter) SwigPyBuiltin_SetterClosure, (char*)"_cbd_t.prompt", (void*) &_cbd_t_prompt_getset }
+,
+ {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
+};
+
+SWIGINTERN PyObject *
+SwigPyBuiltin___cbd_t_richcompare(PyObject *self, PyObject *other, int op) {
+ PyObject *result = NULL;
+ PyObject *tuple = PyTuple_New(1);
+ assert(tuple);
+ PyTuple_SET_ITEM(tuple, 0, other);
+ Py_XINCREF(other);
+ if (!result) {
+ if (SwigPyObject_Check(self) && SwigPyObject_Check(other)) {
+ result = SwigPyObject_richcompare((SwigPyObject *)self, (SwigPyObject *)other, op);
+ } else {
+ result = Py_NotImplemented;
+ Py_INCREF(result);
+ }
+ }
+ Py_DECREF(tuple);
+ return result;
+}
+
+SWIGINTERN PyMethodDef SwigPyBuiltin___cbd_t_methods[] = {
+ { NULL, NULL, 0, NULL } /* Sentinel */
+};
+
+static PyHeapTypeObject SwigPyBuiltin___cbd_t_type = {
+ {
+#if PY_VERSION_HEX >= 0x03000000
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+#endif
+ "_cbd_t", /* tp_name */
+ sizeof(SwigPyObject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor) _wrap_delete__cbd_t_closure, /* tp_dealloc */
+ (printfunc) 0, /* tp_print */
+ (getattrfunc) 0, /* tp_getattr */
+ (setattrfunc) 0, /* tp_setattr */
+#if PY_VERSION_HEX >= 0x03000000
+ 0, /* tp_compare */
+#else
+ (cmpfunc) 0, /* tp_compare */
+#endif
+ (reprfunc) 0, /* tp_repr */
+ &SwigPyBuiltin___cbd_t_type.as_number, /* tp_as_number */
+ &SwigPyBuiltin___cbd_t_type.as_sequence, /* tp_as_sequence */
+ &SwigPyBuiltin___cbd_t_type.as_mapping, /* tp_as_mapping */
+ (hashfunc) 0, /* tp_hash */
+ (ternaryfunc) 0, /* tp_call */
+ (reprfunc) 0, /* tp_str */
+ (getattrofunc) 0, /* tp_getattro */
+ (setattrofunc) 0, /* tp_setattro */
+ &SwigPyBuiltin___cbd_t_type.as_buffer, /* tp_as_buffer */
+#if PY_VERSION_HEX >= 0x03000000
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+#else
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_CHECKTYPES, /* tp_flags */
+#endif
+ "::_cbd_t", /* tp_doc */
+ (traverseproc) 0, /* tp_traverse */
+ (inquiry) 0, /* tp_clear */
+ (richcmpfunc) SwigPyBuiltin___cbd_t_richcompare, /* feature:python:tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ (getiterfunc) 0, /* tp_iter */
+ (iternextfunc) 0, /* tp_iternext */
+ SwigPyBuiltin___cbd_t_methods, /* tp_methods */
+ 0, /* tp_members */
+ SwigPyBuiltin___cbd_t_getset, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ (descrgetfunc) 0, /* tp_descr_get */
+ (descrsetfunc) 0, /* tp_descr_set */
+ (size_t)(((char*)&((SwigPyObject *) 64L)->dict) - (char*) 64L), /* tp_dictoffset */
+ (initproc) _wrap_new__cbd_t, /* tp_init */
+ (allocfunc) 0, /* tp_alloc */
+ (newfunc) 0, /* tp_new */
+ (freefunc) 0, /* tp_free */
+ (inquiry) 0, /* tp_is_gc */
+ (PyObject*) 0, /* tp_bases */
+ (PyObject*) 0, /* tp_mro */
+ (PyObject*) 0, /* tp_cache */
+ (PyObject*) 0, /* tp_subclasses */
+ (PyObject*) 0, /* tp_weaklist */
+ (destructor) 0, /* tp_del */
+#if PY_VERSION_HEX >= 0x02060000
+ (int) 0, /* tp_version_tag */
+#endif
+ },
+ {
+ (binaryfunc) 0, /* nb_add */
+ (binaryfunc) 0, /* nb_subtract */
+ (binaryfunc) 0, /* nb_multiply */
+#if PY_VERSION_HEX < 0x03000000
+ (binaryfunc) 0, /* nb_divide */
+#endif
+ (binaryfunc) 0, /* nb_remainder */
+ (binaryfunc) 0, /* nb_divmod */
+ (ternaryfunc) 0, /* nb_power */
+ (unaryfunc) 0, /* nb_negative */
+ (unaryfunc) 0, /* nb_positive */
+ (unaryfunc) 0, /* nb_absolute */
+ (inquiry) 0, /* nb_nonzero */
+ (unaryfunc) 0, /* nb_invert */
+ (binaryfunc) 0, /* nb_lshift */
+ (binaryfunc) 0, /* nb_rshift */
+ (binaryfunc) 0, /* nb_and */
+ (binaryfunc) 0, /* nb_xor */
+ (binaryfunc) 0, /* nb_or */
+#if PY_VERSION_HEX < 0x03000000
+ (coercion) 0, /* nb_coerce */
+#endif
+ (unaryfunc) 0, /* nb_int */
+#if PY_VERSION_HEX >= 0x03000000
+ (void*) 0, /* nb_reserved */
+#else
+ (unaryfunc) 0, /* nb_long */
+#endif
+ (unaryfunc) 0, /* nb_float */
+#if PY_VERSION_HEX < 0x03000000
+ (unaryfunc) 0, /* nb_oct */
+ (unaryfunc) 0, /* nb_hex */
+#endif
+ (binaryfunc) 0, /* nb_inplace_add */
+ (binaryfunc) 0, /* nb_inplace_subtract */
+ (binaryfunc) 0, /* nb_inplace_multiply */
+#if PY_VERSION_HEX < 0x03000000
+ (binaryfunc) 0, /* nb_inplace_divide */
+#endif
+ (binaryfunc) 0, /* nb_inplace_remainder */
+ (ternaryfunc) 0, /* nb_inplace_power */
+ (binaryfunc) 0, /* nb_inplace_lshift */
+ (binaryfunc) 0, /* nb_inplace_rshift */
+ (binaryfunc) 0, /* nb_inplace_and */
+ (binaryfunc) 0, /* nb_inplace_xor */
+ (binaryfunc) 0, /* nb_inplace_or */
+ (binaryfunc) 0, /* nb_floor_divide */
+ (binaryfunc) 0, /* nb_true_divide */
+ (binaryfunc) 0, /* nb_inplace_floor_divide */
+ (binaryfunc) 0, /* nb_inplace_true_divide */
+#if PY_VERSION_HEX >= 0x02050000
+ (unaryfunc) 0, /* nb_index */
+#endif
+ },
+ {
+ (lenfunc) 0, /* mp_length */
+ (binaryfunc) 0, /* mp_subscript */
+ (objobjargproc) 0, /* mp_ass_subscript */
+ },
+ {
+ (lenfunc) 0, /* sq_length */
+ (binaryfunc) 0, /* sq_concat */
+ (ssizeargfunc) 0, /* sq_repeat */
+ (ssizeargfunc) 0, /* sq_item */
+#if PY_VERSION_HEX >= 0x03000000
+ (void*) 0, /* was_sq_slice */
+#else
+ (ssizessizeargfunc) 0, /* sq_slice */
+#endif
+ (ssizeobjargproc) 0, /* sq_ass_item */
+#if PY_VERSION_HEX >= 0x03000000
+ (void*) 0, /* was_sq_ass_slice */
+#else
+ (ssizessizeobjargproc) 0, /* sq_ass_slice */
+#endif
+ (objobjproc) 0, /* sq_contains */
+ (binaryfunc) 0, /* sq_inplace_concat */
+ (ssizeargfunc) 0, /* sq_inplace_repeat */
+ },
+ {
+#if PY_VERSION_HEX < 0x03000000
+ (readbufferproc) 0, /* bf_getreadbuffer */
+ (writebufferproc) 0, /* bf_getwritebuffer */
+ (segcountproc) 0, /* bf_getsegcount */
+ (charbufferproc) 0, /* bf_getcharbuffer */
+#endif
+#if PY_VERSION_HEX >= 0x02060000
+ (getbufferproc) 0, /* bf_getbuffer */
+ (releasebufferproc) 0, /* bf_releasebuffer */
+#endif
+ },
+ (PyObject*) 0, /* ht_name */
+ (PyObject*) 0, /* ht_slots */
+};
+
+SWIGINTERN SwigPyClientData SwigPyBuiltin___cbd_t_clientdata = {0, 0, 0, 0, 0, 0, (PyTypeObject *)&SwigPyBuiltin___cbd_t_type};
+
+
+/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */
+
+static swig_type_info _swigt__p_AES_KEY = {"_p_AES_KEY", "AES_KEY *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_ASN1_BIT_STRING = {"_p_ASN1_BIT_STRING", "ASN1_BIT_STRING *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_ASN1_INTEGER = {"_p_ASN1_INTEGER", "ASN1_INTEGER *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_ASN1_OBJECT = {"_p_ASN1_OBJECT", "ASN1_OBJECT *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_ASN1_STRING = {"_p_ASN1_STRING", "ASN1_STRING *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_ASN1_TIME = {"_p_ASN1_TIME", "ASN1_TIME *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_BIGNUM = {"_p_BIGNUM", "BIGNUM *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_BIO = {"_p_BIO", "BIO *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_BIO_METHOD = {"_p_BIO_METHOD", "BIO_METHOD *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_DH = {"_p_DH", "DH *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_DSA = {"_p_DSA", "DSA *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_ECDSA_SIG = {"_p_ECDSA_SIG", "ECDSA_SIG *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_EC_KEY = {"_p_EC_KEY", "EC_KEY *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_ENGINE = {"_p_ENGINE", "ENGINE *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_EVP_CIPHER = {"_p_EVP_CIPHER", "EVP_CIPHER *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_EVP_CIPHER_CTX = {"_p_EVP_CIPHER_CTX", "EVP_CIPHER_CTX *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_EVP_MD = {"_p_EVP_MD", "EVP_MD *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_EVP_MD_CTX = {"_p_EVP_MD_CTX", "EVP_MD_CTX *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_EVP_PKEY = {"_p_EVP_PKEY", "EVP_PKEY *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_FILE = {"_p_FILE", "FILE *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_HMAC_CTX = {"_p_HMAC_CTX", "HMAC_CTX *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_PKCS7 = {"_p_PKCS7", "PKCS7 *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_PyObject = {"_p_PyObject", "PyObject *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_RC4_KEY = {"_p_RC4_KEY", "RC4_KEY *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_RSA = {"_p_RSA", "RSA *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_SSL = {"_p_SSL", "SSL *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_SSL_CIPHER = {"_p_SSL_CIPHER", "SSL_CIPHER *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_SSL_CTX = {"_p_SSL_CTX", "SSL_CTX *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_SSL_METHOD = {"_p_SSL_METHOD", "SSL_METHOD *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_SSL_SESSION = {"_p_SSL_SESSION", "SSL_SESSION *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_SwigPyObject = {"_p_SwigPyObject", "SwigPyObject *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_UI_METHOD = {"_p_UI_METHOD", "UI_METHOD *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_X509 = {"_p_X509", "X509 *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_X509V3_CTX = {"_p_X509V3_CTX", "X509V3_CTX *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_X509_CRL = {"_p_X509_CRL", "X509_CRL *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_X509_EXTENSION = {"_p_X509_EXTENSION", "X509_EXTENSION *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_X509_NAME = {"_p_X509_NAME", "X509_NAME *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_X509_NAME_ENTRY = {"_p_X509_NAME_ENTRY", "X509_NAME_ENTRY *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_X509_REQ = {"_p_X509_REQ", "X509_REQ *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_X509_STORE = {"_p_X509_STORE", "X509_STORE *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_X509_STORE_CTX = {"_p_X509_STORE_CTX", "X509_STORE_CTX *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p__cbd_t = {"_p__cbd_t", "_cbd_t *", 0, 0, (void*)&SwigPyBuiltin___cbd_t_clientdata, 0};
+static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_f_int_p_X509_STORE_CTX__int = {"_p_f_int_p_X509_STORE_CTX__int", "int (*)(int,X509_STORE_CTX *)", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_f_p_q_const__void_p_q_const__void__int = {"_p_f_p_q_const__void_p_q_const__void__int", "int (*)(void const *,void const *)", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_f_p_void__p_void = {"_p_f_p_void__p_void", "void *(*)(void *)", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_f_p_void__void = {"_p_f_p_void__void", "void (*)(void *)", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_p_ASN1_OBJECT = {"_p_p_ASN1_OBJECT", "ASN1_OBJECT **", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_p_X509_NAME_ENTRY = {"_p_p_X509_NAME_ENTRY", "X509_NAME_ENTRY **", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_p_char = {"_p_p_char", "char **", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_p_unsigned_char = {"_p_p_unsigned_char", "unsigned char **", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_pyfd_struct = {"_p_pyfd_struct", "BIO_PYFD_CTX *|struct pyfd_struct *|pyfd_struct *", 0, 0, (void*)&SwigPyBuiltin__pyfd_struct_clientdata, 0};
+static swig_type_info _swigt__p_stack_st = {"_p_stack_st", "struct stack_st *|stack_st *|_STACK *", 0, 0, (void*)&SwigPyBuiltin__stack_st_clientdata, 0};
+static swig_type_info _swigt__p_stack_st_OPENSSL_BLOCK = {"_p_stack_st_OPENSSL_BLOCK", "struct stack_st_OPENSSL_BLOCK *|stack_st_OPENSSL_BLOCK *", 0, 0, (void*)&SwigPyBuiltin__stack_st_OPENSSL_BLOCK_clientdata, 0};
+static swig_type_info _swigt__p_stack_st_OPENSSL_STRING = {"_p_stack_st_OPENSSL_STRING", "struct stack_st_OPENSSL_STRING *|stack_st_OPENSSL_STRING *", 0, 0, (void*)&SwigPyBuiltin__stack_st_OPENSSL_STRING_clientdata, 0};
+static swig_type_info _swigt__p_stack_st_SSL_CIPHER = {"_p_stack_st_SSL_CIPHER", "struct stack_st_SSL_CIPHER *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_stack_st_X509 = {"_p_stack_st_X509", "struct stack_st_X509 *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_stack_st_X509_EXTENSION = {"_p_stack_st_X509_EXTENSION", "struct stack_st_X509_EXTENSION *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_unsigned_char = {"_p_unsigned_char", "unsigned char *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_void = {"_p_void", "void *", 0, 0, (void*)0, 0};
+
+static swig_type_info *swig_type_initial[] = {
+ &_swigt__p_AES_KEY,
+ &_swigt__p_ASN1_BIT_STRING,
+ &_swigt__p_ASN1_INTEGER,
+ &_swigt__p_ASN1_OBJECT,
+ &_swigt__p_ASN1_STRING,
+ &_swigt__p_ASN1_TIME,
+ &_swigt__p_BIGNUM,
+ &_swigt__p_BIO,
+ &_swigt__p_BIO_METHOD,
+ &_swigt__p_DH,
+ &_swigt__p_DSA,
+ &_swigt__p_ECDSA_SIG,
+ &_swigt__p_EC_KEY,
+ &_swigt__p_ENGINE,
+ &_swigt__p_EVP_CIPHER,
+ &_swigt__p_EVP_CIPHER_CTX,
+ &_swigt__p_EVP_MD,
+ &_swigt__p_EVP_MD_CTX,
+ &_swigt__p_EVP_PKEY,
+ &_swigt__p_FILE,
+ &_swigt__p_HMAC_CTX,
+ &_swigt__p_PKCS7,
+ &_swigt__p_PyObject,
+ &_swigt__p_RC4_KEY,
+ &_swigt__p_RSA,
+ &_swigt__p_SSL,
+ &_swigt__p_SSL_CIPHER,
+ &_swigt__p_SSL_CTX,
+ &_swigt__p_SSL_METHOD,
+ &_swigt__p_SSL_SESSION,
+ &_swigt__p_SwigPyObject,
+ &_swigt__p_UI_METHOD,
+ &_swigt__p_X509,
+ &_swigt__p_X509V3_CTX,
+ &_swigt__p_X509_CRL,
+ &_swigt__p_X509_EXTENSION,
+ &_swigt__p_X509_NAME,
+ &_swigt__p_X509_NAME_ENTRY,
+ &_swigt__p_X509_REQ,
+ &_swigt__p_X509_STORE,
+ &_swigt__p_X509_STORE_CTX,
+ &_swigt__p__cbd_t,
+ &_swigt__p_char,
+ &_swigt__p_f_int_p_X509_STORE_CTX__int,
+ &_swigt__p_f_p_q_const__void_p_q_const__void__int,
+ &_swigt__p_f_p_void__p_void,
+ &_swigt__p_f_p_void__void,
+ &_swigt__p_p_ASN1_OBJECT,
+ &_swigt__p_p_X509_NAME_ENTRY,
+ &_swigt__p_p_char,
+ &_swigt__p_p_unsigned_char,
+ &_swigt__p_pyfd_struct,
+ &_swigt__p_stack_st,
+ &_swigt__p_stack_st_OPENSSL_BLOCK,
+ &_swigt__p_stack_st_OPENSSL_STRING,
+ &_swigt__p_stack_st_SSL_CIPHER,
+ &_swigt__p_stack_st_X509,
+ &_swigt__p_stack_st_X509_EXTENSION,
+ &_swigt__p_unsigned_char,
+ &_swigt__p_void,
+};
+
+static swig_cast_info _swigc__p_AES_KEY[] = { {&_swigt__p_AES_KEY, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_ASN1_BIT_STRING[] = { {&_swigt__p_ASN1_BIT_STRING, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_ASN1_INTEGER[] = { {&_swigt__p_ASN1_INTEGER, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_ASN1_OBJECT[] = { {&_swigt__p_ASN1_OBJECT, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_ASN1_STRING[] = { {&_swigt__p_ASN1_STRING, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_ASN1_TIME[] = { {&_swigt__p_ASN1_TIME, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_BIGNUM[] = { {&_swigt__p_BIGNUM, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_BIO[] = { {&_swigt__p_BIO, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_BIO_METHOD[] = { {&_swigt__p_BIO_METHOD, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_DH[] = { {&_swigt__p_DH, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_DSA[] = { {&_swigt__p_DSA, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_ECDSA_SIG[] = { {&_swigt__p_ECDSA_SIG, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_EC_KEY[] = { {&_swigt__p_EC_KEY, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_ENGINE[] = { {&_swigt__p_ENGINE, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_EVP_CIPHER[] = { {&_swigt__p_EVP_CIPHER, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_EVP_CIPHER_CTX[] = { {&_swigt__p_EVP_CIPHER_CTX, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_EVP_MD[] = { {&_swigt__p_EVP_MD, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_EVP_MD_CTX[] = { {&_swigt__p_EVP_MD_CTX, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_EVP_PKEY[] = { {&_swigt__p_EVP_PKEY, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_FILE[] = { {&_swigt__p_FILE, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_HMAC_CTX[] = { {&_swigt__p_HMAC_CTX, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_PKCS7[] = { {&_swigt__p_PKCS7, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_PyObject[] = { {&_swigt__p_PyObject, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_RC4_KEY[] = { {&_swigt__p_RC4_KEY, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_RSA[] = { {&_swigt__p_RSA, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_SSL[] = { {&_swigt__p_SSL, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_SSL_CIPHER[] = { {&_swigt__p_SSL_CIPHER, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_SSL_CTX[] = { {&_swigt__p_SSL_CTX, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_SSL_METHOD[] = { {&_swigt__p_SSL_METHOD, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_SSL_SESSION[] = { {&_swigt__p_SSL_SESSION, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_SwigPyObject[] = { {&_swigt__p_SwigPyObject, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_UI_METHOD[] = { {&_swigt__p_UI_METHOD, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_X509[] = { {&_swigt__p_X509, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_X509V3_CTX[] = { {&_swigt__p_X509V3_CTX, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_X509_CRL[] = { {&_swigt__p_X509_CRL, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_X509_EXTENSION[] = { {&_swigt__p_X509_EXTENSION, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_X509_NAME[] = { {&_swigt__p_X509_NAME, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_X509_NAME_ENTRY[] = { {&_swigt__p_X509_NAME_ENTRY, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_X509_REQ[] = { {&_swigt__p_X509_REQ, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_X509_STORE[] = { {&_swigt__p_X509_STORE, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_X509_STORE_CTX[] = { {&_swigt__p_X509_STORE_CTX, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p__cbd_t[] = { {&_swigt__p__cbd_t, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_char[] = { {&_swigt__p_char, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_f_int_p_X509_STORE_CTX__int[] = { {&_swigt__p_f_int_p_X509_STORE_CTX__int, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_f_p_q_const__void_p_q_const__void__int[] = { {&_swigt__p_f_p_q_const__void_p_q_const__void__int, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_f_p_void__p_void[] = { {&_swigt__p_f_p_void__p_void, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_f_p_void__void[] = { {&_swigt__p_f_p_void__void, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_p_ASN1_OBJECT[] = { {&_swigt__p_p_ASN1_OBJECT, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_p_X509_NAME_ENTRY[] = { {&_swigt__p_p_X509_NAME_ENTRY, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_p_char[] = { {&_swigt__p_p_char, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_p_unsigned_char[] = { {&_swigt__p_p_unsigned_char, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_pyfd_struct[] = { {&_swigt__p_pyfd_struct, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_stack_st[] = { {&_swigt__p_stack_st, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_stack_st_OPENSSL_BLOCK[] = { {&_swigt__p_stack_st_OPENSSL_BLOCK, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_stack_st_OPENSSL_STRING[] = { {&_swigt__p_stack_st_OPENSSL_STRING, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_stack_st_SSL_CIPHER[] = { {&_swigt__p_stack_st_SSL_CIPHER, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_stack_st_X509[] = { {&_swigt__p_stack_st_X509, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_stack_st_X509_EXTENSION[] = { {&_swigt__p_stack_st_X509_EXTENSION, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_unsigned_char[] = { {&_swigt__p_unsigned_char, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_void[] = { {&_swigt__p_void, 0, 0, 0},{0, 0, 0, 0}};
+
+static swig_cast_info *swig_cast_initial[] = {
+ _swigc__p_AES_KEY,
+ _swigc__p_ASN1_BIT_STRING,
+ _swigc__p_ASN1_INTEGER,
+ _swigc__p_ASN1_OBJECT,
+ _swigc__p_ASN1_STRING,
+ _swigc__p_ASN1_TIME,
+ _swigc__p_BIGNUM,
+ _swigc__p_BIO,
+ _swigc__p_BIO_METHOD,
+ _swigc__p_DH,
+ _swigc__p_DSA,
+ _swigc__p_ECDSA_SIG,
+ _swigc__p_EC_KEY,
+ _swigc__p_ENGINE,
+ _swigc__p_EVP_CIPHER,
+ _swigc__p_EVP_CIPHER_CTX,
+ _swigc__p_EVP_MD,
+ _swigc__p_EVP_MD_CTX,
+ _swigc__p_EVP_PKEY,
+ _swigc__p_FILE,
+ _swigc__p_HMAC_CTX,
+ _swigc__p_PKCS7,
+ _swigc__p_PyObject,
+ _swigc__p_RC4_KEY,
+ _swigc__p_RSA,
+ _swigc__p_SSL,
+ _swigc__p_SSL_CIPHER,
+ _swigc__p_SSL_CTX,
+ _swigc__p_SSL_METHOD,
+ _swigc__p_SSL_SESSION,
+ _swigc__p_SwigPyObject,
+ _swigc__p_UI_METHOD,
+ _swigc__p_X509,
+ _swigc__p_X509V3_CTX,
+ _swigc__p_X509_CRL,
+ _swigc__p_X509_EXTENSION,
+ _swigc__p_X509_NAME,
+ _swigc__p_X509_NAME_ENTRY,
+ _swigc__p_X509_REQ,
+ _swigc__p_X509_STORE,
+ _swigc__p_X509_STORE_CTX,
+ _swigc__p__cbd_t,
+ _swigc__p_char,
+ _swigc__p_f_int_p_X509_STORE_CTX__int,
+ _swigc__p_f_p_q_const__void_p_q_const__void__int,
+ _swigc__p_f_p_void__p_void,
+ _swigc__p_f_p_void__void,
+ _swigc__p_p_ASN1_OBJECT,
+ _swigc__p_p_X509_NAME_ENTRY,
+ _swigc__p_p_char,
+ _swigc__p_p_unsigned_char,
+ _swigc__p_pyfd_struct,
+ _swigc__p_stack_st,
+ _swigc__p_stack_st_OPENSSL_BLOCK,
+ _swigc__p_stack_st_OPENSSL_STRING,
+ _swigc__p_stack_st_SSL_CIPHER,
+ _swigc__p_stack_st_X509,
+ _swigc__p_stack_st_X509_EXTENSION,
+ _swigc__p_unsigned_char,
+ _swigc__p_void,
+};
+
+
+/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */
+
+static swig_const_info swig_const_table[] = {
+{0, 0, 0, 0.0, 0, 0}};
+
+#ifdef __cplusplus
+}
+#endif
+static PyTypeObject *builtin_bases[2];
+
+/* -----------------------------------------------------------------------------
+ * Type initialization:
+ * This problem is tough by the requirement that no dynamic
+ * memory is used. Also, since swig_type_info structures store pointers to
+ * swig_cast_info structures and swig_cast_info structures store pointers back
+ * to swig_type_info structures, we need some lookup code at initialization.
+ * The idea is that swig generates all the structures that are needed.
+ * The runtime then collects these partially filled structures.
+ * The SWIG_InitializeModule function takes these initial arrays out of
+ * swig_module, and does all the lookup, filling in the swig_module.types
+ * array with the correct data and linking the correct swig_cast_info
+ * structures together.
+ *
+ * The generated swig_type_info structures are assigned staticly to an initial
+ * array. We just loop through that array, and handle each type individually.
+ * First we lookup if this type has been already loaded, and if so, use the
+ * loaded structure instead of the generated one. Then we have to fill in the
+ * cast linked list. The cast data is initially stored in something like a
+ * two-dimensional array. Each row corresponds to a type (there are the same
+ * number of rows as there are in the swig_type_initial array). Each entry in
+ * a column is one of the swig_cast_info structures for that type.
+ * The cast_initial array is actually an array of arrays, because each row has
+ * a variable number of columns. So to actually build the cast linked list,
+ * we find the array of casts associated with the type, and loop through it
+ * adding the casts to the list. The one last trick we need to do is making
+ * sure the type pointer in the swig_cast_info struct is correct.
+ *
+ * First off, we lookup the cast->type name to see if it is already loaded.
+ * There are three cases to handle:
+ * 1) If the cast->type has already been loaded AND the type we are adding
+ * casting info to has not been loaded (it is in this module), THEN we
+ * replace the cast->type pointer with the type pointer that has already
+ * been loaded.
+ * 2) If BOTH types (the one we are adding casting info to, and the
+ * cast->type) are loaded, THEN the cast info has already been loaded by
+ * the previous module so we just ignore it.
+ * 3) Finally, if cast->type has not already been loaded, then we add that
+ * swig_cast_info to the linked list (because the cast->type) pointer will
+ * be correct.
+ * ----------------------------------------------------------------------------- */
+
+#ifdef __cplusplus
+extern "C" {
+#if 0
+} /* c-mode */
+#endif
+#endif
+
+#if 0
+#define SWIGRUNTIME_DEBUG
+#endif
+
+
+SWIGRUNTIME void
+SWIG_InitializeModule(void *clientdata) {
+ size_t i;
+ swig_module_info *module_head, *iter;
+ int found, init;
+
+ /* check to see if the circular list has been setup, if not, set it up */
+ if (swig_module.next==0) {
+ /* Initialize the swig_module */
+ swig_module.type_initial = swig_type_initial;
+ swig_module.cast_initial = swig_cast_initial;
+ swig_module.next = &swig_module;
+ init = 1;
+ } else {
+ init = 0;
+ }
+
+ /* Try and load any already created modules */
+ module_head = SWIG_GetModule(clientdata);
+ if (!module_head) {
+ /* This is the first module loaded for this interpreter */
+ /* so set the swig module into the interpreter */
+ SWIG_SetModule(clientdata, &swig_module);
+ module_head = &swig_module;
+ } else {
+ /* the interpreter has loaded a SWIG module, but has it loaded this one? */
+ found=0;
+ iter=module_head;
+ do {
+ if (iter==&swig_module) {
+ found=1;
+ break;
+ }
+ iter=iter->next;
+ } while (iter!= module_head);
+
+ /* if the is found in the list, then all is done and we may leave */
+ if (found) return;
+ /* otherwise we must add out module into the list */
+ swig_module.next = module_head->next;
+ module_head->next = &swig_module;
+ }
+
+ /* When multiple interpeters are used, a module could have already been initialized in
+ a different interpreter, but not yet have a pointer in this interpreter.
+ In this case, we do not want to continue adding types... everything should be
+ set up already */
+ if (init == 0) return;
+
+ /* Now work on filling in swig_module.types */
+#ifdef SWIGRUNTIME_DEBUG
+ printf("SWIG_InitializeModule: size %d\n", swig_module.size);
+#endif
+ for (i = 0; i < swig_module.size; ++i) {
+ swig_type_info *type = 0;
+ swig_type_info *ret;
+ swig_cast_info *cast;
+
+#ifdef SWIGRUNTIME_DEBUG
+ printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name);
+#endif
+
+ /* if there is another module already loaded */
+ if (swig_module.next != &swig_module) {
+ type = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, swig_module.type_initial[i]->name);
+ }
+ if (type) {
+ /* Overwrite clientdata field */
+#ifdef SWIGRUNTIME_DEBUG
+ printf("SWIG_InitializeModule: found type %s\n", type->name);
+#endif
+ if (swig_module.type_initial[i]->clientdata) {
+ type->clientdata = swig_module.type_initial[i]->clientdata;
+#ifdef SWIGRUNTIME_DEBUG
+ printf("SWIG_InitializeModule: found and overwrite type %s \n", type->name);
+#endif
+ }
+ } else {
+ type = swig_module.type_initial[i];
+ }
+
+ /* Insert casting types */
+ cast = swig_module.cast_initial[i];
+ while (cast->type) {
+ /* Don't need to add information already in the list */
+ ret = 0;
+#ifdef SWIGRUNTIME_DEBUG
+ printf("SWIG_InitializeModule: look cast %s\n", cast->type->name);
+#endif
+ if (swig_module.next != &swig_module) {
+ ret = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, cast->type->name);
+#ifdef SWIGRUNTIME_DEBUG
+ if (ret) printf("SWIG_InitializeModule: found cast %s\n", ret->name);
+#endif
+ }
+ if (ret) {
+ if (type == swig_module.type_initial[i]) {
+#ifdef SWIGRUNTIME_DEBUG
+ printf("SWIG_InitializeModule: skip old type %s\n", ret->name);
+#endif
+ cast->type = ret;
+ ret = 0;
+ } else {
+ /* Check for casting already in the list */
+ swig_cast_info *ocast = SWIG_TypeCheck(ret->name, type);
+#ifdef SWIGRUNTIME_DEBUG
+ if (ocast) printf("SWIG_InitializeModule: skip old cast %s\n", ret->name);
+#endif
+ if (!ocast) ret = 0;
+ }
+ }
+
+ if (!ret) {
+#ifdef SWIGRUNTIME_DEBUG
+ printf("SWIG_InitializeModule: adding cast %s\n", cast->type->name);
+#endif
+ if (type->cast) {
+ type->cast->prev = cast;
+ cast->next = type->cast;
+ }
+ type->cast = cast;
+ }
+ cast++;
+ }
+ /* Set entry in modules->types array equal to the type */
+ swig_module.types[i] = type;
+ }
+ swig_module.types[i] = 0;
+
+#ifdef SWIGRUNTIME_DEBUG
+ printf("**** SWIG_InitializeModule: Cast List ******\n");
+ for (i = 0; i < swig_module.size; ++i) {
+ int j = 0;
+ swig_cast_info *cast = swig_module.cast_initial[i];
+ printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name);
+ while (cast->type) {
+ printf("SWIG_InitializeModule: cast type %s\n", cast->type->name);
+ cast++;
+ ++j;
+ }
+ printf("---- Total casts: %d\n",j);
+ }
+ printf("**** SWIG_InitializeModule: Cast List ******\n");
+#endif
+}
+
+/* This function will propagate the clientdata field of type to
+* any new swig_type_info structures that have been added into the list
+* of equivalent types. It is like calling
+* SWIG_TypeClientData(type, clientdata) a second time.
+*/
+SWIGRUNTIME void
+SWIG_PropagateClientData(void) {
+ size_t i;
+ swig_cast_info *equiv;
+ static int init_run = 0;
+
+ if (init_run) return;
+ init_run = 1;
+
+ for (i = 0; i < swig_module.size; i++) {
+ if (swig_module.types[i]->clientdata) {
+ equiv = swig_module.types[i]->cast;
+ while (equiv) {
+ if (!equiv->converter) {
+ if (equiv->type && !equiv->type->clientdata)
+ SWIG_TypeClientData(equiv->type, swig_module.types[i]->clientdata);
+ }
+ equiv = equiv->next;
+ }
+ }
+ }
+}
+
+#ifdef __cplusplus
+#if 0
+{
+ /* c-mode */
+#endif
+}
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /* Python-specific SWIG API */
+#define SWIG_newvarlink() SWIG_Python_newvarlink()
+#define SWIG_addvarlink(p, name, get_attr, set_attr) SWIG_Python_addvarlink(p, name, get_attr, set_attr)
+#define SWIG_InstallConstants(d, constants) SWIG_Python_InstallConstants(d, constants)
+
+ /* -----------------------------------------------------------------------------
+ * global variable support code.
+ * ----------------------------------------------------------------------------- */
+
+ typedef struct swig_globalvar {
+ char *name; /* Name of global variable */
+ PyObject *(*get_attr)(void); /* Return the current value */
+ int (*set_attr)(PyObject *); /* Set the value */
+ struct swig_globalvar *next;
+ } swig_globalvar;
+
+ typedef struct swig_varlinkobject {
+ PyObject_HEAD
+ swig_globalvar *vars;
+ } swig_varlinkobject;
+
+ SWIGINTERN PyObject *
+ swig_varlink_repr(swig_varlinkobject *SWIGUNUSEDPARM(v)) {
+#if PY_VERSION_HEX >= 0x03000000
+ return PyUnicode_InternFromString("<Swig global variables>");
+#else
+ return PyString_FromString("<Swig global variables>");
+#endif
+ }
+
+ SWIGINTERN PyObject *
+ swig_varlink_str(swig_varlinkobject *v) {
+#if PY_VERSION_HEX >= 0x03000000
+ PyObject *str = PyUnicode_InternFromString("(");
+ PyObject *tail;
+ PyObject *joined;
+ swig_globalvar *var;
+ for (var = v->vars; var; var=var->next) {
+ tail = PyUnicode_FromString(var->name);
+ joined = PyUnicode_Concat(str, tail);
+ Py_DecRef(str);
+ Py_DecRef(tail);
+ str = joined;
+ if (var->next) {
+ tail = PyUnicode_InternFromString(", ");
+ joined = PyUnicode_Concat(str, tail);
+ Py_DecRef(str);
+ Py_DecRef(tail);
+ str = joined;
+ }
+ }
+ tail = PyUnicode_InternFromString(")");
+ joined = PyUnicode_Concat(str, tail);
+ Py_DecRef(str);
+ Py_DecRef(tail);
+ str = joined;
+#else
+ PyObject *str = PyString_FromString("(");
+ swig_globalvar *var;
+ for (var = v->vars; var; var=var->next) {
+ PyString_ConcatAndDel(&str,PyString_FromString(var->name));
+ if (var->next) PyString_ConcatAndDel(&str,PyString_FromString(", "));
+ }
+ PyString_ConcatAndDel(&str,PyString_FromString(")"));
+#endif
+ return str;
+ }
+
+ SWIGINTERN int
+ swig_varlink_print(swig_varlinkobject *v, FILE *fp, int SWIGUNUSEDPARM(flags)) {
+ char *tmp;
+ PyObject *str = swig_varlink_str(v);
+ fprintf(fp,"Swig global variables ");
+ fprintf(fp,"%s\n", tmp = SWIG_Python_str_AsChar(str));
+ SWIG_Python_str_DelForPy3(tmp);
+ Py_DECREF(str);
+ return 0;
+ }
+
+ SWIGINTERN void
+ swig_varlink_dealloc(swig_varlinkobject *v) {
+ swig_globalvar *var = v->vars;
+ while (var) {
+ swig_globalvar *n = var->next;
+ free(var->name);
+ free(var);
+ var = n;
+ }
+ }
+
+ SWIGINTERN PyObject *
+ swig_varlink_getattr(swig_varlinkobject *v, char *n) {
+ PyObject *res = NULL;
+ swig_globalvar *var = v->vars;
+ while (var) {
+ if (strcmp(var->name,n) == 0) {
+ res = (*var->get_attr)();
+ break;
+ }
+ var = var->next;
+ }
+ if (res == NULL && !PyErr_Occurred()) {
+ PyErr_SetString(PyExc_NameError,"Unknown C global variable");
+ }
+ return res;
+ }
+
+ SWIGINTERN int
+ swig_varlink_setattr(swig_varlinkobject *v, char *n, PyObject *p) {
+ int res = 1;
+ swig_globalvar *var = v->vars;
+ while (var) {
+ if (strcmp(var->name,n) == 0) {
+ res = (*var->set_attr)(p);
+ break;
+ }
+ var = var->next;
+ }
+ if (res == 1 && !PyErr_Occurred()) {
+ PyErr_SetString(PyExc_NameError,"Unknown C global variable");
+ }
+ return res;
+ }
+
+ SWIGINTERN PyTypeObject*
+ swig_varlink_type(void) {
+ static char varlink__doc__[] = "Swig var link object";
+ static PyTypeObject varlink_type;
+ static int type_init = 0;
+ if (!type_init) {
+ const PyTypeObject tmp = {
+ /* PyObject header changed in Python 3 */
+#if PY_VERSION_HEX >= 0x03000000
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+#endif
+ (char *)"swigvarlink", /* tp_name */
+ sizeof(swig_varlinkobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor) swig_varlink_dealloc, /* tp_dealloc */
+ (printfunc) swig_varlink_print, /* tp_print */
+ (getattrfunc) swig_varlink_getattr, /* tp_getattr */
+ (setattrfunc) swig_varlink_setattr, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc) swig_varlink_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ (reprfunc) swig_varlink_str, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ 0, /* tp_flags */
+ varlink__doc__, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+#if PY_VERSION_HEX >= 0x02020000
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* tp_iter -> tp_weaklist */
+#endif
+#if PY_VERSION_HEX >= 0x02030000
+ 0, /* tp_del */
+#endif
+#if PY_VERSION_HEX >= 0x02060000
+ 0, /* tp_version */
+#endif
+#ifdef COUNT_ALLOCS
+ 0,0,0,0 /* tp_alloc -> tp_next */
+#endif
+ };
+ varlink_type = tmp;
+ type_init = 1;
+#if PY_VERSION_HEX < 0x02020000
+ varlink_type.ob_type = &PyType_Type;
+#else
+ if (PyType_Ready(&varlink_type) < 0)
+ return NULL;
+#endif
+ }
+ return &varlink_type;
+ }
+
+ /* Create a variable linking object for use later */
+ SWIGINTERN PyObject *
+ SWIG_Python_newvarlink(void) {
+ swig_varlinkobject *result = PyObject_NEW(swig_varlinkobject, swig_varlink_type());
+ if (result) {
+ result->vars = 0;
+ }
+ return ((PyObject*) result);
+ }
+
+ SWIGINTERN void
+ SWIG_Python_addvarlink(PyObject *p, char *name, PyObject *(*get_attr)(void), int (*set_attr)(PyObject *p)) {
+ swig_varlinkobject *v = (swig_varlinkobject *) p;
+ swig_globalvar *gv = (swig_globalvar *) malloc(sizeof(swig_globalvar));
+ if (gv) {
+ size_t size = strlen(name)+1;
+ gv->name = (char *)malloc(size);
+ if (gv->name) {
+ strncpy(gv->name,name,size);
+ gv->get_attr = get_attr;
+ gv->set_attr = set_attr;
+ gv->next = v->vars;
+ }
+ }
+ v->vars = gv;
+ }
+
+ SWIGINTERN PyObject *
+ SWIG_globals(void) {
+ static PyObject *_SWIG_globals = 0;
+ if (!_SWIG_globals) _SWIG_globals = SWIG_newvarlink();
+ return _SWIG_globals;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * constants/methods manipulation
+ * ----------------------------------------------------------------------------- */
+
+ /* Install Constants */
+ SWIGINTERN void
+ SWIG_Python_InstallConstants(PyObject *d, swig_const_info constants[]) {
+ PyObject *obj = 0;
+ size_t i;
+ for (i = 0; constants[i].type; ++i) {
+ switch(constants[i].type) {
+ case SWIG_PY_POINTER:
+ obj = SWIG_InternalNewPointerObj(constants[i].pvalue, *(constants[i]).ptype,0);
+ break;
+ case SWIG_PY_BINARY:
+ obj = SWIG_NewPackedObj(constants[i].pvalue, constants[i].lvalue, *(constants[i].ptype));
+ break;
+ default:
+ obj = 0;
+ break;
+ }
+ if (obj) {
+ PyDict_SetItemString(d, constants[i].name, obj);
+ Py_DECREF(obj);
+ }
+ }
+ }
+
+ /* -----------------------------------------------------------------------------*/
+ /* Fix SwigMethods to carry the callback ptrs when needed */
+ /* -----------------------------------------------------------------------------*/
+
+ SWIGINTERN void
+ SWIG_Python_FixMethods(PyMethodDef *methods,
+ swig_const_info *const_table,
+ swig_type_info **types,
+ swig_type_info **types_initial) {
+ size_t i;
+ for (i = 0; methods[i].ml_name; ++i) {
+ const char *c = methods[i].ml_doc;
+ if (c && (c = strstr(c, "swig_ptr: "))) {
+ int j;
+ swig_const_info *ci = 0;
+ const char *name = c + 10;
+ for (j = 0; const_table[j].type; ++j) {
+ if (strncmp(const_table[j].name, name,
+ strlen(const_table[j].name)) == 0) {
+ ci = &(const_table[j]);
+ break;
+ }
+ }
+ if (ci) {
+ void *ptr = (ci->type == SWIG_PY_POINTER) ? ci->pvalue : 0;
+ if (ptr) {
+ size_t shift = (ci->ptype) - types;
+ swig_type_info *ty = types_initial[shift];
+ size_t ldoc = (c - methods[i].ml_doc);
+ size_t lptr = strlen(ty->name)+2*sizeof(void*)+2;
+ char *ndoc = (char*)malloc(ldoc + lptr + 10);
+ if (ndoc) {
+ char *buff = ndoc;
+ strncpy(buff, methods[i].ml_doc, ldoc);
+ buff += ldoc;
+ strncpy(buff, "swig_ptr: ", 10);
+ buff += 10;
+ SWIG_PackVoidPtr(buff, ptr, ty->name, lptr);
+ methods[i].ml_doc = ndoc;
+ }
+ }
+ }
+ }
+ }
+ }
+
+#ifdef __cplusplus
+}
+#endif
+
+/* -----------------------------------------------------------------------------*
+ * Partial Init method
+ * -----------------------------------------------------------------------------*/
+
+#ifdef __cplusplus
+extern "C"
+#endif
+
+SWIGEXPORT
+#if PY_VERSION_HEX >= 0x03000000
+PyObject*
+#else
+void
+#endif
+SWIG_init(void) {
+ PyObject *m, *d, *md;
+#if PY_VERSION_HEX >= 0x03000000
+ static struct PyModuleDef SWIG_module = {
+# if PY_VERSION_HEX >= 0x03020000
+ PyModuleDef_HEAD_INIT,
+# else
+ {
+ PyObject_HEAD_INIT(NULL)
+ NULL, /* m_init */
+ 0, /* m_index */
+ NULL, /* m_copy */
+ },
+# endif
+ (char *) SWIG_name,
+ NULL,
+ -1,
+ SwigMethods,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ };
+#endif
+
+#if defined(SWIGPYTHON_BUILTIN)
+ static SwigPyClientData SwigPyObject_clientdata = {
+ 0, 0, 0, 0, 0, 0, 0
+ };
+ static PyGetSetDef this_getset_def = {
+ (char *)"this", &SwigPyBuiltin_ThisClosure, NULL, NULL, NULL
+ };
+ static SwigPyGetSet thisown_getset_closure = {
+ (PyCFunction) SwigPyObject_own,
+ (PyCFunction) SwigPyObject_own
+ };
+ static PyGetSetDef thisown_getset_def = {
+ (char *)"thisown", SwigPyBuiltin_GetterClosure, SwigPyBuiltin_SetterClosure, NULL, &thisown_getset_closure
+ };
+ PyObject *metatype_args;
+ PyTypeObject *builtin_pytype;
+ int builtin_base_count;
+ swig_type_info *builtin_basetype;
+ PyObject *tuple;
+ PyGetSetDescrObject *static_getset;
+ PyTypeObject *metatype;
+ SwigPyClientData *cd;
+ PyObject *public_interface, *public_symbol;
+ PyObject *this_descr;
+ PyObject *thisown_descr;
+ int i;
+
+ (void)builtin_pytype;
+ (void)builtin_base_count;
+ (void)builtin_basetype;
+ (void)tuple;
+ (void)static_getset;
+
+ /* metatype is used to implement static member variables. */
+ metatype_args = Py_BuildValue("(s(O){})", "SwigPyObjectType", &PyType_Type);
+ assert(metatype_args);
+ metatype = (PyTypeObject *) PyType_Type.tp_call((PyObject *) &PyType_Type, metatype_args, NULL);
+ assert(metatype);
+ Py_DECREF(metatype_args);
+ metatype->tp_setattro = (setattrofunc) &SwigPyObjectType_setattro;
+ assert(PyType_Ready(metatype) >= 0);
+#endif
+
+ /* Fix SwigMethods to carry the callback ptrs when needed */
+ SWIG_Python_FixMethods(SwigMethods, swig_const_table, swig_types, swig_type_initial);
+
+#if PY_VERSION_HEX >= 0x03000000
+ m = PyModule_Create(&SWIG_module);
+#else
+ m = Py_InitModule((char *) SWIG_name, SwigMethods);
+#endif
+ md = d = PyModule_GetDict(m);
+ (void)md;
+
+ SWIG_InitializeModule(0);
+
+#ifdef SWIGPYTHON_BUILTIN
+ SwigPyObject_stype = SWIG_MangledTypeQuery("_p_SwigPyObject");
+ assert(SwigPyObject_stype);
+ cd = (SwigPyClientData*) SwigPyObject_stype->clientdata;
+ if (!cd) {
+ SwigPyObject_stype->clientdata = &SwigPyObject_clientdata;
+ SwigPyObject_clientdata.pytype = SwigPyObject_TypeOnce();
+ } else if (SwigPyObject_TypeOnce()->tp_basicsize != cd->pytype->tp_basicsize) {
+ PyErr_SetString(PyExc_RuntimeError, "Import error: attempted to load two incompatible swig-generated modules.");
+# if PY_VERSION_HEX >= 0x03000000
+ return NULL;
+# else
+ return;
+# endif
+ }
+
+ /* All objects have a 'this' attribute */
+ this_descr = PyDescr_NewGetSet(SwigPyObject_type(), &this_getset_def);
+ (void)this_descr;
+
+ /* All objects have a 'thisown' attribute */
+ thisown_descr = PyDescr_NewGetSet(SwigPyObject_type(), &thisown_getset_def);
+ (void)thisown_descr;
+
+ public_interface = PyList_New(0);
+ public_symbol = 0;
+ (void)public_symbol;
+
+ PyDict_SetItemString(md, "__all__", public_interface);
+ Py_DECREF(public_interface);
+ for (i = 0; SwigMethods[i].ml_name != NULL; ++i)
+ SwigPyBuiltin_AddPublicSymbol(public_interface, SwigMethods[i].ml_name);
+ for (i = 0; swig_const_table[i].name != 0; ++i)
+ SwigPyBuiltin_AddPublicSymbol(public_interface, swig_const_table[i].name);
+#endif
+
+ SWIG_InstallConstants(d,swig_const_table);
+
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "OPENSSL_VERSION_NUMBER",SWIG_From_long((long)(0x100020bfL)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "OPENSSL_VERSION_TEXT",SWIG_FromCharPtr("OpenSSL 1.0.2k 26 Jan 2017"));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "OPENSSL_VERSION_PTEXT",SWIG_FromCharPtr(" part of OpenSSL 1.0.2k 26 Jan 2017"));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "SHLIB_VERSION_HISTORY",SWIG_FromCharPtr(""));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "SHLIB_VERSION_NUMBER",SWIG_FromCharPtr("1.0.2k"));
+
+ /* type '::stack_st' */
+ builtin_pytype = (PyTypeObject *)&SwigPyBuiltin__stack_st_type;
+ builtin_pytype->tp_dict = d = PyDict_New();
+ SwigPyBuiltin_SetMetaType(builtin_pytype, metatype);
+ builtin_pytype->tp_new = PyType_GenericNew;
+ builtin_base_count = 0;
+ builtin_bases[builtin_base_count] = NULL;
+ SwigPyBuiltin_InitBases(builtin_pytype, builtin_bases);
+ PyDict_SetItemString(d, "this", this_descr);
+ PyDict_SetItemString(d, "thisown", thisown_descr);
+ if (PyType_Ready(builtin_pytype) < 0) {
+ PyErr_SetString(PyExc_TypeError, "Could not create type '_STACK'.");
+#if PY_VERSION_HEX >= 0x03000000
+ return NULL;
+#else
+ return;
+#endif
+ }
+ Py_INCREF(builtin_pytype);
+ PyModule_AddObject(m, "_STACK", (PyObject*) builtin_pytype);
+ SwigPyBuiltin_AddPublicSymbol(public_interface, "_STACK");
+ d = md;
+
+ /* type '::stack_st_OPENSSL_STRING' */
+ builtin_pytype = (PyTypeObject *)&SwigPyBuiltin__stack_st_OPENSSL_STRING_type;
+ builtin_pytype->tp_dict = d = PyDict_New();
+ SwigPyBuiltin_SetMetaType(builtin_pytype, metatype);
+ builtin_pytype->tp_new = PyType_GenericNew;
+ builtin_base_count = 0;
+ builtin_bases[builtin_base_count] = NULL;
+ SwigPyBuiltin_InitBases(builtin_pytype, builtin_bases);
+ PyDict_SetItemString(d, "this", this_descr);
+ PyDict_SetItemString(d, "thisown", thisown_descr);
+ if (PyType_Ready(builtin_pytype) < 0) {
+ PyErr_SetString(PyExc_TypeError, "Could not create type 'stack_st_OPENSSL_STRING'.");
+#if PY_VERSION_HEX >= 0x03000000
+ return NULL;
+#else
+ return;
+#endif
+ }
+ Py_INCREF(builtin_pytype);
+ PyModule_AddObject(m, "stack_st_OPENSSL_STRING", (PyObject*) builtin_pytype);
+ SwigPyBuiltin_AddPublicSymbol(public_interface, "stack_st_OPENSSL_STRING");
+ d = md;
+
+ /* type '::stack_st_OPENSSL_BLOCK' */
+ builtin_pytype = (PyTypeObject *)&SwigPyBuiltin__stack_st_OPENSSL_BLOCK_type;
+ builtin_pytype->tp_dict = d = PyDict_New();
+ SwigPyBuiltin_SetMetaType(builtin_pytype, metatype);
+ builtin_pytype->tp_new = PyType_GenericNew;
+ builtin_base_count = 0;
+ builtin_bases[builtin_base_count] = NULL;
+ SwigPyBuiltin_InitBases(builtin_pytype, builtin_bases);
+ PyDict_SetItemString(d, "this", this_descr);
+ PyDict_SetItemString(d, "thisown", thisown_descr);
+ if (PyType_Ready(builtin_pytype) < 0) {
+ PyErr_SetString(PyExc_TypeError, "Could not create type 'stack_st_OPENSSL_BLOCK'.");
+#if PY_VERSION_HEX >= 0x03000000
+ return NULL;
+#else
+ return;
+#endif
+ }
+ Py_INCREF(builtin_pytype);
+ PyModule_AddObject(m, "stack_st_OPENSSL_BLOCK", (PyObject*) builtin_pytype);
+ SwigPyBuiltin_AddPublicSymbol(public_interface, "stack_st_OPENSSL_BLOCK");
+ d = md;
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "bio_noclose",SWIG_From_int((int)(BIO_NOCLOSE)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "bio_close",SWIG_From_int((int)(BIO_CLOSE)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "BIO_FLAGS_READ",SWIG_From_int((int)(0x01)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "BIO_FLAGS_WRITE",SWIG_From_int((int)(0x02)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "BIO_FLAGS_IO_SPECIAL",SWIG_From_int((int)(0x04)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "BIO_FLAGS_RWS",SWIG_From_int((int)((BIO_FLAGS_READ|BIO_FLAGS_WRITE|BIO_FLAGS_IO_SPECIAL))));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "BIO_FLAGS_SHOULD_RETRY",SWIG_From_int((int)(0x08)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "BIO_FLAGS_MEM_RDONLY",SWIG_From_int((int)(0x200)));
+ PyDict_SetItemString(md,(char*)"cvar", SWIG_globals());
+ SwigPyBuiltin_AddPublicSymbol(public_interface, "cvar");
+ SWIG_addvarlink(SWIG_globals(),(char*)"_bio_err",Swig_var__bio_err_get, Swig_var__bio_err_set);
+
+ /* type '::pyfd_struct' */
+ builtin_pytype = (PyTypeObject *)&SwigPyBuiltin__pyfd_struct_type;
+ builtin_pytype->tp_dict = d = PyDict_New();
+ SwigPyBuiltin_SetMetaType(builtin_pytype, metatype);
+ builtin_pytype->tp_new = PyType_GenericNew;
+ builtin_base_count = 0;
+ builtin_bases[builtin_base_count] = NULL;
+ SwigPyBuiltin_InitBases(builtin_pytype, builtin_bases);
+ PyDict_SetItemString(d, "this", this_descr);
+ PyDict_SetItemString(d, "thisown", thisown_descr);
+ if (PyType_Ready(builtin_pytype) < 0) {
+ PyErr_SetString(PyExc_TypeError, "Could not create type 'BIO_PYFD_CTX'.");
+#if PY_VERSION_HEX >= 0x03000000
+ return NULL;
+#else
+ return;
+#endif
+ }
+ Py_INCREF(builtin_pytype);
+ PyModule_AddObject(m, "BIO_PYFD_CTX", (PyObject*) builtin_pytype);
+ SwigPyBuiltin_AddPublicSymbol(public_interface, "BIO_PYFD_CTX");
+ d = md;
+ SWIG_addvarlink(SWIG_globals(),(char*)"methods_fdp",Swig_var_methods_fdp_get, Swig_var_methods_fdp_set);
+ SWIG_addvarlink(SWIG_globals(),(char*)"_rand_err",Swig_var__rand_err_get, Swig_var__rand_err_set);
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "PKCS5_SALT_LEN",SWIG_From_int((int)(8)));
+ SWIG_addvarlink(SWIG_globals(),(char*)"_evp_err",Swig_var__evp_err_get, Swig_var__evp_err_set);
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "AES_BLOCK_SIZE",SWIG_From_int((int)(AES_BLOCK_SIZE)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "OPENSSL_NO_RC4",SWIG_From_int((int)(0)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "dh_check_ok",SWIG_From_int((int)(0)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "dh_check_p_not_prime",SWIG_From_int((int)(DH_CHECK_P_NOT_PRIME)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "dh_check_p_not_strong",SWIG_From_int((int)(DH_CHECK_P_NOT_STRONG_PRIME)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "dh_check_g_failed",SWIG_From_int((int)(DH_UNABLE_TO_CHECK_GENERATOR)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "dh_check_bad_g",SWIG_From_int((int)(DH_NOT_SUITABLE_GENERATOR)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "DH_GENERATOR_2",SWIG_From_int((int)(2)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "DH_GENERATOR_5",SWIG_From_int((int)(5)));
+ SWIG_addvarlink(SWIG_globals(),(char*)"_dh_err",Swig_var__dh_err_get, Swig_var__dh_err_set);
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "no_padding",SWIG_From_int((int)(RSA_NO_PADDING)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "pkcs1_padding",SWIG_From_int((int)(RSA_PKCS1_PADDING)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "sslv23_padding",SWIG_From_int((int)(RSA_SSLV23_PADDING)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "pkcs1_oaep_padding",SWIG_From_int((int)(RSA_PKCS1_OAEP_PADDING)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_sha1",SWIG_From_int((int)(NID_sha1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_sha224",SWIG_From_int((int)(NID_sha224)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_sha256",SWIG_From_int((int)(NID_sha256)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_sha384",SWIG_From_int((int)(NID_sha384)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_sha512",SWIG_From_int((int)(NID_sha512)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_md5",SWIG_From_int((int)(NID_md5)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_ripemd160",SWIG_From_int((int)(NID_ripemd160)));
+ SWIG_addvarlink(SWIG_globals(),(char*)"_rsa_err",Swig_var__rsa_err_get, Swig_var__rsa_err_set);
+ SWIG_addvarlink(SWIG_globals(),(char*)"_dsa_err",Swig_var__dsa_err_get, Swig_var__dsa_err_set);
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "ssl_error_none",SWIG_From_int((int)(SSL_ERROR_NONE)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "ssl_error_ssl",SWIG_From_int((int)(SSL_ERROR_SSL)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "ssl_error_want_read",SWIG_From_int((int)(SSL_ERROR_WANT_READ)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "ssl_error_want_write",SWIG_From_int((int)(SSL_ERROR_WANT_WRITE)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "ssl_error_want_x509_lookup",SWIG_From_int((int)(SSL_ERROR_WANT_X509_LOOKUP)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "ssl_error_syscall",SWIG_From_int((int)(SSL_ERROR_SYSCALL)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "ssl_error_zero_return",SWIG_From_int((int)(SSL_ERROR_ZERO_RETURN)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "ssl_error_want_connect",SWIG_From_int((int)(SSL_ERROR_WANT_CONNECT)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "SSL_VERIFY_NONE",SWIG_From_int((int)(0x00)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "SSL_VERIFY_PEER",SWIG_From_int((int)(0x01)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "SSL_VERIFY_FAIL_IF_NO_PEER_CERT",SWIG_From_int((int)(0x02)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "SSL_VERIFY_CLIENT_ONCE",SWIG_From_int((int)(0x04)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "SSL_ST_CONNECT",SWIG_From_int((int)(0x1000)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "SSL_ST_ACCEPT",SWIG_From_int((int)(0x2000)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "SSL_ST_MASK",SWIG_From_int((int)(0x0FFF)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "SSL_ST_INIT",SWIG_From_int((int)((SSL_ST_CONNECT|SSL_ST_ACCEPT))));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "SSL_ST_BEFORE",SWIG_From_int((int)(0x4000)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "SSL_ST_OK",SWIG_From_int((int)(0x03)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "SSL_ST_RENEGOTIATE",SWIG_From_int((int)((0x04|SSL_ST_CONNECT|SSL_ST_ACCEPT))));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "SSL_CB_LOOP",SWIG_From_int((int)(0x01)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "SSL_CB_EXIT",SWIG_From_int((int)(0x02)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "SSL_CB_READ",SWIG_From_int((int)(0x04)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "SSL_CB_WRITE",SWIG_From_int((int)(0x08)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "SSL_CB_ALERT",SWIG_From_int((int)(0x4000)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "SSL_CB_READ_ALERT",SWIG_From_int((int)((SSL_CB_ALERT|SSL_CB_READ))));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "SSL_CB_WRITE_ALERT",SWIG_From_int((int)((SSL_CB_ALERT|SSL_CB_WRITE))));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "SSL_CB_ACCEPT_LOOP",SWIG_From_int((int)((SSL_ST_ACCEPT|SSL_CB_LOOP))));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "SSL_CB_ACCEPT_EXIT",SWIG_From_int((int)((SSL_ST_ACCEPT|SSL_CB_EXIT))));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "SSL_CB_CONNECT_LOOP",SWIG_From_int((int)((SSL_ST_CONNECT|SSL_CB_LOOP))));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "SSL_CB_CONNECT_EXIT",SWIG_From_int((int)((SSL_ST_CONNECT|SSL_CB_EXIT))));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "SSL_CB_HANDSHAKE_START",SWIG_From_int((int)(0x10)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "SSL_CB_HANDSHAKE_DONE",SWIG_From_int((int)(0x20)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "SSL_SENT_SHUTDOWN",SWIG_From_int((int)(1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "SSL_RECEIVED_SHUTDOWN",SWIG_From_int((int)(2)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "SSL_SESS_CACHE_OFF",SWIG_From_int((int)(0x000)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "SSL_SESS_CACHE_CLIENT",SWIG_From_int((int)(0x001)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "SSL_SESS_CACHE_SERVER",SWIG_From_int((int)(0x002)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "SSL_SESS_CACHE_BOTH",SWIG_From_int((int)((SSL_SESS_CACHE_CLIENT|SSL_SESS_CACHE_SERVER))));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "SSL_OP_ALL",SWIG_From_int((int)(0x00000FFFL)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "SSL_OP_NO_SSLv2",SWIG_From_int((int)(0x01000000L)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "SSL_OP_NO_SSLv3",SWIG_From_int((int)(0x02000000L)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "SSL_OP_NO_TLSv1",SWIG_From_int((int)(0x04000000L)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS",SWIG_From_int((int)(0x00000800L)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "SSL_MODE_ENABLE_PARTIAL_WRITE",SWIG_From_int((int)(SSL_MODE_ENABLE_PARTIAL_WRITE)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER",SWIG_From_int((int)(SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "SSL_MODE_AUTO_RETRY",SWIG_From_int((int)(SSL_MODE_AUTO_RETRY)));
+ SWIG_addvarlink(SWIG_globals(),(char*)"_ssl_err",Swig_var__ssl_err_get, Swig_var__ssl_err_set);
+ SWIG_addvarlink(SWIG_globals(),(char*)"_ssl_timeout_err",Swig_var__ssl_timeout_err_get, Swig_var__ssl_timeout_err_set);
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_TRUST_DEFAULT",SWIG_From_int((int)(-1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_TRUST_COMPAT",SWIG_From_int((int)(1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_TRUST_SSL_CLIENT",SWIG_From_int((int)(2)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_TRUST_SSL_SERVER",SWIG_From_int((int)(3)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_TRUST_EMAIL",SWIG_From_int((int)(4)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_TRUST_OBJECT_SIGN",SWIG_From_int((int)(5)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_TRUST_OCSP_SIGN",SWIG_From_int((int)(6)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_TRUST_OCSP_REQUEST",SWIG_From_int((int)(7)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_TRUST_DYNAMIC",SWIG_From_int((int)(1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_TRUST_DYNAMIC_NAME",SWIG_From_int((int)(2)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_TRUST_TRUSTED",SWIG_From_int((int)(1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_TRUST_REJECTED",SWIG_From_int((int)(2)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_TRUST_UNTRUSTED",SWIG_From_int((int)(3)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_PURPOSE_SSL_CLIENT",SWIG_From_int((int)(1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_PURPOSE_SSL_SERVER",SWIG_From_int((int)(2)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_PURPOSE_NS_SSL_SERVER",SWIG_From_int((int)(3)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_PURPOSE_SMIME_SIGN",SWIG_From_int((int)(4)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_PURPOSE_SMIME_ENCRYPT",SWIG_From_int((int)(5)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_PURPOSE_CRL_SIGN",SWIG_From_int((int)(6)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_PURPOSE_ANY",SWIG_From_int((int)(7)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_PURPOSE_OCSP_HELPER",SWIG_From_int((int)(8)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509V3_EXT_UNKNOWN_MASK",SWIG_From_long((long)((0xfL << 16))));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509V3_EXT_DEFAULT",SWIG_From_long((long)(0)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509V3_EXT_ERROR_UNKNOWN",SWIG_From_long((long)((1L << 16))));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509V3_EXT_PARSE_UNKNOWN",SWIG_From_long((long)((2L << 16))));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509V3_EXT_DUMP_UNKNOWN",SWIG_From_long((long)((3L << 16))));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_commonName",SWIG_From_int((int)(13)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_countryName",SWIG_From_int((int)(14)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_localityName",SWIG_From_int((int)(15)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_stateOrProvinceName",SWIG_From_int((int)(16)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_organizationName",SWIG_From_int((int)(17)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_organizationalUnitName",SWIG_From_int((int)(18)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_serialNumber",SWIG_From_int((int)(105)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_surname",SWIG_From_int((int)(100)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_givenName",SWIG_From_int((int)(99)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_pkcs9_emailAddress",SWIG_From_int((int)(48)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_V_OK",SWIG_From_int((int)(0)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT",SWIG_From_int((int)(2)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_V_ERR_UNABLE_TO_GET_CRL",SWIG_From_int((int)(3)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE",SWIG_From_int((int)(4)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE",SWIG_From_int((int)(5)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY",SWIG_From_int((int)(6)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_V_ERR_CERT_SIGNATURE_FAILURE",SWIG_From_int((int)(7)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_V_ERR_CRL_SIGNATURE_FAILURE",SWIG_From_int((int)(8)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_V_ERR_CERT_NOT_YET_VALID",SWIG_From_int((int)(9)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_V_ERR_CERT_HAS_EXPIRED",SWIG_From_int((int)(10)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_V_ERR_CRL_NOT_YET_VALID",SWIG_From_int((int)(11)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_V_ERR_CRL_HAS_EXPIRED",SWIG_From_int((int)(12)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD",SWIG_From_int((int)(13)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD",SWIG_From_int((int)(14)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD",SWIG_From_int((int)(15)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD",SWIG_From_int((int)(16)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_V_ERR_OUT_OF_MEM",SWIG_From_int((int)(17)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT",SWIG_From_int((int)(18)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN",SWIG_From_int((int)(19)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY",SWIG_From_int((int)(20)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE",SWIG_From_int((int)(21)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_V_ERR_CERT_CHAIN_TOO_LONG",SWIG_From_int((int)(22)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_V_ERR_CERT_REVOKED",SWIG_From_int((int)(23)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_V_ERR_INVALID_CA",SWIG_From_int((int)(24)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_V_ERR_PATH_LENGTH_EXCEEDED",SWIG_From_int((int)(25)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_V_ERR_INVALID_PURPOSE",SWIG_From_int((int)(26)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_V_ERR_CERT_UNTRUSTED",SWIG_From_int((int)(27)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_V_ERR_CERT_REJECTED",SWIG_From_int((int)(28)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "X509_V_ERR_APPLICATION_VERIFICATION",SWIG_From_int((int)(50)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "XN_FLAG_COMPAT",SWIG_From_int((int)(0)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "XN_FLAG_SEP_COMMA_PLUS",SWIG_From_int((int)((1 << 16))));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "XN_FLAG_SEP_CPLUS_SPC",SWIG_From_int((int)((2 << 16))));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "XN_FLAG_SEP_MULTILINE",SWIG_From_int((int)((4 << 16))));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "XN_FLAG_DN_REV",SWIG_From_int((int)((1 << 20))));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "XN_FLAG_FN_LN",SWIG_From_int((int)((1 << 21))));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "XN_FLAG_SPC_EQ",SWIG_From_int((int)((1 << 23))));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "XN_FLAG_DUMP_UNKNOWN_FIELDS",SWIG_From_int((int)((1 << 24))));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "XN_FLAG_FN_ALIGN",SWIG_From_int((int)((1 << 25))));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "XN_FLAG_ONELINE",SWIG_From_int((int)((ASN1_STRFLGS_RFC2253|ASN1_STRFLGS_ESC_QUOTE|XN_FLAG_SEP_CPLUS_SPC|XN_FLAG_SPC_EQ))));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "XN_FLAG_MULTILINE",SWIG_From_int((int)((ASN1_STRFLGS_ESC_CTRL|ASN1_STRFLGS_ESC_MSB|XN_FLAG_SEP_MULTILINE|XN_FLAG_SPC_EQ|XN_FLAG_FN_LN|XN_FLAG_FN_ALIGN))));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "XN_FLAG_RFC2253",SWIG_From_int((int)((ASN1_STRFLGS_RFC2253|XN_FLAG_SEP_COMMA_PLUS|XN_FLAG_DN_REV|XN_FLAG_DUMP_UNKNOWN_FIELDS))));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "RSA_3",SWIG_From_int((int)(0x3L)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "RSA_F4",SWIG_From_int((int)(0x10001L)));
+ SWIG_addvarlink(SWIG_globals(),(char*)"_x509_err",Swig_var__x509_err_get, Swig_var__x509_err_set);
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "ASN1_STRFLGS_ESC_2253",SWIG_From_int((int)(1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "ASN1_STRFLGS_ESC_CTRL",SWIG_From_int((int)(2)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "ASN1_STRFLGS_ESC_MSB",SWIG_From_int((int)(4)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "ASN1_STRFLGS_ESC_QUOTE",SWIG_From_int((int)(8)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "ASN1_STRFLGS_UTF8_CONVERT",SWIG_From_int((int)(0x10)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "ASN1_STRFLGS_IGNORE_TYPE",SWIG_From_int((int)(0x20)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "ASN1_STRFLGS_SHOW_TYPE",SWIG_From_int((int)(0x40)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "ASN1_STRFLGS_DUMP_ALL",SWIG_From_int((int)(0x80)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "ASN1_STRFLGS_DUMP_UNKNOWN",SWIG_From_int((int)(0x100)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "ASN1_STRFLGS_DUMP_DER",SWIG_From_int((int)(0x200)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "ASN1_STRFLGS_RFC2253",SWIG_From_int((int)((ASN1_STRFLGS_ESC_2253|ASN1_STRFLGS_ESC_CTRL|ASN1_STRFLGS_ESC_MSB|ASN1_STRFLGS_UTF8_CONVERT|ASN1_STRFLGS_DUMP_UNKNOWN|ASN1_STRFLGS_DUMP_DER))));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "PKCS7_TEXT",SWIG_From_int((int)(0x1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "PKCS7_NOCERTS",SWIG_From_int((int)(0x2)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "PKCS7_NOSIGS",SWIG_From_int((int)(0x4)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "PKCS7_NOCHAIN",SWIG_From_int((int)(0x8)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "PKCS7_NOINTERN",SWIG_From_int((int)(0x10)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "PKCS7_NOVERIFY",SWIG_From_int((int)(0x20)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "PKCS7_DETACHED",SWIG_From_int((int)(0x40)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "PKCS7_BINARY",SWIG_From_int((int)(0x80)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "PKCS7_NOATTR",SWIG_From_int((int)(0x100)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "PKCS7_SIGNED",SWIG_From_int((int)(NID_pkcs7_signed)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "PKCS7_ENVELOPED",SWIG_From_int((int)(NID_pkcs7_enveloped)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "PKCS7_SIGNED_ENVELOPED",SWIG_From_int((int)(NID_pkcs7_signedAndEnveloped)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "PKCS7_DATA",SWIG_From_int((int)(NID_pkcs7_data)));
+ SWIG_addvarlink(SWIG_globals(),(char*)"_pkcs7_err",Swig_var__pkcs7_err_get, Swig_var__pkcs7_err_set);
+ SWIG_addvarlink(SWIG_globals(),(char*)"_smime_err",Swig_var__smime_err_get, Swig_var__smime_err_set);
+ SWIG_addvarlink(SWIG_globals(),(char*)"_util_err",Swig_var__util_err_get, Swig_var__util_err_set);
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "OPENSSL_NO_EC",SWIG_From_int((int)(0)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_secp112r1",SWIG_From_int((int)(NID_secp112r1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_secp112r2",SWIG_From_int((int)(NID_secp112r2)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_secp128r1",SWIG_From_int((int)(NID_secp128r1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_secp128r2",SWIG_From_int((int)(NID_secp128r2)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_secp160k1",SWIG_From_int((int)(NID_secp160k1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_secp160r1",SWIG_From_int((int)(NID_secp160r1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_secp160r2",SWIG_From_int((int)(NID_secp160r2)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_secp192k1",SWIG_From_int((int)(NID_secp192k1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_secp224k1",SWIG_From_int((int)(NID_secp224k1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_secp224r1",SWIG_From_int((int)(NID_secp224r1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_secp256k1",SWIG_From_int((int)(NID_secp256k1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_secp384r1",SWIG_From_int((int)(NID_secp384r1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_secp521r1",SWIG_From_int((int)(NID_secp521r1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_sect113r1",SWIG_From_int((int)(NID_sect113r1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_sect113r2",SWIG_From_int((int)(NID_sect113r2)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_sect131r1",SWIG_From_int((int)(NID_sect131r1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_sect131r2",SWIG_From_int((int)(NID_sect131r2)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_sect163k1",SWIG_From_int((int)(NID_sect163k1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_sect163r1",SWIG_From_int((int)(NID_sect163r1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_sect163r2",SWIG_From_int((int)(NID_sect163r2)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_sect193r1",SWIG_From_int((int)(NID_sect193r1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_sect193r2",SWIG_From_int((int)(NID_sect193r2)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_sect233k1",SWIG_From_int((int)(NID_sect233k1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_sect233r1",SWIG_From_int((int)(NID_sect233r1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_sect239k1",SWIG_From_int((int)(NID_sect239k1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_sect283k1",SWIG_From_int((int)(NID_sect283k1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_sect283r1",SWIG_From_int((int)(NID_sect283r1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_sect409k1",SWIG_From_int((int)(NID_sect409k1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_sect409r1",SWIG_From_int((int)(NID_sect409r1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_sect571k1",SWIG_From_int((int)(NID_sect571k1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_sect571r1",SWIG_From_int((int)(NID_sect571r1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_X9_62_prime192v1",SWIG_From_int((int)(NID_X9_62_prime192v1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_X9_62_prime192v2",SWIG_From_int((int)(NID_X9_62_prime192v2)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_X9_62_prime192v3",SWIG_From_int((int)(NID_X9_62_prime192v3)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_X9_62_prime239v1",SWIG_From_int((int)(NID_X9_62_prime239v1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_X9_62_prime239v2",SWIG_From_int((int)(NID_X9_62_prime239v2)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_X9_62_prime239v3",SWIG_From_int((int)(NID_X9_62_prime239v3)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_X9_62_prime256v1",SWIG_From_int((int)(NID_X9_62_prime256v1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_X9_62_c2pnb163v1",SWIG_From_int((int)(NID_X9_62_c2pnb163v1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_X9_62_c2pnb163v2",SWIG_From_int((int)(NID_X9_62_c2pnb163v2)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_X9_62_c2pnb163v3",SWIG_From_int((int)(NID_X9_62_c2pnb163v3)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_X9_62_c2pnb176v1",SWIG_From_int((int)(NID_X9_62_c2pnb176v1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_X9_62_c2tnb191v1",SWIG_From_int((int)(NID_X9_62_c2tnb191v1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_X9_62_c2tnb191v2",SWIG_From_int((int)(NID_X9_62_c2tnb191v2)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_X9_62_c2tnb191v3",SWIG_From_int((int)(NID_X9_62_c2tnb191v3)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_X9_62_c2pnb208w1",SWIG_From_int((int)(NID_X9_62_c2pnb208w1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_X9_62_c2tnb239v1",SWIG_From_int((int)(NID_X9_62_c2tnb239v1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_X9_62_c2tnb239v2",SWIG_From_int((int)(NID_X9_62_c2tnb239v2)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_X9_62_c2tnb239v3",SWIG_From_int((int)(NID_X9_62_c2tnb239v3)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_X9_62_c2pnb272w1",SWIG_From_int((int)(NID_X9_62_c2pnb272w1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_X9_62_c2pnb304w1",SWIG_From_int((int)(NID_X9_62_c2pnb304w1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_X9_62_c2tnb359v1",SWIG_From_int((int)(NID_X9_62_c2tnb359v1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_X9_62_c2pnb368w1",SWIG_From_int((int)(NID_X9_62_c2pnb368w1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_X9_62_c2tnb431r1",SWIG_From_int((int)(NID_X9_62_c2tnb431r1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_wap_wsg_idm_ecid_wtls1",SWIG_From_int((int)(NID_wap_wsg_idm_ecid_wtls1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_wap_wsg_idm_ecid_wtls3",SWIG_From_int((int)(NID_wap_wsg_idm_ecid_wtls3)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_wap_wsg_idm_ecid_wtls4",SWIG_From_int((int)(NID_wap_wsg_idm_ecid_wtls4)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_wap_wsg_idm_ecid_wtls5",SWIG_From_int((int)(NID_wap_wsg_idm_ecid_wtls5)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_wap_wsg_idm_ecid_wtls6",SWIG_From_int((int)(NID_wap_wsg_idm_ecid_wtls6)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_wap_wsg_idm_ecid_wtls7",SWIG_From_int((int)(NID_wap_wsg_idm_ecid_wtls7)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_wap_wsg_idm_ecid_wtls8",SWIG_From_int((int)(NID_wap_wsg_idm_ecid_wtls8)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_wap_wsg_idm_ecid_wtls9",SWIG_From_int((int)(NID_wap_wsg_idm_ecid_wtls9)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_wap_wsg_idm_ecid_wtls10",SWIG_From_int((int)(NID_wap_wsg_idm_ecid_wtls10)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_wap_wsg_idm_ecid_wtls11",SWIG_From_int((int)(NID_wap_wsg_idm_ecid_wtls11)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_wap_wsg_idm_ecid_wtls12",SWIG_From_int((int)(NID_wap_wsg_idm_ecid_wtls12)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_ipsec3",SWIG_From_int((int)(NID_ipsec3)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "NID_ipsec4",SWIG_From_int((int)(NID_ipsec4)));
+ SWIG_addvarlink(SWIG_globals(),(char*)"_ec_err",Swig_var__ec_err_get, Swig_var__ec_err_set);
+
+ /* type '::_cbd_t' */
+ builtin_pytype = (PyTypeObject *)&SwigPyBuiltin___cbd_t_type;
+ builtin_pytype->tp_dict = d = PyDict_New();
+ SwigPyBuiltin_SetMetaType(builtin_pytype, metatype);
+ builtin_pytype->tp_new = PyType_GenericNew;
+ builtin_base_count = 0;
+ builtin_bases[builtin_base_count] = NULL;
+ SwigPyBuiltin_InitBases(builtin_pytype, builtin_bases);
+ PyDict_SetItemString(d, "this", this_descr);
+ PyDict_SetItemString(d, "thisown", thisown_descr);
+ if (PyType_Ready(builtin_pytype) < 0) {
+ PyErr_SetString(PyExc_TypeError, "Could not create type '_cbd_t'.");
+#if PY_VERSION_HEX >= 0x03000000
+ return NULL;
+#else
+ return;
+#endif
+ }
+ Py_INCREF(builtin_pytype);
+ PyModule_AddObject(m, "_cbd_t", (PyObject*) builtin_pytype);
+ SwigPyBuiltin_AddPublicSymbol(public_interface, "_cbd_t");
+ d = md;
+ SWIG_addvarlink(SWIG_globals(),(char*)"_engine_err",Swig_var__engine_err_get, Swig_var__engine_err_set);
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "ENGINE_METHOD_RSA",SWIG_From_int((int)(0x0001)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "ENGINE_METHOD_DSA",SWIG_From_int((int)(0x0002)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "ENGINE_METHOD_DH",SWIG_From_int((int)(0x0004)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "ENGINE_METHOD_RAND",SWIG_From_int((int)(0x0008)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "ENGINE_METHOD_ECDH",SWIG_From_int((int)(0x0010)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "ENGINE_METHOD_ECDSA",SWIG_From_int((int)(0x0020)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "ENGINE_METHOD_CIPHERS",SWIG_From_int((int)(0x0040)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "ENGINE_METHOD_DIGESTS",SWIG_From_int((int)(0x0080)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "ENGINE_METHOD_STORE",SWIG_From_int((int)(0x0100)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "ENGINE_METHOD_ALL",SWIG_From_int((int)(0xFFFF)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "ENGINE_METHOD_NONE",SWIG_From_int((int)(0x0000)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "encrypt",SWIG_From_int((int)(1)));
+ SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, "decrypt",SWIG_From_int((int)(0)));
+
+ /* Initialize threading */
+ SWIG_PYTHON_INITIALIZE_THREADS;
+#if PY_VERSION_HEX >= 0x03000000
+ return m;
+#else
+ return;
+#endif
+}
+
diff --git a/SWIG/_objects.i b/SWIG/_objects.i
index 40f5e51..b389d7f 100644
--- a/SWIG/_objects.i
+++ b/SWIG/_objects.i
@@ -3,7 +3,7 @@
* vim: syntax=c sts=4 sw=4
*
* ASN1_OBJECT manipulation functions from OBJ_obj2txt(3SSL).
- *
+ *
* Pavel Shramov
* IMEC MSU
*/
@@ -68,7 +68,7 @@ PyObject *obj_obj2txt(const ASN1_OBJECT *obj, int no_name)
len = OBJ_obj2txt(dummy, 1, obj, no_name);
if (len < 0) {
- PyErr_SetString(PyExc_RuntimeError, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(PyExc_RuntimeError);
return NULL;
} else if (len == 0) {
/* XXX: For OpenSSL prior to 0.9.8b.
@@ -87,7 +87,9 @@ PyObject *obj_obj2txt(const ASN1_OBJECT *obj, int no_name)
buf = PyMem_Malloc(len + 1);
len = OBJ_obj2txt(buf, len + 1, obj, no_name);
- ret = PyString_FromStringAndSize(buf, len);
+
+ ret = PyBytes_FromStringAndSize(buf, len);
+
PyMem_Free(buf);
return ret;
diff --git a/SWIG/_pkcs7.i b/SWIG/_pkcs7.i
index 174f40a..d1fddfb 100644
--- a/SWIG/_pkcs7.i
+++ b/SWIG/_pkcs7.i
@@ -1,7 +1,7 @@
/* Copyright (c) 2000 Ng Pheng Siong. All rights reserved.
* Copyright (c) 2009-2010 Heikki Toivonen. All rights reserved.
*/
-/* $Id: _pkcs7.i 723 2010-02-13 06:53:13Z heikki $ */
+/* $Id$ */
%{
#include <openssl/bio.h>
@@ -40,6 +40,8 @@ extern void PKCS7_add_certificate(PKCS7 *, X509 *);
%constant int PKCS7_SIGNED_ENVELOPED = NID_pkcs7_signedAndEnveloped;
%constant int PKCS7_DATA = NID_pkcs7_data;
+%warnfilter(454) _pkcs7_err;
+%warnfilter(454) _smime_err;
%inline %{
static PyObject *_pkcs7_err, *_smime_err;
@@ -54,24 +56,19 @@ void smime_init(PyObject *smime_err) {
}
%}
-%threadallow pkcs7_encrypt;
%inline %{
-PKCS7 *pkcs7_encrypt(STACK_OF(X509) *stack, BIO *bio, EVP_CIPHER *cipher, int flags) {
- return PKCS7_encrypt(stack, bio, cipher, flags);
-}
-
PyObject *pkcs7_decrypt(PKCS7 *pkcs7, EVP_PKEY *pkey, X509 *cert, int flags) {
int outlen;
char *outbuf;
BIO *bio;
- PyObject *ret;
+ PyObject *ret;
if (!(bio=BIO_new(BIO_s_mem()))) {
PyErr_SetString(PyExc_MemoryError, "pkcs7_decrypt");
return NULL;
}
if (!PKCS7_decrypt(pkcs7, pkey, cert, bio, flags)) {
- PyErr_SetString(_pkcs7_err, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(_pkcs7_err);
BIO_free(bio);
return NULL;
}
@@ -82,33 +79,90 @@ PyObject *pkcs7_decrypt(PKCS7 *pkcs7, EVP_PKEY *pkey, X509 *cert, int flags) {
return NULL;
}
BIO_read(bio, outbuf, outlen);
- ret = PyString_FromStringAndSize(outbuf, outlen);
+
+ ret = PyBytes_FromStringAndSize(outbuf, outlen);
+
BIO_free(bio);
PyMem_Free(outbuf);
return ret;
}
%}
-%threadallow pkcs7_sign0;
+%typemap(out) PKCS7 * {
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+
+ if ($1 != NULL)
+ $result = SWIG_NewPointerObj($1, $1_descriptor, 0);
+ else {
+ m2_PyErr_Msg(_smime_err);
+ $result = NULL;
+ }
+}
+%threadallow pkcs7_encrypt;
%inline %{
-PKCS7 *pkcs7_sign0(X509 *x509, EVP_PKEY *pkey, BIO *bio, int flags) {
- return PKCS7_sign(x509, pkey, NULL, bio, flags);
+PKCS7 *pkcs7_encrypt(STACK_OF(X509) *stack, BIO *bio, EVP_CIPHER *cipher, int flags) {
+ return PKCS7_encrypt(stack, bio, cipher, flags);
}
+
%}
%threadallow pkcs7_sign1;
%inline %{
-PKCS7 *pkcs7_sign1(X509 *x509, EVP_PKEY *pkey, STACK_OF(X509) *stack, BIO *bio, int flags) {
- return PKCS7_sign(x509, pkey, stack, bio, flags);
+PKCS7 *pkcs7_sign1(X509 *x509, EVP_PKEY *pkey, STACK_OF(X509) *stack, BIO *bio, EVP_MD *hash, int flags) {
+
+ PKCS7 *p7 = PKCS7_sign(NULL, NULL, stack, bio, flags | PKCS7_STREAM);
+ if (p7 == NULL) {
+ return NULL;
+ }
+ if (PKCS7_sign_add_signer(p7, x509, pkey, hash, flags) == NULL) {
+ return NULL;
+ }
+ if (PKCS7_final(p7, bio, flags) != 1) {
+ return NULL;
+ }
+ return p7;
}
%}
+%threadallow pkcs7_sign0;
+%inline %{
+PKCS7 *pkcs7_sign0(X509 *x509, EVP_PKEY *pkey, BIO *bio, EVP_MD *hash, int flags) {
+ return pkcs7_sign1(x509, pkey, NULL, bio, hash, flags);
+}
+%}
+
+%typemap(out) PKCS7 * {
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+
+ if ($1 != NULL)
+ $result = SWIG_NewPointerObj($1, $1_descriptor, 0);
+ else {
+ m2_PyErr_Msg(_pkcs7_err);
+ $result = NULL;
+ }
+}
+%threadallow pkcs7_read_bio;
+%inline %{
+PKCS7 *pkcs7_read_bio(BIO *bio) {
+ return PEM_read_bio_PKCS7(bio, NULL, NULL, NULL);
+}
+%}
+
+%threadallow pkcs7_read_bio_der;
+%inline %{
+PKCS7 *pkcs7_read_bio_der(BIO *bio) {
+ return d2i_PKCS7_bio(bio, NULL);
+}
+%}
+
+%typemap(out) PKCS7 * ;
+
%inline %{
PyObject *pkcs7_verify1(PKCS7 *pkcs7, STACK_OF(X509) *stack, X509_STORE *store, BIO *data, int flags) {
int res, outlen;
char *outbuf;
BIO *bio;
- PyObject *ret;
+ PyObject *ret;
if (!(bio=BIO_new(BIO_s_mem()))) {
PyErr_SetString(PyExc_MemoryError, "pkcs7_verify1");
@@ -118,7 +172,7 @@ PyObject *pkcs7_verify1(PKCS7 *pkcs7, STACK_OF(X509) *stack, X509_STORE *store,
res = PKCS7_verify(pkcs7, stack, store, data, bio, flags);
Py_END_ALLOW_THREADS
if (!res) {
- PyErr_SetString(_pkcs7_err, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(_pkcs7_err);
BIO_free(bio);
return NULL;
}
@@ -129,7 +183,9 @@ PyObject *pkcs7_verify1(PKCS7 *pkcs7, STACK_OF(X509) *stack, X509_STORE *store,
return NULL;
}
BIO_read(bio, outbuf, outlen);
- ret = PyString_FromStringAndSize(outbuf, outlen);
+
+ ret = PyBytes_FromStringAndSize(outbuf, outlen);
+
BIO_free(bio);
PyMem_Free(outbuf);
return ret;
@@ -157,6 +213,7 @@ PyObject *smime_read_pkcs7(BIO *bio) {
BIO *bcont = NULL;
PKCS7 *p7;
PyObject *tuple, *_p7, *_BIO;
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
if (BIO_method_type(bio) == BIO_TYPE_MEM) {
/* OpenSSL FAQ explains that this is needed for mem BIO to return EOF,
@@ -170,7 +227,7 @@ PyObject *smime_read_pkcs7(BIO *bio) {
p7=SMIME_read_PKCS7(bio, &bcont);
Py_END_ALLOW_THREADS
if (!p7) {
- PyErr_SetString(_smime_err, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(_smime_err);
return NULL;
}
if (!(tuple=PyTuple_New(2))) {
@@ -190,20 +247,6 @@ PyObject *smime_read_pkcs7(BIO *bio) {
}
%}
-%threadallow pkcs7_read_bio;
-%inline %{
-PKCS7 *pkcs7_read_bio(BIO *bio) {
- return PEM_read_bio_PKCS7(bio, NULL, NULL, NULL);
-}
-%}
-
-%threadallow pkcs7_read_bio_der;
-%inline %{
-PKCS7 *pkcs7_read_bio_der(BIO *bio) {
- return d2i_PKCS7_bio(bio, NULL);
-}
-%}
-
%threadallow pkcs7_write_bio;
%inline %{
int pkcs7_write_bio(PKCS7 *pkcs7, BIO* bio) {
@@ -232,9 +275,9 @@ int smime_crlf_copy(BIO *in, BIO *out) {
return SMIME_crlf_copy(in, out, PKCS7_TEXT);
}
-/* return STACK_OF(X509)* */
-STACK_OF(X509) *pkcs7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags) {
- return PKCS7_get0_signers(p7, certs, flags);
+/* return STACK_OF(X509)* */
+STACK_OF(X509) *pkcs7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags) {
+ return PKCS7_get0_signers(p7, certs, flags);
}
%}
diff --git a/SWIG/_py3k_compat.i b/SWIG/_py3k_compat.i
new file mode 100644
index 0000000..7c90bb4
--- /dev/null
+++ b/SWIG/_py3k_compat.i
@@ -0,0 +1,43 @@
+%{
+#if PY_MAJOR_VERSION >= 3
+
+FILE* PyFile_AsFile(PyObject *pyfile) {
+ FILE* fp;
+ int fd;
+ const char *mode_str = NULL;
+ PyObject *mode_obj;
+
+ if ((fd = PyObject_AsFileDescriptor(pyfile)) == -1) {
+ PyErr_SetString(PyExc_BlockingIOError,
+ "Cannot find file handler for the Python file!");
+ return NULL;
+ }
+
+ if ((mode_obj = PyObject_GetAttrString(pyfile, "mode")) == NULL) {
+ mode_str = "rb";
+ PyErr_Clear();
+ }
+ else {
+ /* convert to plain string
+ * note that error checking is embedded in the function
+ */
+ mode_str = PyUnicode_AsUTF8AndSize(mode_obj, NULL);
+ }
+
+ if((fp = fdopen(fd, mode_str)) == NULL) {
+ PyErr_SetFromErrno(PyExc_IOError);
+ }
+
+ Py_XDECREF(mode_obj);
+ return fp;
+}
+
+#else /* PY2K */
+
+#define PyLong_FromLong(x) PyInt_FromLong(x)
+#define PyUnicode_AsUTF8(x) PyString_AsString(x)
+#define PyUnicode_FromString(x) PyString_FromString(x)
+#define PyUnicode_Format(x, y) PyString_Format(x, y)
+
+#endif /* PY_MAJOR_VERSION */
+%}
diff --git a/SWIG/_rand.i b/SWIG/_rand.i
index 2d4f144..01ab4ef 100644
--- a/SWIG/_rand.i
+++ b/SWIG/_rand.i
@@ -6,6 +6,8 @@
%module _rand
+%rename(rand_file_name) RAND_file_name;
+extern const char *RAND_file_name(char *, size_t );
%rename(rand_load_file) RAND_load_file;
extern int RAND_load_file(const char *, long);
%rename(rand_save_file) RAND_write_file;
@@ -17,6 +19,7 @@ extern int RAND_status(void);
%rename(rand_cleanup) RAND_cleanup;
extern void RAND_cleanup(void);
+%warnfilter(454) _rand_err;
%inline %{
static PyObject *_rand_err;
@@ -27,44 +30,51 @@ void rand_init(PyObject *rand_err) {
PyObject *rand_seed(PyObject *seed) {
const void *buf;
- int len;
+ int len = 0;
- if (m2_PyObject_AsReadBufferInt(seed, &buf, &len) == -1)
- return NULL;
+ m2_PyObject_AsReadBufferInt(seed, &buf, &len);
RAND_seed(buf, len);
- Py_INCREF(Py_None);
- return Py_None;
+ Py_RETURN_NONE;
}
PyObject *rand_add(PyObject *blob, double entropy) {
const void *buf;
- int len;
+ int len = 0;
- if (m2_PyObject_AsReadBufferInt(blob, &buf, &len) == -1)
- return NULL;
+ m2_PyObject_AsReadBufferInt(blob, &buf, &len);
RAND_add(buf, len, entropy);
- Py_INCREF(Py_None);
- return Py_None;
+ Py_RETURN_NONE;
}
PyObject *rand_bytes(int n) {
void *blob;
+ int ret;
PyObject *obj;
if (!(blob = PyMem_Malloc(n))) {
- PyErr_SetString(PyExc_MemoryError, "rand_bytes");
+ PyErr_SetString(PyExc_MemoryError,
+ "Insufficient memory for rand_bytes.");
return NULL;
}
- if (RAND_bytes(blob, n)) {
- obj = PyString_FromStringAndSize(blob, n);
+ if ((ret = RAND_bytes(blob, n)) == 1) {
+ obj = PyBytes_FromStringAndSize(blob, n);
PyMem_Free(blob);
return obj;
+ } else if (ret == 0) {
+ PyErr_SetString(_rand_err, "Not enough randomness.");
+ PyMem_Free(blob);
+ return NULL;
+ } else if (ret == -1) {
+ PyErr_SetString(_rand_err,
+ "Not supported by the current RAND method.");
+ PyMem_Free(blob);
+ return NULL;
} else {
PyMem_Free(blob);
- Py_INCREF(Py_None);
- return Py_None;
+ m2_PyErr_Msg(_rand_err);
+ return NULL;
}
}
@@ -74,7 +84,7 @@ PyObject *rand_pseudo_bytes(int n) {
PyObject *tuple;
if (!(blob=(unsigned char *)PyMem_Malloc(n))) {
- PyErr_SetString(PyExc_MemoryError, "rand_pseudo_bytes");
+ PyErr_SetString(PyExc_MemoryError, "Insufficient memory for rand_pseudo_bytes.");
return NULL;
}
if (!(tuple=PyTuple_New(2))) {
@@ -86,24 +96,43 @@ PyObject *rand_pseudo_bytes(int n) {
if (ret == -1) {
PyMem_Free(blob);
Py_DECREF(tuple);
- Py_INCREF(Py_None);
- return Py_None;
+ PyErr_SetString(_rand_err,
+ "Function RAND_pseudo_bytes not supported by the current RAND method.");
+ return NULL;
} else {
- PyTuple_SET_ITEM(tuple, 0, PyString_FromStringAndSize((char*)blob, n));
+ PyTuple_SET_ITEM(tuple, 0, PyBytes_FromStringAndSize((char*)blob, n));
+
PyMem_Free(blob);
- PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong((long)ret));
+ PyTuple_SET_ITEM(tuple, 1, PyLong_FromLong((long)ret));
return tuple;
}
}
+PyObject *rand_file_name(void) {
+ PyObject *obj;
+ char *str;
+ if ((obj = PyBytes_FromStringAndSize(NULL, BUFSIZ))==NULL) {
+ PyErr_SetString(PyExc_MemoryError, "rand_file_name");
+ return NULL;
+ }
+ str=PyBytes_AS_STRING(obj);
+ if (RAND_file_name(str, BUFSIZ)==NULL) {
+ PyErr_SetString(PyExc_RuntimeError, "rand_file_name");
+ return NULL;
+ }
+ if (_PyBytes_Resize(&obj, (Py_ssize_t)strlen(str))!=0)
+ return NULL; /* mem exception set by _PyBytes_Resize */
+ return obj;
+}
+
void rand_screen(void) {
-#ifdef __WINDOWS__
+#ifdef _WIN32
RAND_screen();
#endif
}
int rand_win32_event(unsigned int imsg, int wparam, long lparam) {
-#ifdef __WINDOWS__
+#ifdef _WIN32
return RAND_event(imsg, wparam, lparam);
#else
return 0;
@@ -116,7 +145,6 @@ int rand_win32_event(unsigned int imsg, int wparam, long lparam) {
RAND_egd
RAND_egd_bytes
RAND_query_egd_bytes
- RAND_file_name
*/
diff --git a/SWIG/_rc4.i b/SWIG/_rc4.i
index 3259997..eb4747e 100644
--- a/SWIG/_rc4.i
+++ b/SWIG/_rc4.i
@@ -1,6 +1,14 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* Copyright (c) 1999 Ng Pheng Siong. All rights reserved. */
-/* $Id: _rc4.i 522 2007-05-08 22:21:51Z heikki $ */
+/* $Id$ */
+
+%include <openssl/opensslconf.h>
+
+#if defined(OPENSSL_NO_RC4)
+#undef OPENSSL_NO_RC4
+%constant OPENSSL_NO_RC4 = 1;
+#else
+%constant OPENSSL_NO_RC4 = 0;
%{
#include <openssl/rc4.h>
@@ -11,11 +19,11 @@
%inline %{
RC4_KEY *rc4_new(void) {
RC4_KEY *key;
-
+
if (!(key = (RC4_KEY *)PyMem_Malloc(sizeof(RC4_KEY))))
PyErr_SetString(PyExc_MemoryError, "rc4_new");
return key;
-}
+}
void rc4_free(RC4_KEY *key) {
PyMem_Free((void *)key);
@@ -23,14 +31,13 @@ void rc4_free(RC4_KEY *key) {
PyObject *rc4_set_key(RC4_KEY *key, PyObject *value) {
const void *vbuf;
- int vlen;
+ int vlen = 0;
if (m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
return NULL;
RC4_set_key(key, vlen, vbuf);
- Py_INCREF(Py_None);
- return Py_None;
+ Py_RETURN_NONE;
}
PyObject *rc4_update(RC4_KEY *key, PyObject *in) {
@@ -47,7 +54,9 @@ PyObject *rc4_update(RC4_KEY *key, PyObject *in) {
return NULL;
}
RC4(key, len, buf, out);
- ret = PyString_FromStringAndSize(out, len);
+
+ ret = PyBytes_FromStringAndSize(out, len);
+
PyMem_Free(out);
return ret;
}
@@ -56,3 +65,5 @@ int rc4_type_check(RC4_KEY *key) {
return 1;
}
%}
+
+#endif
diff --git a/SWIG/_rsa.i b/SWIG/_rsa.i
index 537e802..4ffae01 100644
--- a/SWIG/_rsa.i
+++ b/SWIG/_rsa.i
@@ -1,5 +1,5 @@
/* Copyright (c) 1999-2000 Ng Pheng Siong. All rights reserved. */
-/* $Id: _rsa.i 723 2010-02-13 06:53:13Z heikki $ */
+/* $Id$ */
%{
#include <openssl/bn.h>
@@ -12,12 +12,12 @@
%apply Pointer NONNULL { RSA * };
%apply Pointer NONNULL { PyObject *pyfunc };
+%rename(rsa_size) RSA_size;
+extern int RSA_size(const RSA*);
%rename(rsa_new) RSA_new;
extern RSA *RSA_new(void);
%rename(rsa_free) RSA_free;
extern void RSA_free(RSA *);
-%rename(rsa_size) RSA_size;
-extern int RSA_size(const RSA *);
%rename(rsa_check_key) RSA_check_key;
extern int RSA_check_key(const RSA *);
@@ -39,6 +39,7 @@ extern int RSA_check_key(const RSA *);
%constant int NID_ripemd160 = NID_ripemd160;
+%warnfilter(454) _rsa_err;
%inline %{
static PyObject *_rsa_err;
@@ -81,7 +82,7 @@ int rsa_write_key_no_cipher(RSA *rsa, BIO *f, PyObject *pyfunc) {
Py_INCREF(pyfunc);
Py_BEGIN_ALLOW_THREADS
- ret = PEM_write_bio_RSAPrivateKey(f, rsa, NULL, NULL, 0,
+ ret = PEM_write_bio_RSAPrivateKey(f, rsa, NULL, NULL, 0,
passphrase_callback, (void *)pyfunc);
Py_END_ALLOW_THREADS
Py_DECREF(pyfunc);
@@ -92,7 +93,7 @@ int rsa_write_key_no_cipher(RSA *rsa, BIO *f, PyObject *pyfunc) {
%threadallow rsa_read_pub_key;
%inline %{
RSA *rsa_read_pub_key(BIO *f) {
- return PEM_read_bio_RSA_PUBKEY(f, NULL, NULL, NULL);
+ return PEM_read_bio_RSA_PUBKEY(f, NULL, NULL, NULL);
}
%}
@@ -103,118 +104,146 @@ int rsa_write_pub_key(RSA *rsa, BIO *f) {
}
PyObject *rsa_get_e(RSA *rsa) {
- if (!rsa->e) {
+ const BIGNUM* e = NULL;
+ RSA_get0_key(rsa, NULL, &e, NULL);
+ if (!e) {
PyErr_SetString(_rsa_err, "'e' is unset");
return NULL;
}
- return bn_to_mpi(rsa->e);
+ return bn_to_mpi(e);
}
PyObject *rsa_get_n(RSA *rsa) {
- if (!rsa->n) {
+ const BIGNUM* n = NULL;
+ RSA_get0_key(rsa, &n, NULL, NULL);
+ if (!n) {
PyErr_SetString(_rsa_err, "'n' is unset");
return NULL;
}
- return bn_to_mpi(rsa->n);
+ return bn_to_mpi(n);
}
-PyObject *rsa_set_e(RSA *rsa, PyObject *value) {
- BIGNUM *bn;
- const void *vbuf;
- int vlen;
+PyObject *rsa_set_e(RSA *rsa, PyObject *eval) {
+ const BIGNUM* n_read = NULL;
+ BIGNUM* n = NULL;
+ BIGNUM* e;
- if (m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
+ if (!(e = m2_PyObject_AsBIGNUM(eval, _rsa_err))) {
return NULL;
+ }
- if (!(bn = BN_mpi2bn((unsigned char *)vbuf, vlen, NULL))) {
- PyErr_SetString(_rsa_err, ERR_reason_error_string(ERR_get_error()));
+ /* n and e must be set at the same time so if e is unset, set it to zero */
+ RSA_get0_key(rsa, &n_read, NULL, NULL);
+ if (!n_read) {
+ n = BN_new();
+ }
+
+ if (RSA_set0_key(rsa, n, e, NULL) != 1) {
+ PyErr_SetString(_rsa_err, "Cannot set fields of RSA object.");
+ BN_free(e);
+ BN_free(n);
return NULL;
}
- if (rsa->e)
- BN_free(rsa->e);
- rsa->e = bn;
- Py_INCREF(Py_None);
- return Py_None;
+ Py_RETURN_NONE;
}
-PyObject *rsa_set_n(RSA *rsa, PyObject *value) {
- BIGNUM *bn;
- const void *vbuf;
- int vlen;
+PyObject *rsa_set_n(RSA *rsa, PyObject *nval) {
+ BIGNUM* n;
+ const BIGNUM* e_read = NULL;
+ BIGNUM* e = NULL;
- if (m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
+ if (!(n = m2_PyObject_AsBIGNUM(nval, _rsa_err))) {
return NULL;
+ }
+
+ /* n and e must be set at the same time so if e is unset, set it to zero */
+ RSA_get0_key(rsa, NULL, &e_read, NULL);
+ if (!e_read) {
+ e = BN_new();
+ }
- if (!(bn = BN_mpi2bn((unsigned char *)vbuf, vlen, NULL))) {
- PyErr_SetString(_rsa_err, ERR_reason_error_string(ERR_get_error()));
+ if (RSA_set0_key(rsa, n, e, NULL) != 1) {
+ PyErr_SetString(_rsa_err, "Cannot set fields of RSA object.");
+ BN_free(n);
+ BN_free(e);
return NULL;
}
- if (rsa->n)
- BN_free(rsa->n);
- rsa->n = bn;
- Py_INCREF(Py_None);
- return Py_None;
+ Py_RETURN_NONE;
}
-PyObject *rsa_set_e_bin(RSA *rsa, PyObject *value) {
- BIGNUM *bn;
- const void *vbuf;
- int vlen;
+PyObject *rsa_set_en(RSA *rsa, PyObject *eval, PyObject* nval) {
+ BIGNUM* e, *n;
- if (m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
+ if (!(e = m2_PyObject_AsBIGNUM(eval, _rsa_err)) ||
+ !(n = m2_PyObject_AsBIGNUM(nval, _rsa_err))) {
return NULL;
+ }
- if (!(bn = BN_bin2bn((unsigned char *)vbuf, vlen, NULL))) {
- PyErr_SetString(_rsa_err, ERR_reason_error_string(ERR_get_error()));
+ if (!RSA_set0_key(rsa, n, e, NULL)) {
+ PyErr_SetString(_rsa_err, "Cannot set fields of RSA object.");
+ BN_free(e);
+ BN_free(n);
return NULL;
}
- if (rsa->e)
- BN_free(rsa->e);
- rsa->e = bn;
- Py_INCREF(Py_None);
- return Py_None;
+ Py_RETURN_NONE;
}
-PyObject *rsa_set_n_bin(RSA *rsa, PyObject *value) {
- BIGNUM *bn;
- const void *vbuf;
- int vlen;
+static BIGNUM* PyObject_Bin_AsBIGNUM(PyObject* value) {
+ BIGNUM* bn;
+ const void* vbuf;
+ int vlen = 0;
if (m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
return NULL;
if (!(bn = BN_bin2bn((unsigned char *)vbuf, vlen, NULL))) {
- PyErr_SetString(_rsa_err, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(_rsa_err);
+ return NULL;
+ }
+
+ return bn;
+}
+
+PyObject *rsa_set_en_bin(RSA *rsa, PyObject *eval, PyObject* nval) {
+ BIGNUM* e, *n;
+
+ if (!(e = PyObject_Bin_AsBIGNUM(eval)) ||
+ !(n = PyObject_Bin_AsBIGNUM(nval))) {
+ return NULL;
+ }
+
+ if (!RSA_set0_key(rsa, e, n, NULL)) {
+ PyErr_SetString(_rsa_err, "Cannot set fields of RSA object.");
+ BN_free(e);
+ BN_free(n);
return NULL;
}
- if (rsa->n)
- BN_free(rsa->n);
- rsa->n = bn;
- Py_INCREF(Py_None);
- return Py_None;
+ Py_RETURN_NONE;
}
PyObject *rsa_private_encrypt(RSA *rsa, PyObject *from, int padding) {
const void *fbuf;
void *tbuf;
- int flen, tlen;
+ int flen = 0, tlen;
PyObject *ret;
if (m2_PyObject_AsReadBufferInt(from, &fbuf, &flen) == -1)
return NULL;
- if (!(tbuf = PyMem_Malloc(BN_num_bytes(rsa->n)))) {
+ if (!(tbuf = PyMem_Malloc(RSA_size(rsa)))) {
PyErr_SetString(PyExc_MemoryError, "rsa_private_encrypt");
return NULL;
}
- tlen = RSA_private_encrypt(flen, (unsigned char *)fbuf,
+ tlen = RSA_private_encrypt(flen, (unsigned char *)fbuf,
(unsigned char *)tbuf, rsa, padding);
if (tlen == -1) {
+ m2_PyErr_Msg(_rsa_err);
PyMem_Free(tbuf);
- PyErr_SetString(_rsa_err, ERR_reason_error_string(ERR_get_error()));
return NULL;
}
- ret = PyString_FromStringAndSize((const char *)tbuf, tlen);
+
+ ret = PyBytes_FromStringAndSize((const char *)tbuf, tlen);
+
PyMem_Free(tbuf);
return ret;
}
@@ -222,24 +251,29 @@ PyObject *rsa_private_encrypt(RSA *rsa, PyObject *from, int padding) {
PyObject *rsa_public_decrypt(RSA *rsa, PyObject *from, int padding) {
const void *fbuf;
void *tbuf;
- int flen, tlen;
+ int flen = 0, tlen = 0;
PyObject *ret;
if (m2_PyObject_AsReadBufferInt(from, &fbuf, &flen) == -1)
return NULL;
- if (!(tbuf = PyMem_Malloc(BN_num_bytes(rsa->n)))) {
+ /* OpenSSL docs are confused here: it says we only need buffer
+ * 'RSA_size()-11', but it is true only for RSA PKCS#1 type 1
+ * padding. For other uses we need to use different sizes. */
+ if (!(tbuf = PyMem_Malloc(RSA_size(rsa)))) {
PyErr_SetString(PyExc_MemoryError, "rsa_public_decrypt");
return NULL;
}
- tlen = RSA_public_decrypt(flen, (unsigned char *)fbuf,
+ tlen = RSA_public_decrypt(flen, (unsigned char *)fbuf,
(unsigned char *)tbuf, rsa, padding);
if (tlen == -1) {
+ m2_PyErr_Msg(_rsa_err);
PyMem_Free(tbuf);
- PyErr_SetString(_rsa_err, ERR_reason_error_string(ERR_get_error()));
return NULL;
}
- ret = PyString_FromStringAndSize((const char *)tbuf, tlen);
+
+ ret = PyBytes_FromStringAndSize((const char *)tbuf, tlen);
+
PyMem_Free(tbuf);
return ret;
}
@@ -247,24 +281,26 @@ PyObject *rsa_public_decrypt(RSA *rsa, PyObject *from, int padding) {
PyObject *rsa_public_encrypt(RSA *rsa, PyObject *from, int padding) {
const void *fbuf;
void *tbuf;
- int flen, tlen;
+ int flen = 0, tlen;
PyObject *ret;
if (m2_PyObject_AsReadBufferInt(from, &fbuf, &flen) == -1)
return NULL;
- if (!(tbuf = PyMem_Malloc(BN_num_bytes(rsa->n)))) {
+ if (!(tbuf = PyMem_Malloc(RSA_size(rsa)))) {
PyErr_SetString(PyExc_MemoryError, "rsa_public_encrypt");
return NULL;
}
- tlen = RSA_public_encrypt(flen, (unsigned char *)fbuf,
+ tlen = RSA_public_encrypt(flen, (unsigned char *)fbuf,
(unsigned char *)tbuf, rsa, padding);
if (tlen == -1) {
+ m2_PyErr_Msg(_rsa_err);
PyMem_Free(tbuf);
- PyErr_SetString(_rsa_err, ERR_reason_error_string(ERR_get_error()));
return NULL;
}
- ret = PyString_FromStringAndSize((const char *)tbuf, tlen);
+
+ ret = PyBytes_FromStringAndSize((const char *)tbuf, tlen);
+
PyMem_Free(tbuf);
return ret;
}
@@ -272,24 +308,25 @@ PyObject *rsa_public_encrypt(RSA *rsa, PyObject *from, int padding) {
PyObject *rsa_private_decrypt(RSA *rsa, PyObject *from, int padding) {
const void *fbuf;
void *tbuf;
- int flen, tlen;
+ int flen = 0, tlen;
PyObject *ret;
if (m2_PyObject_AsReadBufferInt(from, &fbuf, &flen) == -1)
return NULL;
- if (!(tbuf = PyMem_Malloc(BN_num_bytes(rsa->n)))) {
+ if (!(tbuf = PyMem_Malloc(RSA_size(rsa)))) {
PyErr_SetString(PyExc_MemoryError, "rsa_private_decrypt");
return NULL;
}
- tlen = RSA_private_decrypt(flen, (unsigned char *)fbuf,
+ tlen = RSA_private_decrypt(flen, (unsigned char *)fbuf,
(unsigned char *)tbuf, rsa, padding);
if (tlen == -1) {
+ m2_PyErr_Msg(_rsa_err);
PyMem_Free(tbuf);
- PyErr_SetString(_rsa_err, ERR_reason_error_string(ERR_get_error()));
return NULL;
}
- ret = PyString_FromStringAndSize((const char *)tbuf, tlen);
+ ret = PyBytes_FromStringAndSize((const char *)tbuf, tlen);
+
PyMem_Free(tbuf);
return ret;
}
@@ -304,7 +341,7 @@ PyObject *rsa_padding_add_pkcs1_pss(RSA *rsa, PyObject *digest, EVP_MD *hash, in
if (m2_PyObject_AsReadBufferInt(digest, &dbuf, &dlen) == -1)
return NULL;
- tlen = RSA_size(rsa);
+ tlen = RSA_size(rsa);
if (!(tbuf = OPENSSL_malloc(tlen))) {
PyErr_SetString(PyExc_MemoryError, "rsa_padding_add_pkcs1_pss");
@@ -318,12 +355,12 @@ PyObject *rsa_padding_add_pkcs1_pss(RSA *rsa, PyObject *digest, EVP_MD *hash, in
salt_length);
if (result == -1) {
+ m2_PyErr_Msg(_rsa_err);
OPENSSL_cleanse(tbuf, tlen);
OPENSSL_free(tbuf);
- PyErr_SetString(_rsa_err, ERR_reason_error_string(ERR_get_error()));
return NULL;
}
- ret = PyString_FromStringAndSize((const char *)tbuf, tlen);
+ ret = PyBytes_FromStringAndSize((const char *)tbuf, tlen);
OPENSSL_cleanse(tbuf, tlen);
OPENSSL_free(tbuf);
return ret;
@@ -360,30 +397,32 @@ PyObject *rsa_sign(RSA *rsa, PyObject *py_digest_string, int method_type) {
unsigned int real_buf_len = 0;
char *digest_string = NULL;
unsigned char * sign_buf = NULL;
- PyObject *signature;
-
+ PyObject *signature;
+
ret = m2_PyString_AsStringAndSizeInt(py_digest_string, &digest_string,
- &digest_len);
+ &digest_len);
if (ret == -1) {
/* PyString_AsStringAndSize raises the correct exceptions. */
return NULL;
}
-
+
buf_len = RSA_size(rsa);
sign_buf = (unsigned char *)PyMem_Malloc(buf_len);
- ret = RSA_sign(method_type, (const unsigned char *)digest_string, digest_len,
+ ret = RSA_sign(method_type, (const unsigned char *)digest_string, digest_len,
sign_buf, &real_buf_len, rsa);
-
+
if (!ret) {
+ m2_PyErr_Msg(_rsa_err);
PyMem_Free(sign_buf);
- PyErr_SetString(_rsa_err, ERR_reason_error_string(ERR_get_error()));
return NULL;
}
- signature = PyString_FromStringAndSize((const char*) sign_buf, buf_len);
+
+ signature = PyBytes_FromStringAndSize((const char*) sign_buf, buf_len);
+
PyMem_Free(sign_buf);
return signature;
-}
-
+}
+
int rsa_verify(RSA *rsa, PyObject *py_verify_string, PyObject* py_sign_string, int method_type){
int ret = 0;
char * sign_string = NULL;
@@ -407,31 +446,57 @@ int rsa_verify(RSA *rsa, PyObject *py_verify_string, PyObject* py_sign_string, i
verify_len, (unsigned char *) sign_string,
sign_len, rsa);
if (!ret) {
- PyErr_SetString(_rsa_err, ERR_reason_error_string(ERR_get_error()));
- }
+ m2_PyErr_Msg(_rsa_err);
+ return 0;
+ }
return ret;
}
-void genrsa_callback(int p, int n, void *arg) {
- PyObject *argv, *ret, *cbfunc;
+PyObject *rsa_generate_key(int bits, unsigned long e, PyObject *pyfunc) {
+ RSA *rsa;
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+ BN_GENCB *gencb;
+ BIGNUM *e_big;
+ int ret;
- cbfunc = (PyObject *)arg;
- argv = Py_BuildValue("(ii)", p, n);
- ret = PyEval_CallObject(cbfunc, argv);
- PyErr_Clear();
- Py_DECREF(argv);
- Py_XDECREF(ret);
-}
+ if ((e_big=BN_new()) == NULL) {
+ m2_PyErr_Msg(_rsa_err);
+ return NULL;
+ }
-RSA *rsa_generate_key(int bits, unsigned long e, PyObject *pyfunc) {
- RSA *rsa;
+ if (BN_set_word(e_big, e) == 0) {
+ m2_PyErr_Msg(_rsa_err);
+ BN_free(e_big);
+ return NULL;
+ }
+
+ if ((gencb=BN_GENCB_new()) == NULL) {
+ m2_PyErr_Msg(_rsa_err);
+ BN_free(e_big);
+ return NULL;
+ }
+
+ if ((rsa = RSA_new()) == NULL) {
+ m2_PyErr_Msg(_rsa_err);
+ BN_free(e_big);
+ BN_GENCB_free(gencb);
+ return NULL;
+ }
+
+ BN_GENCB_set(gencb, bn_gencb_callback, (void *) pyfunc);
Py_INCREF(pyfunc);
- rsa = RSA_generate_key(bits, e, genrsa_callback, (void *)pyfunc);
+ ret = RSA_generate_key_ex(rsa, bits, e_big, gencb);
+ BN_free(e_big);
+ BN_GENCB_free(gencb);
Py_DECREF(pyfunc);
- if (!rsa)
- PyErr_SetString(_rsa_err, ERR_reason_error_string(ERR_get_error()));
- return rsa;
+
+ if (ret)
+ return SWIG_NewPointerObj((void *)rsa, SWIGTYPE_p_RSA, 0);
+
+ m2_PyErr_Msg(_rsa_err);
+ RSA_free(rsa);
+ return NULL;
}
int rsa_type_check(RSA *rsa) {
@@ -439,7 +504,9 @@ int rsa_type_check(RSA *rsa) {
}
int rsa_check_pub_key(RSA *rsa) {
- return (rsa->e) && (rsa->n);
+ const BIGNUM* n, *e;
+ RSA_get0_key(rsa, &n, &e, NULL);
+ return n && e;
}
%}
@@ -449,4 +516,3 @@ int rsa_write_key_der(RSA *rsa, BIO *bio) {
return i2d_RSAPrivateKey_bio(bio, rsa);
}
%}
-
diff --git a/SWIG/_ssl.i b/SWIG/_ssl.i
index c66418a..7257656 100644
--- a/SWIG/_ssl.i
+++ b/SWIG/_ssl.i
@@ -7,16 +7,30 @@
** Copyright (c) 2009-2010 Heikki Toivonen. All rights reserved.
**
*/
-/* $Id: _ssl.i 721 2010-02-13 06:30:33Z heikki $ */
-
+/* $Id$ */
%{
#include <pythread.h>
+#include <limits.h>
#include <openssl/bio.h>
#include <openssl/dh.h>
#include <openssl/ssl.h>
+#include <openssl/tls1.h>
#include <openssl/x509.h>
+#ifdef _WIN32
+#include <WinSock2.h>
+#include <Windows.h>
+#pragma comment(lib, "Ws2_32")
+typedef unsigned __int64 uint64_t;
+#else
+#include <poll.h>
+#include <sys/time.h>
+#endif
%}
+#if OPENSSL_VERSION_NUMBER >= 0x10100005L
+%include <openssl/safestack.h>
+#endif
+
%apply Pointer NONNULL { SSL_CTX * };
%apply Pointer NONNULL { SSL * };
%apply Pointer NONNULL { SSL_CIPHER * };
@@ -32,9 +46,9 @@
extern STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *ssl);
%rename(ssl_get_version) SSL_get_version;
-extern const char *SSL_get_version(CONST SSL *);
+extern const char *SSL_get_version(const SSL *);
%rename(ssl_get_error) SSL_get_error;
-extern int SSL_get_error(CONST SSL *, int);
+extern int SSL_get_error(const SSL *, int);
%rename(ssl_get_state) SSL_state_string;
extern const char *SSL_state_string(const SSL *);
%rename(ssl_get_state_v) SSL_state_string_long;
@@ -48,29 +62,33 @@ extern const char *SSL_alert_desc_string(int);
%rename(ssl_get_alert_desc_v) SSL_alert_desc_string_long;
extern const char *SSL_alert_desc_string_long(int);
-#ifndef OPENSSL_NO_SSL2
-%rename(sslv2_method) SSLv2_method;
-extern SSL_METHOD *SSLv2_method(void);
-#endif
-#ifndef OPENSSL_NO_SSL3
-%rename(sslv3_method) SSLv3_method;
-extern SSL_METHOD *SSLv3_method(void);
-#endif
%rename(sslv23_method) SSLv23_method;
extern SSL_METHOD *SSLv23_method(void);
-%rename(tlsv1_method) TLSv1_method;
+%ignore TLSv1_method;
extern SSL_METHOD *TLSv1_method(void);
+%typemap(out) SSL_CTX * {
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+
+ if ($1 != NULL)
+ $result = SWIG_NewPointerObj($1, $1_descriptor, 0);
+ else {
+ m2_PyErr_Msg(_ssl_err);
+ $result = NULL;
+ }
+}
%rename(ssl_ctx_new) SSL_CTX_new;
extern SSL_CTX *SSL_CTX_new(SSL_METHOD *);
+%typemap(out) SSL_CTX *;
+
%rename(ssl_ctx_free) SSL_CTX_free;
extern void SSL_CTX_free(SSL_CTX *);
%rename(ssl_ctx_set_verify_depth) SSL_CTX_set_verify_depth;
extern void SSL_CTX_set_verify_depth(SSL_CTX *, int);
%rename(ssl_ctx_get_verify_depth) SSL_CTX_get_verify_depth;
-extern int SSL_CTX_get_verify_depth(CONST SSL_CTX *);
+extern int SSL_CTX_get_verify_depth(const SSL_CTX *);
%rename(ssl_ctx_get_verify_mode) SSL_CTX_get_verify_mode;
-extern int SSL_CTX_get_verify_mode(CONST SSL_CTX *);
+extern int SSL_CTX_get_verify_mode(const SSL_CTX *);
%rename(ssl_ctx_set_cipher_list) SSL_CTX_set_cipher_list;
extern int SSL_CTX_set_cipher_list(SSL_CTX *, const char *);
%rename(ssl_ctx_add_session) SSL_CTX_add_session;
@@ -80,9 +98,13 @@ extern int SSL_CTX_remove_session(SSL_CTX *, SSL_SESSION *);
%rename(ssl_ctx_set_session_timeout) SSL_CTX_set_timeout;
extern long SSL_CTX_set_timeout(SSL_CTX *, long);
%rename(ssl_ctx_get_session_timeout) SSL_CTX_get_timeout;
-extern long SSL_CTX_get_timeout(CONST SSL_CTX *);
+extern long SSL_CTX_get_timeout(const SSL_CTX *);
%rename(ssl_ctx_get_cert_store) SSL_CTX_get_cert_store;
-extern X509_STORE *SSL_CTX_get_cert_store(CONST SSL_CTX *);
+extern X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *);
+%rename(ssl_ctx_set_default_verify_paths) SSL_CTX_set_default_verify_paths;
+extern int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx);
+%rename(ssl_get_ex_data_x509_store_ctx_idx) SSL_get_ex_data_X509_STORE_CTX_idx;
+extern int SSL_get_ex_data_X509_STORE_CTX_idx(void);
%rename(bio_new_ssl) BIO_new_ssl;
extern BIO *BIO_new_ssl(SSL_CTX *, int);
@@ -101,7 +123,7 @@ extern void SSL_set_accept_state(SSL *);
%rename(ssl_set_connect_state) SSL_set_connect_state;
extern void SSL_set_connect_state(SSL *);
%rename(ssl_get_shutdown) SSL_get_shutdown;
-extern int SSL_get_shutdown(CONST SSL *);
+extern int SSL_get_shutdown(const SSL *);
%rename(ssl_set_shutdown) SSL_set_shutdown;
extern void SSL_set_shutdown(SSL *, int);
%rename(ssl_shutdown) SSL_shutdown;
@@ -116,35 +138,35 @@ extern int SSL_do_handshake(SSL *);
%threadallow SSL_renegotiate;
extern int SSL_renegotiate(SSL *);
%rename(ssl_pending) SSL_pending;
-extern int SSL_pending(CONST SSL *);
+extern int SSL_pending(const SSL *);
%rename(ssl_get_peer_cert) SSL_get_peer_certificate;
-extern X509 *SSL_get_peer_certificate(CONST SSL *);
+extern X509 *SSL_get_peer_certificate(const SSL *);
%rename(ssl_get_current_cipher) SSL_get_current_cipher;
-extern SSL_CIPHER *SSL_get_current_cipher(CONST SSL *);
+extern SSL_CIPHER *SSL_get_current_cipher(const SSL *);
%rename(ssl_get_verify_mode) SSL_get_verify_mode;
-extern int SSL_get_verify_mode(CONST SSL *);
+extern int SSL_get_verify_mode(const SSL *);
%rename(ssl_get_verify_depth) SSL_get_verify_depth;
-extern int SSL_get_verify_depth(CONST SSL *);
+extern int SSL_get_verify_depth(const SSL *);
%rename(ssl_get_verify_result) SSL_get_verify_result;
-extern long SSL_get_verify_result(CONST SSL *);
+extern long SSL_get_verify_result(const SSL *);
%rename(ssl_get_ssl_ctx) SSL_get_SSL_CTX;
-extern SSL_CTX *SSL_get_SSL_CTX(CONST SSL *);
+extern SSL_CTX *SSL_get_SSL_CTX(const SSL *);
%rename(ssl_get_default_session_timeout) SSL_get_default_timeout;
-extern long SSL_get_default_timeout(CONST SSL *);
+extern long SSL_get_default_timeout(const SSL *);
%rename(ssl_set_cipher_list) SSL_set_cipher_list;
extern int SSL_set_cipher_list(SSL *, const char *);
%rename(ssl_get_cipher_list) SSL_get_cipher_list;
-extern const char *SSL_get_cipher_list(CONST SSL *, int);
+extern const char *SSL_get_cipher_list(const SSL *, int);
%rename(ssl_cipher_get_name) SSL_CIPHER_get_name;
-extern const char *SSL_CIPHER_get_name(CONST SSL_CIPHER *);
+extern const char *SSL_CIPHER_get_name(const SSL_CIPHER *);
%rename(ssl_cipher_get_version) SSL_CIPHER_get_version;
-extern char *SSL_CIPHER_get_version(CONST SSL_CIPHER *);
+extern char *SSL_CIPHER_get_version(const SSL_CIPHER *);
%rename(ssl_get_session) SSL_get_session;
-extern SSL_SESSION *SSL_get_session(CONST SSL *);
+extern SSL_SESSION *SSL_get_session(const SSL *);
%rename(ssl_get1_session) SSL_get1_session;
extern SSL_SESSION *SSL_get1_session(SSL *);
%rename(ssl_set_session) SSL_set_session;
@@ -153,11 +175,16 @@ extern int SSL_set_session(SSL *, SSL_SESSION *);
extern void SSL_SESSION_free(SSL_SESSION *);
%rename(ssl_session_print) SSL_SESSION_print;
%threadallow SSL_SESSION_print;
-extern int SSL_SESSION_print(BIO *, CONST SSL_SESSION *);
+extern int SSL_SESSION_print(BIO *, const SSL_SESSION *);
%rename(ssl_session_set_timeout) SSL_SESSION_set_timeout;
extern long SSL_SESSION_set_timeout(SSL_SESSION *, long);
%rename(ssl_session_get_timeout) SSL_SESSION_get_timeout;
-extern long SSL_SESSION_get_timeout(CONST SSL_SESSION *);
+extern long SSL_SESSION_get_timeout(const SSL_SESSION *);
+
+extern PyObject *ssl_accept(SSL *ssl, double timeout = -1);
+extern PyObject *ssl_connect(SSL *ssl, double timeout = -1);
+extern PyObject *ssl_read(SSL *ssl, int num, double timeout = -1);
+extern int ssl_write(SSL *ssl, PyObject *blob, double timeout = -1);
%constant int ssl_error_none = SSL_ERROR_NONE;
%constant int ssl_error_ssl = SSL_ERROR_SSL;
@@ -179,7 +206,9 @@ extern long SSL_SESSION_get_timeout(CONST SSL_SESSION *);
%constant int SSL_ST_INIT = (SSL_ST_CONNECT|SSL_ST_ACCEPT);
%constant int SSL_ST_BEFORE = 0x4000;
%constant int SSL_ST_OK = 0x03;
-%constant int SSL_ST_RENEGOTIATE = (0x04|SSL_ST_INIT);
+/* SWIG 3.0.1 complains about the next line -- simplified declaration for now */
+/*%constant int SSL_ST_RENEGOTIATE = (0x04|SSL_ST_INIT);*/
+%constant int SSL_ST_RENEGOTIATE = (0x04|SSL_ST_CONNECT|SSL_ST_ACCEPT);
%constant int SSL_CB_LOOP = 0x01;
%constant int SSL_CB_EXIT = 0x02;
@@ -211,17 +240,32 @@ extern long SSL_SESSION_get_timeout(CONST SSL_SESSION *);
%constant int SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS = 0x00000800L;
%constant int SSL_MODE_ENABLE_PARTIAL_WRITE = SSL_MODE_ENABLE_PARTIAL_WRITE;
-%constant int SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER = SSL_MODE_ENABLE_PARTIAL_WRITE;
+%constant int SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER = SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER;
%constant int SSL_MODE_AUTO_RETRY = SSL_MODE_AUTO_RETRY;
+%ignore ssl_handle_error;
+%ignore ssl_sleep_with_timeout;
+%warnfilter(454) _ssl_err;
+%warnfilter(454) _ssl_timeout_err;
%inline %{
static PyObject *_ssl_err;
+static PyObject *_ssl_timeout_err;
-void ssl_init(PyObject *ssl_err) {
+void ssl_init(PyObject *ssl_err, PyObject *ssl_timeout_err) {
SSL_library_init();
SSL_load_error_strings();
Py_INCREF(ssl_err);
+ Py_INCREF(ssl_timeout_err);
_ssl_err = ssl_err;
+ _ssl_timeout_err = ssl_timeout_err;
+}
+
+const SSL_METHOD *tlsv1_method(void) {
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ PyErr_WarnEx(PyExc_DeprecationWarning,
+ "Function TLSv1_method has been deprecated.", 1);
+#endif
+ return TLSv1_method();
}
void ssl_ctx_passphrase_callback(SSL_CTX *ctx, PyObject *pyfunc) {
@@ -232,9 +276,9 @@ void ssl_ctx_passphrase_callback(SSL_CTX *ctx, PyObject *pyfunc) {
int ssl_ctx_use_x509(SSL_CTX *ctx, X509 *x) {
int i;
-
+
if (!(i = SSL_CTX_use_certificate(ctx, x))) {
- PyErr_SetString(_ssl_err, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(_ssl_err);
return -1;
}
return i;
@@ -243,9 +287,9 @@ int ssl_ctx_use_x509(SSL_CTX *ctx, X509 *x) {
int ssl_ctx_use_cert(SSL_CTX *ctx, char *file) {
int i;
-
+
if (!(i = SSL_CTX_use_certificate_file(ctx, file, SSL_FILETYPE_PEM))) {
- PyErr_SetString(_ssl_err, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(_ssl_err);
return -1;
}
return i;
@@ -255,7 +299,7 @@ int ssl_ctx_use_cert_chain(SSL_CTX *ctx, char *file) {
int i;
if (!(i = SSL_CTX_use_certificate_chain_file(ctx, file))) {
- PyErr_SetString(_ssl_err, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(_ssl_err);
return -1;
}
return i;
@@ -264,9 +308,9 @@ int ssl_ctx_use_cert_chain(SSL_CTX *ctx, char *file) {
int ssl_ctx_use_privkey(SSL_CTX *ctx, char *file) {
int i;
-
+
if (!(i = SSL_CTX_use_PrivateKey_file(ctx, file, SSL_FILETYPE_PEM))) {
- PyErr_SetString(_ssl_err, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(_ssl_err);
return -1;
}
return i;
@@ -276,7 +320,7 @@ int ssl_ctx_use_rsa_privkey(SSL_CTX *ctx, RSA *rsakey) {
int i;
if (!(i = SSL_CTX_use_RSAPrivateKey(ctx, rsakey))) {
- PyErr_SetString(_ssl_err, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(_ssl_err);
return -1;
}
return i;
@@ -286,7 +330,7 @@ int ssl_ctx_use_pkey_privkey(SSL_CTX *ctx, EVP_PKEY *pkey) {
int i;
if (!(i = SSL_CTX_use_PrivateKey(ctx, pkey))) {
- PyErr_SetString(_ssl_err, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(_ssl_err);
return -1;
}
return i;
@@ -295,9 +339,9 @@ int ssl_ctx_use_pkey_privkey(SSL_CTX *ctx, EVP_PKEY *pkey) {
int ssl_ctx_check_privkey(SSL_CTX *ctx) {
int ret;
-
+
if (!(ret = SSL_CTX_check_private_key(ctx))) {
- PyErr_SetString(_ssl_err, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(_ssl_err);
return -1;
}
return ret;
@@ -320,7 +364,7 @@ void ssl_ctx_set_verify(SSL_CTX *ctx, int mode, PyObject *pyfunc) {
int ssl_ctx_set_session_id_context(SSL_CTX *ctx, PyObject *sid_ctx) {
const void *buf;
- int len;
+ int len = 0;
if (m2_PyObject_AsReadBufferInt(sid_ctx, &buf, &len) == -1)
return -1;
@@ -379,6 +423,17 @@ long ssl_get_mode(SSL *ssl) {
return SSL_get_mode(ssl);
}
+int ssl_set_tlsext_host_name(SSL *ssl, const char *name) {
+ long l;
+
+ if (!(l = SSL_set_tlsext_host_name(ssl, name))) {
+ m2_PyErr_Msg(_ssl_err);
+ return -1;
+ }
+ /* Return an "int" to match the 'typemap(out) int' in _lib.i */
+ return 1;
+}
+
void ssl_set_client_CA_list_from_file(SSL *ssl, const char *ca_file) {
SSL_set_client_CA_list(ssl, SSL_load_client_CA_file(ca_file));
}
@@ -389,7 +444,7 @@ void ssl_set_client_CA_list_from_context(SSL *ssl, SSL_CTX *ctx) {
int ssl_set_session_id_context(SSL *ssl, PyObject *sid_ctx) {
const void *buf;
- int len;
+ int len = 0;
if (m2_PyObject_AsReadBufferInt(sid_ctx, &buf, &len) == -1)
return -1;
@@ -399,44 +454,172 @@ int ssl_set_session_id_context(SSL *ssl, PyObject *sid_ctx) {
int ssl_set_fd(SSL *ssl, int fd) {
int ret;
-
+
if (!(ret = SSL_set_fd(ssl, fd))) {
- PyErr_SetString(_ssl_err, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(_ssl_err);
return -1;
}
return ret;
}
-PyObject *ssl_accept(SSL *ssl) {
+static void ssl_handle_error(int ssl_err, int ret) {
+ int err;
+
+ switch (ssl_err) {
+ case SSL_ERROR_SSL:
+ PyErr_SetString(_ssl_err,
+ ERR_reason_error_string(ERR_get_error()));
+ break;
+ case SSL_ERROR_SYSCALL:
+ err = ERR_get_error();
+ if (err)
+ PyErr_SetString(_ssl_err, ERR_reason_error_string(err));
+ else if (ret == 0)
+ PyErr_SetString(_ssl_err, "unexpected eof");
+ else if (ret == -1)
+ PyErr_SetFromErrno(_ssl_err);
+ else
+ assert(0);
+ break;
+ default:
+ PyErr_SetString(_ssl_err, "unexpected SSL error");
+ }
+}
+
+#ifdef _WIN32
+/* http://stackoverflow.com/questions/10905892/equivalent-of-gettimeday-for-windows */
+int gettimeofday(struct timeval *tp, void *tzp)
+{
+ // Note: some broken versions only have 8 trailing zero's, the correct epoch has 9 trailing zero's
+ static const uint64_t EPOCH = ((uint64_t) 116444736000000000ULL);
+
+ SYSTEMTIME system_time;
+ FILETIME file_time;
+ uint64_t time;
+
+ GetSystemTime( &system_time );
+ SystemTimeToFileTime( &system_time, &file_time );
+ time = ((uint64_t)file_time.dwLowDateTime ) ;
+ time += ((uint64_t)file_time.dwHighDateTime) << 32;
+
+ tp->tv_sec = (long) ((time - EPOCH) / 10000000L);
+ tp->tv_usec = (long) (system_time.wMilliseconds * 1000);
+ return 0;
+}
+#endif
+
+static int ssl_sleep_with_timeout(SSL *ssl, const struct timeval *start,
+ double timeout, int ssl_err) {
+#ifdef _WIN32
+WSAPOLLFD fd;
+#else
+struct pollfd fd;
+#endif
+ struct timeval tv;
+ int ms, tmp;
+
+ assert(timeout > 0);
+ again:
+ gettimeofday(&tv, NULL);
+ /* tv >= start */
+ if ((timeout + start->tv_sec - tv.tv_sec) > INT_MAX / 1000)
+ ms = -1;
+ else {
+ int fract;
+
+ ms = ((start->tv_sec + (int)timeout) - tv.tv_sec) * 1000;
+ fract = (int)((start->tv_usec + (timeout - (int)timeout) * 1000000
+ - tv.tv_usec + 999) / 1000);
+ if (ms > 0 && fract > INT_MAX - ms)
+ ms = -1;
+ else {
+ ms += fract;
+ if (ms <= 0)
+ goto timeout;
+ }
+ }
+ switch (ssl_err) {
+ case SSL_ERROR_WANT_READ:
+ fd.fd = SSL_get_rfd(ssl);
+ fd.events = POLLIN;
+ break;
+
+ case SSL_ERROR_WANT_WRITE:
+ fd.fd = SSL_get_wfd(ssl);
+ fd.events = POLLOUT;
+ break;
+
+ case SSL_ERROR_WANT_X509_LOOKUP:
+ return 0; /* FIXME: is this correct? */
+
+ default:
+ assert(0);
+ }
+ if (fd.fd == -1) {
+ PyErr_SetString(_ssl_err, "timeout on a non-FD SSL");
+ return -1;
+ }
+ Py_BEGIN_ALLOW_THREADS
+#ifdef _WIN32
+ tmp = WSAPoll(&fd, 1, ms);
+#else
+ tmp = poll(&fd, 1, ms);
+#endif
+ Py_END_ALLOW_THREADS
+ switch (tmp) {
+ case 1:
+ return 0;
+ case 0:
+ goto timeout;
+ case -1:
+#ifdef _WIN32
+ if (WSAGetLastError() == EINTR)
+#else
+ if (errno == EINTR)
+#endif
+ goto again;
+ PyErr_SetFromErrno(_ssl_err);
+ return -1;
+ }
+ return 0;
+
+ timeout:
+ PyErr_SetString(_ssl_timeout_err, "timed out");
+ return -1;
+}
+
+PyObject *ssl_accept(SSL *ssl, double timeout) {
PyObject *obj = NULL;
- int r, err;
+ int r, ssl_err;
+ struct timeval tv;
+ if (timeout > 0)
+ gettimeofday(&tv, NULL);
+ again:
Py_BEGIN_ALLOW_THREADS
r = SSL_accept(ssl);
+ ssl_err = SSL_get_error(ssl, r);
Py_END_ALLOW_THREADS
- switch (SSL_get_error(ssl, r)) {
+ switch (ssl_err) {
case SSL_ERROR_NONE:
case SSL_ERROR_ZERO_RETURN:
- obj = PyInt_FromLong((long)1);
+ obj = PyLong_FromLong((long)1);
break;
case SSL_ERROR_WANT_WRITE:
case SSL_ERROR_WANT_READ:
- obj = PyInt_FromLong((long)0);
- break;
- case SSL_ERROR_SSL:
- PyErr_SetString(_ssl_err, ERR_reason_error_string(ERR_get_error()));
+ if (timeout <= 0) {
+ obj = PyLong_FromLong((long)0);
+ break;
+ }
+ if (ssl_sleep_with_timeout(ssl, &tv, timeout, ssl_err) == 0)
+ goto again;
obj = NULL;
break;
+ case SSL_ERROR_SSL:
case SSL_ERROR_SYSCALL:
- err = ERR_get_error();
- if (err)
- PyErr_SetString(_ssl_err, ERR_reason_error_string(err));
- else if (r == 0)
- PyErr_SetString(_ssl_err, "unexpected eof");
- else if (r == -1)
- PyErr_SetFromErrno(_ssl_err);
+ ssl_handle_error(ssl_err, r);
obj = NULL;
break;
}
@@ -445,36 +628,38 @@ PyObject *ssl_accept(SSL *ssl) {
return obj;
}
-PyObject *ssl_connect(SSL *ssl) {
+PyObject *ssl_connect(SSL *ssl, double timeout) {
PyObject *obj = NULL;
- int r, err;
+ int r, ssl_err;
+ struct timeval tv;
+ if (timeout > 0)
+ gettimeofday(&tv, NULL);
+ again:
Py_BEGIN_ALLOW_THREADS
r = SSL_connect(ssl);
+ ssl_err = SSL_get_error(ssl, r);
Py_END_ALLOW_THREADS
- switch (SSL_get_error(ssl, r)) {
+ switch (ssl_err) {
case SSL_ERROR_NONE:
case SSL_ERROR_ZERO_RETURN:
- obj = PyInt_FromLong((long)1);
+ obj = PyLong_FromLong((long)1);
break;
case SSL_ERROR_WANT_WRITE:
case SSL_ERROR_WANT_READ:
- obj = PyInt_FromLong((long)0);
- break;
- case SSL_ERROR_SSL:
- PyErr_SetString(_ssl_err, ERR_reason_error_string(ERR_get_error()));
+ if (timeout <= 0) {
+ obj = PyLong_FromLong((long)0);
+ break;
+ }
+ if (ssl_sleep_with_timeout(ssl, &tv, timeout, ssl_err) == 0)
+ goto again;
obj = NULL;
break;
+ case SSL_ERROR_SSL:
case SSL_ERROR_SYSCALL:
- err = ERR_get_error();
- if (err)
- PyErr_SetString(_ssl_err, ERR_reason_error_string(err));
- else if (r == 0)
- PyErr_SetString(_ssl_err, "unexpected eof");
- else if (r == -1)
- PyErr_SetFromErrno(_ssl_err);
+ ssl_handle_error(ssl_err, r);
obj = NULL;
break;
}
@@ -487,10 +672,11 @@ void ssl_set_shutdown1(SSL *ssl, int mode) {
SSL_set_shutdown(ssl, mode);
}
-PyObject *ssl_read(SSL *ssl, int num) {
+PyObject *ssl_read(SSL *ssl, int num, double timeout) {
PyObject *obj = NULL;
void *buf;
- int r, err;
+ int r;
+ struct timeval tv;
if (!(buf = PyMem_Malloc(num))) {
PyErr_SetString(PyExc_MemoryError, "ssl_read");
@@ -498,37 +684,43 @@ PyObject *ssl_read(SSL *ssl, int num) {
}
+ if (timeout > 0)
+ gettimeofday(&tv, NULL);
+ again:
Py_BEGIN_ALLOW_THREADS
r = SSL_read(ssl, buf, num);
Py_END_ALLOW_THREADS
-
- switch (SSL_get_error(ssl, r)) {
- case SSL_ERROR_NONE:
- case SSL_ERROR_ZERO_RETURN:
- buf = PyMem_Realloc(buf, r);
- obj = PyString_FromStringAndSize(buf, r);
- break;
- case SSL_ERROR_WANT_WRITE:
- case SSL_ERROR_WANT_READ:
- case SSL_ERROR_WANT_X509_LOOKUP:
- Py_INCREF(Py_None);
- obj = Py_None;
- break;
- case SSL_ERROR_SSL:
- PyErr_SetString(_ssl_err, ERR_reason_error_string(ERR_get_error()));
- obj = NULL;
- break;
- case SSL_ERROR_SYSCALL:
- err = ERR_get_error();
- if (err)
- PyErr_SetString(_ssl_err, ERR_reason_error_string(err));
- else if (r == 0)
- PyErr_SetString(_ssl_err, "unexpected eof");
- else if (r == -1)
- PyErr_SetFromErrno(_ssl_err);
- obj = NULL;
- break;
+ if (r >= 0) {
+ buf = PyMem_Realloc(buf, r);
+ obj = PyBytes_FromStringAndSize(buf, r);
+ } else {
+ int ssl_err;
+
+ ssl_err = SSL_get_error(ssl, r);
+ switch (ssl_err) {
+ case SSL_ERROR_NONE:
+ case SSL_ERROR_ZERO_RETURN:
+ assert(0);
+
+ case SSL_ERROR_WANT_WRITE:
+ case SSL_ERROR_WANT_READ:
+ case SSL_ERROR_WANT_X509_LOOKUP:
+ if (timeout <= 0) {
+ Py_INCREF(Py_None);
+ obj = Py_None;
+ break;
+ }
+ if (ssl_sleep_with_timeout(ssl, &tv, timeout, ssl_err) == 0)
+ goto again;
+ obj = NULL;
+ break;
+ case SSL_ERROR_SSL:
+ case SSL_ERROR_SYSCALL:
+ ssl_handle_error(ssl_err, r);
+ obj = NULL;
+ break;
+ }
}
PyMem_Free(buf);
@@ -546,18 +738,20 @@ PyObject *ssl_read_nbio(SSL *ssl, int num) {
PyErr_SetString(PyExc_MemoryError, "ssl_read");
return NULL;
}
-
-
+
+
Py_BEGIN_ALLOW_THREADS
r = SSL_read(ssl, buf, num);
Py_END_ALLOW_THREADS
-
-
+
+
switch (SSL_get_error(ssl, r)) {
case SSL_ERROR_NONE:
case SSL_ERROR_ZERO_RETURN:
buf = PyMem_Realloc(buf, r);
- obj = PyString_FromStringAndSize(buf, r);
+
+ obj = PyBytes_FromStringAndSize(buf, r);
+
break;
case SSL_ERROR_WANT_WRITE:
case SSL_ERROR_WANT_READ:
@@ -566,7 +760,7 @@ PyObject *ssl_read_nbio(SSL *ssl, int num) {
obj = Py_None;
break;
case SSL_ERROR_SSL:
- PyErr_SetString(_ssl_err, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(_ssl_err);
obj = NULL;
break;
case SSL_ERROR_SYSCALL:
@@ -581,27 +775,31 @@ PyObject *ssl_read_nbio(SSL *ssl, int num) {
break;
}
PyMem_Free(buf);
-
-
+
+
return obj;
}
-int ssl_write(SSL *ssl, PyObject *blob) {
- const void *buf;
- int len, r, err, ret;
+int ssl_write(SSL *ssl, PyObject *blob, double timeout) {
+ Py_buffer buf;
+ int r, ssl_err, ret;
+ struct timeval tv;
- if (m2_PyObject_AsReadBufferInt(blob, &buf, &len) == -1) {
+ if (m2_PyObject_GetBufferInt(blob, &buf, PyBUF_CONTIG_RO) == -1) {
return -1;
}
-
+ if (timeout > 0)
+ gettimeofday(&tv, NULL);
+ again:
Py_BEGIN_ALLOW_THREADS
- r = SSL_write(ssl, buf, len);
+ r = SSL_write(ssl, buf.buf, buf.len);
+ ssl_err = SSL_get_error(ssl, r);
Py_END_ALLOW_THREADS
- switch (SSL_get_error(ssl, r)) {
+ switch (ssl_err) {
case SSL_ERROR_NONE:
case SSL_ERROR_ZERO_RETURN:
ret = r;
@@ -609,43 +807,40 @@ int ssl_write(SSL *ssl, PyObject *blob) {
case SSL_ERROR_WANT_WRITE:
case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_X509_LOOKUP:
+ if (timeout <= 0) {
+ ret = -1;
+ break;
+ }
+ if (ssl_sleep_with_timeout(ssl, &tv, timeout, ssl_err) == 0)
+ goto again;
ret = -1;
break;
case SSL_ERROR_SSL:
- PyErr_SetString(_ssl_err, ERR_reason_error_string(ERR_get_error()));
- ret = -1;
- break;
case SSL_ERROR_SYSCALL:
- err = ERR_get_error();
- if (err)
- PyErr_SetString(_ssl_err, ERR_reason_error_string(ERR_get_error()));
- else if (r == 0)
- PyErr_SetString(_ssl_err, "unexpected eof");
- else if (r == -1)
- PyErr_SetFromErrno(_ssl_err);
+ ssl_handle_error(ssl_err, r);
default:
ret = -1;
}
-
-
+
+ m2_PyBuffer_Release(blob, &buf);
return ret;
}
int ssl_write_nbio(SSL *ssl, PyObject *blob) {
- const void *buf;
- int len, r, err, ret;
+ Py_buffer buf;
+ int r, err, ret;
- if (m2_PyObject_AsReadBufferInt(blob, &buf, &len) == -1) {
+ if (m2_PyObject_GetBufferInt(blob, &buf, PyBUF_CONTIG_RO) == -1) {
return -1;
}
-
+
Py_BEGIN_ALLOW_THREADS
- r = SSL_write(ssl, buf, len);
+ r = SSL_write(ssl, buf.buf, buf.len);
Py_END_ALLOW_THREADS
-
-
+
+
switch (SSL_get_error(ssl, r)) {
case SSL_ERROR_NONE:
case SSL_ERROR_ZERO_RETURN:
@@ -670,8 +865,8 @@ int ssl_write_nbio(SSL *ssl, PyObject *blob) {
default:
ret = -1;
}
-
-
+
+ m2_PyBuffer_Release(blob, &buf);
return ret;
}
@@ -683,7 +878,7 @@ int sk_ssl_cipher_num(STACK_OF(SSL_CIPHER) *stack) {
return sk_SSL_CIPHER_num(stack);
}
-SSL_CIPHER *sk_ssl_cipher_value(STACK_OF(SSL_CIPHER) *stack, int idx) {
+const SSL_CIPHER *sk_ssl_cipher_value(STACK_OF(SSL_CIPHER) *stack, int idx) {
return sk_SSL_CIPHER_value(stack, idx);
}
@@ -707,12 +902,23 @@ void i2d_ssl_session(BIO *bio, SSL_SESSION *sess) {
}
%}
+%typemap(out) SSL_SESSION * {
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+
+ if ($1 != NULL)
+ $result = SWIG_NewPointerObj($1, $1_descriptor, 0);
+ else {
+ m2_PyErr_Msg(_ssl_err);
+ $result = NULL;
+ }
+}
%threadallow ssl_session_read_pem;
%inline %{
SSL_SESSION *ssl_session_read_pem(BIO *bio) {
return PEM_read_bio_SSL_SESSION(bio, NULL, NULL, NULL);
}
%}
+%typemap(out) SSL_SESSION * ;
%threadallow ssl_session_write_pem;
%inline %{
diff --git a/SWIG/_threads.i b/SWIG/_threads.i
index bb625df..69adb9f 100644
--- a/SWIG/_threads.i
+++ b/SWIG/_threads.i
@@ -1,18 +1,19 @@
/* Copyright (c) 1999 Ng Pheng Siong. All rights reserved. */
-/* $Id: _threads.i 690 2009-07-22 08:32:43Z heikki $ */
+/* $Id$ */
%{
#include <pythread.h>
#include <openssl/crypto.h>
-#ifdef THREADING
-static PyThread_type_lock lock_cs[CRYPTO_NUM_LOCKS];
-static long lock_count[CRYPTO_NUM_LOCKS];
+#if defined(THREADING) && OPENSSL_VERSION_NUMBER < 0x10100000L
+#define CRYPTO_num_locks() (CRYPTO_NUM_LOCKS)
+static PyThread_type_lock lock_cs[CRYPTO_num_locks()];
+static long lock_count[CRYPTO_num_locks()];
static int thread_mode = 0;
#endif
void threading_locking_callback(int mode, int type, const char *file, int line) {
-#ifdef THREADING
+#if defined(THREADING) && OPENSSL_VERSION_NUMBER < 0x10100000L
if (mode & CRYPTO_LOCK) {
PyThread_acquire_lock(lock_cs[type], WAIT_LOCK);
lock_count[type]++;
@@ -24,7 +25,7 @@ void threading_locking_callback(int mode, int type, const char *file, int line)
}
unsigned long threading_id_callback(void) {
-#ifdef THREADING
+#if defined(THREADING) && OPENSSL_VERSION_NUMBER < 0x10100000L
return (unsigned long)PyThread_get_thread_ident();
#else
return (unsigned long)0;
@@ -34,10 +35,10 @@ unsigned long threading_id_callback(void) {
%inline %{
void threading_init(void) {
-#ifdef THREADING
+#if defined(THREADING) && OPENSSL_VERSION_NUMBER < 0x10100000L
int i;
if (!thread_mode) {
- for (i=0; i<CRYPTO_NUM_LOCKS; i++) {
+ for (i=0; i<CRYPTO_num_locks(); i++) {
lock_count[i]=0;
lock_cs[i]=PyThread_allocate_lock();
}
@@ -49,11 +50,11 @@ void threading_init(void) {
}
void threading_cleanup(void) {
-#ifdef THREADING
+#if defined(THREADING) && OPENSSL_VERSION_NUMBER < 0x10100000L
int i;
if (thread_mode) {
CRYPTO_set_locking_callback(NULL);
- for (i=0; i<CRYPTO_NUM_LOCKS; i++) {
+ for (i=0; i<CRYPTO_num_locks(); i++) {
lock_count[i]=0;
PyThread_release_lock(lock_cs[i]);
PyThread_free_lock(lock_cs[i]);
diff --git a/SWIG/_util.i b/SWIG/_util.i
index 522b8c8..bc2ee61 100644
--- a/SWIG/_util.i
+++ b/SWIG/_util.i
@@ -1,12 +1,13 @@
/* Copyright (c) 1999-2002 Ng Pheng Siong. All rights reserved.
* Copyright (c) 2009-2010 Heikki Toivonen. All rights reserved.
*/
-/* $Id: _util.i 721 2010-02-13 06:30:33Z heikki $ */
+/* $Id$ */
%{
#include <openssl/x509v3.h>
%}
+%warnfilter(454) _util_err;
%inline %{
static PyObject *_util_err;
@@ -26,10 +27,12 @@ PyObject *util_hex_to_string(PyObject *blob) {
ret = hex_to_string((unsigned char *)buf, len);
if (!ret) {
- PyErr_SetString(_util_err, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(_util_err);
return NULL;
}
- obj = PyString_FromString(ret);
+
+ obj = PyBytes_FromString(ret);
+
OPENSSL_free(ret);
return obj;
}
@@ -47,10 +50,10 @@ PyObject *util_string_to_hex(PyObject *blob) {
len = len0;
ret = string_to_hex((char *)buf, &len);
if (ret == NULL) {
- PyErr_SetString(_util_err, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(_util_err);
return NULL;
}
- obj = PyString_FromStringAndSize((char*)ret, len);
+ obj = PyBytes_FromStringAndSize((char*)ret, len);
OPENSSL_free(ret);
return obj;
}
diff --git a/SWIG/_x509.i b/SWIG/_x509.i
index 0471f68..3c3e83e 100644
--- a/SWIG/_x509.i
+++ b/SWIG/_x509.i
@@ -7,11 +7,22 @@
** Copyright (c) 2009-2010 Heikki Toivonen. All rights reserved.
**
*/
-/* $Id: _x509.i 721 2010-02-13 06:30:33Z heikki $ */
+/* $Id$ */
%{
+#include <openssl/asn1.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
+
+#include <openssl/asn1t.h>
+
+typedef STACK_OF(X509) SEQ_CERT;
+
+ASN1_ITEM_TEMPLATE(SEQ_CERT) =
+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, SeqCert, X509)
+ASN1_ITEM_TEMPLATE_END(SEQ_CERT)
+
+IMPLEMENT_ASN1_FUNCTIONS(SEQ_CERT)
%}
%apply Pointer NONNULL { BIO * };
@@ -62,9 +73,9 @@ extern X509_NAME *X509_get_subject_name(X509 *);
%rename(x509_set_subject_name) X509_set_subject_name;
extern int X509_set_subject_name(X509 *, X509_NAME *);
%rename(x509_cmp_current_time) X509_cmp_current_time;
-extern int X509_cmp_current_time(ASN1_UTCTIME *);
+extern int X509_cmp_current_time(ASN1_TIME *);
+
-
/* From x509.h */
/* standard trust ids */
%constant int X509_TRUST_DEFAULT = -1;
@@ -149,8 +160,6 @@ extern int X509_NAME_add_entry_by_NID(X509_NAME *, int, int, unsigned char *, in
%rename(x509_name_print_ex) X509_NAME_print_ex;
%threadallow X509_NAME_print_ex;
extern int X509_NAME_print_ex(BIO *, X509_NAME *, int, unsigned long);
-%rename(x509_name_print_ex_fp) X509_NAME_print_ex_fp;
-extern int X509_NAME_print_ex_fp(FILE *, X509_NAME *, int, unsigned long);
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
%rename(x509_name_hash) X509_NAME_hash_old;
@@ -177,14 +186,23 @@ extern ASN1_OBJECT *X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *);
%rename(x509_name_entry_get_data) X509_NAME_ENTRY_get_data;
extern ASN1_STRING *X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *);
-%typemap(in) (CONST unsigned char *, int) {
+%typemap(in) (const unsigned char *, int) {
+#if PY_MAJOR_VERSION >= 3
+ if (PyBytes_Check($input)) {
+ Py_ssize_t len;
+
+ $1 = PyBytes_AsString($input);
+ len = PyBytes_Size($input);
+#else
if (PyString_Check($input)) {
Py_ssize_t len;
- $1 = (unsigned char *)PyString_AsString($input);
+ $1 = (unsigned char *)PyString_AsString($input);
len = PyString_Size($input);
+#endif // PY_MAJOR_VERSION >= 3
+
if (len > INT_MAX) {
- PyErr_SetString(PyExc_ValueError, "object too large");
+ PyErr_SetString(_x509_err, "object too large");
return NULL;
}
$2 = len;
@@ -194,8 +212,8 @@ extern ASN1_STRING *X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *);
}
}
%rename(x509_name_entry_set_data) X509_NAME_ENTRY_set_data;
-extern int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *, int, CONST unsigned char *, int);
-%typemap(in) (CONST unsigned char *, int);
+extern int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *, int, const unsigned char *, int);
+%typemap(in) (const unsigned char *, int);
%rename(x509_req_new) X509_REQ_new;
extern X509_REQ * X509_REQ_new();
@@ -230,6 +248,9 @@ extern X509_STORE *X509_STORE_new(void);
extern void X509_STORE_free(X509_STORE *);
%rename(x509_store_add_cert) X509_STORE_add_cert;
extern int X509_STORE_add_cert(X509_STORE *, X509 *);
+%rename(x509_store_set_verify_cb) X509_STORE_set_verify_cb;
+extern void X509_STORE_set_verify_cb(X509_STORE *st,
+ int (*verify_cb)(int ok, X509_STORE_CTX *ctx));
%rename(x509_store_ctx_get_current_cert) X509_STORE_CTX_get_current_cert;
extern X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *);
@@ -247,6 +268,35 @@ extern int X509_EXTENSION_get_critical(X509_EXTENSION *);
%rename(x509_extension_set_critical) X509_EXTENSION_set_critical;
extern int X509_EXTENSION_set_critical(X509_EXTENSION *, int);
+%typemap(out) X509 * {
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+
+ if ($1 != NULL)
+ $result = SWIG_NewPointerObj($1, $1_descriptor, 0);
+ else {
+ m2_PyErr_Msg(_x509_err);
+ $result = NULL;
+ }
+}
+
+
+/* Functions using m2_PyErr_Msg and thus using internal Python C API are
+ * not thread safe, so if we want to have %threadallow here, error
+ * handling must be done outside of these internal functions. */
+%threadallow x509_read_pem;
+%inline %{
+X509 *x509_read_pem(BIO *bio) {
+ return PEM_read_bio_X509(bio, NULL, NULL, NULL);
+}
+%}
+
+%threadallow d2i_x509;
+%inline %{
+X509 *d2i_x509(BIO *bio) {
+ return d2i_X509_bio(bio, NULL);
+}
+%}
+%typemap(out) X509 *;
%constant int NID_commonName = 13;
%constant int NID_countryName = 14;
@@ -319,6 +369,7 @@ extern int X509_EXTENSION_set_critical(X509_EXTENSION *, int);
%constant int RSA_3 = 0x3L;
%constant int RSA_F4 = 0x10001L;
+%warnfilter(454) _x509_err;
%inline %{
static PyObject *_x509_err;
@@ -328,50 +379,51 @@ void x509_init(PyObject *x509_err) {
}
%}
-%threadallow x509_read_pem;
+%typemap(out) X509_REQ * {
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+
+ if ($1 != NULL)
+ $result = SWIG_NewPointerObj($1, $1_descriptor, 0);
+ else {
+ m2_PyErr_Msg(_x509_err);
+ $result = NULL;
+ }
+}
+%threadallow d2i_x509_req;
%inline %{
-X509 *x509_read_pem(BIO *bio) {
- return PEM_read_bio_X509(bio, NULL, NULL, NULL);
+X509_REQ *d2i_x509_req(BIO *bio) {
+ return d2i_X509_REQ_bio(bio, NULL);
}
%}
-%threadallow d2i_x509;
+%threadallow x509_req_read_pem;
%inline %{
-X509 *d2i_x509(BIO *bio) {
- return d2i_X509_bio(bio, NULL);
+X509_REQ *x509_req_read_pem(BIO *bio) {
+ return PEM_read_bio_X509_REQ(bio, NULL, NULL, NULL);
}
%}
-%threadallow d2i_x509_req;
-%inline %{
-X509_REQ *d2i_x509_req(BIO *bio) {
- return d2i_X509_REQ_bio(bio, NULL);
-}
+%typemap(out) X509_REQ *;
-PyObject *i2d_x509(X509 *x)
-{
+%inline %{
+PyObject *i2d_x509(X509 *x) {
int len;
PyObject *ret = NULL;
unsigned char *buf = NULL;
len = i2d_X509(x, &buf);
if (len < 0) {
- PyErr_SetString(_x509_err, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(_x509_err);
}
- else {
- ret = PyString_FromStringAndSize((char*)buf, len);
+ else {
+
+ ret = PyBytes_FromStringAndSize((char*)buf, len);
+
OPENSSL_free(buf);
}
return ret;
}
%}
-%threadallow x509_req_read_pem;
-%inline %{
-X509_REQ *x509_req_read_pem(BIO *bio) {
- return PEM_read_bio_X509_REQ(bio, NULL, NULL, NULL);
-}
-%}
-
%threadallow x509_req_write_pem;
%inline %{
int x509_req_write_pem(BIO *bio, X509_REQ *x) {
@@ -379,12 +431,25 @@ int x509_req_write_pem(BIO *bio, X509_REQ *x) {
}
%}
+%typemap(out) X509_CRL * {
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+
+ if ($1 != NULL)
+ $result = SWIG_NewPointerObj($1, $1_descriptor, 0);
+ else {
+ m2_PyErr_Msg(_x509_err);
+ $result = NULL;
+ }
+}
%threadallow x509_crl_read_pem;
%inline %{
X509_CRL *x509_crl_read_pem(BIO *bio) {
return PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL);
}
+%}
+%typemap(out) X509_CRL * ;
+%inline %{
/* X509_set_version() is a macro. */
int x509_set_version(X509 *x, long version) {
return X509_set_version(x, version);
@@ -396,22 +461,22 @@ long x509_get_version(X509 *x) {
}
/* X509_set_notBefore() is a macro. */
-int x509_set_not_before(X509 *x, ASN1_UTCTIME *tm) {
+int x509_set_not_before(X509 *x, ASN1_TIME *tm) {
return X509_set_notBefore(x, tm);
}
/* X509_get_notBefore() is a macro. */
-ASN1_UTCTIME *x509_get_not_before(X509 *x) {
+ASN1_TIME *x509_get_not_before(X509 *x) {
return X509_get_notBefore(x);
}
/* X509_set_notAfter() is a macro. */
-int x509_set_not_after(X509 *x, ASN1_UTCTIME *tm) {
+int x509_set_not_after(X509 *x, ASN1_TIME *tm) {
return X509_set_notAfter(x, tm);
}
/* X509_get_notAfter() is a macro. */
-ASN1_UTCTIME *x509_get_not_after(X509 *x) {
+ASN1_TIME *x509_get_not_after(X509 *x) {
return X509_get_notAfter(x);
}
@@ -419,8 +484,8 @@ int x509_sign(X509 *x, EVP_PKEY *pkey, EVP_MD *md) {
return X509_sign(x, pkey, md);
}
-/* XXX The first parameter is really ASN1_TIME, does it matter? */
-ASN1_TIME *x509_gmtime_adj(ASN1_UTCTIME *s, long adj) {
+/* x509_gmtime_adj() is a macro. */
+ASN1_TIME *x509_gmtime_adj(ASN1_TIME *s, long adj) {
return X509_gmtime_adj(s, adj);
}
@@ -430,8 +495,7 @@ PyObject *x509_name_by_nid(X509_NAME *name, int nid) {
PyObject *ret;
if ((len = X509_NAME_get_text_by_NID(name, nid, NULL, 0)) == -1) {
- Py_INCREF(Py_None);
- return Py_None;
+ Py_RETURN_NONE;
}
len++;
if (!(buf = PyMem_Malloc(len))) {
@@ -439,13 +503,15 @@ PyObject *x509_name_by_nid(X509_NAME *name, int nid) {
return NULL;
}
xlen = X509_NAME_get_text_by_NID(name, nid, buf, len);
- ret = PyString_FromStringAndSize(buf, xlen);
+
+ ret = PyBytes_FromStringAndSize(buf, xlen);
+
PyMem_Free(buf);
return ret;
}
int x509_name_set_by_nid(X509_NAME *name, int nid, PyObject *obj) {
- return X509_NAME_add_entry_by_NID(name, nid, MBSTRING_ASC, (unsigned char *)PyString_AsString(obj), -1, -1, 0);
+ return X509_NAME_add_entry_by_NID(name, nid, MBSTRING_ASC, (unsigned char *)PyBytes_AsString(obj), -1, -1, 0);
}
/* x509_name_add_entry_by_txt */
@@ -453,15 +519,15 @@ int x509_name_add_entry_by_txt(X509_NAME *name, char *field, int type, char *byt
return X509_NAME_add_entry_by_txt(name, field, type, (unsigned char *)bytes, len, loc, set);
}
-PyObject *x509_name_get_der(X509_NAME *name)
-{
+PyObject *x509_name_get_der(X509_NAME *name) {
+ const char* pder="";
+ size_t pderlen;
i2d_X509_NAME(name, 0);
- return PyString_FromStringAndSize(name->bytes->data, name->bytes->length);
-}
-
-/* sk_X509_new_null() is a macro returning "STACK_OF(X509) *". */
-STACK_OF(X509) *sk_x509_new_null(void) {
- return sk_X509_new_null();
+ if (!X509_NAME_get0_der(name, (const unsigned char **)pder, &pderlen)) {
+ m2_PyErr_Msg(_x509_err);
+ return NULL;
+ }
+ return PyBytes_FromStringAndSize(pder, pderlen);
}
/* sk_X509_free() is a macro. */
@@ -478,9 +544,16 @@ int sk_x509_push(STACK_OF(X509) *stack, X509 *x509) {
X509 *sk_x509_pop(STACK_OF(X509) *stack) {
return sk_X509_pop(stack);
}
+%}
+%inline %{
int x509_store_load_locations(X509_STORE *store, const char *file) {
- return X509_STORE_load_locations(store, file, NULL);
+ int locations = 0;
+
+ if ((locations = X509_STORE_load_locations(store, file, NULL)) < 1) {
+ m2_PyErr_Msg(_x509_err);
+ }
+ return locations;
}
int x509_type_check(X509 *x509) {
@@ -510,48 +583,56 @@ int x509_req_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts) {
X509_NAME_ENTRY *x509_name_entry_create_by_txt(X509_NAME_ENTRY **ne, char *field, int type, char *bytes, int len) {
return X509_NAME_ENTRY_create_by_txt( ne, field, type, (unsigned char *)bytes, len);
}
+%}
-#if OPENSSL_VERSION_NUMBER >= 0x10000000L
-LHASH_OF(CONF_VALUE)
-#else
-LHASH
-#endif
-*x509v3_lhash() {
- return lh_new(NULL, NULL); /* Should probably be lh_CONF_VALUE_new but won't compile. */
-}
+%typemap(out) X509V3_CTX * {
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+ if ($1 != NULL)
+ $result = SWIG_NewPointerObj($1, $1_descriptor, 0);
+ else {
+ $result = NULL;
+ }
+}
+%inline %{
X509V3_CTX *
-#if OPENSSL_VERSION_NUMBER >= 0x10000000L
-x509v3_set_conf_lhash(LHASH_OF(CONF_VALUE) * lhash) {
-#else
-x509v3_set_conf_lhash(LHASH * lhash) {
-#endif
+x509v3_set_nconf(void) {
X509V3_CTX * ctx;
+ CONF *conf = NCONF_new(NULL);
+
if (!(ctx=(X509V3_CTX *)PyMem_Malloc(sizeof(X509V3_CTX)))) {
- PyErr_SetString(PyExc_MemoryError, "x509v3_set_conf_lhash");
+ PyErr_SetString(PyExc_MemoryError, "x509v3_set_nconf");
return NULL;
}
- X509V3_set_conf_lhash(ctx, lhash);
+ /* X509V3_set_nconf does not generate any error signs at all. */
+ X509V3_set_nconf(ctx, conf);
return ctx;
}
+%}
+%typemap(out) X509V3_CTX * ;
+
+%typemap(out) X509_EXTENSION * {
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+ if ($1 != NULL)
+ $result = SWIG_NewPointerObj($1, $1_descriptor, 0);
+ else {
+ m2_PyErr_Msg(_x509_err);
+ $result = NULL;
+ }
+}
+%inline %{
X509_EXTENSION *
-#if OPENSSL_VERSION_NUMBER >= 0x10000000L
-x509v3_ext_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, char *name, char *value) {
-#else
-x509v3_ext_conf(LHASH *conf, X509V3_CTX *ctx, char *name, char *value) {
-#endif
+x509v3_ext_conf(void *conf, X509V3_CTX *ctx, char *name, char *value) {
X509_EXTENSION * ext = NULL;
- ext = X509V3_EXT_conf(conf, ctx, name, value);
- PyMem_Free(ctx);
-#if OPENSSL_VERSION_NUMBER >= 0x10000000L
- lh_CONF_VALUE_free(conf);
-#else
- lh_free(conf);
-#endif
+ ext = X509V3_EXT_conf(conf, ctx, name, value);
+ PyMem_Free(ctx);
return ext;
}
+%}
+%typemap(out) X509_EXTENSION * ;
+%inline %{
/* X509_EXTENSION_free() might be a macro, didn't find definition. */
void x509_extension_free(X509_EXTENSION *ext) {
X509_EXTENSION_free(ext);
@@ -559,13 +640,13 @@ void x509_extension_free(X509_EXTENSION *ext) {
PyObject *x509_extension_get_name(X509_EXTENSION *ext) {
PyObject * ext_name;
- const char * ext_name_str;
+ const char * ext_name_str;
ext_name_str = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext)));
if (!ext_name_str) {
- PyErr_SetString(_x509_err, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(_x509_err);
return NULL;
}
- ext_name = PyString_FromStringAndSize(ext_name_str, strlen(ext_name_str));
+ ext_name = PyBytes_FromStringAndSize(ext_name_str, strlen(ext_name_str));
return ext_name;
}
@@ -604,59 +685,89 @@ void *x509_store_ctx_get_app_data(X509_STORE_CTX *ctx) {
return X509_STORE_CTX_get_app_data(ctx);
}
-/*#defines for i2d and d2i types, which are typed differently
-in openssl-0.9.8 than they are in openssl-0.9.7. This will
-be picked up by the C preprocessor, not the SWIG preprocessor.
-Used in the wrapping of ASN1_seq_unpack and ASN1_seq_pack functions.
-*/
-#if OPENSSL_VERSION_NUMBER >= 0x0090800fL
-#define D2ITYPE d2i_of_void *
-#define I2DTYPE i2d_of_void *
-#else
-#define D2ITYPE char *(*)()
-#define I2DTYPE int (*)()
-#endif
+/* X509_STORE_CTX_get_app_data is a macro. */
+void *x509_store_ctx_get_ex_data(X509_STORE_CTX *ctx, int idx) {
+ return X509_STORE_CTX_get_ex_data(ctx, idx);
+}
+
+void x509_store_set_verify_cb(X509_STORE *store, PyObject *pyfunc) {
+ Py_XDECREF(x509_store_verify_cb_func);
+ Py_INCREF(pyfunc);
+ x509_store_verify_cb_func = pyfunc;
+ X509_STORE_set_verify_cb(store, x509_store_verify_callback);
+}
+%}
+%typemap(out) STACK_OF(X509) * {
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+
+ if ($1 != NULL)
+ $result = SWIG_NewPointerObj($1, $1_descriptor, 0);
+ else {
+ $result = NULL;
+ }
+}
+
+%inline %{
STACK_OF(X509) *
make_stack_from_der_sequence(PyObject * pyEncodedString){
STACK_OF(X509) *certs;
Py_ssize_t encoded_string_len;
char *encoded_string;
+ const unsigned char *tmp_str;
+
+ encoded_string_len = PyBytes_Size(pyEncodedString);
- encoded_string_len = PyString_Size(pyEncodedString);
if (encoded_string_len > INT_MAX) {
- PyErr_SetString(PyExc_ValueError, "object too large");
+ PyErr_Format(_x509_err, "object too large");
return NULL;
}
- encoded_string = PyString_AsString(pyEncodedString);
+
+ encoded_string = PyBytes_AsString(pyEncodedString);
+
if (!encoded_string) {
+ PyErr_SetString(_x509_err,
+ "Cannot convert Python Bytes to (char *).");
return NULL;
}
- certs = ASN1_seq_unpack_X509((unsigned char *)encoded_string, encoded_string_len, d2i_X509, X509_free );
- if (!certs) {
- PyErr_SetString(_x509_err, ERR_reason_error_string(ERR_get_error()));
- return NULL;
+ tmp_str = (unsigned char *)encoded_string;
+ certs = d2i_SEQ_CERT(NULL, &tmp_str, encoded_string_len);
+ if (certs == NULL) {
+ PyErr_SetString(_x509_err, "Generating STACK_OF(X509) failed.");
+ return NULL;
}
-
return certs;
}
+/* sk_X509_new_null() is a macro returning "STACK_OF(X509) *". */
+STACK_OF(X509) *sk_x509_new_null(void) {
+ return sk_X509_new_null();
+}
+%}
+
+%typemap(out) STACK_OF(X509) *;
+
+%inline %{
PyObject *
get_der_encoding_stack(STACK_OF(X509) *stack){
PyObject * encodedString;
-
- unsigned char * encoding;
- int len;
-
- encoding = ASN1_seq_pack_X509(stack, i2d_X509, NULL, &len);
+
+ unsigned char * encoding = NULL;
+ int len;
+
+ len = i2d_SEQ_CERT(stack, &encoding);
if (!encoding) {
- PyErr_SetString(_x509_err, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(_x509_err);
return NULL;
}
- encodedString = PyString_FromStringAndSize((const char *)encoding, len);
- OPENSSL_free(encoding);
- return encodedString;
+
+ encodedString = PyBytes_FromStringAndSize((const char *)encoding, len);
+
+ if (encoding)
+ OPENSSL_free(encoding);
+
+ return encodedString;
}
%}
@@ -664,7 +775,7 @@ get_der_encoding_stack(STACK_OF(X509) *stack){
/* Free malloc'ed return value for x509_name_oneline */
%typemap(ret) char * {
if ($1 != NULL)
- OPENSSL_free($1);
+ OPENSSL_free($1);
}
%inline %{
char *x509_name_oneline(X509_NAME *x) {
diff --git a/SWIG/libcrypto-compat.h b/SWIG/libcrypto-compat.h
new file mode 100644
index 0000000..7c4c913
--- /dev/null
+++ b/SWIG/libcrypto-compat.h
@@ -0,0 +1,62 @@
+#ifndef LIBCRYPTO_COMPAT_H
+#define LIBCRYPTO_COMPAT_H
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+#include <openssl/ecdsa.h>
+#include <openssl/dh.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+
+int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d);
+int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q);
+int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp);
+void RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d);
+void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q);
+void RSA_get0_crt_params(const RSA *r, const BIGNUM **dmp1, const BIGNUM **dmq1, const BIGNUM **iqmp);
+
+void DSA_get0_pqg(const DSA *d, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g);
+int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g);
+void DSA_get0_key(const DSA *d, const BIGNUM **pub_key, const BIGNUM **priv_key);
+int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key);
+
+void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps);
+int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s);
+
+void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps);
+int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s);
+
+void DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g);
+int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g);
+void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key);
+int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key);
+int DH_set_length(DH *dh, long length);
+
+const unsigned char *EVP_CIPHER_CTX_iv(const EVP_CIPHER_CTX *ctx);
+unsigned char *EVP_CIPHER_CTX_iv_noconst(EVP_CIPHER_CTX *ctx);
+EVP_MD_CTX *EVP_MD_CTX_new(void);
+void EVP_MD_CTX_free(EVP_MD_CTX *ctx);
+#define EVP_CIPHER_impl_ctx_size(e) e->ctx_size
+#define EVP_CIPHER_CTX_get_cipher_data(ctx) ctx->cipher_data
+
+int RSA_size(const RSA* rsa);
+RSA_METHOD *RSA_meth_dup(const RSA_METHOD *meth);
+int RSA_meth_set1_name(RSA_METHOD *meth, const char *name);
+#define RSA_meth_get_finish(meth) meth->finish
+int RSA_meth_set_priv_enc(RSA_METHOD *meth, int (*priv_enc) (int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding));
+int RSA_meth_set_priv_dec(RSA_METHOD *meth, int (*priv_dec) (int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding));
+int RSA_meth_set_finish(RSA_METHOD *meth, int (*finish) (RSA *rsa));
+void RSA_meth_free(RSA_METHOD *meth);
+
+int RSA_bits(const RSA *r);
+
+RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey);
+
+int X509_NAME_get0_der(X509_NAME *nm, const unsigned char **pder,
+ size_t *pderlen);
+
+#endif /* OPENSSL_VERSION_NUMBER */
+
+#endif /* LIBCRYPTO_COMPAT_H */
diff --git a/SWIG/py3k_compat.h b/SWIG/py3k_compat.h
new file mode 100644
index 0000000..2e914a5
--- /dev/null
+++ b/SWIG/py3k_compat.h
@@ -0,0 +1,32 @@
+#ifndef PY3K_COMPAT_H
+#define PY3K_COMPAT_H
+
+#if PY_MAJOR_VERSION >= 3
+
+FILE* PyFile_AsFile(PyObject *p);
+PyObject* PyFile_Name(PyObject *p);
+
+#else /* PY2K */
+
+/* Concerning PyBytes* functions:
+ *
+ * Python 3’s str() type is equivalent to Python 2’s unicode(); the
+ * C functions are called PyUnicode_* for both. The old 8-bit string
+ * type has become bytes(), with C functions called PyBytes_*. Python
+ * 2.6 and later provide a compatibility header, bytesobject.h, mapping
+ * PyBytes names to PyString ones. For best compatibility with Python 3,
+ * PyUnicode should be used for textual data and PyBytes for binary
+ * data. It’s also important to remember that PyBytes and PyUnicode in
+ * Python 3 are not interchangeable like PyString and PyUnicode are in
+ * Python 2. The following example shows best practices with regards to
+ * PyUnicode, PyString, and PyBytes.
+ *
+ * From https://docs.python.org/2.7/howto/cporting.html
+ */
+
+PyObject* PyLong_FromLong(long x);
+const char* PyUnicode_AsUTF8(PyObject *unicode);
+
+#endif /* PY_MAJOR_VERSION */
+
+#endif /* PY3K_COMPAT_H */
diff --git a/appveyor.yml b/appveyor.yml
new file mode 100644
index 0000000..8d39bc4
--- /dev/null
+++ b/appveyor.yml
@@ -0,0 +1,151 @@
+environment:
+ global:
+ # PyPI login environment:
+ USER:
+ secure: oqWqarxnd4H23FMywnlQeg==
+ PASS:
+ secure: j/VSxdYJ7mdR44u8OdywLg==
+ X86_OPENSSL_INSTALLER: Win32OpenSSL-1_1_0k.exe
+ X64_OPENSSL_INSTALLER: Win64OpenSSL-1_1_0k.exe
+
+ matrix:
+
+ # Pre-installed Python versions, which Appveyor may upgrade to
+ # a later point release.
+ - PYTHON: "C:\\Python36"
+ PYTHON_VERSION: "3.6.x" # currently 3.6.4
+ PYTHON_ARCH: "32"
+ OPENSSL_PATH: "C:\\OpenSSL-1-1-Win32"
+ PYWIN32: "pywin32-222.win32-py3.6.exe"
+ PYWIN32_RELEASE: b222
+
+ - PYTHON: "C:\\Python36-x64"
+ PYTHON_VERSION: "3.6.x" # currently 3.6.4
+ PYTHON_ARCH: "64"
+ OPENSSL_PATH: "C:\\OpenSSL-1-1-Win64"
+ PYWIN32: "pywin32-222.win-amd64-py3.6.exe"
+ PYWIN32_RELEASE: b222
+ APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
+
+ - PYTHON: "C:\\Python35"
+ PYTHON_VERSION: "3.5.x" # currently 3.6.4
+ PYTHON_ARCH: "32"
+ OPENSSL_PATH: "C:\\OpenSSL-1-1-Win32"
+ PYWIN32: "pywin32-222.win32-py3.5.exe"
+ PYWIN32_RELEASE: b222
+
+ - PYTHON: "C:\\Python35-x64"
+ PYTHON_VERSION: "3.5.x" # currently 3.6.4
+ PYTHON_ARCH: "64"
+ OPENSSL_PATH: "C:\\OpenSSL-1-1-Win64"
+ PYWIN32: "pywin32-222.win-amd64-py3.5.exe"
+ PYWIN32_RELEASE: b222
+ APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
+
+ - PYTHON: "C:\\Python27"
+ PYTHON_VERSION: "2.7.x" # currently 2.7.9
+ PYTHON_ARCH: "32"
+ OPENSSL_PATH: "C:\\OpenSSL-Win32"
+ PYWIN32: "pywin32-222.win32-py2.7.exe"
+ PYWIN32_RELEASE: b222
+
+ - PYTHON: "C:\\Python27"
+ PYTHON_VERSION: "2.7.x" # currently 2.7.9
+ PYTHON_ARCH: "32"
+ OPENSSL_PATH: "C:\\OpenSSL-1-1-Win32"
+ PYWIN32: "pywin32-222.win32-py2.7.exe"
+ PYWIN32_RELEASE: b222
+
+ - PYTHON: "C:\\Python27-x64"
+ PYTHON_VERSION: "2.7.x" # currently 2.7.9
+ PYTHON_ARCH: "64"
+ OPENSSL_PATH: "C:\\OpenSSL-1-1-Win64"
+ PYWIN32: "pywin32-222.win-amd64-py2.7.exe"
+ PYWIN32_RELEASE: b222
+
+ - PYTHON: "C:\\Python27-x64"
+ PYTHON_VERSION: "2.7.x" # currently 2.7.9
+ PYTHON_ARCH: "64"
+ OPENSSL_PATH: "C:\\OpenSSL-1-1-Win64"
+ PYWIN32: "pywin32-222.win-amd64-py2.7.exe"
+ PYWIN32_RELEASE: b222
+
+nuget:
+ account_feed: true
+
+install:
+ # Install non-python dependencies using chocolatey package manager
+ - choco install -r -y swig
+
+
+ # Install Python (from the official .msi of http://python.org) and pip when
+ # not already installed.
+ - ps: if (-not(Test-Path($env:PYTHON))) { & appveyor\install.ps1 }
+
+ # Prepend newly installed Python to the PATH of this build (this cannot be
+ # done from inside the powershell script as it would require to restart
+ # the parent CMD process).
+ - "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%;%OPENSSL_PATH%\\bin"
+
+ # Check that we have the expected version and architecture for Python
+ - "python --version"
+ - "python -c \"import struct; print(struct.calcsize('P') * 8)\""
+
+ # Install the build dependencies of the project. If some dependencies contain
+ # compiled extensions and are not provided as pre-built wheel packages,
+ # pip will build them from source using the MSVC compiler matching the
+ # target Python version and architecture
+ - "%PYTHON%\\Scripts\\pip.exe install -r dev-requirements.txt"
+
+ - ECHO "Install OpenSSL 1.1.0 32bit"
+ - curl -o "c:\\%X86_OPENSSL_INSTALLER%" -fsSL "https://slproweb.com/download/%X86_OPENSSL_INSTALLER%"
+ - "c:\\%X86_OPENSSL_INSTALLER% /silent /verysilent /DIR=C:\\OpenSSL-1-1-Win32"
+
+ - ECHO "Install OpenSSL 1.1.0 64bit"
+ - curl -o "c:\\%X64_OPENSSL_INSTALLER%" -fsSL "https://slproweb.com/download/%X64_OPENSSL_INSTALLER%"
+ - "c:\\%X64_OPENSSL_INSTALLER% /silent /verysilent /DIR=C:\\OpenSSL-1-1-Win64"
+
+ - ECHO "Install pywin32"
+ - curl -o "%PYWIN32%" -fsSL "https://github.com/mhammond/pywin32/releases/download/%PYWIN32_RELEASE%/%PYWIN32%"
+ - "%PYTHON%\\Scripts\\easy_install.exe %PYWIN32%"
+ #- mkdir pywin32
+ #- 7z x "%PYWIN32%" -opywin32
+ #- xcopy /e "pywin32\\PLATLIB" "%PYTHON%\\Lib\\site-packages"
+
+ - ECHO "Filesystem root:"
+ - ps: "ls \"C:/\""
+
+ - ps: "ls \"C:/OpenSSL-Win32\""
+ - ECHO "Installed SDKs:"
+ - ps: if (Test-Path "C:/Program Files/Microsoft SDKs/Windows") { ls "C:/Program Files/Microsoft SDKs/Windows" }
+
+ - ECHO "Appveyor OpenSSL Version (%OPENSSL_VERSION%)"
+ - "%OPENSSL_PATH%/bin/openssl.exe version"
+
+ - ECHO "Python OpenSSL Version (%PYTHON%)"
+ - "%PYTHON%\\python.exe -c \"import ssl; print(getattr(ssl, 'OPENSSL_VERSION', None))\""
+
+build_script:
+ - "%PYTHON%\\python.exe setup.py build --openssl=\"%OPENSSL_PATH%\" --bundledlls"
+
+test_script:
+ - "%PYTHON%\\python.exe setup.py test"
+
+after_test:
+ # If tests are successful, create a whl package for the project.
+ - "%PYTHON%\\python.exe setup.py bdist_wheel bdist_wininst bdist_msi"
+ - ps: "ls dist"
+
+artifacts:
+ # Archive the generated wheel package in the ci.appveyor.com build report.
+ - path: dist\*
+
+ - path: SWIG/_m2crypto_wrap.c
+ name: _m2crypto_wrap.zip
+ type: zip
+
+after_build:
+ - ps: Get-ChildItem SWIG\_m2crypto_wrap.c | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name }
+
+on_failure:
+ - ps: Get-ChildItem SWIG\_m2crypto_wrap.c | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name }
diff --git a/contrib/SimpleX509create.py b/contrib/SimpleX509create.py
index 7f5fc67..84fe242 100644
--- a/contrib/SimpleX509create.py
+++ b/contrib/SimpleX509create.py
@@ -2,6 +2,7 @@
#
#vim: ts=4 sw=4 nowrap
#
+from __future__ import print_function
"""PKI demo by Peter Teniz <peter.teniz@inverisa.net>"""
@@ -13,150 +14,150 @@ MBSTRING_ASC = MBSTRING_FLAG | 1
MBSTRING_BMP = MBSTRING_FLAG | 2
-class Cert:
- def __init__ ( self ):
- self.RsaKey = { 'KeyLength' : 1024,
- 'PubExponent' : 0x10001, # -> 65537
- 'keygen_callback' : self.callback
- }
+class Cert(object):
+ def __init__ ( self ):
+ self.RsaKey = { 'KeyLength' : 1024,
+ 'PubExponent' : 0x10001, # -> 65537
+ 'keygen_callback' : self.callback
+ }
- self.KeyPair = None
- self.PKey = None
+ self.KeyPair = None
+ self.PKey = None
- self.X509Request = None
- self.X509Certificate = None
+ self.X509Request = None
+ self.X509Certificate = None
- def callback ( self, *args ):
- return 'p'
+ def callback ( self, *args ):
+ return 'p'
- def CreatePKey ( self ):
- self.KeyPair = M2Crypto.RSA.gen_key( self.RsaKey['KeyLength'], self.RsaKey['PubExponent'], self.RsaKey['keygen_callback'] )
- #PubKey = M2Crypto.RSA.new_pub_key( self.KeyPair.pub () )
+ def CreatePKey ( self ):
+ self.KeyPair = M2Crypto.RSA.gen_key( self.RsaKey['KeyLength'], self.RsaKey['PubExponent'], self.RsaKey['keygen_callback'] )
+ #PubKey = M2Crypto.RSA.new_pub_key( self.KeyPair.pub () )
- self.KeyPair.save_key( 'KeyPair.pem', cipher='des_ede3_cbc', callback=self.callback )
-
- self.PKey = M2Crypto.EVP.PKey ( md='sha1')
- self.PKey.assign_rsa ( self.KeyPair )
+ self.KeyPair.save_key( 'KeyPair.pem', cipher='des_ede3_cbc', callback=self.callback )
+ self.PKey = M2Crypto.EVP.PKey ( md='sha1')
+ self.PKey.assign_rsa ( self.KeyPair )
- def CreateX509Request ( self ):
- #
- # X509 REQUEST
- #
- self.X509Request = M2Crypto.X509.Request ()
+ def CreateX509Request ( self ):
+ #
+ # X509 REQUEST
+ #
- #
- # subject
- #
+ self.X509Request = M2Crypto.X509.Request ()
- X509Name = M2Crypto.X509.X509_Name ()
+ #
+ # subject
+ #
- X509Name.add_entry_by_txt ( field='C', type=MBSTRING_ASC, entry='austria', len=-1, loc=-1, set=0 ) # country name
- X509Name.add_entry_by_txt ( field='SP', type=MBSTRING_ASC, entry='kernten', len=-1, loc=-1, set=0 ) # state of province name
- X509Name.add_entry_by_txt ( field='L', type=MBSTRING_ASC, entry='stgallen', len=-1, loc=-1, set=0 ) # locality name
- X509Name.add_entry_by_txt ( field='O', type=MBSTRING_ASC, entry='labor', len=-1, loc=-1, set=0 ) # organization name
- X509Name.add_entry_by_txt ( field='OU', type=MBSTRING_ASC, entry='it-department', len=-1, loc=-1, set=0 ) # organizational unit name
- X509Name.add_entry_by_txt ( field='CN', type=MBSTRING_ASC, entry='Certificate client', len=-1, loc=-1, set=0 ) # common name
- X509Name.add_entry_by_txt ( field='Email', type=MBSTRING_ASC, entry='user@localhost', len=-1, loc=-1, set=0 ) # pkcs9 email address
- X509Name.add_entry_by_txt ( field='emailAddress', type=MBSTRING_ASC, entry='user@localhost', len=-1, loc=-1, set=0 ) # pkcs9 email address
+ X509Name = M2Crypto.X509.X509_Name ()
- self.X509Request.set_subject_name( X509Name )
+ X509Name.add_entry_by_txt ( field='C', type=MBSTRING_ASC, entry='austria', len=-1, loc=-1, set=0 ) # country name
+ X509Name.add_entry_by_txt ( field='SP', type=MBSTRING_ASC, entry='kernten', len=-1, loc=-1, set=0 ) # state of province name
+ X509Name.add_entry_by_txt ( field='L', type=MBSTRING_ASC, entry='stgallen', len=-1, loc=-1, set=0 ) # locality name
+ X509Name.add_entry_by_txt ( field='O', type=MBSTRING_ASC, entry='labor', len=-1, loc=-1, set=0 ) # organization name
+ X509Name.add_entry_by_txt ( field='OU', type=MBSTRING_ASC, entry='it-department', len=-1, loc=-1, set=0 ) # organizational unit name
+ X509Name.add_entry_by_txt ( field='CN', type=MBSTRING_ASC, entry='Certificate client', len=-1, loc=-1, set=0 ) # common name
+ X509Name.add_entry_by_txt ( field='Email', type=MBSTRING_ASC, entry='user@localhost', len=-1, loc=-1, set=0 ) # pkcs9 email address
+ X509Name.add_entry_by_txt ( field='emailAddress', type=MBSTRING_ASC, entry='user@localhost', len=-1, loc=-1, set=0 ) # pkcs9 email address
- #
- # publickey
- #
+ self.X509Request.set_subject_name( X509Name )
- self.X509Request.set_pubkey ( pkey=self.PKey )
- self.X509Request.sign ( pkey=self.PKey, md='sha1' )
- #print X509Request.as_text ()
+ #
+ # publickey
+ #
+ self.X509Request.set_pubkey ( pkey=self.PKey )
+ self.X509Request.sign ( pkey=self.PKey, md='sha1' )
+ #print(X509Request.as_text ())
- def CreateX509Certificate ( self ):
- #
- # X509 CERTIFICATE
- #
- self.X509Certificate = M2Crypto.X509.X509 ()
+ def CreateX509Certificate ( self ):
+ #
+ # X509 CERTIFICATE
+ #
- #
- # version
- #
+ self.X509Certificate = M2Crypto.X509.X509 ()
- self.X509Certificate.set_version ( 0 )
+ #
+ # version
+ #
- #
- # time notBefore
- #
+ self.X509Certificate.set_version ( 0 )
- ASN1 = M2Crypto.ASN1.ASN1_UTCTIME ()
- ASN1.set_time ( 500 )
- self.X509Certificate.set_not_before( ASN1 )
+ #
+ # time notBefore
+ #
- #
- # time notAfter
- #
+ ASN1 = M2Crypto.ASN1.ASN1_TIME ()
+ ASN1.set_time ( 500 )
+ self.X509Certificate.set_not_before( ASN1 )
- ASN1 = M2Crypto.ASN1.ASN1_UTCTIME ()
- ASN1.set_time ( 500 )
- self.X509Certificate.set_not_after( ASN1 )
+ #
+ # time notAfter
+ #
- #
- # public key
- #
+ ASN1 = M2Crypto.ASN1.ASN1_TIME ()
+ ASN1.set_time ( 500 )
+ self.X509Certificate.set_not_after( ASN1 )
- self.X509Certificate.set_pubkey ( pkey=self.PKey )
-
- #
- # subject
- #
+ #
+ # public key
+ #
- X509Name = self.X509Request.get_subject ()
+ self.X509Certificate.set_pubkey ( pkey=self.PKey )
- #print X509Name.entry_count ()
- #print X509Name.as_text ()
+ #
+ # subject
+ #
- self.X509Certificate.set_subject_name( X509Name )
+ X509Name = self.X509Request.get_subject ()
- #
- # issuer
- #
+ #print(X509Name.entry_count ())
+ #print(X509Name.as_text ())
- X509Name = M2Crypto.X509.X509_Name ( M2Crypto.m2.x509_name_new () )
+ self.X509Certificate.set_subject_name( X509Name )
- X509Name.add_entry_by_txt ( field='C', type=MBSTRING_ASC, entry='germany', len=-1, loc=-1, set=0 ) # country name
- X509Name.add_entry_by_txt ( field='SP', type=MBSTRING_ASC, entry='bavaria', len=-1, loc=-1, set=0 ) # state of province name
- X509Name.add_entry_by_txt ( field='L', type=MBSTRING_ASC, entry='munich', len=-1, loc=-1, set=0 ) # locality name
- X509Name.add_entry_by_txt ( field='O', type=MBSTRING_ASC, entry='sbs', len=-1, loc=-1, set=0 ) # organization name
- X509Name.add_entry_by_txt ( field='OU', type=MBSTRING_ASC, entry='it-department', len=-1, loc=-1, set=0 ) # organizational unit name
- X509Name.add_entry_by_txt ( field='CN', type=MBSTRING_ASC, entry='Certificate Authority', len=-1, loc=-1, set=0 ) # common name
- X509Name.add_entry_by_txt ( field='Email', type=MBSTRING_ASC, entry='admin@localhost', len=-1, loc=-1, set=0 ) # pkcs9 email address
- X509Name.add_entry_by_txt ( field='emailAddress', type=MBSTRING_ASC, entry='admin@localhost', len=-1, loc=-1, set=0 ) # pkcs9 email address
+ #
+ # issuer
+ #
- #print X509Name.entry_count ()
- #print X509Name.as_text ()
+ X509Name = M2Crypto.X509.X509_Name ( M2Crypto.m2.x509_name_new () )
- self.X509Certificate.set_issuer_name( X509Name )
+ X509Name.add_entry_by_txt ( field='C', type=MBSTRING_ASC, entry='germany', len=-1, loc=-1, set=0 ) # country name
+ X509Name.add_entry_by_txt ( field='SP', type=MBSTRING_ASC, entry='bavaria', len=-1, loc=-1, set=0 ) # state of province name
+ X509Name.add_entry_by_txt ( field='L', type=MBSTRING_ASC, entry='munich', len=-1, loc=-1, set=0 ) # locality name
+ X509Name.add_entry_by_txt ( field='O', type=MBSTRING_ASC, entry='sbs', len=-1, loc=-1, set=0 ) # organization name
+ X509Name.add_entry_by_txt ( field='OU', type=MBSTRING_ASC, entry='it-department', len=-1, loc=-1, set=0 ) # organizational unit name
+ X509Name.add_entry_by_txt ( field='CN', type=MBSTRING_ASC, entry='Certificate Authority', len=-1, loc=-1, set=0 ) # common name
+ X509Name.add_entry_by_txt ( field='Email', type=MBSTRING_ASC, entry='admin@localhost', len=-1, loc=-1, set=0 ) # pkcs9 email address
+ X509Name.add_entry_by_txt ( field='emailAddress', type=MBSTRING_ASC, entry='admin@localhost', len=-1, loc=-1, set=0 ) # pkcs9 email address
- #
- # signing
- #
+ #print(X509Name.entry_count ())
+ #print(X509Name.as_text ())
- self.X509Certificate.sign( pkey=self.PKey, md='sha1' )
- print self.X509Certificate.as_text ()
+ self.X509Certificate.set_issuer_name( X509Name )
+
+ #
+ # signing
+ #
+
+ self.X509Certificate.sign( pkey=self.PKey, md='sha1' )
+ print(self.X509Certificate.as_text ())
if __name__ == '__main__':
- run = Cert ()
- run.CreatePKey ()
- run.CreateX509Request ()
- run.CreateX509Certificate ()
+ run = Cert ()
+ run.CreatePKey ()
+ run.CreateX509Request ()
+ run.CreateX509Certificate ()
diff --git a/contrib/dave.patch b/contrib/dave.patch
deleted file mode 100644
index 6e41073..0000000
--- a/contrib/dave.patch
+++ /dev/null
@@ -1,180 +0,0 @@
---- _ssl.i.orig Tue Sep 18 06:06:34 2001
-+++ _ssl.i Thu Dec 12 08:57:39 2002
-@@ -238,9 +238,18 @@
- return ret;
- }
-
-+void SetWantRWError(int which) {
-+ PyObject *o = Py_BuildValue("(is)", which,
-+
-ERR_reason_error_string(ERR_get_error()));
-+ if (o != NULL) {
-+ PyErr_SetObject(_ssl_err, o);
-+ Py_DECREF(o);
-+ }
-+}
-+
- PyObject *ssl_accept(SSL *ssl) {
- PyObject *obj;
-- int r, err;
-+ int r, err, which;
- PyThreadState *_save;
-
- if (thread_mode) {
-@@ -252,14 +261,15 @@
- _save = (PyThreadState *)SSL_get_app_data(ssl);
- PyEval_RestoreThread(_save);
- }
-- switch (SSL_get_error(ssl, r)) {
-+ switch ((which = SSL_get_error(ssl, r))) {
- case SSL_ERROR_NONE:
- case SSL_ERROR_ZERO_RETURN:
- obj = PyInt_FromLong((long)1);
- break;
- case SSL_ERROR_WANT_WRITE:
- case SSL_ERROR_WANT_READ:
-- obj = PyInt_FromLong((long)0);
-+ SetWantRWError(which);
-+ obj = NULL;
- break;
- case SSL_ERROR_SSL:
- PyErr_SetString(_ssl_err,
-ERR_reason_error_string(ERR_get_error()));
-@@ -281,7 +291,7 @@
-
- PyObject *ssl_connect(SSL *ssl) {
- PyObject *obj;
-- int r, err;
-+ int r, err, which;
- PyThreadState *_save;
-
- if (thread_mode) {
-@@ -293,14 +303,15 @@
- _save = (PyThreadState *)SSL_get_app_data(ssl);
- PyEval_RestoreThread(_save);
- }
-- switch (SSL_get_error(ssl, r)) {
-+ switch ((which = SSL_get_error(ssl, r))) {
- case SSL_ERROR_NONE:
- case SSL_ERROR_ZERO_RETURN:
- obj = PyInt_FromLong((long)1);
- break;
- case SSL_ERROR_WANT_WRITE:
- case SSL_ERROR_WANT_READ:
-- obj = PyInt_FromLong((long)0);
-+ SetWantRWError(which);
-+ obj = NULL;
- break;
- case SSL_ERROR_SSL:
- PyErr_SetString(_ssl_err,
-ERR_reason_error_string(ERR_get_error()));
-@@ -327,7 +338,7 @@
- PyObject *ssl_read(SSL *ssl, int num) {
- PyObject *obj;
- void *buf;
-- int r, err;
-+ int r, err, which;
- PyThreadState *_save;
-
- if (!(buf = PyMem_Malloc(num))) {
-@@ -343,7 +354,7 @@
- _save = (PyThreadState *)SSL_get_app_data(ssl);
- PyEval_RestoreThread(_save);
- }
-- switch (SSL_get_error(ssl, r)) {
-+ switch ((which = SSL_get_error(ssl, r))) {
- case SSL_ERROR_NONE:
- case SSL_ERROR_ZERO_RETURN:
- buf = PyMem_Realloc(buf, r);
-@@ -352,8 +363,8 @@
- case SSL_ERROR_WANT_WRITE:
- case SSL_ERROR_WANT_READ:
- case SSL_ERROR_WANT_X509_LOOKUP:
-- Py_INCREF(Py_None);
-- obj = Py_None;
-+ SetWantRWError(which);
-+ obj = NULL;
- break;
- case SSL_ERROR_SSL:
- PyErr_SetString(_ssl_err,
-ERR_reason_error_string(ERR_get_error()));
-@@ -377,14 +388,14 @@
- PyObject *ssl_read_nbio(SSL *ssl, int num) {
- PyObject *obj;
- void *buf;
-- int r, err;
-+ int r, err, which;
-
- if (!(buf = PyMem_Malloc(num))) {
- PyErr_SetString(PyExc_MemoryError, "ssl_read");
- return NULL;
- }
- r = SSL_read(ssl, buf, num);
-- switch (SSL_get_error(ssl, r)) {
-+ switch ((which = SSL_get_error(ssl, r))) {
- case SSL_ERROR_NONE:
- case SSL_ERROR_ZERO_RETURN:
- buf = PyMem_Realloc(buf, r);
-@@ -392,6 +403,9 @@
- break;
- case SSL_ERROR_WANT_WRITE:
- case SSL_ERROR_WANT_READ:
-+ SetWantRWError(which);
-+ obj = NULL;
-+ break;
- case SSL_ERROR_WANT_X509_LOOKUP:
- Py_INCREF(Py_None);
- obj = Py_None;
-@@ -417,7 +431,7 @@
-
- int ssl_write(SSL *ssl, PyObject *blob) {
- const void *buf;
-- int len, r, err;
-+ int len, r, err, which;
- PyThreadState *_save;
-
- #if PYTHON_API_VERSION >= 1009
-@@ -440,12 +454,14 @@
- _save = (PyThreadState *)SSL_get_app_data(ssl);
- PyEval_RestoreThread(_save);
- }
-- switch (SSL_get_error(ssl, r)) {
-+ switch ((which = SSL_get_error(ssl, r))) {
- case SSL_ERROR_NONE:
- case SSL_ERROR_ZERO_RETURN:
- return r;
- case SSL_ERROR_WANT_WRITE:
- case SSL_ERROR_WANT_READ:
-+ SetWantRWError(which);
-+ return -1;
- case SSL_ERROR_WANT_X509_LOOKUP:
- return -1;
- case SSL_ERROR_SSL:
-@@ -466,7 +482,7 @@
-
- int ssl_write_nbio(SSL *ssl, PyObject *blob) {
- const void *buf;
-- int len, r, err;
-+ int len, r, err, which;
-
- #if PYTHON_API_VERSION >= 1009
- if (PyObject_AsReadBuffer(blob, &buf, &len) == -1)
-@@ -480,12 +496,14 @@
- buf = (const void *)PyString_AsString(blob);
- #endif
- r = SSL_write(ssl, buf, len);
-- switch (SSL_get_error(ssl, r)) {
-+ switch ((which = SSL_get_error(ssl, r))) {
- case SSL_ERROR_NONE:
- case SSL_ERROR_ZERO_RETURN:
- return r;
- case SSL_ERROR_WANT_WRITE:
- case SSL_ERROR_WANT_READ:
-+ SetWantRWError(which);
-+ return -1;
- case SSL_ERROR_WANT_X509_LOOKUP:
- return -1;
- case SSL_ERROR_SSL:
-
-
-
diff --git a/contrib/dispatcher.py b/contrib/dispatcher.py
index 6e7302d..6f3b0e0 100644
--- a/contrib/dispatcher.py
+++ b/contrib/dispatcher.py
@@ -1,191 +1,177 @@
-#!/usr/local/bin/python -O
-"""
- Implements a [hopefully] non-blocking SSL dispatcher on top of
- M2Crypto package.
-
- Written by Ilya Etingof <ilya@glas.net>, 05/2001
-"""
-import asyncore, socket
-
-# M2Crypto
-from M2Crypto import SSL
-
-class _nb_connection (SSL.Connection):
- """Functional equivalent of SSL.Connection class. Facilitates
- possibly delayed socket.connect() and socket.accept()
- termination.
- """
- def __init__ (self, ctx, sock):
- SSL.Connection.__init__ (self, ctx, sock)
-
- def connect(self, addr):
- self._setup_ssl(addr)
- return self._check_ssl_return(SSL.m2.ssl_connect(self.ssl))
-
- def accept(self, addr):
- self._setup_ssl(addr)
- self.accept_ssl()
-
-class dispatcher(asyncore.dispatcher_with_send):
- """A non-blocking SSL dispatcher that mimics the
- asyncode.dispatcher API.
- """
- def __init__ (self, cert, key, sock=None, serving=None):
- asyncore.dispatcher_with_send.__init__ (self)
-
- self.__serving = serving
-
- # XXX
- if sock:
- if self.__serving:
- self.set_socket(sock)
- else:
- self.create_socket (socket.AF_INET, socket.SOCK_STREAM)
-
- self.ctx = SSL.Context('sslv23')
- self.ctx.set_verify(SSL.verify_none, 10)
- self.ctx.load_cert(cert, key)
- self.ctx.set_info_callback()
-
- self.ssl = _nb_connection(self.ctx, self.socket)
-
- self.__output = ''
- self.__want_write = 1
-
- #
- # The following are asyncore overloaded methods
- #
-
- def handle_connect (self):
- """Initiate SSL connection negotiation
- """
- if self.__serving:
- self.ssl.accept (self.addr)
-
- self.peer = self.ssl.get_peer_cert()
-
- self.handle_ssl_accept()
-
- else:
- self.ssl.connect (self.addr)
-
- self.handle_ssl_connect()
-
- def handle_read(self):
- """Read user and/or SSL protocol data from SSL connection
- """
- ret = self.ssl._read_nbio()
-
- if ret:
- self.handle_ssl_read(ret)
- else:
- # Assume write is wanted
- self.__want_write = 1
-
- def handle_write(self):
- """Write pending user and/or SSL protocol data down to SSL
- connection
- """
- self.__want_write = 0
-
- ret = self.ssl._write_nbio(self.__output)
-
- if ret < 0:
- try:
- err = SSL.m2.ssl_get_error(self.ssl.ssl, ret)
-
- except SSL.SSLError:
- return
-
- if err == SSL.m2.ssl_error_want_write:
- self.__want_write = 1
- else:
- self.__output = self.__output[ret:]
-
- def writable (self):
- """Indicate that write is desired if here're some
- user and/or SSL protocol data.
- """
- if self.__output or self.__want_write:
- return 1
-
- return self.ssl_writable()
-
- def handle_close (self):
- """Shutdown SSL connection.
- """
- self.ssl = None
-
- self.ctx = None
- self.close ()
-
- self.handle_ssl_close()
-
- def handle_error (self, *info):
- """A trap for asyncore errors
- """
- self.handle_ssl_error(info)
-
- #
- # The following are ssl.dispatcher API
- #
-
- def ssl_connect(self, server):
- """Initiate SSL connection
- """
- self.connect(server)
-
- def ssl_write(self, data):
- """Write data to SSL connection
- """
- self.__output = self.__output + data
-
- def ssl_close(self):
- """Close SSL connection
- """
- self.handle_close()
-
- def handle_ssl_connect(self):
- """Invoked on SSL connection establishment (whilst
- in client mode)
- """
- print 'Unhandled handle_ssl_connect()'
-
- def handle_ssl_accept(self):
- """Invoked on SSL connection establishment (whilst
- in server mode)
- """
- print 'Unhandled handle_ssl_accept()'
-
- def handle_ssl_read(self, data):
- """Invoked on new data arrival to SSL connection
- """
- print 'Unhandled handle_ssl_read event'
-
- def handle_ssl_close(self):
- """Invoked on SSL connection termination
- """
- pass
-
- def ssl_writable(self):
- """Invoked prior to every select() call
- """
- return 0
-
-if __name__=='__main__':
- """Give it a test run
- """
- class client(dispatcher):
- """SSL client class
- """
- def __init__ (self, cert, key):
- dispatcher.__init__(self, cert, key)
-
- def handle_ssl_read(self, data):
- print data
- self.ssl_write('test write')
-
- ssl = client('test.cert', 'test.key')
- ssl.ssl_connect(('localhost', 7777))
-
- asyncore.loop()
+#!/usr/local/bin/python -O
+from __future__ import print_function
+"""Implements a [hopefully] non-blocking SSL Dispatcher on top of M2Crypto.
+
+ Written by Ilya Etingof <ilya@glas.net>, 05/2001
+"""
+import asyncore # type: ignore # https://github.com/python/typeshed/issues/356
+import socket
+
+# M2Crypto
+from M2Crypto import SSL # type: ignore # we are not in proper directory
+
+
+class NBConnection(SSL.Connection):
+ """Functional equivalent of SSL.Connection class.
+
+ Facilitates possibly delayed socket.connect() and socket.accept()
+ termination.
+ """
+ def __init__(self, ctx, sock):
+ SSL.Connection.__init__(self, ctx, sock)
+
+ def connect(self, addr):
+ self._setup_ssl(addr)
+ # FIXME SSL.Connection doesn't have _check_ssl_return method
+ return self._check_ssl_return(SSL.m2.ssl_connect(self.ssl))
+
+ def accept(self, addr):
+ self._setup_ssl(addr)
+ self.accept_ssl()
+
+
+class Dispatcher(asyncore.dispatcher_with_send):
+ """A non-blocking SSL Dispatcher that mimics the asyncode.dispatcher API"""
+ def __init__(self, cert, key, sock=None, serving=None):
+ asyncore.dispatcher_with_send.__init__(self)
+
+ self.__serving = serving
+
+ # XXX
+ if sock:
+ if self.__serving:
+ self.set_socket(sock)
+ else:
+ self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
+
+ self.ctx = SSL.Context()
+ self.ctx.set_verify(SSL.verify_none, 10)
+ self.ctx.load_cert(cert, key)
+ self.ctx.set_info_callback()
+
+ self.ssl = NBConnection(self.ctx, self.socket)
+ self.peer = None
+
+ self.__output = ''
+ self.__want_write = 1
+
+ #
+ # The following are asyncore overloaded methods
+ #
+
+ def handle_connect(self):
+ """Initiate SSL connection negotiation"""
+ if self.__serving:
+ self.ssl.accept(self.addr)
+
+ self.peer = self.ssl.get_peer_cert()
+
+ self.handle_ssl_accept()
+
+ else:
+ self.ssl.connect(self.addr)
+
+ self.handle_ssl_connect()
+
+ def handle_read(self):
+ """Read user and/or SSL protocol data from SSL connection"""
+ ret = self.ssl._read_nbio()
+
+ if ret:
+ self.handle_ssl_read(ret)
+ else:
+ # Assume write is wanted
+ self.__want_write = 1
+
+ def handle_write(self):
+ """Write pending user or SSL protocol data down to SSL connection"""
+ self.__want_write = 0
+
+ ret = self.ssl._write_nbio(self.__output)
+
+ if ret < 0:
+ try:
+ err = SSL.m2.ssl_get_error(self.ssl.ssl, ret)
+
+ except SSL.SSLError:
+ return
+
+ if err == SSL.m2.ssl_error_want_write:
+ self.__want_write = 1
+ else:
+ self.__output = self.__output[ret:]
+
+ def writable(self):
+ """Indicate that write is desired.
+
+ Happens if there's some user and/or SSL protocol data.
+ """
+ if self.__output or self.__want_write:
+ return 1
+
+ return self.ssl_writable()
+
+ def handle_close(self):
+ """Shutdown SSL connection."""
+ self.ssl = None
+
+ self.ctx = None
+ self.close()
+
+ self.handle_ssl_close()
+
+ def handle_error(self, *info):
+ """A trap for asyncore errors"""
+ self.handle_ssl_error(info)
+
+ #
+ # The following are ssl.dispatcher API
+ #
+
+ def ssl_connect(self, server):
+ """Initiate SSL connection"""
+ self.connect(server)
+
+ def ssl_write(self, data):
+ """Write data to SSL connection"""
+ self.__output = self.__output + data
+
+ def ssl_close(self):
+ """Close SSL connection"""
+ self.handle_close()
+
+ def handle_ssl_connect(self):
+ """Invoked on SSL connection establishment (whilst in Client mode)"""
+ print('Unhandled handle_ssl_connect()')
+
+ def handle_ssl_accept(self):
+ """Invoked on SSL connection establishment (whilst in server mode)"""
+ print('Unhandled handle_ssl_accept()')
+
+ def handle_ssl_read(self, data):
+ """Invoked on new data arrival to SSL connection"""
+ print('Unhandled handle_ssl_read event')
+
+ def handle_ssl_close(self):
+ """Invoked on SSL connection termination"""
+ pass
+
+ def ssl_writable(self):
+ """Invoked prior to every select() call"""
+ return 0
+
+if __name__ == '__main__':
+ """Give it a test run"""
+ class Client(Dispatcher):
+ """SSL Client class"""
+ def __init__(self, cert, key):
+ Dispatcher.__init__(self, cert, key)
+
+ def handle_ssl_read(self, data):
+ print(data)
+ self.ssl_write('test write')
+
+ ssl = Client('test.cert', 'test.key')
+ ssl.ssl_connect(('localhost', 7777))
+
+ asyncore.loop()
diff --git a/contrib/isaac.httpslib.py b/contrib/isaac.httpslib.py
index ae9d23d..c5474b8 100644
--- a/contrib/isaac.httpslib.py
+++ b/contrib/isaac.httpslib.py
@@ -1,116 +1,85 @@
-"""M2Crypto support for Python 1.5.2 and Python 2.x's httplib.
+from __future__ import print_function
+
+"""M2Crypto support for Python 2.x's httplib.
Copyright (c) 1999-2002 Ng Pheng Siong. All rights reserved."""
-import string, sys
-from httplib import *
-import SSL
+import string
-if sys.version[0] == '2':
-
- if sys.version[:3] in ['2.1', '2.2']:
- # In 2.1 and above, httplib exports "HTTP" only.
- from httplib import HTTPConnection, HTTPS_PORT
- # ISS Added:
- from httplib import HTTPResponse,FakeSocket
+from M2Crypto import SSL
- class HTTPSConnection(HTTPConnection):
-
- """
- This class allows communication via SSL using M2Crypto.
- """
-
- default_port = HTTPS_PORT
-
- def __init__(self, host, port=None, **ssl):
- keys = ssl.keys()
- try:
- keys.remove('key_file')
- except ValueError:
- pass
- try:
- keys.remove('cert_file')
- except ValueError:
- pass
- try:
- keys.remove('ssl_context')
- except ValueError:
- pass
- if keys:
- raise IllegalKeywordArgument()
- try:
- self.ssl_ctx = ssl['ssl_context']
- assert isinstance(self.ssl_ctx, SSL.Context)
- except KeyError:
- self.ssl_ctx = SSL.Context('sslv23')
- HTTPConnection.__init__(self, host, port)
-
- def connect(self):
- self.sock = SSL.Connection(self.ssl_ctx)
- self.sock.connect((self.host, self.port))
-
- def close(self):
- # This kludges around line 545 of httplib.py,
- # which closes the connection in this object;
- # the connection remains open in the response
- # object.
- #
- # M2Crypto doesn't close-here-keep-open-there,
- # so, in effect, we don't close until the whole
- # business is over and gc kicks in.
- #
- # Long-running callers beware leakage.
- #
- # 05-Jan-2002: This module works with Python 2.2,
- # but I've not investigated if the above conditions
- # remain.
- pass
+from httplib import FakeSocket, HTTP, HTTPConnection, HTTPResponse, HTTPS_PORT
- class HTTPS(HTTP):
-
- _connection_class = HTTPSConnection
-
- def __init__(self, host='', port=None, **ssl):
- HTTP.__init__(self, host, port)
- try:
- self.ssl_ctx = ssl['ssl_context']
- except KeyError:
- self.ssl_ctx = SSL.Context('sslv23')
-
-
-elif sys.version[:3] == '1.5':
-
- class HTTPS(HTTP):
-
- def __init__(self, ssl_context, host='', port=None):
- assert isinstance(ssl_context, SSL.Context)
- self.debuglevel=0
- self.file=None
- self.ssl_ctx=ssl_context
- if host:
- self.connect(host, port)
-
- def connect(self, host, port=None):
- # Cribbed from httplib.HTTP.
- if not port:
- i = string.find(host, ':')
- if i >= 0:
- host, port = host[:i], host[i+1:]
- try: port = string.atoi(port)
- except string.atoi_error:
- raise socket.error, "nonnumeric port"
- if not port: port = HTTPS_PORT
- self.sock = SSL.Connection(self.ssl_ctx)
- if self.debuglevel > 0: print 'connect:', (host, port)
- self.sock.connect((host, port))
+class HTTPSConnection(HTTPConnection):
+
+ """
+ This class allows communication via SSL using M2Crypto.
+ """
+
+ default_port = HTTPS_PORT
+
+ def __init__(self, host, port=None, **ssl):
+ keys = ssl.keys()
+ try:
+ keys.remove('key_file')
+ except ValueError:
+ pass
+ try:
+ keys.remove('cert_file')
+ except ValueError:
+ pass
+ try:
+ keys.remove('ssl_context')
+ except ValueError:
+ pass
+ if keys:
+ raise ValueError()
+ try:
+ self.ssl_ctx = ssl['ssl_context']
+ assert isinstance(self.ssl_ctx, SSL.Context)
+ except KeyError:
+ self.ssl_ctx = SSL.Context('sslv23')
+ HTTPConnection.__init__(self, host, port)
+
+ def connect(self):
+ self.sock = SSL.Connection(self.ssl_ctx)
+ self.sock.connect((self.host, self.port))
+
+ def close(self):
+ # This kludges around line 545 of httplib.py,
+ # which closes the connection in this object;
+ # the connection remains open in the response
+ # object.
+ #
+ # M2Crypto doesn't close-here-keep-open-there,
+ # so, in effect, we don't close until the whole
+ # business is over and gc kicks in.
+ #
+ # Long-running callers beware leakage.
+ #
+ # 05-Jan-2002: This module works with Python 2.2,
+ # but I've not investigated if the above conditions
+ # remain.
+ pass
+
+class HTTPS(HTTP):
+
+ _connection_class = HTTPSConnection
+
+ def __init__(self, host='', port=None, **ssl):
+ HTTP.__init__(self, host, port)
+ try:
+ self.ssl_ctx = ssl['ssl_context']
+ except KeyError:
+ self.ssl_ctx = SSL.Context('sslv23')
# ISS Added.
# From here, starts the proxy patch
class HTTPProxyConnection(HTTPConnection):
"""
This class provides HTTP access through (authenticated) proxies.
-
+
Example:
If the HTTP proxy address is proxy.your.org:8080, an authenticated proxy
(one which requires a username/password combination in order to serve
@@ -161,7 +130,7 @@ class HTTPProxyConnection(HTTPConnection):
HTTPConnection.putrequest(self, method, newurl)
# Add proxy-specific headers
self._add_auth_proxy_header()
-
+
def _add_auth_proxy_header(self):
"""Adds an HTTP header for authenticated proxies
"""
@@ -177,7 +146,7 @@ class HTTPProxyConnection(HTTPConnection):
class HTTPSProxyResponse(HTTPResponse):
"""
Replacement class for HTTPResponse
- Proxy responses (made through SSL) have to keep the connection open
+ Proxy responses (made through SSL) have to keep the connection open
after the initial request, since the connection is tunneled to the SSL
host with the CONNECT method.
"""
@@ -187,7 +156,7 @@ class HTTPSProxyResponse(HTTPResponse):
class HTTPSProxyConnection(HTTPProxyConnection):
"""This class provides HTTP access through (authenticated) proxies.
-
+
Example:
If the HTTP proxy address is proxy.your.org:8080, an authenticated proxy
(one which requires a username/password combination in order to serve
@@ -207,8 +176,8 @@ class HTTPSProxyConnection(HTTPProxyConnection):
def __init__(self, proxy, host, port=None, username=None, password=None, **x509):
for key in x509.keys():
- if key not in ['cert_file', 'key_file','ssl_context']:
- raise IllegalKeywordArgument()
+ if key not in ['cert_file', 'key_file', 'ssl_context']:
+ raise ValueError()
self.key_file = x509.get('key_file')
self.cert_file = x509.get('cert_file')
#ISS Added
@@ -217,12 +186,12 @@ class HTTPSProxyConnection(HTTPProxyConnection):
HTTPProxyConnection.__init__(self, proxy, host, port, username, password)
def connect(self):
- """Connect (using SSL) to the host and port specified in __init__
+ """Connect (using SSL) to the host and port specified in __init__
(through a proxy)."""
import socket
# Set the connection with the proxy
HTTPProxyConnection.connect(self)
- # Use the stock HTTPConnection putrequest
+ # Use the stock HTTPConnection putrequest
host = "%s:%s" % (self._host, self._port)
HTTPConnection.putrequest(self, "CONNECT", host)
# Add proxy-specific stuff
@@ -257,7 +226,7 @@ class HTTPSProxyConnection(HTTPProxyConnection):
# Fake the socket
ssl = socket.ssl(self.sock, self.key_file, self.cert_file)
self.sock = FakeSocket(self.sock, ssl)
- if self.debuglevel > 0: print 'socket type:', self.sock
+ if self.debuglevel > 0: print('socket type:', self.sock)
def putrequest(self, method, url):
"""Send a request to the server.
diff --git a/contrib/m2crypto.spec b/contrib/m2crypto.spec
deleted file mode 100644
index f80cddb..0000000
--- a/contrib/m2crypto.spec
+++ /dev/null
@@ -1,46 +0,0 @@
-%define name m2crypto
-%define version 0.06
-%define snap snap5
-%define release %{snap}.1
-%define prefix %{_prefix}
-
-Summary: Python crypto library
-Name: %{name}
-Version: %{version}
-Release: %{release}
-Copyright: tummy.com, ltd.
-Group: Applications/Crypto
-Source: %{name}-%{version}-%{snap}.zip
-Packager: Sean Reifschneider <jafo-rpms@tummy.com>
-BuildRoot: /var/tmp/%{name}-root
-Requires: openssl >= 0.9.6a
-Patch0: m2crypto-makefile.patch
-BuildPrereq: openssl-devel >= 0.9.6a
-BuildPrereq: swig >= 1.1p5
-
-%description
-M2Crypto makes available to the Python programmer the following:
-
- RSA, DH, DSA, HMACs, message digests, symmetric ciphers.
- SSL functionality to implement clients and servers.
- HTTPS extensions to Python's httplib, urllib, and the eff-bot's xmlrpclib.
- S/MIME v2.
-
-%prep
-%setup -n %{name}-%{version}-%{snap}
-%patch0 -p1
-%build
-( cd swig; make -f Makefile.py1 )
-
-%install
-[ -n "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf "$RPM_BUILD_ROOT"
-mkdir -p "$RPM_BUILD_ROOT"/usr/lib/python1.5/site-packages
-cp -a M2Crypto "$RPM_BUILD_ROOT"/usr/lib/python1.5/site-packages
-
-%clean
-[ -n "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf "$RPM_BUILD_ROOT"
-
-%files
-%defattr(755,root,root)
-%doc BUGS CHANGES INSTALL LICENCE README STORIES doc demo tests patches
-/usr/lib/python1.5/site-packages
diff --git a/contrib/smimeplus.py b/contrib/smimeplus.py
index 5a9c22d..9475ab0 100644
--- a/contrib/smimeplus.py
+++ b/contrib/smimeplus.py
@@ -1,13 +1,10 @@
-import sys, os, tempfile
import UserDict
-from email import Message
+import os
+import tempfile
+
import M2Crypto
-if not (sys.version_info[0] >= 2 and sys.version_info[1] >= 2):
- class object:
- pass
- True=1
- False=0
+from email import Message
class smimeplus(object):
@@ -17,7 +14,7 @@ class smimeplus(object):
self.setcacert(cacert)
self.randfile = randfile
self.__loadrand()
-
+
def __passcallback(self, v):
"""private key passphrase callback function"""
return self.passphrase
@@ -43,7 +40,7 @@ class smimeplus(object):
return _data
def __pack(self, msg):
- """Convert 'msg' to string and put it into an memory buffer for
+ """Convert 'msg' to string and put it into an memory buffer for
openssl operation"""
return M2Crypto.BIO.MemoryBuffer(self.__gettext(msg))
@@ -64,7 +61,7 @@ class smimeplus(object):
_sender.load_key_bio(self.__pack(self.key), self.__pack(self.cert),
callback=self.__passcallback)
- _signed = _sender.sign(self.__pack(msg))
+ _signed = _sender.sign(self.__pack(msg), M2Crypto.SMIME.PKCS7_DETACHED)
_out = self.__pack(None)
_sender.write(_out, _signed, self.__pack(msg))
@@ -72,7 +69,7 @@ class smimeplus(object):
def verify(self, smsg, scert):
"""Verify to see if 'smsg' was signed by 'scert', and scert was
- issued by cacert of this object. Return message signed if success,
+ issued by cacert of this object. Return message signed if success,
None otherwise"""
# Load signer's cert.
_x509 = M2Crypto.X509.load_cert_bio(self.__pack(scert))
@@ -89,34 +86,34 @@ class smimeplus(object):
_sender = M2Crypto.SMIME.SMIME()
_sender.set_x509_stack(_stack)
_sender.set_x509_store(_store)
-
+
# Load signed message, verify it, and return result
_p7, _data = M2Crypto.SMIME.smime_load_pkcs7_bio(self.__pack(smsg))
try:
- return _sender.verify(_p7, flags=M2Crypto.SMIME.PKCS7_SIGNED)
- except M2Crypto.SMIME.SMIME_Error, _msg:
+ return _sender.verify(_p7, _data, flags=M2Crypto.SMIME.PKCS7_SIGNED)
+ except M2Crypto.SMIME.SMIME_Error:
return None
def encrypt(self, rcert, msg):
# Instantiate an SMIME object.
_sender = M2Crypto.SMIME.SMIME()
-
+
# Load target cert to encrypt to.
_x509 = M2Crypto.X509.load_cert_bio(self.__pack(rcert))
_stack = M2Crypto.X509.X509_Stack()
_stack.push(_x509)
_sender.set_x509_stack(_stack)
-
+
_sender.set_cipher(M2Crypto.SMIME.Cipher(self.cipher))
-
+
# Encrypt the buffer.
_buf = self.__pack(self.__gettext(msg))
_p7 = _sender.encrypt(_buf)
-
+
# Output p7 in mail-friendly format.
_out = self.__pack('')
_sender.write(_out, _p7)
-
+
# Save the PRNG's state.
self.__saverand()
@@ -129,14 +126,14 @@ class smimeplus(object):
_sender = M2Crypto.SMIME.SMIME()
_sender.load_key_bio(self.__pack(self.key), self.__pack(self.cert),
callback=self.__passcallback)
-
+
# Load the encrypted data.
_p7, _data = M2Crypto.SMIME.smime_load_pkcs7_bio(self.__pack(emsg))
-
+
# Decrypt p7.
try:
return _sender.decrypt(_p7)
- except M2Crypto.SMIME.SMIME_Error, _msg:
+ except M2Crypto.SMIME.SMIME_Error:
return None
def addHeader(self, rcert, content, subject=''):
@@ -160,14 +157,14 @@ class X509_Subject(UserDict.UserDict):
UserDict.UserDict.__init__(self)
try:
_data = substr.strip().split('/')
- except AttributeError, _msg:
+ except AttributeError:
pass
else:
for _i in _data:
try:
_k, _v = _i.split('=')
self[_k] = _v
- except ValueError, _msg:
+ except ValueError:
pass
diff --git a/demo/CipherSaber/CipherSaber.py b/demo/CipherSaber/CipherSaber.py
deleted file mode 100644
index 81bd4c6..0000000
--- a/demo/CipherSaber/CipherSaber.py
+++ /dev/null
@@ -1,62 +0,0 @@
-#!/usr/bin/env python
-
-"""CipherSaber, http://ciphersaber.gurus.com.
-
-Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
-
-# XXX getopt handling has bugs.
-
-from M2Crypto import RC4, Rand
-import getopt, getpass, sys
-
-class argerr(Exception): pass
-
-cmd = -1
-inf = sys.stdin
-outf = sys.stdout
-
-optlist, optarg = getopt.getopt(sys.argv[1:], 'dei:o:')
-for opt in optlist:
- if '-d' in opt:
- cmd = cmd + 1
- elif '-e' in opt:
- cmd = cmd + 2
- elif '-i' in opt:
- i = opt[1]
- if i == '-':
- inf = sys.stdin
- else:
- inf = open(i, 'rb')
- elif '-o' in opt:
- o = opt[1]
- if o == '-':
- outf = sys.stdout
- else:
- outf = open(o, 'wb')
-if cmd < 0:
- raise argerr, "either -d or -e"
-if cmd > 1:
- raise argerr, "either -d or -e, not both"
-
-if cmd == 0:
- iv = inf.read(10)
- pp = getpass.getpass('Enter decryption passphrase: ')
-else:
- iv = Rand.rand_bytes(10)
- outf.write(iv)
- pp = getpass.getpass('Enter encryption passphrase: ')
- pp2 = getpass.getpass('Enter passphrase again: ')
- if pp != pp2:
- raise SystemExit, 'passphrase mismatch, I\'m outta here...'
-
-ci = RC4.RC4(pp + iv)
-del pp, iv
-
-while 1:
- buf = inf.read()
- if not buf:
- break
- outf.write(ci.update(buf))
-outf.write(ci.final())
-
-
diff --git a/demo/CipherSaber/cstest1.cs1 b/demo/CipherSaber/cstest1.cs1
deleted file mode 100644
index a9794b6..0000000
--- a/demo/CipherSaber/cstest1.cs1
+++ /dev/null
@@ -1 +0,0 @@
-om «óªg0í¶wÊtàÐ縅CV»Hã|Ûïçó¨OO_³ý \ No newline at end of file
diff --git a/demo/Zope/ZServer/HTTPS_Server.py b/demo/Zope/ZServer/HTTPS_Server.py
deleted file mode 100644
index 06a2668..0000000
--- a/demo/Zope/ZServer/HTTPS_Server.py
+++ /dev/null
@@ -1,187 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2000-2004, Ng Pheng Siong. All Rights Reserved.
-# This file is derived from Zope's ZServer/HTTPServer.py.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE
-#
-##############################################################################
-
-"""
-Medusa HTTPS server for Zope
-
-changes from Medusa's http_server:
-
- Request Threads -- Requests are processed by threads from a thread
- pool.
-
- Output Handling -- Output is pushed directly into the producer
- fifo by the request-handling thread. The HTTP server does not do
- any post-processing such as chunking.
-
- Pipelineable -- This is needed for protocols such as HTTP/1.1 in
- which mutiple requests come in on the same channel, before
- responses are sent back. When requests are pipelined, the client
- doesn't wait for the response before sending another request. The
- server must ensure that responses are sent back in the same order
- as requests are received.
-
-
-changes from Zope's HTTP server:
-
- Well, this is a *HTTPS* server :)
-
- X.509 certificate-based authentication -- When this is in force,
- zhttps_handler, a subclass of zhttp_handler, is installed. The
- https server is configured to request an X.509 certificate from
- the client. When the request reaches zhttps_handler, it sets
- REMOTE_USER to the client's subject distinguished name (DN) from
- the certificate. Zope's REMOTE_USER machinery takes care of the
- rest, e.g., in conjunction with the RemoteUserFolder product.
-
-"""
-
-import sys, time, types
-
-from PubCore import handle
-from medusa import asyncore
-from ZServer import CONNECTION_LIMIT, ZOPE_VERSION
-from HTTPServer import zhttp_handler
-from zLOG import register_subsystem
-
-from M2Crypto import SSL, version
-from medusa.https_server import https_server, https_channel
-from medusa.asyncore import dispatcher
-
-
-ZSERVER_SSL_VERSION=version
-
-register_subsystem('ZServer HTTPS_Server')
-
-
-class zhttps0_handler(zhttp_handler):
- "zhttps0 handler - sets SSL request headers a la mod_ssl"
-
- def __init__ (self, module, uri_base=None, env=None):
- zhttp_handler.__init__(self, module, uri_base, env)
-
- def get_environment(self, request):
- env = zhttp_handler.get_environment(self, request)
- env['SSL_CIPHER'] = request.channel.get_cipher()
- return env
-
-
-class zhttps_handler(zhttps0_handler):
- "zhttps handler - sets REMOTE_USER to user's X.509 certificate Subject DN"
-
- def __init__ (self, module, uri_base=None, env=None):
- zhttps0_handler.__init__(self, module, uri_base, env)
-
- def get_environment(self, request):
- env = zhttps0_handler.get_environment(self, request)
- peer = request.channel.get_peer_cert()
- if peer is not None:
- env['REMOTE_USER'] = str(peer.get_subject())
- return env
-
-
-class zhttps_channel(https_channel):
- "https channel"
-
- closed=0
- zombie_timeout=100*60 # 100 minutes
-
- def __init__(self, server, conn, addr):
- https_channel.__init__(self, server, conn, addr)
- self.queue=[]
- self.working=0
- self.peer_found=0
-
- def push(self, producer, send=1):
- # this is thread-safe when send is false
- # note, that strings are not wrapped in
- # producers by default
- if self.closed:
- return
- self.producer_fifo.push(producer)
- if send: self.initiate_send()
-
- push_with_producer=push
-
- def work(self):
- "try to handle a request"
- if not self.working:
- if self.queue:
- self.working=1
- try: module_name, request, response=self.queue.pop(0)
- except: return
- handle(module_name, request, response)
-
- def close(self):
- self.closed=1
- while self.queue:
- self.queue.pop()
- if self.current_request is not None:
- self.current_request.channel=None # break circ refs
- self.current_request=None
- while self.producer_fifo:
- p=self.producer_fifo.first()
- if p is not None and type(p) != types.StringType:
- p.more() # free up resources held by producer
- self.producer_fifo.pop()
- self.del_channel()
- #self.socket.set_shutdown(SSL.SSL_SENT_SHUTDOWN|SSL.SSL_RECEIVED_SHUTDOWN)
- self.socket.close()
-
- def done(self):
- "Called when a publishing request is finished"
- self.working=0
- self.work()
-
- def kill_zombies(self):
- now = int (time.time())
- for channel in asyncore.socket_map.values():
- if channel.__class__ == self.__class__:
- if (now - channel.creation_time) > channel.zombie_timeout:
- channel.close()
-
-
-class zhttps_server(https_server):
- "https server"
-
- SERVER_IDENT='ZServerSSL/%s' % (ZSERVER_SSL_VERSION,)
-
- channel_class = zhttps_channel
- shutup = 0
-
- def __init__(self, ip, port, ssl_ctx, resolver=None, logger_object=None):
- self.shutup = 1
- https_server.__init__(self, ip, port, ssl_ctx, resolver, logger_object)
- self.ssl_ctx = ssl_ctx
- self.shutup = 0
- self.log_info('(%s) HTTPS server started at %s\n'
- '\tHostname: %s\n\tPort: %d' % (
- self.SERVER_IDENT,
- time.ctime(time.time()),
- self.server_name,
- self.server_port
- ))
-
- def log_info(self, message, type='info'):
- if self.shutup: return
- dispatcher.log_info(self, message, type)
-
- def readable(self):
- return self.accepting and \
- len(asyncore.socket_map) < CONNECTION_LIMIT
-
- def listen(self, num):
- # override asyncore limits for nt's listen queue size
- self.accepting = 1
- return self.socket.listen (num)
-
diff --git a/demo/Zope/ZServer/__init__.py b/demo/Zope/ZServer/__init__.py
deleted file mode 100644
index 69fe9b1..0000000
--- a/demo/Zope/ZServer/__init__.py
+++ /dev/null
@@ -1,95 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE
-#
-##############################################################################
-
-import sys, os
-
-# HACKERY to get around asyncore issues. This ought to go away! We're
-# currently using the Python 2.2 asyncore bundled with Zope to override
-# brokenness in the Python 2.1 version. We need to do some funny business
-# to make this work, as a 2.2-ism crept into the asyncore code.
-if os.name == 'posix':
- import fcntl
- if not hasattr(fcntl, 'F_GETFL'):
- import FCNTL
- fcntl.F_GETFL = FCNTL.F_GETFL
- fcntl.F_SETFL = FCNTL.F_SETFL
-
-from medusa import asyncore
-sys.modules['asyncore'] = asyncore
-
-
-
-from medusa.test import max_sockets
-CONNECTION_LIMIT=max_sockets.max_select_sockets()
-
-ZSERVER_VERSION='1.1b1'
-import App.FindHomes
-try:
- import App.version_txt
- ZOPE_VERSION=App.version_txt.version_txt()
-except:
- ZOPE_VERSION='experimental'
-
-
-# Try to poke zLOG default logging into asyncore
-# XXX We should probably should do a better job of this,
-# however that would mean that ZServer required zLOG.
-try:
- from zLOG import LOG, register_subsystem, BLATHER, INFO, WARNING, ERROR
- register_subsystem('ZServer')
- severity={'info':INFO, 'warning':WARNING, 'error': ERROR}
-
- def log_info(self, message, type='info'):
- if message[:14]=='adding channel' or \
- message[:15]=='closing channel' or \
- message == 'Computing default hostname':
- LOG('ZServer', BLATHER, message)
- else:
- LOG('ZServer', severity[type], message)
-
- import asyncore
- asyncore.dispatcher.log_info=log_info
-except:
- pass
-
-# A routine to try to arrange for request sockets to be closed
-# on exec. This makes it easier for folks who spawn long running
-# processes from Zope code. Thanks to Dieter Maurer for this.
-try:
- import fcntl
- try:
- from fcntl import F_SETFD, FD_CLOEXEC
- except ImportError:
- from FCNTL import F_SETFD, FD_CLOEXEC
-
- def requestCloseOnExec(sock):
- try: fcntl.fcntl(sock.fileno(), F_SETFD, FD_CLOEXEC)
- except: pass
-
-except (ImportError, AttributeError):
-
- def requestCloseOnExec(sock):
- pass
-
-import asyncore
-from medusa import resolver, logger
-from HTTPServer import zhttp_server, zhttp_handler
-from HTTPS_Server import zhttps_server, zhttps0_handler, zhttps_handler
-from PCGIServer import PCGIServer
-from FCGIServer import FCGIServer
-from FTPServer import FTPServer
-from PubCore import setNumberOfThreads
-from medusa.monitor import secure_monitor_server
-
-# override the service name in logger.syslog_logger
-logger.syslog_logger.svc_name='ZServer'
diff --git a/demo/Zope/ZServer/medusa/ftps_server.py b/demo/Zope/ZServer/medusa/ftps_server.py
deleted file mode 100644
index 8fee339..0000000
--- a/demo/Zope/ZServer/medusa/ftps_server.py
+++ /dev/null
@@ -1,438 +0,0 @@
-"""An FTP/TLS server built on Medusa's ftp_server.
-
-Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
-
-# Python
-import socket, string, sys, time
-
-# Medusa
-from counter import counter
-import asynchat, asyncore, ftp_server, logger
-
-# M2Crypto
-from M2Crypto import SSL
-
-VERSION_STRING='0.09'
-
-class ftp_tls_channel(ftp_server.ftp_channel):
-
- """FTP/TLS server channel for Medusa."""
-
- def __init__(self, server, ssl_ctx, conn, addr):
- """Initialise the channel."""
- self.ssl_ctx = ssl_ctx
- self.server = server
- self.current_mode = 'a'
- self.addr = addr
- asynchat.async_chat.__init__(self, conn)
- self.set_terminator('\r\n')
- self.client_addr = (addr[0], 21)
- self.client_dc = None
- self.in_buffer = ''
- self.closing = 0
- self.passive_acceptor = None
- self.passive_connection = None
- self.filesystem = None
- self.authorized = 0
- self._ssl_accepting = 0
- self._ssl_accepted = 0
- self._pbsz = None
- self._prot = None
- resp = '220 %s M2Crypto (Medusa) FTP/TLS server v%s ready.'
- self.respond(resp % (self.server.hostname, VERSION_STRING))
-
- def writable(self):
- return self._ssl_accepting or self._ssl_accepted
-
- def handle_read(self):
- """Handle a read event."""
- if self._ssl_accepting:
- self._ssl_accepted = self.socket.accept_ssl()
- if self._ssl_accepted:
- self._ssl_accepting = 0
- else:
- try:
- ftp_server.ftp_channel.handle_read(self)
- except SSL.SSLError, what:
- if str(what) == 'unexpected eof':
- self.close()
- else:
- raise
-
- def handle_write(self):
- """Handle a write event."""
- if self._ssl_accepting:
- self._ssl_accepted = self.socket.accept_ssl()
- if self._ssl_accepted:
- self._ssl_accepting = 0
- else:
- try:
- ftp_server.ftp_channel.handle_write(self)
- except SSL.SSLError, what:
- if str(what) == 'unexpected eof':
- self.close()
- else:
- raise
-
- def send(self, data):
- """Send data over SSL."""
- try:
- result = self.socket.send(data)
- if result <= 0:
- return 0
- else:
- return result
- except SSL.SSLError, what:
- self.close()
- self.log_info('send: closing channel %s %s' % (repr(self), what))
- return 0
-
- def recv(self, buffer_size):
- """Receive data over SSL."""
- try:
- result = self.socket.recv(buffer_size)
- if not result:
- return ''
- else:
- return result
- except SSL.SSLError, what:
- self.close()
- self.log_info('recv: closing channel %s %s' % (repr(self), what))
- return ''
-
- def found_terminator(self):
- """Dispatch the FTP command."""
- line = self.in_buffer
- if not len(line):
- return
-
- sp = string.find(line, ' ')
- if sp != -1:
- line = [line[:sp], line[sp+1:]]
- else:
- line = [line]
-
- command = string.lower(line[0])
- if string.find(command, 'stor') != -1:
- while command and command[0] not in string.letters:
- command = command[1:]
-
- func_name = 'cmd_%s' % command
- if command != 'pass':
- self.log('<== %s' % repr(self.in_buffer)[1:-1])
- else:
- self.log('<== %s' % line[0]+' <password>')
-
- self.in_buffer = ''
- if not hasattr(self, func_name):
- self.command_not_understood(line[0])
- return
-
- func = getattr(self, func_name)
- if not self.check_command_authorization(command):
- self.command_not_authorized(command)
- else:
- try:
- result = apply(func, (line,))
- except:
- self.server.total_exceptions.increment()
- (file, func, line), t, v, tbinfo = asyncore.compact_traceback()
- if self.client_dc:
- try:
- self.client_dc_close()
- except:
- pass
- resp = '451 Server error: %s, %s: file %s line: %s'
- self.respond(resp % (t, v, file, line))
-
- def make_xmit_channel(self):
- """Create a connection for sending data."""
- pa = self.passive_acceptor
- if pa:
- if pa.ready:
- conn, addr = pa.ready
- if self._prot:
- cdc = tls_xmit_channel(self, conn, self.ssl_ctx, addr)
- else:
- cdc = ftp_server.xmit_channel(self, addr)
- cdc.set_socket(conn)
- cdc.connected = 1
- self.passive_acceptor.close()
- self.passive_acceptor = None
- else:
- if self._prot:
- cdc = tls_xmit_channel(self, None, self.ssl_ctx, None)
- else:
- cdc = ftp_server.xmit_channel(self)
- else:
- if self._prot:
- cdc = tls_xmit_channel(self, None, self.ssl_ctx, self.client_addr)
- else:
- cdc = ftp_server.xmit_channel(self, self.client_addr)
- cdc.create_socket(socket.AF_INET, socket.SOCK_STREAM)
- if self.bind_local_minus_one:
- cdc.bind(('', self.server.port - 1))
- try:
- cdc.connect(self.client_addr)
- except socket.error, what:
- self.respond('425 Cannot build data connection')
- self.client_dc = cdc
-
- def make_recv_channel(self, fd):
- """Create a connection for receiving data."""
- pa = self.passive_acceptor
- if pa:
- if pa.ready:
- conn, addr = pa.ready
- if self._prot:
- cdc = tls_recv_channel(self, conn, self.ssl_ctx, addr, fd)
- else:
- cdc = ftp_server.recv_channel(self, addr, fd)
- cdc.set_socket(conn)
- cdc.connected = 1
- self.passive_acceptor.close()
- self.passive_acceptor = None
- else:
- if self._prot:
- cdc = tls_recv_channel(self, None, self.ssl_ctx, None, fd)
- else:
- cdc = ftp_server.recv_channel(self, None, fd)
- else:
- if self._prot:
- cdc = tls_recv_channel(self, None, self.ssl_ctx, self._prot, self.client_addr, fd)
- else:
- cdc = ftp_server.recv_channel(self, self.client_addr, fd)
- cdc.create_socket(socket.AF_INET, socket.SOCK_STREAM)
- try:
- cdc.connect(self.client_addr)
- except socket.error, what:
- self.respond('425 Cannot build data connection')
- self.client_dc = cdc
-
- def cmd_auth(self, line):
- """Prepare for TLS operation."""
- # XXX Handle variations.
- if line[1] != 'TLS':
- self.command_not_understood (string.join(line))
- else:
- self.respond('234 AUTH TLS successful')
- self._ssl_accepting = 1
- self.socket = SSL.Connection(self.ssl_ctx, self.socket)
- self.socket.setup_addr(self.addr)
- self.socket.setup_ssl()
- self.socket.set_accept_state()
- self._ssl_accepted = self.socket.accept_ssl()
- if self._ssl_accepted:
- self._ssl_accepting = 0
-
- def cmd_pbsz(self, line):
- """Negotiate size of buffer for secure data transfer. For
- FTP/TLS the only valid value for the parameter is '0'; any
- other value is accepted but ignored."""
- if not (self._ssl_accepting or self._ssl_accepted):
- return self.respond('503 AUTH TLS must be issued prior to PBSZ')
- self._pbsz = 1
- self.respond('200 PBSZ=0 successful.')
-
- def cmd_prot(self, line):
- """Negotiate the security level of the data connection."""
- if self._pbsz is None:
- return self.respond('503 PBSZ must be issued prior to PROT')
- if line[1] == 'C':
- self.respond('200 Protection set to Clear')
- self._pbsz = None
- self._prot = None
- elif line[1] == 'P':
- self.respond('200 Protection set to Private')
- self._prot = 1
- elif line[1] in ('S', 'E'):
- self.respond('536 PROT %s unsupported' % line[1])
- else:
- self.respond('504 PROT %s unsupported' % line[1])
-
-
-class ftp_tls_server(ftp_server.ftp_server):
-
- """FTP/TLS server for Medusa."""
-
- SERVER_IDENT = 'M2Crypto FTP/TLS Server (v%s)' % VERSION_STRING
-
- ftp_channel_class = ftp_tls_channel
-
- def __init__(self, authz, ssl_ctx, host=None, ip='', port=21, resolver=None, log_obj=None):
- """Initialise the server."""
- self.ssl_ctx = ssl_ctx
- self.ip = ip
- self.port = port
- self.authorizer = authz
-
- if host is None:
- self.hostname = socket.gethostname()
- else:
- self.hostname = host
-
- self.total_sessions = counter()
- self.closed_sessions = counter()
- self.total_files_out = counter()
- self.total_files_in = counter()
- self.total_bytes_out = counter()
- self.total_bytes_in = counter()
- self.total_exceptions = counter()
-
- asyncore.dispatcher.__init__(self)
- self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
- self.set_reuse_addr()
- self.bind((self.ip, self.port))
- self.listen(5)
-
- if log_obj is None:
- log_obj = sys.stdout
-
- if resolver:
- self.logger = logger.resolving_logger(resolver, log_obj)
- else:
- self.logger = logger.unresolving_logger(logger.file_logger(sys.stdout))
-
- l = 'M2Crypto (Medusa) FTP/TLS server started at %s\n\tAuthz: %s\n\tHostname: %s\n\tPort: %d'
- self.log_info(l % (time.ctime(time.time()), repr(self.authorizer), self.hostname, self.port))
-
- def handle_accept(self):
- """Accept a socket and dispatch a channel to handle it."""
- conn, addr = self.accept()
- self.total_sessions.increment()
- self.log_info('Connection from %s:%d' % addr)
- self.ftp_channel_class(self, self.ssl_ctx, conn, addr)
-
-
-class nbio_ftp_tls_actor:
-
- """TLS protocol negotiation mixin for FTP/TLS."""
-
- def tls_init(self, sock, ssl_ctx, client_addr):
- """Perform TLS protocol negotiation."""
- self.ssl_ctx = ssl_ctx
- self.client_addr = client_addr
- self._ssl_handshaking = 1
- self._ssl_handshake_ok = 0
- if sock:
- self.socket = SSL.Connection(self.ssl_ctx, sock)
- self.socket.setup_addr(self.client_addr)
- self.socket.setup_ssl()
- self._ssl_handshake_ok = self.socket.accept_ssl()
- if self._ssl_handshake_ok:
- self._ssl_handshaking = 0
- self.add_channel()
- # else the client hasn't connected yet; when that happens,
- # handle_connect() will be triggered.
-
- def tls_neg_ok(self):
- """Return status of TLS protocol negotiation."""
- if self._ssl_handshaking:
- self._ssl_handshake_ok = self.socket.accept_ssl()
- if self._ssl_handshake_ok:
- self._ssl_handshaking = 0
- return self._ssl_handshake_ok
-
- def handle_connect(self):
- """Handle a data connection that occurs after this instance came
- into being. When this handler is triggered, self.socket has been
- created and refers to the underlying connected socket."""
- self.socket = SSL.Connection(self.ssl_ctx, self.socket)
- self.socket.setup_addr(self.client_addr)
- self.socket.setup_ssl()
- self._ssl_handshake_ok = self.socket.accept_ssl()
- if self._ssl_handshake_ok:
- self._ssl_handshaking = 0
- self.add_channel()
-
- def send(self, data):
- """Send data over SSL."""
- try:
- result = self.socket.send(data)
- if result <= 0:
- return 0
- else:
- return result
- except SSL.SSLError, what:
- self.close()
- self.log_info('send: closing channel %s %s' % (repr(self), what))
- return 0
-
- def recv(self, buffer_size):
- """Receive data over SSL."""
- try:
- result = self.socket.recv(buffer_size)
- if not result:
- return ''
- else:
- return result
- except SSL.SSLError, what:
- self.close()
- self.log_info('recv: closing channel %s %s' % (repr(self), what))
- return ''
-
-
-class tls_xmit_channel(nbio_ftp_tls_actor, ftp_server.xmit_channel):
-
- """TLS driver for a send-only data connection."""
-
- def __init__(self, channel, conn, ssl_ctx, client_addr=None):
- """Initialise the driver."""
- ftp_server.xmit_channel.__init__(self, channel, client_addr)
- self.tls_init(conn, ssl_ctx, client_addr)
-
- def readable(self):
- """This channel is readable iff TLS negotiation is in progress.
- (Which implies a connected channel, of course.)"""
- if not self.connected:
- return 0
- else:
- return self._ssl_handshaking
-
- def writable(self):
- """This channel is writable iff TLS negotiation is in progress
- or the application has data to send."""
- if self._ssl_handshaking:
- return 1
- else:
- return ftp_server.xmit_channel.writable(self)
-
- def handle_read(self):
- """Handle a read event: either continue with TLS negotiation
- or let the application handle this event."""
- if self.tls_neg_ok():
- ftp_server.xmit_channel.handle_read(self)
-
- def handle_write(self):
- """Handle a write event: either continue with TLS negotiation
- or let the application handle this event."""
- if self.tls_neg_ok():
- ftp_server.xmit_channel.handle_write(self)
-
-
-class tls_recv_channel(nbio_ftp_tls_actor, ftp_server.recv_channel):
-
- """TLS driver for a receive-only data connection."""
-
- def __init__(self, channel, conn, ssl_ctx, client_addr, fd):
- """Initialise the driver."""
- ftp_server.recv_channel.__init__(self, channel, client_addr, fd)
- self.tls_init(conn, ssl_ctx, client_addr)
-
- def writable(self):
- """This channel is writable iff TLS negotiation is in progress."""
- return self._ssl_handshaking
-
- def handle_read(self):
- """Handle a read event: either continue with TLS negotiation
- or let the application handle this event."""
- if self.tls_neg_ok():
- ftp_server.recv_channel.handle_read(self)
-
- def handle_write(self):
- """Handle a write event: either continue with TLS negotiation
- or let the application handle this event."""
- if self.tls_neg_ok():
- ftp_server.recv_channel.handle_write(self)
-
-
diff --git a/demo/Zope/ZServer/medusa/https_server.py b/demo/Zope/ZServer/medusa/https_server.py
deleted file mode 100644
index 9b932b7..0000000
--- a/demo/Zope/ZServer/medusa/https_server.py
+++ /dev/null
@@ -1,83 +0,0 @@
-#!/usr/bin/env python
-
-"""A https server built on Medusa's http_server.
-
-Copyright (c) 1999-2004 Ng Pheng Siong. All rights reserved."""
-
-import asynchat, asyncore, http_server, socket, sys
-from M2Crypto import SSL, version
-
-VERSION_STRING=version
-
-class https_channel(http_server.http_channel):
-
- ac_in_buffer_size = 1 << 16
-
- def __init__(self, server, conn, addr):
- http_server.http_channel.__init__(self, server, conn, addr)
-
- def send(self, data):
- try:
- result = self.socket._write_nbio(data)
- if result <= 0:
- return 0
- else:
- self.server.bytes_out.increment(result)
- return result
- except SSL.SSLError, why:
- self.close()
- self.log_info('send: closing channel %s %s' % (repr(self), why))
- return 0
-
- def recv(self, buffer_size):
- try:
- result = self.socket._read_nbio(buffer_size)
- if result is None:
- return ''
- elif result == '':
- self.close()
- return ''
- else:
- self.server.bytes_in.increment(len(result))
- return result
- except SSL.SSLError, why:
- self.close()
- self.log_info('recv: closing channel %s %s' % (repr(self), why))
- return ''
-
-
-class https_server(http_server.http_server):
-
- SERVER_IDENT='M2Crypto HTTPS Server (v%s)' % VERSION_STRING
-
- channel_class=https_channel
-
- def __init__(self, ip, port, ssl_ctx, resolver=None, logger_object=None):
- http_server.http_server.__init__(self, ip, port, resolver, logger_object)
- self.ssl_ctx=ssl_ctx
-
- def handle_accept(self):
- # Cribbed from http_server.
- self.total_clients.increment()
- try:
- conn, addr = self.accept()
- except socket.error:
- # linux: on rare occasions we get a bogus socket back from
- # accept. socketmodule.c:makesockaddr complains that the
- # address family is unknown. We don't want the whole server
- # to shut down because of this.
- sys.stderr.write ('warning: server accept() threw an exception\n')
- return
-
- # Turn the vanilla socket into an SSL connection.
- try:
- ssl_conn=SSL.Connection(self.ssl_ctx, conn)
- ssl_conn._setup_ssl(addr)
- ssl_conn.accept_ssl()
- self.channel_class(self, ssl_conn, addr)
- except SSL.SSLError:
- pass
-
- def writeable(self):
- return 0
-
diff --git a/demo/Zope/ca.pem b/demo/Zope/ca.pem
deleted file mode 100644
index b7c84a1..0000000
--- a/demo/Zope/ca.pem
+++ /dev/null
@@ -1,20 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDWTCCAsKgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBgDELMAkGA1UEBhMCU0cx
-ETAPBgNVBAoTCE0yQ3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UE
-AxMbTTJDcnlwdG8gQ2VydGlmaWNhdGUgTWFzdGVyMSIwIAYJKoZIhvcNAQkBFhNu
-Z3BzQG5ldG1lbWV0aWMuY29tMB4XDTAxMTIxNTA1NTU0NloXDTA0MTIxNDA1NTU0
-NlowgYAxCzAJBgNVBAYTAlNHMREwDwYDVQQKEwhNMkNyeXB0bzEUMBIGA1UECxML
-TTJDcnlwdG8gQ0ExJDAiBgNVBAMTG00yQ3J5cHRvIENlcnRpZmljYXRlIE1hc3Rl
-cjEiMCAGCSqGSIb3DQEJARYTbmdwc0BuZXRtZW1ldGljLmNvbTCBnzANBgkqhkiG
-9w0BAQEFAAOBjQAwgYkCgYEAx8soJbS719LHK62VVVIQeC3oW0HvFArwPnA0LuEK
-q+LaqMOJg1rS7hvFdX03diV+XJw7cC0iECZYJNG4ii1xbY6KRmufkInaAwm54E3N
-e+YYVocaqUkcN6xVf6fwnLfPXbpFS/K2Umg11ObKMmi80JmiIdjcjRRCQZC7g1hf
-q+kCAwEAAaOB4DCB3TAdBgNVHQ4EFgQU6/qcBzEtQphfXLhiOHbt2KqBwMIwga0G
-A1UdIwSBpTCBooAU6/qcBzEtQphfXLhiOHbt2KqBwMKhgYakgYMwgYAxCzAJBgNV
-BAYTAlNHMREwDwYDVQQKEwhNMkNyeXB0bzEUMBIGA1UECxMLTTJDcnlwdG8gQ0Ex
-JDAiBgNVBAMTG00yQ3J5cHRvIENlcnRpZmljYXRlIE1hc3RlcjEiMCAGCSqGSIb3
-DQEJARYTbmdwc0BuZXRtZW1ldGljLmNvbYIBADAMBgNVHRMEBTADAQH/MA0GCSqG
-SIb3DQEBBAUAA4GBAD+I14GuS5vJmyv1k7mUMbAicsWRHZ+zrGOq9L/L2LsA+lKQ
-dAzEZE2+Zv8LBPJVltbJJhcFNJS/ZMAjEm4xlJuCpvXVMxd/M5AM29aqekWlIK7J
-vsdDL8IuzpRkMniUiNKPhmB6IPIOslvUKx6QofcE0wDh6pg4VvIbCjkpZ7gf
------END CERTIFICATE-----
diff --git a/demo/Zope/dh1024.pem b/demo/Zope/dh1024.pem
deleted file mode 100644
index 81d43f6..0000000
--- a/demo/Zope/dh1024.pem
+++ /dev/null
@@ -1,5 +0,0 @@
------BEGIN DH PARAMETERS-----
-MIGHAoGBAJf2QmHKtQXdKCjhPx1ottPb0PMTBH9A6FbaWMsTuKG/K3g6TG1Z1fkq
-/Gz/PWk/eLI9TzFgqVAuPvr3q14a1aZeVUMTgo2oO5/y2UHe6VaJ+trqCTat3xlx
-/mNbIK9HA2RgPC3gWfVLZQrY+gz3ASHHR5nXWHEyvpuZm7m3h+irAgEC
------END DH PARAMETERS-----
diff --git a/demo/Zope/lib/python/Products/GuardedFile/GuardedFile.py b/demo/Zope/lib/python/Products/GuardedFile/GuardedFile.py
deleted file mode 100644
index 1e3137f..0000000
--- a/demo/Zope/lib/python/Products/GuardedFile/GuardedFile.py
+++ /dev/null
@@ -1,53 +0,0 @@
-"""GuardedFile.GuardedFile
-
-Copyright (c) 2000-2003 Ng Pheng Siong. All rights reserved.
-This software is released under the ZPL. Usual disclaimers apply."""
-
-__version__ = '1.3'
-
-from AccessControl import getSecurityManager
-from Globals import HTMLFile, MessageDialog
-from OFS.Image import File, cookId
-
-manage_addForm = HTMLFile('add', globals(),Kind='GuardedFile',kind='GuardedFile')
-def manage_addGuardedFile(self, id, file, title='', precondition='', content_type='', REQUEST=None):
- """
- Add a new GuardedFile object.
-
- Creates a new GuardedFile object 'id' with the content of 'file'.
- """
- # Object creation stuff, cribbed from OFS.Image.manage_addFile().
- id, title = cookId(id, title, file)
- self = self.this()
- self._setObject(id, GuardedFile(id, title, '', content_type, precondition))
- obj = self._getOb(id)
- obj.manage_upload(file)
-
- # Unset permission acquisition.
- obj.manage_acquiredPermissions()
-
- # Create a proxy role and set a specific permission for it.
- proxy_role = "proxy_for_%s" % id
- self._addRole(proxy_role)
- obj.manage_role(proxy_role, ['View'])
- uname = getSecurityManager().getUser().getUserName()
- self.manage_addLocalRoles(uname, (proxy_role,), REQUEST)
-
- # Feedback.
- if REQUEST: return MessageDialog(
- title ='Success!',
- message='GuardedFile "%s" has been created.' % id,
- action ='manage_main')
-
-
-class GuardedFile(File):
- """A File object accessible by proxy only."""
- meta_type = "GuardedFile"
-
- def manage_beforeDelete(self, item, container):
- """Delete self's proxy role."""
- role = "proxy_for_%s" % self.__name__
- container._delRoles([role], None)
- self.manage_delLocalRoles(self.users_with_local_role(role))
-
-
diff --git a/demo/Zope/lib/python/Products/GuardedFile/README.txt b/demo/Zope/lib/python/Products/GuardedFile/README.txt
deleted file mode 100644
index d35b9a5..0000000
--- a/demo/Zope/lib/python/Products/GuardedFile/README.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-GuardedFile
-
- A GuardedFile is a Zope File that is accessible *by proxy* only.
-
- When a GuardedFile is created, all acquired permissions are unset.
- A proxy role is created in its container with the sole permission
- "View".
-
- When the GuardedFile is deleted, its associated proxy role is also
- removed.
-
- In all other aspects a GuardedFile behaves exactly like a File.
-
-
- $Id: README.txt 299 2005-06-09 17:32:28Z heikki $
- $Revision: 1.2 $
diff --git a/demo/Zope/lib/python/Products/GuardedFile/TODO.txt b/demo/Zope/lib/python/Products/GuardedFile/TODO.txt
deleted file mode 100644
index 8afc8c7..0000000
--- a/demo/Zope/lib/python/Products/GuardedFile/TODO.txt
+++ /dev/null
@@ -1 +0,0 @@
-1. Icon.
diff --git a/demo/Zope/lib/python/Products/GuardedFile/__init__.py b/demo/Zope/lib/python/Products/GuardedFile/__init__.py
deleted file mode 100644
index f587c75..0000000
--- a/demo/Zope/lib/python/Products/GuardedFile/__init__.py
+++ /dev/null
@@ -1,25 +0,0 @@
-"""GuardedFile.__init__
-
-Copyright (c) 2000 Ng Pheng Siong. All rights reserved.
-This software is released under the ZPL."""
-
-__version__ = '1.1'
-
-import GuardedFile
-
-def initialize(context):
- try:
- context.registerClass(
- GuardedFile.GuardedFile,
- constructors=(GuardedFile.manage_addForm, GuardedFile.manage_addGuardedFile)
- #icon='folder.gif'
- )
- context.registerBaseClass(GuardedFile.GuardedFile)
-
- except:
- import sys, traceback, string
- type, val, tb = sys.exc_info()
- sys.stderr.write(string.join(
- traceback.format_exception(type, val, tb),''))
- del type, val, tb
-
diff --git a/demo/Zope/lib/python/Products/GuardedFile/add.dtml b/demo/Zope/lib/python/Products/GuardedFile/add.dtml
deleted file mode 100644
index ed78fa6..0000000
--- a/demo/Zope/lib/python/Products/GuardedFile/add.dtml
+++ /dev/null
@@ -1,78 +0,0 @@
-<dtml-var manage_page_header>
-
-<dtml-var "manage_form_title(this(), _, form_title='Add GuardedFile')">
-
-<p class="form-help">
- A GuardedFile is a Zope File that is accessible <em>by proxy</em> only.
-</p>
-
-<p class="form-help">
- When a GuardedFile is created, all acquired permissions are unset.
- A proxy role is created in its container with the sole permission
- "View".
-</p>
-
-<p class="form-help">
- When the GuardedFile is deleted, its associated proxy role is also
- removed.
-</p>
-
-<p class="form-help">
- In all other aspects a GuardedFile behaves exactly like a File.
-</p>
-
-<p class="form-help">
- You can create a new <dtml-var kind> using the form below.
- Select a file from your local computer by clicking the
- <em>Browse</em> button. The file you select will be uploaded
- to Zope as a <dtml-var kind>.
-</P>
-
-<FORM ACTION="manage_add<dtml-var Kind>" METHOD="POST"
- ENCTYPE="multipart/form-data">
-<table cellspacing="0" cellpadding="2" border="0">
- <tr>
- <td align="left" valign="top">
- <div class="form-label">
- Id
- </div>
- </td>
- <td align="left" valign="top">
- <input type="text" name="id" size="40" />
- </td>
- </tr>
- <tr>
- <td align="left" valign="top">
- <div class="form-optional">
- Title
- </div>
- </td>
- <td align="left" valign="top">
- <input type="text" name="title" size="40" />
- </td>
- </tr>
- <tr>
- <td align="left" valign="top">
- <div class="form-label">
- File
- </div>
- </td>
- <td align="left" valign="top">
- <input type="file" name="file:string" size="25" value="" />
- </td>
- </tr>
- <tr>
- <td align="left" valign="top">
- </td>
- <td align="left" valign="top">
- <div class="form-element">
- <input class="form-element" type="submit" name="submit"
- value=" Add " />
- </div>
- </td>
- </tr>
-</TABLE>
-</FORM>
-
-<dtml-var manage_page_footer>
-
diff --git a/demo/Zope/lib/python/Products/GuardedFile/refresh.txt b/demo/Zope/lib/python/Products/GuardedFile/refresh.txt
deleted file mode 100644
index e69de29..0000000
--- a/demo/Zope/lib/python/Products/GuardedFile/refresh.txt
+++ /dev/null
diff --git a/demo/Zope/lib/python/Products/GuardedFile/version.txt b/demo/Zope/lib/python/Products/GuardedFile/version.txt
deleted file mode 100644
index 1e5ebbf..0000000
--- a/demo/Zope/lib/python/Products/GuardedFile/version.txt
+++ /dev/null
@@ -1 +0,0 @@
-GuardedFile-1-1-0
diff --git a/demo/Zope/lib/python/Products/ZSmime/README.txt b/demo/Zope/lib/python/Products/ZSmime/README.txt
deleted file mode 100644
index f43740b..0000000
--- a/demo/Zope/lib/python/Products/ZSmime/README.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-ZSmime enables Zope to generate S/MIME-signed/encrypted messages.
-
-ZSmime is useful where Zope accepts confidential information over the
-web, e.g., credit card information, Swiss bank account instructions, etc.
-Such information can be protected by ZSmime and relayed off-site
-immediately. This reduces the value of the information carried on-site
-and in turn reduces the effect of a successful attack against the site.
-
-Even if the S/MIME-protected information remains on-site, it is now
-encrypted - this introduces additional cost in defeating the protection
-and may mitigate the impact of a successful site penetration.
-
-ZSmime adds a DTML tag "dtml-smime" to Zope.
-
-
-$Id: README.txt 299 2005-06-09 17:32:28Z heikki $
-$Revision: 1.1 $
-
diff --git a/demo/Zope/lib/python/Products/ZSmime/SmimeTag.py b/demo/Zope/lib/python/Products/ZSmime/SmimeTag.py
deleted file mode 100644
index 142bec9..0000000
--- a/demo/Zope/lib/python/Products/ZSmime/SmimeTag.py
+++ /dev/null
@@ -1,104 +0,0 @@
-"""ZSmime.SmimeTag
-
-Copyright (c) 1999-2001 Ng Pheng Siong. All rights reserved.
-This software is released under the ZPL. Usual disclaimers apply."""
-
-__version__ = '1.2'
-
-# Zope tag stuff.
-from DocumentTemplate.DT_String import String
-from DocumentTemplate.DT_Util import *
-from DocumentTemplate.DT_Var import Var, Call
-
-# M2Crypto.
-from M2Crypto import BIO, SMIME, X509
-
-SmimeError = "SmimeTag Error"
-
-class SmimeTag:
- """<dtml-smime>"""
-
- name = 'smime'
- blockContinuations = ()
-
- def __init__(self, blocks):
- tname, args, section = blocks[0]
- self.section = section
-
- args = parse_params(args, signer=None, recipients=None)
- has_key = args.has_key
-
- if has_key('signer'):
- self.signer = args['signer']
- try:
- Call(self.signer)
- except ParseError:
- raise SmimeError, ('Invalid parameter "signer".')
- else:
- raise SmimeError, ('The parameter "signer" was not specified in tag.')
-
- if has_key('recipients'):
- self.recipients = args['recipients']
- try:
- Call(self.recipients)
- except ParseError:
- raise SmimeError, ('Invalid parameter "recipients".')
- else:
- raise SmimeError, ('The parameter "recipients" was not specified in tag.')
-
-
- def render(self, md):
- # Render the dtml block.
- data = render_blocks(self.section.blocks, md)
- data_bio = BIO.MemoryBuffer(data)
-
- # Prepare to S/MIME.
- s = SMIME.SMIME()
-
- # Render the signer key, load into BIO.
- try:
- signer = Var(self.signer).render(md)
- except ParseError:
- raise SmimeError, ('Invalid parameter "signer".')
- signer_key_bio = BIO.MemoryBuffer(signer)
- signer_cert_bio = BIO.MemoryBuffer(signer) # XXX Kludge.
-
- # Sign the data.
- s.load_key_bio(signer_key_bio, signer_cert_bio)
- p7 = s.sign(data_bio, flags=SMIME.PKCS7_TEXT)
-
- # Recreate coz sign() has consumed the MemoryBuffer.
- # May be cheaper to seek to start.
- data_bio = BIO.MemoryBuffer(data)
-
- # Render recipients, load into BIO.
- try:
- recip = Var(self.recipients).render(md)
- except ParseError:
- raise SmimeError, ('Invalid parameter "recipients".')
- recip_bio = BIO.MemoryBuffer(recip)
-
- # Load recipient certificates.
- sk = X509.X509_Stack()
- sk.push(X509.load_cert_bio(recip_bio))
- s.set_x509_stack(sk)
-
- # Set a cipher.
- s.set_cipher(SMIME.Cipher('des_ede3_cbc'))
-
- # Encrypt.
- tmp_bio = BIO.MemoryBuffer()
- s.write(tmp_bio, p7)
- p7 = s.encrypt(tmp_bio)
-
- # Finally, return the now signed/encrypted PKCS7.
- out = BIO.MemoryBuffer()
- s.write(out, p7)
- return out.getvalue()
-
-
- __call__ = render
-
-
-String.commands['smime'] = SmimeTag
-
diff --git a/demo/Zope/lib/python/Products/ZSmime/__init__.py b/demo/Zope/lib/python/Products/ZSmime/__init__.py
deleted file mode 100644
index ebb77f6..0000000
--- a/demo/Zope/lib/python/Products/ZSmime/__init__.py
+++ /dev/null
@@ -1,9 +0,0 @@
-"""ZSmime.__init__
-
-Copyright (c) 2000 Ng Pheng Siong. All rights reserved.
-This software is released under the ZPL. Usual disclaimers apply."""
-
-__version__='1.1'
-
-import SmimeTag
-
diff --git a/demo/Zope/lib/python/Products/ZSmime/version.txt b/demo/Zope/lib/python/Products/ZSmime/version.txt
deleted file mode 100644
index ac26a94..0000000
--- a/demo/Zope/lib/python/Products/ZSmime/version.txt
+++ /dev/null
@@ -1 +0,0 @@
-ZSmime-1-0-1
diff --git a/demo/Zope/server.pem b/demo/Zope/server.pem
deleted file mode 100644
index 1ee9282..0000000
--- a/demo/Zope/server.pem
+++ /dev/null
@@ -1,36 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDYjCCAsugAwIBAgIBBDANBgkqhkiG9w0BAQQFADCBgDELMAkGA1UEBhMCU0cx
-ETAPBgNVBAoTCE0yQ3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UE
-AxMbTTJDcnlwdG8gQ2VydGlmaWNhdGUgTWFzdGVyMSIwIAYJKoZIhvcNAQkBFhNu
-Z3BzQG5ldG1lbWV0aWMuY29tMB4XDTAzMDYyMjEzMzAxNFoXDTA0MDYyMTEzMzAx
-NFowXTELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRIwEAYDVQQDEwls
-b2NhbGhvc3QxJzAlBgkqhkiG9w0BCQEWGGFkbWluQHNlcnZlci5leGFtcGxlLmRv
-bTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA37aKGZtFicl8xXXTLJ8/JD7c
-kd3t/teCX9i61lpaDQCKBoVrrursIvZihemMKI9g/u/+BLqt5g8mBdgUdYz0txc8
-KEbV2hj+wwOX4H3XwD0Y+DysXiNHq7/tFdmzSVHoLxpY4zYzXbxQ/p049wvIyPRp
-/y3omcnx/TEUhkn+JmkCAwEAAaOCAQwwggEIMAkGA1UdEwQCMAAwLAYJYIZIAYb4
-QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBTB
-H/mUYlww24mJlSxEtGdlwojO9zCBrQYDVR0jBIGlMIGigBTr+pwHMS1CmF9cuGI4
-du3YqoHAwqGBhqSBgzCBgDELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRv
-MRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UEAxMbTTJDcnlwdG8gQ2VydGlm
-aWNhdGUgTWFzdGVyMSIwIAYJKoZIhvcNAQkBFhNuZ3BzQG5ldG1lbWV0aWMuY29t
-ggEAMA0GCSqGSIb3DQEBBAUAA4GBAAvl6v0s3eFeGP4iAcrfysuK7jzFKhjDYuOy
-lVS3u33bZNLnMpM6OSEM9yPh4WpFCVHf+nYwC71pk4ilsLVXjKxymm2lNGcxLVuW
-iydFz4Ly9nmN7Ja9ygYT39dGAFP/wN7ELTpsbul8VfmqhNg9y81d8i/A1tK3AGA8
-0QkPQNdP
------END CERTIFICATE-----
------BEGIN RSA PRIVATE KEY-----
-MIICXAIBAAKBgQDftooZm0WJyXzFddMsnz8kPtyR3e3+14Jf2LrWWloNAIoGhWuu
-6uwi9mKF6Ywoj2D+7/4Euq3mDyYF2BR1jPS3FzwoRtXaGP7DA5fgfdfAPRj4PKxe
-I0erv+0V2bNJUegvGljjNjNdvFD+nTj3C8jI9Gn/LeiZyfH9MRSGSf4maQIDAQAB
-AoGAHpeVtv62uarl9xKvuBBm0AwQmZnhq9HIsFaw5hMg8Vo7hbzFBvx1IirTOkC/
-u+QvfW1QLVFh6m3z4ySzV4fZBtcd6F9SbSrZ0xsxIUB2NOSa1RGgiaP61bJnMMM1
-xM3O9iwM5GZc3Gqy08QOCpDl0772VJ+9Gz3FA88mrc6rHQkCQQDz6RIatFjT28n8
-1vy0nHwwZz2oXTpe/pyZPwoKj8zVsmrKhKwOw7l8ArxjP8zoHOE7AQBCXYDMNoFp
-IAF0yuqrAkEA6s0wMEdPpQeb0XHAfccyJQoeULxHdVFoz1wWmGSOm4YmQtR8/QJx
-luEgfpeRkzxBKt5Ls3MEkheIOw7xV24zOwJAMz+DaE0AZPNHS3K4ghJnHZxzng6I
-lzEUIjbWm0V/ml70hTy/EhMZw+6nOotLOHHo+QbK0SboSwAgzL/Gzo1cJQJANqpS
-38qadleRJXAQWrg3qnvyluVe1aeAeVZ9RDmVIgxXeBO0jcs12uTLBe4PzHGo0mwy
-v7K1i7XC180gzzQu5QJBAOxITT9RoWSSozPvnirHd37sn+RsrNYkV07NAa80M20Z
-DkBPHeMVkNgigrQ6L6vWmbRDGQbGcMplAxnI5ppKCoU=
------END RSA PRIVATE KEY-----
diff --git a/demo/Zope/starts b/demo/Zope/starts
deleted file mode 100644
index 2676243..0000000
--- a/demo/Zope/starts
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/sh
-umask 077
-reldir=`dirname $0`
-cwd=`cd $reldir; pwd`
-# Zope's event logger is controlled by the "EVENT_LOG_FILE" environment
-# variable. If you don't have a "EVENT_LOG_FILE" environment variable
-# (or its older alias "STUPID_LOG_FILE") set, Zope will log to the standard
-# output. For more information on EVENT_LOG_FILE, see doc/ENVIRONMENT.txt.
-ZLOGFILE=$EVENT_LOG_FILE
-if [ -z "$ZLOGFILE" ]; then
- ZLOGFILE=$STUPID_LOG_FILE
-fi
-if [ -z "$ZLOGFILE" ]; then
- EVENT_LOG_FILE=""
- export EVENT_LOG_FILE
-fi
-exec /usr/local/bin/python2.1 $cwd/z2s.py -D "$@"
diff --git a/demo/Zope/starts.bat b/demo/Zope/starts.bat
deleted file mode 100755
index c8bd3b6..0000000
--- a/demo/Zope/starts.bat
+++ /dev/null
@@ -1 +0,0 @@
-"C:\pkg\zope260\bin\python.exe" "C:\pkg\zope260\z2s.py" -D %1 %2 %3 %4 %5 %6 %7 %8 %9
diff --git a/demo/Zope/utilities/x509_user.py b/demo/Zope/utilities/x509_user.py
deleted file mode 100644
index 1d350d6..0000000
--- a/demo/Zope/utilities/x509_user.py
+++ /dev/null
@@ -1,79 +0,0 @@
-#!/usr/bin/env python
-
-"""
-This is a very simple program to manage the access_x509 database. The
-overriding goal is program portability, hence its use of 'anydbm'.
-
-Invoke it thusly:
-
- x509_user.py
- -u <username>
- [ -x <X.509 subject DN> ]
- [ -f <database> ]
-
-<username> is the Zope username; it must be present.
-
-<X.509 subject DN> is the X.509 certificate's subject distinguished name
-to associate with the user. If it is present, the association is created
-or updated. If it is absent, the association is removed.
-
-<database> defaults to 'access_x509'.
-
-(I told you this is a dumb program.)
-
-
-To read the subject distinguished name from the certificate 'client.pem',
-invoke 'openssl' thusly:
-
- openssl x509 -subject -noout -in client.pem
-
-This produces the output:
-
- subject=/C=SG/O=M2Crypto Client/CN=M2Crypto Client/Email=ngps@post1.com
-
-
-Next, invoke this tool:
-
- x509_user.py -u superuser \\
- -f "/C=SG/O=M2Crypto Client/CN=M2Crypto Client/Email=ngps@post1.com"
-
-This associates the user who owns client.pem to the Zope "superuser".
-
-
-Copyright (c) 2000 Ng Pheng Siong. This program is released under the ZPL.
-"""
-
-import anydbm, getopt, sys
-
-x509_db = 'access_x509'
-username = subject_dn = None
-
-argerr='Usage'
-
-optlist, optarg=getopt.getopt(sys.argv[1:], 'f:u:x:') # ;-)
-for opt in optlist:
- if '-f' in opt:
- x509_db = opt[1]
- elif '-u' in opt:
- username = opt[1]
- elif '-x' in opt:
- subject_dn = opt[1]
-
-if username is None:
- raise argerr, '\n' + __doc__
-
-db = anydbm.open(x509_db, 'cw')
-if subject_dn is None:
- # Remove the association...
- try:
- subject_dn = db[username]
- del db[subject_dn]
- del db[username]
- except:
- pass
-else:
- # Create/update the association.
- db[subject_dn] = username
- db[username] = subject_dn
-db.close()
-
diff --git a/demo/Zope/z2s.py b/demo/Zope/z2s.py
deleted file mode 100644
index 33885ab..0000000
--- a/demo/Zope/z2s.py
+++ /dev/null
@@ -1,1078 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE
-#
-##############################################################################
-"""Zope 2 ZServer start-up file
-
-Usage: %(program)s [options] [environment settings]
-
-Options:
-
- -h
-
- Output this text.
-
- -z path
-
- The location of the Zope installation.
- The default is the location of this script, %(here)s.
-
- -Z 0 or 1
-
- UNIX only! This option is ignored on Windows.
-
- This option controls whether a management process will be created
- that restarts Zope after a shutdown or crash.
-
- If the argument to -Z is non-null (e.g. "-Z1" or "-Zyes"), a
- management process will be used. If the argument to -Z is "-", or
- "0", (e.g. "-Z-" or "-Z0"), a management process will not be used.
- On UNIX, the default behavior is to create a separate management
- process (e.g. -Z1) if the -Z option is not specified.
-
- (Note: the -Z option in Zopes before Zope 2.6 used to be used to specify
- a pidfile name for the management process. This pidfile no longer
- exists).
-
- -t n
-
- The number of threads to use, if ZODB3 is used. The default is
- %(NUMBER_OF_THREADS)s.
-
- -i n
-
- Set the interpreter check interval. This integer value
- determines how often the interpreter checks for periodic things
- such as thread switches and signal handlers. The Zope default
- is 500, but you may want to experiment with other values that
- may increase performance in your particular environment.
-
- -D
-
- Run in Zope debug mode. This causes the Zope process not to
- detach from the controlling terminal, and is equivalent to
- supplying the environment variable setting Z_DEBUG_MODE=1
-
- -a ipaddress
-
- The IP address to listen on. If this is an empty string
- (e.g. -a ''), then all addresses on the machine are used. The
- default is %(IP_ADDRESS)s.
-
- -d ipaddress
-
- IP address of your DNS server. If this is an empty string
- (e.g. -d ''), then IP addresses will not be logged. If you have
- DNS service on your local machine then you can set this to
- 127.0.0.1. The default is: %(DNS_IP)s.
-
- -u username or uid number
-
- The username to run ZServer as. You may want to run ZServer as
- a dedicated user. This only works under Unix, and if ZServer
- is started as root, and is required in that case.
-
- -P [ipaddress:]number
-
- Set the web, ftp and monitor port numbers simultaneously
- as offsets from the number. The web port number will be number+80.
- The FTP port number will be number+21. The monitor port number will
- be number+99.
-
- The number can be preeceeded by an ip address follwed by a colon
- to specify an address to listen on. This allows different servers
- to listen on different addresses.
-
- Multiple -P options can be provided to run multiple sets of servers.
-
- -w port
-
- The Web server (HTTP) port. This defaults to %(HTTP_PORT)s. The
- standard port for HTTP services is 80. If this is a dash
- (e.g. -w -), then HTTP is disabled.
-
- The number can be preeceeded by an ip address follwed by a colon
- to specify an address to listen on. This allows different servers
- to listen on different addresses.
-
- Multiple -w options can be provided to run multiple servers.
-
- -y port
-
- The SSL Web server (HTTPS) port. This defaults to %(HTTPS_PORT)s. The
- standard port for HTTPS services is 443. If this is a dash
- (e.g. -y -), then HTTPS is disabled.
-
- The number can be preeceeded by an ip address follwed by a colon
- to specify an address to listen on. This allows different servers
- to listen on different addresses.
-
- Multiple -y options can be provided to run multiple servers.
-
- -W port
-
- The "WebDAV source" port. If this is a dash (e.g. -W -), then
- "WebDAV source" is disabled. The default is disabled. Note that
- this feature is a workaround for the lack of "source-link" support
- in standard WebDAV clients.
-
- The port can be preeceeded by an ip address follwed by a colon
- to specify an address to listen on. This allows different servers
- to listen on different addresses.
-
- Multiple -W options can be provided to run multiple servers.
-
- -Y port
-
- The "WebDAV source over HTTPS" port. If this is a dash (e.g. -Y -), then
- "WebDAV source over HTTPS" is disabled. The default is disabled. Note that
- this feature is a workaround for the lack of "source-link" support
- in standard WebDAV clients.
-
- The port can be preeceeded by an ip address follwed by a colon
- to specify an address to listen on. This allows different servers
- to listen on different addresses.
-
- Multiple -Y options can be provided to run multiple servers.
-
- -x
-
- If present, this option causes Zope to run in X.509 certificate-based
- authentication mode.
-
- -C
- --force-http-connection-close
-
- If present, this option causes Zope to close all HTTP connections,
- regardless of the 'Connection:' header (or lack of one) sent by
- the client.
-
- -f port
-
- The FTP port. If this is a dash (e.g. -f -), then FTP
- is disabled. The standard port for FTP services is 21. The
- default is %(FTP_PORT)s.
-
- The port can be preeceeded by an ip address follwed by a colon
- to specify an address to listen on. This allows different servers
- to listen on different addresses.
-
- Multiple -f options can be provided to run multiple servers.
-
- -p path
-
- Path to the PCGI resource file. The default value is
- %(PCGI_FILE)s, relative to the Zope location. If this is a dash
- (-p -) or the file does not exist, then PCGI is disabled.
-
- -F path_or_port
-
- Either a port number (for inet sockets) or a path name (for unix
- domain sockets) for the FastCGI Server. If the flag and value are
- not specified then the FastCGI Server is disabled.
-
- -m port
-
- The secure monitor server port. If this is a dash
- (-m -), then the monitor server is disabled. The monitor server
- allows interactive Python style access to a running ZServer. To
- access the server see medusa/monitor_client.py or
- medusa/monitor_client_win32.py. The monitor server password is the
- same as the Zope emergency user password set in the 'access'
- file. The default is to not start up a monitor server.
-
- The port can be preeceeded by an ip address follwed by a colon
- to specify an address to listen on. This allows different servers
- to listen on different addresses.
-
- Multiple -m options can be provided to run multiple servers.
-
- --icp port
-
- The ICP port. ICP can be used to distribute load between back-end
- zope servers, if you are using an ICP-aware front-end proxy such
- as Squid.
-
- The port can be preeceeded by an ip address follwed by a colon
- to specify an address to listen on. This allows different servers
- to listen on different addresses.
-
- Multiple --icp options can be provided to run multiple servers.
-
- -l path
-
- Path to the ZServer log file. If this is a relative path then the
- log file will be written to the 'var' directory. The default is
- %(LOG_FILE)s.
-
- -r
-
- Run ZServer is read-only mode. ZServer won't write anything to disk.
- No log files, no pid files, nothing. This means that you can't do a
- lot of stuff like use PCGI, and zdaemon. ZServer will log hits to
- STDOUT and zLOG will log to STDERR.
-
- -L
-
- Enable locale (internationalization) support. The value passed for
- this option should be the name of the locale to be used (see your
- operating system documentation for locale information specific to
- your system). If an empty string is passed for this option (-L ''),
- Zope will set the locale to the user's default setting (typically
- specified in the $LANG environment variable). If your Python
- installation does not support the locale module, the requested
- locale is not supported by your system or an empty string was
- passed but no default locale can be found, an error will be raised
- and Zope will not start.
-
- -X
-
- Disable servers. This might be used to effectively disable all
- default server settings or previous server settings in the option
- list before providing new settings. For example to provide just a
- web server:
-
- %(program)s -X -w80
-
- -M file
-
- Save detailed logging information to the given file.
- This log includes separate entries for:
-
- - The start of a request,
- - The start of processing the request in an application thread,
- - The start of response output, and
- - The end of the request.
-
-Environment settings are of the form: NAME=VALUE.
-
-Note: you *must* use Python 2.1 or later!
-"""
-
-
-# This is required path hackery for the win32 binary distribution
-# that ensures that the bundled python libraries are used. In a
-# win32 binary distribution, the installer will have replaced the
-# marker string with the actual software home. If that has not
-# happened, then the path munging code is skipped.
-swhome=r'INSERT_SOFTWARE_HOME'
-if swhome != 'INSERT_SOFTWARE_HOME':
- import sys
- sys.path.insert(0, '%s/lib/python' % swhome)
- sys.path.insert(1, '%s/bin/lib' % swhome)
- sys.path.insert(2, '%s/bin/lib/plat-win' % swhome)
- sys.path.insert(3, '%s/bin/lib/win32' % swhome)
- sys.path.insert(4, '%s/bin/lib/win32/lib' % swhome)
- sys.path.insert(5, '%s' % swhome)
-
-
-import os, sys, getopt, codecs, string
-import socket
-
-from types import StringType, IntType
-# workaround to allow unicode encoding conversions in DTML
-dummy = codecs.lookup('iso-8859-1')
-
-sys.setcheckinterval(500)
-
-program=sys.argv[0]
-here=os.path.join(os.getcwd(), os.path.split(program)[0])
-
-########################################################################
-# Configuration section
-
-## General configuration options
-##
-
-# This is the IP address of the network interface you want your servers to
-# be visible from. This can be changed to '' to listen on all interfaces.
-IP_ADDRESS=''
-
-# IP address of your DNS server. Set to '' if you do not want to resolve
-# IP addresses. If you have DNS service on your local machine then you can
-# set this to '127.0.0.1'
-DNS_IP=''
-
-# User id to run ZServer as. Note that this only works under Unix, and if
-# ZServer is started by root. This no longer defaults to 'nobody' since
-# that can lead to a Zope file compromise.
-UID=None
-
-# Log file location. If this is a relative path, then it is joined the
-# the 'var' directory.
-LOG_FILE='Z2.log'
-
-## HTTP configuration
-##
-
-# Port for HTTP Server. The standard port for HTTP services is 80.
-HTTP_PORT=8080
-
-# Port for HTTPS Server. The standard port for HTTPS services is 443.
-HTTPS_PORT=8443
-
-# HTTP enivornment settings.
-HTTP_ENV={}
-
-# HTTPS enivornment settings.
-HTTPS_ENV={}
-
-# Should we close all HTTP connections, ignoring the (usually absent)
-# 'Connection:' header?
-FORCE_HTTP_CONNECTION_CLOSE=0
-
-# Port for the special "WebDAV source view" HTTP handler. There is no
-# standard port for this handler, which is disabled by default.
-WEBDAV_SOURCE_PORT=[]
-
-# Port for the special "WebDAV source view over SSL" HTTP handler. There is no
-# standard port for this handler, which is disabled by default.
-WEBDAV_SSL_SOURCE_PORT=[]
-
-# Should we use client X.509 certificate-based authentication?
-X509_REMOTE_USER=None
-
-## FTP configuration
-
-# Port for the FTP Server. The standard port for FTP services is 21.
-FTP_PORT=8021
-
-## PCGI configuration
-
-# You can configure the PCGI server manually, or have it read its
-# configuration information from a PCGI info file.
-PCGI_FILE='Zope.cgi'
-
-## Monitor configuration
-MONITOR_PORT=0
-
-## ICP configuration
-ICP_PORT=0
-
-# Module to be published, which must be Main or Zope
-MODULE='Zope'
-
-# The size of the thread pool, if ZODB3 is used.
-NUMBER_OF_THREADS=4
-
-# Localization support
-LOCALE_ID=None
-
-# Socket path or port for the FastCGI Server
-FCGI_PORT=None
-
-# Detailed log file
-DETAILED_LOG_FILE=''
-
-# Use a daemon process
-USE_DAEMON = 1
-
-#
-########################################################################
-
-########################################################################
-# Handle command-line arguments:
-
-def server_info(old, v, offset=0):
- # interpret v as a port or address/port and get new value
- if v == '-': v=''
- l=v.find(':')
- if l >= 0:
- a=v[:l]
- v=v[l+1:]
- else:
- a=IP_ADDRESS
-
- if not v: return v
-
- try:
- v=int(v)
- if v < 0: raise 'Invalid port', v
- v=v+offset
- except: raise 'Invalid port', v
-
- if isinstance(old, IntType): old=[(a,v)]
- else: old.append((a,v))
-
- return old
-
-
-try:
- python_version = sys.version.split()[0]
- if python_version < '2.1':
- raise 'Invalid python version', python_version
- if python_version[:3] == '2.1':
- if python_version[4:5] < '3':
- import warnings
- err = ('You are running Python version %s. This Python version '
- 'has known bugs that may cause Zope to run improperly. '
- 'Consider upgrading to a Python in the 2.1 series '
- 'with at least version number 2.1.3. (Note that Zope does '
- 'not yet run under any Python 2.2 version).' %
- python_version)
- warnings.warn(err)
- if python_version[:3] == '2.2':
- import warnings
- err = ('You are running Python version %s. This Python version '
- 'has not yet been tested with Zope and you may experience '
- 'operational problems as a result. Consider using '
- 'Python 2.1.3 instead.' % python_version)
- warnings.warn(err)
-
-
- opts, args = getopt.getopt(sys.argv[1:],
- 'hz:Z:t:i:a:d:u:w:W:y:Y:x:f:p:m:Sl:2DP:rF:L:XM:C',
- ['icp=', 'force-http-connection-close'
- ])
-
- DEBUG=0
- READ_ONLY=0
- if sys.platform == 'win32':
- USE_DAEMON = 0
-
-
- # Get environment variables
- for a in args:
- if a.find('='):
- a=a.split('=')
- o=a[0]
- v='='.join(a[1:])
- if o:
- os.environ[o]=v
- HTTP_ENV[o]=v
- else:
- raise 'Invalid argument', a
-
- for o, v in opts:
- if o=='-z': here=v
- elif o=='-Z':
- if v in ('-', '0', ''):
- USE_DAEMON=0
- elif sys.platform != 'win32':
- USE_DAEMON = 1
- elif o=='-r': READ_ONLY=1
- elif o=='-t':
- try: v=int(v)
- except: raise 'Invalid number of threads', v
- NUMBER_OF_THREADS=v
-
- elif o=='-i':
- try: v=int(v)
- except: raise 'Invalid value for -i option', v
- sys.setcheckinterval(v)
-
- elif o=='-a': IP_ADDRESS=v
- elif o=='-d':
- if v=='-': v=''
- DNS_IP=v
- elif o=='-u': UID=v
- elif o=='-D':
- os.environ['Z_DEBUG_MODE']='1'
- DEBUG=1
- elif o=='-S': sys.ZMANAGED=1
- elif o=='-X':
- MONITOR_PORT=HTTP_PORT=FTP_PORT=FCGI_PORT=ICP_PORT=0
- WEBDAV_SOURCE_PORT=0
- PCGI_FILE=''
- elif o=='-m':
- MONITOR_PORT=server_info(MONITOR_PORT, v)
- elif o=='-w':
- HTTP_PORT=server_info(HTTP_PORT, v)
- elif o=='-y':
- HTTPS_PORT=server_info(HTTPS_PORT, v)
- elif o=='-C' or o=='--force-http-connection-close':
- FORCE_HTTP_CONNECTION_CLOSE=1
- elif o=='-W':
- WEBDAV_SOURCE_PORT=server_info(WEBDAV_SOURCE_PORT, v)
- elif o=='-Y':
- WEBDAV_SSL_SOURCE_PORT=server_info(WEBDAV_SSL_SOURCE_PORT, v)
- elif o=='-x':
- if v in ('-', '0', ''):
- X509_REMOTE_USER=None
- else:
- X509_REMOTE_USER=1
- elif o=='-f':
- FTP_PORT=server_info(FTP_PORT, v)
- elif o=='-P':
- HTTP_PORT=server_info(HTTP_PORT, v, 80)
- FTP_PORT=server_info(FTP_PORT, v, 21)
- elif o=='--icp':
- ICP_PORT=server_info(ICP_PORT, v)
-
- elif o=='-p':
- if v=='-': v=''
- PCGI_FILE=v
- elif o=='-h':
- print __doc__ % vars()
- sys.exit(0)
- elif o=='-2': MODULE='Main'
- elif o=='-l': LOG_FILE=v
- elif o=='-L':
- if v: LOCALE_ID=v
- else: LOCALE_ID=''
- elif o=='-F':
- if v=='-': v=''
- FCGI_PORT=v
- elif o=='-M': DETAILED_LOG_FILE=v
-
-except SystemExit: sys.exit(0)
-except:
- print __doc__ % vars()
- print
- print 'Error:'
- print "%s: %s" % (sys.exc_type, sys.exc_value)
- sys.exit(1)
-
-#
-########################################################################
-
-########################################################################
-# OK, let's get going!
-
-# Jigger path:
-sys.path=[os.path.join(here,'lib','python'),here
- ]+filter(None, sys.path)
-
-
-
-# Try to set the locale if specified on the command
-# line. If the locale module is not available or the
-# requested locale is not supported by the local
-# machine, raise an error so that the user is made
-# aware of the problem.
-
-def set_locale(val):
- try:
- import locale
- except:
- raise SystemExit, (
- 'The locale module could not be imported.\n'
- 'To use localization options, you must ensure\n'
- 'that the locale module is compiled into your\n'
- 'Python installation.'
- )
- try:
- locale.setlocale(locale.LC_ALL, val)
- except:
- raise SystemExit, (
- 'The specified locale is not supported by your system.\n'
- 'See your operating system documentation for more\n'
- 'information on locale support.'
- )
-if LOCALE_ID is not None:
- set_locale(LOCALE_ID)
-
-import zdaemon
-# from this point forward we can use the zope logger
-# importing ZDaemon before importing ZServer causes ZServer logging
-# not to work.
-
-# Import ZServer before we open the database or get at interesting
-# application code so that ZServer's asyncore gets to be the
-# official one. Also gets SOFTWARE_HOME, INSTANCE_HOME, and CLIENT_HOME
-import ZServer
-
-# install signal handlers if on posix
-if os.name == 'posix':
- from Signals import Signals
- Signals.registerZopeSignals()
-
-# Location of the ZServer pid file. When Zope starts up it will write
-# its PID to this file. If Zope is run under zdaemon control, zdaemon
-# will write to this pidfile instead of Zope.
-PID_FILE=os.path.join(CLIENT_HOME, 'Z2.pid')
-
-if USE_DAEMON and not READ_ONLY:
- import App.FindHomes
- sys.ZMANAGED=1
- # zdaemon.run creates a process which "manages" the actual Zope
- # process (restarts it if it dies). The management process passes along
- # signals that it receives to its child.
- zdaemon.run(sys.argv, os.path.join(CLIENT_HOME, PID_FILE))
-
-os.chdir(CLIENT_HOME)
-
-def _warn_nobody():
- zLOG.LOG("z2", zLOG.INFO, ("Running Zope as 'nobody' can compromise "
- "your Zope files; consider using a "
- "dedicated user account for Zope") )
-
-try:
- # Import logging support
- import zLOG
- import ZLogger
-
- if READ_ONLY:
- if hasattr(zLOG, '_set_stupid_dest'):
- zLOG._set_stupid_dest(sys.stderr)
- else:
- zLOG._stupid_dest = sys.stderr
- else:
- zLOG.log_write = ZLogger.ZLogger.log_write
-
- if DETAILED_LOG_FILE:
- from ZServer import DebugLogger
- logfile=os.path.join(CLIENT_HOME, DETAILED_LOG_FILE)
- zLOG.LOG('z2', zLOG.BLATHER,
- 'Using detailed request log file %s' % logfile)
- DL=DebugLogger.DebugLogger(logfile)
- DebugLogger.log=DL.log
- DebugLogger.reopen=DL.reopen
- sys.__detailedlog=DL
-
- # Import Zope (or Main)
- if MODULE == 'Zope':
- import Zope
- Zope.startup()
- else:
- exec "import "+MODULE in {}
-
- # Location of the ZServer log file. This file logs all ZServer activity.
- # You may wish to create different logs for different servers. See
- # medusa/logger.py for more information.
- if not os.path.isabs(LOG_FILE):
- LOG_PATH=os.path.join(CLIENT_HOME, LOG_FILE)
- else:
- LOG_PATH=LOG_FILE
-
- # import ZServer stuff
-
- # First, we need to increase the number of threads
- if MODULE=='Zope':
- from ZServer import setNumberOfThreads
- setNumberOfThreads(NUMBER_OF_THREADS)
-
- from ZServer import resolver, logger, asyncore
-
- from ZServer import zhttp_server, zhttp_handler
- from ZServer import zhttps_server, zhttps0_handler, zhttps_handler
- from ZServer.WebDAVSrcHandler import WebDAVSrcHandler
- from ZServer import PCGIServer,FTPServer,FCGIServer
-
- from ZServer import secure_monitor_server
-
- from M2Crypto import SSL, Rand
-
- ## ZServer startup
- ##
-
- ## In X509_REMOTE_USER mode, we log the client cert's subject DN.
- if X509_REMOTE_USER:
-
- import base64, string, time
-
- def log (self, bytes):
- user_agent=self.get_header('user-agent')
- if not user_agent: user_agent=''
- referer=self.get_header('referer')
- if not referer: referer=''
-
- get_peer_cert = getattr(self.channel, 'get_peer_cert', None)
- if get_peer_cert is not None:
- name = str(get_peer_cert().get_subject())
- else:
- name = 'Anonymous'
- auth=self.get_header('Authorization')
- if auth is not None:
- if string.lower(auth[:6]) == 'basic ':
- try: decoded=base64.decodestring(auth[6:])
- except base64.binascii.Error: decoded=''
- t = string.split(decoded, ':', 1)
- if len(t) < 2:
- name = 'Unknown (bad auth string)'
- else:
- name = t[0]
-
- self.channel.server.logger.log (
- self.channel.addr[0],
- ' - %s [%s] "%s" %d %d "%s" "%s"\n' % (
- name,
- self.log_date_string (time.time()),
- self.request,
- self.reply_code,
- bytes,
- referer,
- user_agent
- )
- )
-
- from ZServer.medusa import http_server
- http_server.http_request.log = log
-
- # Resolver and Logger, used by other servers
- if DNS_IP:
- rs = resolver.caching_resolver(DNS_IP)
- else:
- rs=None
-
- if READ_ONLY:
- lg = logger.file_logger('-') # log to stdout
- zLOG.LOG('z2', zLOG.BLATHER, 'Logging access log to stdout')
- elif os.environ.has_key('ZSYSLOG_ACCESS'):
- if os.environ.has_key("ZSYSLOG_ACCESS_FACILITY"):
- lg = logger.syslog_logger(
- os.environ['ZSYSLOG_ACCESS'],
- facility=os.environ['ZSYSLOG_ACCESS_FACILITY'])
- else:
- lg = logger.syslog_logger(os.environ['ZSYSLOG_ACCESS'])
- zLOG.LOG('z2', zLOG.BLATHER, 'Using local syslog access log')
- elif os.environ.has_key('ZSYSLOG_ACCESS_SERVER'):
- (addr, port) = os.environ['ZSYSLOG_ACCESS_SERVER'].split( ':')
- lg = logger.syslog_logger((addr, int(port)))
- zLOG.LOG('z2', zLOG.BLATHER, 'Using remote syslog access log')
- else:
- lg = logger.file_logger(LOG_PATH)
- zLOG.LOG('z2', zLOG.BLATHER, 'Using access log file %s' % LOG_PATH)
- sys.__lg = lg
-
- port_err=('\n\nZope wants to use %(socktype)s port %(port)s for its '
- '%(protocol)s service, but it is already in use by another '
- 'application on this machine. Either shut the application down '
- 'which is using this port, or start Zope with a different '
- '%(protocol)s port via the "%(switch)s" command-line switch.\n')
-
- # HTTP Server
- if HTTP_PORT:
- if isinstance(HTTP_PORT, IntType): HTTP_PORT=((IP_ADDRESS, HTTP_PORT),)
- for address, port in HTTP_PORT:
- try:
- hs = zhttp_server(
- ip=address,
- port=port,
- resolver=rs,
- logger_object=lg)
- except socket.error, why:
- if why[0] == 98: # address in use
- raise port_err % {'port':port,
- 'socktype':'TCP',
- 'protocol':'HTTP',
- 'switch':'-w'}
- raise
- # Handler for a published module. zhttp_handler takes 3 arguments:
- # The name of the module to publish, and optionally the URI base
- # which is basically the SCRIPT_NAME, and optionally a dictionary
- # with CGI environment variables which override default
- # settings. The URI base setting is useful when you want to
- # publish more than one module with the same HTTP server. The CGI
- # environment setting is useful when you want to proxy requests
- # from another web server to ZServer, and would like the CGI
- # environment to reflect the CGI environment of the other web
- # server.
- try:
- del HTTP_ENV['HTTPS']
- except KeyError:
- pass
- zh = zhttp_handler(MODULE, '', HTTP_ENV)
- if FORCE_HTTP_CONNECTION_CLOSE:
- zh._force_connection_close = 1
- hs.install_handler(zh)
-
- # HTTPS Server
- if HTTPS_PORT:
- ssl_ctx = SSL.Context('sslv23')
- ssl_ctx.load_cert_chain('%s/server.pem' % INSTANCE_HOME)
- ssl_ctx.load_verify_locations('%s/ca.pem' % INSTANCE_HOME)
- ssl_ctx.load_client_CA('%s/ca.pem' % INSTANCE_HOME)
- #ssl_ctx.set_allow_unknown_ca(1)
- ssl_ctx.set_session_id_ctx(MODULE)
- ssl_ctx.set_tmp_dh('%s/dh1024.pem' % INSTANCE_HOME)
- if X509_REMOTE_USER:
- ssl_ctx.set_verify(SSL.verify_peer, 10)
- else:
- ssl_ctx.set_verify(SSL.verify_none, 10)
- if type(HTTPS_PORT) is type(0): HTTPS_PORT=((IP_ADDRESS, HTTPS_PORT),)
-
- for address, port in HTTPS_PORT:
- hss = zhttps_server(
- ip=address,
- port=port,
- ssl_ctx=ssl_ctx,
- resolver=rs,
- logger_object=lg)
-
- try:
- del HTTPS_ENV['HTTP']
- except KeyError:
- pass
- HTTPS_ENV['HTTPS']='ON'
-
- if X509_REMOTE_USER:
- zsh = zhttps_handler(MODULE, '', HTTPS_ENV)
- else:
- zsh = zhttps0_handler(MODULE, '', HTTPS_ENV)
- hss.install_handler(zsh)
-
- # WebDAV source Server (runs HTTP, but munges request to return
- # 'manage_FTPget').
- if WEBDAV_SOURCE_PORT:
- if isinstance(WEBDAV_SOURCE_PORT, IntType):
- WEBDAV_SOURCE_PORT=((IP_ADDRESS, WEBDAV_SOURCE_PORT),)
- for address, port in WEBDAV_SOURCE_PORT:
- try:
- hs = zhttp_server(
- ip=address,
- port=port,
- resolver=rs,
- logger_object=lg)
- except socket.error, why:
- if why[0] == 98: # address in use
- raise port_err % {'port':port,
- 'socktype':'TCP',
- 'protocol':'WebDAV source',
- 'switch':'-W'}
- raise
-
- # Handler for a published module. zhttp_handler takes 3 arguments:
- # The name of the module to publish, and optionally the URI base
- # which is basically the SCRIPT_NAME, and optionally a dictionary
- # with CGI environment variables which override default
- # settings. The URI base setting is useful when you want to
- # publish more than one module with the same HTTP server. The CGI
- # environment setting is useful when you want to proxy requests
- # from another web server to ZServer, and would like the CGI
- # environment to reflect the CGI environment of the other web
- # server.
- zh = WebDAVSrcHandler(MODULE, '', HTTP_ENV)
- hs.install_handler(zh)
-
- # enable document retrieval of the document source on the
- # standard HTTP port
-
- clients = os.environ.get('WEBDAV_SOURCE_PORT_CLIENTS')
- if clients:
- import re
- sys.WEBDAV_SOURCE_PORT_CLIENTS = re.compile(clients).search
- else:
- sys.WEBDAV_SOURCE_PORT_CLIENTS = None
-
- # WebDAV-over-SSL source Server (runs HTTPS, but munges request to return
- # 'manage_FTPget').
- if WEBDAV_SSL_SOURCE_PORT:
- ssl_ctx = SSL.Context('sslv23')
- ssl_ctx.load_cert_chain('%s/server.pem' % INSTANCE_HOME)
- ssl_ctx.load_verify_locations('%s/ca.pem' % INSTANCE_HOME)
- ssl_ctx.load_client_CA('%s/ca.pem' % INSTANCE_HOME)
- ssl_ctx.set_verify(SSL.verify_none, 10)
- ssl_ctx.set_session_id_ctx(MODULE)
- ssl_ctx.set_tmp_dh('%s/dh1024.pem' % INSTANCE_HOME)
- if type(WEBDAV_SSL_SOURCE_PORT) is type(0):
- WEBDAV_SSL_SOURCE_PORT=((IP_ADDRESS, WEBDAV_SSL_SOURCE_PORT),)
- for address, port in WEBDAV_SSL_SOURCE_PORT:
- hss = zhttps_server(
- ip=address,
- port=port,
- ssl_ctx=ssl_ctx,
- resolver=rs,
- logger_object=lg)
-
- try:
- del HTTPS_ENV['HTTP']
- except KeyError:
- pass
- HTTPS_ENV['HTTPS']='ON'
-
- zsh = WebDAVSrcHandler(MODULE, '', HTTPS_ENV)
- hss.install_handler(zsh)
-
- # FTP Server
- if FTP_PORT:
- if isinstance(FTP_PORT, IntType): FTP_PORT=((IP_ADDRESS, FTP_PORT),)
- for address, port in FTP_PORT:
- try:
- FTPServer(
- module=MODULE,
- ip=address,
- port=port,
- resolver=rs,
- logger_object=lg)
- except socket.error, why:
- if why[0] == 98: # address in use
- raise port_err % {'port':port,
- 'socktype':'TCP',
- 'protocol':'FTP',
- 'switch':'-f'}
- raise
-
- # PCGI Server
- if PCGI_FILE and not READ_ONLY:
- PCGI_FILE=os.path.join(here, PCGI_FILE)
- if os.path.exists(PCGI_FILE):
- zpcgi = PCGIServer(
- module=MODULE,
- ip=IP_ADDRESS,
- pcgi_file=PCGI_FILE,
- resolver=rs,
- logger_object=lg)
-
-
- # FastCGI Server
- if FCGI_PORT and not READ_ONLY:
- fcgiPort = None
- fcgiPath = None
- try:
- fcgiPort = int(FCGI_PORT)
- except ValueError:
- fcgiPath = FCGI_PORT
- try:
- zfcgi = FCGIServer(module=MODULE,
- ip=IP_ADDRESS,
- port=fcgiPort,
- socket_file=fcgiPath,
- resolver=rs,
- logger_object=lg)
- except socket.error, why:
- if why[0] == 98: # address in use
- raise port_err % {'port':fcgiPort,
- 'socktype':'TCP',
- 'protocol':'FastCGI',
- 'switch':'-F'}
- raise
-
-
- # Monitor Server
- if MONITOR_PORT:
- from AccessControl.User import emergency_user
- if not hasattr(emergency_user, '__null_user__'):
- pw = emergency_user._getPassword()
- else:
- pw = None
- zLOG.LOG("z2", zLOG.WARNING, 'Monitor server not started'
- ' because no emergency user exists.')
- if pw:
- if isinstance(MONITOR_PORT, IntType):
- MONITOR_PORT=((IP_ADDRESS, MONITOR_PORT),)
- for address, port in MONITOR_PORT:
- try:
- monitor=secure_monitor_server(
- password=pw,
- hostname=address,
- port=port)
- except socket.error, why:
- if why[0] == 98: # address in use
- raise port_err % {'port':port,
- 'socktype':'TCP',
- 'protocol':'monitor server',
- 'switch':'-m'}
- raise
-
- if ICP_PORT:
- if isinstance(ICP_PORT, IntType): ICP_PORT=((IP_ADDRESS, ICP_PORT),)
- from ZServer.ICPServer import ICPServer
- for address, port in ICP_PORT:
- try:
- ICPServer(address,port)
- except socket.error, why:
- if why[0] == 98: # address in use
- raise port_err % {'port':port,
- 'socktype':'UDP',
- 'protocol':'ICP',
- 'switch':'--icp'}
- raise
-
- if not USE_DAEMON and not READ_ONLY:
- if os.path.exists(PID_FILE): os.unlink(PID_FILE)
- pf = open(PID_FILE, 'w')
- pid='%s\n' % os.getpid()
- pf.write(pid)
- pf.close()
-
- # Warn if we were started as nobody.
- try:
- import pwd
- if os.getuid():
- if pwd.getpwuid(os.getuid())[0] == 'nobody':
- _warn_nobody()
- except:
- pass
-
- # Drop root privileges if we have them, and do some sanity checking
- # to make sure we're not starting with an obviously insecure setup.
- try:
- if os.getuid() == 0:
- try:
- import initgroups
- except:
- raise SystemExit, 'initgroups is required to safely setuid'
- if UID == None:
- raise SystemExit, ('A user was not specified to setuid '
- 'to; fix this to start as root (see '
- 'doc/SETUID.txt)')
- import stat
- client_home_stat = os.stat(CLIENT_HOME)
- client_home_faults = []
- if not (client_home_stat[stat.ST_MODE]&01000):
- client_home_faults.append('does not have the sticky bit set')
- if client_home_stat[stat.ST_UID] != 0:
- client_home_faults.append('is not owned by root')
- if client_home_faults:
- client_home_faults.append('fix this to start as root (see '
- 'doc/SETUID.txt)')
- err = '%s %s' % (CLIENT_HOME, ', '.join(client_home_faults))
- raise SystemExit, err
-
- try:
- try: UID = string.atoi(UID)
- except: pass
- gid = None
- if isinstance(UID, StringType):
- uid = pwd.getpwnam(UID)[2]
- gid = pwd.getpwnam(UID)[3]
- elif isinstance(UID, IntType):
- uid = pwd.getpwuid(UID)[2]
- gid = pwd.getpwuid(UID)[3]
- UID = pwd.getpwuid(UID)[0]
- else:
- raise KeyError
- if UID == 'nobody':
- _warn_nobody()
- try:
- initgroups.initgroups(UID, gid)
- if gid is not None:
- try:
- os.setgid(gid)
- except OSError:
- pass
- os.setuid(uid)
- except OSError:
- pass
- except KeyError:
- zLOG.LOG("z2", zLOG.ERROR, ("Can't find UID %s" % UID))
- except AttributeError:
- pass
- except:
- raise
-
- # Check umask sanity if we're on posix.
- if os.name == 'posix' and not os.environ.get('Z_DEBUG_MODE'):
- # umask is silly, blame POSIX. We have to set it to get its value.
- current_umask = os.umask(0)
- os.umask(current_umask)
- if current_umask != 077:
- current_umask = '%03o' % current_umask
- zLOG.LOG("z2", zLOG.INFO, (
- 'Your umask of %s may be too permissive; for the security of '
- 'your Zope data, it is recommended you use 077' % current_umask
- ))
-
-except:
- # Log startup exception and tell zdaemon not to restart us.
- try:
- zLOG.LOG("z2", zLOG.PANIC, "Startup exception",
- error=sys.exc_info())
- except: pass
- sys.exit(0)
-
-# Start Medusa, Ye Hass!
-Rand.load_file('%s/randpool.dat' % INSTANCE_HOME, -1)
-sys.ZServerExitCode=0
-asyncore.loop()
-Rand.save_file('%s/randpool.dat' % INSTANCE_HOME)
-sys.exit(sys.ZServerExitCode)
diff --git a/demo/Zope/z2s.py.diff b/demo/Zope/z2s.py.diff
deleted file mode 100644
index f79cd94..0000000
--- a/demo/Zope/z2s.py.diff
+++ /dev/null
@@ -1,266 +0,0 @@
---- z2s.py Sun Oct 26 17:51:00 2003
-+++ /usr/local/home/ngps/pkg/zope261/z2.py Thu Jan 30 22:41:42 2003
-@@ -105,21 +105,9 @@
-
- Multiple -w options can be provided to run multiple servers.
-
-- -y port
--
-- The SSL Web server (HTTPS) port. This defaults to %(HTTPS_PORT)s. The
-- standard port for HTTPS services is 443. If this is a dash
-- (e.g. -y -), then HTTPS is disabled.
--
-- The number can be preeceeded by an ip address follwed by a colon
-- to specify an address to listen on. This allows different servers
-- to listen on different addresses.
--
-- Multiple -y options can be provided to run multiple servers.
--
- -W port
-
-- The "WebDAV source" port. If this is a dash (e.g. -W -), then
-+ The "WebDAV source" port. If this is a dash (e.g. -w -), then
- "WebDAV source" is disabled. The default is disabled. Note that
- this feature is a workaround for the lack of "source-link" support
- in standard WebDAV clients.
-@@ -130,24 +118,6 @@
-
- Multiple -W options can be provided to run multiple servers.
-
-- -Y port
--
-- The "WebDAV source over HTTPS" port. If this is a dash (e.g. -Y -), then
-- "WebDAV source over HTTPS" is disabled. The default is disabled. Note that
-- this feature is a workaround for the lack of "source-link" support
-- in standard WebDAV clients.
--
-- The port can be preeceeded by an ip address follwed by a colon
-- to specify an address to listen on. This allows different servers
-- to listen on different addresses.
--
-- Multiple -Y options can be provided to run multiple servers.
--
-- -x
--
-- If present, this option causes Zope to run in X.509 certificate-based
-- authentication mode.
--
- -C
- --force-http-connection-close
-
-@@ -316,15 +286,9 @@
- # Port for HTTP Server. The standard port for HTTP services is 80.
- HTTP_PORT=8080
-
--# Port for HTTPS Server. The standard port for HTTPS services is 443.
--HTTPS_PORT=8443
--
- # HTTP enivornment settings.
- HTTP_ENV={}
-
--# HTTPS enivornment settings.
--HTTPS_ENV={}
--
- # Should we close all HTTP connections, ignoring the (usually absent)
- # 'Connection:' header?
- FORCE_HTTP_CONNECTION_CLOSE=0
-@@ -333,13 +297,6 @@
- # standard port for this handler, which is disabled by default.
- WEBDAV_SOURCE_PORT=[]
-
--# Port for the special "WebDAV source view over SSL" HTTP handler. There is no
--# standard port for this handler, which is disabled by default.
--WEBDAV_SSL_SOURCE_PORT=[]
--
--# Should we use client X.509 certificate-based authentication?
--X509_REMOTE_USER=None
--
- ## FTP configuration
-
- # Port for the FTP Server. The standard port for FTP services is 21.
-@@ -429,7 +386,7 @@
-
-
- opts, args = getopt.getopt(sys.argv[1:],
-- 'hz:Z:t:i:a:d:u:w:W:y:Y:x:f:p:m:Sl:2DP:rF:L:XM:C',
-+ 'hz:Z:t:i:a:d:u:w:W:f:p:m:Sl:2DP:rF:L:XM:C',
- ['icp=', 'force-http-connection-close'
- ])
-
-@@ -486,19 +443,10 @@
- MONITOR_PORT=server_info(MONITOR_PORT, v)
- elif o=='-w':
- HTTP_PORT=server_info(HTTP_PORT, v)
-- elif o=='-y':
-- HTTPS_PORT=server_info(HTTPS_PORT, v)
- elif o=='-C' or o=='--force-http-connection-close':
- FORCE_HTTP_CONNECTION_CLOSE=1
- elif o=='-W':
- WEBDAV_SOURCE_PORT=server_info(WEBDAV_SOURCE_PORT, v)
-- elif o=='-Y':
-- WEBDAV_SSL_SOURCE_PORT=server_info(WEBDAV_SSL_SOURCE_PORT, v)
-- elif o=='-x':
-- if v in ('-', '0', ''):
-- X509_REMOTE_USER=None
-- else:
-- X509_REMOTE_USER=1
- elif o=='-f':
- FTP_PORT=server_info(FTP_PORT, v)
- elif o=='-P':
-@@ -653,60 +601,14 @@
- from ZServer import resolver, logger, asyncore
-
- from ZServer import zhttp_server, zhttp_handler
-- from ZServer import zhttps_server, zhttps0_handler, zhttps_handler
- from ZServer.WebDAVSrcHandler import WebDAVSrcHandler
- from ZServer import PCGIServer,FTPServer,FCGIServer
-
- from ZServer import secure_monitor_server
-
-- from M2Crypto import SSL, Rand
--
- ## ZServer startup
- ##
-
-- ## In X509_REMOTE_USER mode, we log the client cert's subject DN.
-- if X509_REMOTE_USER:
--
-- import base64, string, time
--
-- def log (self, bytes):
-- user_agent=self.get_header('user-agent')
-- if not user_agent: user_agent=''
-- referer=self.get_header('referer')
-- if not referer: referer=''
--
-- get_peer_cert = getattr(self.channel, 'get_peer_cert', None)
-- if get_peer_cert is not None:
-- name = str(get_peer_cert().get_subject())
-- else:
-- name = 'Anonymous'
-- auth=self.get_header('Authorization')
-- if auth is not None:
-- if string.lower(auth[:6]) == 'basic ':
-- try: decoded=base64.decodestring(auth[6:])
-- except base64.binascii.Error: decoded=''
-- t = string.split(decoded, ':', 1)
-- if len(t) < 2:
-- name = 'Unknown (bad auth string)'
-- else:
-- name = t[0]
--
-- self.channel.server.logger.log (
-- self.channel.addr[0],
-- ' - %s [%s] "%s" %d %d "%s" "%s"\n' % (
-- name,
-- self.log_date_string (time.time()),
-- self.request,
-- self.reply_code,
-- bytes,
-- referer,
-- user_agent
-- )
-- )
--
-- from ZServer.medusa import http_server
-- http_server.http_request.log = log
--
- # Resolver and Logger, used by other servers
- if DNS_IP:
- rs = resolver.caching_resolver(DNS_IP)
-@@ -766,51 +668,11 @@
- # from another web server to ZServer, and would like the CGI
- # environment to reflect the CGI environment of the other web
- # server.
-- try:
-- del HTTP_ENV['HTTPS']
-- except KeyError:
-- pass
- zh = zhttp_handler(MODULE, '', HTTP_ENV)
- if FORCE_HTTP_CONNECTION_CLOSE:
- zh._force_connection_close = 1
- hs.install_handler(zh)
-
-- # HTTPS Server
-- if HTTPS_PORT:
-- ssl_ctx = SSL.Context('sslv23')
-- ssl_ctx.load_cert_chain('%s/server.pem' % INSTANCE_HOME)
-- ssl_ctx.load_verify_locations('%s/ca.pem' % INSTANCE_HOME)
-- ssl_ctx.load_client_CA('%s/ca.pem' % INSTANCE_HOME)
-- #ssl_ctx.set_allow_unknown_ca(1)
-- ssl_ctx.set_session_id_ctx(MODULE)
-- ssl_ctx.set_tmp_dh('%s/dh1024.pem' % INSTANCE_HOME)
-- if X509_REMOTE_USER:
-- ssl_ctx.set_verify(SSL.verify_peer|SSL.verify_fail_if_no_peer_cert, 10)
-- #ssl_ctx.set_verify(SSL.verify_peer, 10)
-- else:
-- ssl_ctx.set_verify(SSL.verify_none, 10)
-- if type(HTTPS_PORT) is type(0): HTTPS_PORT=((IP_ADDRESS, HTTPS_PORT),)
--
-- for address, port in HTTPS_PORT:
-- hss = zhttps_server(
-- ip=address,
-- port=port,
-- ssl_ctx=ssl_ctx,
-- resolver=rs,
-- logger_object=lg)
--
-- try:
-- del HTTPS_ENV['HTTP']
-- except KeyError:
-- pass
-- HTTPS_ENV['HTTPS']='ON'
--
-- if X509_REMOTE_USER:
-- zsh = zhttps_handler(MODULE, '', HTTPS_ENV)
-- else:
-- zsh = zhttps0_handler(MODULE, '', HTTPS_ENV)
-- hss.install_handler(zsh)
--
- # WebDAV source Server (runs HTTP, but munges request to return
- # 'manage_FTPget').
- if WEBDAV_SOURCE_PORT:
-@@ -854,34 +716,6 @@
- else:
- sys.WEBDAV_SOURCE_PORT_CLIENTS = None
-
-- # WebDAV-over-SSL source Server (runs HTTPS, but munges request to return
-- # 'manage_FTPget').
-- if WEBDAV_SSL_SOURCE_PORT:
-- ssl_ctx = SSL.Context('sslv23')
-- ssl_ctx.load_cert_chain('%s/server.pem' % INSTANCE_HOME)
-- ssl_ctx.load_verify_locations('%s/ca.pem' % INSTANCE_HOME)
-- ssl_ctx.load_client_CA('%s/ca.pem' % INSTANCE_HOME)
-- ssl_ctx.set_verify(SSL.verify_none, 10)
-- ssl_ctx.set_session_id_ctx(MODULE)
-- ssl_ctx.set_tmp_dh('%s/dh1024.pem' % INSTANCE_HOME)
-- if type(WEBDAV_SSL_SOURCE_PORT) is type(0):
-- WEBDAV_SSL_SOURCE_PORT=((IP_ADDRESS, WEBDAV_SSL_SOURCE_PORT),)
-- for address, port in WEBDAV_SSL_SOURCE_PORT:
-- hss = zhttps_server(
-- ip=address,
-- port=port,
-- ssl_ctx=ssl_ctx,
-- resolver=rs,
-- logger_object=lg)
--
-- try:
-- del HTTPS_ENV['HTTP']
-- except KeyError:
-- pass
-- HTTPS_ENV['HTTPS']='ON'
--
-- zsh = WebDAVSrcHandler(MODULE, '', HTTPS_ENV)
-- hss.install_handler(zsh)
-
- # FTP Server
- if FTP_PORT:
-@@ -1072,8 +906,6 @@
- sys.exit(0)
-
- # Start Medusa, Ye Hass!
--Rand.load_file('%s/randpool.dat' % INSTANCE_HOME, -1)
- sys.ZServerExitCode=0
- asyncore.loop()
--Rand.save_file('%s/randpool.dat' % INSTANCE_HOME)
- sys.exit(sys.ZServerExitCode)
diff --git a/demo/Zope27/INSTALL.txt b/demo/Zope27/INSTALL.txt
deleted file mode 100644
index b3728c5..0000000
--- a/demo/Zope27/INSTALL.txt
+++ /dev/null
@@ -1,200 +0,0 @@
-=========================================
- ZServerSSL for Zope 2.7.0b2
-=========================================
-
-:Author: Ng Pheng Siong
-:Id: $Id$
-:Date: $Date$
-:Web-Site: http://sandbox.rulemaker.net/ngps/zope/zssl/
-
-.. contents::
-
-
-Directories
------------------------
-
-This distribution is contained in ``m2crypto-0.12/demo/Zope27/``. Its
-directory structure assumes the following:
-
-- Zope 2.7.0b2 is installed in <install-dir>.
-- An instance has been created in <instance-home>.
-
-
-<install-dir>
------------------------
-
-The following files are to be copied to the corresponding directories
-in your <install-dir>:
-
-- install_dir/lib/python/ZServer/HTTPS_Server.py
-- install_dir/lib/python/ZServer/medusa/https_server.py
-
-The following patch files are to be applied to the corresponding
-directories in your <install-dir>:
-
-- install_dir/lib/python/ZServer/__init__.py.patch
-- install_dir/lib/python/ZServer/component.xml.patch
-- install_dir/lib/python/ZServer/datatypes.py.patch
-
-
-<instance-home>
------------------------
-
-The following files are to be copied to the corresponding directories
-in your <instance-home>:
-
-- instance_home/ssl/ca.pem
-- instance_home/ssl/server.pem
-- instance_home/ssl/dh1024.pem
-
-These are example files. For more information on them, consult the
-ZServerSSL HOWTO for Zope 2.6.
-
-The following patch files are to be applied to the corresponding
-directories in your <instance-home>:
-
-- instance_home/README.txt.patch
-- instance_home/etc/zope.conf.patch
-
-(Patching README.txt is optional.)
-
-There appears to be a bug in Zope 2.7.0b2, where INSTANCE_HOME in a
-running Zope points to <install-dir>, not <instance-home>. Workaround
-this with the following:
-
-::
-
- $ (cd <install-dir>; ln -s <instance-home>/ssl)
-
-
-Launch ZServerSSL
--------------------
-
-::
-
- $ <instance-home>/bin/runzope
-
-
-Testing
----------
-
-Below, we assume your Zope server is running on ``localhost``.
-
-
-HTTPS
-~~~~~~~
-
-This testing is done with Mozilla 1.1 on FreeBSD.
-
-1. With a browser, connect to https://localhost:8443/. Browse
- around. Check out your browser's HTTPS informational screens.
-
-2. Connect to https://localhost:8443/manage. Verify that you can
- access Zope's management functionality.
-
-
-WebDAV-over-HTTPS
-~~~~~~~~~~~~~~~~~~~
-
-This testing is done with Cadaver 0.21.0 on FreeBSD.
-
-::
-
- $ cadaver https://localhost:8443/
- WARNING: Untrusted server certificate presented:
- Issued to: M2Crypto, SG
- Issued by: M2Crypto, SG
- Do you wish to accept the certificate? (y/n) y
- Authentication required for Zope on server `localhost':
- Username: admin
- Password:
- dav:/> ls
- Listing collection `/': succeeded.
- Coll: Control_Panel 0 Sep 28 00:38
- Coll: temp_folder 0 Sep 28 17:30
- acl_users 0 Sep 28 00:38
- browser_id_manager 0 Sep 28 00:38
- error_log 0 Sep 28 00:38
- index_html 28 Sep 28 00:39
- session_data_manager 0 Sep 28 00:38
- standard_error_message 1189 Sep 28 00:39
- standard_html_footer 18 Sep 28 00:39
- standard_html_header 82 Sep 28 00:39
- standard_template.pt 282 Sep 28 00:39
- dav:/> quit
- Connection to `localhost' closed.
- $
-
-
-Python with M2Crypto
-~~~~~~~~~~~~~~~~~~~~~~
-
-This testing is done with M2Crypto 0.12 and Python 2.2.3 on FreeBSD.
-
-HTTPS
-```````
-
->>> from M2Crypto import Rand, SSL, m2urllib
->>> url = m2urllib.FancyURLopener()
->>> url.addheader('Connection', 'close')
->>> u = url.open('https://127.0.0.1:8443/')
-send: 'GET / HTTP/1.1\r\nHost: 127.0.0.1:8443\r\nAccept-Encoding: identity\r\nUser-agent: Python-urllib/1.15\r\nConnection: close\r\n\r\n'
-reply: 'HTTP/1.1 200 OK\r\n'
-header: Server: ZServerSSL/0.12
-header: Date: Sun, 28 Sep 2003 09:40:14 GMT
-header: Content-Length: 3055
-header: Etag:
-header: Content-Type: text/html
-header: Connection: close
->>> while 1:
-... data = u.read()
-... if not data: break
-... print data
-...
-
-::
-
- [blah blah blah]
-
- <p>
- Go directly to the <a href="/manage" target="_top">
- Zope Management Interface</a> if you'd like to start working with Zope
- right away. <strong>NOTE: Some versions of Microsoft Internet Explorer,
- (specifically IE 5.01 and early versions of IE 5.5) may have problems
- displaying Zope management pages. If you cannot view the management pages,
- try upgrading your IE installation to the latest release version, or use
- a different browser.</strong>
- </p>
- </li>
-
- <li>
- <p>
- Find out about <a href="http://www.zope.com/" target="_new">Zope
- Corporation</a>, the publishers of Zope.
- </p>
- </li>
-
- </ul>
-
- </body>
- </html>
-
->>> u.close()
->>>
-
-
-XMLRPC-over-HTTPS
-```````````````````
-
->>> from M2Crypto.m2xmlrpclib import Server, SSL_Transport
->>> zs = Server('https://127.0.0.1:8443/', SSL_Transport())
->>> print zs.propertyMap()
-[{'type': 'string', 'id': 'title', 'mode': 'w'}]
->>>
-
-
-Conclusion
-------------
-
-Yes, it works! ;-)
-
diff --git a/demo/Zope27/install_dir/lib/python/ZServer/HTTPS_Server.py b/demo/Zope27/install_dir/lib/python/ZServer/HTTPS_Server.py
deleted file mode 100644
index 49b6177..0000000
--- a/demo/Zope27/install_dir/lib/python/ZServer/HTTPS_Server.py
+++ /dev/null
@@ -1,187 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2000-2003, Ng Pheng Siong. All Rights Reserved.
-# This file is derived from Zope's ZServer/HTTPServer.py.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE
-#
-##############################################################################
-
-"""
-Medusa HTTPS server for Zope
-
-changes from Medusa's http_server:
-
- Request Threads -- Requests are processed by threads from a thread
- pool.
-
- Output Handling -- Output is pushed directly into the producer
- fifo by the request-handling thread. The HTTP server does not do
- any post-processing such as chunking.
-
- Pipelineable -- This is needed for protocols such as HTTP/1.1 in
- which mutiple requests come in on the same channel, before
- responses are sent back. When requests are pipelined, the client
- doesn't wait for the response before sending another request. The
- server must ensure that responses are sent back in the same order
- as requests are received.
-
-
-changes from Zope's HTTP server:
-
- Well, this is a *HTTPS* server :)
-
- X.509 certificate-based authentication -- When this is in force,
- zhttps_handler, a subclass of zhttp_handler, is installed. The
- https server is configured to request an X.509 certificate from
- the client. When the request reaches zhttps_handler, it sets
- REMOTE_USER to the client's subject distinguished name (DN) from
- the certificate. Zope's REMOTE_USER machinery takes care of the
- rest, e.g., in conjunction with the RemoteUserFolder product.
-
-"""
-
-import sys, time, types
-
-from PubCore import handle
-import asyncore
-from ZServer import CONNECTION_LIMIT, ZOPE_VERSION
-from HTTPServer import zhttp_handler
-from zLOG import register_subsystem
-
-from M2Crypto import SSL
-from medusa.https_server import https_server, https_channel
-from asyncore import dispatcher
-
-
-ZSERVER_SSL_VERSION='0.12'
-
-register_subsystem('ZServer HTTPS_Server')
-
-
-class zhttps0_handler(zhttp_handler):
- "zhttps0 handler - sets SSL request headers a la mod_ssl"
-
- def __init__ (self, module, uri_base=None, env=None):
- zhttp_handler.__init__(self, module, uri_base, env)
-
- def get_environment(self, request):
- env = zhttp_handler.get_environment(self, request)
- env['SSL_CIPHER'] = request.channel.get_cipher()
- return env
-
-
-class zhttps_handler(zhttps0_handler):
- "zhttps handler - sets REMOTE_USER to user's X.509 certificate Subject DN"
-
- def __init__ (self, module, uri_base=None, env=None):
- zhttps0_handler.__init__(self, module, uri_base, env)
-
- def get_environment(self, request):
- env = zhttps0_handler.get_environment(self, request)
- peer = request.channel.get_peer_cert()
- if peer is not None:
- env['REMOTE_USER'] = str(peer.get_subject())
- return env
-
-
-class zhttps_channel(https_channel):
- "https channel"
-
- closed=0
- zombie_timeout=100*60 # 100 minutes
-
- def __init__(self, server, conn, addr):
- https_channel.__init__(self, server, conn, addr)
- self.queue=[]
- self.working=0
- self.peer_found=0
-
- def push(self, producer, send=1):
- # this is thread-safe when send is false
- # note, that strings are not wrapped in
- # producers by default
- if self.closed:
- return
- self.producer_fifo.push(producer)
- if send: self.initiate_send()
-
- push_with_producer=push
-
- def work(self):
- "try to handle a request"
- if not self.working:
- if self.queue:
- self.working=1
- try: module_name, request, response=self.queue.pop(0)
- except: return
- handle(module_name, request, response)
-
- def close(self):
- self.closed=1
- while self.queue:
- self.queue.pop()
- if self.current_request is not None:
- self.current_request.channel=None # break circ refs
- self.current_request=None
- while self.producer_fifo:
- p=self.producer_fifo.first()
- if p is not None and type(p) != types.StringType:
- p.more() # free up resources held by producer
- self.producer_fifo.pop()
- self.del_channel()
- #self.socket.set_shutdown(SSL.SSL_SENT_SHUTDOWN|SSL.SSL_RECEIVED_SHUTDOWN)
- self.socket.close()
-
- def done(self):
- "Called when a publishing request is finished"
- self.working=0
- self.work()
-
- def kill_zombies(self):
- now = int (time.time())
- for channel in asyncore.socket_map.values():
- if channel.__class__ == self.__class__:
- if (now - channel.creation_time) > channel.zombie_timeout:
- channel.close()
-
-
-class zhttps_server(https_server):
- "https server"
-
- SERVER_IDENT='ZServerSSL/%s' % (ZSERVER_SSL_VERSION,)
-
- channel_class = zhttps_channel
- shutup = 0
-
- def __init__(self, ip, port, ssl_ctx, resolver=None, logger_object=None):
- self.shutup = 1
- https_server.__init__(self, ip, port, ssl_ctx, resolver, logger_object)
- self.ssl_ctx = ssl_ctx
- self.shutup = 0
- self.log_info('(%s) HTTPS server started at %s\n'
- '\tHostname: %s\n\tPort: %d' % (
- self.SERVER_IDENT,
- time.ctime(time.time()),
- self.server_name,
- self.server_port
- ))
-
- def log_info(self, message, type='info'):
- if self.shutup: return
- dispatcher.log_info(self, message, type)
-
- def readable(self):
- return self.accepting and \
- len(asyncore.socket_map) < CONNECTION_LIMIT
-
- def listen(self, num):
- # override asyncore limits for nt's listen queue size
- self.accepting = 1
- return self.socket.listen (num)
-
diff --git a/demo/Zope27/install_dir/lib/python/ZServer/__init__.py.patch b/demo/Zope27/install_dir/lib/python/ZServer/__init__.py.patch
deleted file mode 100644
index 0ba84b7..0000000
--- a/demo/Zope27/install_dir/lib/python/ZServer/__init__.py.patch
+++ /dev/null
@@ -1,10 +0,0 @@
---- __init__.py.org Sat Sep 27 20:23:00 2003
-+++ __init__.py Sun Oct 26 18:01:27 2003
-@@ -68,6 +68,7 @@
- import asyncore
- from medusa import resolver, logger
- from HTTPServer import zhttp_server, zhttp_handler
-+from HTTPS_Server import zhttps_server, zhttps0_handler, zhttps_handler
- from PCGIServer import PCGIServer
- from FCGIServer import FCGIServer
- from FTPServer import FTPServer
diff --git a/demo/Zope27/install_dir/lib/python/ZServer/component.xml.patch b/demo/Zope27/install_dir/lib/python/ZServer/component.xml.patch
deleted file mode 100644
index 364d91f..0000000
--- a/demo/Zope27/install_dir/lib/python/ZServer/component.xml.patch
+++ /dev/null
@@ -1,28 +0,0 @@
---- component.xml.org Sat Sep 27 20:21:22 2003
-+++ component.xml Sat Sep 27 21:11:26 2003
-@@ -21,6 +21,25 @@
- </key>
- </sectiontype>
-
-+ <sectiontype name="https-server"
-+ datatype=".HTTPS_ServerFactory"
-+ implements="ZServer.server">
-+ <key name="address" datatype="inet-address"/>
-+ <key name="force-connection-close" datatype="boolean" default="off"/>
-+ <key name="webdav-source-clients">
-+ <description>
-+ Regular expression used to identify clients who should
-+ receive WebDAV source responses to GET requests.
-+ </description>
-+ </key>
-+ <key name="x509-remote-user" datatype="boolean" default="on">
-+ <description>
-+ If "on", request client X.509 certificate and set REMOTE_USER to
-+ said certificate's Subject Distinguished Name.
-+ </description>
-+ </key>
-+ </sectiontype>
-+
- <sectiontype name="webdav-source-server"
- datatype=".WebDAVSourceServerFactory"
- implements="ZServer.server">
diff --git a/demo/Zope27/install_dir/lib/python/ZServer/datatypes.py.patch b/demo/Zope27/install_dir/lib/python/ZServer/datatypes.py.patch
deleted file mode 100644
index b2ad9c8..0000000
--- a/demo/Zope27/install_dir/lib/python/ZServer/datatypes.py.patch
+++ /dev/null
@@ -1,59 +0,0 @@
---- datatypes.py.org Sat Sep 27 20:21:15 2003
-+++ datatypes.py Sun Oct 26 21:19:58 2003
-@@ -72,7 +72,56 @@
-
- def createHandler(self):
- from ZServer import HTTPServer
-+ try:
-+ del self.cgienv['HTTPS']
-+ except KeyError:
-+ pass
- return HTTPServer.zhttp_handler(self.module, '', self.cgienv)
-+
-+
-+class HTTPS_ServerFactory(HTTPServerFactory):
-+ def __init__(self, section):
-+ HTTPServerFactory.__init__(self, section)
-+ self.x509_remote_user = section.x509_remote_user
-+ from M2Crypto import Rand, SSL
-+ Rand.load_file('%s/randpool.dat' % INSTANCE_HOME, -1)
-+ ssl_ctx = SSL.Context('sslv23')
-+ ssl_ctx.load_cert_chain('%s/ssl/server.pem' % INSTANCE_HOME)
-+ ssl_ctx.load_verify_locations('%s/ssl/ca.pem' % INSTANCE_HOME,'')
-+ ssl_ctx.load_client_CA('%s/ssl/ca.pem' % INSTANCE_HOME)
-+ ssl_ctx.set_session_id_ctx('Zope 2.7.0b2')
-+ ssl_ctx.set_tmp_dh('%s/ssl/dh1024.pem' % INSTANCE_HOME)
-+ if self.x509_remote_user:
-+ ssl_ctx.set_verify(SSL.verify_peer, 10)
-+ else:
-+ ssl_ctx.set_verify(SSL.verify_none, 10)
-+ self.ssl_ctx = ssl_ctx
-+
-+ def create(self):
-+ from ZServer import HTTPS_Server
-+ from ZServer.AccessLogger import access_logger
-+ handler = self.createHandler()
-+ handler._force_connection_close = self.force_connection_close
-+ if self.webdav_source_clients:
-+ handler.set_webdav_source_clients(self.webdav_source_clients)
-+ server = HTTPS_Server.zhttps_server(ip=self.host, port=self.port,
-+ ssl_ctx=self.ssl_ctx,
-+ resolver=self.dnsresolver,
-+ logger_object=access_logger)
-+ server.install_handler(handler)
-+ return server
-+
-+ def createHandler(self):
-+ from ZServer import HTTPS_Server
-+ try:
-+ del self.cgienv['HTTP']
-+ except KeyError:
-+ pass
-+ self.cgienv['HTTPS'] = 'ON'
-+ if self.x509_remote_user:
-+ return HTTPS_Server.zhttps_handler(self.module, '', self.cgienv)
-+ else:
-+ return HTTPS_Server.zhttps0_handler(self.module, '', self.cgienv)
-
-
- class WebDAVSourceServerFactory(HTTPServerFactory):
diff --git a/demo/Zope27/install_dir/lib/python/ZServer/medusa/https_server.py b/demo/Zope27/install_dir/lib/python/ZServer/medusa/https_server.py
deleted file mode 100644
index 84a0197..0000000
--- a/demo/Zope27/install_dir/lib/python/ZServer/medusa/https_server.py
+++ /dev/null
@@ -1,83 +0,0 @@
-#!/usr/bin/env python
-
-"""A https server built on Medusa's http_server.
-
-Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
-
-import asynchat, asyncore, http_server, socket, sys
-from M2Crypto import SSL, version
-
-VERSION_STRING=version
-
-class https_channel(http_server.http_channel):
-
- ac_in_buffer_size = 1 << 16
-
- def __init__(self, server, conn, addr):
- http_server.http_channel.__init__(self, server, conn, addr)
-
- def send(self, data):
- try:
- result = self.socket._write_nbio(data)
- if result <= 0:
- return 0
- else:
- self.server.bytes_out.increment(result)
- return result
- except SSL.SSLError, why:
- self.close()
- self.log_info('send: closing channel %s %s' % (repr(self), why))
- return 0
-
- def recv(self, buffer_size):
- try:
- result = self.socket._read_nbio(buffer_size)
- if result is None:
- return ''
- elif result == '':
- self.close()
- return ''
- else:
- self.server.bytes_in.increment(len(result))
- return result
- except SSL.SSLError, why:
- self.close()
- self.log_info('recv: closing channel %s %s' % (repr(self), why))
- return ''
-
-
-class https_server(http_server.http_server):
-
- SERVER_IDENT='M2Crypto HTTPS Server (v%s)' % VERSION_STRING
-
- channel_class=https_channel
-
- def __init__(self, ip, port, ssl_ctx, resolver=None, logger_object=None):
- http_server.http_server.__init__(self, ip, port, resolver, logger_object)
- self.ssl_ctx=ssl_ctx
-
- def handle_accept(self):
- # Cribbed from http_server.
- self.total_clients.increment()
- try:
- conn, addr = self.accept()
- except socket.error:
- # linux: on rare occasions we get a bogus socket back from
- # accept. socketmodule.c:makesockaddr complains that the
- # address family is unknown. We don't want the whole server
- # to shut down because of this.
- sys.stderr.write ('warning: server accept() threw an exception\n')
- return
-
- # Turn the vanilla socket into an SSL connection.
- try:
- ssl_conn=SSL.Connection(self.ssl_ctx, conn)
- ssl_conn._setup_ssl(addr)
- ssl_conn.accept_ssl()
- self.channel_class(self, ssl_conn, addr)
- except SSL.SSLError:
- pass
-
- def writeable(self):
- return 0
-
diff --git a/demo/Zope27/instance_home/README.txt.patch b/demo/Zope27/instance_home/README.txt.patch
deleted file mode 100644
index 0d39005..0000000
--- a/demo/Zope27/instance_home/README.txt.patch
+++ /dev/null
@@ -1,7 +0,0 @@
---- README.txt.org Sat Sep 27 20:56:11 2003
-+++ README.txt Sat Sep 27 20:56:44 2003
-@@ -7,3 +7,4 @@
- log/ Log files
- Products/ Installed products specific to the instance
- var/ Run-time data files, including the object database
-+ ssl/ ZServerSSL data files
diff --git a/demo/Zope27/instance_home/etc/zope.conf.patch b/demo/Zope27/instance_home/etc/zope.conf.patch
deleted file mode 100644
index cc9b093..0000000
--- a/demo/Zope27/instance_home/etc/zope.conf.patch
+++ /dev/null
@@ -1,16 +0,0 @@
---- zope.conf.org Sat Sep 27 21:03:22 2003
-+++ zope.conf Sat Sep 27 21:05:08 2003
-@@ -650,6 +650,13 @@
- # force-connection-close on
- </http-server>
-
-+<https-server>
-+ # valid keys are "address", "force-connection-close" and "x509-remote-user"
-+ address 8443
-+ # force-connection-close on
-+ x509-remote-user on
-+</https-server>
-+
- <ftp-server>
- # valid key is "address"
- address 8021
diff --git a/demo/Zope27/instance_home/ssl/ca.pem b/demo/Zope27/instance_home/ssl/ca.pem
deleted file mode 100644
index b7c84a1..0000000
--- a/demo/Zope27/instance_home/ssl/ca.pem
+++ /dev/null
@@ -1,20 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDWTCCAsKgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBgDELMAkGA1UEBhMCU0cx
-ETAPBgNVBAoTCE0yQ3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UE
-AxMbTTJDcnlwdG8gQ2VydGlmaWNhdGUgTWFzdGVyMSIwIAYJKoZIhvcNAQkBFhNu
-Z3BzQG5ldG1lbWV0aWMuY29tMB4XDTAxMTIxNTA1NTU0NloXDTA0MTIxNDA1NTU0
-NlowgYAxCzAJBgNVBAYTAlNHMREwDwYDVQQKEwhNMkNyeXB0bzEUMBIGA1UECxML
-TTJDcnlwdG8gQ0ExJDAiBgNVBAMTG00yQ3J5cHRvIENlcnRpZmljYXRlIE1hc3Rl
-cjEiMCAGCSqGSIb3DQEJARYTbmdwc0BuZXRtZW1ldGljLmNvbTCBnzANBgkqhkiG
-9w0BAQEFAAOBjQAwgYkCgYEAx8soJbS719LHK62VVVIQeC3oW0HvFArwPnA0LuEK
-q+LaqMOJg1rS7hvFdX03diV+XJw7cC0iECZYJNG4ii1xbY6KRmufkInaAwm54E3N
-e+YYVocaqUkcN6xVf6fwnLfPXbpFS/K2Umg11ObKMmi80JmiIdjcjRRCQZC7g1hf
-q+kCAwEAAaOB4DCB3TAdBgNVHQ4EFgQU6/qcBzEtQphfXLhiOHbt2KqBwMIwga0G
-A1UdIwSBpTCBooAU6/qcBzEtQphfXLhiOHbt2KqBwMKhgYakgYMwgYAxCzAJBgNV
-BAYTAlNHMREwDwYDVQQKEwhNMkNyeXB0bzEUMBIGA1UECxMLTTJDcnlwdG8gQ0Ex
-JDAiBgNVBAMTG00yQ3J5cHRvIENlcnRpZmljYXRlIE1hc3RlcjEiMCAGCSqGSIb3
-DQEJARYTbmdwc0BuZXRtZW1ldGljLmNvbYIBADAMBgNVHRMEBTADAQH/MA0GCSqG
-SIb3DQEBBAUAA4GBAD+I14GuS5vJmyv1k7mUMbAicsWRHZ+zrGOq9L/L2LsA+lKQ
-dAzEZE2+Zv8LBPJVltbJJhcFNJS/ZMAjEm4xlJuCpvXVMxd/M5AM29aqekWlIK7J
-vsdDL8IuzpRkMniUiNKPhmB6IPIOslvUKx6QofcE0wDh6pg4VvIbCjkpZ7gf
------END CERTIFICATE-----
diff --git a/demo/Zope27/instance_home/ssl/dh1024.pem b/demo/Zope27/instance_home/ssl/dh1024.pem
deleted file mode 100644
index 81d43f6..0000000
--- a/demo/Zope27/instance_home/ssl/dh1024.pem
+++ /dev/null
@@ -1,5 +0,0 @@
------BEGIN DH PARAMETERS-----
-MIGHAoGBAJf2QmHKtQXdKCjhPx1ottPb0PMTBH9A6FbaWMsTuKG/K3g6TG1Z1fkq
-/Gz/PWk/eLI9TzFgqVAuPvr3q14a1aZeVUMTgo2oO5/y2UHe6VaJ+trqCTat3xlx
-/mNbIK9HA2RgPC3gWfVLZQrY+gz3ASHHR5nXWHEyvpuZm7m3h+irAgEC
------END DH PARAMETERS-----
diff --git a/demo/Zope27/instance_home/ssl/server.pem b/demo/Zope27/instance_home/ssl/server.pem
deleted file mode 100644
index 1ee9282..0000000
--- a/demo/Zope27/instance_home/ssl/server.pem
+++ /dev/null
@@ -1,36 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDYjCCAsugAwIBAgIBBDANBgkqhkiG9w0BAQQFADCBgDELMAkGA1UEBhMCU0cx
-ETAPBgNVBAoTCE0yQ3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UE
-AxMbTTJDcnlwdG8gQ2VydGlmaWNhdGUgTWFzdGVyMSIwIAYJKoZIhvcNAQkBFhNu
-Z3BzQG5ldG1lbWV0aWMuY29tMB4XDTAzMDYyMjEzMzAxNFoXDTA0MDYyMTEzMzAx
-NFowXTELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRIwEAYDVQQDEwls
-b2NhbGhvc3QxJzAlBgkqhkiG9w0BCQEWGGFkbWluQHNlcnZlci5leGFtcGxlLmRv
-bTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA37aKGZtFicl8xXXTLJ8/JD7c
-kd3t/teCX9i61lpaDQCKBoVrrursIvZihemMKI9g/u/+BLqt5g8mBdgUdYz0txc8
-KEbV2hj+wwOX4H3XwD0Y+DysXiNHq7/tFdmzSVHoLxpY4zYzXbxQ/p049wvIyPRp
-/y3omcnx/TEUhkn+JmkCAwEAAaOCAQwwggEIMAkGA1UdEwQCMAAwLAYJYIZIAYb4
-QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBTB
-H/mUYlww24mJlSxEtGdlwojO9zCBrQYDVR0jBIGlMIGigBTr+pwHMS1CmF9cuGI4
-du3YqoHAwqGBhqSBgzCBgDELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRv
-MRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UEAxMbTTJDcnlwdG8gQ2VydGlm
-aWNhdGUgTWFzdGVyMSIwIAYJKoZIhvcNAQkBFhNuZ3BzQG5ldG1lbWV0aWMuY29t
-ggEAMA0GCSqGSIb3DQEBBAUAA4GBAAvl6v0s3eFeGP4iAcrfysuK7jzFKhjDYuOy
-lVS3u33bZNLnMpM6OSEM9yPh4WpFCVHf+nYwC71pk4ilsLVXjKxymm2lNGcxLVuW
-iydFz4Ly9nmN7Ja9ygYT39dGAFP/wN7ELTpsbul8VfmqhNg9y81d8i/A1tK3AGA8
-0QkPQNdP
------END CERTIFICATE-----
------BEGIN RSA PRIVATE KEY-----
-MIICXAIBAAKBgQDftooZm0WJyXzFddMsnz8kPtyR3e3+14Jf2LrWWloNAIoGhWuu
-6uwi9mKF6Ywoj2D+7/4Euq3mDyYF2BR1jPS3FzwoRtXaGP7DA5fgfdfAPRj4PKxe
-I0erv+0V2bNJUegvGljjNjNdvFD+nTj3C8jI9Gn/LeiZyfH9MRSGSf4maQIDAQAB
-AoGAHpeVtv62uarl9xKvuBBm0AwQmZnhq9HIsFaw5hMg8Vo7hbzFBvx1IirTOkC/
-u+QvfW1QLVFh6m3z4ySzV4fZBtcd6F9SbSrZ0xsxIUB2NOSa1RGgiaP61bJnMMM1
-xM3O9iwM5GZc3Gqy08QOCpDl0772VJ+9Gz3FA88mrc6rHQkCQQDz6RIatFjT28n8
-1vy0nHwwZz2oXTpe/pyZPwoKj8zVsmrKhKwOw7l8ArxjP8zoHOE7AQBCXYDMNoFp
-IAF0yuqrAkEA6s0wMEdPpQeb0XHAfccyJQoeULxHdVFoz1wWmGSOm4YmQtR8/QJx
-luEgfpeRkzxBKt5Ls3MEkheIOw7xV24zOwJAMz+DaE0AZPNHS3K4ghJnHZxzng6I
-lzEUIjbWm0V/ml70hTy/EhMZw+6nOotLOHHo+QbK0SboSwAgzL/Gzo1cJQJANqpS
-38qadleRJXAQWrg3qnvyluVe1aeAeVZ9RDmVIgxXeBO0jcs12uTLBe4PzHGo0mwy
-v7K1i7XC180gzzQu5QJBAOxITT9RoWSSozPvnirHd37sn+RsrNYkV07NAa80M20Z
-DkBPHeMVkNgigrQ6L6vWmbRDGQbGcMplAxnI5ppKCoU=
------END RSA PRIVATE KEY-----
diff --git a/demo/ZopeX3/INSTALL.txt b/demo/ZopeX3/INSTALL.txt
deleted file mode 100644
index 67adbc8..0000000
--- a/demo/ZopeX3/INSTALL.txt
+++ /dev/null
@@ -1,73 +0,0 @@
-=========================================
- ZServerSSL for ZopeX3.0.0
-=========================================
-
-:Author: Ng Pheng Siong
-:Id: $Id: INSTALL.txt 354 2006-02-25 00:13:15Z heikki $
-:Date: $Date$
-:Web-Site: http://sandbox.rulemaker.net/ngps/zope/zssl/
-
-.. contents::
-
-
-Directories
------------------------
-
-Directory structure assumes the following:
-
-- ZopeX3.0.0 is installed in <install-dir>.
-- An instance has been created in <instance-home>.
-
-
-<install-dir>
------------------------
-
-The following files are to be copied to the corresponding directories
-in your <install-dir>:
-
-- install_dir/lib/python/zope/server/http/https_server.py
-- install_dir/lib/python/zope/server/http/https_serverchannel.py
-- install_dir/lib/python/zope/server/http/publisherhttps_server.py
-- install_dir/lib/python/zope/app/server/https.py
-
-
-<instance-home>
------------------------
-
-The following files are to be copied to the corresponding directories
-in your <instance-home>:
-
-- instance_home/ssl/ca.pem
-- instance_home/ssl/server.pem
-- instance_home/ssl/dh1024.pem
-
-These are example files. For more information on them, consult the
-ZServerSSL HOWTO for Zope 2.6.
-
-The following patch files are to be applied to the corresponding
-directories:
-
-- install_dir/lib/python/zope/app/server/configure.zcml.patch
-- instance_home/etc/zope.conf.patch
-
-
-Launch ZServerSSL
--------------------
-
-::
-
- $ <instance-home>/bin/runzope
-
-
-Testing
----------
-
-This section TDB. I have tested ZServerSSL for Zope 3 with 'openssl
-s_client' and 'openssl s_client -nbio' successfully.
-
-
-Conclusion
-------------
-
-Yes, it works! ;-)
-
diff --git a/demo/ZopeX3/install_dir/lib/python/zope/app/server/configure.zcml.patch b/demo/ZopeX3/install_dir/lib/python/zope/app/server/configure.zcml.patch
deleted file mode 100644
index 8d8f031..0000000
--- a/demo/ZopeX3/install_dir/lib/python/zope/app/server/configure.zcml.patch
+++ /dev/null
@@ -1,28 +0,0 @@
---- configure.zcml.org Mon Sep 27 16:10:47 2004
-+++ configure.zcml Mon Sep 27 16:11:42 2004
-@@ -5,6 +5,12 @@
- provides="zope.app.applicationcontrol.interfaces.IServerControl" />
-
- <utility
-+ name="HTTPS"
-+ component=".https.https"
-+ provides=".servertype.IServerType"
-+ />
-+
-+ <utility
- name="HTTP"
- component=".http.http"
- provides=".servertype.IServerType"
-@@ -13,6 +19,12 @@
- <utility
- name="PostmortemDebuggingHTTP"
- component=".http.pmhttp"
-+ provides=".servertype.IServerType"
-+ />
-+
-+ <utility
-+ name="PostmortemDebuggingHTTPS"
-+ component=".https.pmhttps"
- provides=".servertype.IServerType"
- />
-
diff --git a/demo/ZopeX3/install_dir/lib/python/zope/app/server/https.py b/demo/ZopeX3/install_dir/lib/python/zope/app/server/https.py
deleted file mode 100644
index 2278f3e..0000000
--- a/demo/ZopeX3/install_dir/lib/python/zope/app/server/https.py
+++ /dev/null
@@ -1,28 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2004, Ng Pheng Siong.
-# All Rights Reserved.
-#
-# XXX license TBD; should be Zope 3's ZPL, I just haven't read thru that.
-#
-##############################################################################
-"""HTTPS server factories
-
-$Id: https.py 240 2004-10-02 12:40:14Z ngps $
-"""
-
-from zope.app.publication.httpfactory import HTTPPublicationRequestFactory
-from zope.app.server.servertype import ServerType
-from zope.server.http.commonaccesslogger import CommonAccessLogger
-from zope.server.http.publisherhttps_server import PMDBHTTPS_Server
-from zope.server.http.publisherhttps_server import PublisherHTTPS_Server
-
-https = ServerType(PublisherHTTPS_Server,
- HTTPPublicationRequestFactory,
- CommonAccessLogger,
- 8443, True)
-
-pmhttps = ServerType(PMDBHTTPS_Server,
- HTTPPublicationRequestFactory,
- CommonAccessLogger,
- 8376, True)
diff --git a/demo/ZopeX3/install_dir/lib/python/zope/server/http/https_server.py b/demo/ZopeX3/install_dir/lib/python/zope/server/http/https_server.py
deleted file mode 100644
index 9e1eb3e..0000000
--- a/demo/ZopeX3/install_dir/lib/python/zope/server/http/https_server.py
+++ /dev/null
@@ -1,104 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2004, Ng Pheng Siong.
-# All Rights Reserved.
-#
-# XXX license TBD; should be Zope 3's ZPL, I just haven't read thru that.
-#
-##############################################################################
-"""HTTPS Server
-
-This is a HTTPS version of HTTPServer.
-
-$Id: https_server.py 240 2004-10-02 12:40:14Z ngps $
-"""
-
-import asyncore, logging, os.path
-
-from zope.server.http.httpserver import HTTPServer
-from zope.server.http.https_serverchannel import HTTPS_ServerChannel
-from M2Crypto import SSL, version
-
-
-# 2004-09-27, ngps:
-# 'sslv2' or 'sslv23' interoperates with Firefox and IE.
-# 'sslv3' or 'tlsv1' doesn't.
-def make_ssl_context(dir, ssl_proto='sslv23'):
- sslctx = SSL.Context(ssl_proto)
- sslctx.load_cert(os.path.join(dir, 'server.pem'))
- sslctx.load_verify_locations(os.path.join(dir, 'ca.pem'))
- sslctx.load_client_CA(os.path.join(dir, 'ca.pem'))
- sslctx.set_verify(SSL.verify_none, 10)
- sslctx.set_session_id_ctx('someblahblahthing')
- sslctx.set_tmp_dh(os.path.join(dir, 'dh1024.pem'))
- #sslctx.set_info_callback() # debugging only; not thread-safe
- return sslctx
-
-
-class HTTPS_Server(HTTPServer):
- """This is a generic HTTPS Server."""
-
- channel_class = HTTPS_ServerChannel
- SERVER_IDENT = 'zope.server.zserverssl_https'
-
- def __init__(self, ip, port, ssl_ctx=None, task_dispatcher=None, adj=None, start=1,
- hit_log=None, verbose=0):
- HTTPServer.__init__(self, ip, port, task_dispatcher, adj, start, hit_log, verbose)
- if ssl_ctx is None:
- self.ssl_ctx = make_ssl_context(os.path.realpath(__file__))
- else:
- self.ssl_ctx = ssl_ctx
-
- def executeRequest(self, task):
- """Execute an HTTP request."""
- # This is a default implementation, meant to be overridden.
- body = "The HTTPS server is running!\r\n" * 10
- task.response_headers['Content-Type'] = 'text/plain'
- task.response_headers['Content-Length'] = str(len(body))
- task.write(body)
-
- def handle_accept(self):
- """See zope.server.interfaces.IDispatcherEventHandler"""
- try:
- v = self.accept()
- if v is None:
- return
- conn, addr = v
- except socket.error:
- # Linux: On rare occasions we get a bogus socket back from
- # accept. socketmodule.c:makesockaddr complains that the
- # address family is unknown. We don't want the whole server
- # to shut down because of this.
- if self.adj.log_socket_errors:
- self.log_info ('warning: server accept() threw an exception',
- 'warning')
- return
- for (level, optname, value) in self.adj.socket_options:
- conn.setsockopt(level, optname, value)
- # Turn the vanilla socket into an SSL connection.
- try:
- ssl_conn = SSL.Connection(self.ssl_ctx, conn)
- ssl_conn._setup_ssl(addr)
- ssl_conn.accept_ssl()
- self.channel_class(self, ssl_conn, addr, self.adj)
- except SSL.SSLError, why:
- self.log_info('accept: cannot make SSL connection %s' % (why,), 'warning')
- pass
-
-
-
-if __name__ == '__main__':
-
- from zope.server.taskthreads import ThreadedTaskDispatcher
- td = ThreadedTaskDispatcher()
- td.setThreadCount(4)
- HTTPS_Server('', 8443, ssl_ctx=None, task_dispatcher=td, verbose=1)
-
- try:
- import asyncore
- while 1:
- asyncore.poll(5)
-
- except KeyboardInterrupt:
- print 'shutting down...'
- td.shutdown()
diff --git a/demo/ZopeX3/install_dir/lib/python/zope/server/http/https_serverchannel.py b/demo/ZopeX3/install_dir/lib/python/zope/server/http/https_serverchannel.py
deleted file mode 100644
index c33a84d..0000000
--- a/demo/ZopeX3/install_dir/lib/python/zope/server/http/https_serverchannel.py
+++ /dev/null
@@ -1,55 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2004, Ng Pheng Siong.
-# All Rights Reserved.
-#
-# XXX license TBD; should be Zope 3's ZPL, I just haven't read thru that.
-#
-##############################################################################
-"""HTTPS Server Channel
-
-$Id: https_serverchannel.py 240 2004-10-02 12:40:14Z ngps $
-"""
-from zope.server.serverchannelbase import ServerChannelBase
-from zope.server.http.httptask import HTTPTask
-from zope.server.http.httprequestparser import HTTPRequestParser
-from zope.server.http.httpserverchannel import HTTPServerChannel
-from M2Crypto import SSL
-
-
-class HTTPS_ServerChannel(HTTPServerChannel):
- """HTTPS-specific Server Channel"""
-
- task_class = HTTPTask
- parser_class = HTTPRequestParser
-
- def send(self, data):
- try:
- result = self.socket._write_nbio(data)
- if result <= 0:
- return 0
- else:
- #self.server.bytes_out.increment(result)
- return result
- except SSL.SSLError, why:
- self.close()
- self.log_info('send: closing channel %s %s' % (repr(self), why), 'warning')
- return 0
-
- def recv(self, buffer_size):
- try:
- result = self.socket._read_nbio(buffer_size)
- if result is None:
- return ''
- elif result == '':
- self.close()
- return ''
- else:
- #self.server.bytes_in.increment(len(result))
- return result
- except SSL.SSLError, why:
- self.close()
- self.log_info('recv: closing channel %s %s' % (repr(self), why), 'warning')
- return ''
-
-
diff --git a/demo/ZopeX3/install_dir/lib/python/zope/server/http/publisherhttps_server.py b/demo/ZopeX3/install_dir/lib/python/zope/server/http/publisherhttps_server.py
deleted file mode 100644
index aa8738d..0000000
--- a/demo/ZopeX3/install_dir/lib/python/zope/server/http/publisherhttps_server.py
+++ /dev/null
@@ -1,83 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2004, Ng Pheng Siong.
-# All Rights Reserved.
-#
-# XXX license TBD; should be Zope 3's ZPL, I just haven't read thru that.
-#
-##############################################################################
-"""HTTPS Server that uses the Zope Publisher for executing a task.
-
-$Id: publisherhttps_server.py 240 2004-10-02 12:40:14Z ngps $
-"""
-import os.path, sys
-from zope.server.http.https_server import HTTPS_Server, make_ssl_context
-from zope.publisher.publish import publish
-
-
-def get_instance_ssldir():
- # This is real cheesy: It seems Zope3 doesn't have convenient
- # programmatic access to INSTANCE_HOME. This code relies on zopectl
- # setting the first entry of PYTHONPATH to $INSTANCE_HOME/lib/python.
- return os.path.join(os.path.dirname(os.path.dirname(sys.path[0])), 'ssl')
-
-
-class PublisherHTTPS_Server(HTTPS_Server):
- """Zope Publisher-specific HTTPS Server"""
-
- def __init__(self, request_factory, sub_protocol=None, *args, **kw):
-
- # The common HTTP
- self.request_factory = request_factory
-
- # An HTTP server is not limited to serving up HTML; it can be
- # used for other protocols, like XML-RPC, SOAP and so as well
- # Here we just allow the logger to output the sub-protocol type.
- if sub_protocol:
- self.SERVER_IDENT += ' (%s)' %str(sub_protocol)
-
- kw['ssl_ctx'] = make_ssl_context(get_instance_ssldir())
- HTTPS_Server.__init__(self, *args, **kw)
-
- def executeRequest(self, task):
- """Overrides HTTPServer.executeRequest()."""
- env = task.getCGIEnvironment()
- env['HTTPS'] = 'ON'
- try:
- del env['HTTP']
- except KeyError:
- pass
- instream = task.request_data.getBodyStream()
-
- request = self.request_factory(instream, task, env)
- response = request.response
- response.setHeaderOutput(task)
- response.setHTTPTransaction(task)
- publish(request)
-
-
-class PMDBHTTPS_Server(PublisherHTTPS_Server):
- """Enter the post-mortem debugger when there's an error"""
-
- def executeRequest(self, task):
- """Overrides HTTPServer.executeRequest()."""
- env = task.getCGIEnvironment()
- env['HTTPS'] = 'ON'
- try:
- del env['HTTP']
- except KeyError:
- pass
- instream = task.request_data.getBodyStream()
-
- request = self.request_factory(instream, task, env)
- response = request.response
- response.setHeaderOutput(task)
- try:
- publish(request, handle_errors=False)
- except:
- import sys, pdb
- print "%s:" % sys.exc_info()[0]
- print sys.exc_info()[1]
- pdb.post_mortem(sys.exc_info()[2])
- raise
-
diff --git a/demo/ZopeX3/instance_home/etc/zope.conf.patch b/demo/ZopeX3/instance_home/etc/zope.conf.patch
deleted file mode 100644
index f281246..0000000
--- a/demo/ZopeX3/instance_home/etc/zope.conf.patch
+++ /dev/null
@@ -1,26 +0,0 @@
---- zope.conf.org Tue Sep 28 09:49:02 2004
-+++ zope.conf Tue Sep 28 09:49:27 2004
-@@ -20,6 +20,11 @@
- address 8080
- </server>
-
-+<server>
-+ type HTTPS
-+ address 8443
-+</server>
-+
- # For debugging purposes, you can use this publisher instead/as well
- # (obviously if it's as well, use a different port number). If there's
- # an exception, Zope will drop into pdb at the point of the exception.
-@@ -27,6 +32,11 @@
- #<server>
- # type PostmortemDebuggingHTTP
- # address 8080
-+#</server>
-+#
-+#<server>
-+# type PostmortemDebuggingHTTPS
-+# address 8443
- #</server>
-
- <server>
diff --git a/demo/ZopeX3/instance_home/ssl/ca.pem b/demo/ZopeX3/instance_home/ssl/ca.pem
deleted file mode 100644
index b7c84a1..0000000
--- a/demo/ZopeX3/instance_home/ssl/ca.pem
+++ /dev/null
@@ -1,20 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDWTCCAsKgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBgDELMAkGA1UEBhMCU0cx
-ETAPBgNVBAoTCE0yQ3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UE
-AxMbTTJDcnlwdG8gQ2VydGlmaWNhdGUgTWFzdGVyMSIwIAYJKoZIhvcNAQkBFhNu
-Z3BzQG5ldG1lbWV0aWMuY29tMB4XDTAxMTIxNTA1NTU0NloXDTA0MTIxNDA1NTU0
-NlowgYAxCzAJBgNVBAYTAlNHMREwDwYDVQQKEwhNMkNyeXB0bzEUMBIGA1UECxML
-TTJDcnlwdG8gQ0ExJDAiBgNVBAMTG00yQ3J5cHRvIENlcnRpZmljYXRlIE1hc3Rl
-cjEiMCAGCSqGSIb3DQEJARYTbmdwc0BuZXRtZW1ldGljLmNvbTCBnzANBgkqhkiG
-9w0BAQEFAAOBjQAwgYkCgYEAx8soJbS719LHK62VVVIQeC3oW0HvFArwPnA0LuEK
-q+LaqMOJg1rS7hvFdX03diV+XJw7cC0iECZYJNG4ii1xbY6KRmufkInaAwm54E3N
-e+YYVocaqUkcN6xVf6fwnLfPXbpFS/K2Umg11ObKMmi80JmiIdjcjRRCQZC7g1hf
-q+kCAwEAAaOB4DCB3TAdBgNVHQ4EFgQU6/qcBzEtQphfXLhiOHbt2KqBwMIwga0G
-A1UdIwSBpTCBooAU6/qcBzEtQphfXLhiOHbt2KqBwMKhgYakgYMwgYAxCzAJBgNV
-BAYTAlNHMREwDwYDVQQKEwhNMkNyeXB0bzEUMBIGA1UECxMLTTJDcnlwdG8gQ0Ex
-JDAiBgNVBAMTG00yQ3J5cHRvIENlcnRpZmljYXRlIE1hc3RlcjEiMCAGCSqGSIb3
-DQEJARYTbmdwc0BuZXRtZW1ldGljLmNvbYIBADAMBgNVHRMEBTADAQH/MA0GCSqG
-SIb3DQEBBAUAA4GBAD+I14GuS5vJmyv1k7mUMbAicsWRHZ+zrGOq9L/L2LsA+lKQ
-dAzEZE2+Zv8LBPJVltbJJhcFNJS/ZMAjEm4xlJuCpvXVMxd/M5AM29aqekWlIK7J
-vsdDL8IuzpRkMniUiNKPhmB6IPIOslvUKx6QofcE0wDh6pg4VvIbCjkpZ7gf
------END CERTIFICATE-----
diff --git a/demo/ZopeX3/instance_home/ssl/dh1024.pem b/demo/ZopeX3/instance_home/ssl/dh1024.pem
deleted file mode 100644
index 81d43f6..0000000
--- a/demo/ZopeX3/instance_home/ssl/dh1024.pem
+++ /dev/null
@@ -1,5 +0,0 @@
------BEGIN DH PARAMETERS-----
-MIGHAoGBAJf2QmHKtQXdKCjhPx1ottPb0PMTBH9A6FbaWMsTuKG/K3g6TG1Z1fkq
-/Gz/PWk/eLI9TzFgqVAuPvr3q14a1aZeVUMTgo2oO5/y2UHe6VaJ+trqCTat3xlx
-/mNbIK9HA2RgPC3gWfVLZQrY+gz3ASHHR5nXWHEyvpuZm7m3h+irAgEC
------END DH PARAMETERS-----
diff --git a/demo/ZopeX3/instance_home/ssl/server.pem b/demo/ZopeX3/instance_home/ssl/server.pem
deleted file mode 100644
index 1ee9282..0000000
--- a/demo/ZopeX3/instance_home/ssl/server.pem
+++ /dev/null
@@ -1,36 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDYjCCAsugAwIBAgIBBDANBgkqhkiG9w0BAQQFADCBgDELMAkGA1UEBhMCU0cx
-ETAPBgNVBAoTCE0yQ3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UE
-AxMbTTJDcnlwdG8gQ2VydGlmaWNhdGUgTWFzdGVyMSIwIAYJKoZIhvcNAQkBFhNu
-Z3BzQG5ldG1lbWV0aWMuY29tMB4XDTAzMDYyMjEzMzAxNFoXDTA0MDYyMTEzMzAx
-NFowXTELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRIwEAYDVQQDEwls
-b2NhbGhvc3QxJzAlBgkqhkiG9w0BCQEWGGFkbWluQHNlcnZlci5leGFtcGxlLmRv
-bTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA37aKGZtFicl8xXXTLJ8/JD7c
-kd3t/teCX9i61lpaDQCKBoVrrursIvZihemMKI9g/u/+BLqt5g8mBdgUdYz0txc8
-KEbV2hj+wwOX4H3XwD0Y+DysXiNHq7/tFdmzSVHoLxpY4zYzXbxQ/p049wvIyPRp
-/y3omcnx/TEUhkn+JmkCAwEAAaOCAQwwggEIMAkGA1UdEwQCMAAwLAYJYIZIAYb4
-QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBTB
-H/mUYlww24mJlSxEtGdlwojO9zCBrQYDVR0jBIGlMIGigBTr+pwHMS1CmF9cuGI4
-du3YqoHAwqGBhqSBgzCBgDELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRv
-MRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UEAxMbTTJDcnlwdG8gQ2VydGlm
-aWNhdGUgTWFzdGVyMSIwIAYJKoZIhvcNAQkBFhNuZ3BzQG5ldG1lbWV0aWMuY29t
-ggEAMA0GCSqGSIb3DQEBBAUAA4GBAAvl6v0s3eFeGP4iAcrfysuK7jzFKhjDYuOy
-lVS3u33bZNLnMpM6OSEM9yPh4WpFCVHf+nYwC71pk4ilsLVXjKxymm2lNGcxLVuW
-iydFz4Ly9nmN7Ja9ygYT39dGAFP/wN7ELTpsbul8VfmqhNg9y81d8i/A1tK3AGA8
-0QkPQNdP
------END CERTIFICATE-----
------BEGIN RSA PRIVATE KEY-----
-MIICXAIBAAKBgQDftooZm0WJyXzFddMsnz8kPtyR3e3+14Jf2LrWWloNAIoGhWuu
-6uwi9mKF6Ywoj2D+7/4Euq3mDyYF2BR1jPS3FzwoRtXaGP7DA5fgfdfAPRj4PKxe
-I0erv+0V2bNJUegvGljjNjNdvFD+nTj3C8jI9Gn/LeiZyfH9MRSGSf4maQIDAQAB
-AoGAHpeVtv62uarl9xKvuBBm0AwQmZnhq9HIsFaw5hMg8Vo7hbzFBvx1IirTOkC/
-u+QvfW1QLVFh6m3z4ySzV4fZBtcd6F9SbSrZ0xsxIUB2NOSa1RGgiaP61bJnMMM1
-xM3O9iwM5GZc3Gqy08QOCpDl0772VJ+9Gz3FA88mrc6rHQkCQQDz6RIatFjT28n8
-1vy0nHwwZz2oXTpe/pyZPwoKj8zVsmrKhKwOw7l8ArxjP8zoHOE7AQBCXYDMNoFp
-IAF0yuqrAkEA6s0wMEdPpQeb0XHAfccyJQoeULxHdVFoz1wWmGSOm4YmQtR8/QJx
-luEgfpeRkzxBKt5Ls3MEkheIOw7xV24zOwJAMz+DaE0AZPNHS3K4ghJnHZxzng6I
-lzEUIjbWm0V/ml70hTy/EhMZw+6nOotLOHHo+QbK0SboSwAgzL/Gzo1cJQJANqpS
-38qadleRJXAQWrg3qnvyluVe1aeAeVZ9RDmVIgxXeBO0jcs12uTLBe4PzHGo0mwy
-v7K1i7XC180gzzQu5QJBAOxITT9RoWSSozPvnirHd37sn+RsrNYkV07NAa80M20Z
-DkBPHeMVkNgigrQ6L6vWmbRDGQbGcMplAxnI5ppKCoU=
------END RSA PRIVATE KEY-----
diff --git a/demo/bio_mem_rw.py b/demo/bio_mem_rw.py
deleted file mode 100644
index bcb78b8..0000000
--- a/demo/bio_mem_rw.py
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/usr/bin/env python2.0
-
-"""Demonstrates the use of m2.bio_set_mem_eof_return().
-Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
-
-from M2Crypto import m2
-m2.lib_init()
-
-use_mem = 1
-
-if use_mem:
- bio = m2.bio_new(m2.bio_s_mem())
-else:
- bio = m2.bio_new_file('XXX', 'wb')
-ciph = m2.bf_cbc()
-filt = m2.bio_new(m2.bio_f_cipher())
-m2.bio_set_cipher(filt, ciph, 'key', 'iv', 1)
-m2.bio_push(filt, bio)
-m2.bio_write(filt, '12345678901234567890')
-m2.bio_flush(filt)
-m2.bio_pop(filt)
-m2.bio_free(filt)
-if use_mem:
- m2.bio_set_mem_eof_return(bio, 0)
- xxx = m2.bio_read(bio, 100)
- print `xxx`, len(xxx)
-m2.bio_free(bio)
-
-if use_mem:
- bio = m2.bio_new(m2.bio_s_mem())
- m2.bio_write(bio, xxx)
- m2.bio_set_mem_eof_return(bio, 0)
-else:
- bio = m2.bio_new_file('XXX', 'rb')
-ciph = m2.bf_cbc()
-filt = m2.bio_new(m2.bio_f_cipher())
-m2.bio_set_cipher(filt, ciph, 'key', 'iv', 0)
-m2.bio_push(filt, bio)
-yyy = m2.bio_read(filt, 100)
-print `yyy`
-m2.bio_pop(filt)
-m2.bio_free(filt)
-m2.bio_free(bio)
-
diff --git a/demo/dhtest.py b/demo/dhtest.py
deleted file mode 100644
index 9fd87c6..0000000
--- a/demo/dhtest.py
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env python
-
-"""DH demonstration.
-
-Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
-
-from M2Crypto import DH, Rand
-
-def test():
- print 'generating dh params:'
- a = DH.gen_params(128, 2)
- b = DH.set_params(a.p, a.g)
- a.gen_key()
- b.gen_key()
- print 'p = ', `a.p`
- print 'g = ', `a.g`
- print 'a.pub =', `a.pub`
- print 'a.priv =', `a.priv`
- print 'b.pub =', `b.pub`
- print 'b.priv =', `b.priv`
- print 'a.key = ', `a.compute_key(b.pub)`
- print 'b.key = ', `b.compute_key(a.pub)`
-
-if __name__=='__main__':
- Rand.load_file('randpool.dat', -1)
- test()
- Rand.save_file('randpool.dat')
diff --git a/demo/dsa1024pvtkey.pem b/demo/dsa1024pvtkey.pem
deleted file mode 100644
index 8379ed1..0000000
--- a/demo/dsa1024pvtkey.pem
+++ /dev/null
@@ -1,12 +0,0 @@
------BEGIN DSA PRIVATE KEY-----
-MIIBvQIBAAKBgQD08iE3LXjSB/lA6Gq19XMzfmTvRBgFn+t9qNN6awFhrkowgyrI
-HaR6oCCHSvUcjdC0JcJdz8lSqofZkPknX6EEDkmlzZiUhtTZf0XiooeKigAiSlE2
-PpoS4RFcOOqOwVwRJI3mC2lzypI46/OPS0IOZFsxhXQpn1xnkmpEt83ZwwIVAPNw
-e6agkM25mv12Il7IuBBNl3cPAoGBAKOES1BV2E3zWj6gXOXFP02dk5A+zd7z4Qj+
-cx5euat07cAHYU0BZGJMTXlHSGf7YQOePuaxs9vTtSeUb1TeMFEr63Jispc9Kzce
-rd+E/IjiX7KCMbeGHnhtzC0FU/squZ76vp1TAXSozpfBvn73zAwAFPo/rHO4k6kH
-lXAez1QqAoGBAN6iYzbOnMckBtouHGBrdF4ea750DYnH5O2cij+yjgLMttuaxmZe
-0iFtJpXp6m4IHKAzIGgKhUGabAz+4O2/ZnmNu0oZzXkpBLL84pksDd0nObtgueL6
-sdTbhGl1kqpWRiK9T16gwqYxdcZiG5M5qbWtJIWWdv3mI9ql0XfUPWfpAhUA8e81
-iGFXunNE3ecKjCOKUL2EnEA=
------END DSA PRIVATE KEY-----
diff --git a/demo/dsa_bench.py b/demo/dsa_bench.py
deleted file mode 100644
index cd4b1f9..0000000
--- a/demo/dsa_bench.py
+++ /dev/null
@@ -1,176 +0,0 @@
-#!/usr/bin/env python
-
-"""
- DSA demo and benchmark.
-
- Usage: python -O dsa_bench.py [option option option ...]
- where options may include:
- makenewkey showpubkey showdigest showprofile
- md5 sha1 sha256 sha512
- <key length>
-
- NB:
- DSA is formally defined with SHA-1 and key length 1024.
- The OpenSSL implementation actually supports most any
- hashing algorithm and key length, as long as the key
- length is longer than the digest length. If not SHA-1
- and 1024, you should be very clear. The use of "DSA"
- without any qualifiers implies SHA-1 and 1024.
-
- Larry Bugbee
- November 2006
-
-
- Some portions are Copyright (c) 1999-2003 Ng Pheng Siong.
- All rights reserved.
-
- Portions created by Open Source Applications Foundation
- (OSAF) are Copyright (C) 2004 OSAF. All Rights Reserved.
-
-"""
-
-from M2Crypto import DSA, EVP, Rand
-from M2Crypto.EVP import MessageDigest
-import sys, base64
-
-# --------------------------------------------------------------
-# program parameters
-
-makenewkey = 0 # 1 = make/save new key, 0 = use existing
-showpubkey = 0 # 1 = show the public key value
-showdigest = 0 # 1 = show the digest value
-showprofile = 0 # 1 = use the python profiler
-
-hashalgs = ['md5', 'ripemd160', 'sha1',
- 'sha224', 'sha256', 'sha384', 'sha512']
-
-# default hashing algorithm
-hashalg = 'sha1'
-
-# default key length
-keylen = 1024
-
-# number of speed test loops
-N1 = N2 = 100
-
-# --------------------------------------------------------------
-# functions
-
-def test(dsa, dgst):
- print ' testing signing and verification...',
- try:
- r,s = dsa.sign(dgst)
- except Exception, e:
- print '\n\n *** %s *** \n' % e
- sys.exit()
- if not dsa.verify(dgst, r, s):
- print 'not ok'
- else:
- print 'ok'
-
-def test_asn1(dsa, dgst):
- # XXX Randomly fails: bug in there somewhere... (0.9.4)
- print ' testing asn1 signing and verification...',
- blob = dsa.sign_asn1(dgst)
- if not dsa.verify_asn1(dgst, blob):
- print 'not ok'
- else:
- print 'ok'
-
-def speed():
- from time import time
- t1 = time()
- for i in range(N1):
- r,s = dsa.sign(dgst)
- print ' %d signings: %8.2fs' % (N1, (time() - t1))
- t1 = time()
- for i in range(N2):
- dsa.verify(dgst, r, s)
- print ' %d verifications: %8.2fs' % (N2, (time() - t1))
-
-def test_speed(dsa, dgst):
- print ' measuring speed...'
- if showprofile:
- import profile
- profile.run('speed()')
- else:
- speed()
- print
-
-# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-def main(keylen, hashalg):
- global dsa, dgst # this exists ONLY for speed testing
-
- Rand.load_file('randpool.dat', -1)
-
- pvtkeyfilename = 'DSA%dpvtkey.pem' % (keylen)
- pubkeyfilename = 'DSA%dpubkey.pem' % (keylen)
-
- if makenewkey:
- print ' making and saving a new key'
- dsa = DSA.gen_params(keylen)
- dsa.gen_key()
- dsa.save_key(pvtkeyfilename, None ) # no pswd callback
- dsa.save_pub_key(pubkeyfilename)
- else:
- print ' loading an existing key'
- dsa = DSA.load_key(pvtkeyfilename)
- print ' dsa key length:', len(dsa)
-
- if not dsa.check_key():
- raise 'key is not initialised'
-
- if showpubkey:
- dsa_pub = dsa.pub
- pub_pem = base64.encodestring(dsa_pub)
- print ' PEM public key is: \n',pub_pem
-
- # since we are testing signing and verification, let's not
- # be fussy about the digest. Just make one.
- md = EVP.MessageDigest(hashalg)
- md.update('can you spell subliminal channel?')
- dgst = md.digest()
- print ' hash algorithm: %s' % hashalg
- if showdigest:
- print ' %s digest: \n%s' % (hashalg, base64.encodestring(dgst))
-
- test(dsa, dgst)
-# test_asn1(dsa, dgst)
- test_speed(dsa, dgst)
- Rand.save_file('randpool.dat')
-
-# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-def print_usage():
- print """
- Usage: python -O %s [option option option ...]
- where options may include:
- makenewkey showpubkey showdigest showprofile
- md5 sha1 sha256 sha512
- <key length>
-""" % sys.argv[0]
- sys.exit()
-
-# --------------------------------------------------------------
-# --------------------------------------------------------------
-
-if __name__=='__main__':
- for arg in sys.argv[1:]:
- if arg in hashalgs: hashalg = arg; continue
- if arg == 'makenewkey': makenewkey = 1; continue
- if arg == 'showpubkey': showpubkey = 1; continue
- if arg == 'showdigest': showdigest = 1; continue
- if arg == 'showprofile': showprofile = 1; continue
- try:
- keylen = int(arg)
- except:
- print '\n *** argument "%s" not understood ***' % arg
- print_usage()
-
- main(keylen, hashalg)
-
-
-# --------------------------------------------------------------
-# --------------------------------------------------------------
-# --------------------------------------------------------------
diff --git a/demo/dsatest.pem b/demo/dsatest.pem
deleted file mode 100644
index 8d5d97f..0000000
--- a/demo/dsatest.pem
+++ /dev/null
@@ -1,8 +0,0 @@
------BEGIN DSA PRIVATE KEY-----
-MIH4AgEAAkEA0NGZ0GRXdPLh/0c980Ot8ZbfV/DvJ19ZzsDhKXRxNNw36Ms4lb9Y
-ZMnJ1CliIDkpHx8sXEak0vkdeB2efGGBPQIVAJY7PF7CiA+jj+t3EyHf/sgVagPP
-AkEApkvDehftx8Kt+3GRsYkEgcKqsU6tue+QQOFOFYsCbMq/3rxIEKk0q1PqHfid
-+BsMiEY4FFmF5BqmgGAf6+V9twJATbbgPKi/EboVrtBdkTM52LSCQHPa/CEcj322
-0s5Ix1dwojdQaNpq6HhCm6+g9SXPENy9I/PK85YnawI4A6w1pQIULRB2HSm1X14c
-+guvmhIobv6wE50=
------END DSA PRIVATE KEY-----
diff --git a/demo/dsatest.py b/demo/dsatest.py
deleted file mode 100644
index 854b8b9..0000000
--- a/demo/dsatest.py
+++ /dev/null
@@ -1,57 +0,0 @@
-#!/usr/bin/env python
-
-"""DSA demonstration.
-
-Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
-
-from M2Crypto import DSA, EVP, Rand
-
-md=EVP.MessageDigest('sha1')
-md.update('can you spell subliminal channel?')
-dgst=md.digest()
-
-d=DSA.load_key('dsatest.pem')
-
-def test():
- print 'testing signing...',
- r,s=d.sign(dgst)
- if not d.verify(dgst, r, s):
- print 'not ok'
- else:
- print 'ok'
-
-def test_asn1():
- # XXX Randomly fails: bug in there somewhere... (0.9.4)
- print 'testing asn1 signing...',
- blob=d.sign_asn1(dgst)
- if not d.verify_asn1(dgst, blob):
- print 'not ok'
- else:
- print 'ok'
-
-def speed():
- from time import time
- N1 = 5242
- N2 = 2621
- t1 = time()
- for i in range(N1):
- r,s = d.sign(dgst)
- print '%d signings: %8.2fs' % (N1, (time() - t1))
- t1 = time()
- for i in range(N2):
- d.verify(dgst, r, s)
- print '%d verifications: %8.2fs' % (N2, (time() - t1))
-
-def test_speed():
- print 'measuring speed...'
- import profile
- profile.run('speed()')
-
-
-if __name__=='__main__':
- Rand.load_file('randpool.dat', -1)
- test()
- test_asn1()
- #test_speed()
- Rand.save_file('randpool.dat')
-
diff --git a/demo/ec/ecdhtest.py b/demo/ec/ecdhtest.py
deleted file mode 100644
index 6d407b6..0000000
--- a/demo/ec/ecdhtest.py
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/usr/bin/env python
-
-"""ECDH demonstration.
-
-Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved.
-
-Portions copyright (c) 2005-2006 Vrije Universiteit Amsterdam.
-All rights reserved."""
-
-from M2Crypto import EC,Rand
-
-def test():
- print 'generating ec keys:'
- a=EC.gen_params(EC.NID_sect233k1)
- a.gen_key()
- b=EC.gen_params(EC.NID_sect233k1)
- b.gen_key()
- a_shared_key = a.compute_dh_key(b.pub())
- b_shared_key = b.compute_dh_key(a.pub())
- print 'shared key according to a = ', `a_shared_key`
- print 'shared key according to b = ', `b_shared_key`
- if a_shared_key == b_shared_key:
- print 'ok'
- else:
- print 'not ok'
-
-
-if __name__=='__main__':
- Rand.load_file('randpool.dat', -1)
- test()
- Rand.save_file('randpool.dat')
diff --git a/demo/ec/ecdsa_bench.py b/demo/ec/ecdsa_bench.py
deleted file mode 100644
index bafceb1..0000000
--- a/demo/ec/ecdsa_bench.py
+++ /dev/null
@@ -1,368 +0,0 @@
-#!/usr/bin/env python
-
-"""
- ECDSA demo and benchmark.
-
- Usage: python -O ecdsa_bench.py [option option option ...]
- where options may include:
- makenewkey showpubkey showdigest showprofile
- md5 sha1 sha256 sha512
- secp160r1 secp224r1 secp192k1 sect283r1
- sect283k1 secp256k1 secp384r1 secp521r1
- (other curves and hashes are supported, see below)
-
- Larry Bugbee, June 2006
-
- Portions:
- Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved.
- Copyright (c) 2005 Vrije Universiteit Amsterdam. All rights reserved.
-
-"""
-
-from M2Crypto import EC, EVP, Rand
-from M2Crypto.EVP import MessageDigest
-import sys, base64
-
-# --------------------------------------------------------------
-# program parameters
-
-makenewkey = 0 # 1 = make/save new key, 0 = use existing
-showpubkey = 0 # 1 = show the public key value
-showdigest = 0 # 1 = show the digest value
-showprofile = 0 # 1 = use the python profiler
-
-hashalgs = ['md5', 'ripemd160', 'sha1',
- 'sha224', 'sha256', 'sha384', 'sha512']
-
-curves = ['secp112r1',
- 'secp112r2',
- 'secp128r1',
- 'secp128r2',
- 'secp160k1',
- 'secp160r1',
- 'secp160r2',
- 'secp192k1',
- 'secp224k1',
- 'secp224r1',
- 'secp256k1',
- 'secp384r1',
- 'secp521r1',
- 'sect113r1',
- 'sect113r2',
- 'sect131r1',
- 'sect131r2',
- 'sect163k1',
- 'sect163r1',
- 'sect163r2',
- 'sect193r1',
- 'sect193r2',
- 'sect233k1',
- 'sect233r1',
- 'sect239k1',
- 'sect283k1',
- 'sect283r1',
- 'sect409k1',
- 'sect409r1',
- 'sect571k1',
- 'sect571r1',
- 'X9_62_prime192v1',
- 'X9_62_prime192v2',
- 'X9_62_prime192v3',
- 'X9_62_prime239v1',
- 'X9_62_prime239v2',
- 'X9_62_prime239v3',
- 'X9_62_prime256v1',
- 'X9_62_c2pnb163v1',
- 'X9_62_c2pnb163v2',
- 'X9_62_c2pnb163v3',
- 'X9_62_c2pnb176v1',
- 'X9_62_c2tnb191v1',
- 'X9_62_c2tnb191v2',
- 'X9_62_c2tnb191v3',
- 'X9_62_c2pnb208w1',
- 'X9_62_c2tnb239v1',
- 'X9_62_c2tnb239v2',
- 'X9_62_c2tnb239v3',
- 'X9_62_c2pnb272w1',
- 'X9_62_c2pnb304w1',
- 'X9_62_c2tnb359v1',
- 'X9_62_c2pnb368w1',
- 'X9_62_c2tnb431r1',
- 'wap_wsg_idm_ecid_wtls1',
- 'wap_wsg_idm_ecid_wtls3',
- 'wap_wsg_idm_ecid_wtls4',
- 'wap_wsg_idm_ecid_wtls5',
- 'wap_wsg_idm_ecid_wtls6',
- 'wap_wsg_idm_ecid_wtls7',
- 'wap_wsg_idm_ecid_wtls8',
- 'wap_wsg_idm_ecid_wtls9',
- 'wap_wsg_idm_ecid_wtls10',
- 'wap_wsg_idm_ecid_wtls11',
- 'wap_wsg_idm_ecid_wtls12',
- ]
-
-# The following two curves, according to OpenSSL, have a
-# "Questionable extension field!" and are not supported by
-# the OpenSSL inverse function. ECError: no inverse.
-# As such they cannot be used for signing. They might,
-# however, be usable for encryption but that has not
-# been tested. Until thir usefulness can be established,
-# they are not supported at this time.
-#
-# Oakley-EC2N-3:
-# IPSec/IKE/Oakley curve #3 over a 155 bit binary field.
-# Oakley-EC2N-4:
-# IPSec/IKE/Oakley curve #4 over a 185 bit binary field.
-#
-# aka 'ipsec3' and 'ipsec4'
-
-# curves2 is a shorthand convenience so as to not require the
-# entering the "X9_62_" prefix
-curves2 = ['prime192v1',
- 'prime192v2',
- 'prime192v3',
- 'prime239v1',
- 'prime239v2',
- 'prime239v3',
- 'prime256v1',
- 'c2pnb163v1',
- 'c2pnb163v2',
- 'c2pnb163v3',
- 'c2pnb176v1',
- 'c2tnb191v1',
- 'c2tnb191v2',
- 'c2tnb191v3',
- 'c2pnb208w1',
- 'c2tnb239v1',
- 'c2tnb239v2',
- 'c2tnb239v3',
- 'c2pnb272w1',
- 'c2pnb304w1',
- 'c2tnb359v1',
- 'c2pnb368w1',
- 'c2tnb431r1',
- ]
-
-# default hashing algorithm
-hashalg = 'sha1'
-
-# default elliptical curve
-curve = 'secp160r1'
-
-# for a complete list of supported algorithms and curves, see
-# the bottom of this file
-
-# number of speed test loops
-N1 = N2 = 100
-
-# --------------------------------------------------------------
-# functions
-
-def test(ec, dgst):
- print ' testing signing and verification...',
- try:
-# ec = EC.gen_params(EC.NID_secp160r1)
-# ec.gen_key()
- r,s = ec.sign_dsa(dgst)
- except Exception, e:
- print '\n\n *** %s *** \n' % e
- sys.exit()
- if not ec.verify_dsa(dgst, r, s):
- print 'not ok'
- else:
- print 'ok'
-
-def test_asn1(ec, dgst):
- print ' testing asn1 signing and verification...',
- blob = ec.sign_dsa_asn1(dgst)
- if not ec.verify_dsa_asn1(dgst, blob):
- print 'not ok'
- else:
- print 'ok'
-
-def speed():
- from time import time
- t1 = time()
- for i in range(N1):
- r,s = ec.sign_dsa(dgst)
- print ' %d signings: %8.2fs' % (N1, (time() - t1))
- t1 = time()
- for i in range(N2):
- ec.verify_dsa(dgst, r, s)
- print ' %d verifications: %8.2fs' % (N2, (time() - t1))
-
-def test_speed(ec, dgst):
- print ' measuring speed...'
- if showprofile:
- import profile
- profile.run('speed()')
- else:
- speed()
- print
-
-# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-def main(curve, hashalg):
- global ec, dgst # this exists ONLY for speed testing
-
- Rand.load_file('randpool.dat', -1)
-
- if curve in curves2:
- curve = 'X9_62_' + curve
- ec_curve = eval('EC.NID_%s' % curve)
-
- pvtkeyfilename = '%spvtkey.pem' % (curve)
- pubkeyfilename = '%spubkey.pem' % (curve)
-
- if makenewkey:
- print ' making and saving a new key'
- ec = EC.gen_params(ec_curve)
- ec.gen_key()
- ec.save_key(pvtkeyfilename, None )
- ec.save_pub_key(pubkeyfilename)
- else:
- print ' loading an existing key'
- ec=EC.load_key(pvtkeyfilename)
- print ' ecdsa key length:', len(ec)
- print ' curve: %s' % curve
-
- if not ec.check_key():
- raise 'key is not initialised'
-
- if showpubkey:
- ec_pub = ec.pub()
- pub_der = ec_pub.get_der()
- pub_pem = base64.encodestring(pub_der)
- print ' PEM public key is: \n',pub_pem
-
- # since we are testing signing and verification, let's not
- # be fussy about the digest. Just make one.
- md = EVP.MessageDigest(hashalg)
- md.update('can you spell subliminal channel?')
- dgst = md.digest()
- print ' hash algorithm: %s' % hashalg
- if showdigest:
- print ' %s digest: \n%s' % (base64.encodestring(dgst))
-
- test(ec, dgst)
-# test_asn1(ec, dgst)
- test_speed(ec, dgst)
- Rand.save_file('randpool.dat')
-
-# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-def print_usage():
- print """
- Usage: python -O %s [option option option ...]
- where options may include:
- makenewkey showpubkey showdigest showprofile
- md5 sha1 sha256 sha512
- secp160r1 secp224r1 secp192k1 sect283r1
- sect283k1 secp256k1 secp384r1 secp521r1
- (other curves and hashes are supported, check pgm src)
-""" % sys.argv[0]
- sys.exit()
-
-# --------------------------------------------------------------
-# --------------------------------------------------------------
-
-if __name__=='__main__':
- for arg in sys.argv[1:]:
- if arg in hashalgs: hashalg = arg; continue
- if arg in curves + curves2: curve = arg; continue
- if arg == 'makenewkey': makenewkey = 1; continue
- if arg == 'showpubkey': showpubkey = 1; continue
- if arg == 'showdigest': showdigest = 1; continue
- if arg == 'showprofile': showprofile = 1; continue
-
- print '\n *** argument "%s" not understood ***' % arg
- print_usage()
-
- main(curve, hashalg)
-
-
-# --------------------------------------------------------------
-# --------------------------------------------------------------
-# --------------------------------------------------------------
-
-
-"""
- Elliptical curves supported by OpenSSL
- ======================================
-
-$ openssl ecparam -list_curves
- secp112r1 : SECG/WTLS curve over a 112 bit prime field
- secp112r2 : SECG curve over a 112 bit prime field
- secp128r1 : SECG curve over a 128 bit prime field
- secp128r2 : SECG curve over a 128 bit prime field
- secp160k1 : SECG curve over a 160 bit prime field
- secp160r1 : SECG curve over a 160 bit prime field
- secp160r2 : SECG/WTLS curve over a 160 bit prime field
- secp192k1 : SECG curve over a 192 bit prime field
- secp224k1 : SECG curve over a 224 bit prime field
- secp224r1 : NIST/SECG curve over a 224 bit prime field
- secp256k1 : SECG curve over a 256 bit prime field
- secp384r1 : NIST/SECG curve over a 384 bit prime field
- secp521r1 : NIST/SECG curve over a 521 bit prime field
- prime192v1: NIST/X9.62/SECG curve over a 192 bit prime field
- prime192v2: X9.62 curve over a 192 bit prime field
- prime192v3: X9.62 curve over a 192 bit prime field
- prime239v1: X9.62 curve over a 239 bit prime field
- prime239v2: X9.62 curve over a 239 bit prime field
- prime239v3: X9.62 curve over a 239 bit prime field
- prime256v1: X9.62/SECG curve over a 256 bit prime field
- sect113r1 : SECG curve over a 113 bit binary field
- sect113r2 : SECG curve over a 113 bit binary field
- sect131r1 : SECG/WTLS curve over a 131 bit binary field
- sect131r2 : SECG curve over a 131 bit binary field
- sect163k1 : NIST/SECG/WTLS curve over a 163 bit binary field
- sect163r1 : SECG curve over a 163 bit binary field
- sect163r2 : NIST/SECG curve over a 163 bit binary field
- sect193r1 : SECG curve over a 193 bit binary field
- sect193r2 : SECG curve over a 193 bit binary field
- sect233k1 : NIST/SECG/WTLS curve over a 233 bit binary field
- sect233r1 : NIST/SECG/WTLS curve over a 233 bit binary field
- sect239k1 : SECG curve over a 239 bit binary field
- sect283k1 : NIST/SECG curve over a 283 bit binary field
- sect283r1 : NIST/SECG curve over a 283 bit binary field
- sect409k1 : NIST/SECG curve over a 409 bit binary field
- sect409r1 : NIST/SECG curve over a 409 bit binary field
- sect571k1 : NIST/SECG curve over a 571 bit binary field
- sect571r1 : NIST/SECG curve over a 571 bit binary field
- c2pnb163v1: X9.62 curve over a 163 bit binary field
- c2pnb163v2: X9.62 curve over a 163 bit binary field
- c2pnb163v3: X9.62 curve over a 163 bit binary field
- c2pnb176v1: X9.62 curve over a 176 bit binary field
- c2tnb191v1: X9.62 curve over a 191 bit binary field
- c2tnb191v2: X9.62 curve over a 191 bit binary field
- c2tnb191v3: X9.62 curve over a 191 bit binary field
- c2pnb208w1: X9.62 curve over a 208 bit binary field
- c2tnb239v1: X9.62 curve over a 239 bit binary field
- c2tnb239v2: X9.62 curve over a 239 bit binary field
- c2tnb239v3: X9.62 curve over a 239 bit binary field
- c2pnb272w1: X9.62 curve over a 272 bit binary field
- c2pnb304w1: X9.62 curve over a 304 bit binary field
- c2tnb359v1: X9.62 curve over a 359 bit binary field
- c2pnb368w1: X9.62 curve over a 368 bit binary field
- c2tnb431r1: X9.62 curve over a 431 bit binary field
- wap-wsg-idm-ecid-wtls1: WTLS curve over a 113 bit binary field
- wap-wsg-idm-ecid-wtls3: NIST/SECG/WTLS curve over a 163 bit binary field
- wap-wsg-idm-ecid-wtls4: SECG curve over a 113 bit binary field
- wap-wsg-idm-ecid-wtls5: X9.62 curve over a 163 bit binary field
- wap-wsg-idm-ecid-wtls6: SECG/WTLS curve over a 112 bit prime field
- wap-wsg-idm-ecid-wtls7: SECG/WTLS curve over a 160 bit prime field
- wap-wsg-idm-ecid-wtls8: WTLS curve over a 112 bit prime field
- wap-wsg-idm-ecid-wtls9: WTLS curve over a 160 bit prime field
- wap-wsg-idm-ecid-wtls10: NIST/SECG/WTLS curve over a 233 bit binary field
- wap-wsg-idm-ecid-wtls11: NIST/SECG/WTLS curve over a 233 bit binary field
- wap-wsg-idm-ecid-wtls12: WTLS curvs over a 224 bit prime field
- Oakley-EC2N-3:
- IPSec/IKE/Oakley curve #3 over a 155 bit binary field.
- Not suitable for ECDSA.
- Questionable extension field!
- Oakley-EC2N-4:
- IPSec/IKE/Oakley curve #4 over a 185 bit binary field.
- Not suitable for ECDSA.
- Questionable extension field!
-
-"""
diff --git a/demo/ec/ecdsatest.pem b/demo/ec/ecdsatest.pem
deleted file mode 100644
index cc37a65..0000000
--- a/demo/ec/ecdsatest.pem
+++ /dev/null
@@ -1,5 +0,0 @@
------BEGIN EC PRIVATE KEY-----
-MG0CAQEEHVkQ54w5gN39TScPaC+TTKmJunupCfuNqEcWOZeXoAcGBSuBBAAaoUAD
-PgAEAIcWBNwIi1fP2Sd33wpayKBuw2oqBVvgvfYiipMcASzxCf6IFUC03IOob/Lu
-Y3mPHRZKwzSKBlD1ZkXh
------END EC PRIVATE KEY-----
diff --git a/demo/ec/ecdsatest.py b/demo/ec/ecdsatest.py
deleted file mode 100644
index 61ad625..0000000
--- a/demo/ec/ecdsatest.py
+++ /dev/null
@@ -1,68 +0,0 @@
-#!/usr/bin/env python
-
-"""ECDSA demonstration.
-
-Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved.
-Portions copyright (c) 2005-2006 Vrije Universiteit Amsterdam. All rights reserved.
-"""
-
-from M2Crypto import EC, EVP, Rand
-import base64
-
-md=EVP.MessageDigest('sha1')
-md.update('can you spell subliminal channel?')
-dgst=md.digest()
-
-ec=EC.load_key('ecdsatest.pem')
-#ec=EC.gen_params(EC.NID_sect233k1)
-#ec.gen_key()
-ec_pub = ec.pub()
-pub_der = ec_pub.get_der()
-pub_pem = base64.encodestring(pub_der)
-print 'PEM public key is',pub_pem
-ec.save_key( 'ecdsatest.pem', None )
-
-
-def test():
- print 'testing signing...',
- r,s=ec.sign_dsa(dgst)
- if not ec.verify_dsa(dgst, r, s):
- print 'not ok'
- else:
- print 'ok'
-
-def test_asn1():
- # XXX Randomly fails: bug in there somewhere... (0.9.4)
- print 'testing asn1 signing...',
- blob=ec.sign_dsa_asn1(dgst)
- if not ec.verify_dsa_asn1(dgst, blob):
- print 'not ok'
- else:
- print 'ok'
-
-def speed():
- from time import time
- N1 = 5242
- N2 = 2621
- t1 = time()
- for i in range(N1):
- r,s = ec.sign(dgst)
- print '%d signings: %8.2fs' % (N1, (time() - t1))
- t1 = time()
- for i in range(N2):
- ec.verify(dgst, r, s)
- print '%d verifications: %8.2fs' % (N2, (time() - t1))
-
-def test_speed():
- print 'measuring speed...'
- import profile
- profile.run('speed()')
-
-
-if __name__=='__main__':
- Rand.load_file('randpool.dat', -1)
- test()
- test_asn1()
- #test_speed()
- Rand.save_file('randpool.dat')
-
diff --git a/demo/ec/secp160r1pvtkey.pem b/demo/ec/secp160r1pvtkey.pem
deleted file mode 100644
index 6eac827..0000000
--- a/demo/ec/secp160r1pvtkey.pem
+++ /dev/null
@@ -1,4 +0,0 @@
------BEGIN EC PRIVATE KEY-----
-MFACAQEEFN1C7AYNKDl9dBLfm0QW1nB7WGs7oAcGBSuBBAAIoSwDKgEErnCVbfXH
-11Ax4AZq4eh8c3gWIBeaRu6tGRpITFCjtHot78c/oVqBrg==
------END EC PRIVATE KEY-----
diff --git a/demo/https.howto/ca.pem b/demo/https.howto/ca.pem
deleted file mode 100644
index d8ba0d3..0000000
--- a/demo/https.howto/ca.pem
+++ /dev/null
@@ -1,59 +0,0 @@
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 0 (0x0)
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=US, ST=CA, O=M2Crypto CA, CN=localhost
- Validity
- Not Before: Apr 22 04:35:56 2006 GMT
- Not After : Apr 21 04:35:56 2009 GMT
- Subject: C=US, ST=CA, O=M2Crypto CA, CN=localhost
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- RSA Public Key: (1024 bit)
- Modulus (1024 bit):
- 00:d8:80:02:8f:b5:7d:9f:9b:79:76:67:a5:66:64:
- c0:30:0c:71:65:f1:c6:78:01:a0:29:d4:3a:2c:e5:
- ee:58:4d:db:53:c5:74:6e:4e:f7:b6:a5:8e:ef:ab:
- e8:7c:f5:5d:2d:18:ba:95:b8:15:43:6e:5a:78:c2:
- 91:05:08:b2:7e:cf:c4:d3:bb:ac:c7:43:27:fb:8f:
- 43:0d:7b:d0:d1:32:51:86:11:6e:3e:aa:68:19:88:
- b9:cf:d5:72:f0:a4:73:d1:69:c4:65:14:0e:12:64:
- 7e:1f:df:18:09:0b:6a:4b:cd:bf:ae:59:82:15:1c:
- 90:0f:c3:e5:cb:b3:ed:86:4d
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints:
- CA:TRUE
- Netscape Comment:
- OpenSSL Generated Certificate
- X509v3 Subject Key Identifier:
- 5C:F9:C5:9B:B0:02:37:3C:66:73:4D:0E:CB:5A:3D:BB:3A:46:22:DD
- X509v3 Authority Key Identifier:
- keyid:5C:F9:C5:9B:B0:02:37:3C:66:73:4D:0E:CB:5A:3D:BB:3A:46:22:DD
-
- Signature Algorithm: sha1WithRSAEncryption
- 6b:9e:71:4a:ad:d2:1c:b7:58:1a:6e:8b:89:92:8d:4e:62:61:
- 06:2e:e8:11:f8:9c:a0:e2:11:7c:b6:e2:be:ef:b9:b1:35:20:
- d1:81:62:c5:ca:3c:4f:c9:88:72:f7:50:d8:e8:e0:06:43:ee:
- c5:5c:38:9b:e7:24:46:a6:ee:8d:b0:70:4e:75:96:00:db:d6:
- 59:f9:58:74:67:9f:ca:9c:12:fc:77:a7:0e:5a:38:22:5b:de:
- c9:33:35:bd:d0:4c:9f:6a:0f:71:7b:db:cb:fd:da:bc:39:4f:
- 23:1e:74:5b:ff:8d:73:72:16:a9:9f:57:54:96:3e:2c:f0:65:
- af:df
------BEGIN CERTIFICATE-----
-MIICfDCCAeWgAwIBAgIBADANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJVUzEL
-MAkGA1UECBMCQ0ExFDASBgNVBAoTC00yQ3J5cHRvIENBMRIwEAYDVQQDEwlsb2Nh
-bGhvc3QwHhcNMDYwNDIyMDQzNTU2WhcNMDkwNDIxMDQzNTU2WjBEMQswCQYDVQQG
-EwJVUzELMAkGA1UECBMCQ0ExFDASBgNVBAoTC00yQ3J5cHRvIENBMRIwEAYDVQQD
-Ewlsb2NhbGhvc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANiAAo+1fZ+b
-eXZnpWZkwDAMcWXxxngBoCnUOizl7lhN21PFdG5O97alju+r6Hz1XS0YupW4FUNu
-WnjCkQUIsn7PxNO7rMdDJ/uPQw170NEyUYYRbj6qaBmIuc/VcvCkc9FpxGUUDhJk
-fh/fGAkLakvNv65ZghUckA/D5cuz7YZNAgMBAAGjfjB8MAwGA1UdEwQFMAMBAf8w
-LAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0G
-A1UdDgQWBBRc+cWbsAI3PGZzTQ7LWj27OkYi3TAfBgNVHSMEGDAWgBRc+cWbsAI3
-PGZzTQ7LWj27OkYi3TANBgkqhkiG9w0BAQUFAAOBgQBrnnFKrdIct1gabouJko1O
-YmEGLugR+Jyg4hF8tuK+77mxNSDRgWLFyjxPyYhy91DY6OAGQ+7FXDib5yRGpu6N
-sHBOdZYA29ZZ+Vh0Z5/KnBL8d6cOWjgiW97JMzW90Eyfag9xe9vL/dq8OU8jHnRb
-/41zchapn1dUlj4s8GWv3w==
------END CERTIFICATE-----
diff --git a/demo/https.howto/dh1024.pem b/demo/https.howto/dh1024.pem
deleted file mode 100644
index 81d43f6..0000000
--- a/demo/https.howto/dh1024.pem
+++ /dev/null
@@ -1,5 +0,0 @@
------BEGIN DH PARAMETERS-----
-MIGHAoGBAJf2QmHKtQXdKCjhPx1ottPb0PMTBH9A6FbaWMsTuKG/K3g6TG1Z1fkq
-/Gz/PWk/eLI9TzFgqVAuPvr3q14a1aZeVUMTgo2oO5/y2UHe6VaJ+trqCTat3xlx
-/mNbIK9HA2RgPC3gWfVLZQrY+gz3ASHHR5nXWHEyvpuZm7m3h+irAgEC
------END DH PARAMETERS-----
diff --git a/demo/https.howto/get_https.py b/demo/https.howto/get_https.py
deleted file mode 100755
index 9728fab..0000000
--- a/demo/https.howto/get_https.py
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/env python
-"""Demonstrations of M2Crypto.httpslib.
-
-Copyright (c) 1999-2002 Ng Pheng Siong. All rights reserved.
-
-Portions created by Open Source Applications Foundation (OSAF) are
-Copyright (C) 2006 OSAF. All Rights Reserved.
-"""
-
-from M2Crypto import Rand, SSL, httpslib
-
-def get_https():
- ctx = SSL.Context()
- if ctx.load_verify_locations('ca.pem') != 1:
- raise Exception('CA certificates not loaded')
- ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, 9)
- h = httpslib.HTTPSConnection('localhost', 9443, ssl_context=ctx)
- h.set_debuglevel(1)
- h.putrequest('GET', '/')
- h.endheaders()
- resp = h.getresponse()
- while 1:
- data = resp.read()
- if not data:
- break
- print data
- h.close()
-
-Rand.load_file('../randpool.dat', -1)
-get_https()
-Rand.save_file('../randpool.dat')
-
diff --git a/demo/https.howto/https_cli.py b/demo/https.howto/https_cli.py
deleted file mode 100644
index bb34625..0000000
--- a/demo/https.howto/https_cli.py
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/usr/bin/env python
-
-"""Demonstrations of M2Crypto.httpslib.
-
-Copyright (c) 1999-2002 Ng Pheng Siong. All rights reserved.
-
-Portions created by Open Source Applications Foundation (OSAF) are
-Copyright (C) 2006 OSAF. All Rights Reserved.
-"""
-
-import sys
-from M2Crypto import Rand, SSL, httpslib, threading
-
-
-def test_httpslib():
- ctx = SSL.Context()
- if ctx.load_verify_locations('ca.pem') != 1:
- raise Exception('CA certificates not loaded')
- ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, 9)
- ctx.set_info_callback()
- h = httpslib.HTTPSConnection('localhost', 9443, ssl_context=ctx)
- h.set_debuglevel(1)
- h.putrequest('GET', '/')
- h.putheader('Accept', 'text/html')
- h.putheader('Accept', 'text/plain')
- h.putheader('Connection', 'close')
- h.endheaders()
- resp = h.getresponse()
- f = resp.fp
- c = 0
- while 1:
- # Either of following two works.
- #data = f.readline()
- data = resp.read()
- if not data: break
- c = c + len(data)
- sys.stdout.write(data)
- sys.stdout.flush()
- f.close()
- h.close()
-
-
-if __name__=='__main__':
- Rand.load_file('../randpool.dat', -1)
- #threading.init()
- test_httpslib()
- #threading.cleanup()
- Rand.save_file('../randpool.dat')
-
diff --git a/demo/https.howto/orig_https_srv.py b/demo/https.howto/orig_https_srv.py
deleted file mode 100644
index 83be0fb..0000000
--- a/demo/https.howto/orig_https_srv.py
+++ /dev/null
@@ -1,153 +0,0 @@
-"""This server extends BaseHTTPServer and SimpleHTTPServer thusly:
-1. One thread per connection.
-2. Generates directory listings.
-
-In addition, it has the following properties:
-1. Works over HTTPS only.
-2. Displays SSL handshaking and SSL session info.
-3. Performs SSL renegotiation when a magic url is requested.
-
-TODO:
-1. Cache stat() of directory entries.
-2. Fancy directory indexing.
-3. Interface ZPublisher.
-
-Copyright (c) 1999-2000 Ng Pheng Siong. All rights reserved.
-
-Portions created by Open Source Applications Foundation (OSAF) are
-Copyright (C) 2006 OSAF. All Rights Reserved.
-"""
-
-import os, sys
-from SimpleHTTPServer import SimpleHTTPRequestHandler
-
-from M2Crypto import Rand, SSL, threading
-from M2Crypto.SSL.SSLServer import ThreadingSSLServer
-
-try:
- from cStringIO import StringIO
-except ImportError:
- from StringIO import StringIO
-
-
-def mkdirlist(path, url):
- dirlist = os.listdir(path)
- dirlist.sort()
- f = StringIO()
- f.write('<title>Index listing for %s</title>\r\n' % (url,))
- f.write('<h1>Index listing for %s</h1>\r\n' % (url,))
- f.write('<pre>\r\n')
- for d in dirlist:
- if os.path.isdir(os.path.join(path, d)):
- d2 = d + '/'
- else:
- d2 = d
- if url == '/':
- f.write('<a href="/%s">%s</a><br>\r\n' % (d, d2))
- else:
- f.write('<a href="%s/%s">%s</a><br>\r\n' % (url, d, d2))
- f.write('</pre>\r\n\r\n')
- f.reset()
- return f
-
-
-class HTTP_Handler(SimpleHTTPRequestHandler):
-
- server_version = "https_srv/0.1"
- reneg = 0
-
- # Cribbed from SimpleHTTPRequestHander to add the ".der" entry,
- # which facilitates installing your own certificates into browsers.
- extensions_map = {
- '': 'text/plain', # Default, *must* be present
- '.html': 'text/html',
- '.htm': 'text/html',
- '.gif': 'image/gif',
- '.jpg': 'image/jpeg',
- '.jpeg': 'image/jpeg',
- '.der': 'application/x-x509-ca-cert'
- }
-
- def send_head(self):
- if self.path[1:8] == '_reneg_':
- self.reneg = 1
- self.path = self.path[8:]
- path = self.translate_path(self.path)
- if os.path.isdir(path):
- f = mkdirlist(path, self.path)
- filetype = 'text/html'
- else:
- try:
- f = open(path, 'rb')
- filetype = self.guess_type(path)
- except IOError:
- self.send_error(404, "File not found")
- return None
- self.send_response(200)
- self.send_header("Content-type", filetype)
- self.end_headers()
- return f
-
- def do_GET(self):
- #sess = self.request.get_session()
- #self.log_message('\n%s', sess.as_text())
- f = self.send_head()
- if self.reneg:
- self.reneg = 0
- self.request.renegotiate()
- sess = self.request.get_session()
- self.log_message('\n%s', sess.as_text())
- if f:
- self.copyfile(f, self.wfile)
- f.close()
-
- def do_HEAD(self):
- #sess = self.request.get_session()
- #self.log_message('\n%s', sess.as_text())
- f = self.send_head()
- if f:
- f.close()
-
-
-class HTTPS_Server(ThreadingSSLServer):
- def __init__(self, server_addr, handler, ssl_ctx):
- ThreadingSSLServer.__init__(self, server_addr, handler, ssl_ctx)
- self.server_name = server_addr[0]
- self.server_port = server_addr[1]
-
- def finish(self):
- self.request.set_shutdown(SSL.SSL_RECEIVED_SHUTDOWN | SSL.SSL_SENT_SHUTDOWN)
- self.request.close()
-
-
-def init_context(protocol, certfile, cafile, verify, verify_depth=10):
- ctx=SSL.Context(protocol)
- ctx.load_cert(certfile)
- ctx.load_client_ca(cafile)
- if ctx.load_verify_locations(cafile) != 1:
- raise Exception('CA certificates not loaded')
- ctx.set_verify(verify, verify_depth)
- ctx.set_allow_unknown_ca(1)
- ctx.set_session_id_ctx('https_srv')
- ctx.set_info_callback()
- return ctx
-
-
-if __name__ == '__main__':
- if len(sys.argv) < 2:
- wdir = '.'
- else:
- wdir = sys.argv[1]
- Rand.load_file('../randpool.dat', -1)
- threading.init()
- ctx = init_context('sslv23', 'server.pem', 'ca.pem', \
- SSL.verify_none)
- #SSL.verify_peer | SSL.verify_fail_if_no_peer_cert)
- ctx.set_tmp_dh('dh1024.pem')
- os.chdir(wdir)
- httpsd = HTTPS_Server(('', 9443), HTTP_Handler, ctx)
- httpsd.serve_forever()
- threading.cleanup()
- Rand.save_file('../randpool.dat')
-
-
diff --git a/demo/https.howto/server.pem b/demo/https.howto/server.pem
deleted file mode 100644
index bcd826c..0000000
--- a/demo/https.howto/server.pem
+++ /dev/null
@@ -1,74 +0,0 @@
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 1 (0x1)
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=US, ST=CA, O=M2Crypto CA, CN=localhost
- Validity
- Not Before: Apr 22 04:36:56 2006 GMT
- Not After : Apr 22 04:36:56 2007 GMT
- Subject: C=US, ST=CA, O=M2Crypto Server, CN=localhost
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- RSA Public Key: (1024 bit)
- Modulus (1024 bit):
- 00:a5:cc:39:ad:ba:81:3d:bd:05:f4:61:50:9f:9c:
- f6:ad:ec:29:d9:78:1e:24:61:f7:1b:36:bf:69:d8:
- b3:45:ae:6f:3a:4c:4f:d6:13:6d:60:8d:f2:bb:2a:
- c4:1b:79:fd:e2:f8:d6:3c:56:53:3b:27:f7:3f:70:
- a4:64:99:63:46:2e:3f:ef:52:da:a9:04:5b:6e:d4:
- 40:57:c5:59:61:d3:3f:7d:b8:03:c1:9b:65:46:2a:
- c5:9d:70:b7:ca:79:6e:dd:e4:3f:c2:f4:2f:2e:81:
- 32:c8:e9:a6:b6:a8:c8:1f:48:be:7a:66:56:98:fc:
- 3c:25:fc:d9:3d:73:07:30:71
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints:
- CA:FALSE
- Netscape Comment:
- OpenSSL Generated Certificate
- X509v3 Subject Key Identifier:
- F0:48:3A:32:88:8C:80:D7:22:AB:56:F8:86:B3:04:47:10:76:37:BE
- X509v3 Authority Key Identifier:
- keyid:5C:F9:C5:9B:B0:02:37:3C:66:73:4D:0E:CB:5A:3D:BB:3A:46:22:DD
-
- Signature Algorithm: sha1WithRSAEncryption
- 39:47:95:5c:ea:7e:db:b8:e0:80:f6:e5:d4:9f:83:bc:41:89:
- 31:97:c8:a4:95:0d:5d:6d:cc:64:8d:19:71:17:75:4b:7f:fb:
- 35:88:bf:68:e2:a2:be:c5:71:71:56:2a:92:31:25:2a:4b:98:
- 4e:77:42:45:78:45:21:a5:76:99:92:39:32:7d:a2:4c:38:b0:
- f1:db:7f:d1:4d:23:99:35:1e:0e:a1:59:a3:ff:9c:51:ef:4c:
- 11:c9:32:61:38:11:7d:57:2a:81:9a:96:1f:b3:88:f7:ab:5b:
- 58:f7:79:9b:a8:e3:b7:09:90:8e:c9:7d:44:4f:af:85:dc:c8:
- 29:4d
------BEGIN CERTIFICATE-----
-MIICfTCCAeagAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJVUzEL
-MAkGA1UECBMCQ0ExFDASBgNVBAoTC00yQ3J5cHRvIENBMRIwEAYDVQQDEwlsb2Nh
-bGhvc3QwHhcNMDYwNDIyMDQzNjU2WhcNMDcwNDIyMDQzNjU2WjBIMQswCQYDVQQG
-EwJVUzELMAkGA1UECBMCQ0ExGDAWBgNVBAoTD00yQ3J5cHRvIFNlcnZlcjESMBAG
-A1UEAxMJbG9jYWxob3N0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQClzDmt
-uoE9vQX0YVCfnPat7CnZeB4kYfcbNr9p2LNFrm86TE/WE21gjfK7KsQbef3i+NY8
-VlM7J/c/cKRkmWNGLj/vUtqpBFtu1EBXxVlh0z99uAPBm2VGKsWdcLfKeW7d5D/C
-9C8ugTLI6aa2qMgfSL56ZlaY/Dwl/Nk9cwcwcQIDAQABo3sweTAJBgNVHRMEAjAA
-MCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAd
-BgNVHQ4EFgQU8Eg6MoiMgNciq1b4hrMERxB2N74wHwYDVR0jBBgwFoAUXPnFm7AC
-Nzxmc00Oy1o9uzpGIt0wDQYJKoZIhvcNAQEFBQADgYEAOUeVXOp+27jggPbl1J+D
-vEGJMZfIpJUNXW3MZI0ZcRd1S3/7NYi/aOKivsVxcVYqkjElKkuYTndCRXhFIaV2
-mZI5Mn2iTDiw8dt/0U0jmTUeDqFZo/+cUe9MEckyYTgRfVcqgZqWH7OI96tbWPd5
-m6jjtwmQjsl9RE+vhdzIKU0=
------END CERTIFICATE-----
------BEGIN RSA PRIVATE KEY-----
-MIICXQIBAAKBgQClzDmtuoE9vQX0YVCfnPat7CnZeB4kYfcbNr9p2LNFrm86TE/W
-E21gjfK7KsQbef3i+NY8VlM7J/c/cKRkmWNGLj/vUtqpBFtu1EBXxVlh0z99uAPB
-m2VGKsWdcLfKeW7d5D/C9C8ugTLI6aa2qMgfSL56ZlaY/Dwl/Nk9cwcwcQIDAQAB
-AoGBAIwzbZbePsnxXOaxoBbJCcQ7D4yJSZvkh6womKauC7Lh9carn1tc5EIg5uCl
-Il5Fw466c5dkPE+q1SZ9X1Z+avYh4ypHjpcr1Lfvwo0wfOBx5MBj6ppMdwgrMXuo
-jRChK3gBZXmKaIH19h/sGp/lZRW2HiX63aN11KDmtfwo6Bq9AkEA2OftYJUqceK3
-/E8q6OE1oQLm+oK6CPZ29A5TRNOadRu1opDR/y59GcUQ5ebJNH8DXyF82lSi3DKt
-SNoSOF32cwJBAMOuKGUAwnq1yH3q+MAF7CZjGou7Ar6VRseyLnD5nttynT85QRW8
-N/WCosKLhV7wi9kKJmHGUJfRAqdo14D8IIsCQQCVjrU6FyABDpZVvjCUClT0BBBH
-QsQLUgWLGiWIG28wuD5xLPHexas0jZCtNIgfTkSA35I66Iiy065vwQ03GHLJAkAG
-eGC/jjngAtjBSR62grufPVGoYyOhF6CCg+LDO43EJdMLPyJmzJVxGcO1+RUM4ZlO
-MOa5/uu1SWT0EiRmEHAnAkBusVcHcd6d4uaoiCybIhF4hL4GsbKoImIciakNlteA
-c1RZZHc2jzO/Ihoz50H1njXwY86YbjncOXw8shtayd8j
------END RSA PRIVATE KEY-----
diff --git a/demo/medusa/00_README b/demo/medusa/00_README
deleted file mode 100644
index 1f0ce36..0000000
--- a/demo/medusa/00_README
+++ /dev/null
@@ -1,32 +0,0 @@
-
- 19 Sep 2001
--------------
-
-M2Crypto HTTPS and FTP/TLS servers
-
-All the files in this directory are from the Apr 2001 release
-of Medusa, except for the following:
-
-- 00_README (this file)
-- server.pem, the server's certificate
-- ca.pem, my CA certificate
-- https_server.py
-- ftps_server.py
-- START.py
-- START_xmlrpc.py
-- index.html, a sample HTML file
-- poison_handler.py, a webpoison clone
-
-By default, http_server listens on port 9080 and https_server port 9443.
-Document root is current directory, and serves up index.html.
-
-The xmlrpc server is accessible below '/RPC2'. It requires Fredrik Lundh's
-xmlrpc_handler on PYTHONPATH.
-
-The FTP/TLS server listens on port 9021 by default. I've only tested it with
-the 'anonymous' authentication handler.
-
-Medusa files are copyright Sam Rushing. My files are copyright me.
-
-
-
diff --git a/demo/medusa/START.py b/demo/medusa/START.py
deleted file mode 100644
index 62021f7..0000000
--- a/demo/medusa/START.py
+++ /dev/null
@@ -1,71 +0,0 @@
-#!/usr/bin/env python
-
-# Standard Python library
-import os
-import os.path
-import sys
-
-# Medusa
-import asyncore
-import default_handler
-import filesys
-import ftp_server
-import http_server
-import status_handler
-
-# M2Crypto
-import https_server
-import poison_handler
-import ftps_server
-from M2Crypto import Rand, SSL, threading
-
-HTTP_PORT=9080
-HTTPS_PORT=9443
-FTP_PORT = 9021
-
-hs=http_server.http_server('', HTTP_PORT)
-
-Rand.load_file('../randpool.dat', -1)
-ssl_ctx=SSL.Context('sslv23')
-ssl_ctx.load_cert('server.pem')
-ssl_ctx.load_verify_location('ca.pem')
-ssl_ctx.load_client_CA('ca.pem')
-#ssl_ctx.set_verify(SSL.verify_peer, 10)
-#ssl_ctx.set_verify(SSL.verify_peer|SSL.verify_fail_if_no_peer_cert, 10)
-#ssl_ctx.set_verify(SSL.verify_peer|SSL.verify_client_once, 10)
-ssl_ctx.set_verify(SSL.verify_none, 10)
-ssl_ctx.set_session_id_ctx('127.0.0.1:9443')
-ssl_ctx.set_tmp_dh('dh1024.pem')
-ssl_ctx.set_info_callback()
-
-hss=https_server.https_server('', HTTPS_PORT, ssl_ctx)
-
-#fs=filesys.os_filesystem(os.path.abspath(os.curdir))
-fs=filesys.os_filesystem('/usr/local/pkg/apache/htdocs')
-#fs=filesys.os_filesystem('c:/pkg/jdk130/docs')
-dh=default_handler.default_handler(fs)
-hs.install_handler(dh)
-hss.install_handler(dh)
-
-#class rpc_demo (xmlrpc_handler.xmlrpc_handler):
-# def call (self, method, params):
-# print 'method="%s" params=%s' % (method, params)
-# return "Sure, that works"
-#rpch = rpc_demo()
-#hs.install_handler(rpch)
-#hss.install_handler(rpch)
-
-ph=poison_handler.poison_handler(10)
-hs.install_handler(ph)
-hss.install_handler(ph)
-
-fauthz = ftp_server.anon_authorizer('/usr/local/pkg/apache/htdocs')
-ftps = ftps_server.ftp_tls_server(fauthz, ssl_ctx, port=FTP_PORT)
-
-sh=status_handler.status_extension([hs, hss, ftps])
-hs.install_handler(sh)
-hss.install_handler(sh)
-
-asyncore.loop()
-Rand.save_file('../randpool.dat')
-
diff --git a/demo/medusa/START_xmlrpc.py b/demo/medusa/START_xmlrpc.py
deleted file mode 100644
index 193e8bf..0000000
--- a/demo/medusa/START_xmlrpc.py
+++ /dev/null
@@ -1,72 +0,0 @@
-#!/usr/bin/env python
-
-# Standard Python library
-import os
-import os.path
-import sys
-
-# Medusa
-import asyncore
-import default_handler
-import filesys
-import http_server
-import status_handler
-
-# M2Crypto
-import https_server
-import poison_handler
-from M2Crypto import Rand, SSL
-
-# XMLrpc
-import xmlrpc_handler
-
-
-HTTP_PORT=9080
-HTTPS_PORT=9443
-
-hs=http_server.http_server('', HTTP_PORT)
-
-Rand.load_file('../randpool.dat', -1)
-ssl_ctx=SSL.Context('sslv23')
-ssl_ctx.load_cert('server.pem')
-#ssl_ctx.load_verify_location('ca.pem')
-#ssl_ctx.load_client_CA('ca.pem')
-#ssl_ctx.set_verify(SSL.verify_peer, 10)
-#ssl_ctx.set_verify(SSL.verify_peer|SSL.verify_fail_if_no_peer_cert, 10)
-#ssl_ctx.set_verify(SSL.verify_peer|SSL.verify_client_once, 10)
-ssl_ctx.set_verify(SSL.verify_none, 10)
-ssl_ctx.set_session_id_ctx('127.0.0.1:9443')
-ssl_ctx.set_tmp_dh('dh1024.pem')
-#ssl_ctx.set_info_callback()
-
-hss=https_server.https_server('', HTTPS_PORT, ssl_ctx)
-
-#fs=filesys.os_filesystem(os.path.abspath(os.curdir))
-fs=filesys.os_filesystem('/usr/local/pkg/apache/htdocs')
-#fs=filesys.os_filesystem('c:/pkg/jdk118/docs')
-dh=default_handler.default_handler(fs)
-hs.install_handler(dh)
-hss.install_handler(dh)
-
-# Cribbed from xmlrpc_handler.py.
-# This is where you implement your RPC functionality.
-class rpc_demo (xmlrpc_handler.xmlrpc_handler):
- def call (self, method, params):
- print 'method="%s" params=%s' % (method, params)
- return "Sure, that works"
-
-rpch = rpc_demo()
-hs.install_handler(rpch)
-hss.install_handler(rpch)
-
-ph=poison_handler.poison_handler(10)
-hs.install_handler(ph)
-hss.install_handler(ph)
-
-sh=status_handler.status_extension([hss])
-hs.install_handler(sh)
-hss.install_handler(sh)
-
-asyncore.loop()
-Rand.save_file('../randpool.dat')
-
diff --git a/demo/medusa/asynchat.py b/demo/medusa/asynchat.py
deleted file mode 100644
index 2e51f1a..0000000
--- a/demo/medusa/asynchat.py
+++ /dev/null
@@ -1,292 +0,0 @@
-# -*- Mode: Python; tab-width: 4 -*-
-# $Id: asynchat.py 299 2005-06-09 17:32:28Z heikki $
-# Author: Sam Rushing <rushing@nightmare.com>
-
-# ======================================================================
-# Copyright 1996 by Sam Rushing
-#
-# All Rights Reserved
-#
-# Permission to use, copy, modify, and distribute this software and
-# its documentation for any purpose and without fee is hereby
-# granted, provided that the above copyright notice appear in all
-# copies and that both that copyright notice and this permission
-# notice appear in supporting documentation, and that the name of Sam
-# Rushing not be used in advertising or publicity pertaining to
-# distribution of the software without specific, written prior
-# permission.
-#
-# SAM RUSHING DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
-# NO EVENT SHALL SAM RUSHING BE LIABLE FOR ANY SPECIAL, INDIRECT OR
-# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
-# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-# ======================================================================
-
-"""A class supporting chat-style (command/response) protocols.
-
-This class adds support for 'chat' style protocols - where one side
-sends a 'command', and the other sends a response (examples would be
-the common internet protocols - smtp, nntp, ftp, etc..).
-
-The handle_read() method looks at the input stream for the current
-'terminator' (usually '\r\n' for single-line responses, '\r\n.\r\n'
-for multi-line output), calling self.found_terminator() on its
-receipt.
-
-for example:
-Say you build an async nntp client using this class. At the start
-of the connection, you'll have self.terminator set to '\r\n', in
-order to process the single-line greeting. Just before issuing a
-'LIST' command you'll set it to '\r\n.\r\n'. The output of the LIST
-command will be accumulated (using your own 'collect_incoming_data'
-method) up to the terminator, and then control will be returned to
-you - by calling your self.found_terminator() method.
-"""
-
-import socket
-import asyncore
-import string
-
-class async_chat (asyncore.dispatcher):
- """This is an abstract class. You must derive from this class, and add
- the two methods collect_incoming_data() and found_terminator()"""
-
- # these are overridable defaults
-
- ac_in_buffer_size = 4096
- ac_out_buffer_size = 4096
-
- def __init__ (self, conn=None):
- self.ac_in_buffer = ''
- self.ac_out_buffer = ''
- self.producer_fifo = fifo()
- asyncore.dispatcher.__init__ (self, conn)
-
- def set_terminator (self, term):
- "Set the input delimiter. Can be a fixed string of any length, an integer, or None"
- self.terminator = term
-
- def get_terminator (self):
- return self.terminator
-
- # grab some more data from the socket,
- # throw it to the collector method,
- # check for the terminator,
- # if found, transition to the next state.
-
- def handle_read (self):
-
- try:
- data = self.recv (self.ac_in_buffer_size)
- except socket.error, why:
- self.handle_error()
- return
-
- self.ac_in_buffer = self.ac_in_buffer + data
-
- # Continue to search for self.terminator in self.ac_in_buffer,
- # while calling self.collect_incoming_data. The while loop
- # is necessary because we might read several data+terminator
- # combos with a single recv(1024).
-
- while self.ac_in_buffer:
- lb = len(self.ac_in_buffer)
- terminator = self.get_terminator()
- if terminator is None:
- # no terminator, collect it all
- self.collect_incoming_data (self.ac_in_buffer)
- self.ac_in_buffer = ''
- elif type(terminator) == type(0):
- # numeric terminator
- n = terminator
- if lb < n:
- self.collect_incoming_data (self.ac_in_buffer)
- self.ac_in_buffer = ''
- self.terminator = self.terminator - lb
- else:
- self.collect_incoming_data (self.ac_in_buffer[:n])
- self.ac_in_buffer = self.ac_in_buffer[n:]
- self.terminator = 0
- self.found_terminator()
- else:
- # 3 cases:
- # 1) end of buffer matches terminator exactly:
- # collect data, transition
- # 2) end of buffer matches some prefix:
- # collect data to the prefix
- # 3) end of buffer does not match any prefix:
- # collect data
- terminator_len = len(terminator)
- index = string.find (self.ac_in_buffer, terminator)
- if index != -1:
- # we found the terminator
- if index > 0:
- # don't bother reporting the empty string (source of subtle bugs)
- self.collect_incoming_data (self.ac_in_buffer[:index])
- self.ac_in_buffer = self.ac_in_buffer[index+terminator_len:]
- # This does the Right Thing if the terminator is changed here.
- self.found_terminator()
- else:
- # check for a prefix of the terminator
- index = find_prefix_at_end (self.ac_in_buffer, terminator)
- if index:
- if index != lb:
- # we found a prefix, collect up to the prefix
- self.collect_incoming_data (self.ac_in_buffer[:-index])
- self.ac_in_buffer = self.ac_in_buffer[-index:]
- break
- else:
- # no prefix, collect it all
- self.collect_incoming_data (self.ac_in_buffer)
- self.ac_in_buffer = ''
-
- def handle_write (self):
- self.initiate_send ()
-
- def handle_close (self):
- self.close()
-
- def push (self, data):
- self.producer_fifo.push (simple_producer (data))
- self.initiate_send()
-
- def push_with_producer (self, producer):
- self.producer_fifo.push (producer)
- self.initiate_send()
-
- def readable (self):
- "predicate for inclusion in the readable for select()"
- return (len(self.ac_in_buffer) <= self.ac_in_buffer_size)
-
- def writable (self):
- "predicate for inclusion in the writable for select()"
- # return len(self.ac_out_buffer) or len(self.producer_fifo) or (not self.connected)
- # this is about twice as fast, though not as clear.
- return not (
- (self.ac_out_buffer is '') and
- self.producer_fifo.is_empty() and
- self.connected
- )
-
- def close_when_done (self):
- "automatically close this channel once the outgoing queue is empty"
- self.producer_fifo.push (None)
-
- # refill the outgoing buffer by calling the more() method
- # of the first producer in the queue
- def refill_buffer (self):
- _string_type = type('')
- while 1:
- if len(self.producer_fifo):
- p = self.producer_fifo.first()
- # a 'None' in the producer fifo is a sentinel,
- # telling us to close the channel.
- if p is None:
- if not self.ac_out_buffer:
- self.producer_fifo.pop()
- self.close()
- return
- elif type(p) is _string_type:
- self.producer_fifo.pop()
- self.ac_out_buffer = self.ac_out_buffer + p
- return
- data = p.more()
- if data:
- self.ac_out_buffer = self.ac_out_buffer + data
- return
- else:
- self.producer_fifo.pop()
- else:
- return
-
- def initiate_send (self):
- obs = self.ac_out_buffer_size
- # try to refill the buffer
- if (len (self.ac_out_buffer) < obs):
- self.refill_buffer()
-
- if self.ac_out_buffer and self.connected:
- # try to send the buffer
- try:
- num_sent = self.send (self.ac_out_buffer[:obs])
- if num_sent:
- self.ac_out_buffer = self.ac_out_buffer[num_sent:]
-
- except socket.error, why:
- self.handle_error()
- return
-
- def discard_buffers (self):
- # Emergencies only!
- self.ac_in_buffer = ''
- self.ac_out_buffer = ''
- while self.producer_fifo:
- self.producer_fifo.pop()
-
-
-class simple_producer:
-
- def __init__ (self, data, buffer_size=512):
- self.data = data
- self.buffer_size = buffer_size
-
- def more (self):
- if len (self.data) > self.buffer_size:
- result = self.data[:self.buffer_size]
- self.data = self.data[self.buffer_size:]
- return result
- else:
- result = self.data
- self.data = ''
- return result
-
-class fifo:
- def __init__ (self, list=None):
- if not list:
- self.list = []
- else:
- self.list = list
-
- def __len__ (self):
- return len(self.list)
-
- def is_empty (self):
- return self.list == []
-
- def first (self):
- return self.list[0]
-
- def push (self, data):
- self.list.append (data)
-
- def pop (self):
- if self.list:
- result = self.list[0]
- del self.list[0]
- return (1, result)
- else:
- return (0, None)
-
-# Given 'haystack', see if any prefix of 'needle' is at its end. This
-# assumes an exact match has already been checked. Return the number of
-# characters matched.
-# for example:
-# f_p_a_e ("qwerty\r", "\r\n") => 1
-# f_p_a_e ("qwertydkjf", "\r\n") => 0
-# f_p_a_e ("qwerty\r\n", "\r\n") => <undefined>
-
-# this could maybe be made faster with a computed regex?
-# [answer: no; circa Python-2.0, Jan 2001]
-# new python: 28961/s
-# old python: 18307/s
-# re: 12820/s
-# regex: 14035/s
-
-def find_prefix_at_end (haystack, needle):
- l = len(needle) - 1
- while l and not haystack.endswith(needle[:l]):
- l -= 1
- return l
diff --git a/demo/medusa/asyncore.py b/demo/medusa/asyncore.py
deleted file mode 100644
index 7f751aa..0000000
--- a/demo/medusa/asyncore.py
+++ /dev/null
@@ -1,552 +0,0 @@
-# -*- Mode: Python; tab-width: 4 -*-
-# $Id: asyncore.py 299 2005-06-09 17:32:28Z heikki $
-# Author: Sam Rushing <rushing@nightmare.com>
-
-# ======================================================================
-# Copyright 1996 by Sam Rushing
-#
-# All Rights Reserved
-#
-# Permission to use, copy, modify, and distribute this software and
-# its documentation for any purpose and without fee is hereby
-# granted, provided that the above copyright notice appear in all
-# copies and that both that copyright notice and this permission
-# notice appear in supporting documentation, and that the name of Sam
-# Rushing not be used in advertising or publicity pertaining to
-# distribution of the software without specific, written prior
-# permission.
-#
-# SAM RUSHING DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
-# NO EVENT SHALL SAM RUSHING BE LIABLE FOR ANY SPECIAL, INDIRECT OR
-# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
-# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-# ======================================================================
-
-"""Basic infrastructure for asynchronous socket service clients and servers.
-
-There are only two ways to have a program on a single processor do "more
-than one thing at a time". Multi-threaded programming is the simplest and
-most popular way to do it, but there is another very different technique,
-that lets you have nearly all the advantages of multi-threading, without
-actually using multiple threads. it's really only practical if your program
-is largely I/O bound. If your program is CPU bound, then pre-emptive
-scheduled threads are probably what you really need. Network servers are
-rarely CPU-bound, however.
-
-If your operating system supports the select() system call in its I/O
-library (and nearly all do), then you can use it to juggle multiple
-communication channels at once; doing other work while your I/O is taking
-place in the "background." Although this strategy can seem strange and
-complex, especially at first, it is in many ways easier to understand and
-control than multi-threaded programming. The module documented here solves
-many of the difficult problems for you, making the task of building
-sophisticated high-performance network servers and clients a snap.
-"""
-
-import exceptions
-import select
-import socket
-import string
-import sys
-
-import os
-if os.name == 'nt':
- EWOULDBLOCK = 10035
- EINPROGRESS = 10036
- EALREADY = 10037
- ECONNRESET = 10054
- ENOTCONN = 10057
- ESHUTDOWN = 10058
-else:
- from errno import EALREADY, EINPROGRESS, EWOULDBLOCK, ECONNRESET, ENOTCONN, ESHUTDOWN
-
-try:
- socket_map
-except NameError:
- socket_map = {}
-
-class ExitNow (exceptions.Exception):
- pass
-
-DEBUG = 0
-
-def poll (timeout=0.0, map=None):
- global DEBUG
- if map is None:
- map = socket_map
- if map:
- r = []; w = []; e = []
- for fd, obj in map.items():
- if obj.readable():
- r.append (fd)
- if obj.writable():
- w.append (fd)
- r,w,e = select.select (r,w,e, timeout)
-
- if DEBUG:
- print r,w,e
-
- for fd in r:
- try:
- obj = map[fd]
- try:
- obj.handle_read_event()
- except ExitNow:
- raise ExitNow
- except:
- obj.handle_error()
- except KeyError:
- pass
-
- for fd in w:
- try:
- obj = map[fd]
- try:
- obj.handle_write_event()
- except ExitNow:
- raise ExitNow
- except:
- obj.handle_error()
- except KeyError:
- pass
-
-def poll2 (timeout=0.0, map=None):
- import poll
- if map is None:
- map=socket_map
- # timeout is in milliseconds
- timeout = int(timeout*1000)
- if map:
- l = []
- for fd, obj in map.items():
- flags = 0
- if obj.readable():
- flags = poll.POLLIN
- if obj.writable():
- flags = flags | poll.POLLOUT
- if flags:
- l.append ((fd, flags))
- r = poll.poll (l, timeout)
- for fd, flags in r:
- try:
- obj = map[fd]
- try:
- if (flags & poll.POLLIN):
- obj.handle_read_event()
- if (flags & poll.POLLOUT):
- obj.handle_write_event()
- except ExitNow:
- raise ExitNow
- except:
- obj.handle_error()
- except KeyError:
- pass
-
-def poll3 (timeout=0.0, map=None):
- # Use the poll() support added to the select module in Python 2.0
- if map is None:
- map=socket_map
- # timeout is in milliseconds
- timeout = int(timeout*1000)
- pollster = select.poll()
- if map:
- l = []
- for fd, obj in map.items():
- flags = 0
- if obj.readable():
- flags = select.POLLIN
- if obj.writable():
- flags = flags | select.POLLOUT
- if flags:
- pollster.register(fd, flags)
- r = pollster.poll (timeout)
- for fd, flags in r:
- try:
- obj = map[fd]
- try:
- if (flags & select.POLLIN):
- obj.handle_read_event()
- if (flags & select.POLLOUT):
- obj.handle_write_event()
- except ExitNow:
- raise ExitNow
- except:
- obj.handle_error()
- except KeyError:
- pass
-
-def loop (timeout=30.0, use_poll=0, map=None):
-
- if use_poll:
- if hasattr (select, 'poll'):
- poll_fun = poll3
- else:
- poll_fun = poll2
- else:
- poll_fun = poll
-
- if map is None:
- map=socket_map
-
- while map:
- poll_fun (timeout, map)
-
-class dispatcher:
- debug = 0
- connected = 0
- accepting = 0
- closing = 0
- addr = None
-
- def __init__ (self, sock=None, map=None):
- if sock:
- self.set_socket (sock, map)
- # I think it should inherit this anyway
- self.socket.setblocking (0)
- self.connected = 1
-
- def __repr__ (self):
- try:
- status = []
- if self.accepting and self.addr:
- status.append ('listening')
- elif self.connected:
- status.append ('connected')
- if self.addr:
- status.append ('%s:%d' % self.addr)
- return '<%s %s at %x>' % (
- self.__class__.__name__,
- string.join (status, ' '),
- id(self)
- )
- except:
- try:
- ar = repr(self.addr)
- except:
- ar = 'no self.addr!'
-
- return '<__repr__ (self) failed for object at %x (addr=%s)>' % (id(self),ar)
-
- def add_channel (self, map=None):
- #self.log_info ('adding channel %s' % self)
- if map is None:
- map=socket_map
- map [self._fileno] = self
-
- def del_channel (self, map=None):
- fd = self._fileno
- if map is None:
- map=socket_map
- if map.has_key (fd):
- #self.log_info ('closing channel %d:%s' % (fd, self))
- del map [fd]
-
- def create_socket (self, family, type):
- self.family_and_type = family, type
- self.socket = socket.socket (family, type)
- self.socket.setblocking(0)
- self._fileno = self.socket.fileno()
- self.add_channel()
-
- def set_socket (self, sock, map=None):
- self.__dict__['socket'] = sock
- self._fileno = sock.fileno()
- self.add_channel (map)
-
- def set_reuse_addr (self):
- # try to re-use a server port if possible
- try:
- self.socket.setsockopt (
- socket.SOL_SOCKET, socket.SO_REUSEADDR,
- self.socket.getsockopt (socket.SOL_SOCKET, socket.SO_REUSEADDR) | 1
- )
- except:
- pass
-
- # ==================================================
- # predicates for select()
- # these are used as filters for the lists of sockets
- # to pass to select().
- # ==================================================
-
- def readable (self):
- return 1
-
- if os.name == 'mac':
- # The macintosh will select a listening socket for
- # write if you let it. What might this mean?
- def writable (self):
- return not self.accepting
- else:
- def writable (self):
- return 1
-
- # ==================================================
- # socket object methods.
- # ==================================================
-
- def listen (self, num):
- self.accepting = 1
- if os.name == 'nt' and num > 5:
- num = 1
- return self.socket.listen (num)
-
- def bind (self, addr):
- self.addr = addr
- return self.socket.bind (addr)
-
- def connect (self, address):
- self.connected = 0
- try:
- self.socket.connect (address)
- except socket.error, why:
- if why[0] in (EINPROGRESS, EALREADY, EWOULDBLOCK):
- return
- else:
- raise socket.error, why
- self.connected = 1
- self.handle_connect()
-
- def accept (self):
- try:
- conn, addr = self.socket.accept()
- return conn, addr
- except socket.error, why:
- if why[0] == EWOULDBLOCK:
- pass
- else:
- raise socket.error, why
-
- def send (self, data):
- try:
- result = self.socket.send (data)
- return result
- except socket.error, why:
- if why[0] == EWOULDBLOCK:
- return 0
- else:
- raise socket.error, why
- return 0
-
- def recv (self, buffer_size):
- try:
- data = self.socket.recv (buffer_size)
- if not data:
- # a closed connection is indicated by signaling
- # a read condition, and having recv() return 0.
- self.handle_close()
- return ''
- else:
- return data
- except socket.error, why:
- # winsock sometimes throws ENOTCONN
- if why[0] in [ECONNRESET, ENOTCONN, ESHUTDOWN]:
- self.handle_close()
- return ''
- else:
- raise socket.error, why
-
- def close (self):
- self.del_channel()
- self.socket.close()
-
- # cheap inheritance, used to pass all other attribute
- # references to the underlying socket object.
- def __getattr__ (self, attr):
- return getattr (self.socket, attr)
-
- # log and log_info maybe overriden to provide more sophisitcated
- # logging and warning methods. In general, log is for 'hit' logging
- # and 'log_info' is for informational, warning and error logging.
-
- def log (self, message):
- sys.stderr.write ('log: %s\n' % str(message))
-
- def log_info (self, message, type='info'):
- if __debug__ or type != 'info':
- print '%s: %s' % (type, message)
-
- def handle_read_event (self):
- if self.accepting:
- # for an accepting socket, getting a read implies
- # that we are connected
- if not self.connected:
- self.connected = 1
- self.handle_accept()
- elif not self.connected:
- self.handle_connect()
- self.connected = 1
- self.handle_read()
- else:
- self.handle_read()
-
- def handle_write_event (self):
- # getting a write implies that we are connected
- if not self.connected:
- self.handle_connect()
- self.connected = 1
- self.handle_write()
-
- def handle_expt_event (self):
- self.handle_expt()
-
- def handle_error (self):
- (file,fun,line), t, v, tbinfo = compact_traceback()
-
- # sometimes a user repr method will crash.
- try:
- self_repr = repr (self)
- except:
- self_repr = '<__repr__ (self) failed for object at %0x>' % id(self)
-
- self.log_info (
- 'uncaptured python exception, closing channel %s (%s:%s %s)' % (
- self_repr,
- t,
- v,
- tbinfo
- ),
- 'error'
- )
- self.close()
-
- def handle_expt (self):
- self.log_info ('unhandled exception', 'warning')
-
- def handle_read (self):
- self.log_info ('unhandled read event', 'warning')
-
- def handle_write (self):
- self.log_info ('unhandled write event', 'warning')
-
- def handle_connect (self):
- self.log_info ('unhandled connect event', 'warning')
-
- def handle_accept (self):
- self.log_info ('unhandled accept event', 'warning')
-
- def handle_close (self):
- self.log_info ('unhandled close event', 'warning')
- self.close()
-
-# ---------------------------------------------------------------------------
-# adds simple buffered output capability, useful for simple clients.
-# [for more sophisticated usage use asynchat.async_chat]
-# ---------------------------------------------------------------------------
-
-class dispatcher_with_send (dispatcher):
- def __init__ (self, sock=None):
- dispatcher.__init__ (self, sock)
- self.out_buffer = ''
-
- def initiate_send (self):
- num_sent = 0
- num_sent = dispatcher.send (self, self.out_buffer[:512])
- self.out_buffer = self.out_buffer[num_sent:]
-
- def handle_write (self):
- self.initiate_send()
-
- def writable (self):
- return (not self.connected) or len(self.out_buffer)
-
- def send (self, data):
- if self.debug:
- self.log_info ('sending %s' % repr(data))
- self.out_buffer = self.out_buffer + data
- self.initiate_send()
-
-# ---------------------------------------------------------------------------
-# used for debugging.
-# ---------------------------------------------------------------------------
-
-def compact_traceback ():
- t,v,tb = sys.exc_info()
- tbinfo = []
- while 1:
- tbinfo.append ((
- tb.tb_frame.f_code.co_filename,
- tb.tb_frame.f_code.co_name,
- str(tb.tb_lineno)
- ))
- tb = tb.tb_next
- if not tb:
- break
-
- # just to be safe
- del tb
-
- file, function, line = tbinfo[-1]
- info = '[' + string.join (
- map (
- lambda x: string.join (x, '|'),
- tbinfo
- ),
- '] ['
- ) + ']'
- return (file, function, line), t, v, info
-
-def close_all (map=None):
- if map is None:
- map=socket_map
- for x in map.values():
- x.socket.close()
- map.clear()
-
-# Asynchronous File I/O:
-#
-# After a little research (reading man pages on various unixen, and
-# digging through the linux kernel), I've determined that select()
-# isn't meant for doing doing asynchronous file i/o.
-# Heartening, though - reading linux/mm/filemap.c shows that linux
-# supports asynchronous read-ahead. So _MOST_ of the time, the data
-# will be sitting in memory for us already when we go to read it.
-#
-# What other OS's (besides NT) support async file i/o? [VMS?]
-#
-# Regardless, this is useful for pipes, and stdin/stdout...
-
-import os
-if os.name == 'posix':
- import fcntl
- import FCNTL
-
- class file_wrapper:
- # here we override just enough to make a file
- # look like a socket for the purposes of asyncore.
- def __init__ (self, fd):
- self.fd = fd
-
- def recv (self, *args):
- return apply (os.read, (self.fd,)+args)
-
- def send (self, *args):
- return apply (os.write, (self.fd,)+args)
-
- read = recv
- write = send
-
- def close (self):
- return os.close (self.fd)
-
- def fileno (self):
- return self.fd
-
- class file_dispatcher (dispatcher):
- def __init__ (self, fd):
- dispatcher.__init__ (self)
- self.connected = 1
- # set it to non-blocking mode
- flags = fcntl.fcntl (fd, FCNTL.F_GETFL, 0)
- flags = flags | FCNTL.O_NONBLOCK
- fcntl.fcntl (fd, FCNTL.F_SETFL, flags)
- self.set_file (fd)
-
- def set_file (self, fd):
- self._fileno = fd
- self.socket = file_wrapper (fd)
- self.add_channel()
-
diff --git a/demo/medusa/auth_handler.py b/demo/medusa/auth_handler.py
deleted file mode 100644
index 70eaf3c..0000000
--- a/demo/medusa/auth_handler.py
+++ /dev/null
@@ -1,135 +0,0 @@
-# -*- Mode: Python; tab-width: 4 -*-
-#
-# Author: Sam Rushing <rushing@nightmare.com>
-# Copyright 1996-2000 by Sam Rushing
-# All Rights Reserved.
-#
-
-# support for 'basic' authenticaion.
-
-import base64
-import md5
-import re
-import string
-import time
-import counter
-
-import default_handler
-
-get_header = default_handler.get_header
-
-import http_server
-import producers
-
-# This is a 'handler' that wraps an authorization method
-# around access to the resources normally served up by
-# another handler.
-
-# does anyone support digest authentication? (rfc2069)
-
-class auth_handler:
- def __init__ (self, dict, handler, realm='default'):
- self.authorizer = dictionary_authorizer (dict)
- self.handler = handler
- self.realm = realm
- self.pass_count = counter.counter()
- self.fail_count = counter.counter()
-
- def match (self, request):
- # by default, use the given handler's matcher
- return self.handler.match (request)
-
- def handle_request (self, request):
- # authorize a request before handling it...
- scheme = get_header (AUTHORIZATION, request.header)
-
- if scheme:
- scheme = string.lower (scheme)
- if scheme == 'basic':
- cookie = AUTHORIZATION.group(2)
- try:
- decoded = base64.decodestring (cookie)
- except:
- print 'malformed authorization info <%s>' % cookie
- request.error (400)
- return
- auth_info = string.split (decoded, ':')
- if self.authorizer.authorize (auth_info):
- self.pass_count.increment()
- request.auth_info = auth_info
- self.handler.handle_request (request)
- else:
- self.handle_unauthorized (request)
- #elif scheme == 'digest':
- # print 'digest: ',AUTHORIZATION.group(2)
- else:
- print 'unknown/unsupported auth method: %s' % scheme
- self.handle_unauthorized()
- else:
- # list both? prefer one or the other?
- # you could also use a 'nonce' here. [see below]
- #auth = 'Basic realm="%s" Digest realm="%s"' % (self.realm, self.realm)
- #nonce = self.make_nonce (request)
- #auth = 'Digest realm="%s" nonce="%s"' % (self.realm, nonce)
- #request['WWW-Authenticate'] = auth
- #print 'sending header: %s' % request['WWW-Authenticate']
- self.handle_unauthorized (request)
-
- def handle_unauthorized (self, request):
- # We are now going to receive data that we want to ignore.
- # to ignore the file data we're not interested in.
- self.fail_count.increment()
- request.channel.set_terminator (None)
- request['Connection'] = 'close'
- request['WWW-Authenticate'] = 'Basic realm="%s"' % self.realm
- request.error (401)
-
- def make_nonce (self, request):
- "A digest-authentication <nonce>, constructed as suggested in RFC 2069"
- ip = request.channel.server.ip
- now = str (long (time.time()))[:-1]
- private_key = str (id (self))
- nonce = string.join ([ip, now, private_key], ':')
- return self.apply_hash (nonce)
-
- def apply_hash (self, s):
- "Apply MD5 to a string <s>, then wrap it in base64 encoding."
- m = md5.new()
- m.update (s)
- d = m.digest()
- # base64.encodestring tacks on an extra linefeed.
- return base64.encodestring (d)[:-1]
-
- def status (self):
- # Thanks to mwm@contessa.phone.net (Mike Meyer)
- r = [
- producers.simple_producer (
- '<li>Authorization Extension : '
- '<b>Unauthorized requests:</b> %s<ul>' % self.fail_count
- )
- ]
- if hasattr (self.handler, 'status'):
- r.append (self.handler.status())
- r.append (
- producers.simple_producer ('</ul>')
- )
- return producers.composite_producer (
- http_server.fifo (r)
- )
-
-class dictionary_authorizer:
- def __init__ (self, dict):
- self.dict = dict
-
- def authorize (self, auth_info):
- [username, password] = auth_info
- if (self.dict.has_key (username)) and (self.dict[username] == password):
- return 1
- else:
- return 0
-
-AUTHORIZATION = re.compile (
- # scheme challenge
- 'Authorization: ([^ ]+) (.*)',
- re.IGNORECASE
- )
diff --git a/demo/medusa/ca.pem b/demo/medusa/ca.pem
deleted file mode 100644
index b7c84a1..0000000
--- a/demo/medusa/ca.pem
+++ /dev/null
@@ -1,20 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDWTCCAsKgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBgDELMAkGA1UEBhMCU0cx
-ETAPBgNVBAoTCE0yQ3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UE
-AxMbTTJDcnlwdG8gQ2VydGlmaWNhdGUgTWFzdGVyMSIwIAYJKoZIhvcNAQkBFhNu
-Z3BzQG5ldG1lbWV0aWMuY29tMB4XDTAxMTIxNTA1NTU0NloXDTA0MTIxNDA1NTU0
-NlowgYAxCzAJBgNVBAYTAlNHMREwDwYDVQQKEwhNMkNyeXB0bzEUMBIGA1UECxML
-TTJDcnlwdG8gQ0ExJDAiBgNVBAMTG00yQ3J5cHRvIENlcnRpZmljYXRlIE1hc3Rl
-cjEiMCAGCSqGSIb3DQEJARYTbmdwc0BuZXRtZW1ldGljLmNvbTCBnzANBgkqhkiG
-9w0BAQEFAAOBjQAwgYkCgYEAx8soJbS719LHK62VVVIQeC3oW0HvFArwPnA0LuEK
-q+LaqMOJg1rS7hvFdX03diV+XJw7cC0iECZYJNG4ii1xbY6KRmufkInaAwm54E3N
-e+YYVocaqUkcN6xVf6fwnLfPXbpFS/K2Umg11ObKMmi80JmiIdjcjRRCQZC7g1hf
-q+kCAwEAAaOB4DCB3TAdBgNVHQ4EFgQU6/qcBzEtQphfXLhiOHbt2KqBwMIwga0G
-A1UdIwSBpTCBooAU6/qcBzEtQphfXLhiOHbt2KqBwMKhgYakgYMwgYAxCzAJBgNV
-BAYTAlNHMREwDwYDVQQKEwhNMkNyeXB0bzEUMBIGA1UECxMLTTJDcnlwdG8gQ0Ex
-JDAiBgNVBAMTG00yQ3J5cHRvIENlcnRpZmljYXRlIE1hc3RlcjEiMCAGCSqGSIb3
-DQEJARYTbmdwc0BuZXRtZW1ldGljLmNvbYIBADAMBgNVHRMEBTADAQH/MA0GCSqG
-SIb3DQEBBAUAA4GBAD+I14GuS5vJmyv1k7mUMbAicsWRHZ+zrGOq9L/L2LsA+lKQ
-dAzEZE2+Zv8LBPJVltbJJhcFNJS/ZMAjEm4xlJuCpvXVMxd/M5AM29aqekWlIK7J
-vsdDL8IuzpRkMniUiNKPhmB6IPIOslvUKx6QofcE0wDh6pg4VvIbCjkpZ7gf
------END CERTIFICATE-----
diff --git a/demo/medusa/counter.py b/demo/medusa/counter.py
deleted file mode 100644
index 997d687..0000000
--- a/demo/medusa/counter.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# -*- Mode: Python; tab-width: 4 -*-
-
-# It is tempting to add an __int__ method to this class, but it's not
-# a good idea. This class tries to gracefully handle integer
-# overflow, and to hide this detail from both the programmer and the
-# user. Note that the __str__ method can be relied on for printing out
-# the value of a counter:
-#
-# >>> print 'Total Client: %s' % self.total_clients
-#
-# If you need to do arithmetic with the value, then use the 'as_long'
-# method, the use of long arithmetic is a reminder that the counter
-# will overflow.
-
-class counter:
- "general-purpose counter"
-
- def __init__ (self, initial_value=0):
- self.value = initial_value
-
- def increment (self, delta=1):
- result = self.value
- try:
- self.value = self.value + delta
- except OverflowError:
- self.value = long(self.value) + delta
- return result
-
- def decrement (self, delta=1):
- result = self.value
- try:
- self.value = self.value - delta
- except OverflowError:
- self.value = long(self.value) - delta
- return result
-
- def as_long (self):
- return long(self.value)
-
- def __nonzero__ (self):
- return self.value != 0
-
- def __repr__ (self):
- return '<counter value=%s at %x>' % (self.value, id(self))
-
- def __str__ (self):
- return str(long(self.value))
- #return str(long(self.value))[:-1]
diff --git a/demo/medusa/default_handler.py b/demo/medusa/default_handler.py
deleted file mode 100644
index 4585b0f..0000000
--- a/demo/medusa/default_handler.py
+++ /dev/null
@@ -1,215 +0,0 @@
-# -*- Mode: Python; tab-width: 4 -*-
-#
-# Author: Sam Rushing <rushing@nightmare.com>
-# Copyright 1997 by Sam Rushing
-# All Rights Reserved.
-#
-
-# standard python modules
-import os
-import re
-import posixpath
-import stat
-import string
-import time
-
-# medusa modules
-import http_date
-import http_server
-import mime_type_table
-import status_handler
-import producers
-
-unquote = http_server.unquote
-
-# This is the 'default' handler. it implements the base set of
-# features expected of a simple file-delivering HTTP server. file
-# services are provided through a 'filesystem' object, the very same
-# one used by the FTP server.
-#
-# You can replace or modify this handler if you want a non-standard
-# HTTP server. You can also derive your own handler classes from
-# it.
-#
-# support for handling POST requests is available in the derived
-# class <default_with_post_handler>, defined below.
-#
-
-from counter import counter
-
-class default_handler:
-
- valid_commands = ['get', 'head']
-
- IDENT = 'Default HTTP Request Handler'
-
- # Pathnames that are tried when a URI resolves to a directory name
- directory_defaults = [
- 'index.html',
- 'default.html'
- ]
-
- default_file_producer = producers.file_producer
-
- def __init__ (self, filesystem):
- self.filesystem = filesystem
- # count total hits
- self.hit_counter = counter()
- # count file deliveries
- self.file_counter = counter()
- # count cache hits
- self.cache_counter = counter()
-
- hit_counter = 0
-
- def __repr__ (self):
- return '<%s (%s hits) at %x>' % (
- self.IDENT,
- self.hit_counter,
- id (self)
- )
-
- # always match, since this is a default
- def match (self, request):
- return 1
-
- # handle a file request, with caching.
-
- def handle_request (self, request):
-
- if request.command not in self.valid_commands:
- request.error (400) # bad request
- return
-
- self.hit_counter.increment()
-
- path, params, query, fragment = request.split_uri()
-
- if '%' in path:
- path = unquote (path)
-
- # strip off all leading slashes
- while path and path[0] == '/':
- path = path[1:]
-
- if self.filesystem.isdir (path):
- if path and path[-1] != '/':
- request['Location'] = 'http://%s/%s/' % (
- request.channel.server.server_name,
- path
- )
- request.error (301)
- return
-
- # we could also generate a directory listing here,
- # may want to move this into another method for that
- # purpose
- found = 0
- if path and path[-1] != '/':
- path = path + '/'
- for default in self.directory_defaults:
- p = path + default
- if self.filesystem.isfile (p):
- path = p
- found = 1
- break
- if not found:
- request.error (404) # Not Found
- return
-
- elif not self.filesystem.isfile (path):
- request.error (404) # Not Found
- return
-
- file_length = self.filesystem.stat (path)[stat.ST_SIZE]
-
- ims = get_header_match (IF_MODIFIED_SINCE, request.header)
-
- length_match = 1
- if ims:
- length = ims.group (4)
- if length:
- try:
- length = string.atoi (length)
- if length != file_length:
- length_match = 0
- except:
- pass
-
- ims_date = 0
-
- if ims:
- ims_date = http_date.parse_http_date (ims.group (1))
-
- try:
- mtime = self.filesystem.stat (path)[stat.ST_MTIME]
- except:
- request.error (404)
- return
-
- if length_match and ims_date:
- if mtime <= ims_date:
- request.reply_code = 304
- request.done()
- self.cache_counter.increment()
- return
- try:
- file = self.filesystem.open (path, 'rb')
- except IOError:
- request.error (404)
- return
-
- request['Last-Modified'] = http_date.build_http_date (mtime)
- request['Content-Length'] = file_length
- self.set_content_type (path, request)
-
- if request.command == 'get':
- request.push (self.default_file_producer (file))
-
- self.file_counter.increment()
- request.done()
-
- def set_content_type (self, path, request):
- ext = string.lower (get_extension (path))
- if mime_type_table.content_type_map.has_key (ext):
- request['Content-Type'] = mime_type_table.content_type_map[ext]
- else:
- # TODO: test a chunk off the front of the file for 8-bit
- # characters, and use application/octet-stream instead.
- request['Content-Type'] = 'text/plain'
-
- def status (self):
- return producers.simple_producer (
- '<li>%s' % status_handler.html_repr (self)
- + '<ul>'
- + ' <li><b>Total Hits:</b> %s' % self.hit_counter
- + ' <li><b>Files Delivered:</b> %s' % self.file_counter
- + ' <li><b>Cache Hits:</b> %s' % self.cache_counter
- + '</ul>'
- )
-
-# HTTP/1.0 doesn't say anything about the "; length=nnnn" addition
-# to this header. I suppose it's purpose is to avoid the overhead
-# of parsing dates...
-IF_MODIFIED_SINCE = re.compile (
- 'If-Modified-Since: ([^;]+)((; length=([0-9]+)$)|$)',
- re.IGNORECASE
- )
-
-USER_AGENT = re.compile ('User-Agent: (.*)', re.IGNORECASE)
-
-CONTENT_TYPE = re.compile (
- r'Content-Type: ([^;]+)((; boundary=([A-Za-z0-9\'\(\)+_,./:=?-]+)$)|$)',
- re.IGNORECASE
- )
-
-get_header = http_server.get_header
-get_header_match = http_server.get_header_match
-
-def get_extension (path):
- dirsep = string.rfind (path, '/')
- dotsep = string.rfind (path, '.')
- if dotsep > dirsep:
- return path[dotsep+1:]
- else:
- return ''
diff --git a/demo/medusa/dh1024.pem b/demo/medusa/dh1024.pem
deleted file mode 100644
index 81d43f6..0000000
--- a/demo/medusa/dh1024.pem
+++ /dev/null
@@ -1,5 +0,0 @@
------BEGIN DH PARAMETERS-----
-MIGHAoGBAJf2QmHKtQXdKCjhPx1ottPb0PMTBH9A6FbaWMsTuKG/K3g6TG1Z1fkq
-/Gz/PWk/eLI9TzFgqVAuPvr3q14a1aZeVUMTgo2oO5/y2UHe6VaJ+trqCTat3xlx
-/mNbIK9HA2RgPC3gWfVLZQrY+gz3ASHHR5nXWHEyvpuZm7m3h+irAgEC
------END DH PARAMETERS-----
diff --git a/demo/medusa/filesys.py b/demo/medusa/filesys.py
deleted file mode 100644
index 003af2e..0000000
--- a/demo/medusa/filesys.py
+++ /dev/null
@@ -1,466 +0,0 @@
-# -*- Mode: Python; tab-width: 4 -*-
-# $Id: filesys.py 299 2005-06-09 17:32:28Z heikki $
-# Author: Sam Rushing <rushing@nightmare.com>
-#
-# Generic filesystem interface.
-#
-
-# We want to provide a complete wrapper around any and all
-# filesystem operations.
-
-# this class is really just for documentation,
-# identifying the API for a filesystem object.
-
-# opening files for reading, and listing directories, should
-# return a producer.
-
-class abstract_filesystem:
- def __init__ (self):
- pass
-
- def current_directory (self):
- "Return a string representing the current directory."
- pass
-
- def listdir (self, path, long=0):
- """Return a listing of the directory at 'path' The empty string
- indicates the current directory. If 'long' is set, instead
- return a list of (name, stat_info) tuples
- """
- pass
-
- def open (self, path, mode):
- "Return an open file object"
- pass
-
- def stat (self, path):
- "Return the equivalent of os.stat() on the given path."
- pass
-
- def isdir (self, path):
- "Does the path represent a directory?"
- pass
-
- def isfile (self, path):
- "Does the path represent a plain file?"
- pass
-
- def cwd (self, path):
- "Change the working directory."
- pass
-
- def cdup (self):
- "Change to the parent of the current directory."
- pass
-
-
- def longify (self, path):
- """Return a 'long' representation of the filename
- [for the output of the LIST command]"""
- pass
-
-# standard wrapper around a unix-like filesystem, with a 'false root'
-# capability.
-
-# security considerations: can symbolic links be used to 'escape' the
-# root? should we allow it? if not, then we could scan the
-# filesystem on startup, but that would not help if they were added
-# later. We will probably need to check for symlinks in the cwd method.
-
-# what to do if wd is an invalid directory?
-
-import os
-import stat
-
-import string
-
-def safe_stat (path):
- try:
- return (path, os.stat (path))
- except:
- return None
-
-import regsub
-import glob
-
-class os_filesystem:
- path_module = os.path
-
- # set this to zero if you want to disable pathname globbing.
- # [we currently don't glob, anyway]
- do_globbing = 1
-
- def __init__ (self, root, wd='/'):
- self.root = root
- self.wd = wd
-
- def current_directory (self):
- return self.wd
-
- def isfile (self, path):
- p = self.normalize (self.path_module.join (self.wd, path))
- return self.path_module.isfile (self.translate(p))
-
- def isdir (self, path):
- p = self.normalize (self.path_module.join (self.wd, path))
- return self.path_module.isdir (self.translate(p))
-
- def cwd (self, path):
- p = self.normalize (self.path_module.join (self.wd, path))
- translated_path = self.translate(p)
- if not self.path_module.isdir (translated_path):
- return 0
- else:
- old_dir = os.getcwd()
- # temporarily change to that directory, in order
- # to see if we have permission to do so.
- try:
- can = 0
- try:
- os.chdir (translated_path)
- can = 1
- self.wd = p
- except:
- pass
- finally:
- if can:
- os.chdir (old_dir)
- return can
-
- def cdup (self):
- return self.cwd ('..')
-
- def listdir (self, path, long=0):
- p = self.translate (path)
- # I think we should glob, but limit it to the current
- # directory only.
- ld = os.listdir (p)
- if not long:
- return list_producer (ld, 0, None)
- else:
- old_dir = os.getcwd()
- try:
- os.chdir (p)
- # if os.stat fails we ignore that file.
- result = filter (None, map (safe_stat, ld))
- finally:
- os.chdir (old_dir)
- return list_producer (result, 1, self.longify)
-
- # TODO: implement a cache w/timeout for stat()
- def stat (self, path):
- p = self.translate (path)
- return os.stat (p)
-
- def open (self, path, mode):
- p = self.translate (path)
- return open (p, mode)
-
- def unlink (self, path):
- p = self.translate (path)
- return os.unlink (p)
-
- def mkdir (self, path):
- p = self.translate (path)
- return os.mkdir (p)
-
- def rmdir (self, path):
- p = self.translate (path)
- return os.rmdir (p)
-
- # utility methods
- def normalize (self, path):
- # watch for the ever-sneaky '/+' path element
- path = regsub.gsub ('/+', '/', path)
- p = self.path_module.normpath (path)
- # remove 'dangling' cdup's.
- if len(p) > 2 and p[:3] == '/..':
- p = '/'
- return p
-
- def translate (self, path):
- # we need to join together three separate
- # path components, and do it safely.
- # <real_root>/<current_directory>/<path>
- # use the operating system's path separator.
- path = string.join (string.split (path, '/'), os.sep)
- p = self.normalize (self.path_module.join (self.wd, path))
- p = self.normalize (self.path_module.join (self.root, p[1:]))
- return p
-
- def longify (self, (path, stat_info)):
- return unix_longify (path, stat_info)
-
- def __repr__ (self):
- return '<unix-style fs root:%s wd:%s>' % (
- self.root,
- self.wd
- )
-
-if os.name == 'posix':
-
- class unix_filesystem (os_filesystem):
- pass
-
- class schizophrenic_unix_filesystem (os_filesystem):
- PROCESS_UID = os.getuid()
- PROCESS_EUID = os.geteuid()
- PROCESS_GID = os.getgid()
- PROCESS_EGID = os.getegid()
-
- def __init__ (self, root, wd='/', persona=(None, None)):
- os_filesystem.__init__ (self, root, wd)
- self.persona = persona
-
- def become_persona (self):
- if self.persona is not (None, None):
- uid, gid = self.persona
- # the order of these is important!
- os.setegid (gid)
- os.seteuid (uid)
-
- def become_nobody (self):
- if self.persona is not (None, None):
- os.seteuid (self.PROCESS_UID)
- os.setegid (self.PROCESS_GID)
-
- # cwd, cdup, open, listdir
- def cwd (self, path):
- try:
- self.become_persona()
- return os_filesystem.cwd (self, path)
- finally:
- self.become_nobody()
-
- def cdup (self, path):
- try:
- self.become_persona()
- return os_filesystem.cdup (self)
- finally:
- self.become_nobody()
-
- def open (self, filename, mode):
- try:
- self.become_persona()
- return os_filesystem.open (self, filename, mode)
- finally:
- self.become_nobody()
-
- def listdir (self, path, long=0):
- try:
- self.become_persona()
- return os_filesystem.listdir (self, path, long)
- finally:
- self.become_nobody()
-
-# This hasn't been very reliable across different platforms.
-# maybe think about a separate 'directory server'.
-#
-# import posixpath
-# import fcntl
-# import FCNTL
-# import select
-# import asyncore
-#
-# # pipes /bin/ls for directory listings.
-# class unix_filesystem (os_filesystem):
-# pass
-# path_module = posixpath
-#
-# def listdir (self, path, long=0):
-# p = self.translate (path)
-# if not long:
-# return list_producer (os.listdir (p), 0, None)
-# else:
-# command = '/bin/ls -l %s' % p
-# print 'opening pipe to "%s"' % command
-# fd = os.popen (command, 'rt')
-# return pipe_channel (fd)
-#
-# # this is both a dispatcher, _and_ a producer
-# class pipe_channel (asyncore.file_dispatcher):
-# buffer_size = 4096
-#
-# def __init__ (self, fd):
-# asyncore.file_dispatcher.__init__ (self, fd)
-# self.fd = fd
-# self.done = 0
-# self.data = ''
-#
-# def handle_read (self):
-# if len (self.data) < self.buffer_size:
-# self.data = self.data + self.fd.read (self.buffer_size)
-# #print '%s.handle_read() => len(self.data) == %d' % (self, len(self.data))
-#
-# def handle_expt (self):
-# #print '%s.handle_expt()' % self
-# self.done = 1
-#
-# def ready (self):
-# #print '%s.ready() => %d' % (self, len(self.data))
-# return ((len (self.data) > 0) or self.done)
-#
-# def more (self):
-# if self.data:
-# r = self.data
-# self.data = ''
-# elif self.done:
-# self.close()
-# self.downstream.finished()
-# r = ''
-# else:
-# r = None
-# #print '%s.more() => %s' % (self, (r and len(r)))
-# return r
-
-# For the 'real' root, we could obtain a list of drives, and then
-# use that. Doesn't win32 provide such a 'real' filesystem?
-# [yes, I think something like this "\\.\c\windows"]
-
-class msdos_filesystem (os_filesystem):
- def longify (self, (path, stat_info)):
- return msdos_longify (path, stat_info)
-
-# A merged filesystem will let you plug other filesystems together.
-# We really need the equivalent of a 'mount' capability - this seems
-# to be the most general idea. So you'd use a 'mount' method to place
-# another filesystem somewhere in the hierarchy.
-
-# Note: this is most likely how I will handle ~user directories
-# with the http server.
-
-class merged_filesystem:
- def __init__ (self, *fsys):
- pass
-
-# this matches the output of NT's ftp server (when in
-# MSDOS mode) exactly.
-
-def msdos_longify (file, stat_info):
- if stat.S_ISDIR (stat_info[stat.ST_MODE]):
- dir = '<DIR>'
- else:
- dir = ' '
- date = msdos_date (stat_info[stat.ST_MTIME])
- return '%s %s %8d %s' % (
- date,
- dir,
- stat_info[stat.ST_SIZE],
- file
- )
-
-def msdos_date (t):
- try:
- info = time.gmtime (t)
- except:
- info = time.gmtime (0)
- # year, month, day, hour, minute, second, ...
- if info[3] > 11:
- merid = 'PM'
- info[3] = info[3] - 12
- else:
- merid = 'AM'
- return '%02d-%02d-%02d %02d:%02d%s' % (
- info[1],
- info[2],
- info[0]%100,
- info[3],
- info[4],
- merid
- )
-
-months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
- 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
-
-mode_table = {
- '0':'---',
- '1':'--x',
- '2':'-w-',
- '3':'-wx',
- '4':'r--',
- '5':'r-x',
- '6':'rw-',
- '7':'rwx'
- }
-
-import time
-
-def unix_longify (file, stat_info):
- # for now, only pay attention to the lower bits
- mode = ('%o' % stat_info[stat.ST_MODE])[-3:]
- mode = string.join (map (lambda x: mode_table[x], mode), '')
- if stat.S_ISDIR (stat_info[stat.ST_MODE]):
- dirchar = 'd'
- else:
- dirchar = '-'
- date = ls_date (long(time.time()), stat_info[stat.ST_MTIME])
- return '%s%s %3d %-8d %-8d %8d %s %s' % (
- dirchar,
- mode,
- stat_info[stat.ST_NLINK],
- stat_info[stat.ST_UID],
- stat_info[stat.ST_GID],
- stat_info[stat.ST_SIZE],
- date,
- file
- )
-
-# Emulate the unix 'ls' command's date field.
-# it has two formats - if the date is more than 180
-# days in the past, then it's like this:
-# Oct 19 1995
-# otherwise, it looks like this:
-# Oct 19 17:33
-
-def ls_date (now, t):
- try:
- info = time.gmtime (t)
- except:
- info = time.gmtime (0)
- # 15,600,000 == 86,400 * 180
- if (now - t) > 15600000:
- return '%s %2d %d' % (
- months[info[1]-1],
- info[2],
- info[0]
- )
- else:
- return '%s %2d %02d:%02d' % (
- months[info[1]-1],
- info[2],
- info[3],
- info[4]
- )
-
-# ===========================================================================
-# Producers
-# ===========================================================================
-
-class list_producer:
- def __init__ (self, file_list, long, longify):
- self.file_list = file_list
- self.long = long
- self.longify = longify
- self.done = 0
-
- def ready (self):
- if len(self.file_list):
- return 1
- else:
- if not self.done:
- self.done = 1
- return 0
- return (len(self.file_list) > 0)
-
- # this should do a pushd/popd
- def more (self):
- if not self.file_list:
- return ''
- else:
- # do a few at a time
- bunch = self.file_list[:50]
- if self.long:
- bunch = map (self.longify, bunch)
- self.file_list = self.file_list[50:]
- return string.joinfields (bunch, '\r\n') + '\r\n'
-
diff --git a/demo/medusa/ftp_server.py b/demo/medusa/ftp_server.py
deleted file mode 100644
index 78363cf..0000000
--- a/demo/medusa/ftp_server.py
+++ /dev/null
@@ -1,1127 +0,0 @@
-# -*- Mode: Python; tab-width: 4 -*-
-
-# Author: Sam Rushing <rushing@nightmare.com>
-# Copyright 1996-2000 by Sam Rushing
-# All Rights Reserved.
-#
-
-# An extensible, configurable, asynchronous FTP server.
-#
-# All socket I/O is non-blocking, however file I/O is currently
-# blocking. Eventually file I/O may be made non-blocking, too, if it
-# seems necessary. Currently the only CPU-intensive operation is
-# getting and formatting a directory listing. [this could be moved
-# into another process/directory server, or another thread?]
-#
-# Only a subset of RFC 959 is implemented, but much of that RFC is
-# vestigial anyway. I've attempted to include the most commonly-used
-# commands, using the feature set of wu-ftpd as a guide.
-
-import asyncore
-import asynchat
-
-import os
-import regsub
-import socket
-import stat
-import string
-import sys
-import time
-
-# TODO: implement a directory listing cache. On very-high-load
-# servers this could save a lot of disk abuse, and possibly the
-# work of computing emulated unix ls output.
-
-# Potential security problem with the FTP protocol? I don't think
-# there's any verification of the origin of a data connection. Not
-# really a problem for the server (since it doesn't send the port
-# command, except when in PASV mode) But I think a data connection
-# could be spoofed by a program with access to a sniffer - it could
-# watch for a PORT command to go over a command channel, and then
-# connect to that port before the server does.
-
-# Unix user id's:
-# In order to support assuming the id of a particular user,
-# it seems there are two options:
-# 1) fork, and seteuid in the child
-# 2) carefully control the effective uid around filesystem accessing
-# methods, using try/finally. [this seems to work]
-
-VERSION = '1.1'
-
-from counter import counter
-import producers
-import status_handler
-import logger
-import string
-
-class ftp_channel (asynchat.async_chat):
-
- # defaults for a reliable __repr__
- addr = ('unknown','0')
-
- # unset this in a derived class in order
- # to enable the commands in 'self.write_commands'
- read_only = 1
- write_commands = ['appe','dele','mkd','rmd','rnfr','rnto','stor','stou']
-
- restart_position = 0
-
- # comply with (possibly troublesome) RFC959 requirements
- # This is necessary to correctly run an active data connection
- # through a firewall that triggers on the source port (expected
- # to be 'L-1', or 20 in the normal case).
- bind_local_minus_one = 0
-
- def __init__ (self, server, conn, addr):
- self.server = server
- self.current_mode = 'a'
- self.addr = addr
- asynchat.async_chat.__init__ (self, conn)
- self.set_terminator ('\r\n')
-
- # client data port. Defaults to 'the same as the control connection'.
- self.client_addr = (addr[0], 21)
-
- self.client_dc = None
- self.in_buffer = ''
- self.closing = 0
- self.passive_acceptor = None
- self.passive_connection = None
- self.filesystem = None
- self.authorized = 0
- # send the greeting
- self.respond (
- '220 %s FTP server (Medusa Async V%s [experimental]) ready.' % (
- self.server.hostname,
- VERSION
- )
- )
-
-# def __del__ (self):
-# print 'ftp_channel.__del__()'
-
- # --------------------------------------------------
- # async-library methods
- # --------------------------------------------------
-
- def handle_expt (self):
- # this is handled below. not sure what I could
- # do here to make that code less kludgish.
- pass
-
- def collect_incoming_data (self, data):
- self.in_buffer = self.in_buffer + data
- if len(self.in_buffer) > 4096:
- # silently truncate really long lines
- # (possible denial-of-service attack)
- self.in_buffer = ''
-
- def found_terminator (self):
-
- line = self.in_buffer
-
- if not len(line):
- return
-
- sp = string.find (line, ' ')
- if sp != -1:
- line = [line[:sp], line[sp+1:]]
- else:
- line = [line]
-
- command = string.lower (line[0])
- # watch especially for 'urgent' abort commands.
- if string.find (command, 'abor') != -1:
- # strip off telnet sync chars and the like...
- while command and command[0] not in string.letters:
- command = command[1:]
- fun_name = 'cmd_%s' % command
- if command != 'pass':
- self.log ('<== %s' % repr(self.in_buffer)[1:-1])
- else:
- self.log ('<== %s' % line[0]+' <password>')
- self.in_buffer = ''
- if not hasattr (self, fun_name):
- self.command_not_understood (line[0])
- return
- fun = getattr (self, fun_name)
- if (not self.authorized) and (command not in ('user', 'pass', 'help', 'quit')):
- self.respond ('530 Please log in with USER and PASS')
- elif (not self.check_command_authorization (command)):
- self.command_not_authorized (command)
- else:
- try:
- result = apply (fun, (line,))
- except:
- self.server.total_exceptions.increment()
- (file, fun, line), t,v, tbinfo = asyncore.compact_traceback()
- if self.client_dc:
- try:
- self.client_dc.close()
- except:
- pass
- self.respond (
- '451 Server Error: %s, %s: file: %s line: %s' % (
- t,v,file,line,
- )
- )
-
- closed = 0
- def close (self):
- if not self.closed:
- self.closed = 1
- if self.passive_acceptor:
- self.passive_acceptor.close()
- if self.client_dc:
- self.client_dc.close()
- self.server.closed_sessions.increment()
- asynchat.async_chat.close (self)
-
- # --------------------------------------------------
- # filesystem interface functions.
- # override these to provide access control or perform
- # other functions.
- # --------------------------------------------------
-
- def cwd (self, line):
- return self.filesystem.cwd (line[1])
-
- def cdup (self, line):
- return self.filesystem.cdup()
-
- def open (self, path, mode):
- return self.filesystem.open (path, mode)
-
- # returns a producer
- def listdir (self, path, long=0):
- return self.filesystem.listdir (path, long)
-
- def get_dir_list (self, line, long=0):
- # we need to scan the command line for arguments to '/bin/ls'...
- args = line[1:]
- path_args = []
- for arg in args:
- if arg[0] != '-':
- path_args.append (arg)
- else:
- # ignore arguments
- pass
- if len(path_args) < 1:
- dir = '.'
- else:
- dir = path_args[0]
- return self.listdir (dir, long)
-
- # --------------------------------------------------
- # authorization methods
- # --------------------------------------------------
-
- def check_command_authorization (self, command):
- if command in self.write_commands and self.read_only:
- return 0
- else:
- return 1
-
- # --------------------------------------------------
- # utility methods
- # --------------------------------------------------
-
- def log (self, message):
- self.server.logger.log (
- self.addr[0],
- '%d %s' % (
- self.addr[1], message
- )
- )
-
- def respond (self, resp):
- self.log ('==> %s' % resp)
- self.push (resp + '\r\n')
-
- def command_not_understood (self, command):
- self.respond ("500 '%s': command not understood." % command)
-
- def command_not_authorized (self, command):
- self.respond (
- "530 You are not authorized to perform the '%s' command" % (
- command
- )
- )
-
- def make_xmit_channel (self):
- # In PASV mode, the connection may or may _not_ have been made
- # yet. [although in most cases it is... FTP Explorer being
- # the only exception I've yet seen]. This gets somewhat confusing
- # because things may happen in any order...
- pa = self.passive_acceptor
- if pa:
- if pa.ready:
- # a connection has already been made.
- conn, addr = self.passive_acceptor.ready
- cdc = xmit_channel (self, addr)
- cdc.set_socket (conn)
- cdc.connected = 1
- self.passive_acceptor.close()
- self.passive_acceptor = None
- else:
- # we're still waiting for a connect to the PASV port.
- cdc = xmit_channel (self)
- else:
- # not in PASV mode.
- ip, port = self.client_addr
- cdc = xmit_channel (self, self.client_addr)
- cdc.create_socket (socket.AF_INET, socket.SOCK_STREAM)
- if self.bind_local_minus_one:
- cdc.bind (('', self.server.port - 1))
- try:
- cdc.connect ((ip, port))
- except socket.error, why:
- self.respond ("425 Can't build data connection")
- self.client_dc = cdc
-
- # pretty much the same as xmit, but only right on the verge of
- # being worth a merge.
- def make_recv_channel (self, fd):
- pa = self.passive_acceptor
- if pa:
- if pa.ready:
- # a connection has already been made.
- conn, addr = pa.ready
- cdc = recv_channel (self, addr, fd)
- cdc.set_socket (conn)
- cdc.connected = 1
- self.passive_acceptor.close()
- self.passive_acceptor = None
- else:
- # we're still waiting for a connect to the PASV port.
- cdc = recv_channel (self, None, fd)
- else:
- # not in PASV mode.
- ip, port = self.client_addr
- cdc = recv_channel (self, self.client_addr, fd)
- cdc.create_socket (socket.AF_INET, socket.SOCK_STREAM)
- try:
- cdc.connect ((ip, port))
- except socket.error, why:
- self.respond ("425 Can't build data connection")
- self.client_dc = cdc
-
- type_map = {
- 'a':'ASCII',
- 'i':'Binary',
- 'e':'EBCDIC',
- 'l':'Binary'
- }
-
- type_mode_map = {
- 'a':'t',
- 'i':'b',
- 'e':'b',
- 'l':'b'
- }
-
- # --------------------------------------------------
- # command methods
- # --------------------------------------------------
-
- def cmd_type (self, line):
- 'specify data transfer type'
- # ascii, ebcdic, image, local <byte size>
- t = string.lower (line[1])
- # no support for EBCDIC
- # if t not in ['a','e','i','l']:
- if t not in ['a','i','l']:
- self.command_not_understood (string.join (line))
- elif t == 'l' and (len(line) > 2 and line[2] != '8'):
- self.respond ('504 Byte size must be 8')
- else:
- self.current_mode = t
- self.respond ('200 Type set to %s.' % self.type_map[t])
-
-
- def cmd_quit (self, line):
- 'terminate session'
- self.respond ('221 Goodbye.')
- self.close_when_done()
-
- def cmd_port (self, line):
- 'specify data connection port'
- info = string.split (line[1], ',')
- ip = string.join (info[:4], '.')
- port = string.atoi(info[4])*256 + string.atoi(info[5])
- # how many data connections at a time?
- # I'm assuming one for now...
- # TODO: we should (optionally) verify that the
- # ip number belongs to the client. [wu-ftpd does this?]
- self.client_addr = (ip, port)
- self.respond ('200 PORT command successful.')
-
- def new_passive_acceptor (self):
- # ensure that only one of these exists at a time.
- if self.passive_acceptor is not None:
- self.passive_acceptor.close()
- self.passive_acceptor = None
- self.passive_acceptor = passive_acceptor (self)
- return self.passive_acceptor
-
- def cmd_pasv (self, line):
- 'prepare for server-to-server transfer'
- pc = self.new_passive_acceptor()
- port = pc.addr[1]
- ip_addr = pc.control_channel.getsockname()[0]
- self.respond (
- '227 Entering Passive Mode (%s,%d,%d)' % (
- string.join (string.split (ip_addr, '.'), ','),
- port/256,
- port%256
- )
- )
- self.client_dc = None
-
- def cmd_nlst (self, line):
- 'give name list of files in directory'
- # ncftp adds the -FC argument for the user-visible 'nlist'
- # command. We could try to emulate ls flags, but not just yet.
- if '-FC' in line:
- line.remove ('-FC')
- try:
- dir_list_producer = self.get_dir_list (line, 0)
- except os.error, why:
- self.respond ('550 Could not list directory: %s' % repr(why))
- return
- self.respond (
- '150 Opening %s mode data connection for file list' % (
- self.type_map[self.current_mode]
- )
- )
- self.make_xmit_channel()
- self.client_dc.push_with_producer (dir_list_producer)
- self.client_dc.close_when_done()
-
- def cmd_list (self, line):
- 'give list files in a directory'
- try:
- dir_list_producer = self.get_dir_list (line, 1)
- except os.error, why:
- self.respond ('550 Could not list directory: %s' % repr(why))
- return
- self.respond (
- '150 Opening %s mode data connection for file list' % (
- self.type_map[self.current_mode]
- )
- )
- self.make_xmit_channel()
- self.client_dc.push_with_producer (dir_list_producer)
- self.client_dc.close_when_done()
-
- def cmd_cwd (self, line):
- 'change working directory'
- if self.cwd (line):
- self.respond ('250 CWD command successful.')
- else:
- self.respond ('550 No such directory.')
-
- def cmd_cdup (self, line):
- 'change to parent of current working directory'
- if self.cdup(line):
- self.respond ('250 CDUP command successful.')
- else:
- self.respond ('550 No such directory.')
-
- def cmd_pwd (self, line):
- 'print the current working directory'
- self.respond (
- '257 "%s" is the current directory.' % (
- self.filesystem.current_directory()
- )
- )
-
- # modification time
- # example output:
- # 213 19960301204320
- def cmd_mdtm (self, line):
- 'show last modification time of file'
- filename = line[1]
- if not self.filesystem.isfile (filename):
- self.respond ('550 "%s" is not a file' % filename)
- else:
- mtime = time.gmtime(self.filesystem.stat(filename)[stat.ST_MTIME])
- self.respond (
- '213 %4d%02d%02d%02d%02d%02d' % (
- mtime[0],
- mtime[1],
- mtime[2],
- mtime[3],
- mtime[4],
- mtime[5]
- )
- )
-
- def cmd_noop (self, line):
- 'do nothing'
- self.respond ('200 NOOP command successful.')
-
- def cmd_size (self, line):
- 'return size of file'
- filename = line[1]
- if not self.filesystem.isfile (filename):
- self.respond ('550 "%s" is not a file' % filename)
- else:
- self.respond (
- '213 %d' % (self.filesystem.stat(filename)[stat.ST_SIZE])
- )
-
- def cmd_retr (self, line):
- 'retrieve a file'
- if len(line) < 2:
- self.command_not_understood (string.join (line))
- else:
- file = line[1]
- if not self.filesystem.isfile (file):
- self.log_info ('checking %s' % file)
- self.respond ('550 No such file')
- else:
- try:
- # FIXME: for some reason, 'rt' isn't working on win95
- mode = 'r'+self.type_mode_map[self.current_mode]
- fd = self.open (file, mode)
- except IOError, why:
- self.respond ('553 could not open file for reading: %s' % (repr(why)))
- return
- self.respond (
- "150 Opening %s mode data connection for file '%s'" % (
- self.type_map[self.current_mode],
- file
- )
- )
- self.make_xmit_channel()
-
- if self.restart_position:
- # try to position the file as requested, but
- # give up silently on failure (the 'file object'
- # may not support seek())
- try:
- fd.seek (self.restart_position)
- except:
- pass
- self.restart_position = 0
-
- self.client_dc.push_with_producer (
- file_producer (self, self.client_dc, fd)
- )
- self.client_dc.close_when_done()
-
- def cmd_stor (self, line, mode='wb'):
- 'store a file'
- if len (line) < 2:
- self.command_not_understood (string.join (line))
- else:
- if self.restart_position:
- restart_position = 0
- self.respond ('553 restart on STOR not yet supported')
- return
- file = line[1]
- # todo: handle that type flag
- try:
- fd = self.open (file, mode)
- except IOError, why:
- self.respond ('553 could not open file for writing: %s' % (repr(why)))
- return
- self.respond (
- '150 Opening %s connection for %s' % (
- self.type_map[self.current_mode],
- file
- )
- )
- self.make_recv_channel (fd)
-
- def cmd_abor (self, line):
- 'abort operation'
- if self.client_dc:
- self.client_dc.close()
- self.respond ('226 ABOR command successful.')
-
- def cmd_appe (self, line):
- 'append to a file'
- return self.cmd_stor (line, 'ab')
-
- def cmd_dele (self, line):
- if len (line) != 2:
- self.command_not_understood (string.join (line))
- else:
- file = line[1]
- if self.filesystem.isfile (file):
- try:
- self.filesystem.unlink (file)
- self.respond ('250 DELE command successful.')
- except:
- self.respond ('550 error deleting file.')
- else:
- self.respond ('550 %s: No such file.' % file)
-
- def cmd_mkd (self, line):
- if len (line) != 2:
- self.command.not_understood (string.join (line))
- else:
- path = line[1]
- try:
- self.filesystem.mkdir (path)
- self.respond ('257 MKD command successful.')
- except:
- self.respond ('550 error creating directory.')
-
- def cmd_rmd (self, line):
- if len (line) != 2:
- self.command.not_understood (string.join (line))
- else:
- path = line[1]
- try:
- self.filesystem.rmdir (path)
- self.respond ('250 RMD command successful.')
- except:
- self.respond ('550 error removing directory.')
-
- def cmd_user (self, line):
- 'specify user name'
- if len(line) > 1:
- self.user = line[1]
- self.respond ('331 Password required.')
- else:
- self.command_not_understood (string.join (line))
-
- def cmd_pass (self, line):
- 'specify password'
- if len(line) < 2:
- pw = ''
- else:
- pw = line[1]
- result, message, fs = self.server.authorizer.authorize (self, self.user, pw)
- if result:
- self.respond ('230 %s' % message)
- self.filesystem = fs
- self.authorized = 1
- self.log_info('Successful login: Filesystem=%s' % repr(fs))
- else:
- self.respond ('530 %s' % message)
-
- def cmd_rest (self, line):
- 'restart incomplete transfer'
- try:
- pos = string.atoi (line[1])
- except ValueError:
- self.command_not_understood (string.join (line))
- self.restart_position = pos
- self.respond (
- '350 Restarting at %d. Send STORE or RETRIEVE to initiate transfer.' % pos
- )
-
- def cmd_stru (self, line):
- 'obsolete - set file transfer structure'
- if line[1] in 'fF':
- # f == 'file'
- self.respond ('200 STRU F Ok')
- else:
- self.respond ('504 Unimplemented STRU type')
-
- def cmd_mode (self, line):
- 'obsolete - set file transfer mode'
- if line[1] in 'sS':
- # f == 'file'
- self.respond ('200 MODE S Ok')
- else:
- self.respond ('502 Unimplemented MODE type')
-
-# The stat command has two personalities. Normally it returns status
-# information about the current connection. But if given an argument,
-# it is equivalent to the LIST command, with the data sent over the
-# control connection. Strange. But wuftpd, ftpd, and nt's ftp server
-# all support it.
-#
-## def cmd_stat (self, line):
-## 'return status of server'
-## pass
-
- def cmd_syst (self, line):
- 'show operating system type of server system'
- # Replying to this command is of questionable utility, because
- # this server does not behave in a predictable way w.r.t. the
- # output of the LIST command. We emulate Unix ls output, but
- # on win32 the pathname can contain drive information at the front
- # Currently, the combination of ensuring that os.sep == '/'
- # and removing the leading slash when necessary seems to work.
- # [cd'ing to another drive also works]
- #
- # This is how wuftpd responds, and is probably
- # the most expected. The main purpose of this reply is so that
- # the client knows to expect Unix ls-style LIST output.
- self.respond ('215 UNIX Type: L8')
- # one disadvantage to this is that some client programs
- # assume they can pass args to /bin/ls.
- # a few typical responses:
- # 215 UNIX Type: L8 (wuftpd)
- # 215 Windows_NT version 3.51
- # 215 VMS MultiNet V3.3
- # 500 'SYST': command not understood. (SVR4)
-
- def cmd_help (self, line):
- 'give help information'
- # find all the methods that match 'cmd_xxxx',
- # use their docstrings for the help response.
- attrs = dir(self.__class__)
- help_lines = []
- for attr in attrs:
- if attr[:4] == 'cmd_':
- x = getattr (self, attr)
- if type(x) == type(self.cmd_help):
- if x.__doc__:
- help_lines.append ('\t%s\t%s' % (attr[4:], x.__doc__))
- if help_lines:
- self.push ('214-The following commands are recognized\r\n')
- self.push_with_producer (producers.lines_producer (help_lines))
- self.push ('214\r\n')
- else:
- self.push ('214-\r\n\tHelp Unavailable\r\n214\r\n')
-
-class ftp_server (asyncore.dispatcher):
- # override this to spawn a different FTP channel class.
- ftp_channel_class = ftp_channel
-
- SERVER_IDENT = 'FTP Server (V%s)' % VERSION
-
- def __init__ (
- self,
- authorizer,
- hostname =None,
- ip ='',
- port =21,
- resolver =None,
- logger_object=logger.file_logger (sys.stdout)
- ):
- self.ip = ip
- self.port = port
- self.authorizer = authorizer
-
- if hostname is None:
- self.hostname = socket.gethostname()
- else:
- self.hostname = hostname
-
- # statistics
- self.total_sessions = counter()
- self.closed_sessions = counter()
- self.total_files_out = counter()
- self.total_files_in = counter()
- self.total_bytes_out = counter()
- self.total_bytes_in = counter()
- self.total_exceptions = counter()
- #
- asyncore.dispatcher.__init__ (self)
- self.create_socket (socket.AF_INET, socket.SOCK_STREAM)
-
- self.set_reuse_addr()
- self.bind ((self.ip, self.port))
- self.listen (5)
-
- if not logger_object:
- logger_object = sys.stdout
-
- if resolver:
- self.logger = logger.resolving_logger (resolver, logger_object)
- else:
- self.logger = logger.unresolving_logger (logger_object)
-
- self.log_info('FTP server started at %s\n\tAuthorizer:%s\n\tHostname: %s\n\tPort: %d' % (
- time.ctime(time.time()),
- repr (self.authorizer),
- self.hostname,
- self.port)
- )
-
- def writable (self):
- return 0
-
- def handle_read (self):
- pass
-
- def handle_connect (self):
- pass
-
- def handle_accept (self):
- conn, addr = self.accept()
- self.total_sessions.increment()
- self.log_info('Incoming connection from %s:%d' % (addr[0], addr[1]))
- self.ftp_channel_class (self, conn, addr)
-
- # return a producer describing the state of the server
- def status (self):
-
- def nice_bytes (n):
- return string.join (status_handler.english_bytes (n))
-
- return producers.lines_producer (
- ['<h2>%s</h2>' % self.SERVER_IDENT,
- '<br>Listening on <b>Host:</b> %s' % self.hostname,
- '<b>Port:</b> %d' % self.port,
- '<br>Sessions',
- '<b>Total:</b> %s' % self.total_sessions,
- '<b>Current:</b> %d' % (self.total_sessions.as_long() - self.closed_sessions.as_long()),
- '<br>Files',
- '<b>Sent:</b> %s' % self.total_files_out,
- '<b>Received:</b> %s' % self.total_files_in,
- '<br>Bytes',
- '<b>Sent:</b> %s' % nice_bytes (self.total_bytes_out.as_long()),
- '<b>Received:</b> %s' % nice_bytes (self.total_bytes_in.as_long()),
- '<br>Exceptions: %s' % self.total_exceptions,
- ]
- )
-
-# ======================================================================
-# Data Channel Classes
-# ======================================================================
-
-# This socket accepts a data connection, used when the server has been
-# placed in passive mode. Although the RFC implies that we ought to
-# be able to use the same acceptor over and over again, this presents
-# a problem: how do we shut it off, so that we are accepting
-# connections only when we expect them? [we can't]
-#
-# wuftpd, and probably all the other servers, solve this by allowing
-# only one connection to hit this acceptor. They then close it. Any
-# subsequent data-connection command will then try for the default
-# port on the client side [which is of course never there]. So the
-# 'always-send-PORT/PASV' behavior seems required.
-#
-# Another note: wuftpd will also be listening on the channel as soon
-# as the PASV command is sent. It does not wait for a data command
-# first.
-
-# --- we need to queue up a particular behavior:
-# 1) xmit : queue up producer[s]
-# 2) recv : the file object
-#
-# It would be nice if we could make both channels the same. Hmmm..
-#
-
-class passive_acceptor (asyncore.dispatcher):
- ready = None
-
- def __init__ (self, control_channel):
- # connect_fun (conn, addr)
- asyncore.dispatcher.__init__ (self)
- self.control_channel = control_channel
- self.create_socket (socket.AF_INET, socket.SOCK_STREAM)
- # bind to an address on the interface that the
- # control connection is coming from.
- self.bind ((
- self.control_channel.getsockname()[0],
- 0
- ))
- self.addr = self.getsockname()
- self.listen (1)
-
-# def __del__ (self):
-# print 'passive_acceptor.__del__()'
-
- def log (self, *ignore):
- pass
-
- def handle_accept (self):
- conn, addr = self.accept()
- dc = self.control_channel.client_dc
- if dc is not None:
- dc.set_socket (conn)
- dc.addr = addr
- dc.connected = 1
- self.control_channel.passive_acceptor = None
- else:
- self.ready = conn, addr
- self.close()
-
-
-class xmit_channel (asynchat.async_chat):
-
- # for an ethernet, you want this to be fairly large, in fact, it
- # _must_ be large for performance comparable to an ftpd. [64k] we
- # ought to investigate automatically-sized buffers...
-
- ac_out_buffer_size = 16384
- bytes_out = 0
-
- def __init__ (self, channel, client_addr=None):
- self.channel = channel
- self.client_addr = client_addr
- asynchat.async_chat.__init__ (self)
-
-# def __del__ (self):
-# print 'xmit_channel.__del__()'
-
- def log (*args):
- pass
-
- def readable (self):
- return not self.connected
-
- def writable (self):
- return 1
-
- def send (self, data):
- result = asynchat.async_chat.send (self, data)
- self.bytes_out = self.bytes_out + result
- return result
-
- def handle_error (self):
- # usually this is to catch an unexpected disconnect.
- self.log_info ('unexpected disconnect on data xmit channel', 'error')
- try:
- self.close()
- except:
- pass
-
- # TODO: there's a better way to do this. we need to be able to
- # put 'events' in the producer fifo. to do this cleanly we need
- # to reposition the 'producer' fifo as an 'event' fifo.
-
- def close (self):
- c = self.channel
- s = c.server
- c.client_dc = None
- s.total_files_out.increment()
- s.total_bytes_out.increment (self.bytes_out)
- if not len(self.producer_fifo):
- c.respond ('226 Transfer complete')
- elif not c.closed:
- c.respond ('426 Connection closed; transfer aborted')
- del c
- del s
- del self.channel
- asynchat.async_chat.close (self)
-
-class recv_channel (asyncore.dispatcher):
- def __init__ (self, channel, client_addr, fd):
- self.channel = channel
- self.client_addr = client_addr
- self.fd = fd
- asyncore.dispatcher.__init__ (self)
- self.bytes_in = counter()
-
- def log (self, *ignore):
- pass
-
- def handle_connect (self):
- pass
-
- def writable (self):
- return 0
-
- def recv (*args):
- result = apply (asyncore.dispatcher.recv, args)
- self = args[0]
- self.bytes_in.increment(len(result))
- return result
-
- buffer_size = 8192
-
- def handle_read (self):
- block = self.recv (self.buffer_size)
- if block:
- try:
- self.fd.write (block)
- except IOError:
- self.log_info ('got exception writing block...', 'error')
-
- def handle_close (self):
- s = self.channel.server
- s.total_files_in.increment()
- s.total_bytes_in.increment(self.bytes_in.as_long())
- self.fd.close()
- self.channel.respond ('226 Transfer complete.')
- self.close()
-
-import filesys
-
-# not much of a doorman! 8^)
-class dummy_authorizer:
- def __init__ (self, root='/'):
- self.root = root
- def authorize (self, channel, username, password):
- channel.persona = -1, -1
- channel.read_only = 1
- return 1, 'Ok.', filesys.os_filesystem (self.root)
-
-class anon_authorizer:
- def __init__ (self, root='/'):
- self.root = root
-
- def authorize (self, channel, username, password):
- if username in ('ftp', 'anonymous'):
- channel.persona = -1, -1
- channel.read_only = 1
- return 1, 'Ok.', filesys.os_filesystem (self.root)
- else:
- return 0, 'Password invalid.', None
-
-# ===========================================================================
-# Unix-specific improvements
-# ===========================================================================
-
-if os.name == 'posix':
-
- class unix_authorizer:
- # return a trio of (success, reply_string, filesystem)
- def authorize (self, channel, username, password):
- import crypt
- import pwd
- try:
- info = pwd.getpwnam (username)
- except KeyError:
- return 0, 'No such user.', None
- mangled = info[1]
- if crypt.crypt (password, mangled[:2]) == mangled:
- channel.read_only = 0
- fs = filesys.schizophrenic_unix_filesystem (
- '/',
- info[5],
- persona = (info[2], info[3])
- )
- return 1, 'Login successful.', fs
- else:
- return 0, 'Password invalid.', None
-
- def __repr__ (self):
- return '<standard unix authorizer>'
-
- # simple anonymous ftp support
- class unix_authorizer_with_anonymous (unix_authorizer):
- def __init__ (self, root=None, real_users=0):
- self.root = root
- self.real_users = real_users
-
- def authorize (self, channel, username, password):
- if string.lower(username) in ['anonymous', 'ftp']:
- import pwd
- try:
- # ok, here we run into lots of confusion.
- # on some os', anon runs under user 'nobody',
- # on others as 'ftp'. ownership is also critical.
- # need to investigate.
- # linux: new linuxen seem to have nobody's UID=-1,
- # which is an illegal value. Use ftp.
- ftp_user_info = pwd.getpwnam ('ftp')
- if string.lower(os.uname()[0]) == 'linux':
- nobody_user_info = pwd.getpwnam ('ftp')
- else:
- nobody_user_info = pwd.getpwnam ('nobody')
- channel.read_only = 1
- if self.root is None:
- self.root = ftp_user_info[5]
- fs = filesys.unix_filesystem (self.root, '/')
- return 1, 'Anonymous Login Successful', fs
- except KeyError:
- return 0, 'Anonymous account not set up', None
- elif self.real_users:
- return unix_authorizer.authorize (
- self,
- channel,
- username,
- password
- )
- else:
- return 0, 'User logins not allowed', None
-
-class file_producer:
- block_size = 16384
- def __init__ (self, server, dc, fd):
- self.fd = fd
- self.done = 0
-
- def more (self):
- if self.done:
- return ''
- else:
- block = self.fd.read (self.block_size)
- if not block:
- self.fd.close()
- self.done = 1
- return block
-
-# usage: ftp_server /PATH/TO/FTP/ROOT PORT
-# for example:
-# $ ftp_server /home/users/ftp 8021
-
-if os.name == 'posix':
- def test (port='8021'):
- import sys
- fs = ftp_server (
- unix_authorizer(),
- port=string.atoi (port)
- )
- try:
- asyncore.loop()
- except KeyboardInterrupt:
- self.log_info('FTP server shutting down. (received SIGINT)', 'warning')
- # close everything down on SIGINT.
- # of course this should be a cleaner shutdown.
- asyncore.close_all()
-
- if __name__ == '__main__':
- test (sys.argv[1])
-# not unix
-else:
- def test ():
- fs = ftp_server (dummy_authorizer())
- if __name__ == '__main__':
- test ()
-
-# this is the command list from the wuftpd man page
-# '*' means we've implemented it.
-# '!' requires write access
-#
-command_documentation = {
- 'abor': 'abort previous command', #*
- 'acct': 'specify account (ignored)',
- 'allo': 'allocate storage (vacuously)',
- 'appe': 'append to a file', #*!
- 'cdup': 'change to parent of current working directory', #*
- 'cwd': 'change working directory', #*
- 'dele': 'delete a file', #!
- 'help': 'give help information', #*
- 'list': 'give list files in a directory', #*
- 'mkd': 'make a directory', #!
- 'mdtm': 'show last modification time of file', #*
- 'mode': 'specify data transfer mode',
- 'nlst': 'give name list of files in directory', #*
- 'noop': 'do nothing', #*
- 'pass': 'specify password', #*
- 'pasv': 'prepare for server-to-server transfer', #*
- 'port': 'specify data connection port', #*
- 'pwd': 'print the current working directory', #*
- 'quit': 'terminate session', #*
- 'rest': 'restart incomplete transfer', #*
- 'retr': 'retrieve a file', #*
- 'rmd': 'remove a directory', #!
- 'rnfr': 'specify rename-from file name', #!
- 'rnto': 'specify rename-to file name', #!
- 'site': 'non-standard commands (see next section)',
- 'size': 'return size of file', #*
- 'stat': 'return status of server', #*
- 'stor': 'store a file', #*!
- 'stou': 'store a file with a unique name', #!
- 'stru': 'specify data transfer structure',
- 'syst': 'show operating system type of server system', #*
- 'type': 'specify data transfer type', #*
- 'user': 'specify user name', #*
- 'xcup': 'change to parent of current working directory (deprecated)',
- 'xcwd': 'change working directory (deprecated)',
- 'xmkd': 'make a directory (deprecated)', #!
- 'xpwd': 'print the current working directory (deprecated)',
- 'xrmd': 'remove a directory (deprecated)', #!
-}
-
-
-# debugging aid (linux)
-def get_vm_size ():
- return string.atoi (string.split(open ('/proc/self/stat').readline())[22])
-
-def print_vm():
- print 'vm: %8dk' % (get_vm_size()/1024)
diff --git a/demo/medusa/ftps_server.py b/demo/medusa/ftps_server.py
deleted file mode 100644
index 8fee339..0000000
--- a/demo/medusa/ftps_server.py
+++ /dev/null
@@ -1,438 +0,0 @@
-"""An FTP/TLS server built on Medusa's ftp_server.
-
-Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
-
-# Python
-import socket, string, sys, time
-
-# Medusa
-from counter import counter
-import asynchat, asyncore, ftp_server, logger
-
-# M2Crypto
-from M2Crypto import SSL
-
-VERSION_STRING='0.09'
-
-class ftp_tls_channel(ftp_server.ftp_channel):
-
- """FTP/TLS server channel for Medusa."""
-
- def __init__(self, server, ssl_ctx, conn, addr):
- """Initialise the channel."""
- self.ssl_ctx = ssl_ctx
- self.server = server
- self.current_mode = 'a'
- self.addr = addr
- asynchat.async_chat.__init__(self, conn)
- self.set_terminator('\r\n')
- self.client_addr = (addr[0], 21)
- self.client_dc = None
- self.in_buffer = ''
- self.closing = 0
- self.passive_acceptor = None
- self.passive_connection = None
- self.filesystem = None
- self.authorized = 0
- self._ssl_accepting = 0
- self._ssl_accepted = 0
- self._pbsz = None
- self._prot = None
- resp = '220 %s M2Crypto (Medusa) FTP/TLS server v%s ready.'
- self.respond(resp % (self.server.hostname, VERSION_STRING))
-
- def writable(self):
- return self._ssl_accepting or self._ssl_accepted
-
- def handle_read(self):
- """Handle a read event."""
- if self._ssl_accepting:
- self._ssl_accepted = self.socket.accept_ssl()
- if self._ssl_accepted:
- self._ssl_accepting = 0
- else:
- try:
- ftp_server.ftp_channel.handle_read(self)
- except SSL.SSLError, what:
- if str(what) == 'unexpected eof':
- self.close()
- else:
- raise
-
- def handle_write(self):
- """Handle a write event."""
- if self._ssl_accepting:
- self._ssl_accepted = self.socket.accept_ssl()
- if self._ssl_accepted:
- self._ssl_accepting = 0
- else:
- try:
- ftp_server.ftp_channel.handle_write(self)
- except SSL.SSLError, what:
- if str(what) == 'unexpected eof':
- self.close()
- else:
- raise
-
- def send(self, data):
- """Send data over SSL."""
- try:
- result = self.socket.send(data)
- if result <= 0:
- return 0
- else:
- return result
- except SSL.SSLError, what:
- self.close()
- self.log_info('send: closing channel %s %s' % (repr(self), what))
- return 0
-
- def recv(self, buffer_size):
- """Receive data over SSL."""
- try:
- result = self.socket.recv(buffer_size)
- if not result:
- return ''
- else:
- return result
- except SSL.SSLError, what:
- self.close()
- self.log_info('recv: closing channel %s %s' % (repr(self), what))
- return ''
-
- def found_terminator(self):
- """Dispatch the FTP command."""
- line = self.in_buffer
- if not len(line):
- return
-
- sp = string.find(line, ' ')
- if sp != -1:
- line = [line[:sp], line[sp+1:]]
- else:
- line = [line]
-
- command = string.lower(line[0])
- if string.find(command, 'stor') != -1:
- while command and command[0] not in string.letters:
- command = command[1:]
-
- func_name = 'cmd_%s' % command
- if command != 'pass':
- self.log('<== %s' % repr(self.in_buffer)[1:-1])
- else:
- self.log('<== %s' % line[0]+' <password>')
-
- self.in_buffer = ''
- if not hasattr(self, func_name):
- self.command_not_understood(line[0])
- return
-
- func = getattr(self, func_name)
- if not self.check_command_authorization(command):
- self.command_not_authorized(command)
- else:
- try:
- result = apply(func, (line,))
- except:
- self.server.total_exceptions.increment()
- (file, func, line), t, v, tbinfo = asyncore.compact_traceback()
- if self.client_dc:
- try:
- self.client_dc_close()
- except:
- pass
- resp = '451 Server error: %s, %s: file %s line: %s'
- self.respond(resp % (t, v, file, line))
-
- def make_xmit_channel(self):
- """Create a connection for sending data."""
- pa = self.passive_acceptor
- if pa:
- if pa.ready:
- conn, addr = pa.ready
- if self._prot:
- cdc = tls_xmit_channel(self, conn, self.ssl_ctx, addr)
- else:
- cdc = ftp_server.xmit_channel(self, addr)
- cdc.set_socket(conn)
- cdc.connected = 1
- self.passive_acceptor.close()
- self.passive_acceptor = None
- else:
- if self._prot:
- cdc = tls_xmit_channel(self, None, self.ssl_ctx, None)
- else:
- cdc = ftp_server.xmit_channel(self)
- else:
- if self._prot:
- cdc = tls_xmit_channel(self, None, self.ssl_ctx, self.client_addr)
- else:
- cdc = ftp_server.xmit_channel(self, self.client_addr)
- cdc.create_socket(socket.AF_INET, socket.SOCK_STREAM)
- if self.bind_local_minus_one:
- cdc.bind(('', self.server.port - 1))
- try:
- cdc.connect(self.client_addr)
- except socket.error, what:
- self.respond('425 Cannot build data connection')
- self.client_dc = cdc
-
- def make_recv_channel(self, fd):
- """Create a connection for receiving data."""
- pa = self.passive_acceptor
- if pa:
- if pa.ready:
- conn, addr = pa.ready
- if self._prot:
- cdc = tls_recv_channel(self, conn, self.ssl_ctx, addr, fd)
- else:
- cdc = ftp_server.recv_channel(self, addr, fd)
- cdc.set_socket(conn)
- cdc.connected = 1
- self.passive_acceptor.close()
- self.passive_acceptor = None
- else:
- if self._prot:
- cdc = tls_recv_channel(self, None, self.ssl_ctx, None, fd)
- else:
- cdc = ftp_server.recv_channel(self, None, fd)
- else:
- if self._prot:
- cdc = tls_recv_channel(self, None, self.ssl_ctx, self._prot, self.client_addr, fd)
- else:
- cdc = ftp_server.recv_channel(self, self.client_addr, fd)
- cdc.create_socket(socket.AF_INET, socket.SOCK_STREAM)
- try:
- cdc.connect(self.client_addr)
- except socket.error, what:
- self.respond('425 Cannot build data connection')
- self.client_dc = cdc
-
- def cmd_auth(self, line):
- """Prepare for TLS operation."""
- # XXX Handle variations.
- if line[1] != 'TLS':
- self.command_not_understood (string.join(line))
- else:
- self.respond('234 AUTH TLS successful')
- self._ssl_accepting = 1
- self.socket = SSL.Connection(self.ssl_ctx, self.socket)
- self.socket.setup_addr(self.addr)
- self.socket.setup_ssl()
- self.socket.set_accept_state()
- self._ssl_accepted = self.socket.accept_ssl()
- if self._ssl_accepted:
- self._ssl_accepting = 0
-
- def cmd_pbsz(self, line):
- """Negotiate size of buffer for secure data transfer. For
- FTP/TLS the only valid value for the parameter is '0'; any
- other value is accepted but ignored."""
- if not (self._ssl_accepting or self._ssl_accepted):
- return self.respond('503 AUTH TLS must be issued prior to PBSZ')
- self._pbsz = 1
- self.respond('200 PBSZ=0 successful.')
-
- def cmd_prot(self, line):
- """Negotiate the security level of the data connection."""
- if self._pbsz is None:
- return self.respond('503 PBSZ must be issued prior to PROT')
- if line[1] == 'C':
- self.respond('200 Protection set to Clear')
- self._pbsz = None
- self._prot = None
- elif line[1] == 'P':
- self.respond('200 Protection set to Private')
- self._prot = 1
- elif line[1] in ('S', 'E'):
- self.respond('536 PROT %s unsupported' % line[1])
- else:
- self.respond('504 PROT %s unsupported' % line[1])
-
-
-class ftp_tls_server(ftp_server.ftp_server):
-
- """FTP/TLS server for Medusa."""
-
- SERVER_IDENT = 'M2Crypto FTP/TLS Server (v%s)' % VERSION_STRING
-
- ftp_channel_class = ftp_tls_channel
-
- def __init__(self, authz, ssl_ctx, host=None, ip='', port=21, resolver=None, log_obj=None):
- """Initialise the server."""
- self.ssl_ctx = ssl_ctx
- self.ip = ip
- self.port = port
- self.authorizer = authz
-
- if host is None:
- self.hostname = socket.gethostname()
- else:
- self.hostname = host
-
- self.total_sessions = counter()
- self.closed_sessions = counter()
- self.total_files_out = counter()
- self.total_files_in = counter()
- self.total_bytes_out = counter()
- self.total_bytes_in = counter()
- self.total_exceptions = counter()
-
- asyncore.dispatcher.__init__(self)
- self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
- self.set_reuse_addr()
- self.bind((self.ip, self.port))
- self.listen(5)
-
- if log_obj is None:
- log_obj = sys.stdout
-
- if resolver:
- self.logger = logger.resolving_logger(resolver, log_obj)
- else:
- self.logger = logger.unresolving_logger(logger.file_logger(sys.stdout))
-
- l = 'M2Crypto (Medusa) FTP/TLS server started at %s\n\tAuthz: %s\n\tHostname: %s\n\tPort: %d'
- self.log_info(l % (time.ctime(time.time()), repr(self.authorizer), self.hostname, self.port))
-
- def handle_accept(self):
- """Accept a socket and dispatch a channel to handle it."""
- conn, addr = self.accept()
- self.total_sessions.increment()
- self.log_info('Connection from %s:%d' % addr)
- self.ftp_channel_class(self, self.ssl_ctx, conn, addr)
-
-
-class nbio_ftp_tls_actor:
-
- """TLS protocol negotiation mixin for FTP/TLS."""
-
- def tls_init(self, sock, ssl_ctx, client_addr):
- """Perform TLS protocol negotiation."""
- self.ssl_ctx = ssl_ctx
- self.client_addr = client_addr
- self._ssl_handshaking = 1
- self._ssl_handshake_ok = 0
- if sock:
- self.socket = SSL.Connection(self.ssl_ctx, sock)
- self.socket.setup_addr(self.client_addr)
- self.socket.setup_ssl()
- self._ssl_handshake_ok = self.socket.accept_ssl()
- if self._ssl_handshake_ok:
- self._ssl_handshaking = 0
- self.add_channel()
- # else the client hasn't connected yet; when that happens,
- # handle_connect() will be triggered.
-
- def tls_neg_ok(self):
- """Return status of TLS protocol negotiation."""
- if self._ssl_handshaking:
- self._ssl_handshake_ok = self.socket.accept_ssl()
- if self._ssl_handshake_ok:
- self._ssl_handshaking = 0
- return self._ssl_handshake_ok
-
- def handle_connect(self):
- """Handle a data connection that occurs after this instance came
- into being. When this handler is triggered, self.socket has been
- created and refers to the underlying connected socket."""
- self.socket = SSL.Connection(self.ssl_ctx, self.socket)
- self.socket.setup_addr(self.client_addr)
- self.socket.setup_ssl()
- self._ssl_handshake_ok = self.socket.accept_ssl()
- if self._ssl_handshake_ok:
- self._ssl_handshaking = 0
- self.add_channel()
-
- def send(self, data):
- """Send data over SSL."""
- try:
- result = self.socket.send(data)
- if result <= 0:
- return 0
- else:
- return result
- except SSL.SSLError, what:
- self.close()
- self.log_info('send: closing channel %s %s' % (repr(self), what))
- return 0
-
- def recv(self, buffer_size):
- """Receive data over SSL."""
- try:
- result = self.socket.recv(buffer_size)
- if not result:
- return ''
- else:
- return result
- except SSL.SSLError, what:
- self.close()
- self.log_info('recv: closing channel %s %s' % (repr(self), what))
- return ''
-
-
-class tls_xmit_channel(nbio_ftp_tls_actor, ftp_server.xmit_channel):
-
- """TLS driver for a send-only data connection."""
-
- def __init__(self, channel, conn, ssl_ctx, client_addr=None):
- """Initialise the driver."""
- ftp_server.xmit_channel.__init__(self, channel, client_addr)
- self.tls_init(conn, ssl_ctx, client_addr)
-
- def readable(self):
- """This channel is readable iff TLS negotiation is in progress.
- (Which implies a connected channel, of course.)"""
- if not self.connected:
- return 0
- else:
- return self._ssl_handshaking
-
- def writable(self):
- """This channel is writable iff TLS negotiation is in progress
- or the application has data to send."""
- if self._ssl_handshaking:
- return 1
- else:
- return ftp_server.xmit_channel.writable(self)
-
- def handle_read(self):
- """Handle a read event: either continue with TLS negotiation
- or let the application handle this event."""
- if self.tls_neg_ok():
- ftp_server.xmit_channel.handle_read(self)
-
- def handle_write(self):
- """Handle a write event: either continue with TLS negotiation
- or let the application handle this event."""
- if self.tls_neg_ok():
- ftp_server.xmit_channel.handle_write(self)
-
-
-class tls_recv_channel(nbio_ftp_tls_actor, ftp_server.recv_channel):
-
- """TLS driver for a receive-only data connection."""
-
- def __init__(self, channel, conn, ssl_ctx, client_addr, fd):
- """Initialise the driver."""
- ftp_server.recv_channel.__init__(self, channel, client_addr, fd)
- self.tls_init(conn, ssl_ctx, client_addr)
-
- def writable(self):
- """This channel is writable iff TLS negotiation is in progress."""
- return self._ssl_handshaking
-
- def handle_read(self):
- """Handle a read event: either continue with TLS negotiation
- or let the application handle this event."""
- if self.tls_neg_ok():
- ftp_server.recv_channel.handle_read(self)
-
- def handle_write(self):
- """Handle a write event: either continue with TLS negotiation
- or let the application handle this event."""
- if self.tls_neg_ok():
- ftp_server.recv_channel.handle_write(self)
-
-
diff --git a/demo/medusa/http_date.py b/demo/medusa/http_date.py
deleted file mode 100644
index c40f70d..0000000
--- a/demo/medusa/http_date.py
+++ /dev/null
@@ -1,126 +0,0 @@
-# -*- Mode: Python; tab-width: 4 -*-
-
-import re
-import string
-import time
-
-def concat (*args):
- return ''.join (args)
-
-def join (seq, field=' '):
- return field.join (seq)
-
-def group (s):
- return '(' + s + ')'
-
-short_days = ['sun','mon','tue','wed','thu','fri','sat']
-long_days = ['sunday','monday','tuesday','wednesday','thursday','friday','saturday']
-
-short_day_reg = group (join (short_days, '|'))
-long_day_reg = group (join (long_days, '|'))
-
-daymap = {}
-for i in range(7):
- daymap[short_days[i]] = i
- daymap[long_days[i]] = i
-
-hms_reg = join (3 * [group('[0-9][0-9]')], ':')
-
-months = ['jan','feb','mar','apr','may','jun','jul','aug','sep','oct','nov','dec']
-
-monmap = {}
-for i in range(12):
- monmap[months[i]] = i+1
-
-months_reg = group (join (months, '|'))
-
-# From draft-ietf-http-v11-spec-07.txt/3.3.1
-# Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123
-# Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036
-# Sun Nov 6 08:49:37 1994 ; ANSI C's asctime() format
-
-# rfc822 format
-rfc822_date = join (
- [concat (short_day_reg,','), # day
- group('[0-9][0-9]?'), # date
- months_reg, # month
- group('[0-9]+'), # year
- hms_reg, # hour minute second
- 'gmt'
- ],
- ' '
- )
-
-rfc822_reg = re.compile (rfc822_date)
-
-def unpack_rfc822 (m):
- g = m.group
- a = string.atoi
- return (
- a(g(4)), # year
- monmap[g(3)], # month
- a(g(2)), # day
- a(g(5)), # hour
- a(g(6)), # minute
- a(g(7)), # second
- 0,
- 0,
- 0
- )
-
-# rfc850 format
-rfc850_date = join (
- [concat (long_day_reg,','),
- join (
- [group ('[0-9][0-9]?'),
- months_reg,
- group ('[0-9]+')
- ],
- '-'
- ),
- hms_reg,
- 'gmt'
- ],
- ' '
- )
-
-rfc850_reg = re.compile (rfc850_date)
-# they actually unpack the same way
-def unpack_rfc850 (m):
- g = m.group
- a = string.atoi
- return (
- a(g(4)), # year
- monmap[g(3)], # month
- a(g(2)), # day
- a(g(5)), # hour
- a(g(6)), # minute
- a(g(7)), # second
- 0,
- 0,
- 0
- )
-
-# parsdate.parsedate - ~700/sec.
-# parse_http_date - ~1333/sec.
-
-def build_http_date (when):
- return time.strftime ('%a, %d %b %Y %H:%M:%S GMT', time.gmtime(when))
-
-def parse_http_date (d):
- d = string.lower (d)
- tz = time.timezone
- m = rfc850_reg.match (d)
- if m and m.end() == len(d):
- retval = int (time.mktime (unpack_rfc850(m)) - tz)
- else:
- m = rfc822_reg.match (d)
- if m and m.end() == len(d):
- retval = int (time.mktime (unpack_rfc822(m)) - tz)
- else:
- return 0
- # Thanks to Craig Silverstein <csilvers@google.com> for pointing
- # out the DST discrepancy
- if time.daylight and time.localtime(retval)[-1] == 1: # DST correction
- retval = retval + (tz - time.altzone)
- return retval
diff --git a/demo/medusa/http_server.py b/demo/medusa/http_server.py
deleted file mode 100644
index 2f261ab..0000000
--- a/demo/medusa/http_server.py
+++ /dev/null
@@ -1,784 +0,0 @@
-#! /usr/local/bin/python
-# -*- Mode: Python; tab-width: 4 -*-
-#
-# Author: Sam Rushing <rushing@nightmare.com>
-# Copyright 1996-2000 by Sam Rushing
-# All Rights Reserved.
-#
-
-# python modules
-import os
-import re
-import socket
-import stat
-import string
-import sys
-import time
-
-# async modules
-import asyncore
-import asynchat
-
-# medusa modules
-import http_date
-import producers
-import status_handler
-import logger
-
-VERSION_STRING = '1.1'
-
-from counter import counter
-from urllib import unquote
-
-# ===========================================================================
-# Request Object
-# ===========================================================================
-
-class http_request:
-
- # default reply code
- reply_code = 200
-
- request_counter = counter()
-
- # Whether to automatically use chunked encoding when
- #
- # HTTP version is 1.1
- # Content-Length is not set
- # Chunked encoding is not already in effect
- #
- # If your clients are having trouble, you might want to disable this.
- use_chunked = 1
-
- # by default, this request object ignores user data.
- collector = None
-
- def __init__ (self, *args):
- # unpack information about the request
- (self.channel, self.request,
- self.command, self.uri, self.version,
- self.header) = args
-
- self.outgoing = fifo()
- self.reply_headers = {
- 'Server' : 'Medusa/%s' % VERSION_STRING,
- 'Date' : http_date.build_http_date (time.time())
- }
- self.request_number = http_request.request_counter.increment()
- self._split_uri = None
- self._header_cache = {}
-
- # --------------------------------------------------
- # reply header management
- # --------------------------------------------------
- def __setitem__ (self, key, value):
- self.reply_headers[key] = value
-
- def __getitem__ (self, key):
- return self.reply_headers[key]
-
- def has_key (self, key):
- return self.reply_headers.has_key (key)
-
- def build_reply_header (self):
- return string.join (
- [self.response(self.reply_code)] + map (
- lambda x: '%s: %s' % x,
- self.reply_headers.items()
- ),
- '\r\n'
- ) + '\r\n\r\n'
-
- # --------------------------------------------------
- # split a uri
- # --------------------------------------------------
-
- # <path>;<params>?<query>#<fragment>
- path_regex = re.compile (
- # path params query fragment
- r'([^;?#]*)(;[^?#]*)?(\?[^#]*)?(#.*)?'
- )
-
- def split_uri (self):
- if self._split_uri is None:
- m = self.path_regex.match (self.uri)
- if m.end() != len(self.uri):
- raise ValueError, "Broken URI"
- else:
- self._split_uri = m.groups()
- return self._split_uri
-
- def get_header_with_regex (self, head_reg, group):
- for line in self.header:
- m = head_reg.match (line)
- if m.end() == len(line):
- return head_reg.group (group)
- return ''
-
- def get_header (self, header):
- header = string.lower (header)
- hc = self._header_cache
- if not hc.has_key (header):
- h = header + ': '
- hl = len(h)
- for line in self.header:
- if string.lower (line[:hl]) == h:
- r = line[hl:]
- hc[header] = r
- return r
- hc[header] = None
- return None
- else:
- return hc[header]
-
- # --------------------------------------------------
- # user data
- # --------------------------------------------------
-
- def collect_incoming_data (self, data):
- if self.collector:
- self.collector.collect_incoming_data (data)
- else:
- self.log_info(
- 'Dropping %d bytes of incoming request data' % len(data),
- 'warning'
- )
-
- def found_terminator (self):
- if self.collector:
- self.collector.found_terminator()
- else:
- self.log_info (
- 'Unexpected end-of-record for incoming request',
- 'warning'
- )
-
- def push (self, thing):
- if type(thing) == type(''):
- self.outgoing.push (producers.simple_producer (thing))
- else:
- self.outgoing.push (thing)
-
- def response (self, code=200):
- message = self.responses[code]
- self.reply_code = code
- return 'HTTP/%s %d %s' % (self.version, code, message)
-
- def error (self, code):
- self.reply_code = code
- message = self.responses[code]
- s = self.DEFAULT_ERROR_MESSAGE % {
- 'code': code,
- 'message': message,
- }
- self['Content-Length'] = len(s)
- self['Content-Type'] = 'text/html'
- # make an error reply
- self.push (s)
- self.done()
-
- # can also be used for empty replies
- reply_now = error
-
- def done (self):
- "finalize this transaction - send output to the http channel"
-
- # ----------------------------------------
- # persistent connection management
- # ----------------------------------------
-
- # --- BUCKLE UP! ----
-
- connection = string.lower (get_header (CONNECTION, self.header))
-
- close_it = 0
- wrap_in_chunking = 0
-
- if self.version == '1.0':
- if connection == 'keep-alive':
- if not self.has_key ('Content-Length'):
- close_it = 1
- else:
- self['Connection'] = 'Keep-Alive'
- else:
- close_it = 1
- elif self.version == '1.1':
- if connection == 'close':
- close_it = 1
- elif not self.has_key ('Content-Length'):
- if self.has_key ('Transfer-Encoding'):
- if not self['Transfer-Encoding'] == 'chunked':
- close_it = 1
- elif self.use_chunked:
- self['Transfer-Encoding'] = 'chunked'
- wrap_in_chunking = 1
- else:
- close_it = 1
- elif self.version is None:
- # Although we don't *really* support http/0.9 (because we'd have to
- # use \r\n as a terminator, and it would just yuck up a lot of stuff)
- # it's very common for developers to not want to type a version number
- # when using telnet to debug a server.
- close_it = 1
-
- outgoing_header = producers.simple_producer (self.build_reply_header())
-
- if close_it:
- self['Connection'] = 'close'
-
- if wrap_in_chunking:
- outgoing_producer = producers.chunked_producer (
- producers.composite_producer (self.outgoing)
- )
- # prepend the header
- outgoing_producer = producers.composite_producer (
- fifo([outgoing_header, outgoing_producer])
- )
- else:
- # prepend the header
- self.outgoing.push_front (outgoing_header)
- outgoing_producer = producers.composite_producer (self.outgoing)
-
- # apply a few final transformations to the output
- self.channel.push_with_producer (
- # globbing gives us large packets
- producers.globbing_producer (
- # hooking lets us log the number of bytes sent
- producers.hooked_producer (
- outgoing_producer,
- self.log
- )
- )
- )
-
- self.channel.current_request = None
-
- if close_it:
- self.channel.close_when_done()
-
- def log_date_string (self, when):
- return time.strftime (
- '%d/%b/%Y:%H:%M:%S ',
- time.gmtime(when)
- ) + tz_for_log
-
- def log (self, bytes):
- self.channel.server.logger.log (
- self.channel.addr[0],
- '%d - - [%s] "%s" %d %d\n' % (
- self.channel.addr[1],
- self.log_date_string (time.time()),
- self.request,
- self.reply_code,
- bytes
- )
- )
-
- responses = {
- 100: "Continue",
- 101: "Switching Protocols",
- 200: "OK",
- 201: "Created",
- 202: "Accepted",
- 203: "Non-Authoritative Information",
- 204: "No Content",
- 205: "Reset Content",
- 206: "Partial Content",
- 300: "Multiple Choices",
- 301: "Moved Permanently",
- 302: "Moved Temporarily",
- 303: "See Other",
- 304: "Not Modified",
- 305: "Use Proxy",
- 400: "Bad Request",
- 401: "Unauthorized",
- 402: "Payment Required",
- 403: "Forbidden",
- 404: "Not Found",
- 405: "Method Not Allowed",
- 406: "Not Acceptable",
- 407: "Proxy Authentication Required",
- 408: "Request Time-out",
- 409: "Conflict",
- 410: "Gone",
- 411: "Length Required",
- 412: "Precondition Failed",
- 413: "Request Entity Too Large",
- 414: "Request-URI Too Large",
- 415: "Unsupported Media Type",
- 500: "Internal Server Error",
- 501: "Not Implemented",
- 502: "Bad Gateway",
- 503: "Service Unavailable",
- 504: "Gateway Time-out",
- 505: "HTTP Version not supported"
- }
-
- # Default error message
- DEFAULT_ERROR_MESSAGE = string.join (
- ['<head>',
- '<title>Error response</title>',
- '</head>',
- '<body>',
- '<h1>Error response</h1>',
- '<p>Error code %(code)d.',
- '<p>Message: %(message)s.',
- '</body>',
- ''
- ],
- '\r\n'
- )
-
-
-# ===========================================================================
-# HTTP Channel Object
-# ===========================================================================
-
-class http_channel (asynchat.async_chat):
-
- # use a larger default output buffer
- ac_out_buffer_size = 1<<16
-
- current_request = None
- channel_counter = counter()
-
- def __init__ (self, server, conn, addr):
- self.channel_number = http_channel.channel_counter.increment()
- self.request_counter = counter()
- asynchat.async_chat.__init__ (self, conn)
- self.server = server
- self.addr = addr
- self.set_terminator ('\r\n\r\n')
- self.in_buffer = ''
- self.creation_time = int (time.time())
- self.check_maintenance()
-
- def __repr__ (self):
- ar = asynchat.async_chat.__repr__(self)[1:-1]
- return '<%s channel#: %s requests:%s>' % (
- ar,
- self.channel_number,
- self.request_counter
- )
-
- # Channel Counter, Maintenance Interval...
- maintenance_interval = 500
-
- def check_maintenance (self):
- if not self.channel_number % self.maintenance_interval:
- self.maintenance()
-
- def maintenance (self):
- self.kill_zombies()
-
- # 30-minute zombie timeout. status_handler also knows how to kill zombies.
- zombie_timeout = 30 * 60
-
- def kill_zombies (self):
- now = int (time.time())
- for channel in asyncore.socket_map.values():
- if channel.__class__ == self.__class__:
- if (now - channel.creation_time) > channel.zombie_timeout:
- channel.close()
-
- # --------------------------------------------------
- # send/recv overrides, good place for instrumentation.
- # --------------------------------------------------
-
- # this information needs to get into the request object,
- # so that it may log correctly.
- def send (self, data):
- result = asynchat.async_chat.send (self, data)
- self.server.bytes_out.increment (len(data))
- return result
-
- def recv (self, buffer_size):
- try:
- result = asynchat.async_chat.recv (self, buffer_size)
- self.server.bytes_in.increment (len(result))
- return result
- except MemoryError:
- # --- Save a Trip to Your Service Provider ---
- # It's possible for a process to eat up all the memory of
- # the machine, and put it in an extremely wedged state,
- # where medusa keeps running and can't be shut down. This
- # is where MemoryError tends to get thrown, though of
- # course it could get thrown elsewhere.
- sys.exit ("Out of Memory!")
-
- def handle_error (self):
- t, v = sys.exc_info()[:2]
- if t is SystemExit:
- raise t, v
- else:
- asynchat.async_chat.handle_error (self)
-
- def log (self, *args):
- pass
-
- # --------------------------------------------------
- # async_chat methods
- # --------------------------------------------------
-
- def collect_incoming_data (self, data):
- if self.current_request:
- # we are receiving data (probably POST data) for a request
- self.current_request.collect_incoming_data (data)
- else:
- # we are receiving header (request) data
- self.in_buffer = self.in_buffer + data
-
- def found_terminator (self):
- if self.current_request:
- self.current_request.found_terminator()
- else:
- header = self.in_buffer
- self.in_buffer = ''
- lines = string.split (header, '\r\n')
-
- # --------------------------------------------------
- # crack the request header
- # --------------------------------------------------
-
- while lines and not lines[0]:
- # as per the suggestion of http-1.1 section 4.1, (and
- # Eric Parker <eparker@zyvex.com>), ignore a leading
- # blank lines (buggy browsers tack it onto the end of
- # POST requests)
- lines = lines[1:]
-
- if not lines:
- self.close_when_done()
- return
-
- request = lines[0]
-
- # unquote path if necessary (thanks to Skip Montaro for pointing
- # out that we must unquote in piecemeal fashion).
- if '%' in request:
- request = unquote (request)
-
- command, uri, version = crack_request (request)
- header = join_headers (lines[1:])
-
- r = http_request (self, request, command, uri, version, header)
- self.request_counter.increment()
- self.server.total_requests.increment()
-
- if command is None:
- self.log_info ('Bad HTTP request: %s' % repr(request), 'error')
- r.error (400)
- return
-
- # --------------------------------------------------
- # handler selection and dispatch
- # --------------------------------------------------
- for h in self.server.handlers:
- if h.match (r):
- try:
- self.current_request = r
- # This isn't used anywhere.
- # r.handler = h # CYCLE
- h.handle_request (r)
- except:
- self.server.exceptions.increment()
- (file, fun, line), t, v, tbinfo = asyncore.compact_traceback()
- self.log_info(
- 'Server Error: %s, %s: file: %s line: %s' % (t,v,file,line),
- 'error')
- try:
- r.error (500)
- except:
- pass
- return
-
- # no handlers, so complain
- r.error (404)
-
- def writable (self):
- # this is just the normal async_chat 'writable', here for comparison
- return self.ac_out_buffer or len(self.producer_fifo)
-
- def writable_for_proxy (self):
- # this version of writable supports the idea of a 'stalled' producer
- # [i.e., it's not ready to produce any output yet] This is needed by
- # the proxy, which will be waiting for the magic combination of
- # 1) hostname resolved
- # 2) connection made
- # 3) data available.
- if self.ac_out_buffer:
- return 1
- elif len(self.producer_fifo):
- p = self.producer_fifo.first()
- if hasattr (p, 'stalled'):
- return not p.stalled()
- else:
- return 1
-
-# ===========================================================================
-# HTTP Server Object
-# ===========================================================================
-
-class http_server (asyncore.dispatcher):
-
- SERVER_IDENT = 'HTTP Server (V%s)' % VERSION_STRING
-
- channel_class = http_channel
-
- def __init__ (self, ip, port, resolver=None, logger_object=None):
- self.ip = ip
- self.port = port
- asyncore.dispatcher.__init__ (self)
- self.create_socket (socket.AF_INET, socket.SOCK_STREAM)
-
- self.handlers = []
-
- if not logger_object:
- logger_object = logger.file_logger (sys.stdout)
-
- self.set_reuse_addr()
- self.bind ((ip, port))
-
- # lower this to 5 if your OS complains
- self.listen (1024)
-
- host, port = self.socket.getsockname()
- if not ip:
- self.log_info('Computing default hostname', 'warning')
- ip = socket.gethostbyname (socket.gethostname())
- try:
- self.server_name = socket.gethostbyaddr (ip)[0]
- except socket.error:
- self.log_info('Cannot do reverse lookup', 'warning')
- self.server_name = ip # use the IP address as the "hostname"
-
- self.server_port = port
- self.total_clients = counter()
- self.total_requests = counter()
- self.exceptions = counter()
- self.bytes_out = counter()
- self.bytes_in = counter()
-
- if not logger_object:
- logger_object = logger.file_logger (sys.stdout)
-
- if resolver:
- self.logger = logger.resolving_logger (resolver, logger_object)
- else:
- self.logger = logger.unresolving_logger (logger_object)
-
- self.log_info (
- 'Medusa (V%s) started at %s'
- '\n\tHostname: %s'
- '\n\tPort:%d'
- '\n' % (
- VERSION_STRING,
- time.ctime(time.time()),
- self.server_name,
- port,
- )
- )
-
- def writable (self):
- return 0
-
- def handle_read (self):
- pass
-
- def readable (self):
- return self.accepting
-
- def handle_connect (self):
- pass
-
- def handle_accept (self):
- self.total_clients.increment()
- try:
- conn, addr = self.accept()
- except socket.error:
- # linux: on rare occasions we get a bogus socket back from
- # accept. socketmodule.c:makesockaddr complains that the
- # address family is unknown. We don't want the whole server
- # to shut down because of this.
- self.log_info ('warning: server accept() threw an exception', 'warning')
- return
- except TypeError:
- # unpack non-sequence. this can happen when a read event
- # fires on a listening socket, but when we call accept()
- # we get EWOULDBLOCK, so dispatcher.accept() returns None.
- # Seen on FreeBSD3.
- self.log_info ('warning: server accept() threw EWOULDBLOCK', 'warning')
- return
-
- self.channel_class (self, conn, addr)
-
- def install_handler (self, handler, back=0):
- if back:
- self.handlers.append (handler)
- else:
- self.handlers.insert (0, handler)
-
- def remove_handler (self, handler):
- self.handlers.remove (handler)
-
- def status (self):
- def nice_bytes (n):
- return string.join (status_handler.english_bytes (n))
-
- handler_stats = filter (None, map (maybe_status, self.handlers))
-
- if self.total_clients:
- ratio = self.total_requests.as_long() / float(self.total_clients.as_long())
- else:
- ratio = 0.0
-
- return producers.composite_producer (
- fifo ([producers.lines_producer (
- ['<h2>%s</h2>' % self.SERVER_IDENT,
- '<br>Listening on: <b>Host:</b> %s' % self.server_name,
- '<b>Port:</b> %d' % self.port,
- '<p><ul>'
- '<li>Total <b>Clients:</b> %s' % self.total_clients,
- '<b>Requests:</b> %s' % self.total_requests,
- '<b>Requests/Client:</b> %.1f' % (ratio),
- '<li>Total <b>Bytes In:</b> %s' % (nice_bytes (self.bytes_in.as_long())),
- '<b>Bytes Out:</b> %s' % (nice_bytes (self.bytes_out.as_long())),
- '<li>Total <b>Exceptions:</b> %s' % self.exceptions,
- '</ul><p>'
- '<b>Extension List</b><ul>',
- ])] + handler_stats + [producers.simple_producer('</ul>')]
- )
- )
-
-def maybe_status (thing):
- if hasattr (thing, 'status'):
- return thing.status()
- else:
- return None
-
-CONNECTION = re.compile ('Connection: (.*)', re.IGNORECASE)
-
-# merge multi-line headers
-# [486dx2: ~500/sec]
-def join_headers (headers):
- r = []
- for i in range(len(headers)):
- if headers[i][0] in ' \t':
- r[-1] = r[-1] + headers[i][1:]
- else:
- r.append (headers[i])
- return r
-
-def get_header (head_reg, lines, group=1):
- for line in lines:
- m = head_reg.match (line)
- if m and m.end() == len(line):
- return m.group (group)
- return ''
-
-def get_header_match (head_reg, lines):
- for line in lines:
- m = head_reg.match (line)
- if m and m.end() == len(line):
- return m
- return ''
-
-REQUEST = re.compile ('([^ ]+) ([^ ]+)(( HTTP/([0-9.]+))$|$)')
-
-def crack_request (r):
- m = REQUEST.match (r)
- if m.end() == len(r):
- if m.group(3):
- version = m.group(5)
- else:
- version = None
- return string.lower (m.group(1)), m.group(2), version
- else:
- return None, None, None
-
-class fifo:
- def __init__ (self, list=None):
- if not list:
- self.list = []
- else:
- self.list = list
-
- def __len__ (self):
- return len(self.list)
-
- def first (self):
- return self.list[0]
-
- def push_front (self, object):
- self.list.insert (0, object)
-
- def push (self, data):
- self.list.append (data)
-
- def pop (self):
- if self.list:
- result = self.list[0]
- del self.list[0]
- return (1, result)
- else:
- return (0, None)
-
-def compute_timezone_for_log ():
- if time.daylight:
- tz = time.altzone
- else:
- tz = time.timezone
- if tz > 0:
- neg = 1
- else:
- neg = 0
- tz = -tz
- h, rem = divmod (tz, 3600)
- m, rem = divmod (rem, 60)
- if neg:
- return '-%02d%02d' % (h, m)
- else:
- return '+%02d%02d' % (h, m)
-
-# if you run this program over a TZ change boundary, this will be invalid.
-tz_for_log = compute_timezone_for_log()
-
-if __name__ == '__main__':
- import sys
- if len(sys.argv) < 2:
- print 'usage: %s <root> <port>' % (sys.argv[0])
- else:
- import monitor
- import filesys
- import default_handler
- import status_handler
- import ftp_server
- import chat_server
- import resolver
- import logger
- rs = resolver.caching_resolver ('127.0.0.1')
- lg = logger.file_logger (sys.stdout)
- ms = monitor.secure_monitor_server ('fnord', '127.0.0.1', 9999)
- fs = filesys.os_filesystem (sys.argv[1])
- dh = default_handler.default_handler (fs)
- hs = http_server ('', string.atoi (sys.argv[2]), rs, lg)
- hs.install_handler (dh)
- ftp = ftp_server.ftp_server (
- ftp_server.dummy_authorizer(sys.argv[1]),
- port=8021,
- resolver=rs,
- logger_object=lg
- )
- cs = chat_server.chat_server ('', 7777)
- sh = status_handler.status_extension([hs,ms,ftp,cs,rs])
- hs.install_handler (sh)
- if ('-p' in sys.argv):
- def profile_loop ():
- try:
- asyncore.loop()
- except KeyboardInterrupt:
- pass
- import profile
- profile.run ('profile_loop()', 'profile.out')
- else:
- asyncore.loop()
diff --git a/demo/medusa/https_server.py b/demo/medusa/https_server.py
deleted file mode 100644
index 1492586..0000000
--- a/demo/medusa/https_server.py
+++ /dev/null
@@ -1,83 +0,0 @@
-#!/usr/bin/env python
-
-"""A https server built on Medusa's http_server.
-
-Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
-
-import asynchat, asyncore, http_server, socket, sys
-from M2Crypto import SSL
-
-VERSION_STRING='0.09'
-
-class https_channel(http_server.http_channel):
-
- def __init__(self, server, conn, addr):
- http_server.http_channel.__init__(self, server, conn, addr)
-
- def send(self, data):
- try:
- result = self.socket._write_nbio(data)
- if result <= 0:
- return 0
- else:
- self.server.bytes_out.increment(result)
- return result
- except SSL.SSLError, why:
- self.close()
- self.log_info('send: closing channel %s %s' % (repr(self), why))
- return 0
-
- def recv(self, buffer_size):
- try:
- result = self.socket._read_nbio(buffer_size)
- if result is None:
- return ''
- elif result == '':
- self.close()
- return ''
- else:
- self.server.bytes_in.increment(len(result))
- return result
- except SSL.SSLError, why:
- self.close()
- self.log_info('recv: closing channel %s %s' % (repr(self), why))
- return ''
-
-
-class https_server(http_server.http_server):
-
- SERVER_IDENT='M2Crypto HTTPS Server (v%s)' % VERSION_STRING
-
- channel_class=https_channel
-
- def __init__(self, ip, port, ssl_ctx, resolver=None, logger_object=None):
- http_server.http_server.__init__(self, ip, port, resolver, logger_object)
- sys.stdout.write(self.SERVER_IDENT + '\n\n')
- sys.stdout.flush()
- self.ssl_ctx=ssl_ctx
-
- def handle_accept(self):
- # Cribbed from http_server.
- self.total_clients.increment()
- try:
- conn, addr = self.accept()
- except socket.error:
- # linux: on rare occasions we get a bogus socket back from
- # accept. socketmodule.c:makesockaddr complains that the
- # address family is unknown. We don't want the whole server
- # to shut down because of this.
- sys.stderr.write ('warning: server accept() threw an exception\n')
- return
-
- # Turn the vanilla socket into an SSL connection.
- try:
- ssl_conn=SSL.Connection(self.ssl_ctx, conn)
- ssl_conn._setup_ssl(addr)
- ssl_conn.accept_ssl()
- self.channel_class(self, ssl_conn, addr)
- except SSL.SSLError:
- pass
-
- def writeable(self):
- return 0
-
diff --git a/demo/medusa/index.html b/demo/medusa/index.html
deleted file mode 100644
index 0f7de19..0000000
--- a/demo/medusa/index.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<html>
-<title>M2Crypto HTTPS Server</title>
-<body>
-<h1>M2Crypto HTTPS Server - It works!</h1>
-</body>
-</html>
diff --git a/demo/medusa/logger.py b/demo/medusa/logger.py
deleted file mode 100644
index 48be665..0000000
--- a/demo/medusa/logger.py
+++ /dev/null
@@ -1,262 +0,0 @@
-# -*- Mode: Python; tab-width: 4 -*-
-
-import asynchat
-import socket
-import string
-import time # these three are for the rotating logger
-import os # |
-import stat # v
-
-#
-# three types of log:
-# 1) file
-# with optional flushing. Also, one that rotates the log.
-# 2) socket
-# dump output directly to a socket connection. [how do we
-# keep it open?]
-# 3) syslog
-# log to syslog via tcp. this is a per-line protocol.
-#
-
-#
-# The 'standard' interface to a logging object is simply
-# log_object.log (message)
-#
-
-# a file-like object that captures output, and
-# makes sure to flush it always... this could
-# be connected to:
-# o stdio file
-# o low-level file
-# o socket channel
-# o syslog output...
-
-class file_logger:
-
- # pass this either a path or a file object.
- def __init__ (self, file, flush=1, mode='a'):
- if type(file) == type(''):
- if (file == '-'):
- import sys
- self.file = sys.stdout
- else:
- self.file = open (file, mode)
- else:
- self.file = file
- self.do_flush = flush
-
- def __repr__ (self):
- return '<file logger: %s>' % self.file
-
- def write (self, data):
- self.file.write (data)
- self.maybe_flush()
-
- def writeline (self, line):
- self.file.writeline (line)
- self.maybe_flush()
-
- def writelines (self, lines):
- self.file.writelines (lines)
- self.maybe_flush()
-
- def maybe_flush (self):
- if self.do_flush:
- self.file.flush()
-
- def flush (self):
- self.file.flush()
-
- def softspace (self, *args):
- pass
-
- def log (self, message):
- if message[-1] not in ('\r', '\n'):
- self.write (message + '\n')
- else:
- self.write (message)
-
-# like a file_logger, but it must be attached to a filename.
-# When the log gets too full, or a certain time has passed,
-# it backs up the log and starts a new one. Note that backing
-# up the log is done via "mv" because anything else (cp, gzip)
-# would take time, during which medusa would do nothing else.
-
-class rotating_file_logger (file_logger):
-
- # If freq is non-None we back up "daily", "weekly", or "monthly".
- # Else if maxsize is non-None we back up whenever the log gets
- # to big. If both are None we never back up.
- def __init__ (self, file, freq=None, maxsize=None, flush=1, mode='a'):
- self.filename = file
- self.mode = mode
- self.file = open (file, mode)
- self.freq = freq
- self.maxsize = maxsize
- self.rotate_when = self.next_backup(self.freq)
- self.do_flush = flush
-
- def __repr__ (self):
- return '<rotating-file logger: %s>' % self.file
-
- # We back up at midnight every 1) day, 2) monday, or 3) 1st of month
- def next_backup (self, freq):
- (yr, mo, day, hr, min, sec, wd, jday, dst) = time.localtime(time.time())
- if freq == 'daily':
- return time.mktime(yr,mo,day+1, 0,0,0, 0,0,-1)
- elif freq == 'weekly':
- return time.mktime(yr,mo,day-wd+7, 0,0,0, 0,0,-1) # wd(monday)==0
- elif freq == 'monthly':
- return time.mktime(yr,mo+1,1, 0,0,0, 0,0,-1)
- else:
- return None # not a date-based backup
-
- def maybe_flush (self): # rotate first if necessary
- self.maybe_rotate()
- if self.do_flush: # from file_logger()
- self.file.flush()
-
- def maybe_rotate (self):
- if self.freq and time.time() > self.rotate_when:
- self.rotate()
- self.rotate_when = self.next_backup(self.freq)
- elif self.maxsize: # rotate when we get too big
- try:
- if os.stat(self.filename)[stat.ST_SIZE] > self.maxsize:
- self.rotate()
- except os.error: # file not found, probably
- self.rotate() # will create a new file
-
- def rotate (self):
- (yr, mo, day, hr, min, sec, wd, jday, dst) = time.localtime(time.time())
- try:
- self.file.close()
- newname = '%s.ends%04d%02d%02d' % (self.filename, yr, mo, day)
- try:
- open(newname, "r").close() # check if file exists
- newname = newname + "-%02d%02d%02d" % (hr, min, sec)
- except: # YEARMODY is unique
- pass
- os.rename(self.filename, newname)
- self.file = open(self.filename, self.mode)
- except:
- pass
-
-# syslog is a line-oriented log protocol - this class would be
-# appropriate for FTP or HTTP logs, but not for dumping stderr to.
-
-# TODO: a simple safety wrapper that will ensure that the line sent
-# to syslog is reasonable.
-
-# TODO: async version of syslog_client: now, log entries use blocking
-# send()
-
-import m_syslog
-syslog_logger = m_syslog.syslog_client
-
-class syslog_logger (m_syslog.syslog_client):
- def __init__ (self, address, facility='user'):
- m_syslog.syslog_client.__init__ (self, address)
- self.facility = m_syslog.facility_names[facility]
- self.address=address
-
- def __repr__ (self):
- return '<syslog logger address=%s>' % (repr(self.address))
-
- def log (self, message):
- m_syslog.syslog_client.log (
- self,
- message,
- facility=self.facility,
- priority=m_syslog.LOG_INFO
- )
-
-# log to a stream socket, asynchronously
-
-class socket_logger (asynchat.async_chat):
-
- def __init__ (self, address):
-
- if type(address) == type(''):
- self.create_socket (socket.AF_UNIX, socket.SOCK_STREAM)
- else:
- self.create_socket (socket.AF_INET, socket.SOCK_STREAM)
-
- self.connect (address)
- self.address = address
-
- def __repr__ (self):
- return '<socket logger: address=%s>' % (self.address)
-
- def log (self, message):
- if message[-2:] != '\r\n':
- self.socket.push (message + '\r\n')
- else:
- self.socket.push (message)
-
-# log to multiple places
-class multi_logger:
- def __init__ (self, loggers):
- self.loggers = loggers
-
- def __repr__ (self):
- return '<multi logger: %s>' % (repr(self.loggers))
-
- def log (self, message):
- for logger in self.loggers:
- logger.log (message)
-
-class resolving_logger:
- """Feed (ip, message) combinations into this logger to get a
- resolved hostname in front of the message. The message will not
- be logged until the PTR request finishes (or fails)."""
-
- def __init__ (self, resolver, logger):
- self.resolver = resolver
- self.logger = logger
-
- class logger_thunk:
- def __init__ (self, message, logger):
- self.message = message
- self.logger = logger
-
- def __call__ (self, host, ttl, answer):
- if not answer:
- answer = host
- self.logger.log ('%s:%s' % (answer, self.message))
-
- def log (self, ip, message):
- self.resolver.resolve_ptr (
- ip,
- self.logger_thunk (
- message,
- self.logger
- )
- )
-
-class unresolving_logger:
- "Just in case you don't want to resolve"
- def __init__ (self, logger):
- self.logger = logger
-
- def log (self, ip, message):
- self.logger.log ('%s:%s' % (ip, message))
-
-
-def strip_eol (line):
- while line and line[-1] in '\r\n':
- line = line[:-1]
- return line
-
-class tail_logger:
- "Keep track of the last <size> log messages"
- def __init__ (self, logger, size=500):
- self.size = size
- self.logger = logger
- self.messages = []
-
- def log (self, message):
- self.messages.append (strip_eol (message))
- if len (self.messages) > self.size:
- del self.messages[0]
- self.logger.log (message)
diff --git a/demo/medusa/m_syslog.py b/demo/medusa/m_syslog.py
deleted file mode 100644
index bb376db..0000000
--- a/demo/medusa/m_syslog.py
+++ /dev/null
@@ -1,177 +0,0 @@
-# -*- Mode: Python; tab-width: 4 -*-
-
-# ======================================================================
-# Copyright 1997 by Sam Rushing
-#
-# All Rights Reserved
-#
-# Permission to use, copy, modify, and distribute this software and
-# its documentation for any purpose and without fee is hereby
-# granted, provided that the above copyright notice appear in all
-# copies and that both that copyright notice and this permission
-# notice appear in supporting documentation, and that the name of Sam
-# Rushing not be used in advertising or publicity pertaining to
-# distribution of the software without specific, written prior
-# permission.
-#
-# SAM RUSHING DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
-# NO EVENT SHALL SAM RUSHING BE LIABLE FOR ANY SPECIAL, INDIRECT OR
-# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
-# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-# ======================================================================
-
-"""socket interface to unix syslog.
-On Unix, there are usually two ways of getting to syslog: via a
-local unix-domain socket, or via the TCP service.
-
-Usually "/dev/log" is the unix domain socket. This may be different
-for other systems.
-
->>> my_client = syslog_client ('/dev/log')
-
-Otherwise, just use the UDP version, port 514.
-
->>> my_client = syslog_client (('my_log_host', 514))
-
-On win32, you will have to use the UDP version. Note that
-you can use this to log to other hosts (and indeed, multiple
-hosts).
-
-This module is not a drop-in replacement for the python
-<syslog> extension module - the interface is different.
-
-Usage:
-
->>> c = syslog_client()
->>> c = syslog_client ('/strange/non_standard_log_location')
->>> c = syslog_client (('other_host.com', 514))
->>> c.log ('testing', facility='local0', priority='debug')
-
-"""
-
-# TODO: support named-pipe syslog.
-# [see ftp://sunsite.unc.edu/pub/Linux/system/Daemons/syslog-fifo.tar.z]
-
-# from <linux/sys/syslog.h>:
-# ===========================================================================
-# priorities/facilities are encoded into a single 32-bit quantity, where the
-# bottom 3 bits are the priority (0-7) and the top 28 bits are the facility
-# (0-big number). Both the priorities and the facilities map roughly
-# one-to-one to strings in the syslogd(8) source code. This mapping is
-# included in this file.
-#
-# priorities (these are ordered)
-
-LOG_EMERG = 0 # system is unusable
-LOG_ALERT = 1 # action must be taken immediately
-LOG_CRIT = 2 # critical conditions
-LOG_ERR = 3 # error conditions
-LOG_WARNING = 4 # warning conditions
-LOG_NOTICE = 5 # normal but significant condition
-LOG_INFO = 6 # informational
-LOG_DEBUG = 7 # debug-level messages
-
-# facility codes
-LOG_KERN = 0 # kernel messages
-LOG_USER = 1 # random user-level messages
-LOG_MAIL = 2 # mail system
-LOG_DAEMON = 3 # system daemons
-LOG_AUTH = 4 # security/authorization messages
-LOG_SYSLOG = 5 # messages generated internally by syslogd
-LOG_LPR = 6 # line printer subsystem
-LOG_NEWS = 7 # network news subsystem
-LOG_UUCP = 8 # UUCP subsystem
-LOG_CRON = 9 # clock daemon
-LOG_AUTHPRIV = 10 # security/authorization messages (private)
-
-# other codes through 15 reserved for system use
-LOG_LOCAL0 = 16 # reserved for local use
-LOG_LOCAL1 = 17 # reserved for local use
-LOG_LOCAL2 = 18 # reserved for local use
-LOG_LOCAL3 = 19 # reserved for local use
-LOG_LOCAL4 = 20 # reserved for local use
-LOG_LOCAL5 = 21 # reserved for local use
-LOG_LOCAL6 = 22 # reserved for local use
-LOG_LOCAL7 = 23 # reserved for local use
-
-priority_names = {
- "alert": LOG_ALERT,
- "crit": LOG_CRIT,
- "debug": LOG_DEBUG,
- "emerg": LOG_EMERG,
- "err": LOG_ERR,
- "error": LOG_ERR, # DEPRECATED
- "info": LOG_INFO,
- "notice": LOG_NOTICE,
- "panic": LOG_EMERG, # DEPRECATED
- "warn": LOG_WARNING, # DEPRECATED
- "warning": LOG_WARNING,
- }
-
-facility_names = {
- "auth": LOG_AUTH,
- "authpriv": LOG_AUTHPRIV,
- "cron": LOG_CRON,
- "daemon": LOG_DAEMON,
- "kern": LOG_KERN,
- "lpr": LOG_LPR,
- "mail": LOG_MAIL,
- "news": LOG_NEWS,
- "security": LOG_AUTH, # DEPRECATED
- "syslog": LOG_SYSLOG,
- "user": LOG_USER,
- "uucp": LOG_UUCP,
- "local0": LOG_LOCAL0,
- "local1": LOG_LOCAL1,
- "local2": LOG_LOCAL2,
- "local3": LOG_LOCAL3,
- "local4": LOG_LOCAL4,
- "local5": LOG_LOCAL5,
- "local6": LOG_LOCAL6,
- "local7": LOG_LOCAL7,
- }
-
-import socket
-
-class syslog_client:
- def __init__ (self, address='/dev/log'):
- self.address = address
- if type (address) == type(''):
- self.socket = socket.socket (socket.AF_UNIX, socket.SOCK_STREAM)
- self.socket.connect (address)
- self.unix = 1
- else:
- self.socket = socket.socket (socket.AF_INET, socket.SOCK_DGRAM)
- self.unix = 0
-
- # curious: when talking to the unix-domain '/dev/log' socket, a
- # zero-terminator seems to be required. this string is placed
- # into a class variable so that it can be overridden if
- # necessary.
-
- log_format_string = '<%d>%s\000'
-
- def log (self, message, facility=LOG_USER, priority=LOG_INFO):
- message = self.log_format_string % (
- self.encode_priority (facility, priority),
- message
- )
- if self.unix:
- self.socket.send (message)
- else:
- self.socket.sendto (message, self.address)
-
- def encode_priority (self, facility, priority):
- if type(facility) == type(''):
- facility = facility_names[facility]
- if type(priority) == type(''):
- priority = priority_names[priority]
- return (facility<<3) | priority
-
- def close (self):
- if self.unix:
- self.socket.close()
-
diff --git a/demo/medusa/medusa_gif.py b/demo/medusa/medusa_gif.py
deleted file mode 100644
index 005644a..0000000
--- a/demo/medusa/medusa_gif.py
+++ /dev/null
@@ -1,8 +0,0 @@
-# -*- Mode: Python -*-
-
-# the medusa icon as a python source file.
-
-width = 97
-height = 61
-
-data = 'GIF89aa\000=\000\204\000\000\000\000\000\255\255\255\245\245\245ssskkkccc111)))\326\326\326!!!\316\316\316\300\300\300\204\204\000\224\224\224\214\214\214\200\200\200RRR\377\377\377JJJ\367\367\367BBB\347\347\347\000\204\000\020\020\020\265\265\265\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000!\371\004\001\000\000\021\000,\000\000\000\000a\000=\000\000\005\376`$\216di\236h\252\256l\353\276p,\317tm\337x\256\357|m\001@\240E\305\000\364\2164\206R)$\005\201\214\007r\012{X\255\312a\004\260\\>\026\3240\353)\224n\001W+X\334\373\231~\344.\303b\216\024\027x<\273\307\255G,rJiWN\014{S}k"?ti\013EdPQ\207G@_%\000\026yy\\\201\202\227\224<\221Fs$pOjWz\241<r@vO\236\231\233k\247M\2544\203F\177\235\236L#\247\256Z\270,\266BxJ[\276\256A]iE\304\305\262\273E\313\201\275i#\\\303\321\'h\203V\\\177\326\276\216\220P~\335\230_\264\013\342\275\344KF\233\360Q\212\352\246\000\367\274s\361\236\334\347T\341;\341\246\2202\177\3142\211`\242o\325@S\202\264\031\252\207\260\323\256\205\311\036\236\270\002\'\013\302\177\274H\010\324X\002\0176\212\037\376\321\360\032\226\207\244\2674(+^\202\346r\205J\0211\375\241Y#\256f\0127\315>\272\002\325\307g\012(\007\205\312#j\317(\012A\200\224.\241\003\346GS\247\033\245\344\264\366\015L\'PXQl]\266\263\243\232\260?\245\316\371\362\225\035\332\243J\273\332Q\263\357-D\241T\327\270\265\013W&\330\010u\371b\322IW0\214\261]\003\033Va\365Z#\207\213a\030k\2647\262\014p\354\024[n\321N\363\346\317\003\037P\000\235C\302\000\3228(\244\363YaA\005\022\255_\237@\260\000A\212\326\256qbp\321\332\266\011\334=T\023\010"!B\005\003A\010\224\020\220 H\002\337#\020 O\276E\357h\221\327\003\\\000b@v\004\351A.h\365\354\342B\002\011\257\025\\ \220\340\301\353\006\000\024\214\200pA\300\353\012\364\241k/\340\033C\202\003\000\310fZ\011\003V\240R\005\007\354\376\026A\000\000\360\'\202\177\024\004\210\003\000\305\215\360\000\000\015\220\240\332\203\027@\'\202\004\025VpA\000%\210x\321\206\032J\341\316\010\262\211H"l\333\341\200\200>"]P\002\212\011\010`\002\0066FP\200\001\'\024p]\004\027(8B\221\306]\000\201w>\002iB\001\007\340\260"v7J1\343(\257\020\251\243\011\242i\263\017\215\337\035\220\200\221\365m4d\015\016D\251\341iN\354\346Ng\253\200I\240\031\35609\245\2057\311I\302\2007t\231"&`\314\310\244\011e\226(\236\010w\212\300\234\011\012HX(\214\253\311@\001\233^\222pg{% \340\035\224&H\000\246\201\362\215`@\001"L\340\004\030\234\022\250\'\015(V:\302\235\030\240q\337\205\224\212h@\177\006\000\250\210\004\007\310\207\337\005\257-P\346\257\367]p\353\203\271\256:\203\236\211F\340\247\010\3329g\244\010\307*=A\000\203\260y\012\304s#\014\007D\207,N\007\304\265\027\021C\233\207%B\366[m\353\006\006\034j\360\306+\357\274a\204\000\000;'
diff --git a/demo/medusa/mime_type_table.py b/demo/medusa/mime_type_table.py
deleted file mode 100644
index dbc64a4..0000000
--- a/demo/medusa/mime_type_table.py
+++ /dev/null
@@ -1,113 +0,0 @@
-# -*- Python -*-
-# Converted by ./convert_mime_type_table.py from:
-# /usr/src2/apache_1.2b6/conf/mime.types
-#
-content_type_map = \
- {
- 'ai': 'application/postscript',
- 'aif': 'audio/x-aiff',
- 'aifc': 'audio/x-aiff',
- 'aiff': 'audio/x-aiff',
- 'au': 'audio/basic',
- 'avi': 'video/x-msvideo',
- 'bcpio': 'application/x-bcpio',
- 'bin': 'application/octet-stream',
- 'cdf': 'application/x-netcdf',
- 'class': 'application/octet-stream',
- 'cpio': 'application/x-cpio',
- 'cpt': 'application/mac-compactpro',
- 'csh': 'application/x-csh',
- 'dcr': 'application/x-director',
- 'dir': 'application/x-director',
- 'dms': 'application/octet-stream',
- 'doc': 'application/msword',
- 'dvi': 'application/x-dvi',
- 'dxr': 'application/x-director',
- 'eps': 'application/postscript',
- 'etx': 'text/x-setext',
- 'exe': 'application/octet-stream',
- 'gif': 'image/gif',
- 'gtar': 'application/x-gtar',
- 'gz': 'application/x-gzip',
- 'hdf': 'application/x-hdf',
- 'hqx': 'application/mac-binhex40',
- 'htm': 'text/html',
- 'html': 'text/html',
- 'ice': 'x-conference/x-cooltalk',
- 'ief': 'image/ief',
- 'jpe': 'image/jpeg',
- 'jpeg': 'image/jpeg',
- 'jpg': 'image/jpeg',
- 'kar': 'audio/midi',
- 'latex': 'application/x-latex',
- 'lha': 'application/octet-stream',
- 'lzh': 'application/octet-stream',
- 'man': 'application/x-troff-man',
- 'me': 'application/x-troff-me',
- 'mid': 'audio/midi',
- 'midi': 'audio/midi',
- 'mif': 'application/x-mif',
- 'mov': 'video/quicktime',
- 'movie': 'video/x-sgi-movie',
- 'mp2': 'audio/mpeg',
- 'mpe': 'video/mpeg',
- 'mpeg': 'video/mpeg',
- 'mpg': 'video/mpeg',
- 'mpga': 'audio/mpeg',
- 'mp3': 'audio/mpeg',
- 'ms': 'application/x-troff-ms',
- 'nc': 'application/x-netcdf',
- 'oda': 'application/oda',
- 'pbm': 'image/x-portable-bitmap',
- 'pdb': 'chemical/x-pdb',
- 'pdf': 'application/pdf',
- 'pgm': 'image/x-portable-graymap',
- 'png': 'image/png',
- 'pnm': 'image/x-portable-anymap',
- 'ppm': 'image/x-portable-pixmap',
- 'ppt': 'application/powerpoint',
- 'ps': 'application/postscript',
- 'qt': 'video/quicktime',
- 'ra': 'audio/x-realaudio',
- 'ram': 'audio/x-pn-realaudio',
- 'ras': 'image/x-cmu-raster',
- 'rgb': 'image/x-rgb',
- 'roff': 'application/x-troff',
- 'rpm': 'audio/x-pn-realaudio-plugin',
- 'rtf': 'application/rtf',
- 'rtx': 'text/richtext',
- 'sgm': 'text/x-sgml',
- 'sgml': 'text/x-sgml',
- 'sh': 'application/x-sh',
- 'shar': 'application/x-shar',
- 'sit': 'application/x-stuffit',
- 'skd': 'application/x-koan',
- 'skm': 'application/x-koan',
- 'skp': 'application/x-koan',
- 'skt': 'application/x-koan',
- 'snd': 'audio/basic',
- 'src': 'application/x-wais-source',
- 'sv4cpio': 'application/x-sv4cpio',
- 'sv4crc': 'application/x-sv4crc',
- 't': 'application/x-troff',
- 'tar': 'application/x-tar',
- 'tcl': 'application/x-tcl',
- 'tex': 'application/x-tex',
- 'texi': 'application/x-texinfo',
- 'texinfo': 'application/x-texinfo',
- 'tif': 'image/tiff',
- 'tiff': 'image/tiff',
- 'tr': 'application/x-troff',
- 'tsv': 'text/tab-separated-values',
- 'txt': 'text/plain',
- 'ustar': 'application/x-ustar',
- 'vcd': 'application/x-cdlink',
- 'vrml': 'x-world/x-vrml',
- 'wav': 'audio/x-wav',
- 'wrl': 'x-world/x-vrml',
- 'xbm': 'image/x-xbitmap',
- 'xpm': 'image/x-xpixmap',
- 'xwd': 'image/x-xwindowdump',
- 'xyz': 'chemical/x-pdb',
- 'zip': 'application/zip',
- }
diff --git a/demo/medusa/poison_handler.py b/demo/medusa/poison_handler.py
deleted file mode 100644
index acc78ab..0000000
--- a/demo/medusa/poison_handler.py
+++ /dev/null
@@ -1,69 +0,0 @@
-
-import string
-import whrandom
-
-RESP_HEAD="""\
-<HTML><BODY BGCOLOR=\"#ffffff\">
-"""
-
-RESP_MIDDLE="""
-<h2>M2Crypto https server demonstration</h2>
-
-This web page is generated by the "poison" http request handler.
-<br>
-The links just go on and on and on...
-<br><br>
-"""
-
-RESP_TAIL="""
-</BODY></HTML>
-"""
-
-charset='012345678/90ABCDEFGHIJKLM/NOPQRSTUVWXYZabcd/efghijklmnopqrs/tuvwxyz'
-numchar=len(charset)
-
-def makepage(numlinks):
-
- title='<title>'
- for u in range(whrandom.randint(3, 15)):
- pick=whrandom.randint(0, numchar-1)
- title=title+charset[pick]
- title=title+'</title>'
-
- url='\r\n'
- numlinks=whrandom.randint(2, numlinks)
- for i in range(numlinks):
- url=url+'<a href="/poison/'
- for u in range(whrandom.randint(3, 15)):
- pick=whrandom.randint(0, numchar-1)
- ch=charset[pick]
- if ch=='/' and url[-1]=='/':
- ch=charset[pick+1]
- url=url+ch
- url=url+'/">'
- for u in range(whrandom.randint(3, 15)):
- pick=whrandom.randint(0, numchar-1)
- url=url+charset[pick]
- url=url+'</a><br>\r\n'
-
- url=RESP_HEAD+title+RESP_MIDDLE+url+RESP_TAIL
- return url
-
-
-class poison_handler:
- """This is a clone of webpoison - every URL returns a page of URLs, each of which
- returns a page of URLs, each of _which_ returns a page of URLs, ad infinitum.
- The objective is to sucker address-harvesting bots run by spammers."""
-
- def __init__(self, numlinks=10):
- self.numlinks = numlinks
- self.poison_level = 0
-
- def match(self, request):
- return (request.uri[:7] == '/poison')
-
- def handle_request(self, request):
- if request.command == 'get':
- request.push(makepage(self.numlinks))
- request.done()
-
diff --git a/demo/medusa/producers.py b/demo/medusa/producers.py
deleted file mode 100644
index 2138258..0000000
--- a/demo/medusa/producers.py
+++ /dev/null
@@ -1,329 +0,0 @@
-# -*- Mode: Python; tab-width: 4 -*-
-
-import string
-
-"""
-A collection of producers.
-Each producer implements a particular feature: They can be combined
-in various ways to get interesting and useful behaviors.
-
-For example, you can feed dynamically-produced output into the compressing
-producer, then wrap this with the 'chunked' transfer-encoding producer.
-"""
-
-class simple_producer:
- "producer for a string"
- def __init__ (self, data, buffer_size=1024):
- self.data = data
- self.buffer_size = buffer_size
-
- def more (self):
- if len (self.data) > self.buffer_size:
- result = self.data[:self.buffer_size]
- self.data = self.data[self.buffer_size:]
- return result
- else:
- result = self.data
- self.data = ''
- return result
-
-class scanning_producer:
- "like simple_producer, but more efficient for large strings"
- def __init__ (self, data, buffer_size=1024):
- self.data = data
- self.buffer_size = buffer_size
- self.pos = 0
-
- def more (self):
- if self.pos < len(self.data):
- lp = self.pos
- rp = min (
- len(self.data),
- self.pos + self.buffer_size
- )
- result = self.data[lp:rp]
- self.pos = self.pos + len(result)
- return result
- else:
- return ''
-
-class lines_producer:
- "producer for a list of lines"
-
- def __init__ (self, lines):
- self.lines = lines
-
- def ready (self):
- return len(self.lines)
-
- def more (self):
- if self.lines:
- chunk = self.lines[:50]
- self.lines = self.lines[50:]
- return string.join (chunk, '\r\n') + '\r\n'
- else:
- return ''
-
-class buffer_list_producer:
- "producer for a list of buffers"
-
- # i.e., data == string.join (buffers, '')
-
- def __init__ (self, buffers):
-
- self.index = 0
- self.buffers = buffers
-
- def more (self):
- if self.index >= len(self.buffers):
- return ''
- else:
- data = self.buffers[self.index]
- self.index = self.index + 1
- return data
-
-class file_producer:
- "producer wrapper for file[-like] objects"
-
- # match http_channel's outgoing buffer size
- out_buffer_size = 1<<16
-
- def __init__ (self, file):
- self.done = 0
- self.file = file
-
- def more (self):
- if self.done:
- return ''
- else:
- data = self.file.read (self.out_buffer_size)
- if not data:
- self.file.close()
- del self.file
- self.done = 1
- return ''
- else:
- return data
-
-# A simple output producer. This one does not [yet] have
-# the safety feature builtin to the monitor channel: runaway
-# output will not be caught.
-
-# don't try to print from within any of the methods
-# of this object.
-
-class output_producer:
- "Acts like an output file; suitable for capturing sys.stdout"
- def __init__ (self):
- self.data = ''
-
- def write (self, data):
- lines = string.splitfields (data, '\n')
- data = string.join (lines, '\r\n')
- self.data = self.data + data
-
- def writeline (self, line):
- self.data = self.data + line + '\r\n'
-
- def writelines (self, lines):
- self.data = self.data + string.joinfields (
- lines,
- '\r\n'
- ) + '\r\n'
-
- def ready (self):
- return (len (self.data) > 0)
-
- def flush (self):
- pass
-
- def softspace (self, *args):
- pass
-
- def more (self):
- if self.data:
- result = self.data[:512]
- self.data = self.data[512:]
- return result
- else:
- return ''
-
-class composite_producer:
- "combine a fifo of producers into one"
- def __init__ (self, producers):
- self.producers = producers
-
- def more (self):
- while len(self.producers):
- p = self.producers.first()
- d = p.more()
- if d:
- return d
- else:
- self.producers.pop()
- else:
- return ''
-
-
-class globbing_producer:
- """
- 'glob' the output from a producer into a particular buffer size.
- helps reduce the number of calls to send(). [this appears to
- gain about 30% performance on requests to a single channel]
- """
-
- def __init__ (self, producer, buffer_size=1<<16):
- self.producer = producer
- self.buffer = ''
- self.buffer_size = buffer_size
-
- def more (self):
- while len(self.buffer) < self.buffer_size:
- data = self.producer.more()
- if data:
- self.buffer = self.buffer + data
- else:
- break
- r = self.buffer
- self.buffer = ''
- return r
-
-
-class hooked_producer:
- """
- A producer that will call <function> when it empties,.
- with an argument of the number of bytes produced. Useful
- for logging/instrumentation purposes.
- """
-
- def __init__ (self, producer, function):
- self.producer = producer
- self.function = function
- self.bytes = 0
-
- def more (self):
- if self.producer:
- result = self.producer.more()
- if not result:
- self.producer = None
- self.function (self.bytes)
- else:
- self.bytes = self.bytes + len(result)
- return result
- else:
- return ''
-
-# HTTP 1.1 emphasizes that an advertised Content-Length header MUST be
-# correct. In the face of Strange Files, it is conceivable that
-# reading a 'file' may produce an amount of data not matching that
-# reported by os.stat() [text/binary mode issues, perhaps the file is
-# being appended to, etc..] This makes the chunked encoding a True
-# Blessing, and it really ought to be used even with normal files.
-# How beautifully it blends with the concept of the producer.
-
-class chunked_producer:
- """A producer that implements the 'chunked' transfer coding for HTTP/1.1.
- Here is a sample usage:
- request['Transfer-Encoding'] = 'chunked'
- request.push (
- producers.chunked_producer (your_producer)
- )
- request.done()
- """
-
- def __init__ (self, producer, footers=None):
- self.producer = producer
- self.footers = footers
-
- def more (self):
- if self.producer:
- data = self.producer.more()
- if data:
- return '%x\r\n%s\r\n' % (len(data), data)
- else:
- self.producer = None
- if self.footers:
- return string.join (
- ['0'] + self.footers,
- '\r\n'
- ) + '\r\n\r\n'
- else:
- return '0\r\n\r\n'
- else:
- return ''
-
-# Unfortunately this isn't very useful right now (Aug 97), because
-# apparently the browsers don't do on-the-fly decompression. Which
-# is sad, because this could _really_ speed things up, especially for
-# low-bandwidth clients (i.e., most everyone).
-
-try:
- import zlib
-except ImportError:
- zlib = None
-
-class compressed_producer:
- """
- Compress another producer on-the-fly, using ZLIB
- [Unfortunately, none of the current browsers seem to support this]
- """
-
- # Note: It's not very efficient to have the server repeatedly
- # compressing your outgoing files: compress them ahead of time, or
- # use a compress-once-and-store scheme. However, if you have low
- # bandwidth and low traffic, this may make more sense than
- # maintaining your source files compressed.
- #
- # Can also be used for compressing dynamically-produced output.
-
- def __init__ (self, producer, level=5):
- self.producer = producer
- self.compressor = zlib.compressobj (level)
-
- def more (self):
- if self.producer:
- cdata = ''
- # feed until we get some output
- while not cdata:
- data = self.producer.more()
- if not data:
- self.producer = None
- return self.compressor.flush()
- else:
- cdata = self.compressor.compress (data)
- return cdata
- else:
- return ''
-
-class escaping_producer:
-
- "A producer that escapes a sequence of characters"
- " Common usage: escaping the CRLF.CRLF sequence in SMTP, NNTP, etc..."
-
- def __init__ (self, producer, esc_from='\r\n.', esc_to='\r\n..'):
- self.producer = producer
- self.esc_from = esc_from
- self.esc_to = esc_to
- self.buffer = ''
- from asynchat import find_prefix_at_end
- self.find_prefix_at_end = find_prefix_at_end
-
- def more (self):
- esc_from = self.esc_from
- esc_to = self.esc_to
-
- buffer = self.buffer + self.producer.more()
-
- if buffer:
- buffer = string.replace (buffer, esc_from, esc_to)
- i = self.find_prefix_at_end (buffer, esc_from)
- if i:
- # we found a prefix
- self.buffer = buffer[-i:]
- return buffer[:-i]
- else:
- # no prefix, return it all
- self.buffer = ''
- return buffer
- else:
- return buffer
diff --git a/demo/medusa/put_handler.py b/demo/medusa/put_handler.py
deleted file mode 100644
index 488fb42..0000000
--- a/demo/medusa/put_handler.py
+++ /dev/null
@@ -1,113 +0,0 @@
-# -*- Mode: Python; tab-width: 4 -*-
-#
-# Author: Sam Rushing <rushing@nightmare.com>
-# Copyright 1996-2000 by Sam Rushing
-# All Rights Reserved.
-#
-
-import re
-import string
-
-import default_handler
-unquote = default_handler.unquote
-get_header = default_handler.get_header
-
-last_request = None
-
-class put_handler:
- def __init__ (self, filesystem, uri_regex):
- self.filesystem = filesystem
- if type (uri_regex) == type(''):
- self.uri_regex = re.compile (uri_regex)
- else:
- self.uri_regex = uri_regex
-
- def match (self, request):
- uri = request.uri
- if request.command == 'put':
- m = self.uri_regex.match (uri)
- if m and m.end() == len(uri):
- return 1
- return 0
-
- def handle_request (self, request):
-
- path, params, query, fragment = request.split_uri()
-
- # strip off leading slashes
- while path and path[0] == '/':
- path = path[1:]
-
- if '%' in path:
- path = unquote (path)
-
- # make sure there's a content-length header
- cl = get_header (CONTENT_LENGTH, request.header)
- if not cl:
- request.error (411)
- return
- else:
- cl = string.atoi (cl)
-
- # don't let the try to overwrite a directory
- if self.filesystem.isdir (path):
- request.error (405)
- return
-
- is_update = self.filesystem.isfile (path)
-
- try:
- output_file = self.filesystem.open (path, 'wb')
- except:
- request.error (405)
- return
-
- request.collector = put_collector (output_file, cl, request, is_update)
-
- # no terminator while receiving PUT data
- request.channel.set_terminator (None)
-
- # don't respond yet, wait until we've received the data...
-
-class put_collector:
- def __init__ (self, file, length, request, is_update):
- self.file = file
- self.length = length
- self.request = request
- self.is_update = is_update
- self.bytes_in = 0
-
- def collect_incoming_data (self, data):
- ld = len(data)
- bi = self.bytes_in
- if (bi + ld) >= self.length:
- # last bit of data
- chunk = self.length - bi
- self.file.write (data[:chunk])
- self.file.close()
-
- if chunk != ld:
- print 'orphaned %d bytes: <%s>' % (ld - chunk, repr(data[chunk:]))
-
- # do some housekeeping
- r = self.request
- ch = r.channel
- ch.current_request = None
- # set the terminator back to the default
- ch.set_terminator ('\r\n\r\n')
- if self.is_update:
- r.reply_code = 204 # No content
- r.done()
- else:
- r.reply_now (201) # Created
- # avoid circular reference
- del self.request
- else:
- self.file.write (data)
- self.bytes_in = self.bytes_in + ld
-
- def found_terminator (self):
- # shouldn't be called
- pass
-
-CONTENT_LENGTH = re.compile ('Content-Length: ([0-9]+)', re.IGNORECASE)
diff --git a/demo/medusa/redirecting_handler.py b/demo/medusa/redirecting_handler.py
deleted file mode 100644
index e6a1e90..0000000
--- a/demo/medusa/redirecting_handler.py
+++ /dev/null
@@ -1,44 +0,0 @@
-# -*- Mode: Python; tab-width: 4 -*-
-#
-# Author: Sam Rushing <rushing@nightmare.com>
-# Copyright 1996-2000 by Sam Rushing
-# All Rights Reserved.
-#
-
-import re
-import counter
-
-class redirecting_handler:
-
- def __init__ (self, pattern, redirect, regex_flag=re.IGNORECASE):
- self.pattern = pattern
- self.redirect = redirect
- self.patreg = re.compile (pattern, regex_flag)
- self.hits = counter.counter()
-
- def match (self, request):
- m = self.patref.match (request.uri)
- return (m and (m.end() == len(request.uri)))
-
- def handle_request (self, request):
- self.hits.increment()
- m = self.patreg.match (request.uri)
- part = m.group(1)
-
- request['Location'] = self.redirect % part
- request.error (302) # moved temporarily
-
- def __repr__ (self):
- return '<Redirecting Handler at %08x [%s => %s]>' % (
- id(self),
- repr(self.pattern),
- repr(self.redirect)
- )
-
- def status (self):
- import producers
- return producers.simple_producer (
- '<li> Redirecting Handler %s => %s <b>Hits</b>: %s' % (
- self.pattern, self.redirect, self.hits
- )
- )
diff --git a/demo/medusa/server.pem b/demo/medusa/server.pem
deleted file mode 100644
index 1ee9282..0000000
--- a/demo/medusa/server.pem
+++ /dev/null
@@ -1,36 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDYjCCAsugAwIBAgIBBDANBgkqhkiG9w0BAQQFADCBgDELMAkGA1UEBhMCU0cx
-ETAPBgNVBAoTCE0yQ3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UE
-AxMbTTJDcnlwdG8gQ2VydGlmaWNhdGUgTWFzdGVyMSIwIAYJKoZIhvcNAQkBFhNu
-Z3BzQG5ldG1lbWV0aWMuY29tMB4XDTAzMDYyMjEzMzAxNFoXDTA0MDYyMTEzMzAx
-NFowXTELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRIwEAYDVQQDEwls
-b2NhbGhvc3QxJzAlBgkqhkiG9w0BCQEWGGFkbWluQHNlcnZlci5leGFtcGxlLmRv
-bTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA37aKGZtFicl8xXXTLJ8/JD7c
-kd3t/teCX9i61lpaDQCKBoVrrursIvZihemMKI9g/u/+BLqt5g8mBdgUdYz0txc8
-KEbV2hj+wwOX4H3XwD0Y+DysXiNHq7/tFdmzSVHoLxpY4zYzXbxQ/p049wvIyPRp
-/y3omcnx/TEUhkn+JmkCAwEAAaOCAQwwggEIMAkGA1UdEwQCMAAwLAYJYIZIAYb4
-QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBTB
-H/mUYlww24mJlSxEtGdlwojO9zCBrQYDVR0jBIGlMIGigBTr+pwHMS1CmF9cuGI4
-du3YqoHAwqGBhqSBgzCBgDELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRv
-MRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UEAxMbTTJDcnlwdG8gQ2VydGlm
-aWNhdGUgTWFzdGVyMSIwIAYJKoZIhvcNAQkBFhNuZ3BzQG5ldG1lbWV0aWMuY29t
-ggEAMA0GCSqGSIb3DQEBBAUAA4GBAAvl6v0s3eFeGP4iAcrfysuK7jzFKhjDYuOy
-lVS3u33bZNLnMpM6OSEM9yPh4WpFCVHf+nYwC71pk4ilsLVXjKxymm2lNGcxLVuW
-iydFz4Ly9nmN7Ja9ygYT39dGAFP/wN7ELTpsbul8VfmqhNg9y81d8i/A1tK3AGA8
-0QkPQNdP
------END CERTIFICATE-----
------BEGIN RSA PRIVATE KEY-----
-MIICXAIBAAKBgQDftooZm0WJyXzFddMsnz8kPtyR3e3+14Jf2LrWWloNAIoGhWuu
-6uwi9mKF6Ywoj2D+7/4Euq3mDyYF2BR1jPS3FzwoRtXaGP7DA5fgfdfAPRj4PKxe
-I0erv+0V2bNJUegvGljjNjNdvFD+nTj3C8jI9Gn/LeiZyfH9MRSGSf4maQIDAQAB
-AoGAHpeVtv62uarl9xKvuBBm0AwQmZnhq9HIsFaw5hMg8Vo7hbzFBvx1IirTOkC/
-u+QvfW1QLVFh6m3z4ySzV4fZBtcd6F9SbSrZ0xsxIUB2NOSa1RGgiaP61bJnMMM1
-xM3O9iwM5GZc3Gqy08QOCpDl0772VJ+9Gz3FA88mrc6rHQkCQQDz6RIatFjT28n8
-1vy0nHwwZz2oXTpe/pyZPwoKj8zVsmrKhKwOw7l8ArxjP8zoHOE7AQBCXYDMNoFp
-IAF0yuqrAkEA6s0wMEdPpQeb0XHAfccyJQoeULxHdVFoz1wWmGSOm4YmQtR8/QJx
-luEgfpeRkzxBKt5Ls3MEkheIOw7xV24zOwJAMz+DaE0AZPNHS3K4ghJnHZxzng6I
-lzEUIjbWm0V/ml70hTy/EhMZw+6nOotLOHHo+QbK0SboSwAgzL/Gzo1cJQJANqpS
-38qadleRJXAQWrg3qnvyluVe1aeAeVZ9RDmVIgxXeBO0jcs12uTLBe4PzHGo0mwy
-v7K1i7XC180gzzQu5QJBAOxITT9RoWSSozPvnirHd37sn+RsrNYkV07NAa80M20Z
-DkBPHeMVkNgigrQ6L6vWmbRDGQbGcMplAxnI5ppKCoU=
------END RSA PRIVATE KEY-----
diff --git a/demo/medusa/status_handler.py b/demo/medusa/status_handler.py
deleted file mode 100644
index 2e6223e..0000000
--- a/demo/medusa/status_handler.py
+++ /dev/null
@@ -1,282 +0,0 @@
-# -*- Mode: Python; tab-width: 4 -*-
-
-VERSION_STRING = "$Id: status_handler.py 299 2005-06-09 17:32:28Z heikki $"
-
-#
-# medusa status extension
-#
-
-import string
-import time
-import re
-
-import asyncore
-import http_server
-import medusa_gif
-import producers
-from counter import counter
-
-START_TIME = long(time.time())
-
-class status_extension:
- hit_counter = counter()
-
- def __init__ (self, objects, statusdir='/status', allow_emergency_debug=0):
- self.objects = objects
- self.statusdir = statusdir
- self.allow_emergency_debug = allow_emergency_debug
- # We use /status instead of statusdir here because it's too
- # hard to pass statusdir to the logger, who makes the HREF
- # to the object dir. We don't need the security-through-
- # obscurity here in any case, because the id is obscurity enough
- self.hyper_regex = re.compile('/status/object/([0-9]+)/.*')
- self.hyper_objects = []
- for object in objects:
- self.register_hyper_object (object)
-
- def __repr__ (self):
- return '<Status Extension (%s hits) at %x>' % (
- self.hit_counter,
- id(self)
- )
-
- def match (self, request):
- path, params, query, fragment = request.split_uri()
- # For reasons explained above, we don't use statusdir for /object
- return (path[:len(self.statusdir)] == self.statusdir or
- path[:len("/status/object/")] == '/status/object/')
-
- # Possible Targets:
- # /status
- # /status/channel_list
- # /status/medusa.gif
-
- # can we have 'clickable' objects?
- # [yes, we can use id(x) and do a linear search]
-
- # Dynamic producers:
- # HTTP/1.0: we must close the channel, because it's dynamic output
- # HTTP/1.1: we can use the chunked transfer-encoding, and leave
- # it open.
-
- def handle_request (self, request):
- [path, params, query, fragment] = request.split_uri()
- self.hit_counter.increment()
- if path == self.statusdir: # and not a subdirectory
- up_time = string.join (english_time (long(time.time()) - START_TIME))
- request['Content-Type'] = 'text/html'
- request.push (
- '<html>'
- '<title>Medusa Status Reports</title>'
- '<body bgcolor="#ffffff">'
- '<h1>Medusa Status Reports</h1>'
- '<b>Up:</b> %s' % up_time
- )
- for i in range(len(self.objects)):
- request.push (self.objects[i].status())
- request.push ('<hr>\r\n')
- request.push (
- '<p><a href="%s/channel_list">Channel List</a>'
- '<hr>'
- '<img src="%s/medusa.gif" align=right width=%d height=%d>'
- '</body></html>' % (
- self.statusdir,
- self.statusdir,
- medusa_gif.width,
- medusa_gif.height
- )
- )
- request.done()
- elif path == self.statusdir + '/channel_list':
- request['Content-Type'] = 'text/html'
- request.push ('<html><body>')
- request.push(channel_list_producer(self.statusdir))
- request.push (
- '<hr>'
- '<img src="%s/medusa.gif" align=right width=%d height=%d>' % (
- self.statusdir,
- medusa_gif.width,
- medusa_gif.height
- ) +
- '</body></html>'
- )
- request.done()
-
- elif path == self.statusdir + '/medusa.gif':
- request['Content-Type'] = 'image/gif'
- request['Content-Length'] = len(medusa_gif.data)
- request.push (medusa_gif.data)
- request.done()
-
- elif path == self.statusdir + '/close_zombies':
- message = (
- '<h2>Closing all zombie http client connections...</h2>'
- '<p><a href="%s">Back to the status page</a>' % self.statusdir
- )
- request['Content-Type'] = 'text/html'
- request['Content-Length'] = len (message)
- request.push (message)
- now = int (time.time())
- for channel in asyncore.socket_map.keys():
- if channel.__class__ == http_server.http_channel:
- if channel != request.channel:
- if (now - channel.creation_time) > channel.zombie_timeout:
- channel.close()
- request.done()
-
- # Emergency Debug Mode
- # If a server is running away from you, don't KILL it!
- # Move all the AF_INET server ports and perform an autopsy...
- # [disabled by default to protect the innocent]
- elif self.allow_emergency_debug and path == self.statusdir + '/emergency_debug':
- request.push ('<html>Moving All Servers...</html>')
- request.done()
- for channel in asyncore.socket_map.keys():
- if channel.accepting:
- if type(channel.addr) is type(()):
- ip, port = channel.addr
- channel.socket.close()
- channel.del_channel()
- channel.addr = (ip, port+10000)
- fam, typ = channel.family_and_type
- channel.create_socket (fam, typ)
- channel.set_reuse_addr()
- channel.bind (channel.addr)
- channel.listen(5)
-
- else:
- m = self.hyper_regex.match (path)
- if m:
- oid = string.atoi (m.group (1))
- for object in self.hyper_objects:
- if id (object) == oid:
- if hasattr (object, 'hyper_respond'):
- object.hyper_respond (self, path, request)
- else:
- request.error (404)
- return
-
- def status (self):
- return producers.simple_producer (
- '<li>Status Extension <b>Hits</b> : %s' % self.hit_counter
- )
-
- def register_hyper_object (self, object):
- if not object in self.hyper_objects:
- self.hyper_objects.append (object)
-
-import logger
-
-class logger_for_status (logger.tail_logger):
-
- def status (self):
- return 'Last %d log entries for: %s' % (
- len (self.messages),
- html_repr (self)
- )
-
- def hyper_respond (self, sh, path, request):
- request['Content-Type'] = 'text/plain'
- messages = self.messages[:]
- messages.reverse()
- request.push (lines_producer (messages))
- request.done()
-
-class lines_producer:
- def __init__ (self, lines):
- self.lines = lines
-
- def ready (self):
- return len(self.lines)
-
- def more (self):
- if self.lines:
- chunk = self.lines[:50]
- self.lines = self.lines[50:]
- return string.join (chunk, '\r\n') + '\r\n'
- else:
- return ''
-
-class channel_list_producer (lines_producer):
- def __init__ (self, statusdir):
- channel_reprs = map (
- lambda x: '&lt;' + repr(x)[1:-1] + '&gt;',
- asyncore.socket_map.values()
- )
- channel_reprs.sort()
- lines_producer.__init__ (
- self,
- ['<h1>Active Channel List</h1>',
- '<pre>'
- ] + channel_reprs + [
- '</pre>',
- '<p><a href="%s">Status Report</a>' % statusdir
- ]
- )
-
-
-# this really needs a full-blown quoter...
-def sanitize (s):
- if '<' in s:
- s = string.join (string.split (s, '<'), '&lt;')
- if '>' in s:
- s = string.join (string.split (s, '>'), '&gt;')
- return s
-
-def html_repr (object):
- so = sanitize (repr (object))
- if hasattr (object, 'hyper_respond'):
- return '<a href="/status/object/%d/">%s</a>' % (id (object), so)
- else:
- return so
-
-def html_reprs (list, front='', back=''):
- reprs = map (
- lambda x,f=front,b=back: '%s%s%s' % (f,x,b),
- map (lambda x: sanitize (html_repr(x)), list)
- )
- reprs.sort()
- return reprs
-
-# for example, tera, giga, mega, kilo
-# p_d (n, (1024, 1024, 1024, 1024))
-# smallest divider goes first - for example
-# minutes, hours, days
-# p_d (n, (60, 60, 24))
-
-def progressive_divide (n, parts):
- result = []
- for part in parts:
- n, rem = divmod (n, part)
- result.append (rem)
- result.append (n)
- return result
-
-# b,k,m,g,t
-def split_by_units (n, units, dividers, format_string):
- divs = progressive_divide (n, dividers)
- result = []
- for i in range(len(units)):
- if divs[i]:
- result.append (format_string % (divs[i], units[i]))
- result.reverse()
- if not result:
- return [format_string % (0, units[0])]
- else:
- return result
-
-def english_bytes (n):
- return split_by_units (
- n,
- ('','K','M','G','T'),
- (1024, 1024, 1024, 1024, 1024),
- '%d %sB'
- )
-
-def english_time (n):
- return split_by_units (
- n,
- ('secs', 'mins', 'hours', 'days', 'weeks', 'years'),
- ( 60, 60, 24, 7, 52),
- '%d %s'
- )
diff --git a/demo/medusa/virtual_handler.py b/demo/medusa/virtual_handler.py
deleted file mode 100644
index 96f19df..0000000
--- a/demo/medusa/virtual_handler.py
+++ /dev/null
@@ -1,60 +0,0 @@
-# -*- Mode: Python; tab-width: 4 -*-
-
-import socket
-import default_handler
-import re
-
-HOST = re.compile ('Host: ([^:/]+).*', re.IGNORECASE)
-
-get_header = default_handler.get_header
-
-class virtual_handler:
-
- """HTTP request handler for an HTTP/1.0-style virtual host. Each
- Virtual host must have a different IP"""
-
- def __init__ (self, handler, hostname):
- self.handler = handler
- self.hostname = hostname
- try:
- self.ip = socket.gethostbyname (hostname)
- except socket.error:
- raise ValueError, "Virtual Hostname %s does not appear to be registered in the DNS" % hostname
-
- def match (self, request):
- if (request.channel.addr[0] == self.ip):
- return 1
- else:
- return 0
-
- def handle_request (self, request):
- return self.handler.handle_request (request)
-
- def __repr__ (self):
- return '<virtual request handler for %s>' % self.hostname
-
-
-class virtual_handler_with_host:
-
- """HTTP request handler for HTTP/1.1-style virtual hosts. This
- matches by checking the value of the 'Host' header in the request.
- You actually don't _have_ to support HTTP/1.1 to use this, since
- many browsers now send the 'Host' header. This is a Good Thing."""
-
- def __init__ (self, handler, hostname):
- self.handler = handler
- self.hostname = hostname
-
- def match (self, request):
- host = get_header (HOST, request.header)
- if host == self.hostname:
- return 1
- else:
- return 0
-
- def handle_request (self, request):
- return self.handler.handle_request (request)
-
- def __repr__ (self):
- return '<virtual request handler for %s>' % self.hostname
-
diff --git a/demo/medusa/xmlrpc_handler.py b/demo/medusa/xmlrpc_handler.py
deleted file mode 100644
index d56baf2..0000000
--- a/demo/medusa/xmlrpc_handler.py
+++ /dev/null
@@ -1,104 +0,0 @@
-# -*- Mode: Python; tab-width: 4 -*-
-
-# See http://www.xml-rpc.com/
-# http://www.pythonware.com/products/xmlrpc/
-
-# Based on "xmlrpcserver.py" by Fredrik Lundh (fredrik@pythonware.com)
-
-VERSION = "$Id: xmlrpc_handler.py 299 2005-06-09 17:32:28Z heikki $"
-
-import http_server
-import xmlrpclib
-
-import string
-import sys
-
-class xmlrpc_handler:
-
- def match (self, request):
- # Note: /RPC2 is not required by the spec, so you may override this method.
- if request.uri[:5] == '/RPC2':
- return 1
- else:
- return 0
-
- def handle_request (self, request):
- [path, params, query, fragment] = request.split_uri()
-
- if request.command in ('post', 'put'):
- request.collector = collector (self, request)
- else:
- request.error (400)
-
- def continue_request (self, data, request):
- params, method = xmlrpclib.loads (data)
- try:
- # generate response
- try:
- response = self.call (method, params)
- if type(response) != type(()):
- response = (response,)
- except:
- # report exception back to server
- response = xmlrpclib.dumps (
- xmlrpclib.Fault (1, "%s:%s" % (sys.exc_type, sys.exc_value))
- )
- else:
- response = xmlrpclib.dumps (response, methodresponse=1)
- except:
- # internal error, report as HTTP server error
- request.error (500)
- else:
- # got a valid XML RPC response
- request['Content-Type'] = 'text/xml'
- request.push (response)
- request.done()
-
- def call (self, method, params):
- # override this method to implement RPC methods
- raise "NotYetImplemented"
-
-class collector:
-
- "gathers input for POST and PUT requests"
-
- def __init__ (self, handler, request):
-
- self.handler = handler
- self.request = request
- self.data = ''
-
- # make sure there's a content-length header
- cl = request.get_header ('content-length')
-
- if not cl:
- request.error (411)
- else:
- cl = string.atoi (cl)
- # using a 'numeric' terminator
- self.request.channel.set_terminator (cl)
-
- def collect_incoming_data (self, data):
- self.data = self.data + data
-
- def found_terminator (self):
- # set the terminator back to the default
- self.request.channel.set_terminator ('\r\n\r\n')
- self.handler.continue_request (self.data, self.request)
-
-if __name__ == '__main__':
-
- class rpc_demo (xmlrpc_handler):
-
- def call (self, method, params):
- print 'method="%s" params=%s' % (method, params)
- return "Sure, that works"
-
- import asyncore
- import http_server
-
- hs = http_server.http_server ('', 8000)
- rpc = rpc_demo()
- hs.install_handler (rpc)
-
- asyncore.loop()
diff --git a/demo/medusa054/00_README b/demo/medusa054/00_README
deleted file mode 100644
index 5701364..0000000
--- a/demo/medusa054/00_README
+++ /dev/null
@@ -1,30 +0,0 @@
-
- 21 Mar 2004
--------------
-
-M2Crypto HTTPS and FTP/TLS servers
-
-All the files in this directory are from Medusa 0.54, except for the
-following:
-
-- 00_README (this file)
-- server.pem, the server's certificate
-- ca.pem, my CA certificate
-- https_server.py
-- ftps_server.py
-- START.py
-- START_xmlrpc.py
-- index.html, a sample HTML file
-- poison_handler.py, a webpoison clone
-
-By default, http_server listens on port 39080 and https_server port
-39443. Document root is current directory, and serves up index.html.
-
-The xmlrpc server is accessible below '/RPC2'.
-
-The FTP/TLS server listens on port 39021 by default. I've only tested it with
-the 'anonymous' authentication handler.
-
-Medusa files are copyright Sam Rushing. Recent versions are maintained
-by Andrew Kuchling. My files are copyright me.
-
diff --git a/demo/medusa054/START.py b/demo/medusa054/START.py
deleted file mode 100644
index fb08ab3..0000000
--- a/demo/medusa054/START.py
+++ /dev/null
@@ -1,71 +0,0 @@
-#!/usr/bin/env python
-
-# Standard Python library
-import os
-import os.path
-import sys
-
-# Medusa
-import asyncore
-import default_handler
-import filesys
-import ftp_server
-import http_server
-import status_handler
-
-# M2Crypto
-import https_server
-import poison_handler
-import ftps_server
-from M2Crypto import Rand, SSL, threading
-
-HTTP_PORT=39080
-HTTPS_PORT=39443
-FTP_PORT = 39021
-
-hs=http_server.http_server('', HTTP_PORT)
-
-Rand.load_file('../randpool.dat', -1)
-ssl_ctx=SSL.Context('sslv23')
-ssl_ctx.load_cert('server.pem')
-ssl_ctx.load_verify_locations('ca.pem', '')
-ssl_ctx.load_client_CA('ca.pem')
-#ssl_ctx.set_verify(SSL.verify_peer, 10)
-#ssl_ctx.set_verify(SSL.verify_peer|SSL.verify_fail_if_no_peer_cert, 10)
-#ssl_ctx.set_verify(SSL.verify_peer|SSL.verify_client_once, 10)
-ssl_ctx.set_verify(SSL.verify_none, 10)
-ssl_ctx.set_session_id_ctx('127.0.0.1:39443')
-ssl_ctx.set_tmp_dh('dh1024.pem')
-ssl_ctx.set_info_callback()
-
-hss=https_server.https_server('', HTTPS_PORT, ssl_ctx)
-
-fs=filesys.os_filesystem(os.path.abspath(os.curdir))
-#fs=filesys.os_filesystem('/usr/local/pkg/apache/htdocs')
-#fs=filesys.os_filesystem('c:/pkg/jdk130/docs')
-dh=default_handler.default_handler(fs)
-hs.install_handler(dh)
-hss.install_handler(dh)
-
-#class rpc_demo (xmlrpc_handler.xmlrpc_handler):
-# def call (self, method, params):
-# print 'method="%s" params=%s' % (method, params)
-# return "Sure, that works"
-#rpch = rpc_demo()
-#hs.install_handler(rpch)
-#hss.install_handler(rpch)
-
-ph=poison_handler.poison_handler(10)
-hs.install_handler(ph)
-hss.install_handler(ph)
-
-fauthz = ftp_server.anon_authorizer('/usr/local/pkg/apache/htdocs')
-ftps = ftps_server.ftp_tls_server(fauthz, ssl_ctx, port=FTP_PORT)
-
-sh=status_handler.status_extension([hs, hss, ftps])
-hs.install_handler(sh)
-hss.install_handler(sh)
-
-asyncore.loop()
-Rand.save_file('../randpool.dat')
-
diff --git a/demo/medusa054/START_xmlrpc.py b/demo/medusa054/START_xmlrpc.py
deleted file mode 100644
index 65b6d67..0000000
--- a/demo/medusa054/START_xmlrpc.py
+++ /dev/null
@@ -1,72 +0,0 @@
-#!/usr/bin/env python
-
-# Standard Python library
-import os
-import os.path
-import sys
-
-# Medusa
-import asyncore
-import default_handler
-import filesys
-import http_server
-import status_handler
-
-# M2Crypto
-import https_server
-import poison_handler
-from M2Crypto import Rand, SSL
-
-# XMLrpc
-import xmlrpc_handler
-
-
-HTTP_PORT=39080
-HTTPS_PORT=39443
-
-hs=http_server.http_server('', HTTP_PORT)
-
-Rand.load_file('../randpool.dat', -1)
-ssl_ctx=SSL.Context('sslv23')
-ssl_ctx.load_cert('server.pem')
-#ssl_ctx.load_verify_location('ca.pem')
-#ssl_ctx.load_client_CA('ca.pem')
-#ssl_ctx.set_verify(SSL.verify_peer, 10)
-#ssl_ctx.set_verify(SSL.verify_peer|SSL.verify_fail_if_no_peer_cert, 10)
-#ssl_ctx.set_verify(SSL.verify_peer|SSL.verify_client_once, 10)
-ssl_ctx.set_verify(SSL.verify_none, 10)
-ssl_ctx.set_session_id_ctx('127.0.0.1:9443')
-ssl_ctx.set_tmp_dh('dh1024.pem')
-#ssl_ctx.set_info_callback()
-
-hss=https_server.https_server('', HTTPS_PORT, ssl_ctx)
-
-fs=filesys.os_filesystem(os.path.abspath(os.curdir))
-#fs=filesys.os_filesystem('/usr/local/pkg/apache/htdocs')
-#fs=filesys.os_filesystem('c:/pkg/jdk118/docs')
-dh=default_handler.default_handler(fs)
-hs.install_handler(dh)
-hss.install_handler(dh)
-
-# Cribbed from xmlrpc_handler.py.
-# This is where you implement your RPC functionality.
-class rpc_demo (xmlrpc_handler.xmlrpc_handler):
- def call (self, method, params):
- print 'method="%s" params=%s' % (method, params)
- return "Sure, that works"
-
-rpch = rpc_demo()
-hs.install_handler(rpch)
-hss.install_handler(rpch)
-
-ph=poison_handler.poison_handler(10)
-hs.install_handler(ph)
-hss.install_handler(ph)
-
-sh=status_handler.status_extension([hss])
-hs.install_handler(sh)
-hss.install_handler(sh)
-
-asyncore.loop()
-Rand.save_file('../randpool.dat')
-
diff --git a/demo/medusa054/ca.pem b/demo/medusa054/ca.pem
deleted file mode 100644
index b7c84a1..0000000
--- a/demo/medusa054/ca.pem
+++ /dev/null
@@ -1,20 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDWTCCAsKgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBgDELMAkGA1UEBhMCU0cx
-ETAPBgNVBAoTCE0yQ3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UE
-AxMbTTJDcnlwdG8gQ2VydGlmaWNhdGUgTWFzdGVyMSIwIAYJKoZIhvcNAQkBFhNu
-Z3BzQG5ldG1lbWV0aWMuY29tMB4XDTAxMTIxNTA1NTU0NloXDTA0MTIxNDA1NTU0
-NlowgYAxCzAJBgNVBAYTAlNHMREwDwYDVQQKEwhNMkNyeXB0bzEUMBIGA1UECxML
-TTJDcnlwdG8gQ0ExJDAiBgNVBAMTG00yQ3J5cHRvIENlcnRpZmljYXRlIE1hc3Rl
-cjEiMCAGCSqGSIb3DQEJARYTbmdwc0BuZXRtZW1ldGljLmNvbTCBnzANBgkqhkiG
-9w0BAQEFAAOBjQAwgYkCgYEAx8soJbS719LHK62VVVIQeC3oW0HvFArwPnA0LuEK
-q+LaqMOJg1rS7hvFdX03diV+XJw7cC0iECZYJNG4ii1xbY6KRmufkInaAwm54E3N
-e+YYVocaqUkcN6xVf6fwnLfPXbpFS/K2Umg11ObKMmi80JmiIdjcjRRCQZC7g1hf
-q+kCAwEAAaOB4DCB3TAdBgNVHQ4EFgQU6/qcBzEtQphfXLhiOHbt2KqBwMIwga0G
-A1UdIwSBpTCBooAU6/qcBzEtQphfXLhiOHbt2KqBwMKhgYakgYMwgYAxCzAJBgNV
-BAYTAlNHMREwDwYDVQQKEwhNMkNyeXB0bzEUMBIGA1UECxMLTTJDcnlwdG8gQ0Ex
-JDAiBgNVBAMTG00yQ3J5cHRvIENlcnRpZmljYXRlIE1hc3RlcjEiMCAGCSqGSIb3
-DQEJARYTbmdwc0BuZXRtZW1ldGljLmNvbYIBADAMBgNVHRMEBTADAQH/MA0GCSqG
-SIb3DQEBBAUAA4GBAD+I14GuS5vJmyv1k7mUMbAicsWRHZ+zrGOq9L/L2LsA+lKQ
-dAzEZE2+Zv8LBPJVltbJJhcFNJS/ZMAjEm4xlJuCpvXVMxd/M5AM29aqekWlIK7J
-vsdDL8IuzpRkMniUiNKPhmB6IPIOslvUKx6QofcE0wDh6pg4VvIbCjkpZ7gf
------END CERTIFICATE-----
diff --git a/demo/medusa054/counter.py b/demo/medusa054/counter.py
deleted file mode 100644
index 9dae67c..0000000
--- a/demo/medusa054/counter.py
+++ /dev/null
@@ -1,51 +0,0 @@
-# -*- Mode: Python -*-
-
-# It is tempting to add an __int__ method to this class, but it's not
-# a good idea. This class tries to gracefully handle integer
-# overflow, and to hide this detail from both the programmer and the
-# user. Note that the __str__ method can be relied on for printing out
-# the value of a counter:
-#
-# >>> print 'Total Client: %s' % self.total_clients
-#
-# If you need to do arithmetic with the value, then use the 'as_long'
-# method, the use of long arithmetic is a reminder that the counter
-# will overflow.
-
-class counter:
- "general-purpose counter"
-
- def __init__ (self, initial_value=0):
- self.value = initial_value
-
- def increment (self, delta=1):
- result = self.value
- try:
- self.value = self.value + delta
- except OverflowError:
- self.value = long(self.value) + delta
- return result
-
- def decrement (self, delta=1):
- result = self.value
- try:
- self.value = self.value - delta
- except OverflowError:
- self.value = long(self.value) - delta
- return result
-
- def as_long (self):
- return long(self.value)
-
- def __nonzero__ (self):
- return self.value != 0
-
- def __repr__ (self):
- return '<counter value=%s at %x>' % (self.value, id(self))
-
- def __str__ (self):
- s = str(long(self.value))
- if s[-1:] == 'L':
- s = s[:-1]
- return s
-
diff --git a/demo/medusa054/default_handler.py b/demo/medusa054/default_handler.py
deleted file mode 100644
index 9d5e9d7..0000000
--- a/demo/medusa054/default_handler.py
+++ /dev/null
@@ -1,213 +0,0 @@
-# -*- Mode: Python -*-
-#
-# Author: Sam Rushing <rushing@nightmare.com>
-# Copyright 1997 by Sam Rushing
-# All Rights Reserved.
-#
-
-# standard python modules
-import mimetypes
-import re
-import stat
-import string
-
-# medusa modules
-import http_date
-import http_server
-import status_handler
-import producers
-
-unquote = http_server.unquote
-
-# This is the 'default' handler. it implements the base set of
-# features expected of a simple file-delivering HTTP server. file
-# services are provided through a 'filesystem' object, the very same
-# one used by the FTP server.
-#
-# You can replace or modify this handler if you want a non-standard
-# HTTP server. You can also derive your own handler classes from
-# it.
-#
-# support for handling POST requests is available in the derived
-# class <default_with_post_handler>, defined below.
-#
-
-from counter import counter
-
-class default_handler:
-
- valid_commands = ['GET', 'HEAD']
-
- IDENT = 'Default HTTP Request Handler'
-
- # Pathnames that are tried when a URI resolves to a directory name
- directory_defaults = [
- 'index.html',
- 'default.html'
- ]
-
- default_file_producer = producers.file_producer
-
- def __init__ (self, filesystem):
- self.filesystem = filesystem
- # count total hits
- self.hit_counter = counter()
- # count file deliveries
- self.file_counter = counter()
- # count cache hits
- self.cache_counter = counter()
-
- hit_counter = 0
-
- def __repr__ (self):
- return '<%s (%s hits) at %x>' % (
- self.IDENT,
- self.hit_counter,
- id (self)
- )
-
- # always match, since this is a default
- def match (self, request):
- return 1
-
- # handle a file request, with caching.
-
- def handle_request (self, request):
-
- if request.command not in self.valid_commands:
- request.error (400) # bad request
- return
-
- self.hit_counter.increment()
-
- path, params, query, fragment = request.split_uri()
-
- if '%' in path:
- path = unquote (path)
-
- # strip off all leading slashes
- while path and path[0] == '/':
- path = path[1:]
-
- if self.filesystem.isdir (path):
- if path and path[-1] != '/':
- request['Location'] = 'http://%s/%s/' % (
- request.channel.server.server_name,
- path
- )
- request.error (301)
- return
-
- # we could also generate a directory listing here,
- # may want to move this into another method for that
- # purpose
- found = 0
- if path and path[-1] != '/':
- path = path + '/'
- for default in self.directory_defaults:
- p = path + default
- if self.filesystem.isfile (p):
- path = p
- found = 1
- break
- if not found:
- request.error (404) # Not Found
- return
-
- elif not self.filesystem.isfile (path):
- request.error (404) # Not Found
- return
-
- file_length = self.filesystem.stat (path)[stat.ST_SIZE]
-
- ims = get_header_match (IF_MODIFIED_SINCE, request.header)
-
- length_match = 1
- if ims:
- length = ims.group (4)
- if length:
- try:
- length = string.atoi (length)
- if length != file_length:
- length_match = 0
- except:
- pass
-
- ims_date = 0
-
- if ims:
- ims_date = http_date.parse_http_date (ims.group (1))
-
- try:
- mtime = self.filesystem.stat (path)[stat.ST_MTIME]
- except:
- request.error (404)
- return
-
- if length_match and ims_date:
- if mtime <= ims_date:
- request.reply_code = 304
- request.done()
- self.cache_counter.increment()
- return
- try:
- file = self.filesystem.open (path, 'rb')
- except IOError:
- request.error (404)
- return
-
- request['Last-Modified'] = http_date.build_http_date (mtime)
- request['Content-Length'] = file_length
- self.set_content_type (path, request)
-
- if request.command == 'GET':
- request.push (self.default_file_producer (file))
-
- self.file_counter.increment()
- request.done()
-
- def set_content_type (self, path, request):
- ext = string.lower (get_extension (path))
- typ, encoding = mimetypes.guess_type(path)
- if typ is not None:
- request['Content-Type'] = typ
- else:
- # TODO: test a chunk off the front of the file for 8-bit
- # characters, and use application/octet-stream instead.
- request['Content-Type'] = 'text/plain'
-
- def status (self):
- return producers.simple_producer (
- '<li>%s' % status_handler.html_repr (self)
- + '<ul>'
- + ' <li><b>Total Hits:</b> %s' % self.hit_counter
- + ' <li><b>Files Delivered:</b> %s' % self.file_counter
- + ' <li><b>Cache Hits:</b> %s' % self.cache_counter
- + '</ul>'
- )
-
-# HTTP/1.0 doesn't say anything about the "; length=nnnn" addition
-# to this header. I suppose its purpose is to avoid the overhead
-# of parsing dates...
-IF_MODIFIED_SINCE = re.compile (
- 'If-Modified-Since: ([^;]+)((; length=([0-9]+)$)|$)',
- re.IGNORECASE
- )
-
-USER_AGENT = re.compile ('User-Agent: (.*)', re.IGNORECASE)
-
-CONTENT_TYPE = re.compile (
- r'Content-Type: ([^;]+)((; boundary=([A-Za-z0-9\'\(\)+_,./:=?-]+)$)|$)',
- re.IGNORECASE
- )
-
-get_header = http_server.get_header
-get_header_match = http_server.get_header_match
-
-def get_extension (path):
- dirsep = string.rfind (path, '/')
- dotsep = string.rfind (path, '.')
- if dotsep > dirsep:
- return path[dotsep+1:]
- else:
- return ''
diff --git a/demo/medusa054/dh1024.pem b/demo/medusa054/dh1024.pem
deleted file mode 100644
index 81d43f6..0000000
--- a/demo/medusa054/dh1024.pem
+++ /dev/null
@@ -1,5 +0,0 @@
------BEGIN DH PARAMETERS-----
-MIGHAoGBAJf2QmHKtQXdKCjhPx1ottPb0PMTBH9A6FbaWMsTuKG/K3g6TG1Z1fkq
-/Gz/PWk/eLI9TzFgqVAuPvr3q14a1aZeVUMTgo2oO5/y2UHe6VaJ+trqCTat3xlx
-/mNbIK9HA2RgPC3gWfVLZQrY+gz3ASHHR5nXWHEyvpuZm7m3h+irAgEC
------END DH PARAMETERS-----
diff --git a/demo/medusa054/filesys.py b/demo/medusa054/filesys.py
deleted file mode 100644
index 1affd8f..0000000
--- a/demo/medusa054/filesys.py
+++ /dev/null
@@ -1,394 +0,0 @@
-# -*- Mode: Python -*-
-# $Id: filesys.py 299 2005-06-09 17:32:28Z heikki $
-# Author: Sam Rushing <rushing@nightmare.com>
-#
-# Generic filesystem interface.
-#
-
-# We want to provide a complete wrapper around any and all
-# filesystem operations.
-
-# this class is really just for documentation,
-# identifying the API for a filesystem object.
-
-# opening files for reading, and listing directories, should
-# return a producer.
-
-class abstract_filesystem:
- def __init__ (self):
- pass
-
- def current_directory (self):
- "Return a string representing the current directory."
- pass
-
- def listdir (self, path, long=0):
- """Return a listing of the directory at 'path' The empty string
- indicates the current directory. If 'long' is set, instead
- return a list of (name, stat_info) tuples
- """
- pass
-
- def open (self, path, mode):
- "Return an open file object"
- pass
-
- def stat (self, path):
- "Return the equivalent of os.stat() on the given path."
- pass
-
- def isdir (self, path):
- "Does the path represent a directory?"
- pass
-
- def isfile (self, path):
- "Does the path represent a plain file?"
- pass
-
- def cwd (self, path):
- "Change the working directory."
- pass
-
- def cdup (self):
- "Change to the parent of the current directory."
- pass
-
-
- def longify (self, path):
- """Return a 'long' representation of the filename
- [for the output of the LIST command]"""
- pass
-
-# standard wrapper around a unix-like filesystem, with a 'false root'
-# capability.
-
-# security considerations: can symbolic links be used to 'escape' the
-# root? should we allow it? if not, then we could scan the
-# filesystem on startup, but that would not help if they were added
-# later. We will probably need to check for symlinks in the cwd method.
-
-# what to do if wd is an invalid directory?
-
-import os
-import stat
-import re
-import string
-
-def safe_stat (path):
- try:
- return (path, os.stat (path))
- except:
- return None
-
-import glob
-
-class os_filesystem:
- path_module = os.path
-
- # set this to zero if you want to disable pathname globbing.
- # [we currently don't glob, anyway]
- do_globbing = 1
-
- def __init__ (self, root, wd='/'):
- self.root = root
- self.wd = wd
-
- def current_directory (self):
- return self.wd
-
- def isfile (self, path):
- p = self.normalize (self.path_module.join (self.wd, path))
- return self.path_module.isfile (self.translate(p))
-
- def isdir (self, path):
- p = self.normalize (self.path_module.join (self.wd, path))
- return self.path_module.isdir (self.translate(p))
-
- def cwd (self, path):
- p = self.normalize (self.path_module.join (self.wd, path))
- translated_path = self.translate(p)
- if not self.path_module.isdir (translated_path):
- return 0
- else:
- old_dir = os.getcwd()
- # temporarily change to that directory, in order
- # to see if we have permission to do so.
- try:
- can = 0
- try:
- os.chdir (translated_path)
- can = 1
- self.wd = p
- except:
- pass
- finally:
- if can:
- os.chdir (old_dir)
- return can
-
- def cdup (self):
- return self.cwd ('..')
-
- def listdir (self, path, long=0):
- p = self.translate (path)
- # I think we should glob, but limit it to the current
- # directory only.
- ld = os.listdir (p)
- if not long:
- return list_producer (ld, None)
- else:
- old_dir = os.getcwd()
- try:
- os.chdir (p)
- # if os.stat fails we ignore that file.
- result = filter (None, map (safe_stat, ld))
- finally:
- os.chdir (old_dir)
- return list_producer (result, self.longify)
-
- # TODO: implement a cache w/timeout for stat()
- def stat (self, path):
- p = self.translate (path)
- return os.stat (p)
-
- def open (self, path, mode):
- p = self.translate (path)
- return open (p, mode)
-
- def unlink (self, path):
- p = self.translate (path)
- return os.unlink (p)
-
- def mkdir (self, path):
- p = self.translate (path)
- return os.mkdir (p)
-
- def rmdir (self, path):
- p = self.translate (path)
- return os.rmdir (p)
-
- # utility methods
- def normalize (self, path):
- # watch for the ever-sneaky '/+' path element
- path = re.sub('/+', '/', path)
- p = self.path_module.normpath (path)
- # remove 'dangling' cdup's.
- if len(p) > 2 and p[:3] == '/..':
- p = '/'
- return p
-
- def translate (self, path):
- # we need to join together three separate
- # path components, and do it safely.
- # <real_root>/<current_directory>/<path>
- # use the operating system's path separator.
- path = string.join (string.split (path, '/'), os.sep)
- p = self.normalize (self.path_module.join (self.wd, path))
- p = self.normalize (self.path_module.join (self.root, p[1:]))
- return p
-
- def longify (self, (path, stat_info)):
- return unix_longify (path, stat_info)
-
- def __repr__ (self):
- return '<unix-style fs root:%s wd:%s>' % (
- self.root,
- self.wd
- )
-
-if os.name == 'posix':
-
- class unix_filesystem (os_filesystem):
- pass
-
- class schizophrenic_unix_filesystem (os_filesystem):
- PROCESS_UID = os.getuid()
- PROCESS_EUID = os.geteuid()
- PROCESS_GID = os.getgid()
- PROCESS_EGID = os.getegid()
-
- def __init__ (self, root, wd='/', persona=(None, None)):
- os_filesystem.__init__ (self, root, wd)
- self.persona = persona
-
- def become_persona (self):
- if self.persona is not (None, None):
- uid, gid = self.persona
- # the order of these is important!
- os.setegid (gid)
- os.seteuid (uid)
-
- def become_nobody (self):
- if self.persona is not (None, None):
- os.seteuid (self.PROCESS_UID)
- os.setegid (self.PROCESS_GID)
-
- # cwd, cdup, open, listdir
- def cwd (self, path):
- try:
- self.become_persona()
- return os_filesystem.cwd (self, path)
- finally:
- self.become_nobody()
-
- def cdup (self, path):
- try:
- self.become_persona()
- return os_filesystem.cdup (self)
- finally:
- self.become_nobody()
-
- def open (self, filename, mode):
- try:
- self.become_persona()
- return os_filesystem.open (self, filename, mode)
- finally:
- self.become_nobody()
-
- def listdir (self, path, long=0):
- try:
- self.become_persona()
- return os_filesystem.listdir (self, path, long)
- finally:
- self.become_nobody()
-
-# For the 'real' root, we could obtain a list of drives, and then
-# use that. Doesn't win32 provide such a 'real' filesystem?
-# [yes, I think something like this "\\.\c\windows"]
-
-class msdos_filesystem (os_filesystem):
- def longify (self, (path, stat_info)):
- return msdos_longify (path, stat_info)
-
-# A merged filesystem will let you plug other filesystems together.
-# We really need the equivalent of a 'mount' capability - this seems
-# to be the most general idea. So you'd use a 'mount' method to place
-# another filesystem somewhere in the hierarchy.
-
-# Note: this is most likely how I will handle ~user directories
-# with the http server.
-
-class merged_filesystem:
- def __init__ (self, *fsys):
- pass
-
-# this matches the output of NT's ftp server (when in
-# MSDOS mode) exactly.
-
-def msdos_longify (file, stat_info):
- if stat.S_ISDIR (stat_info[stat.ST_MODE]):
- dir = '<DIR>'
- else:
- dir = ' '
- date = msdos_date (stat_info[stat.ST_MTIME])
- return '%s %s %8d %s' % (
- date,
- dir,
- stat_info[stat.ST_SIZE],
- file
- )
-
-def msdos_date (t):
- try:
- info = time.gmtime (t)
- except:
- info = time.gmtime (0)
- # year, month, day, hour, minute, second, ...
- if info[3] > 11:
- merid = 'PM'
- info[3] = info[3] - 12
- else:
- merid = 'AM'
- return '%02d-%02d-%02d %02d:%02d%s' % (
- info[1],
- info[2],
- info[0]%100,
- info[3],
- info[4],
- merid
- )
-
-months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
- 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
-
-mode_table = {
- '0':'---',
- '1':'--x',
- '2':'-w-',
- '3':'-wx',
- '4':'r--',
- '5':'r-x',
- '6':'rw-',
- '7':'rwx'
- }
-
-import time
-
-def unix_longify (file, stat_info):
- # for now, only pay attention to the lower bits
- mode = ('%o' % stat_info[stat.ST_MODE])[-3:]
- mode = string.join (map (lambda x: mode_table[x], mode), '')
- if stat.S_ISDIR (stat_info[stat.ST_MODE]):
- dirchar = 'd'
- else:
- dirchar = '-'
- date = ls_date (long(time.time()), stat_info[stat.ST_MTIME])
- return '%s%s %3d %-8d %-8d %8d %s %s' % (
- dirchar,
- mode,
- stat_info[stat.ST_NLINK],
- stat_info[stat.ST_UID],
- stat_info[stat.ST_GID],
- stat_info[stat.ST_SIZE],
- date,
- file
- )
-
-# Emulate the unix 'ls' command's date field.
-# it has two formats - if the date is more than 180
-# days in the past, then it's like this:
-# Oct 19 1995
-# otherwise, it looks like this:
-# Oct 19 17:33
-
-def ls_date (now, t):
- try:
- info = time.gmtime (t)
- except:
- info = time.gmtime (0)
- # 15,600,000 == 86,400 * 180
- if (now - t) > 15600000:
- return '%s %2d %d' % (
- months[info[1]-1],
- info[2],
- info[0]
- )
- else:
- return '%s %2d %02d:%02d' % (
- months[info[1]-1],
- info[2],
- info[3],
- info[4]
- )
-
-# ===========================================================================
-# Producers
-# ===========================================================================
-
-class list_producer:
- def __init__ (self, list, func=None):
- self.list = list
- self.func = func
-
- # this should do a pushd/popd
- def more (self):
- if not self.list:
- return ''
- else:
- # do a few at a time
- bunch = self.list[:50]
- if self.func is not None:
- bunch = map (self.func, bunch)
- self.list = self.list[50:]
- return string.joinfields (bunch, '\r\n') + '\r\n'
-
diff --git a/demo/medusa054/ftp_server.py b/demo/medusa054/ftp_server.py
deleted file mode 100644
index 859cd65..0000000
--- a/demo/medusa054/ftp_server.py
+++ /dev/null
@@ -1,1111 +0,0 @@
-# -*- Mode: Python -*-
-
-# Author: Sam Rushing <rushing@nightmare.com>
-# Copyright 1996-2000 by Sam Rushing
-# All Rights Reserved.
-#
-
-# An extensible, configurable, asynchronous FTP server.
-#
-# All socket I/O is non-blocking, however file I/O is currently
-# blocking. Eventually file I/O may be made non-blocking, too, if it
-# seems necessary. Currently the only CPU-intensive operation is
-# getting and formatting a directory listing. [this could be moved
-# into another process/directory server, or another thread?]
-#
-# Only a subset of RFC 959 is implemented, but much of that RFC is
-# vestigial anyway. I've attempted to include the most commonly-used
-# commands, using the feature set of wu-ftpd as a guide.
-
-import asyncore
-import asynchat
-
-import os
-import socket
-import stat
-import string
-import sys
-import time
-
-#from medusa.producers import file_producer
-from producers import file_producer
-
-# TODO: implement a directory listing cache. On very-high-load
-# servers this could save a lot of disk abuse, and possibly the
-# work of computing emulated unix ls output.
-
-# Potential security problem with the FTP protocol? I don't think
-# there's any verification of the origin of a data connection. Not
-# really a problem for the server (since it doesn't send the port
-# command, except when in PASV mode) But I think a data connection
-# could be spoofed by a program with access to a sniffer - it could
-# watch for a PORT command to go over a command channel, and then
-# connect to that port before the server does.
-
-# Unix user id's:
-# In order to support assuming the id of a particular user,
-# it seems there are two options:
-# 1) fork, and seteuid in the child
-# 2) carefully control the effective uid around filesystem accessing
-# methods, using try/finally. [this seems to work]
-
-VERSION = '1.1'
-
-from counter import counter
-import producers
-import status_handler
-import logger
-
-class ftp_channel (asynchat.async_chat):
-
- # defaults for a reliable __repr__
- addr = ('unknown','0')
-
- # unset this in a derived class in order
- # to enable the commands in 'self.write_commands'
- read_only = 1
- write_commands = ['appe','dele','mkd','rmd','rnfr','rnto','stor','stou']
-
- restart_position = 0
-
- # comply with (possibly troublesome) RFC959 requirements
- # This is necessary to correctly run an active data connection
- # through a firewall that triggers on the source port (expected
- # to be 'L-1', or 20 in the normal case).
- bind_local_minus_one = 0
-
- def __init__ (self, server, conn, addr):
- self.server = server
- self.current_mode = 'a'
- self.addr = addr
- asynchat.async_chat.__init__ (self, conn)
- self.set_terminator ('\r\n')
-
- # client data port. Defaults to 'the same as the control connection'.
- self.client_addr = (addr[0], 21)
-
- self.client_dc = None
- self.in_buffer = ''
- self.closing = 0
- self.passive_acceptor = None
- self.passive_connection = None
- self.filesystem = None
- self.authorized = 0
- # send the greeting
- self.respond (
- '220 %s FTP server (Medusa Async V%s [experimental]) ready.' % (
- self.server.hostname,
- VERSION
- )
- )
-
-# def __del__ (self):
-# print 'ftp_channel.__del__()'
-
- # --------------------------------------------------
- # async-library methods
- # --------------------------------------------------
-
- def handle_expt (self):
- # this is handled below. not sure what I could
- # do here to make that code less kludgish.
- pass
-
- def collect_incoming_data (self, data):
- self.in_buffer = self.in_buffer + data
- if len(self.in_buffer) > 4096:
- # silently truncate really long lines
- # (possible denial-of-service attack)
- self.in_buffer = ''
-
- def found_terminator (self):
-
- line = self.in_buffer
-
- if not len(line):
- return
-
- sp = string.find (line, ' ')
- if sp != -1:
- line = [line[:sp], line[sp+1:]]
- else:
- line = [line]
-
- command = string.lower (line[0])
- # watch especially for 'urgent' abort commands.
- if string.find (command, 'abor') != -1:
- # strip off telnet sync chars and the like...
- while command and command[0] not in string.letters:
- command = command[1:]
- fun_name = 'cmd_%s' % command
- if command != 'pass':
- self.log ('<== %s' % repr(self.in_buffer)[1:-1])
- else:
- self.log ('<== %s' % line[0]+' <password>')
- self.in_buffer = ''
- if not hasattr (self, fun_name):
- self.command_not_understood (line[0])
- return
- fun = getattr (self, fun_name)
- if (not self.authorized) and (command not in ('user', 'pass', 'help', 'quit')):
- self.respond ('530 Please log in with USER and PASS')
- elif (not self.check_command_authorization (command)):
- self.command_not_authorized (command)
- else:
- try:
- result = apply (fun, (line,))
- except:
- self.server.total_exceptions.increment()
- (file, fun, line), t,v, tbinfo = asyncore.compact_traceback()
- if self.client_dc:
- try:
- self.client_dc.close()
- except:
- pass
- self.respond (
- '451 Server Error: %s, %s: file: %s line: %s' % (
- t,v,file,line,
- )
- )
-
- closed = 0
- def close (self):
- if not self.closed:
- self.closed = 1
- if self.passive_acceptor:
- self.passive_acceptor.close()
- if self.client_dc:
- self.client_dc.close()
- self.server.closed_sessions.increment()
- asynchat.async_chat.close (self)
-
- # --------------------------------------------------
- # filesystem interface functions.
- # override these to provide access control or perform
- # other functions.
- # --------------------------------------------------
-
- def cwd (self, line):
- return self.filesystem.cwd (line[1])
-
- def cdup (self, line):
- return self.filesystem.cdup()
-
- def open (self, path, mode):
- return self.filesystem.open (path, mode)
-
- # returns a producer
- def listdir (self, path, long=0):
- return self.filesystem.listdir (path, long)
-
- def get_dir_list (self, line, long=0):
- # we need to scan the command line for arguments to '/bin/ls'...
- args = line[1:]
- path_args = []
- for arg in args:
- if arg[0] != '-':
- path_args.append (arg)
- else:
- # ignore arguments
- pass
- if len(path_args) < 1:
- dir = '.'
- else:
- dir = path_args[0]
- return self.listdir (dir, long)
-
- # --------------------------------------------------
- # authorization methods
- # --------------------------------------------------
-
- def check_command_authorization (self, command):
- if command in self.write_commands and self.read_only:
- return 0
- else:
- return 1
-
- # --------------------------------------------------
- # utility methods
- # --------------------------------------------------
-
- def log (self, message):
- self.server.logger.log (
- self.addr[0],
- '%d %s' % (
- self.addr[1], message
- )
- )
-
- def respond (self, resp):
- self.log ('==> %s' % resp)
- self.push (resp + '\r\n')
-
- def command_not_understood (self, command):
- self.respond ("500 '%s': command not understood." % command)
-
- def command_not_authorized (self, command):
- self.respond (
- "530 You are not authorized to perform the '%s' command" % (
- command
- )
- )
-
- def make_xmit_channel (self):
- # In PASV mode, the connection may or may _not_ have been made
- # yet. [although in most cases it is... FTP Explorer being
- # the only exception I've yet seen]. This gets somewhat confusing
- # because things may happen in any order...
- pa = self.passive_acceptor
- if pa:
- if pa.ready:
- # a connection has already been made.
- conn, addr = self.passive_acceptor.ready
- cdc = xmit_channel (self, addr)
- cdc.set_socket (conn)
- cdc.connected = 1
- self.passive_acceptor.close()
- self.passive_acceptor = None
- else:
- # we're still waiting for a connect to the PASV port.
- cdc = xmit_channel (self)
- else:
- # not in PASV mode.
- ip, port = self.client_addr
- cdc = xmit_channel (self, self.client_addr)
- cdc.create_socket (socket.AF_INET, socket.SOCK_STREAM)
- if self.bind_local_minus_one:
- cdc.bind (('', self.server.port - 1))
- try:
- cdc.connect ((ip, port))
- except socket.error, why:
- self.respond ("425 Can't build data connection")
- self.client_dc = cdc
-
- # pretty much the same as xmit, but only right on the verge of
- # being worth a merge.
- def make_recv_channel (self, fd):
- pa = self.passive_acceptor
- if pa:
- if pa.ready:
- # a connection has already been made.
- conn, addr = pa.ready
- cdc = recv_channel (self, addr, fd)
- cdc.set_socket (conn)
- cdc.connected = 1
- self.passive_acceptor.close()
- self.passive_acceptor = None
- else:
- # we're still waiting for a connect to the PASV port.
- cdc = recv_channel (self, None, fd)
- else:
- # not in PASV mode.
- ip, port = self.client_addr
- cdc = recv_channel (self, self.client_addr, fd)
- cdc.create_socket (socket.AF_INET, socket.SOCK_STREAM)
- try:
- cdc.connect ((ip, port))
- except socket.error, why:
- self.respond ("425 Can't build data connection")
- self.client_dc = cdc
-
- type_map = {
- 'a':'ASCII',
- 'i':'Binary',
- 'e':'EBCDIC',
- 'l':'Binary'
- }
-
- type_mode_map = {
- 'a':'t',
- 'i':'b',
- 'e':'b',
- 'l':'b'
- }
-
- # --------------------------------------------------
- # command methods
- # --------------------------------------------------
-
- def cmd_type (self, line):
- 'specify data transfer type'
- # ascii, ebcdic, image, local <byte size>
- t = string.lower (line[1])
- # no support for EBCDIC
- # if t not in ['a','e','i','l']:
- if t not in ['a','i','l']:
- self.command_not_understood (string.join (line))
- elif t == 'l' and (len(line) > 2 and line[2] != '8'):
- self.respond ('504 Byte size must be 8')
- else:
- self.current_mode = t
- self.respond ('200 Type set to %s.' % self.type_map[t])
-
-
- def cmd_quit (self, line):
- 'terminate session'
- self.respond ('221 Goodbye.')
- self.close_when_done()
-
- def cmd_port (self, line):
- 'specify data connection port'
- info = string.split (line[1], ',')
- ip = string.join (info[:4], '.')
- port = string.atoi(info[4])*256 + string.atoi(info[5])
- # how many data connections at a time?
- # I'm assuming one for now...
- # TODO: we should (optionally) verify that the
- # ip number belongs to the client. [wu-ftpd does this?]
- self.client_addr = (ip, port)
- self.respond ('200 PORT command successful.')
-
- def new_passive_acceptor (self):
- # ensure that only one of these exists at a time.
- if self.passive_acceptor is not None:
- self.passive_acceptor.close()
- self.passive_acceptor = None
- self.passive_acceptor = passive_acceptor (self)
- return self.passive_acceptor
-
- def cmd_pasv (self, line):
- 'prepare for server-to-server transfer'
- pc = self.new_passive_acceptor()
- port = pc.addr[1]
- ip_addr = pc.control_channel.getsockname()[0]
- self.respond (
- '227 Entering Passive Mode (%s,%d,%d)' % (
- string.replace(ip_addr, '.', ','),
- port/256,
- port%256
- )
- )
- self.client_dc = None
-
- def cmd_nlst (self, line):
- 'give name list of files in directory'
- # ncftp adds the -FC argument for the user-visible 'nlist'
- # command. We could try to emulate ls flags, but not just yet.
- if '-FC' in line:
- line.remove ('-FC')
- try:
- dir_list_producer = self.get_dir_list (line, 0)
- except os.error, why:
- self.respond ('550 Could not list directory: %s' % why)
- return
- self.respond (
- '150 Opening %s mode data connection for file list' % (
- self.type_map[self.current_mode]
- )
- )
- self.make_xmit_channel()
- self.client_dc.push_with_producer (dir_list_producer)
- self.client_dc.close_when_done()
-
- def cmd_list (self, line):
- 'give a list of files in a directory'
- try:
- dir_list_producer = self.get_dir_list (line, 1)
- except os.error, why:
- self.respond ('550 Could not list directory: %s' % why)
- return
- self.respond (
- '150 Opening %s mode data connection for file list' % (
- self.type_map[self.current_mode]
- )
- )
- self.make_xmit_channel()
- self.client_dc.push_with_producer (dir_list_producer)
- self.client_dc.close_when_done()
-
- def cmd_cwd (self, line):
- 'change working directory'
- if self.cwd (line):
- self.respond ('250 CWD command successful.')
- else:
- self.respond ('550 No such directory.')
-
- def cmd_cdup (self, line):
- 'change to parent of current working directory'
- if self.cdup(line):
- self.respond ('250 CDUP command successful.')
- else:
- self.respond ('550 No such directory.')
-
- def cmd_pwd (self, line):
- 'print the current working directory'
- self.respond (
- '257 "%s" is the current directory.' % (
- self.filesystem.current_directory()
- )
- )
-
- # modification time
- # example output:
- # 213 19960301204320
- def cmd_mdtm (self, line):
- 'show last modification time of file'
- filename = line[1]
- if not self.filesystem.isfile (filename):
- self.respond ('550 "%s" is not a file' % filename)
- else:
- mtime = time.gmtime(self.filesystem.stat(filename)[stat.ST_MTIME])
- self.respond (
- '213 %4d%02d%02d%02d%02d%02d' % (
- mtime[0],
- mtime[1],
- mtime[2],
- mtime[3],
- mtime[4],
- mtime[5]
- )
- )
-
- def cmd_noop (self, line):
- 'do nothing'
- self.respond ('200 NOOP command successful.')
-
- def cmd_size (self, line):
- 'return size of file'
- filename = line[1]
- if not self.filesystem.isfile (filename):
- self.respond ('550 "%s" is not a file' % filename)
- else:
- self.respond (
- '213 %d' % (self.filesystem.stat(filename)[stat.ST_SIZE])
- )
-
- def cmd_retr (self, line):
- 'retrieve a file'
- if len(line) < 2:
- self.command_not_understood (string.join (line))
- else:
- file = line[1]
- if not self.filesystem.isfile (file):
- self.log_info ('checking %s' % file)
- self.respond ('550 No such file')
- else:
- try:
- # FIXME: for some reason, 'rt' isn't working on win95
- mode = 'r'+self.type_mode_map[self.current_mode]
- fd = self.open (file, mode)
- except IOError, why:
- self.respond ('553 could not open file for reading: %s' % (repr(why)))
- return
- self.respond (
- "150 Opening %s mode data connection for file '%s'" % (
- self.type_map[self.current_mode],
- file
- )
- )
- self.make_xmit_channel()
-
- if self.restart_position:
- # try to position the file as requested, but
- # give up silently on failure (the 'file object'
- # may not support seek())
- try:
- fd.seek (self.restart_position)
- except:
- pass
- self.restart_position = 0
-
- self.client_dc.push_with_producer (
- file_producer (fd)
- )
- self.client_dc.close_when_done()
-
- def cmd_stor (self, line, mode='wb'):
- 'store a file'
- if len (line) < 2:
- self.command_not_understood (string.join (line))
- else:
- if self.restart_position:
- restart_position = 0
- self.respond ('553 restart on STOR not yet supported')
- return
- file = line[1]
- # todo: handle that type flag
- try:
- fd = self.open (file, mode)
- except IOError, why:
- self.respond ('553 could not open file for writing: %s' % (repr(why)))
- return
- self.respond (
- '150 Opening %s connection for %s' % (
- self.type_map[self.current_mode],
- file
- )
- )
- self.make_recv_channel (fd)
-
- def cmd_abor (self, line):
- 'abort operation'
- if self.client_dc:
- self.client_dc.close()
- self.respond ('226 ABOR command successful.')
-
- def cmd_appe (self, line):
- 'append to a file'
- return self.cmd_stor (line, 'ab')
-
- def cmd_dele (self, line):
- if len (line) != 2:
- self.command_not_understood (string.join (line))
- else:
- file = line[1]
- if self.filesystem.isfile (file):
- try:
- self.filesystem.unlink (file)
- self.respond ('250 DELE command successful.')
- except:
- self.respond ('550 error deleting file.')
- else:
- self.respond ('550 %s: No such file.' % file)
-
- def cmd_mkd (self, line):
- if len (line) != 2:
- self.command_not_understood (string.join (line))
- else:
- path = line[1]
- try:
- self.filesystem.mkdir (path)
- self.respond ('257 MKD command successful.')
- except:
- self.respond ('550 error creating directory.')
-
- def cmd_rmd (self, line):
- if len (line) != 2:
- self.command_not_understood (string.join (line))
- else:
- path = line[1]
- try:
- self.filesystem.rmdir (path)
- self.respond ('250 RMD command successful.')
- except:
- self.respond ('550 error removing directory.')
-
- def cmd_user (self, line):
- 'specify user name'
- if len(line) > 1:
- self.user = line[1]
- self.respond ('331 Password required.')
- else:
- self.command_not_understood (string.join (line))
-
- def cmd_pass (self, line):
- 'specify password'
- if len(line) < 2:
- pw = ''
- else:
- pw = line[1]
- result, message, fs = self.server.authorizer.authorize (self, self.user, pw)
- if result:
- self.respond ('230 %s' % message)
- self.filesystem = fs
- self.authorized = 1
- self.log_info('Successful login: Filesystem=%s' % repr(fs))
- else:
- self.respond ('530 %s' % message)
-
- def cmd_rest (self, line):
- 'restart incomplete transfer'
- try:
- pos = string.atoi (line[1])
- except ValueError:
- self.command_not_understood (string.join (line))
- self.restart_position = pos
- self.respond (
- '350 Restarting at %d. Send STORE or RETRIEVE to initiate transfer.' % pos
- )
-
- def cmd_stru (self, line):
- 'obsolete - set file transfer structure'
- if line[1] in 'fF':
- # f == 'file'
- self.respond ('200 STRU F Ok')
- else:
- self.respond ('504 Unimplemented STRU type')
-
- def cmd_mode (self, line):
- 'obsolete - set file transfer mode'
- if line[1] in 'sS':
- # f == 'file'
- self.respond ('200 MODE S Ok')
- else:
- self.respond ('502 Unimplemented MODE type')
-
-# The stat command has two personalities. Normally it returns status
-# information about the current connection. But if given an argument,
-# it is equivalent to the LIST command, with the data sent over the
-# control connection. Strange. But wuftpd, ftpd, and nt's ftp server
-# all support it.
-#
-## def cmd_stat (self, line):
-## 'return status of server'
-## pass
-
- def cmd_syst (self, line):
- 'show operating system type of server system'
- # Replying to this command is of questionable utility, because
- # this server does not behave in a predictable way w.r.t. the
- # output of the LIST command. We emulate Unix ls output, but
- # on win32 the pathname can contain drive information at the front
- # Currently, the combination of ensuring that os.sep == '/'
- # and removing the leading slash when necessary seems to work.
- # [cd'ing to another drive also works]
- #
- # This is how wuftpd responds, and is probably
- # the most expected. The main purpose of this reply is so that
- # the client knows to expect Unix ls-style LIST output.
- self.respond ('215 UNIX Type: L8')
- # one disadvantage to this is that some client programs
- # assume they can pass args to /bin/ls.
- # a few typical responses:
- # 215 UNIX Type: L8 (wuftpd)
- # 215 Windows_NT version 3.51
- # 215 VMS MultiNet V3.3
- # 500 'SYST': command not understood. (SVR4)
-
- def cmd_help (self, line):
- 'give help information'
- # find all the methods that match 'cmd_xxxx',
- # use their docstrings for the help response.
- attrs = dir(self.__class__)
- help_lines = []
- for attr in attrs:
- if attr[:4] == 'cmd_':
- x = getattr (self, attr)
- if type(x) == type(self.cmd_help):
- if x.__doc__:
- help_lines.append ('\t%s\t%s' % (attr[4:], x.__doc__))
- if help_lines:
- self.push ('214-The following commands are recognized\r\n')
- self.push_with_producer (producers.lines_producer (help_lines))
- self.push ('214\r\n')
- else:
- self.push ('214-\r\n\tHelp Unavailable\r\n214\r\n')
-
-class ftp_server (asyncore.dispatcher):
- # override this to spawn a different FTP channel class.
- ftp_channel_class = ftp_channel
-
- SERVER_IDENT = 'FTP Server (V%s)' % VERSION
-
- def __init__ (
- self,
- authorizer,
- hostname =None,
- ip ='',
- port =21,
- resolver =None,
- logger_object=logger.file_logger (sys.stdout)
- ):
- self.ip = ip
- self.port = port
- self.authorizer = authorizer
-
- if hostname is None:
- self.hostname = socket.gethostname()
- else:
- self.hostname = hostname
-
- # statistics
- self.total_sessions = counter()
- self.closed_sessions = counter()
- self.total_files_out = counter()
- self.total_files_in = counter()
- self.total_bytes_out = counter()
- self.total_bytes_in = counter()
- self.total_exceptions = counter()
- #
- asyncore.dispatcher.__init__ (self)
- self.create_socket (socket.AF_INET, socket.SOCK_STREAM)
-
- self.set_reuse_addr()
- self.bind ((self.ip, self.port))
- self.listen (5)
-
- if not logger_object:
- logger_object = sys.stdout
-
- if resolver:
- self.logger = logger.resolving_logger (resolver, logger_object)
- else:
- self.logger = logger.unresolving_logger (logger_object)
-
- self.log_info('FTP server started at %s\n\tAuthorizer:%s\n\tHostname: %s\n\tPort: %d' % (
- time.ctime(time.time()),
- repr (self.authorizer),
- self.hostname,
- self.port)
- )
-
- def writable (self):
- return 0
-
- def handle_read (self):
- pass
-
- def handle_connect (self):
- pass
-
- def handle_accept (self):
- conn, addr = self.accept()
- self.total_sessions.increment()
- self.log_info('Incoming connection from %s:%d' % (addr[0], addr[1]))
- self.ftp_channel_class (self, conn, addr)
-
- # return a producer describing the state of the server
- def status (self):
-
- def nice_bytes (n):
- return string.join (status_handler.english_bytes (n))
-
- return producers.lines_producer (
- ['<h2>%s</h2>' % self.SERVER_IDENT,
- '<br>Listening on <b>Host:</b> %s' % self.hostname,
- '<b>Port:</b> %d' % self.port,
- '<br>Sessions',
- '<b>Total:</b> %s' % self.total_sessions,
- '<b>Current:</b> %d' % (self.total_sessions.as_long() - self.closed_sessions.as_long()),
- '<br>Files',
- '<b>Sent:</b> %s' % self.total_files_out,
- '<b>Received:</b> %s' % self.total_files_in,
- '<br>Bytes',
- '<b>Sent:</b> %s' % nice_bytes (self.total_bytes_out.as_long()),
- '<b>Received:</b> %s' % nice_bytes (self.total_bytes_in.as_long()),
- '<br>Exceptions: %s' % self.total_exceptions,
- ]
- )
-
-# ======================================================================
-# Data Channel Classes
-# ======================================================================
-
-# This socket accepts a data connection, used when the server has been
-# placed in passive mode. Although the RFC implies that we ought to
-# be able to use the same acceptor over and over again, this presents
-# a problem: how do we shut it off, so that we are accepting
-# connections only when we expect them? [we can't]
-#
-# wuftpd, and probably all the other servers, solve this by allowing
-# only one connection to hit this acceptor. They then close it. Any
-# subsequent data-connection command will then try for the default
-# port on the client side [which is of course never there]. So the
-# 'always-send-PORT/PASV' behavior seems required.
-#
-# Another note: wuftpd will also be listening on the channel as soon
-# as the PASV command is sent. It does not wait for a data command
-# first.
-
-# --- we need to queue up a particular behavior:
-# 1) xmit : queue up producer[s]
-# 2) recv : the file object
-#
-# It would be nice if we could make both channels the same. Hmmm..
-#
-
-class passive_acceptor (asyncore.dispatcher):
- ready = None
-
- def __init__ (self, control_channel):
- # connect_fun (conn, addr)
- asyncore.dispatcher.__init__ (self)
- self.control_channel = control_channel
- self.create_socket (socket.AF_INET, socket.SOCK_STREAM)
- # bind to an address on the interface that the
- # control connection is coming from.
- self.bind ((
- self.control_channel.getsockname()[0],
- 0
- ))
- self.addr = self.getsockname()
- self.listen (1)
-
-# def __del__ (self):
-# print 'passive_acceptor.__del__()'
-
- def log (self, *ignore):
- pass
-
- def handle_accept (self):
- conn, addr = self.accept()
- dc = self.control_channel.client_dc
- if dc is not None:
- dc.set_socket (conn)
- dc.addr = addr
- dc.connected = 1
- self.control_channel.passive_acceptor = None
- else:
- self.ready = conn, addr
- self.close()
-
-
-class xmit_channel (asynchat.async_chat):
-
- # for an ethernet, you want this to be fairly large, in fact, it
- # _must_ be large for performance comparable to an ftpd. [64k] we
- # ought to investigate automatically-sized buffers...
-
- ac_out_buffer_size = 16384
- bytes_out = 0
-
- def __init__ (self, channel, client_addr=None):
- self.channel = channel
- self.client_addr = client_addr
- asynchat.async_chat.__init__ (self)
-
-# def __del__ (self):
-# print 'xmit_channel.__del__()'
-
- def log (self, *args):
- pass
-
- def readable (self):
- return not self.connected
-
- def writable (self):
- return 1
-
- def send (self, data):
- result = asynchat.async_chat.send (self, data)
- self.bytes_out = self.bytes_out + result
- return result
-
- def handle_error (self):
- # usually this is to catch an unexpected disconnect.
- self.log_info ('unexpected disconnect on data xmit channel', 'error')
- try:
- self.close()
- except:
- pass
-
- # TODO: there's a better way to do this. we need to be able to
- # put 'events' in the producer fifo. to do this cleanly we need
- # to reposition the 'producer' fifo as an 'event' fifo.
-
- def close (self):
- c = self.channel
- s = c.server
- c.client_dc = None
- s.total_files_out.increment()
- s.total_bytes_out.increment (self.bytes_out)
- if not len(self.producer_fifo):
- c.respond ('226 Transfer complete')
- elif not c.closed:
- c.respond ('426 Connection closed; transfer aborted')
- del c
- del s
- del self.channel
- asynchat.async_chat.close (self)
-
-class recv_channel (asyncore.dispatcher):
- def __init__ (self, channel, client_addr, fd):
- self.channel = channel
- self.client_addr = client_addr
- self.fd = fd
- asyncore.dispatcher.__init__ (self)
- self.bytes_in = counter()
-
- def log (self, *ignore):
- pass
-
- def handle_connect (self):
- pass
-
- def writable (self):
- return 0
-
- def recv (*args):
- result = apply (asyncore.dispatcher.recv, args)
- self = args[0]
- self.bytes_in.increment(len(result))
- return result
-
- buffer_size = 8192
-
- def handle_read (self):
- block = self.recv (self.buffer_size)
- if block:
- try:
- self.fd.write (block)
- except IOError:
- self.log_info ('got exception writing block...', 'error')
-
- def handle_close (self):
- s = self.channel.server
- s.total_files_in.increment()
- s.total_bytes_in.increment(self.bytes_in.as_long())
- self.fd.close()
- self.channel.respond ('226 Transfer complete.')
- self.close()
-
-import filesys
-
-# not much of a doorman! 8^)
-class dummy_authorizer:
- def __init__ (self, root='/'):
- self.root = root
- def authorize (self, channel, username, password):
- channel.persona = -1, -1
- channel.read_only = 1
- return 1, 'Ok.', filesys.os_filesystem (self.root)
-
-class anon_authorizer:
- def __init__ (self, root='/'):
- self.root = root
-
- def authorize (self, channel, username, password):
- if username in ('ftp', 'anonymous'):
- channel.persona = -1, -1
- channel.read_only = 1
- return 1, 'Ok.', filesys.os_filesystem (self.root)
- else:
- return 0, 'Password invalid.', None
-
-# ===========================================================================
-# Unix-specific improvements
-# ===========================================================================
-
-if os.name == 'posix':
-
- class unix_authorizer:
- # return a trio of (success, reply_string, filesystem)
- def authorize (self, channel, username, password):
- import crypt
- import pwd
- try:
- info = pwd.getpwnam (username)
- except KeyError:
- return 0, 'No such user.', None
- mangled = info[1]
- if crypt.crypt (password, mangled[:2]) == mangled:
- channel.read_only = 0
- fs = filesys.schizophrenic_unix_filesystem (
- '/',
- info[5],
- persona = (info[2], info[3])
- )
- return 1, 'Login successful.', fs
- else:
- return 0, 'Password invalid.', None
-
- def __repr__ (self):
- return '<standard unix authorizer>'
-
- # simple anonymous ftp support
- class unix_authorizer_with_anonymous (unix_authorizer):
- def __init__ (self, root=None, real_users=0):
- self.root = root
- self.real_users = real_users
-
- def authorize (self, channel, username, password):
- if string.lower(username) in ['anonymous', 'ftp']:
- import pwd
- try:
- # ok, here we run into lots of confusion.
- # on some os', anon runs under user 'nobody',
- # on others as 'ftp'. ownership is also critical.
- # need to investigate.
- # linux: new linuxen seem to have nobody's UID=-1,
- # which is an illegal value. Use ftp.
- ftp_user_info = pwd.getpwnam ('ftp')
- if string.lower(os.uname()[0]) == 'linux':
- nobody_user_info = pwd.getpwnam ('ftp')
- else:
- nobody_user_info = pwd.getpwnam ('nobody')
- channel.read_only = 1
- if self.root is None:
- self.root = ftp_user_info[5]
- fs = filesys.unix_filesystem (self.root, '/')
- return 1, 'Anonymous Login Successful', fs
- except KeyError:
- return 0, 'Anonymous account not set up', None
- elif self.real_users:
- return unix_authorizer.authorize (
- self,
- channel,
- username,
- password
- )
- else:
- return 0, 'User logins not allowed', None
-
-# usage: ftp_server /PATH/TO/FTP/ROOT PORT
-# for example:
-# $ ftp_server /home/users/ftp 8021
-
-if os.name == 'posix':
- def test (port='8021'):
- fs = ftp_server (
- unix_authorizer(),
- port=string.atoi (port)
- )
- try:
- asyncore.loop()
- except KeyboardInterrupt:
- fs.log_info('FTP server shutting down. (received SIGINT)', 'warning')
- # close everything down on SIGINT.
- # of course this should be a cleaner shutdown.
- asyncore.close_all()
-
- if __name__ == '__main__':
- test (sys.argv[1])
-# not unix
-else:
- def test ():
- fs = ftp_server (dummy_authorizer())
- if __name__ == '__main__':
- test ()
-
-# this is the command list from the wuftpd man page
-# '*' means we've implemented it.
-# '!' requires write access
-#
-command_documentation = {
- 'abor': 'abort previous command', #*
- 'acct': 'specify account (ignored)',
- 'allo': 'allocate storage (vacuously)',
- 'appe': 'append to a file', #*!
- 'cdup': 'change to parent of current working directory', #*
- 'cwd': 'change working directory', #*
- 'dele': 'delete a file', #!
- 'help': 'give help information', #*
- 'list': 'give list files in a directory', #*
- 'mkd': 'make a directory', #!
- 'mdtm': 'show last modification time of file', #*
- 'mode': 'specify data transfer mode',
- 'nlst': 'give name list of files in directory', #*
- 'noop': 'do nothing', #*
- 'pass': 'specify password', #*
- 'pasv': 'prepare for server-to-server transfer', #*
- 'port': 'specify data connection port', #*
- 'pwd': 'print the current working directory', #*
- 'quit': 'terminate session', #*
- 'rest': 'restart incomplete transfer', #*
- 'retr': 'retrieve a file', #*
- 'rmd': 'remove a directory', #!
- 'rnfr': 'specify rename-from file name', #!
- 'rnto': 'specify rename-to file name', #!
- 'site': 'non-standard commands (see next section)',
- 'size': 'return size of file', #*
- 'stat': 'return status of server', #*
- 'stor': 'store a file', #*!
- 'stou': 'store a file with a unique name', #!
- 'stru': 'specify data transfer structure',
- 'syst': 'show operating system type of server system', #*
- 'type': 'specify data transfer type', #*
- 'user': 'specify user name', #*
- 'xcup': 'change to parent of current working directory (deprecated)',
- 'xcwd': 'change working directory (deprecated)',
- 'xmkd': 'make a directory (deprecated)', #!
- 'xpwd': 'print the current working directory (deprecated)',
- 'xrmd': 'remove a directory (deprecated)', #!
-}
-
-
-# debugging aid (linux)
-def get_vm_size ():
- return string.atoi (string.split(open ('/proc/self/stat').readline())[22])
-
-def print_vm():
- print 'vm: %8dk' % (get_vm_size()/1024)
diff --git a/demo/medusa054/ftps_server.py b/demo/medusa054/ftps_server.py
deleted file mode 100644
index bf2f5a9..0000000
--- a/demo/medusa054/ftps_server.py
+++ /dev/null
@@ -1,438 +0,0 @@
-"""An FTP/TLS server built on Medusa's ftp_server.
-
-Copyright (c) 1999-2004 Ng Pheng Siong. All rights reserved."""
-
-# Python
-import socket, string, sys, time
-
-# Medusa
-from counter import counter
-import asynchat, asyncore, ftp_server, logger
-
-# M2Crypto
-from M2Crypto import SSL, version
-
-VERSION_STRING=version
-
-class ftp_tls_channel(ftp_server.ftp_channel):
-
- """FTP/TLS server channel for Medusa."""
-
- def __init__(self, server, ssl_ctx, conn, addr):
- """Initialise the channel."""
- self.ssl_ctx = ssl_ctx
- self.server = server
- self.current_mode = 'a'
- self.addr = addr
- asynchat.async_chat.__init__(self, conn)
- self.set_terminator('\r\n')
- self.client_addr = (addr[0], 21)
- self.client_dc = None
- self.in_buffer = ''
- self.closing = 0
- self.passive_acceptor = None
- self.passive_connection = None
- self.filesystem = None
- self.authorized = 0
- self._ssl_accepting = 0
- self._ssl_accepted = 0
- self._pbsz = None
- self._prot = None
- resp = '220 %s M2Crypto (Medusa) FTP/TLS server v%s ready.'
- self.respond(resp % (self.server.hostname, VERSION_STRING))
-
- def writable(self):
- return self._ssl_accepting or self._ssl_accepted
-
- def handle_read(self):
- """Handle a read event."""
- if self._ssl_accepting:
- self._ssl_accepted = self.socket.accept_ssl()
- if self._ssl_accepted:
- self._ssl_accepting = 0
- else:
- try:
- ftp_server.ftp_channel.handle_read(self)
- except SSL.SSLError, what:
- if str(what) == 'unexpected eof':
- self.close()
- else:
- raise
-
- def handle_write(self):
- """Handle a write event."""
- if self._ssl_accepting:
- self._ssl_accepted = self.socket.accept_ssl()
- if self._ssl_accepted:
- self._ssl_accepting = 0
- else:
- try:
- ftp_server.ftp_channel.handle_write(self)
- except SSL.SSLError, what:
- if str(what) == 'unexpected eof':
- self.close()
- else:
- raise
-
- def send(self, data):
- """Send data over SSL."""
- try:
- result = self.socket.send(data)
- if result <= 0:
- return 0
- else:
- return result
- except SSL.SSLError, what:
- self.close()
- self.log_info('send: closing channel %s %s' % (repr(self), what))
- return 0
-
- def recv(self, buffer_size):
- """Receive data over SSL."""
- try:
- result = self.socket.recv(buffer_size)
- if not result:
- return ''
- else:
- return result
- except SSL.SSLError, what:
- self.close()
- self.log_info('recv: closing channel %s %s' % (repr(self), what))
- return ''
-
- def found_terminator(self):
- """Dispatch the FTP command."""
- line = self.in_buffer
- if not len(line):
- return
-
- sp = string.find(line, ' ')
- if sp != -1:
- line = [line[:sp], line[sp+1:]]
- else:
- line = [line]
-
- command = string.lower(line[0])
- if string.find(command, 'stor') != -1:
- while command and command[0] not in string.letters:
- command = command[1:]
-
- func_name = 'cmd_%s' % command
- if command != 'pass':
- self.log('<== %s' % repr(self.in_buffer)[1:-1])
- else:
- self.log('<== %s' % line[0]+' <password>')
-
- self.in_buffer = ''
- if not hasattr(self, func_name):
- self.command_not_understood(line[0])
- return
-
- func = getattr(self, func_name)
- if not self.check_command_authorization(command):
- self.command_not_authorized(command)
- else:
- try:
- result = apply(func, (line,))
- except:
- self.server.total_exceptions.increment()
- (file, func, line), t, v, tbinfo = asyncore.compact_traceback()
- if self.client_dc:
- try:
- self.client_dc_close()
- except:
- pass
- resp = '451 Server error: %s, %s: file %s line: %s'
- self.respond(resp % (t, v, file, line))
-
- def make_xmit_channel(self):
- """Create a connection for sending data."""
- pa = self.passive_acceptor
- if pa:
- if pa.ready:
- conn, addr = pa.ready
- if self._prot:
- cdc = tls_xmit_channel(self, conn, self.ssl_ctx, addr)
- else:
- cdc = ftp_server.xmit_channel(self, addr)
- cdc.set_socket(conn)
- cdc.connected = 1
- self.passive_acceptor.close()
- self.passive_acceptor = None
- else:
- if self._prot:
- cdc = tls_xmit_channel(self, None, self.ssl_ctx, None)
- else:
- cdc = ftp_server.xmit_channel(self)
- else:
- if self._prot:
- cdc = tls_xmit_channel(self, None, self.ssl_ctx, self.client_addr)
- else:
- cdc = ftp_server.xmit_channel(self, self.client_addr)
- cdc.create_socket(socket.AF_INET, socket.SOCK_STREAM)
- if self.bind_local_minus_one:
- cdc.bind(('', self.server.port - 1))
- try:
- cdc.connect(self.client_addr)
- except socket.error, what:
- self.respond('425 Cannot build data connection')
- self.client_dc = cdc
-
- def make_recv_channel(self, fd):
- """Create a connection for receiving data."""
- pa = self.passive_acceptor
- if pa:
- if pa.ready:
- conn, addr = pa.ready
- if self._prot:
- cdc = tls_recv_channel(self, conn, self.ssl_ctx, addr, fd)
- else:
- cdc = ftp_server.recv_channel(self, addr, fd)
- cdc.set_socket(conn)
- cdc.connected = 1
- self.passive_acceptor.close()
- self.passive_acceptor = None
- else:
- if self._prot:
- cdc = tls_recv_channel(self, None, self.ssl_ctx, None, fd)
- else:
- cdc = ftp_server.recv_channel(self, None, fd)
- else:
- if self._prot:
- cdc = tls_recv_channel(self, None, self.ssl_ctx, self._prot, self.client_addr, fd)
- else:
- cdc = ftp_server.recv_channel(self, self.client_addr, fd)
- cdc.create_socket(socket.AF_INET, socket.SOCK_STREAM)
- try:
- cdc.connect(self.client_addr)
- except socket.error, what:
- self.respond('425 Cannot build data connection')
- self.client_dc = cdc
-
- def cmd_auth(self, line):
- """Prepare for TLS operation."""
- # XXX Handle variations.
- if line[1] != 'TLS':
- self.command_not_understood (string.join(line))
- else:
- self.respond('234 AUTH TLS successful')
- self._ssl_accepting = 1
- self.socket = SSL.Connection(self.ssl_ctx, self.socket)
- self.socket.setup_addr(self.addr)
- self.socket.setup_ssl()
- self.socket.set_accept_state()
- self._ssl_accepted = self.socket.accept_ssl()
- if self._ssl_accepted:
- self._ssl_accepting = 0
-
- def cmd_pbsz(self, line):
- """Negotiate size of buffer for secure data transfer. For
- FTP/TLS the only valid value for the parameter is '0'; any
- other value is accepted but ignored."""
- if not (self._ssl_accepting or self._ssl_accepted):
- return self.respond('503 AUTH TLS must be issued prior to PBSZ')
- self._pbsz = 1
- self.respond('200 PBSZ=0 successful.')
-
- def cmd_prot(self, line):
- """Negotiate the security level of the data connection."""
- if self._pbsz is None:
- return self.respond('503 PBSZ must be issued prior to PROT')
- if line[1] == 'C':
- self.respond('200 Protection set to Clear')
- self._pbsz = None
- self._prot = None
- elif line[1] == 'P':
- self.respond('200 Protection set to Private')
- self._prot = 1
- elif line[1] in ('S', 'E'):
- self.respond('536 PROT %s unsupported' % line[1])
- else:
- self.respond('504 PROT %s unsupported' % line[1])
-
-
-class ftp_tls_server(ftp_server.ftp_server):
-
- """FTP/TLS server for Medusa."""
-
- SERVER_IDENT = 'M2Crypto FTP/TLS Server (v%s)' % VERSION_STRING
-
- ftp_channel_class = ftp_tls_channel
-
- def __init__(self, authz, ssl_ctx, host=None, ip='', port=21, resolver=None, log_obj=None):
- """Initialise the server."""
- self.ssl_ctx = ssl_ctx
- self.ip = ip
- self.port = port
- self.authorizer = authz
-
- if host is None:
- self.hostname = socket.gethostname()
- else:
- self.hostname = host
-
- self.total_sessions = counter()
- self.closed_sessions = counter()
- self.total_files_out = counter()
- self.total_files_in = counter()
- self.total_bytes_out = counter()
- self.total_bytes_in = counter()
- self.total_exceptions = counter()
-
- asyncore.dispatcher.__init__(self)
- self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
- self.set_reuse_addr()
- self.bind((self.ip, self.port))
- self.listen(5)
-
- if log_obj is None:
- log_obj = sys.stdout
-
- if resolver:
- self.logger = logger.resolving_logger(resolver, log_obj)
- else:
- self.logger = logger.unresolving_logger(logger.file_logger(sys.stdout))
-
- l = 'M2Crypto (Medusa) FTP/TLS server started at %s\n\tAuthz: %s\n\tHostname: %s\n\tPort: %d'
- self.log_info(l % (time.ctime(time.time()), repr(self.authorizer), self.hostname, self.port))
-
- def handle_accept(self):
- """Accept a socket and dispatch a channel to handle it."""
- conn, addr = self.accept()
- self.total_sessions.increment()
- self.log_info('Connection from %s:%d' % addr)
- self.ftp_channel_class(self, self.ssl_ctx, conn, addr)
-
-
-class nbio_ftp_tls_actor:
-
- """TLS protocol negotiation mixin for FTP/TLS."""
-
- def tls_init(self, sock, ssl_ctx, client_addr):
- """Perform TLS protocol negotiation."""
- self.ssl_ctx = ssl_ctx
- self.client_addr = client_addr
- self._ssl_handshaking = 1
- self._ssl_handshake_ok = 0
- if sock:
- self.socket = SSL.Connection(self.ssl_ctx, sock)
- self.socket.setup_addr(self.client_addr)
- self.socket.setup_ssl()
- self._ssl_handshake_ok = self.socket.accept_ssl()
- if self._ssl_handshake_ok:
- self._ssl_handshaking = 0
- self.add_channel()
- # else the client hasn't connected yet; when that happens,
- # handle_connect() will be triggered.
-
- def tls_neg_ok(self):
- """Return status of TLS protocol negotiation."""
- if self._ssl_handshaking:
- self._ssl_handshake_ok = self.socket.accept_ssl()
- if self._ssl_handshake_ok:
- self._ssl_handshaking = 0
- return self._ssl_handshake_ok
-
- def handle_connect(self):
- """Handle a data connection that occurs after this instance came
- into being. When this handler is triggered, self.socket has been
- created and refers to the underlying connected socket."""
- self.socket = SSL.Connection(self.ssl_ctx, self.socket)
- self.socket.setup_addr(self.client_addr)
- self.socket.setup_ssl()
- self._ssl_handshake_ok = self.socket.accept_ssl()
- if self._ssl_handshake_ok:
- self._ssl_handshaking = 0
- self.add_channel()
-
- def send(self, data):
- """Send data over SSL."""
- try:
- result = self.socket.send(data)
- if result <= 0:
- return 0
- else:
- return result
- except SSL.SSLError, what:
- self.close()
- self.log_info('send: closing channel %s %s' % (repr(self), what))
- return 0
-
- def recv(self, buffer_size):
- """Receive data over SSL."""
- try:
- result = self.socket.recv(buffer_size)
- if not result:
- return ''
- else:
- return result
- except SSL.SSLError, what:
- self.close()
- self.log_info('recv: closing channel %s %s' % (repr(self), what))
- return ''
-
-
-class tls_xmit_channel(nbio_ftp_tls_actor, ftp_server.xmit_channel):
-
- """TLS driver for a send-only data connection."""
-
- def __init__(self, channel, conn, ssl_ctx, client_addr=None):
- """Initialise the driver."""
- ftp_server.xmit_channel.__init__(self, channel, client_addr)
- self.tls_init(conn, ssl_ctx, client_addr)
-
- def readable(self):
- """This channel is readable iff TLS negotiation is in progress.
- (Which implies a connected channel, of course.)"""
- if not self.connected:
- return 0
- else:
- return self._ssl_handshaking
-
- def writable(self):
- """This channel is writable iff TLS negotiation is in progress
- or the application has data to send."""
- if self._ssl_handshaking:
- return 1
- else:
- return ftp_server.xmit_channel.writable(self)
-
- def handle_read(self):
- """Handle a read event: either continue with TLS negotiation
- or let the application handle this event."""
- if self.tls_neg_ok():
- ftp_server.xmit_channel.handle_read(self)
-
- def handle_write(self):
- """Handle a write event: either continue with TLS negotiation
- or let the application handle this event."""
- if self.tls_neg_ok():
- ftp_server.xmit_channel.handle_write(self)
-
-
-class tls_recv_channel(nbio_ftp_tls_actor, ftp_server.recv_channel):
-
- """TLS driver for a receive-only data connection."""
-
- def __init__(self, channel, conn, ssl_ctx, client_addr, fd):
- """Initialise the driver."""
- ftp_server.recv_channel.__init__(self, channel, client_addr, fd)
- self.tls_init(conn, ssl_ctx, client_addr)
-
- def writable(self):
- """This channel is writable iff TLS negotiation is in progress."""
- return self._ssl_handshaking
-
- def handle_read(self):
- """Handle a read event: either continue with TLS negotiation
- or let the application handle this event."""
- if self.tls_neg_ok():
- ftp_server.recv_channel.handle_read(self)
-
- def handle_write(self):
- """Handle a write event: either continue with TLS negotiation
- or let the application handle this event."""
- if self.tls_neg_ok():
- ftp_server.recv_channel.handle_write(self)
-
-
diff --git a/demo/medusa054/http_date.py b/demo/medusa054/http_date.py
deleted file mode 100644
index d2f90b8..0000000
--- a/demo/medusa054/http_date.py
+++ /dev/null
@@ -1,126 +0,0 @@
-# -*- Mode: Python -*-
-
-import re
-import string
-import time
-
-def concat (*args):
- return ''.join (args)
-
-def join (seq, field=' '):
- return field.join (seq)
-
-def group (s):
- return '(' + s + ')'
-
-short_days = ['sun','mon','tue','wed','thu','fri','sat']
-long_days = ['sunday','monday','tuesday','wednesday','thursday','friday','saturday']
-
-short_day_reg = group (join (short_days, '|'))
-long_day_reg = group (join (long_days, '|'))
-
-daymap = {}
-for i in range(7):
- daymap[short_days[i]] = i
- daymap[long_days[i]] = i
-
-hms_reg = join (3 * [group('[0-9][0-9]')], ':')
-
-months = ['jan','feb','mar','apr','may','jun','jul','aug','sep','oct','nov','dec']
-
-monmap = {}
-for i in range(12):
- monmap[months[i]] = i+1
-
-months_reg = group (join (months, '|'))
-
-# From draft-ietf-http-v11-spec-07.txt/3.3.1
-# Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123
-# Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036
-# Sun Nov 6 08:49:37 1994 ; ANSI C's asctime() format
-
-# rfc822 format
-rfc822_date = join (
- [concat (short_day_reg,','), # day
- group('[0-9][0-9]?'), # date
- months_reg, # month
- group('[0-9]+'), # year
- hms_reg, # hour minute second
- 'gmt'
- ],
- ' '
- )
-
-rfc822_reg = re.compile (rfc822_date)
-
-def unpack_rfc822 (m):
- g = m.group
- a = string.atoi
- return (
- a(g(4)), # year
- monmap[g(3)], # month
- a(g(2)), # day
- a(g(5)), # hour
- a(g(6)), # minute
- a(g(7)), # second
- 0,
- 0,
- 0
- )
-
-# rfc850 format
-rfc850_date = join (
- [concat (long_day_reg,','),
- join (
- [group ('[0-9][0-9]?'),
- months_reg,
- group ('[0-9]+')
- ],
- '-'
- ),
- hms_reg,
- 'gmt'
- ],
- ' '
- )
-
-rfc850_reg = re.compile (rfc850_date)
-# they actually unpack the same way
-def unpack_rfc850 (m):
- g = m.group
- a = string.atoi
- return (
- a(g(4)), # year
- monmap[g(3)], # month
- a(g(2)), # day
- a(g(5)), # hour
- a(g(6)), # minute
- a(g(7)), # second
- 0,
- 0,
- 0
- )
-
-# parsdate.parsedate - ~700/sec.
-# parse_http_date - ~1333/sec.
-
-def build_http_date (when):
- return time.strftime ('%a, %d %b %Y %H:%M:%S GMT', time.gmtime(when))
-
-def parse_http_date (d):
- d = string.lower (d)
- tz = time.timezone
- m = rfc850_reg.match (d)
- if m and m.end() == len(d):
- retval = int (time.mktime (unpack_rfc850(m)) - tz)
- else:
- m = rfc822_reg.match (d)
- if m and m.end() == len(d):
- retval = int (time.mktime (unpack_rfc822(m)) - tz)
- else:
- return 0
- # Thanks to Craig Silverstein <csilvers@google.com> for pointing
- # out the DST discrepancy
- if time.daylight and time.localtime(retval)[-1] == 1: # DST correction
- retval = retval + (tz - time.altzone)
- return retval
diff --git a/demo/medusa054/http_server.py b/demo/medusa054/http_server.py
deleted file mode 100644
index 8502add..0000000
--- a/demo/medusa054/http_server.py
+++ /dev/null
@@ -1,749 +0,0 @@
-#! /usr/local/bin/python
-# -*- Mode: Python -*-
-#
-# Author: Sam Rushing <rushing@nightmare.com>
-# Copyright 1996-2000 by Sam Rushing
-# All Rights Reserved.
-#
-
-# python modules
-import os
-import re
-import socket
-import string
-import sys
-import time
-
-# async modules
-import asyncore
-import asynchat
-
-# medusa modules
-import http_date
-import producers
-import status_handler
-import logger
-
-VERSION_STRING = '1.1'
-
-from counter import counter
-from urllib import unquote, splitquery
-
-# ===========================================================================
-# Request Object
-# ===========================================================================
-
-class http_request:
-
- # default reply code
- reply_code = 200
-
- request_counter = counter()
-
- # Whether to automatically use chunked encoding when
- #
- # HTTP version is 1.1
- # Content-Length is not set
- # Chunked encoding is not already in effect
- #
- # If your clients are having trouble, you might want to disable this.
- use_chunked = 1
-
- # by default, this request object ignores user data.
- collector = None
-
- def __init__ (self, *args):
- # unpack information about the request
- (self.channel, self.request,
- self.command, self.uri, self.version,
- self.header) = args
-
- self.outgoing = []
- self.reply_headers = {
- 'Server' : 'Medusa/%s' % VERSION_STRING,
- 'Date' : http_date.build_http_date (time.time())
- }
- self.request_number = http_request.request_counter.increment()
- self._split_uri = None
- self._header_cache = {}
-
- # --------------------------------------------------
- # reply header management
- # --------------------------------------------------
- def __setitem__ (self, key, value):
- self.reply_headers[key] = value
-
- def __getitem__ (self, key):
- return self.reply_headers[key]
-
- def has_key (self, key):
- return self.reply_headers.has_key (key)
-
- def build_reply_header (self):
- return string.join (
- [self.response(self.reply_code)] + map (
- lambda x: '%s: %s' % x,
- self.reply_headers.items()
- ),
- '\r\n'
- ) + '\r\n\r\n'
-
- # --------------------------------------------------
- # split a uri
- # --------------------------------------------------
-
- # <path>;<params>?<query>#<fragment>
- path_regex = re.compile (
- # path params query fragment
- r'([^;?#]*)(;[^?#]*)?(\?[^#]*)?(#.*)?'
- )
-
- def split_uri (self):
- if self._split_uri is None:
- m = self.path_regex.match (self.uri)
- if m.end() != len(self.uri):
- raise ValueError, "Broken URI"
- else:
- self._split_uri = m.groups()
- return self._split_uri
-
- def get_header_with_regex (self, head_reg, group):
- for line in self.header:
- m = head_reg.match (line)
- if m.end() == len(line):
- return m.group (group)
- return ''
-
- def get_header (self, header):
- header = string.lower (header)
- hc = self._header_cache
- if not hc.has_key (header):
- h = header + ': '
- hl = len(h)
- for line in self.header:
- if string.lower (line[:hl]) == h:
- r = line[hl:]
- hc[header] = r
- return r
- hc[header] = None
- return None
- else:
- return hc[header]
-
- # --------------------------------------------------
- # user data
- # --------------------------------------------------
-
- def collect_incoming_data (self, data):
- if self.collector:
- self.collector.collect_incoming_data (data)
- else:
- self.log_info(
- 'Dropping %d bytes of incoming request data' % len(data),
- 'warning'
- )
-
- def found_terminator (self):
- if self.collector:
- self.collector.found_terminator()
- else:
- self.log_info (
- 'Unexpected end-of-record for incoming request',
- 'warning'
- )
-
- def push (self, thing):
- if type(thing) == type(''):
- self.outgoing.append(producers.simple_producer (thing))
- else:
- self.outgoing.append(thing)
-
- def response (self, code=200):
- message = self.responses[code]
- self.reply_code = code
- return 'HTTP/%s %d %s' % (self.version, code, message)
-
- def error (self, code):
- self.reply_code = code
- message = self.responses[code]
- s = self.DEFAULT_ERROR_MESSAGE % {
- 'code': code,
- 'message': message,
- }
- self['Content-Length'] = len(s)
- self['Content-Type'] = 'text/html'
- # make an error reply
- self.push (s)
- self.done()
-
- # can also be used for empty replies
- reply_now = error
-
- def done (self):
- "finalize this transaction - send output to the http channel"
-
- # ----------------------------------------
- # persistent connection management
- # ----------------------------------------
-
- # --- BUCKLE UP! ----
-
- connection = string.lower (get_header (CONNECTION, self.header))
-
- close_it = 0
- wrap_in_chunking = 0
-
- if self.version == '1.0':
- if connection == 'keep-alive':
- if not self.has_key ('Content-Length'):
- close_it = 1
- else:
- self['Connection'] = 'Keep-Alive'
- else:
- close_it = 1
- elif self.version == '1.1':
- if connection == 'close':
- close_it = 1
- elif not self.has_key ('Content-Length'):
- if self.has_key ('Transfer-Encoding'):
- if not self['Transfer-Encoding'] == 'chunked':
- close_it = 1
- elif self.use_chunked:
- self['Transfer-Encoding'] = 'chunked'
- wrap_in_chunking = 1
- else:
- close_it = 1
- elif self.version is None:
- # Although we don't *really* support http/0.9 (because we'd have to
- # use \r\n as a terminator, and it would just yuck up a lot of stuff)
- # it's very common for developers to not want to type a version number
- # when using telnet to debug a server.
- close_it = 1
-
- outgoing_header = producers.simple_producer (self.build_reply_header())
-
- if close_it:
- self['Connection'] = 'close'
-
- if wrap_in_chunking:
- outgoing_producer = producers.chunked_producer (
- producers.composite_producer (self.outgoing)
- )
- # prepend the header
- outgoing_producer = producers.composite_producer(
- [outgoing_header, outgoing_producer]
- )
- else:
- # prepend the header
- self.outgoing.insert(0, outgoing_header)
- outgoing_producer = producers.composite_producer (self.outgoing)
-
- # apply a few final transformations to the output
- self.channel.push_with_producer (
- # globbing gives us large packets
- producers.globbing_producer (
- # hooking lets us log the number of bytes sent
- producers.hooked_producer (
- outgoing_producer,
- self.log
- )
- )
- )
-
- self.channel.current_request = None
-
- if close_it:
- self.channel.close_when_done()
-
- def log_date_string (self, when):
- gmt = time.gmtime(when)
- if time.daylight and gmt[8]:
- tz = time.altzone
- else:
- tz = time.timezone
- if tz > 0:
- neg = 1
- else:
- neg = 0
- tz = -tz
- h, rem = divmod (tz, 3600)
- m, rem = divmod (rem, 60)
- if neg:
- offset = '-%02d%02d' % (h, m)
- else:
- offset = '+%02d%02d' % (h, m)
-
- return time.strftime ( '%d/%b/%Y:%H:%M:%S ', gmt) + offset
-
- def log (self, bytes):
- self.channel.server.logger.log (
- self.channel.addr[0],
- '%d - - [%s] "%s" %d %d\n' % (
- self.channel.addr[1],
- self.log_date_string (time.time()),
- self.request,
- self.reply_code,
- bytes
- )
- )
-
- responses = {
- 100: "Continue",
- 101: "Switching Protocols",
- 200: "OK",
- 201: "Created",
- 202: "Accepted",
- 203: "Non-Authoritative Information",
- 204: "No Content",
- 205: "Reset Content",
- 206: "Partial Content",
- 300: "Multiple Choices",
- 301: "Moved Permanently",
- 302: "Moved Temporarily",
- 303: "See Other",
- 304: "Not Modified",
- 305: "Use Proxy",
- 400: "Bad Request",
- 401: "Unauthorized",
- 402: "Payment Required",
- 403: "Forbidden",
- 404: "Not Found",
- 405: "Method Not Allowed",
- 406: "Not Acceptable",
- 407: "Proxy Authentication Required",
- 408: "Request Time-out",
- 409: "Conflict",
- 410: "Gone",
- 411: "Length Required",
- 412: "Precondition Failed",
- 413: "Request Entity Too Large",
- 414: "Request-URI Too Large",
- 415: "Unsupported Media Type",
- 500: "Internal Server Error",
- 501: "Not Implemented",
- 502: "Bad Gateway",
- 503: "Service Unavailable",
- 504: "Gateway Time-out",
- 505: "HTTP Version not supported"
- }
-
- # Default error message
- DEFAULT_ERROR_MESSAGE = string.join (
- ['<head>',
- '<title>Error response</title>',
- '</head>',
- '<body>',
- '<h1>Error response</h1>',
- '<p>Error code %(code)d.',
- '<p>Message: %(message)s.',
- '</body>',
- ''
- ],
- '\r\n'
- )
-
-
-# ===========================================================================
-# HTTP Channel Object
-# ===========================================================================
-
-class http_channel (asynchat.async_chat):
-
- # use a larger default output buffer
- ac_out_buffer_size = 1<<16
-
- current_request = None
- channel_counter = counter()
-
- def __init__ (self, server, conn, addr):
- self.channel_number = http_channel.channel_counter.increment()
- self.request_counter = counter()
- asynchat.async_chat.__init__ (self, conn)
- self.server = server
- self.addr = addr
- self.set_terminator ('\r\n\r\n')
- self.in_buffer = ''
- self.creation_time = int (time.time())
- self.check_maintenance()
-
- def __repr__ (self):
- ar = asynchat.async_chat.__repr__(self)[1:-1]
- return '<%s channel#: %s requests:%s>' % (
- ar,
- self.channel_number,
- self.request_counter
- )
-
- # Channel Counter, Maintenance Interval...
- maintenance_interval = 500
-
- def check_maintenance (self):
- if not self.channel_number % self.maintenance_interval:
- self.maintenance()
-
- def maintenance (self):
- self.kill_zombies()
-
- # 30-minute zombie timeout. status_handler also knows how to kill zombies.
- zombie_timeout = 30 * 60
-
- def kill_zombies (self):
- now = int (time.time())
- for channel in asyncore.socket_map.values():
- if channel.__class__ == self.__class__:
- if (now - channel.creation_time) > channel.zombie_timeout:
- channel.close()
-
- # --------------------------------------------------
- # send/recv overrides, good place for instrumentation.
- # --------------------------------------------------
-
- # this information needs to get into the request object,
- # so that it may log correctly.
- def send (self, data):
- result = asynchat.async_chat.send (self, data)
- self.server.bytes_out.increment (len(data))
- return result
-
- def recv (self, buffer_size):
- try:
- result = asynchat.async_chat.recv (self, buffer_size)
- self.server.bytes_in.increment (len(result))
- return result
- except MemoryError:
- # --- Save a Trip to Your Service Provider ---
- # It's possible for a process to eat up all the memory of
- # the machine, and put it in an extremely wedged state,
- # where medusa keeps running and can't be shut down. This
- # is where MemoryError tends to get thrown, though of
- # course it could get thrown elsewhere.
- sys.exit ("Out of Memory!")
-
- def handle_error (self):
- t, v = sys.exc_info()[:2]
- if t is SystemExit:
- raise t, v
- else:
- asynchat.async_chat.handle_error (self)
-
- def log (self, *args):
- pass
-
- # --------------------------------------------------
- # async_chat methods
- # --------------------------------------------------
-
- def collect_incoming_data (self, data):
- if self.current_request:
- # we are receiving data (probably POST data) for a request
- self.current_request.collect_incoming_data (data)
- else:
- # we are receiving header (request) data
- self.in_buffer = self.in_buffer + data
-
- def found_terminator (self):
- if self.current_request:
- self.current_request.found_terminator()
- else:
- header = self.in_buffer
- self.in_buffer = ''
- lines = string.split (header, '\r\n')
-
- # --------------------------------------------------
- # crack the request header
- # --------------------------------------------------
-
- while lines and not lines[0]:
- # as per the suggestion of http-1.1 section 4.1, (and
- # Eric Parker <eparker@zyvex.com>), ignore a leading
- # blank lines (buggy browsers tack it onto the end of
- # POST requests)
- lines = lines[1:]
-
- if not lines:
- self.close_when_done()
- return
-
- request = lines[0]
-
- command, uri, version = crack_request (request)
- header = join_headers (lines[1:])
-
- # unquote path if necessary (thanks to Skip Montanaro for pointing
- # out that we must unquote in piecemeal fashion).
- rpath, rquery = splitquery(uri)
- if '%' in rpath:
- if rquery:
- uri = unquote (rpath) + '?' + rquery
- else:
- uri = unquote (rpath)
-
- r = http_request (self, request, command, uri, version, header)
- self.request_counter.increment()
- self.server.total_requests.increment()
-
- if command is None:
- self.log_info ('Bad HTTP request: %s' % repr(request), 'error')
- r.error (400)
- return
-
- # --------------------------------------------------
- # handler selection and dispatch
- # --------------------------------------------------
- for h in self.server.handlers:
- if h.match (r):
- try:
- self.current_request = r
- # This isn't used anywhere.
- # r.handler = h # CYCLE
- h.handle_request (r)
- except:
- self.server.exceptions.increment()
- (file, fun, line), t, v, tbinfo = asyncore.compact_traceback()
- self.log_info(
- 'Server Error: %s, %s: file: %s line: %s' % (t,v,file,line),
- 'error')
- try:
- r.error (500)
- except:
- pass
- return
-
- # no handlers, so complain
- r.error (404)
-
- def writable_for_proxy (self):
- # this version of writable supports the idea of a 'stalled' producer
- # [i.e., it's not ready to produce any output yet] This is needed by
- # the proxy, which will be waiting for the magic combination of
- # 1) hostname resolved
- # 2) connection made
- # 3) data available.
- if self.ac_out_buffer:
- return 1
- elif len(self.producer_fifo):
- p = self.producer_fifo.first()
- if hasattr (p, 'stalled'):
- return not p.stalled()
- else:
- return 1
-
-# ===========================================================================
-# HTTP Server Object
-# ===========================================================================
-
-class http_server (asyncore.dispatcher):
-
- SERVER_IDENT = 'HTTP Server (V%s)' % VERSION_STRING
-
- channel_class = http_channel
-
- def __init__ (self, ip, port, resolver=None, logger_object=None):
- self.ip = ip
- self.port = port
- asyncore.dispatcher.__init__ (self)
- self.create_socket (socket.AF_INET, socket.SOCK_STREAM)
-
- self.handlers = []
-
- if not logger_object:
- logger_object = logger.file_logger (sys.stdout)
-
- self.set_reuse_addr()
- self.bind ((ip, port))
-
- # lower this to 5 if your OS complains
- self.listen (1024)
-
- host, port = self.socket.getsockname()
- if not ip:
- self.log_info('Computing default hostname', 'warning')
- ip = socket.gethostbyname (socket.gethostname())
- try:
- self.server_name = socket.gethostbyaddr (ip)[0]
- except socket.error:
- self.log_info('Cannot do reverse lookup', 'warning')
- self.server_name = ip # use the IP address as the "hostname"
-
- self.server_port = port
- self.total_clients = counter()
- self.total_requests = counter()
- self.exceptions = counter()
- self.bytes_out = counter()
- self.bytes_in = counter()
-
- if not logger_object:
- logger_object = logger.file_logger (sys.stdout)
-
- if resolver:
- self.logger = logger.resolving_logger (resolver, logger_object)
- else:
- self.logger = logger.unresolving_logger (logger_object)
-
- self.log_info (
- 'Medusa (V%s) started at %s'
- '\n\tHostname: %s'
- '\n\tPort:%d'
- '\n' % (
- VERSION_STRING,
- time.ctime(time.time()),
- self.server_name,
- port,
- )
- )
-
- def writable (self):
- return 0
-
- def handle_read (self):
- pass
-
- def readable (self):
- return self.accepting
-
- def handle_connect (self):
- pass
-
- def handle_accept (self):
- self.total_clients.increment()
- try:
- conn, addr = self.accept()
- except socket.error:
- # linux: on rare occasions we get a bogus socket back from
- # accept. socketmodule.c:makesockaddr complains that the
- # address family is unknown. We don't want the whole server
- # to shut down because of this.
- self.log_info ('warning: server accept() threw an exception', 'warning')
- return
- except TypeError:
- # unpack non-sequence. this can happen when a read event
- # fires on a listening socket, but when we call accept()
- # we get EWOULDBLOCK, so dispatcher.accept() returns None.
- # Seen on FreeBSD3.
- self.log_info ('warning: server accept() threw EWOULDBLOCK', 'warning')
- return
-
- self.channel_class (self, conn, addr)
-
- def install_handler (self, handler, back=0):
- if back:
- self.handlers.append (handler)
- else:
- self.handlers.insert (0, handler)
-
- def remove_handler (self, handler):
- self.handlers.remove (handler)
-
- def status (self):
- def nice_bytes (n):
- return string.join (status_handler.english_bytes (n))
-
- handler_stats = filter (None, map (maybe_status, self.handlers))
-
- if self.total_clients:
- ratio = self.total_requests.as_long() / float(self.total_clients.as_long())
- else:
- ratio = 0.0
-
- return producers.composite_producer (
- [producers.lines_producer (
- ['<h2>%s</h2>' % self.SERVER_IDENT,
- '<br>Listening on: <b>Host:</b> %s' % self.server_name,
- '<b>Port:</b> %d' % self.port,
- '<p><ul>'
- '<li>Total <b>Clients:</b> %s' % self.total_clients,
- '<b>Requests:</b> %s' % self.total_requests,
- '<b>Requests/Client:</b> %.1f' % (ratio),
- '<li>Total <b>Bytes In:</b> %s' % (nice_bytes (self.bytes_in.as_long())),
- '<b>Bytes Out:</b> %s' % (nice_bytes (self.bytes_out.as_long())),
- '<li>Total <b>Exceptions:</b> %s' % self.exceptions,
- '</ul><p>'
- '<b>Extension List</b><ul>',
- ])] + handler_stats + [producers.simple_producer('</ul>')]
- )
-
-def maybe_status (thing):
- if hasattr (thing, 'status'):
- return thing.status()
- else:
- return None
-
-CONNECTION = re.compile ('Connection: (.*)', re.IGNORECASE)
-
-# merge multi-line headers
-# [486dx2: ~500/sec]
-def join_headers (headers):
- r = []
- for i in range(len(headers)):
- if headers[i][0] in ' \t':
- r[-1] = r[-1] + headers[i][1:]
- else:
- r.append (headers[i])
- return r
-
-def get_header (head_reg, lines, group=1):
- for line in lines:
- m = head_reg.match (line)
- if m and m.end() == len(line):
- return m.group (group)
- return ''
-
-def get_header_match (head_reg, lines):
- for line in lines:
- m = head_reg.match (line)
- if m and m.end() == len(line):
- return m
- return ''
-
-REQUEST = re.compile ('([^ ]+) ([^ ]+)(( HTTP/([0-9.]+))$|$)')
-
-def crack_request (r):
- m = REQUEST.match (r)
- if m and m.end() == len(r):
- if m.group(3):
- version = m.group(5)
- else:
- version = None
- return m.group(1), m.group(2), version
- else:
- return None, None, None
-
-if __name__ == '__main__':
- import sys
- if len(sys.argv) < 2:
- print 'usage: %s <root> <port>' % (sys.argv[0])
- else:
- import monitor
- import filesys
- import default_handler
- import status_handler
- import ftp_server
- import chat_server
- import resolver
- import logger
- rs = resolver.caching_resolver ('127.0.0.1')
- lg = logger.file_logger (sys.stdout)
- ms = monitor.secure_monitor_server ('fnord', '127.0.0.1', 9999)
- fs = filesys.os_filesystem (sys.argv[1])
- dh = default_handler.default_handler (fs)
- hs = http_server ('', string.atoi (sys.argv[2]), rs, lg)
- hs.install_handler (dh)
- ftp = ftp_server.ftp_server (
- ftp_server.dummy_authorizer(sys.argv[1]),
- port=8021,
- resolver=rs,
- logger_object=lg
- )
- cs = chat_server.chat_server ('', 7777)
- sh = status_handler.status_extension([hs,ms,ftp,cs,rs])
- hs.install_handler (sh)
- if ('-p' in sys.argv):
- def profile_loop ():
- try:
- asyncore.loop()
- except KeyboardInterrupt:
- pass
- import profile
- profile.run ('profile_loop()', 'profile.out')
- else:
- asyncore.loop()
diff --git a/demo/medusa054/https_server.py b/demo/medusa054/https_server.py
deleted file mode 100644
index f30bc86..0000000
--- a/demo/medusa054/https_server.py
+++ /dev/null
@@ -1,85 +0,0 @@
-#!/usr/bin/env python
-
-"""A https server built on Medusa's http_server.
-
-Copyright (c) 1999-2004 Ng Pheng Siong. All rights reserved."""
-
-import asynchat, asyncore, http_server, socket, sys
-from M2Crypto import SSL, version
-
-VERSION_STRING=version
-
-class https_channel(http_server.http_channel):
-
- ac_in_buffer_size = 1 << 16
-
- def __init__(self, server, conn, addr):
- http_server.http_channel.__init__(self, server, conn, addr)
-
- def send(self, data):
- try:
- result = self.socket._write_nbio(data)
- if result <= 0:
- return 0
- else:
- self.server.bytes_out.increment(result)
- return result
- except SSL.SSLError, why:
- self.close()
- self.log_info('send: closing channel %s %s' % (repr(self), why))
- return 0
-
- def recv(self, buffer_size):
- try:
- result = self.socket._read_nbio(buffer_size)
- if result is None:
- return ''
- elif result == '':
- self.close()
- return ''
- else:
- self.server.bytes_in.increment(len(result))
- return result
- except SSL.SSLError, why:
- self.close()
- self.log_info('recv: closing channel %s %s' % (repr(self), why))
- return ''
-
-
-class https_server(http_server.http_server):
-
- SERVER_IDENT='M2Crypto HTTPS Server (v%s)' % VERSION_STRING
-
- channel_class=https_channel
-
- def __init__(self, ip, port, ssl_ctx, resolver=None, logger_object=None):
- http_server.http_server.__init__(self, ip, port, resolver, logger_object)
- sys.stdout.write(self.SERVER_IDENT + '\n\n')
- sys.stdout.flush()
- self.ssl_ctx=ssl_ctx
-
- def handle_accept(self):
- # Cribbed from http_server.
- self.total_clients.increment()
- try:
- conn, addr = self.accept()
- except socket.error:
- # linux: on rare occasions we get a bogus socket back from
- # accept. socketmodule.c:makesockaddr complains that the
- # address family is unknown. We don't want the whole server
- # to shut down because of this.
- sys.stderr.write ('warning: server accept() threw an exception\n')
- return
-
- # Turn the vanilla socket into an SSL connection.
- try:
- ssl_conn=SSL.Connection(self.ssl_ctx, conn)
- ssl_conn._setup_ssl(addr)
- ssl_conn.accept_ssl()
- self.channel_class(self, ssl_conn, addr)
- except SSL.SSLError:
- pass
-
- def writeable(self):
- return 0
-
diff --git a/demo/medusa054/index.html b/demo/medusa054/index.html
deleted file mode 100644
index 0f7de19..0000000
--- a/demo/medusa054/index.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<html>
-<title>M2Crypto HTTPS Server</title>
-<body>
-<h1>M2Crypto HTTPS Server - It works!</h1>
-</body>
-</html>
diff --git a/demo/medusa054/logger.py b/demo/medusa054/logger.py
deleted file mode 100644
index d131ab5..0000000
--- a/demo/medusa054/logger.py
+++ /dev/null
@@ -1,261 +0,0 @@
-# -*- Mode: Python -*-
-
-import asynchat
-import socket
-import time # these three are for the rotating logger
-import os # |
-import stat # v
-
-#
-# three types of log:
-# 1) file
-# with optional flushing. Also, one that rotates the log.
-# 2) socket
-# dump output directly to a socket connection. [how do we
-# keep it open?]
-# 3) syslog
-# log to syslog via tcp. this is a per-line protocol.
-#
-
-#
-# The 'standard' interface to a logging object is simply
-# log_object.log (message)
-#
-
-# a file-like object that captures output, and
-# makes sure to flush it always... this could
-# be connected to:
-# o stdio file
-# o low-level file
-# o socket channel
-# o syslog output...
-
-class file_logger:
-
- # pass this either a path or a file object.
- def __init__ (self, file, flush=1, mode='a'):
- if type(file) == type(''):
- if (file == '-'):
- import sys
- self.file = sys.stdout
- else:
- self.file = open (file, mode)
- else:
- self.file = file
- self.do_flush = flush
-
- def __repr__ (self):
- return '<file logger: %s>' % self.file
-
- def write (self, data):
- self.file.write (data)
- self.maybe_flush()
-
- def writeline (self, line):
- self.file.writeline (line)
- self.maybe_flush()
-
- def writelines (self, lines):
- self.file.writelines (lines)
- self.maybe_flush()
-
- def maybe_flush (self):
- if self.do_flush:
- self.file.flush()
-
- def flush (self):
- self.file.flush()
-
- def softspace (self, *args):
- pass
-
- def log (self, message):
- if message[-1] not in ('\r', '\n'):
- self.write (message + '\n')
- else:
- self.write (message)
-
-# like a file_logger, but it must be attached to a filename.
-# When the log gets too full, or a certain time has passed,
-# it backs up the log and starts a new one. Note that backing
-# up the log is done via "mv" because anything else (cp, gzip)
-# would take time, during which medusa would do nothing else.
-
-class rotating_file_logger (file_logger):
-
- # If freq is non-None we back up "daily", "weekly", or "monthly".
- # Else if maxsize is non-None we back up whenever the log gets
- # to big. If both are None we never back up.
- def __init__ (self, file, freq=None, maxsize=None, flush=1, mode='a'):
- self.filename = file
- self.mode = mode
- self.file = open (file, mode)
- self.freq = freq
- self.maxsize = maxsize
- self.rotate_when = self.next_backup(self.freq)
- self.do_flush = flush
-
- def __repr__ (self):
- return '<rotating-file logger: %s>' % self.file
-
- # We back up at midnight every 1) day, 2) monday, or 3) 1st of month
- def next_backup (self, freq):
- (yr, mo, day, hr, min, sec, wd, jday, dst) = time.localtime(time.time())
- if freq == 'daily':
- return time.mktime((yr,mo,day+1, 0,0,0, 0,0,-1))
- elif freq == 'weekly':
- return time.mktime((yr,mo,day-wd+7, 0,0,0, 0,0,-1)) # wd(monday)==0
- elif freq == 'monthly':
- return time.mktime((yr,mo+1,1, 0,0,0, 0,0,-1))
- else:
- return None # not a date-based backup
-
- def maybe_flush (self): # rotate first if necessary
- self.maybe_rotate()
- if self.do_flush: # from file_logger()
- self.file.flush()
-
- def maybe_rotate (self):
- if self.freq and time.time() > self.rotate_when:
- self.rotate()
- self.rotate_when = self.next_backup(self.freq)
- elif self.maxsize: # rotate when we get too big
- try:
- if os.stat(self.filename)[stat.ST_SIZE] > self.maxsize:
- self.rotate()
- except os.error: # file not found, probably
- self.rotate() # will create a new file
-
- def rotate (self):
- (yr, mo, day, hr, min, sec, wd, jday, dst) = time.localtime(time.time())
- try:
- self.file.close()
- newname = '%s.ends%04d%02d%02d' % (self.filename, yr, mo, day)
- try:
- open(newname, "r").close() # check if file exists
- newname = newname + "-%02d%02d%02d" % (hr, min, sec)
- except: # YEARMODY is unique
- pass
- os.rename(self.filename, newname)
- self.file = open(self.filename, self.mode)
- except:
- pass
-
-# syslog is a line-oriented log protocol - this class would be
-# appropriate for FTP or HTTP logs, but not for dumping stderr to.
-
-# TODO: a simple safety wrapper that will ensure that the line sent
-# to syslog is reasonable.
-
-# TODO: async version of syslog_client: now, log entries use blocking
-# send()
-
-import m_syslog
-syslog_logger = m_syslog.syslog_client
-
-class syslog_logger (m_syslog.syslog_client):
- def __init__ (self, address, facility='user'):
- m_syslog.syslog_client.__init__ (self, address)
- self.facility = m_syslog.facility_names[facility]
- self.address=address
-
- def __repr__ (self):
- return '<syslog logger address=%s>' % (repr(self.address))
-
- def log (self, message):
- m_syslog.syslog_client.log (
- self,
- message,
- facility=self.facility,
- priority=m_syslog.LOG_INFO
- )
-
-# log to a stream socket, asynchronously
-
-class socket_logger (asynchat.async_chat):
-
- def __init__ (self, address):
-
- if type(address) == type(''):
- self.create_socket (socket.AF_UNIX, socket.SOCK_STREAM)
- else:
- self.create_socket (socket.AF_INET, socket.SOCK_STREAM)
-
- self.connect (address)
- self.address = address
-
- def __repr__ (self):
- return '<socket logger: address=%s>' % (self.address)
-
- def log (self, message):
- if message[-2:] != '\r\n':
- self.socket.push (message + '\r\n')
- else:
- self.socket.push (message)
-
-# log to multiple places
-class multi_logger:
- def __init__ (self, loggers):
- self.loggers = loggers
-
- def __repr__ (self):
- return '<multi logger: %s>' % (repr(self.loggers))
-
- def log (self, message):
- for logger in self.loggers:
- logger.log (message)
-
-class resolving_logger:
- """Feed (ip, message) combinations into this logger to get a
- resolved hostname in front of the message. The message will not
- be logged until the PTR request finishes (or fails)."""
-
- def __init__ (self, resolver, logger):
- self.resolver = resolver
- self.logger = logger
-
- class logger_thunk:
- def __init__ (self, message, logger):
- self.message = message
- self.logger = logger
-
- def __call__ (self, host, ttl, answer):
- if not answer:
- answer = host
- self.logger.log ('%s:%s' % (answer, self.message))
-
- def log (self, ip, message):
- self.resolver.resolve_ptr (
- ip,
- self.logger_thunk (
- message,
- self.logger
- )
- )
-
-class unresolving_logger:
- "Just in case you don't want to resolve"
- def __init__ (self, logger):
- self.logger = logger
-
- def log (self, ip, message):
- self.logger.log ('%s:%s' % (ip, message))
-
-
-def strip_eol (line):
- while line and line[-1] in '\r\n':
- line = line[:-1]
- return line
-
-class tail_logger:
- "Keep track of the last <size> log messages"
- def __init__ (self, logger, size=500):
- self.size = size
- self.logger = logger
- self.messages = []
-
- def log (self, message):
- self.messages.append (strip_eol (message))
- if len (self.messages) > self.size:
- del self.messages[0]
- self.logger.log (message)
diff --git a/demo/medusa054/m_syslog.py b/demo/medusa054/m_syslog.py
deleted file mode 100644
index e212766..0000000
--- a/demo/medusa054/m_syslog.py
+++ /dev/null
@@ -1,182 +0,0 @@
-# -*- Mode: Python -*-
-
-# ======================================================================
-# Copyright 1997 by Sam Rushing
-#
-# All Rights Reserved
-#
-# Permission to use, copy, modify, and distribute this software and
-# its documentation for any purpose and without fee is hereby
-# granted, provided that the above copyright notice appear in all
-# copies and that both that copyright notice and this permission
-# notice appear in supporting documentation, and that the name of Sam
-# Rushing not be used in advertising or publicity pertaining to
-# distribution of the software without specific, written prior
-# permission.
-#
-# SAM RUSHING DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
-# NO EVENT SHALL SAM RUSHING BE LIABLE FOR ANY SPECIAL, INDIRECT OR
-# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
-# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-# ======================================================================
-
-"""socket interface to unix syslog.
-On Unix, there are usually two ways of getting to syslog: via a
-local unix-domain socket, or via the TCP service.
-
-Usually "/dev/log" is the unix domain socket. This may be different
-for other systems.
-
->>> my_client = syslog_client ('/dev/log')
-
-Otherwise, just use the UDP version, port 514.
-
->>> my_client = syslog_client (('my_log_host', 514))
-
-On win32, you will have to use the UDP version. Note that
-you can use this to log to other hosts (and indeed, multiple
-hosts).
-
-This module is not a drop-in replacement for the python
-<syslog> extension module - the interface is different.
-
-Usage:
-
->>> c = syslog_client()
->>> c = syslog_client ('/strange/non_standard_log_location')
->>> c = syslog_client (('other_host.com', 514))
->>> c.log ('testing', facility='local0', priority='debug')
-
-"""
-
-# TODO: support named-pipe syslog.
-# [see ftp://sunsite.unc.edu/pub/Linux/system/Daemons/syslog-fifo.tar.z]
-
-# from <linux/sys/syslog.h>:
-# ===========================================================================
-# priorities/facilities are encoded into a single 32-bit quantity, where the
-# bottom 3 bits are the priority (0-7) and the top 28 bits are the facility
-# (0-big number). Both the priorities and the facilities map roughly
-# one-to-one to strings in the syslogd(8) source code. This mapping is
-# included in this file.
-#
-# priorities (these are ordered)
-
-LOG_EMERG = 0 # system is unusable
-LOG_ALERT = 1 # action must be taken immediately
-LOG_CRIT = 2 # critical conditions
-LOG_ERR = 3 # error conditions
-LOG_WARNING = 4 # warning conditions
-LOG_NOTICE = 5 # normal but significant condition
-LOG_INFO = 6 # informational
-LOG_DEBUG = 7 # debug-level messages
-
-# facility codes
-LOG_KERN = 0 # kernel messages
-LOG_USER = 1 # random user-level messages
-LOG_MAIL = 2 # mail system
-LOG_DAEMON = 3 # system daemons
-LOG_AUTH = 4 # security/authorization messages
-LOG_SYSLOG = 5 # messages generated internally by syslogd
-LOG_LPR = 6 # line printer subsystem
-LOG_NEWS = 7 # network news subsystem
-LOG_UUCP = 8 # UUCP subsystem
-LOG_CRON = 9 # clock daemon
-LOG_AUTHPRIV = 10 # security/authorization messages (private)
-
-# other codes through 15 reserved for system use
-LOG_LOCAL0 = 16 # reserved for local use
-LOG_LOCAL1 = 17 # reserved for local use
-LOG_LOCAL2 = 18 # reserved for local use
-LOG_LOCAL3 = 19 # reserved for local use
-LOG_LOCAL4 = 20 # reserved for local use
-LOG_LOCAL5 = 21 # reserved for local use
-LOG_LOCAL6 = 22 # reserved for local use
-LOG_LOCAL7 = 23 # reserved for local use
-
-priority_names = {
- "alert": LOG_ALERT,
- "crit": LOG_CRIT,
- "debug": LOG_DEBUG,
- "emerg": LOG_EMERG,
- "err": LOG_ERR,
- "error": LOG_ERR, # DEPRECATED
- "info": LOG_INFO,
- "notice": LOG_NOTICE,
- "panic": LOG_EMERG, # DEPRECATED
- "warn": LOG_WARNING, # DEPRECATED
- "warning": LOG_WARNING,
- }
-
-facility_names = {
- "auth": LOG_AUTH,
- "authpriv": LOG_AUTHPRIV,
- "cron": LOG_CRON,
- "daemon": LOG_DAEMON,
- "kern": LOG_KERN,
- "lpr": LOG_LPR,
- "mail": LOG_MAIL,
- "news": LOG_NEWS,
- "security": LOG_AUTH, # DEPRECATED
- "syslog": LOG_SYSLOG,
- "user": LOG_USER,
- "uucp": LOG_UUCP,
- "local0": LOG_LOCAL0,
- "local1": LOG_LOCAL1,
- "local2": LOG_LOCAL2,
- "local3": LOG_LOCAL3,
- "local4": LOG_LOCAL4,
- "local5": LOG_LOCAL5,
- "local6": LOG_LOCAL6,
- "local7": LOG_LOCAL7,
- }
-
-import socket
-
-class syslog_client:
- def __init__ (self, address='/dev/log'):
- self.address = address
- self.stream = 0
- if isinstance(address, type('')):
- try:
- self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
- self.socket.connect(address)
- except socket.error:
- # Some Linux installations have /dev/log
- # a stream socket instead of a datagram socket.
- self.socket = socket.socket (socket.AF_UNIX,
- socket.SOCK_STREAM)
- self.stream = 1
- else:
- self.socket = socket.socket (socket.AF_INET, socket.SOCK_DGRAM)
-
- # curious: when talking to the unix-domain '/dev/log' socket, a
- # zero-terminator seems to be required. this string is placed
- # into a class variable so that it can be overridden if
- # necessary.
-
- log_format_string = '<%d>%s\000'
-
- def log (self, message, facility=LOG_USER, priority=LOG_INFO):
- message = self.log_format_string % (
- self.encode_priority (facility, priority),
- message
- )
- if self.stream:
- self.socket.send (message)
- else:
- self.socket.sendto (message, self.address)
-
- def encode_priority (self, facility, priority):
- if type(facility) == type(''):
- facility = facility_names[facility]
- if type(priority) == type(''):
- priority = priority_names[priority]
- return (facility<<3) | priority
-
- def close (self):
- if self.stream:
- self.socket.close()
diff --git a/demo/medusa054/medusa_gif.py b/demo/medusa054/medusa_gif.py
deleted file mode 100644
index 005644a..0000000
--- a/demo/medusa054/medusa_gif.py
+++ /dev/null
@@ -1,8 +0,0 @@
-# -*- Mode: Python -*-
-
-# the medusa icon as a python source file.
-
-width = 97
-height = 61
-
-data = 'GIF89aa\000=\000\204\000\000\000\000\000\255\255\255\245\245\245ssskkkccc111)))\326\326\326!!!\316\316\316\300\300\300\204\204\000\224\224\224\214\214\214\200\200\200RRR\377\377\377JJJ\367\367\367BBB\347\347\347\000\204\000\020\020\020\265\265\265\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000!\371\004\001\000\000\021\000,\000\000\000\000a\000=\000\000\005\376`$\216di\236h\252\256l\353\276p,\317tm\337x\256\357|m\001@\240E\305\000\364\2164\206R)$\005\201\214\007r\012{X\255\312a\004\260\\>\026\3240\353)\224n\001W+X\334\373\231~\344.\303b\216\024\027x<\273\307\255G,rJiWN\014{S}k"?ti\013EdPQ\207G@_%\000\026yy\\\201\202\227\224<\221Fs$pOjWz\241<r@vO\236\231\233k\247M\2544\203F\177\235\236L#\247\256Z\270,\266BxJ[\276\256A]iE\304\305\262\273E\313\201\275i#\\\303\321\'h\203V\\\177\326\276\216\220P~\335\230_\264\013\342\275\344KF\233\360Q\212\352\246\000\367\274s\361\236\334\347T\341;\341\246\2202\177\3142\211`\242o\325@S\202\264\031\252\207\260\323\256\205\311\036\236\270\002\'\013\302\177\274H\010\324X\002\0176\212\037\376\321\360\032\226\207\244\2674(+^\202\346r\205J\0211\375\241Y#\256f\0127\315>\272\002\325\307g\012(\007\205\312#j\317(\012A\200\224.\241\003\346GS\247\033\245\344\264\366\015L\'PXQl]\266\263\243\232\260?\245\316\371\362\225\035\332\243J\273\332Q\263\357-D\241T\327\270\265\013W&\330\010u\371b\322IW0\214\261]\003\033Va\365Z#\207\213a\030k\2647\262\014p\354\024[n\321N\363\346\317\003\037P\000\235C\302\000\3228(\244\363YaA\005\022\255_\237@\260\000A\212\326\256qbp\321\332\266\011\334=T\023\010"!B\005\003A\010\224\020\220 H\002\337#\020 O\276E\357h\221\327\003\\\000b@v\004\351A.h\365\354\342B\002\011\257\025\\ \220\340\301\353\006\000\024\214\200pA\300\353\012\364\241k/\340\033C\202\003\000\310fZ\011\003V\240R\005\007\354\376\026A\000\000\360\'\202\177\024\004\210\003\000\305\215\360\000\000\015\220\240\332\203\027@\'\202\004\025VpA\000%\210x\321\206\032J\341\316\010\262\211H"l\333\341\200\200>"]P\002\212\011\010`\002\0066FP\200\001\'\024p]\004\027(8B\221\306]\000\201w>\002iB\001\007\340\260"v7J1\343(\257\020\251\243\011\242i\263\017\215\337\035\220\200\221\365m4d\015\016D\251\341iN\354\346Ng\253\200I\240\031\35609\245\2057\311I\302\2007t\231"&`\314\310\244\011e\226(\236\010w\212\300\234\011\012HX(\214\253\311@\001\233^\222pg{% \340\035\224&H\000\246\201\362\215`@\001"L\340\004\030\234\022\250\'\015(V:\302\235\030\240q\337\205\224\212h@\177\006\000\250\210\004\007\310\207\337\005\257-P\346\257\367]p\353\203\271\256:\203\236\211F\340\247\010\3329g\244\010\307*=A\000\203\260y\012\304s#\014\007D\207,N\007\304\265\027\021C\233\207%B\366[m\353\006\006\034j\360\306+\357\274a\204\000\000;'
diff --git a/demo/medusa054/poison_handler.py b/demo/medusa054/poison_handler.py
deleted file mode 100644
index acc78ab..0000000
--- a/demo/medusa054/poison_handler.py
+++ /dev/null
@@ -1,69 +0,0 @@
-
-import string
-import whrandom
-
-RESP_HEAD="""\
-<HTML><BODY BGCOLOR=\"#ffffff\">
-"""
-
-RESP_MIDDLE="""
-<h2>M2Crypto https server demonstration</h2>
-
-This web page is generated by the "poison" http request handler.
-<br>
-The links just go on and on and on...
-<br><br>
-"""
-
-RESP_TAIL="""
-</BODY></HTML>
-"""
-
-charset='012345678/90ABCDEFGHIJKLM/NOPQRSTUVWXYZabcd/efghijklmnopqrs/tuvwxyz'
-numchar=len(charset)
-
-def makepage(numlinks):
-
- title='<title>'
- for u in range(whrandom.randint(3, 15)):
- pick=whrandom.randint(0, numchar-1)
- title=title+charset[pick]
- title=title+'</title>'
-
- url='\r\n'
- numlinks=whrandom.randint(2, numlinks)
- for i in range(numlinks):
- url=url+'<a href="/poison/'
- for u in range(whrandom.randint(3, 15)):
- pick=whrandom.randint(0, numchar-1)
- ch=charset[pick]
- if ch=='/' and url[-1]=='/':
- ch=charset[pick+1]
- url=url+ch
- url=url+'/">'
- for u in range(whrandom.randint(3, 15)):
- pick=whrandom.randint(0, numchar-1)
- url=url+charset[pick]
- url=url+'</a><br>\r\n'
-
- url=RESP_HEAD+title+RESP_MIDDLE+url+RESP_TAIL
- return url
-
-
-class poison_handler:
- """This is a clone of webpoison - every URL returns a page of URLs, each of which
- returns a page of URLs, each of _which_ returns a page of URLs, ad infinitum.
- The objective is to sucker address-harvesting bots run by spammers."""
-
- def __init__(self, numlinks=10):
- self.numlinks = numlinks
- self.poison_level = 0
-
- def match(self, request):
- return (request.uri[:7] == '/poison')
-
- def handle_request(self, request):
- if request.command == 'get':
- request.push(makepage(self.numlinks))
- request.done()
-
diff --git a/demo/medusa054/producers.py b/demo/medusa054/producers.py
deleted file mode 100644
index a04906e..0000000
--- a/demo/medusa054/producers.py
+++ /dev/null
@@ -1,323 +0,0 @@
-# -*- Mode: Python -*-
-
-"""
-A collection of producers.
-Each producer implements a particular feature: They can be combined
-in various ways to get interesting and useful behaviors.
-
-For example, you can feed dynamically-produced output into the compressing
-producer, then wrap this with the 'chunked' transfer-encoding producer.
-"""
-
-import string
-from asynchat import find_prefix_at_end
-
-class simple_producer:
- "producer for a string"
- def __init__ (self, data, buffer_size=1024):
- self.data = data
- self.buffer_size = buffer_size
-
- def more (self):
- if len (self.data) > self.buffer_size:
- result = self.data[:self.buffer_size]
- self.data = self.data[self.buffer_size:]
- return result
- else:
- result = self.data
- self.data = ''
- return result
-
-class scanning_producer:
- "like simple_producer, but more efficient for large strings"
- def __init__ (self, data, buffer_size=1024):
- self.data = data
- self.buffer_size = buffer_size
- self.pos = 0
-
- def more (self):
- if self.pos < len(self.data):
- lp = self.pos
- rp = min (
- len(self.data),
- self.pos + self.buffer_size
- )
- result = self.data[lp:rp]
- self.pos = self.pos + len(result)
- return result
- else:
- return ''
-
-class lines_producer:
- "producer for a list of lines"
-
- def __init__ (self, lines):
- self.lines = lines
-
- def more (self):
- if self.lines:
- chunk = self.lines[:50]
- self.lines = self.lines[50:]
- return string.join (chunk, '\r\n') + '\r\n'
- else:
- return ''
-
-class buffer_list_producer:
- "producer for a list of strings"
-
- # i.e., data == string.join (buffers, '')
-
- def __init__ (self, buffers):
-
- self.index = 0
- self.buffers = buffers
-
- def more (self):
- if self.index >= len(self.buffers):
- return ''
- else:
- data = self.buffers[self.index]
- self.index = self.index + 1
- return data
-
-class file_producer:
- "producer wrapper for file[-like] objects"
-
- # match http_channel's outgoing buffer size
- out_buffer_size = 1<<16
-
- def __init__ (self, file):
- self.done = 0
- self.file = file
-
- def more (self):
- if self.done:
- return ''
- else:
- data = self.file.read (self.out_buffer_size)
- if not data:
- self.file.close()
- del self.file
- self.done = 1
- return ''
- else:
- return data
-
-# A simple output producer. This one does not [yet] have
-# the safety feature builtin to the monitor channel: runaway
-# output will not be caught.
-
-# don't try to print from within any of the methods
-# of this object.
-
-class output_producer:
- "Acts like an output file; suitable for capturing sys.stdout"
- def __init__ (self):
- self.data = ''
-
- def write (self, data):
- lines = string.splitfields (data, '\n')
- data = string.join (lines, '\r\n')
- self.data = self.data + data
-
- def writeline (self, line):
- self.data = self.data + line + '\r\n'
-
- def writelines (self, lines):
- self.data = self.data + string.joinfields (
- lines,
- '\r\n'
- ) + '\r\n'
-
- def flush (self):
- pass
-
- def softspace (self, *args):
- pass
-
- def more (self):
- if self.data:
- result = self.data[:512]
- self.data = self.data[512:]
- return result
- else:
- return ''
-
-class composite_producer:
- "combine a fifo of producers into one"
- def __init__ (self, producers):
- self.producers = producers
-
- def more (self):
- while len(self.producers):
- p = self.producers[0]
- d = p.more()
- if d:
- return d
- else:
- self.producers.pop(0)
- else:
- return ''
-
-
-class globbing_producer:
- """
- 'glob' the output from a producer into a particular buffer size.
- helps reduce the number of calls to send(). [this appears to
- gain about 30% performance on requests to a single channel]
- """
-
- def __init__ (self, producer, buffer_size=1<<16):
- self.producer = producer
- self.buffer = ''
- self.buffer_size = buffer_size
-
- def more (self):
- while len(self.buffer) < self.buffer_size:
- data = self.producer.more()
- if data:
- self.buffer = self.buffer + data
- else:
- break
- r = self.buffer
- self.buffer = ''
- return r
-
-
-class hooked_producer:
- """
- A producer that will call <function> when it empties,.
- with an argument of the number of bytes produced. Useful
- for logging/instrumentation purposes.
- """
-
- def __init__ (self, producer, function):
- self.producer = producer
- self.function = function
- self.bytes = 0
-
- def more (self):
- if self.producer:
- result = self.producer.more()
- if not result:
- self.producer = None
- self.function (self.bytes)
- else:
- self.bytes = self.bytes + len(result)
- return result
- else:
- return ''
-
-# HTTP 1.1 emphasizes that an advertised Content-Length header MUST be
-# correct. In the face of Strange Files, it is conceivable that
-# reading a 'file' may produce an amount of data not matching that
-# reported by os.stat() [text/binary mode issues, perhaps the file is
-# being appended to, etc..] This makes the chunked encoding a True
-# Blessing, and it really ought to be used even with normal files.
-# How beautifully it blends with the concept of the producer.
-
-class chunked_producer:
- """A producer that implements the 'chunked' transfer coding for HTTP/1.1.
- Here is a sample usage:
- request['Transfer-Encoding'] = 'chunked'
- request.push (
- producers.chunked_producer (your_producer)
- )
- request.done()
- """
-
- def __init__ (self, producer, footers=None):
- self.producer = producer
- self.footers = footers
-
- def more (self):
- if self.producer:
- data = self.producer.more()
- if data:
- return '%x\r\n%s\r\n' % (len(data), data)
- else:
- self.producer = None
- if self.footers:
- return string.join (
- ['0'] + self.footers,
- '\r\n'
- ) + '\r\n\r\n'
- else:
- return '0\r\n\r\n'
- else:
- return ''
-
-# Unfortunately this isn't very useful right now (Aug 97), because
-# apparently the browsers don't do on-the-fly decompression. Which
-# is sad, because this could _really_ speed things up, especially for
-# low-bandwidth clients (i.e., most everyone).
-
-try:
- import zlib
-except ImportError:
- zlib = None
-
-class compressed_producer:
- """
- Compress another producer on-the-fly, using ZLIB
- [Unfortunately, none of the current browsers seem to support this]
- """
-
- # Note: It's not very efficient to have the server repeatedly
- # compressing your outgoing files: compress them ahead of time, or
- # use a compress-once-and-store scheme. However, if you have low
- # bandwidth and low traffic, this may make more sense than
- # maintaining your source files compressed.
- #
- # Can also be used for compressing dynamically-produced output.
-
- def __init__ (self, producer, level=5):
- self.producer = producer
- self.compressor = zlib.compressobj (level)
-
- def more (self):
- if self.producer:
- cdata = ''
- # feed until we get some output
- while not cdata:
- data = self.producer.more()
- if not data:
- self.producer = None
- return self.compressor.flush()
- else:
- cdata = self.compressor.compress (data)
- return cdata
- else:
- return ''
-
-class escaping_producer:
-
- "A producer that escapes a sequence of characters"
- " Common usage: escaping the CRLF.CRLF sequence in SMTP, NNTP, etc..."
-
- def __init__ (self, producer, esc_from='\r\n.', esc_to='\r\n..'):
- self.producer = producer
- self.esc_from = esc_from
- self.esc_to = esc_to
- self.buffer = ''
- self.find_prefix_at_end = find_prefix_at_end
-
- def more (self):
- esc_from = self.esc_from
- esc_to = self.esc_to
-
- buffer = self.buffer + self.producer.more()
-
- if buffer:
- buffer = string.replace (buffer, esc_from, esc_to)
- i = self.find_prefix_at_end (buffer, esc_from)
- if i:
- # we found a prefix
- self.buffer = buffer[-i:]
- return buffer[:-i]
- else:
- # no prefix, return it all
- self.buffer = ''
- return buffer
- else:
- return buffer
diff --git a/demo/medusa054/server.pem b/demo/medusa054/server.pem
deleted file mode 100644
index 1ee9282..0000000
--- a/demo/medusa054/server.pem
+++ /dev/null
@@ -1,36 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDYjCCAsugAwIBAgIBBDANBgkqhkiG9w0BAQQFADCBgDELMAkGA1UEBhMCU0cx
-ETAPBgNVBAoTCE0yQ3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UE
-AxMbTTJDcnlwdG8gQ2VydGlmaWNhdGUgTWFzdGVyMSIwIAYJKoZIhvcNAQkBFhNu
-Z3BzQG5ldG1lbWV0aWMuY29tMB4XDTAzMDYyMjEzMzAxNFoXDTA0MDYyMTEzMzAx
-NFowXTELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRIwEAYDVQQDEwls
-b2NhbGhvc3QxJzAlBgkqhkiG9w0BCQEWGGFkbWluQHNlcnZlci5leGFtcGxlLmRv
-bTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA37aKGZtFicl8xXXTLJ8/JD7c
-kd3t/teCX9i61lpaDQCKBoVrrursIvZihemMKI9g/u/+BLqt5g8mBdgUdYz0txc8
-KEbV2hj+wwOX4H3XwD0Y+DysXiNHq7/tFdmzSVHoLxpY4zYzXbxQ/p049wvIyPRp
-/y3omcnx/TEUhkn+JmkCAwEAAaOCAQwwggEIMAkGA1UdEwQCMAAwLAYJYIZIAYb4
-QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBTB
-H/mUYlww24mJlSxEtGdlwojO9zCBrQYDVR0jBIGlMIGigBTr+pwHMS1CmF9cuGI4
-du3YqoHAwqGBhqSBgzCBgDELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRv
-MRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UEAxMbTTJDcnlwdG8gQ2VydGlm
-aWNhdGUgTWFzdGVyMSIwIAYJKoZIhvcNAQkBFhNuZ3BzQG5ldG1lbWV0aWMuY29t
-ggEAMA0GCSqGSIb3DQEBBAUAA4GBAAvl6v0s3eFeGP4iAcrfysuK7jzFKhjDYuOy
-lVS3u33bZNLnMpM6OSEM9yPh4WpFCVHf+nYwC71pk4ilsLVXjKxymm2lNGcxLVuW
-iydFz4Ly9nmN7Ja9ygYT39dGAFP/wN7ELTpsbul8VfmqhNg9y81d8i/A1tK3AGA8
-0QkPQNdP
------END CERTIFICATE-----
------BEGIN RSA PRIVATE KEY-----
-MIICXAIBAAKBgQDftooZm0WJyXzFddMsnz8kPtyR3e3+14Jf2LrWWloNAIoGhWuu
-6uwi9mKF6Ywoj2D+7/4Euq3mDyYF2BR1jPS3FzwoRtXaGP7DA5fgfdfAPRj4PKxe
-I0erv+0V2bNJUegvGljjNjNdvFD+nTj3C8jI9Gn/LeiZyfH9MRSGSf4maQIDAQAB
-AoGAHpeVtv62uarl9xKvuBBm0AwQmZnhq9HIsFaw5hMg8Vo7hbzFBvx1IirTOkC/
-u+QvfW1QLVFh6m3z4ySzV4fZBtcd6F9SbSrZ0xsxIUB2NOSa1RGgiaP61bJnMMM1
-xM3O9iwM5GZc3Gqy08QOCpDl0772VJ+9Gz3FA88mrc6rHQkCQQDz6RIatFjT28n8
-1vy0nHwwZz2oXTpe/pyZPwoKj8zVsmrKhKwOw7l8ArxjP8zoHOE7AQBCXYDMNoFp
-IAF0yuqrAkEA6s0wMEdPpQeb0XHAfccyJQoeULxHdVFoz1wWmGSOm4YmQtR8/QJx
-luEgfpeRkzxBKt5Ls3MEkheIOw7xV24zOwJAMz+DaE0AZPNHS3K4ghJnHZxzng6I
-lzEUIjbWm0V/ml70hTy/EhMZw+6nOotLOHHo+QbK0SboSwAgzL/Gzo1cJQJANqpS
-38qadleRJXAQWrg3qnvyluVe1aeAeVZ9RDmVIgxXeBO0jcs12uTLBe4PzHGo0mwy
-v7K1i7XC180gzzQu5QJBAOxITT9RoWSSozPvnirHd37sn+RsrNYkV07NAa80M20Z
-DkBPHeMVkNgigrQ6L6vWmbRDGQbGcMplAxnI5ppKCoU=
------END RSA PRIVATE KEY-----
diff --git a/demo/medusa054/status_handler.py b/demo/medusa054/status_handler.py
deleted file mode 100644
index 8d2583e..0000000
--- a/demo/medusa054/status_handler.py
+++ /dev/null
@@ -1,272 +0,0 @@
-# -*- Mode: Python -*-
-
-VERSION_STRING = "$Id: status_handler.py 299 2005-06-09 17:32:28Z heikki $"
-
-#
-# medusa status extension
-#
-
-import string
-import time
-import re
-from cgi import escape
-
-import asyncore
-import http_server
-import medusa_gif
-import producers
-from counter import counter
-
-START_TIME = long(time.time())
-
-class status_extension:
- hit_counter = counter()
-
- def __init__ (self, objects, statusdir='/status', allow_emergency_debug=0):
- self.objects = objects
- self.statusdir = statusdir
- self.allow_emergency_debug = allow_emergency_debug
- # We use /status instead of statusdir here because it's too
- # hard to pass statusdir to the logger, who makes the HREF
- # to the object dir. We don't need the security-through-
- # obscurity here in any case, because the id is obscurity enough
- self.hyper_regex = re.compile('/status/object/([0-9]+)/.*')
- self.hyper_objects = []
- for object in objects:
- self.register_hyper_object (object)
-
- def __repr__ (self):
- return '<Status Extension (%s hits) at %x>' % (
- self.hit_counter,
- id(self)
- )
-
- def match (self, request):
- path, params, query, fragment = request.split_uri()
- # For reasons explained above, we don't use statusdir for /object
- return (path[:len(self.statusdir)] == self.statusdir or
- path[:len("/status/object/")] == '/status/object/')
-
- # Possible Targets:
- # /status
- # /status/channel_list
- # /status/medusa.gif
-
- # can we have 'clickable' objects?
- # [yes, we can use id(x) and do a linear search]
-
- # Dynamic producers:
- # HTTP/1.0: we must close the channel, because it's dynamic output
- # HTTP/1.1: we can use the chunked transfer-encoding, and leave
- # it open.
-
- def handle_request (self, request):
- [path, params, query, fragment] = request.split_uri()
- self.hit_counter.increment()
- if path == self.statusdir: # and not a subdirectory
- up_time = string.join (english_time (long(time.time()) - START_TIME))
- request['Content-Type'] = 'text/html'
- request.push (
- '<html>'
- '<title>Medusa Status Reports</title>'
- '<body bgcolor="#ffffff">'
- '<h1>Medusa Status Reports</h1>'
- '<b>Up:</b> %s' % up_time
- )
- for i in range(len(self.objects)):
- request.push (self.objects[i].status())
- request.push ('<hr>\r\n')
- request.push (
- '<p><a href="%s/channel_list">Channel List</a>'
- '<hr>'
- '<img src="%s/medusa.gif" align=right width=%d height=%d>'
- '</body></html>' % (
- self.statusdir,
- self.statusdir,
- medusa_gif.width,
- medusa_gif.height
- )
- )
- request.done()
- elif path == self.statusdir + '/channel_list':
- request['Content-Type'] = 'text/html'
- request.push ('<html><body>')
- request.push(channel_list_producer(self.statusdir))
- request.push (
- '<hr>'
- '<img src="%s/medusa.gif" align=right width=%d height=%d>' % (
- self.statusdir,
- medusa_gif.width,
- medusa_gif.height
- ) +
- '</body></html>'
- )
- request.done()
-
- elif path == self.statusdir + '/medusa.gif':
- request['Content-Type'] = 'image/gif'
- request['Content-Length'] = len(medusa_gif.data)
- request.push (medusa_gif.data)
- request.done()
-
- elif path == self.statusdir + '/close_zombies':
- message = (
- '<h2>Closing all zombie http client connections...</h2>'
- '<p><a href="%s">Back to the status page</a>' % self.statusdir
- )
- request['Content-Type'] = 'text/html'
- request['Content-Length'] = len (message)
- request.push (message)
- now = int (time.time())
- for channel in asyncore.socket_map.keys():
- if channel.__class__ == http_server.http_channel:
- if channel != request.channel:
- if (now - channel.creation_time) > channel.zombie_timeout:
- channel.close()
- request.done()
-
- # Emergency Debug Mode
- # If a server is running away from you, don't KILL it!
- # Move all the AF_INET server ports and perform an autopsy...
- # [disabled by default to protect the innocent]
- elif self.allow_emergency_debug and path == self.statusdir + '/emergency_debug':
- request.push ('<html>Moving All Servers...</html>')
- request.done()
- for channel in asyncore.socket_map.keys():
- if channel.accepting:
- if type(channel.addr) is type(()):
- ip, port = channel.addr
- channel.socket.close()
- channel.del_channel()
- channel.addr = (ip, port+10000)
- fam, typ = channel.family_and_type
- channel.create_socket (fam, typ)
- channel.set_reuse_addr()
- channel.bind (channel.addr)
- channel.listen(5)
-
- else:
- m = self.hyper_regex.match (path)
- if m:
- oid = string.atoi (m.group (1))
- for object in self.hyper_objects:
- if id (object) == oid:
- if hasattr (object, 'hyper_respond'):
- object.hyper_respond (self, path, request)
- else:
- request.error (404)
- return
-
- def status (self):
- return producers.simple_producer (
- '<li>Status Extension <b>Hits</b> : %s' % self.hit_counter
- )
-
- def register_hyper_object (self, object):
- if not object in self.hyper_objects:
- self.hyper_objects.append (object)
-
-import logger
-
-class logger_for_status (logger.tail_logger):
-
- def status (self):
- return 'Last %d log entries for: %s' % (
- len (self.messages),
- html_repr (self)
- )
-
- def hyper_respond (self, sh, path, request):
- request['Content-Type'] = 'text/plain'
- messages = self.messages[:]
- messages.reverse()
- request.push (lines_producer (messages))
- request.done()
-
-class lines_producer:
- def __init__ (self, lines):
- self.lines = lines
-
- def more (self):
- if self.lines:
- chunk = self.lines[:50]
- self.lines = self.lines[50:]
- return string.join (chunk, '\r\n') + '\r\n'
- else:
- return ''
-
-class channel_list_producer (lines_producer):
- def __init__ (self, statusdir):
- channel_reprs = map (
- lambda x: '&lt;' + repr(x)[1:-1] + '&gt;',
- asyncore.socket_map.values()
- )
- channel_reprs.sort()
- lines_producer.__init__ (
- self,
- ['<h1>Active Channel List</h1>',
- '<pre>'
- ] + channel_reprs + [
- '</pre>',
- '<p><a href="%s">Status Report</a>' % statusdir
- ]
- )
-
-
-def html_repr (object):
- so = escape (repr (object))
- if hasattr (object, 'hyper_respond'):
- return '<a href="/status/object/%d/">%s</a>' % (id (object), so)
- else:
- return so
-
-def html_reprs (list, front='', back=''):
- reprs = map (
- lambda x,f=front,b=back: '%s%s%s' % (f,x,b),
- map (lambda x: escape (html_repr(x)), list)
- )
- reprs.sort()
- return reprs
-
-# for example, tera, giga, mega, kilo
-# p_d (n, (1024, 1024, 1024, 1024))
-# smallest divider goes first - for example
-# minutes, hours, days
-# p_d (n, (60, 60, 24))
-
-def progressive_divide (n, parts):
- result = []
- for part in parts:
- n, rem = divmod (n, part)
- result.append (rem)
- result.append (n)
- return result
-
-# b,k,m,g,t
-def split_by_units (n, units, dividers, format_string):
- divs = progressive_divide (n, dividers)
- result = []
- for i in range(len(units)):
- if divs[i]:
- result.append (format_string % (divs[i], units[i]))
- result.reverse()
- if not result:
- return [format_string % (0, units[0])]
- else:
- return result
-
-def english_bytes (n):
- return split_by_units (
- n,
- ('','K','M','G','T'),
- (1024, 1024, 1024, 1024, 1024),
- '%d %sB'
- )
-
-def english_time (n):
- return split_by_units (
- n,
- ('secs', 'mins', 'hours', 'days', 'weeks', 'years'),
- ( 60, 60, 24, 7, 52),
- '%d %s'
- )
diff --git a/demo/medusa054/xmlrpc_handler.py b/demo/medusa054/xmlrpc_handler.py
deleted file mode 100644
index 15057cf..0000000
--- a/demo/medusa054/xmlrpc_handler.py
+++ /dev/null
@@ -1,103 +0,0 @@
-# -*- Mode: Python -*-
-
-# See http://www.xml-rpc.com/
-# http://www.pythonware.com/products/xmlrpc/
-
-# Based on "xmlrpcserver.py" by Fredrik Lundh (fredrik@pythonware.com)
-
-VERSION = "$Id: xmlrpc_handler.py 299 2005-06-09 17:32:28Z heikki $"
-
-import http_server
-import xmlrpclib
-
-import string
-import sys
-
-class xmlrpc_handler:
-
- def match (self, request):
- # Note: /RPC2 is not required by the spec, so you may override this method.
- if request.uri[:5] == '/RPC2':
- return 1
- else:
- return 0
-
- def handle_request (self, request):
- [path, params, query, fragment] = request.split_uri()
-
- if request.command == 'POST':
- request.collector = collector (self, request)
- else:
- request.error (400)
-
- def continue_request (self, data, request):
- params, method = xmlrpclib.loads (data)
- try:
- # generate response
- try:
- response = self.call (method, params)
- if type(response) != type(()):
- response = (response,)
- except:
- # report exception back to server
- response = xmlrpclib.dumps (
- xmlrpclib.Fault (1, "%s:%s" % (sys.exc_type, sys.exc_value))
- )
- else:
- response = xmlrpclib.dumps (response, methodresponse=1)
- except:
- # internal error, report as HTTP server error
- request.error (500)
- else:
- # got a valid XML RPC response
- request['Content-Type'] = 'text/xml'
- request.push (response)
- request.done()
-
- def call (self, method, params):
- # override this method to implement RPC methods
- raise "NotYetImplemented"
-
-class collector:
-
- "gathers input for POST and PUT requests"
-
- def __init__ (self, handler, request):
-
- self.handler = handler
- self.request = request
- self.data = ''
-
- # make sure there's a content-length header
- cl = request.get_header ('content-length')
-
- if not cl:
- request.error (411)
- else:
- cl = string.atoi (cl)
- # using a 'numeric' terminator
- self.request.channel.set_terminator (cl)
-
- def collect_incoming_data (self, data):
- self.data = self.data + data
-
- def found_terminator (self):
- # set the terminator back to the default
- self.request.channel.set_terminator ('\r\n\r\n')
- self.handler.continue_request (self.data, self.request)
-
-if __name__ == '__main__':
-
- class rpc_demo (xmlrpc_handler):
-
- def call (self, method, params):
- print 'method="%s" params=%s' % (method, params)
- return "Sure, that works"
-
- import asyncore
-
- hs = http_server.http_server ('', 8000)
- rpc = rpc_demo()
- hs.install_handler (rpc)
-
- asyncore.loop()
diff --git a/demo/perf/memio.py b/demo/perf/memio.py
deleted file mode 100644
index 238d85c..0000000
--- a/demo/perf/memio.py
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/usr/bin/env python2.0
-
-"""A comparison of Python's cStringIO and M2Crypto's MemoryBuffer,
-the outcome of which is that MemoryBuffer suffers from doing too much
-in Python.
-
-Two way to optimise MemoryBuffer:
-1. Create MemoryBufferIn and MemoryBufferOut a la StringI and StringO.
-2. Have MemoryBuffer do all internal work with cStringIO. ;-)
-"""
-
-from cStringIO import StringIO
-from M2Crypto.BIO import MemoryBuffer
-from M2Crypto import m2
-import profile
-
-txt = 'Python, Smalltalk, Haskell, Scheme, Lisp, Self, Erlang, ML, ...'
-
-def stringi(iter, txt=txt):
- buf = StringIO()
- for i in range(iter):
- buf.write(txt)
- out = buf.getvalue()
-
-def membufi(iter, txt=txt):
- buf = MemoryBuffer()
- for i in range(iter):
- buf.write(txt)
- out = buf.getvalue()
-
-def membuf2i(iter, txt=txt):
- buf = MemoryBuffer()
- buf.write(txt * iter)
- out = buf.getvalue()
-
-def cmembufi(iter, txt=txt):
- buf = m2.bio_new(m2.bio_s_mem())
- for i in range(iter):
- m2.bio_write(buf, txt)
- m2.bio_set_mem_eof_return(buf, 0)
- out = m2.bio_read(buf, m2.bio_ctrl_pending(buf))
-
-if __name__ == '__main__':
- profile.run('stringi(10000)')
- profile.run('cmembufi(10000)')
- profile.run('membufi(10000)')
- profile.run('membuf2i(10000)')
-
-
diff --git a/demo/perf/sha1.py b/demo/perf/sha1.py
deleted file mode 100644
index 6d85289..0000000
--- a/demo/perf/sha1.py
+++ /dev/null
@@ -1,46 +0,0 @@
-#!/usr/bin/env python2.0
-
-"""A comparison of Python's sha and M2Crypto.EVP.MessageDigest,
-the outcome of which is that EVP.MessageDigest suffers from doing
-too much in Python."""
-
-import profile
-
-from sha import sha
-import M2Crypto
-from M2Crypto import m2
-from M2Crypto.EVP import MessageDigest
-
-txt = 'Python, Smalltalk, Haskell, Scheme, Lisp, Self, Erlang, ML, ...'
-
-def py_sha(iter, txt=txt):
- s = sha()
- for i in range(iter):
- s.update(txt)
- out = s.digest()
-
-def m2_sha(iter, txt=txt):
- s = MessageDigest('sha1')
- for i in range(iter):
- s.update(txt)
- out = s.digest()
-
-def m2_sha_2(iter, txt=txt):
- s = MessageDigest('sha1')
- s.update(txt * iter)
- out = s.digest()
-
-def m2c_sha(iter, txt=txt):
- ctx = m2.md_ctx_new()
- m2.digest_init(ctx, m2.sha1())
- for i in range(iter):
- m2.digest_update(ctx, txt)
- out = m2.digest_final(ctx)
-
-if __name__ == '__main__':
- profile.run('py_sha(10000)')
- profile.run('m2_sha(10000)')
- profile.run('m2_sha_2(10000)')
- profile.run('m2c_sha(10000)')
-
-
diff --git a/demo/pgp/pgpstep.py b/demo/pgp/pgpstep.py
deleted file mode 100644
index ff5b135..0000000
--- a/demo/pgp/pgpstep.py
+++ /dev/null
@@ -1,113 +0,0 @@
-#!/usr/bin/env python
-
-"""pgpstep - steps through a pgp2 packet stream.
-
-Copyright (c) 1999 Ng Pheng Siong. All rights reserved."""
-
-from M2Crypto import PGP, util
-import time
-
-def desc_public_key(pkt):
- print 'packet = public_key'
- print 'version =', pkt.version()
- print 'created = ', time.asctime(time.gmtime(pkt.timestamp()))
- print 'validity code =', pkt.validity()
- print 'pkc type =', `pkt.pkc()`
- #e, n = pkt.pubkey()
- print 'e =', `pkt._e`
- print 'n =', `pkt._n`
- print
-
-def desc_trust(pkt):
- print 'packet = trust'
- print 'trustworthiness = <ignored>'
- print
-
-def desc_userid(pkt):
- print 'packet = user_id'
- print 'user_id =', pkt.userid()
- print
-
-def desc_signature(pkt):
- print 'packet = signature'
- print 'version =', pkt.version()
- print 'classification =', `pkt._classification`
- print 'created = ', time.asctime(time.gmtime(pkt.timestamp()))
- print 'keyid =', `pkt._keyid`
- print 'pkc type =', `pkt.pkc()`
- print 'md_algo =', `pkt._md_algo`
- print 'md_chksum =', `pkt._md_chksum`
- print 'sig =', `pkt._sig`
- print
-
-def desc_private_key(pkt):
- print 'packet = private key'
- print 'version =', pkt.version()
- print 'created = ', time.asctime(time.gmtime(pkt.timestamp()))
- print 'validity code =', pkt.validity()
- print 'pkc type =', `pkt.pkc()`
- print 'e =', `pkt._e`
- print 'n =', `pkt._n`
- print 'cipher =', `pkt._cipher`
- if pkt._cipher == '\001':
- print 'following attributes are encrypted'
- print 'iv =', `pkt._iv`
- print 'd =', `pkt._d`
- print 'p =', `pkt._p`
- print 'q =', `pkt._q`
- print 'u =', `pkt._u`
- print 'checksum =', `pkt._cksum`
- print
-
-def desc_cke(pkt):
- print 'packet = cke'
- print 'iv =', `pkt.iv`
- print 'checksum =', `pkt.cksum`
- print 'ciphertext =', `pkt.ctxt`
- print
-
-def desc_pke(pkt):
- print 'packet = pke'
- print 'version =', pkt.version
- print 'keyid =', `pkt.keyid`
- print 'pkc type =', pkt.pkc_type
- print 'dek =', hex(pkt.dek)[:-1]
- print
-
-def desc_literal(pkt):
- print 'packet = literal data'
- print 'mode =', `pkt.fmode`
- print 'filename =', pkt.fname
- print 'time = ', time.asctime(time.gmtime(pkt.ftime))
- print 'data = <%d octets of literal data>' % (len(pkt.data),)
- print
-
-DESC = {
- PGP.public_key_packet: desc_public_key,
- PGP.trust_packet: desc_trust,
- PGP.userid_packet: desc_userid,
- PGP.signature_packet: desc_signature,
- PGP.private_key_packet: desc_private_key,
- PGP.cke_packet: desc_cke,
- PGP.pke_packet: desc_pke,
- PGP.literal_packet: desc_literal,
-}
-
-if __name__ == '__main__':
- import sys
- count = 0
- for arg in sys.argv[1:]:
- f = open(arg, 'rb')
- ps = PGP.packet_stream(f)
- while 1:
- pkt = ps.read()
- if pkt is None:
- break
- elif pkt:
- print '-'*70
- DESC[pkt.__class__](pkt)
- count = count + ps.count()
- ps.close()
- print '-'*70
- print 'Total octets processed =', count
-
diff --git a/demo/pgp/pubring.pgp b/demo/pgp/pubring.pgp
deleted file mode 100644
index fbe4863..0000000
--- a/demo/pgp/pubring.pgp
+++ /dev/null
Binary files differ
diff --git a/demo/pgp/secring.pgp b/demo/pgp/secring.pgp
deleted file mode 100644
index 7eca123..0000000
--- a/demo/pgp/secring.pgp
+++ /dev/null
Binary files differ
diff --git a/demo/pkcs7/pkcs7-thawte.pem b/demo/pkcs7/pkcs7-thawte.pem
deleted file mode 100644
index a444627..0000000
--- a/demo/pkcs7/pkcs7-thawte.pem
+++ /dev/null
@@ -1,45 +0,0 @@
------BEGIN PKCS7-----
-MIAGCSqGSIb3DQEHAqCAMIIH1wIBATELMAkGBSsOAwIaBQAwgAYJKoZIhvcNAQcB
-AACgggXgMIICxDCCAi2gAwIBAgIDAphPMA0GCSqGSIb3DQEBBAUAMIGUMQswCQYD
-VQQGEwJaQTEVMBMGA1UECBMMV2VzdGVybiBDYXBlMRQwEgYDVQQHEwtEdXJiYW52
-aWxsZTEPMA0GA1UEChMGVGhhd3RlMR0wGwYDVQQLExRDZXJ0aWZpY2F0ZSBTZXJ2
-aWNlczEoMCYGA1UEAxMfUGVyc29uYWwgRnJlZW1haWwgUlNBIDE5OTkuOS4xNjAe
-Fw0wMDA1MTgxMTA4MTJaFw0wMTA1MTgxMTA4MTJaMGUxETAPBgNVBAQTCFN0cm9l
-ZGVyMRAwDgYDVQQqEwdNaWNoYWVsMRkwFwYDVQQDExBNaWNoYWVsIFN0cm9lZGVy
-MSMwIQYJKoZIhvcNAQkBFhRtaWNoYWVsQHN0cm9lZGVyLmNvbTCBnzANBgkqhkiG
-9w0BAQEFAAOBjQAwgYkCgYEAqzxf+ZpWoELOD7sXes/G9O6dSCkGeNL/G5l0k/b4
-C9QnZyEh2S0vWI+g43G1uGhu6sgI5Y1SfrG08xGIUEcmexxnl6krTR/QlHr+t9If
-UXFTmEPAnuIpfPRUqhOQlNFB1DfwKVLb4J3b2947ulv4vpb4owVMC+WjDM5fo765
-RXMCAwEAAaNSMFAwHwYDVR0RBBgwFoEUbWljaGFlbEBzdHJvZWRlci5jb20wDAYD
-VR0TAQH/BAIwADAfBgNVHSMEGDAWgBSIq/Fgg2ZV9ORYx0YdwGG9I9fDjDANBgkq
-hkiG9w0BAQQFAAOBgQCxx7Uvsnq1F/yOIPiUmlaTXLFAvvTj2trHAF4UFhkQGe6V
-IBHmDk62H1xJhA4AHNVz3Pe250S8Fu75OgOh2pRJ8KfB6cJU0gxz9ahRt48Qy6+m
-XUHk9135ru2u8I505nj4i37T6zK3+O/lZU+P79qdPHYwO6dNsYyaRFYLxGyXTjCC
-AxQwggJ9oAMCAQICAQswDQYJKoZIhvcNAQEEBQAwgdExCzAJBgNVBAYTAlpBMRUw
-EwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEaMBgGA1UE
-ChMRVGhhd3RlIENvbnN1bHRpbmcxKDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2Vy
-dmljZXMgRGl2aXNpb24xJDAiBgNVBAMTG1RoYXd0ZSBQZXJzb25hbCBGcmVlbWFp
-bCBDQTErMCkGCSqGSIb3DQEJARYccGVyc29uYWwtZnJlZW1haWxAdGhhd3RlLmNv
-bTAeFw05OTA5MTYxNDAxNDBaFw0wMTA5MTUxNDAxNDBaMIGUMQswCQYDVQQGEwJa
-QTEVMBMGA1UECBMMV2VzdGVybiBDYXBlMRQwEgYDVQQHEwtEdXJiYW52aWxsZTEP
-MA0GA1UEChMGVGhhd3RlMR0wGwYDVQQLExRDZXJ0aWZpY2F0ZSBTZXJ2aWNlczEo
-MCYGA1UEAxMfUGVyc29uYWwgRnJlZW1haWwgUlNBIDE5OTkuOS4xNjCBnzANBgkq
-hkiG9w0BAQEFAAOBjQAwgYkCgYEAs2lal9TQFgt6tcVd6SGcI3LNEkxL937Px/vK
-ciT0QlKsV5Xje2F6F4Tn/XI5OJS06u1lp5IGXr3gZfYZu5R5dkw+uWhwdYQc9BF0
-ALwFLE8JAxcxzPRB1HLGpl3iiESwiy7ETfHw1oU+bPOVlHiRfkDpnNGNFVeOwnPl
-MN5G9U8CAwEAAaM3MDUwEgYDVR0TAQH/BAgwBgEB/wIBADAfBgNVHSMEGDAWgBRy
-ScJzNMZV9At2coF+d/SH58ayDjANBgkqhkiG9w0BAQQFAAOBgQBrxlnpMfrptuyx
-A9jfcnL+kWBI6sZV3XvwZ47GYXDnbcKlN9idtxcoVgWL3Vx1b8aRkMZsZnET0BB8
-a5FvhuAhNi3B1+qyCa3PLW3Gg1Kb+7v+nIed/LfpdJLkXJeu/H6syg1vcnpnLGtz
-9Yb5nfUAbvQdB86dnoJjKe+TCX5V3jGCAdAwggHMAgEBMIGcMIGUMQswCQYDVQQG
-EwJaQTEVMBMGA1UECBMMV2VzdGVybiBDYXBlMRQwEgYDVQQHEwtEdXJiYW52aWxs
-ZTEPMA0GA1UEChMGVGhhd3RlMR0wGwYDVQQLExRDZXJ0aWZpY2F0ZSBTZXJ2aWNl
-czEoMCYGA1UEAxMfUGVyc29uYWwgRnJlZW1haWwgUlNBIDE5OTkuOS4xNgIDAphP
-MAkGBSsOAwIaBQCggYowGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG
-9w0BCQUxDxcNMDAwNzE2MTQ0MzQ0WjAjBgkqhkiG9w0BCQQxFgQU2jmj7l5rSw0y
-Vb/vlWAYkK/YBwkwKwYJKoZIhvcNAQkPMR4wHDAKBggqhkiG9w0DBzAOBggqhkiG
-9w0DAgICAIAwDQYJKoZIhvcNAQEBBQAEgYBagl1y4nRwW+GLhZ5tElkh9Z/yFirz
-ZXI0jMywML/ADxsAf1yV2JIYCCk0V33QdrYy8MVqgErGXxGdA5aKnm5545Wf4Noz
-CLWF4FJc6RDSFp7dv2631TrswdFRRCHNds+dvP5v5EAiADvmEOYaDiWM07jp73jx
-TkkzxW9cevZDaQAAAAA=
------END PKCS7-----
diff --git a/demo/pkcs7/test.py b/demo/pkcs7/test.py
deleted file mode 100644
index afa7477..0000000
--- a/demo/pkcs7/test.py
+++ /dev/null
@@ -1,6 +0,0 @@
-from M2Crypto import BIO, SMIME
-
-pf = BIO.openfile('pkcs7-thawte.pem')
-p7 = SMIME.load_pkcs7_bio(pf)
-print p7.type(1)
-
diff --git a/demo/rsa.priv.pem b/demo/rsa.priv.pem
deleted file mode 100644
index ed34db6..0000000
--- a/demo/rsa.priv.pem
+++ /dev/null
@@ -1,9 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIBOwIBAAJBANQNY7RD9BarYRsmMazM1hd7a+u3QeMPFZQ7Ic+BmmeWHvvVP4Yj
-yu1t6vAut7mKkaDeKbT3yiGVUgAEUaWMXqECAwEAAQJAIHCz8h37N4ScZHThYJgt
-oIYHKpZsg/oIyRaKw54GKxZq5f7YivcWoZ8j7IQ65lHVH3gmaqKOvqdAVVt5imKZ
-KQIhAPPsr9i3FxU+Mac0pvQKhFVJUzAFfKiG3ulVUdHgAaw/AiEA3ozHKzfZWKxH
-gs8v8ZQ/FnfI7DwYYhJC0YsXb6NSvR8CIHymwLo73mTxsogjBQqDcVrwLL3GoAyz
-V6jf+/8HvXMbAiEAj1b3FVQEboOQD6WoyJ1mQO9n/xf50HjYhqRitOnp6ZsCIQDS
-AvkvYKc6LG8IANmVv93g1dyKZvU/OQkAZepqHZB2MQ==
------END RSA PRIVATE KEY-----
diff --git a/demo/rsa.priv0.pem b/demo/rsa.priv0.pem
deleted file mode 100644
index e2b93a1..0000000
--- a/demo/rsa.priv0.pem
+++ /dev/null
@@ -1,15 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-Proc-Type: 4,ENCRYPTED
-DEK-Info: DES-CBC,244DDAFE6F991A53
-
-h1/NnMxq2ku9UkBG2tfM7hCFWmOvwMbVQBYgS4jLm3ENvWRgkm7pCqjCug99Uo5o
-r+NhzqyvSBH+eX3ojVAfpMxkL0TIjMrogRq2TD75v6hTGu/fd4Yrw7vZaKRbLzoh
-rG6m7zdbiQwNyh0bTbbo3WmQ07FXkXrDqihLaZTJOvHNLS1lKwRjIS0MqtyhOfPj
-NNwuNEs6AFz4k6UxNMRXhyU2SXn5SOgZZB12SCIsYA034rwKFKqNRoneaLSlhtut
-1z/BlJaLiZDHJmtxtgz5h3Ss9fQ9J0pLnybx+EM70TPM3hz47/8cQiEYIVg7+QFW
-jNYaGIA6IOcyB7fwX5e/zFy5yXAsmuIw/iP0sYa29hdUG++T8Mp2knrBBwQO77OS
-WRz219dMQQRyyn2jpN5x23AZyz4gHj4YKMm3KO06Y2k=
------END RSA PRIVATE KEY-----
-
-This is the same key as rsa.priv.pem. Passphrase is 'qwerty'.
-
diff --git a/demo/rsa.pub.pem b/demo/rsa.pub.pem
deleted file mode 100644
index 42379aa..0000000
--- a/demo/rsa.pub.pem
+++ /dev/null
@@ -1,4 +0,0 @@
------BEGIN PUBLIC KEY-----
-MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANQNY7RD9BarYRsmMazM1hd7a+u3QeMP
-FZQ7Ic+BmmeWHvvVP4Yjyu1t6vAut7mKkaDeKbT3yiGVUgAEUaWMXqECAwEAAQ==
------END PUBLIC KEY-----
diff --git a/demo/rsa1024pvtkey.pem b/demo/rsa1024pvtkey.pem
deleted file mode 100644
index 481f191..0000000
--- a/demo/rsa1024pvtkey.pem
+++ /dev/null
@@ -1,15 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIICXQIBAAKBgQDE3rnXDvA4lrIUj7ZXQM2ODLw0NnjKXh7+O3GPttvoFoacK1qk
-BRO+aO4hPhvQumySTz+N2RkIsT9PTx6yfyWWwYC1zbbv2cxlCBisGAvrUSL6IfHX
-ND2/vVN+QmOd/b4hfC/ekRo2ylrnX0pOXv/JxiblV9WumiZsBEuhUvxCnQIDAQAB
-AoGBALdaLEDkM8ywZQiLVCptO0RaDgqe1N68zCbBXCGaD7NXD2VxZ0itRdcnyOiC
-/MroZWfakPleQVd8JNeLe66IhosAJd7Zbjf/npYnD4zD1x54zRrSuBquXhz+ev7U
-tZONPxU5QCf/aow4z1s/M+knLyy+0lAUlWwTgOrd5VCQ8suBAkEA5/v48HZW8pQC
-2zxQUFfsnRu6DxJuQ1UvWp51FNUYZM2LjpwgGyCNkCw+nuxPgM1HnOTAMVXkZdwL
-7XG0Gm5ZoQJBANlAKKUc7ItOfN5TeD154Qz9FLtZUgWnWfawvEqiHJ0cPrzyv9v6
-wu19QxP6ORZBWyr8c20/p2fNrk+7YOZAH30CQQDZ9p1HEWlQMlEcu+aaFoJyewKt
-9pszGG6NriRDlpR84cMmEvr3gfaAZ5HOsCli031dpHAP6qvWKJHsXtDhpJ0BAkBs
-fANP4A+myLzF8Hx8hl4BNGej3kh9FkJwU3TS9/y935rck4OG/8NTAFf8o9jZ6izy
-XDnvdffMeALxQapzj9WpAkBQt2yjU3V3bKkNl0XwTk/VK8WGEWTBF1byZv/6VZOb
-q/vOPSexrQmu+T8+lljraJISfIpMSWZhR4oarmnGVRPX
------END RSA PRIVATE KEY-----
diff --git a/demo/rsa_bench.py b/demo/rsa_bench.py
deleted file mode 100644
index b0adacc..0000000
--- a/demo/rsa_bench.py
+++ /dev/null
@@ -1,183 +0,0 @@
-#!/usr/bin/env python
-
-"""
- RSA signing demo and benchmark.
-
- Usage: python -O rsa_bench.py [option option option ...]
- where options may include:
- makenewkey showdigest showprofile
- md5 sha1 sha256 sha512
- <key length>
-
- Larry Bugbee
- November 2006
-
-
- Some portions are Copyright (c) 1999-2003 Ng Pheng Siong.
- All rights reserved.
-
- Portions created by Open Source Applications Foundation
- (OSAF) are Copyright (C) 2004 OSAF. All Rights Reserved.
-
-"""
-
-from M2Crypto import RSA, EVP, Rand
-from M2Crypto.EVP import MessageDigest
-import sys, base64
-
-# --------------------------------------------------------------
-# program parameters
-
-makenewkey = 0 # 1 = make/save new key, 0 = use existing
-showpubkey = 0 # 1 = show the public key value
-showdigest = 0 # 1 = show the digest value
-showprofile = 0 # 1 = use the python profiler
-
-hashalgs = ['md5', 'ripemd160', 'sha1',
- 'sha224', 'sha256', 'sha384', 'sha512']
-
-# default hashing algorithm
-hashalg = 'sha1'
-
-# default key parameters
-keylen = 1024
-exponent = 65537
-'''
- There is some temptation to use an RSA exponent of 3
- because 1) it is easy to remember and 2) it minimizes the
- effort of signature verification. Unfortunately there
- a couple of attacks based on the use of 3. From a draft
- RFC (Easklake, Dec 2000):
- A public exponent of 3 minimizes the effort needed to
- verify a signature. Use of 3 as the public exponent is
- weak for confidentiality uses since, if the same data
- can be collected encrypted under three different keys
- with an exponent of 3 then, using the Chinese Remainder
- Theorem [NETSEC], the original plain text can be easily
- recovered.
- This applies to confidentiality so it is not of major
- concern here. The second attack is a protocol implementation
- weakness and can be patched, but has the patch been applied?
- ...correctly? It is arguably better to get into the habit
- of using a stronger exponent and avoiding these and possible
- future attacks based on 3. I suggest getting in the habit
- of using something stronger. Some suggest using 65537.
-'''
-
-# number of speed test loops
-N1 = N2 = 100
-
-# --------------------------------------------------------------
-# functions
-
-def test(rsa, dgst):
- print ' testing signing and verification...',
- try:
- sig = rsa.sign(dgst)
- except Exception, e:
- print '\n\n *** %s *** \n' % e
- sys.exit()
- if not rsa.verify(dgst, sig):
- print 'not ok'
- else:
- print 'ok'
-
-def test_asn1(rsa, dgst):
- print ' testing asn1 signing and verification...',
- blob = rsa.sign_asn1(dgst)
- if not rsa.verify_asn1(dgst, blob):
- print 'not ok'
- else:
- print 'ok'
-
-def speed():
- from time import time
- t1 = time()
- for i in range(N1):
- sig = rsa.sign(dgst)
- print ' %d signings: %8.2fs' % (N1, (time() - t1))
- t1 = time()
- for i in range(N2):
- rsa.verify(dgst, sig)
- print ' %d verifications: %8.2fs' % (N2, (time() - t1))
-
-def test_speed(rsa, dgst):
- print ' measuring speed...'
- if showprofile:
- import profile
- profile.run('speed()')
- else:
- speed()
- print
-
-# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-def main(keylen, hashalg):
- global rsa, dgst # this exists ONLY for speed testing
-
- Rand.load_file('randpool.dat', -1)
-
- pvtkeyfilename = 'rsa%dpvtkey.pem' % (keylen)
- pubkeyfilename = 'rsa%dpubkey.pem' % (keylen)
-
- if makenewkey:
- print ' making and saving a new key'
- rsa = RSA.gen_key(keylen, exponent)
- rsa.save_key(pvtkeyfilename, None ) # no pswd callback
- rsa.save_pub_key(pubkeyfilename)
- else:
- print ' loading an existing key'
- rsa = RSA.load_key(pvtkeyfilename)
- print ' rsa key length:', len(rsa)
-
- if not rsa.check_key():
- raise 'key is not initialised'
-
- # since we are testing signing and verification, let's not
- # be fussy about the digest. Just make one.
- md = EVP.MessageDigest(hashalg)
- md.update('can you spell subliminal channel?')
- dgst = md.digest()
- print ' hash algorithm: %s' % hashalg
- if showdigest:
- print ' %s digest: \n%s' % (hashalg, base64.encodestring(dgst))
-
- test(rsa, dgst)
-# test_asn1(rsa, dgst)
- test_speed(rsa, dgst)
- Rand.save_file('randpool.dat')
-
-# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-def print_usage():
- print """
- Usage: python -O %s [option option option ...]
- where options may include:
- makenewkey showdigest showprofile
- md5 sha1 sha256 sha512
- <key length>
-""" % sys.argv[0]
- sys.exit()
-
-# --------------------------------------------------------------
-# --------------------------------------------------------------
-
-if __name__=='__main__':
- for arg in sys.argv[1:]:
- if arg in hashalgs: hashalg = arg; continue
- if arg == 'makenewkey': makenewkey = 1; continue
- if arg == 'showpubkey': showpubkey = 1; continue
- if arg == 'showdigest': showdigest = 1; continue
- if arg == 'showprofile': showprofile = 1; continue
- try:
- keylen = int(arg)
- except:
- print '\n *** argument "%s" not understood ***' % arg
- print_usage()
-
- main(keylen, hashalg)
-
-
-# --------------------------------------------------------------
-# --------------------------------------------------------------
-# --------------------------------------------------------------
diff --git a/demo/rsatest.py b/demo/rsatest.py
deleted file mode 100644
index 4277c4d..0000000
--- a/demo/rsatest.py
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/env python
-
-"""RSA demonstration.
-
-Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
-
-from M2Crypto import RSA, EVP, Rand
-
-msg="The magic words are squeamish ossifrage."
-sha1=EVP.MessageDigest('sha1')
-sha1.update(msg)
-dgst=sha1.digest()
-
-priv=RSA.load_key('rsa.priv.pem')
-pub=RSA.load_pub_key('rsa.pub.pem')
-
-def test_encrypt(padding):
- print 'testing public-key encryption:', padding
- padding=eval('RSA.'+padding)
- ctxt=pub.public_encrypt(dgst, padding)
- ptxt=priv.private_decrypt(ctxt, padding)
- if ptxt!=dgst:
- print 'public_encrypt -> private_decrypt: not ok'
-
-def test_sign(padding):
- print 'testing private-key signing:', padding
- padding=eval('RSA.'+padding)
- ctxt=priv.private_encrypt(dgst, padding)
- ptxt=pub.public_decrypt(ctxt, padding)
- if ptxt!=dgst:
- print 'private_decrypt -> public_encrypt: not ok'
-
-def test0():
- print 'testing misc.'
- print `pub.e`, `pub.n`
- print `priv.e`, `priv.n`
-
-if __name__=='__main__':
- Rand.load_file('randpool.dat', -1)
- test_encrypt('pkcs1_padding')
- test_encrypt('pkcs1_oaep_padding')
- #test_encrypt('sslv23_padding')
- test_sign('pkcs1_padding')
- Rand.save_file('randpool.dat')
-
diff --git a/demo/smime.howto/README b/demo/smime.howto/README
deleted file mode 100644
index 2b494d7..0000000
--- a/demo/smime.howto/README
+++ /dev/null
@@ -1,5 +0,0 @@
- 01 Apr 2001
--------------
-
-These are the example programs from the HOWTO.
-
diff --git a/demo/smime.howto/decrypt.py b/demo/smime.howto/decrypt.py
deleted file mode 100644
index 617f4ab..0000000
--- a/demo/smime.howto/decrypt.py
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/usr/bin/env python
-
-"""S/MIME HOWTO demo program.
-
-Copyright (c) 1999-2001 Ng Pheng Siong. All rights reserved."""
-
-from M2Crypto import BIO, SMIME, X509
-
-# Instantiate an SMIME object.
-s = SMIME.SMIME()
-
-# Load private key and cert.
-s.load_key('recipient_key.pem', 'recipient.pem')
-
-# Load the encrypted data.
-p7, data = SMIME.smime_load_pkcs7('encrypt.p7')
-
-# Decrypt p7.
-out = s.decrypt(p7)
-
-print out
-
diff --git a/demo/smime.howto/dv.py b/demo/smime.howto/dv.py
deleted file mode 100644
index 94223a8..0000000
--- a/demo/smime.howto/dv.py
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/usr/bin/env python
-
-"""S/MIME HOWTO demo program.
-
-Copyright (c) 1999-2001 Ng Pheng Siong. All rights reserved."""
-
-from M2Crypto import BIO, SMIME, X509
-
-# Instantiate an SMIME object.
-s = SMIME.SMIME()
-
-# Load private key and cert.
-s.load_key('recipient_key.pem', 'recipient.pem')
-
-# Load the signed/encrypted data.
-p7, data = SMIME.smime_load_pkcs7('se.p7')
-
-# After the above step, 'data' == None.
-# Decrypt p7. 'out' now contains a PKCS #7 signed blob.
-out = s.decrypt(p7)
-
-# Load the signer's cert.
-x509 = X509.load_cert('signer.pem')
-sk = X509.X509_Stack()
-sk.push(x509)
-s.set_x509_stack(sk)
-
-# Load the signer's CA cert. In this case, because the signer's
-# cert is self-signed, it is the signer's cert itself.
-st = X509.X509_Store()
-st.load_info('signer.pem')
-s.set_x509_store(st)
-
-# Recall 'out' contains a PKCS #7 blob.
-# Transform 'out'; verify the resulting PKCS #7 blob.
-p7_bio = BIO.MemoryBuffer(out)
-p7, data = SMIME.smime_load_pkcs7_bio(p7_bio)
-v = s.verify(p7)
-
-print v
-
diff --git a/demo/smime.howto/encrypt.p7 b/demo/smime.howto/encrypt.p7
deleted file mode 100644
index eb8b8a5..0000000
--- a/demo/smime.howto/encrypt.p7
+++ /dev/null
@@ -1,17 +0,0 @@
-From: sender@example.dom
-To: recipient@example.dom
-MIME-Version: 1.0
-Content-Disposition: attachment; filename="smime.p7m"
-Content-Type: application/x-pkcs7-mime; name="smime.p7m"
-Content-Transfer-Encoding: base64
-
-MIIBVwYJKoZIhvcNAQcDoIIBSDCCAUQCAQAxggEAMIH9AgEAMGYwYTELMAkGA1UE
-BhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRkwFwYDVQQDExBTL01JTUUgUmVjaXBp
-ZW50MSQwIgYJKoZIhvcNAQkBFhVyZWNpcGllbnRAZXhhbXBsZS5kb20CAQAwDQYJ
-KoZIhvcNAQEBBQAEgYCdBULuQ/kfjgk17dMwBHdY+vXfqR/B+vJnF0gXhK6gc5d4
-gCkRefEyVu7lGAD2MOdD0cOLFvHdmGHFJqyJ8T+A1mmqrxMAiJImtqN586YnoTUb
-Cw5FaMEd20d6hpGeEVBFHkam0vQKdR1GLG1VPiFn+ytB06g7NNphsI5/uFGyLDA7
-BgkqhkiG9w0BBwEwFAYIKoZIhvcNAwcECPfuW3hoPVr0gBiA4CiFG4m74CT4wHPu
-q1fhEkG3zjraxn4=
-
-
diff --git a/demo/smime.howto/encrypt.py b/demo/smime.howto/encrypt.py
deleted file mode 100644
index ae37526..0000000
--- a/demo/smime.howto/encrypt.py
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/usr/bin/env python
-
-"""S/MIME HOWTO demo program.
-
-Copyright (c) 1999-2001 Ng Pheng Siong. All rights reserved."""
-
-from M2Crypto import BIO, Rand, SMIME, X509
-
-def makebuf(text):
- return BIO.MemoryBuffer(text)
-
-# Make a MemoryBuffer of the message.
-buf = makebuf('a sign of our times')
-
-# Seed the PRNG.
-Rand.load_file('randpool.dat', -1)
-
-# Instantiate an SMIME object.
-s = SMIME.SMIME()
-
-# Load target cert to encrypt to.
-x509 = X509.load_cert('recipient.pem')
-sk = X509.X509_Stack()
-sk.push(x509)
-s.set_x509_stack(sk)
-
-# Set cipher: 3-key triple-DES in CBC mode.
-s.set_cipher(SMIME.Cipher('des_ede3_cbc'))
-
-# Encrypt the buffer.
-p7 = s.encrypt(buf)
-
-# Output p7 in mail-friendly format.
-out = BIO.MemoryBuffer()
-out.write('From: sender@example.dom\n')
-out.write('To: recipient@example.dom\n')
-out.write('Subject: M2Crypto S/MIME testing\n')
-s.write(out, p7)
-
-print out.read()
-
-# Save the PRNG's state.
-Rand.save_file('randpool.dat')
-
diff --git a/demo/smime.howto/recipient.pem b/demo/smime.howto/recipient.pem
deleted file mode 100644
index 78b6c14..0000000
--- a/demo/smime.howto/recipient.pem
+++ /dev/null
@@ -1,18 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIC9zCCAmCgAwIBAgIBADANBgkqhkiG9w0BAQQFADBhMQswCQYDVQQGEwJTRzER
-MA8GA1UEChMITTJDcnlwdG8xGTAXBgNVBAMTEFMvTUlNRSBSZWNpcGllbnQxJDAi
-BgkqhkiG9w0BCQEWFXJlY2lwaWVudEBleGFtcGxlLmRvbTAeFw0wMTAzMzExMTQy
-MTVaFw0wMjAzMzExMTQyMTVaMGExCzAJBgNVBAYTAlNHMREwDwYDVQQKEwhNMkNy
-eXB0bzEZMBcGA1UEAxMQUy9NSU1FIFJlY2lwaWVudDEkMCIGCSqGSIb3DQEJARYV
-cmVjaXBpZW50QGV4YW1wbGUuZG9tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
-gQDQwLwQSshbTn/GUZXnZUQEUDc61OUd+qcPpHfi76Y7ar+2NwsalQ3bu2i7edEK
-IZZWMFRnrOwE9PhmJHJIzfYDswgpHWtRy0P/Oyzt5kLBjvJYuMIqu8gZtWFz0G28
-Q8tGvIuPdWba+9TT3LOv4CXNF1V0k0KgAPd1Uq2FUcBa2QIDAQABo4G+MIG7MB0G
-A1UdDgQWBBQe7b4CDEBuMJyiscil27YBdZBr9zCBiwYDVR0jBIGDMIGAgBQe7b4C
-DEBuMJyiscil27YBdZBr96FlpGMwYTELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0y
-Q3J5cHRvMRkwFwYDVQQDExBTL01JTUUgUmVjaXBpZW50MSQwIgYJKoZIhvcNAQkB
-FhVyZWNpcGllbnRAZXhhbXBsZS5kb22CAQAwDAYDVR0TBAUwAwEB/zANBgkqhkiG
-9w0BAQQFAAOBgQAJbQXzP7AK9u2kyvl8oeZAeJQDRsip4PVMkYd64HW3Hq/9ud3g
-hj/laeUyfcga+c1c1yPUug5Ab+loeHhEEKsL9LqYFXzpFU1lXaID02zcqG7g3PWe
-r9RKsUqrn4ZbRQ+clidnIx4nYLuG6CPQ6ME/uFrYHMsmQEO/+KoJONf/cg==
------END CERTIFICATE-----
diff --git a/demo/smime.howto/recipient_key.pem b/demo/smime.howto/recipient_key.pem
deleted file mode 100644
index 0cb61f6..0000000
--- a/demo/smime.howto/recipient_key.pem
+++ /dev/null
@@ -1,15 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIICXAIBAAKBgQDQwLwQSshbTn/GUZXnZUQEUDc61OUd+qcPpHfi76Y7ar+2Nwsa
-lQ3bu2i7edEKIZZWMFRnrOwE9PhmJHJIzfYDswgpHWtRy0P/Oyzt5kLBjvJYuMIq
-u8gZtWFz0G28Q8tGvIuPdWba+9TT3LOv4CXNF1V0k0KgAPd1Uq2FUcBa2QIDAQAB
-AoGAVOMrFozycH65YtHmXVRGlmJwMxJDoS8+JBRDVBsTw/Gix9wWPdcC7amF60ac
-BLynv6Cjkg01ZMahBBgqCQUH1rii6Kg20MJJtpqvt1X+CAZkytVsQqwutSQXHj+g
-TzZVDxQiuPKMyVhKTSVqutqs2EyFgSKcYuodfms5xDk2EyECQQD6vnEAl2PHBoia
-5wrauujbWTM6H5oioWvJgLaUNgUhJ86/Y+ewKoGxLdYaxx99KhKxN/04i2chIHk0
-c53THOt9AkEA1SD1Rdm93FUMEor+BYEQgiN/4pWnSIsgUjyqV7lPv9QegdDTbVfm
-WuPNev6Z+qo9mpDWbvhCZhH159q7uGfzjQJAe88dLRWThuqK+TGsAmTYJbbdvI1u
-JjteZZjQjk4+KijlxUsnU60pbLsdRQudWMg1gpwKxKjQu2K1dljATUWyYQJARI83
-l2K1+py5J3XixS6BevukdeUiTOnEWe/98/4+szyvG59rg+8UwQQq43fnXIVLD9+r
-u0LNSTxZ2F26qVV3OQJBAIBG0Gv9C44UlCPiJhmMqcpzexX20erOEGu+UiCUhHAC
-ZdWdFaD2dlmk0O/E82LxPPivkGv5DtkNpzCl+3Vo+kI=
------END RSA PRIVATE KEY-----
diff --git a/demo/smime.howto/se.p7 b/demo/smime.howto/se.p7
deleted file mode 100644
index df4af0f..0000000
--- a/demo/smime.howto/se.p7
+++ /dev/null
@@ -1,56 +0,0 @@
-From: sender@example.dom
-To: recipient@example.dom
-MIME-Version: 1.0
-Content-Disposition: attachment; filename="smime.p7m"
-Content-Type: application/x-pkcs7-mime; name="smime.p7m"
-Content-Transfer-Encoding: base64
-
-MIIIwwYJKoZIhvcNAQcDoIIItDCCCLACAQAxggEAMIH9AgEAMGYwYTELMAkGA1UE
-BhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRkwFwYDVQQDExBTL01JTUUgUmVjaXBp
-ZW50MSQwIgYJKoZIhvcNAQkBFhVyZWNpcGllbnRAZXhhbXBsZS5kb20CAQAwDQYJ
-KoZIhvcNAQEBBQAEgYCn4qL7Z8QlmVEMbO2zU5RUtBqw1cYPzxd/4ZF9H+djlL7f
-EDIYHidvTBksXwcBXSTxsKsSusGF95NtwaZf4D3eiR1ChdkeXaiWCUPAQr0Mw4+A
-EJa9eGBuLH+LXH0pDN5OhYb8hsL/EcV2OpOEjOe4aM/u3Ot5u1kK1582oikhCDCC
-B6UGCSqGSIb3DQEHATAUBggqhkiG9w0DBwQImrxQEPwEHHeAggeACeVVKqKjySva
-zos9ahumXC7bMIcfesxQF0L2CcR4wQtnwuzESXNAnQabtlN6cXKLNFGWmilztaEZ
-zHFEEDqtqEeP5BmEkjnNFakhr49yrK/SZpVYYScsUHNcMDOwXMPKKxkk3qOKUlqQ
-m+WvvyaWwZ8kbZNkO+YY4BpOVDEQRH3HG7ngtLP3y/LSx7kcpTl0wi8On9pigZ46
-4u9Odac7bNh5FVMOFiXbIXMuFJ1epy9agtX09eOK9JC9ZHnIl9IgGEL833d+l8MQ
-OdeKqvSTnNf0JKZs52uzUqluI4pywNIiJT1OeU3Ch2vdfvcOcTQohGhIEUb7NWEn
-Z02pBiZ0Tzg/T/sr8B60rPcRSSnGYAfQZPS86QgAMIEaqoHQVox+Qgigr2dynvWQ
-KO0ny4iJLhtRoxD7W7LxaZat6fWvbC4WXKwgis2UJnEWwe8DsoZ3XEnYid3ke2/F
-2+ejHtugd6E4o05vRAO/pOVZUbc4mbZm2zoPgzwm0M9GqQcTOVy1tkpEc6mhrH6y
-AjbSeP/1YkZakDB9bl+TCw24lRquIUbGyNI9GM+oFYyciIYu6RfPhfoh9YU9wqS7
-KcnHk3WG5AxJZ6tZAsz/i/DhtD5zxFsldKMy5OaeBjh6txmQ0aHXPYLmIEdxPSa0
-BnrAeTam/1iOboXT1O2GkPiLJAJjWRAvK/QXsxJMGtSYEnwT+kkAZtU75FOyBuxI
-gQOHO98CGGEy5CI/e/Th+1yMqyiimqDmfVktN4KgzZXbjyv4xzpgNE6o85v7fUg1
-1WoTF38GmbcIbVfBHaRwdWmSxeAsFltHb38u7pP8D24+3hC5OKsNLXxGFJhfp3HW
-4A51fNAi3CaWIh9aZb+SYof8MmtZp9mjL0dKB1OZTyTXqkQ/yU3PIHE+ytM6men3
-tzQefsJlnk/t/zBhxdZo+yCna/ZJe3KmrShoD4ob9prWs48ohDhG7cY4vfW0NuxX
-Im30y+JZe3A0Ktamq1VmpWDhW6Emo+Wk04nDTtU2AcClMoKWgcvIUp0HAgWDhrrx
-6Rf1CiRZngJuCEheCMAvKT8IgcTt7vWRUpRoJrhlKR23GKEVA6T6DF9q8L4F82ul
-yzQ2kdec6s8bD1EQT7e0QcIqEn8RNoSa2aLxRG2JBWqv0AZflKyCjwx35mCv7AmN
-17zPENkGdDgE9xcEEdEe4rkigJ8uaYauEofQsDgSHWQ2oAk91g5FLNImsRn3Z7uy
-qtjc9JTXOymowDXbdYebqNZTxJhXDUnrbawWqyCgohtytnVdW61wKsXV3oEp7PZc
-aL0ZZvVkVkUofaf/2gIGvQ9WnTfpUJ/bEAr0hDdtnmg1QPVu/v/l9eXAnbkh71GX
-OdFpIfvf0zVm/tn/7Vi+HfHRjupHSJBO+bIVQBt3uMLlovU48axSRXUnpIXdHYwN
-3b/MabDQnzV1qvhGTRRj+o39RbDrueNSpXIleA7SzFqZO2LnaDZ/FKbca1CAL+Iy
-KsByJUz7cReE4gU8N3SKKv7ivaibmFG63cvwA1GMUsWZgIYD/xy2nCB4jPCodiFB
-wWUgAblxMcaidKox6Z1zK9oZA62QIX4XGl+0mE/xwxmt2fE5lSBhY8q7N7MvS/Nv
-RDLEgULBMRvcjgIwL4MZZYkUl7oAqQ2aHL45j7vp7U9vIK2j8bcp9v5K3jeccENJ
-qYn/35awflQ66lrrSUWH3evs5IO0FhKSn9c1GGTaZDA5TABzJKySmvphyAh1m24W
-ylzgXQkp/Zi2oWajZ50txiIBgB14dWhuCS4vcwkWjyKur/yGpkY5DILSHZyguqDk
-cwOgKRrC5myL7Zr0/5CwN6sBofOGb2Qhcx+4Cg6DnPwyMXKVTKYnXPvcTj2KvVW+
-qzTIhur0rwC13lK1+sMs/+Esel99fohCTz7+tiebqkPaFcnx8hUgMrllYfGCMXQ/
-hiY+1BVEyDWHWOjj5lxPwzNtPqbVz3uA//Rut/BozOpD/hEjCMVRbadSFZTM+x6+
-nr39DHGZsOn3XSEZSU2C93v77Ls/vdJi6IdJTwCD/yoEK1OY60ciBvCpJ/lLVSQl
-PAdozKEAjqP+fX95MeAENtysXTsqbWawWeS7H/zXmwpWn3LnSJ48pymvwV6nJrYL
-YXHaiuMGIZim9jOT04AyK5LPZ2E9omwVFaHgi10iRigc9y5MixHvN9P5WQ9nP+/c
-kflFQXuph3RqBEWfG8vPFKFvqVQTN0lxUXoOXkKhZ7/Doe3orbfRw/xZUyKnfrzs
-O7MU7PVAubVNUXjKHs2UCYtVMUH0tSuDMkuWUd6d6cmkPht86KvopoXha6zRw1pu
-SE/nGq/o6bproWMPRfoCCN+xow9jeipTD7xkYbiw1+g/9hYaqUYm7QUbuYOrBtLe
-RAlm69yornWrh7+n3GXUSCFQz3nj6sE4JjXciQzhUfEFrCn+qDrgaviFKe0yVYbQ
-LRr3qtSM0gTVWn2XnOlnNuLdvx2UWV7KNNPrnRIoK3KvnfOJTl/RzkT1g+HaEvC3
-MFNlSJNXN6Gavdr8pAdtnVGivdnM1iw0yFKuuzoF1F+cuN8rGMmp
-
-
diff --git a/demo/smime.howto/se.py b/demo/smime.howto/se.py
deleted file mode 100644
index cd4df60..0000000
--- a/demo/smime.howto/se.py
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/usr/bin/env python
-
-"""S/MIME HOWTO demo program.
-
-Copyright (c) 1999-2001 Ng Pheng Siong. All rights reserved."""
-
-from M2Crypto import BIO, Rand, SMIME, X509
-
-def makebuf(text):
- return BIO.MemoryBuffer(text)
-
-# Make a MemoryBuffer of the message.
-buf = makebuf('a sign of our times')
-
-# Seed the PRNG.
-Rand.load_file('randpool.dat', -1)
-
-# Instantiate an SMIME object.
-s = SMIME.SMIME()
-
-# Load signer's key and cert. Sign the buffer.
-s.load_key('signer_key.pem', 'signer.pem')
-p7 = s.sign(buf)
-
-# Load target cert to encrypt the signed message to.
-x509 = X509.load_cert('recipient.pem')
-sk = X509.X509_Stack()
-sk.push(x509)
-s.set_x509_stack(sk)
-
-# Set cipher: 3-key triple-DES in CBC mode.
-s.set_cipher(SMIME.Cipher('des_ede3_cbc'))
-
-# Create a temporary buffer.
-tmp = BIO.MemoryBuffer()
-
-# Write the signed message into the temporary buffer.
-s.write(tmp, p7)
-
-# Encrypt the temporary buffer.
-p7 = s.encrypt(tmp)
-
-# Output p7 in mail-friendly format.
-out = BIO.MemoryBuffer()
-out.write('From: sender@example.dom\n')
-out.write('To: recipient@example.dom\n')
-out.write('Subject: M2Crypto S/MIME testing\n')
-s.write(out, p7)
-
-print out.read()
-
-# Save the PRNG's state.
-Rand.save_file('randpool.dat')
-
diff --git a/demo/smime.howto/sendsmime.py b/demo/smime.howto/sendsmime.py
deleted file mode 100644
index 6df9a89..0000000
--- a/demo/smime.howto/sendsmime.py
+++ /dev/null
@@ -1,82 +0,0 @@
-#!/usr/bin/env python
-
-"""S/MIME sender.
-
-Copyright (c) 1999-2001 Ng Pheng Siong. All rights reserved."""
-
-from M2Crypto import BIO, Rand, SMIME, X509
-import smtplib, string, sys
-
-def sendsmime(from_addr, to_addrs, subject, msg, from_key, from_cert=None, to_certs=None, smtpd='localhost'):
-
- msg_bio = BIO.MemoryBuffer(msg)
- sign = from_key
- encrypt = to_certs
-
- s = SMIME.SMIME()
- if sign:
- s.load_key(from_key, from_cert)
- p7 = s.sign(msg_bio, flags=SMIME.PKCS7_TEXT)
- msg_bio = BIO.MemoryBuffer(msg) # Recreate coz sign() has consumed it.
-
- if encrypt:
- sk = X509.X509_Stack()
- for x in to_certs:
- sk.push(X509.load_cert(x))
- s.set_x509_stack(sk)
- s.set_cipher(SMIME.Cipher('rc2_40_cbc'))
- tmp_bio = BIO.MemoryBuffer()
- if sign:
- s.write(tmp_bio, p7)
- else:
- tmp_bio.write(msg)
- p7 = s.encrypt(tmp_bio)
-
- out = BIO.MemoryBuffer()
- out.write('From: %s\r\n' % from_addr)
- out.write('To: %s\r\n' % string.join(to_addrs, ", "))
- out.write('Subject: %s\r\n' % subject)
- if encrypt:
- s.write(out, p7)
- else:
- if sign:
- s.write(out, p7, msg_bio, SMIME.PKCS7_TEXT)
- else:
- out.write('\r\n')
- out.write(msg)
- out.close()
-
- smtp = smtplib.SMTP()
- smtp.connect(smtpd)
- smtp.sendmail(from_addr, to_addrs, out.read())
- smtp.quit()
-
- # XXX Cleanup the stack and store.
-
-
-msg = """
-S/MIME - Secure Multipurpose Internet Mail Extensions [RFC 2311, RFC 2312] -
-provides a consistent way to send and receive secure MIME data. Based on the
-popular Internet MIME standard, S/MIME provides the following cryptographic
-security services for electronic messaging applications - authentication,
-message integrity and non-repudiation of origin (using digital signatures)
-and privacy and data security (using encryption).
-
-S/MIME is built on the PKCS #7 standard. [PKCS7]
-
-S/MIME is implemented in Netscape Messenger and Microsoft Outlook.
-"""
-
-
-if __name__ == '__main__':
- Rand.load_file('../randpool.dat', -1)
- sendsmime(from_addr = 'ngps@post1.com',
- to_addrs = ['popuser@nova.dyndns.org'],
- subject = 'S/MIME testing',
- msg = msg,
- #from_key = 'signer.pem',
- from_key = None,
- #to_certs = None)
- to_certs = ['recipient.pem'])
- Rand.save_file('../randpool.dat')
-
diff --git a/demo/smime.howto/sign.p7 b/demo/smime.howto/sign.p7
deleted file mode 100644
index 7a39eaa..0000000
--- a/demo/smime.howto/sign.p7
+++ /dev/null
@@ -1,46 +0,0 @@
-From: sender@example.dom
-To: recipient@example.dom
-Subject: M2Crypto S/MIME testing
-MIME-Version: 1.0
-Content-Type: multipart/signed ; protocol="application/x-pkcs7-signature" ; micalg=sha1 ; boundary="----2221986D060512556B8AC18AAA106F39"
-
-This is an S/MIME signed message
-
-------2221986D060512556B8AC18AAA106F39
-a sign of our times
-------2221986D060512556B8AC18AAA106F39
-Content-Type: application/x-pkcs7-signature; name="smime.p7s"
-Content-Transfer-Encoding: base64
-Content-Disposition: attachment; filename="smime.p7s"
-
-MIIE8AYJKoZIhvcNAQcCoIIE4TCCBN0CAQExCzAJBgUrDgMCGgUAMCIGCSqGSIb3
-DQEHAaAVBBNhIHNpZ24gb2Ygb3VyIHRpbWVzoIIC5zCCAuMwggJMoAMCAQICAQAw
-DQYJKoZIhvcNAQEEBQAwWzELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRv
-MRYwFAYDVQQDEw1TL01JTUUgU2VuZGVyMSEwHwYJKoZIhvcNAQkBFhJzZW5kZXJA
-ZXhhbXBsZS5kb20wHhcNMDEwMzMxMTE0MDMzWhcNMDIwMzMxMTE0MDMzWjBbMQsw
-CQYDVQQGEwJTRzERMA8GA1UEChMITTJDcnlwdG8xFjAUBgNVBAMTDVMvTUlNRSBT
-ZW5kZXIxITAfBgkqhkiG9w0BCQEWEnNlbmRlckBleGFtcGxlLmRvbTCBnzANBgkq
-hkiG9w0BAQEFAAOBjQAwgYkCgYEA5c5Tj1CHTSOxa1q2q0FYiwMWYHptJpJcvtZm
-UwrgU5sHrA8OnCM0cDXEj0KPf3cfNjHffB8HWMzI4UEgNmFXQNsxoGZ+iqwxLlNj
-y9Mh7eFW/Bjq5hNXbouSlQ0rWBRkoxV64y+t6lQehb32WfYXQbKFxFJSXzSxOx3R
-8YhSPd0CAwEAAaOBtjCBszAdBgNVHQ4EFgQUXOyolL1t4jaBwZFRM7MS8nBLzUow
-gYMGA1UdIwR8MHqAFFzsqJS9beI2gcGRUTOzEvJwS81KoV+kXTBbMQswCQYDVQQG
-EwJTRzERMA8GA1UEChMITTJDcnlwdG8xFjAUBgNVBAMTDVMvTUlNRSBTZW5kZXIx
-ITAfBgkqhkiG9w0BCQEWEnNlbmRlckBleGFtcGxlLmRvbYIBADAMBgNVHRMEBTAD
-AQH/MA0GCSqGSIb3DQEBBAUAA4GBAHo3DrCHR86fSTVAvfiXdSswWqKtCEhUHRdC
-TLFGl4hDk2GyZxaFuqZwiURz/H7nMicymI2wkz8H/wyHFg8G3BIehURpj2v/ZWXY
-eovbgS7EZALVVkDj4hNl/IIHWd6Gtv1UODf7URbxtl3hQ9/eTWITrefT1heuPnar
-8czydsOLMYIBujCCAbYCAQEwYDBbMQswCQYDVQQGEwJTRzERMA8GA1UEChMITTJD
-cnlwdG8xFjAUBgNVBAMTDVMvTUlNRSBTZW5kZXIxITAfBgkqhkiG9w0BCQEWEnNl
-bmRlckBleGFtcGxlLmRvbQIBADAJBgUrDgMCGgUAoIGxMBgGCSqGSIb3DQEJAzEL
-BgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTAxMDMzMTE0NTgyMVowIwYJKoZI
-hvcNAQkEMRYEFOoeRUd8ExIYXfQq8BTFuKWrSP3iMFIGCSqGSIb3DQEJDzFFMEMw
-CgYIKoZIhvcNAwcwDgYIKoZIhvcNAwICAgCAMA0GCCqGSIb3DQMCAgFAMAcGBSsO
-AwIHMA0GCCqGSIb3DQMCAgEoMA0GCSqGSIb3DQEBAQUABIGAKMjEdSteeZg9ji1C
-Y2r6zuxDVVftpSLy9ZhYOblGYY2b3PhzI0XytdUoLdb+GlPImqE/F5FJCPvTAovq
-uLElbx/FuijA2ly7PQF2ekyFJ0EhvNWT1gcLhi1m0W+Hk/jgCQx7YRojT53Pa9fj
-zuHk7ZkSKe5rZlOJvPJtYREnvD8=
-
-------2221986D060512556B8AC18AAA106F39--
-
-
diff --git a/demo/smime.howto/sign.py b/demo/smime.howto/sign.py
deleted file mode 100644
index 38c4bab..0000000
--- a/demo/smime.howto/sign.py
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/usr/bin/env python
-
-"""S/MIME HOWTO demo program.
-
-Copyright (c) 1999-2001 Ng Pheng Siong. All rights reserved."""
-
-from M2Crypto import BIO, Rand, SMIME
-
-def makebuf(text):
- return BIO.MemoryBuffer(text)
-
-# Make a MemoryBuffer of the message.
-buf = makebuf('a sign of our times')
-
-# Seed the PRNG.
-Rand.load_file('randpool.dat', -1)
-
-# Instantiate an SMIME object; set it up; sign the buffer.
-s = SMIME.SMIME()
-s.load_key('signer_key.pem', 'signer.pem')
-p7 = s.sign(buf)
-
-# Recreate buf.
-buf = makebuf('a sign of our times')
-
-# Output p7 in mail-friendly format.
-out = BIO.MemoryBuffer()
-out.write('From: sender@example.dom\n')
-out.write('To: recipient@example.dom\n')
-out.write('Subject: M2Crypto S/MIME testing\n')
-s.write(out, p7, buf)
-
-print out.read()
-
-# Save the PRNG's state.
-Rand.save_file('randpool.dat')
-
diff --git a/demo/smime.howto/signer.pem b/demo/smime.howto/signer.pem
deleted file mode 100644
index 9189aaa..0000000
--- a/demo/smime.howto/signer.pem
+++ /dev/null
@@ -1,18 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIC4zCCAkygAwIBAgIBADANBgkqhkiG9w0BAQQFADBbMQswCQYDVQQGEwJTRzER
-MA8GA1UEChMITTJDcnlwdG8xFjAUBgNVBAMTDVMvTUlNRSBTZW5kZXIxITAfBgkq
-hkiG9w0BCQEWEnNlbmRlckBleGFtcGxlLmRvbTAeFw0wMTAzMzExMTQwMzNaFw0w
-MjAzMzExMTQwMzNaMFsxCzAJBgNVBAYTAlNHMREwDwYDVQQKEwhNMkNyeXB0bzEW
-MBQGA1UEAxMNUy9NSU1FIFNlbmRlcjEhMB8GCSqGSIb3DQEJARYSc2VuZGVyQGV4
-YW1wbGUuZG9tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDlzlOPUIdNI7Fr
-WrarQViLAxZgem0mkly+1mZTCuBTmwesDw6cIzRwNcSPQo9/dx82Md98HwdYzMjh
-QSA2YVdA2zGgZn6KrDEuU2PL0yHt4Vb8GOrmE1dui5KVDStYFGSjFXrjL63qVB6F
-vfZZ9hdBsoXEUlJfNLE7HdHxiFI93QIDAQABo4G2MIGzMB0GA1UdDgQWBBRc7KiU
-vW3iNoHBkVEzsxLycEvNSjCBgwYDVR0jBHwweoAUXOyolL1t4jaBwZFRM7MS8nBL
-zUqhX6RdMFsxCzAJBgNVBAYTAlNHMREwDwYDVQQKEwhNMkNyeXB0bzEWMBQGA1UE
-AxMNUy9NSU1FIFNlbmRlcjEhMB8GCSqGSIb3DQEJARYSc2VuZGVyQGV4YW1wbGUu
-ZG9tggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAejcOsIdHzp9J
-NUC9+Jd1KzBaoq0ISFQdF0JMsUaXiEOTYbJnFoW6pnCJRHP8fucyJzKYjbCTPwf/
-DIcWDwbcEh6FRGmPa/9lZdh6i9uBLsRkAtVWQOPiE2X8ggdZ3oa2/VQ4N/tRFvG2
-XeFD395NYhOt59PWF64+dqvxzPJ2w4s=
------END CERTIFICATE-----
diff --git a/demo/smime.howto/signer_key.pem b/demo/smime.howto/signer_key.pem
deleted file mode 100644
index ad15a87..0000000
--- a/demo/smime.howto/signer_key.pem
+++ /dev/null
@@ -1,15 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIICXgIBAAKBgQDlzlOPUIdNI7FrWrarQViLAxZgem0mkly+1mZTCuBTmwesDw6c
-IzRwNcSPQo9/dx82Md98HwdYzMjhQSA2YVdA2zGgZn6KrDEuU2PL0yHt4Vb8GOrm
-E1dui5KVDStYFGSjFXrjL63qVB6FvfZZ9hdBsoXEUlJfNLE7HdHxiFI93QIDAQAB
-AoGBALqc4OgZSbYPjQyTfpD1IJTKLgqsgCR5aE0kR7WZuG7MDt/e3ktWn0ebsgFv
-2J12u2bD+yqM++dVbK7WtvTR+QpMhb/0XMhXNsvmn5gOLdKlJjS0RXDDs2DzIS6p
-JNzAmn5zqTVteZAMDLk7ygkO++iGzwRz713ZgxRaKr5YWiLVAkEA+3ev1TTXNEOk
-wQ9fbukMrfUXesqwgrx9VZ1z1X5we42RIIMTYI1edpcujXYvgS3/jdzAWDS1Nqta
-9QB3uy91ywJBAOnysIIQhHn+4zvaOA5vh85WczPhN9C+yRmV70eyL9h+aThUFS4c
-kg2jQOLp8MaxAkmk4xRbZBgehjmDr45b5fcCQQDpIGNlYFBmhpN129+YffugRgjX
-cJNFEKONPKRHd6mmEW9K2dmb+FNr0+p3gOq3csJpbQ7wdyTMov13B1D4ux4TAkAR
-URB1oCleKlrBjGaH0wOXZ1jBp1MNVYHnLez3Pp5CBSFetQKYVi8NaV8dLLnQyztj
-Hhxc3mLrUh8XVMMC45SDAkEAxRCKmkneLceIdwixLIUF0zr0OzJtgyhxMxvHu3ET
-gJcZqNN0y3EgPwcNihpBw7rjpp5e5sjlRNVqLqn8a5/Fog==
------END RSA PRIVATE KEY-----
diff --git a/demo/smime.howto/verify.py b/demo/smime.howto/verify.py
deleted file mode 100644
index 9430add..0000000
--- a/demo/smime.howto/verify.py
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/usr/bin/env python
-
-"""S/MIME HOWTO demo program.
-
-Copyright (c) 1999-2001 Ng Pheng Siong. All rights reserved."""
-
-from M2Crypto import SMIME, X509
-
-# Instantiate an SMIME object.
-s = SMIME.SMIME()
-
-# Load the signer's cert.
-x509 = X509.load_cert('signer.pem')
-sk = X509.X509_Stack()
-sk.push(x509)
-s.set_x509_stack(sk)
-
-# Load the signer's CA cert. In this case, because the signer's
-# cert is self-signed, it is the signer's cert itself.
-st = X509.X509_Store()
-st.load_info('signer.pem')
-s.set_x509_store(st)
-
-# Load the data, verify it.
-p7, data = SMIME.smime_load_pkcs7('sign.p7')
-v = s.verify(p7)
-print v
-print data
-print data.read()
-
diff --git a/demo/smime/README b/demo/smime/README
deleted file mode 100644
index 736e632..0000000
--- a/demo/smime/README
+++ /dev/null
@@ -1,54 +0,0 @@
- 29 Nov 2000
--------------
-- test.py works.
-
-- makesmime.py is sendsmime.py modified to not send
- SMTP, because I do not now have an SMTP server handy.
-
-- sendsmime.py should still work, because makesmime.py
- does.
-
-- unsmime.py doesn't work, possibly because the certificates
- used to generate the tested PKCS7 objects are no longer
- available.
-
-
-
- 20 Nov 2000
--------------
-
-This directory contains various programs and supporting files
-demonstrating M2Crypto's S/MIME functionality.
-
-- test.py exercises the various S/MIME functionality.
-- sendsmime.py (optionally) signs and/or encrypts a message,
- then sends the output via SMTP.
-- makesmime.py is exactly like sendsmime.py, except it writes
- its output to sys.stdout.
-- unsmime.py decrypts and verifies an S/MIME SignedAndEnveloped
- message. It handles the S/MIME output of Netscape Messenger
- successfully.
-
-- ca.pem is M2Crypto's test CA certificate.
-- client.pem and client2.pem contain user certificates and their
- corresponding private keys.
-
-- clear.p7 is a clear-signed S/MIME message.
-- opaque.p7 is a signed S/MIME message.
-- ns.p7 is a clear-signed S/MIME message produced by Messenger.
-- ns.se.p7 is a signed-then-encrypted S/MIME message produced
- by Messenger.
-- m2.se.p7 is a signed-then-encrypted S/MIME message produced
- by sendsmime.py.
-
-
-I tested with export and strong versions of Netscape Communicator
-4.7x.
-
-I have also done some interoperability testing with Sampo Kellomaki's
-smime tool.
-
-I am interested in interoperability testing with Outlook and other
-S/MIME tools. Write me <ngps@post1.com> if you want to collaborate.
-
-
diff --git a/demo/smime/ca.pem b/demo/smime/ca.pem
deleted file mode 100644
index b7c84a1..0000000
--- a/demo/smime/ca.pem
+++ /dev/null
@@ -1,20 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDWTCCAsKgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBgDELMAkGA1UEBhMCU0cx
-ETAPBgNVBAoTCE0yQ3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UE
-AxMbTTJDcnlwdG8gQ2VydGlmaWNhdGUgTWFzdGVyMSIwIAYJKoZIhvcNAQkBFhNu
-Z3BzQG5ldG1lbWV0aWMuY29tMB4XDTAxMTIxNTA1NTU0NloXDTA0MTIxNDA1NTU0
-NlowgYAxCzAJBgNVBAYTAlNHMREwDwYDVQQKEwhNMkNyeXB0bzEUMBIGA1UECxML
-TTJDcnlwdG8gQ0ExJDAiBgNVBAMTG00yQ3J5cHRvIENlcnRpZmljYXRlIE1hc3Rl
-cjEiMCAGCSqGSIb3DQEJARYTbmdwc0BuZXRtZW1ldGljLmNvbTCBnzANBgkqhkiG
-9w0BAQEFAAOBjQAwgYkCgYEAx8soJbS719LHK62VVVIQeC3oW0HvFArwPnA0LuEK
-q+LaqMOJg1rS7hvFdX03diV+XJw7cC0iECZYJNG4ii1xbY6KRmufkInaAwm54E3N
-e+YYVocaqUkcN6xVf6fwnLfPXbpFS/K2Umg11ObKMmi80JmiIdjcjRRCQZC7g1hf
-q+kCAwEAAaOB4DCB3TAdBgNVHQ4EFgQU6/qcBzEtQphfXLhiOHbt2KqBwMIwga0G
-A1UdIwSBpTCBooAU6/qcBzEtQphfXLhiOHbt2KqBwMKhgYakgYMwgYAxCzAJBgNV
-BAYTAlNHMREwDwYDVQQKEwhNMkNyeXB0bzEUMBIGA1UECxMLTTJDcnlwdG8gQ0Ex
-JDAiBgNVBAMTG00yQ3J5cHRvIENlcnRpZmljYXRlIE1hc3RlcjEiMCAGCSqGSIb3
-DQEJARYTbmdwc0BuZXRtZW1ldGljLmNvbYIBADAMBgNVHRMEBTADAQH/MA0GCSqG
-SIb3DQEBBAUAA4GBAD+I14GuS5vJmyv1k7mUMbAicsWRHZ+zrGOq9L/L2LsA+lKQ
-dAzEZE2+Zv8LBPJVltbJJhcFNJS/ZMAjEm4xlJuCpvXVMxd/M5AM29aqekWlIK7J
-vsdDL8IuzpRkMniUiNKPhmB6IPIOslvUKx6QofcE0wDh6pg4VvIbCjkpZ7gf
------END CERTIFICATE-----
diff --git a/demo/smime/clear.p7 b/demo/smime/clear.p7
deleted file mode 100644
index c878407..0000000
--- a/demo/smime/clear.p7
+++ /dev/null
@@ -1,67 +0,0 @@
-To: ngps@post1.com
-From: ngps@post1.com
-Subject: testing
-MIME-Version: 1.0
-Content-Type: multipart/signed; protocol="application/x-pkcs7-signature"; micalg=sha1; boundary="----F0DD27AD8CDFF9AB55B87EE3A626E6D7"
-
-This is an S/MIME signed message
-
-------F0DD27AD8CDFF9AB55B87EE3A626E6D7
-
-S/MIME - Secure Multipurpose Internet Mail Extensions [RFC 2311, RFC 2312] -
-provides a consistent way to send and receive secure MIME data. Based on the
-popular Internet MIME standard, S/MIME provides the following cryptographic
-security services for electronic messaging applications - authentication,
-message integrity and non-repudiation of origin (using digital signatures)
-and privacy and data security (using encryption).
-
-S/MIME is built on the PKCS #7 standard. [PKCS7]
-
-S/MIME is implemented in Netscape Messenger and Microsoft Outlook.
-
-------F0DD27AD8CDFF9AB55B87EE3A626E6D7
-Content-Type: application/x-pkcs7-signature; name="smime.p7s"
-Content-Transfer-Encoding: base64
-Content-Disposition: attachment; filename="smime.p7s"
-
-MIIHHAYJKoZIhvcNAQcCoIIHDTCCBwkCAQExCzAJBgUrDgMCGgUAMIICQwYJKoZI
-hvcNAQcBoIICNASCAjANClMvTUlNRSAtIFNlY3VyZSBNdWx0aXB1cnBvc2UgSW50
-ZXJuZXQgTWFpbCBFeHRlbnNpb25zIFtSRkMgMjMxMSwgUkZDIDIzMTJdIC0gDQpw
-cm92aWRlcyBhIGNvbnNpc3RlbnQgd2F5IHRvIHNlbmQgYW5kIHJlY2VpdmUgc2Vj
-dXJlIE1JTUUgZGF0YS4gQmFzZWQgb24gdGhlDQpwb3B1bGFyIEludGVybmV0IE1J
-TUUgc3RhbmRhcmQsIFMvTUlNRSBwcm92aWRlcyB0aGUgZm9sbG93aW5nIGNyeXB0
-b2dyYXBoaWMNCnNlY3VyaXR5IHNlcnZpY2VzIGZvciBlbGVjdHJvbmljIG1lc3Nh
-Z2luZyBhcHBsaWNhdGlvbnMgLSBhdXRoZW50aWNhdGlvbiwNCm1lc3NhZ2UgaW50
-ZWdyaXR5IGFuZCBub24tcmVwdWRpYXRpb24gb2Ygb3JpZ2luICh1c2luZyBkaWdp
-dGFsIHNpZ25hdHVyZXMpDQphbmQgcHJpdmFjeSBhbmQgZGF0YSBzZWN1cml0eSAo
-dXNpbmcgZW5jcnlwdGlvbikuDQoNClMvTUlNRSBpcyBidWlsdCBvbiB0aGUgUEtD
-UyAjNyBzdGFuZGFyZC4gW1BLQ1M3XQ0KDQpTL01JTUUgaXMgaW1wbGVtZW50ZWQg
-aW4gTmV0c2NhcGUgTWVzc2VuZ2VyIGFuZCBNaWNyb3NvZnQgT3V0bG9vay4NCqCC
-AxAwggMMMIICdaADAgECAgECMA0GCSqGSIb3DQEBBAUAMHsxCzAJBgNVBAYTAlNH
-MREwDwYDVQQKEwhNMkNyeXB0bzEUMBIGA1UECxMLTTJDcnlwdG8gQ0ExJDAiBgNV
-BAMTG00yQ3J5cHRvIENlcnRpZmljYXRlIE1hc3RlcjEdMBsGCSqGSIb3DQEJARYO
-bmdwc0Bwb3N0MS5jb20wHhcNMDAwOTEwMDk1ODIwWhcNMDIwOTEwMDk1ODIwWjBZ
-MQswCQYDVQQGEwJTRzERMA8GA1UEChMITTJDcnlwdG8xGDAWBgNVBAMTD00yQ3J5
-cHRvIENsaWVudDEdMBsGCSqGSIb3DQEJARYObmdwc0Bwb3N0MS5jb20wXDANBgkq
-hkiG9w0BAQEFAANLADBIAkEAoz3zUF0dmxSU+1fso+eTdmjDY71gWNeXWX28qsBJ
-0UFmq4JCtw7Gv4fJ0TZgQHVIrXgKrUvzsquu8eiVjuP/NwIDAQABo4IBBDCCAQAw
-CQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2Vy
-dGlmaWNhdGUwHQYDVR0OBBYEFMcQhEeJ1x9d+8Rzag9yjCiutYKOMIGlBgNVHSME
-gZ0wgZqAFPuHI2nrnDqTFeXFvylRT/7tKDgBoX+kfTB7MQswCQYDVQQGEwJTRzER
-MA8GA1UEChMITTJDcnlwdG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQD
-ExtNMkNyeXB0byBDZXJ0aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5n
-cHNAcG9zdDEuY29tggEAMA0GCSqGSIb3DQEBBAUAA4GBAKy2cWa2BF6cbBPE4ici
-//wOqkLDbsI3YZyUSj7ZPnefghx9EwRJfLB3/sXEf78OHL7yV6IMrvEVEAJCYs+3
-w/lspCMJC0hOomxnt0vjyCCd0JeaEwihQGbOo9V0reXzrUy8yNkwo1w8mMSbIvqh
-+D5uTB0jKL/ml1EVLw3NJf68MYIBmjCCAZYCAQEwgYAwezELMAkGA1UEBhMCU0cx
-ETAPBgNVBAoTCE0yQ3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UE
-AxMbTTJDcnlwdG8gQ2VydGlmaWNhdGUgTWFzdGVyMR0wGwYJKoZIhvcNAQkBFg5u
-Z3BzQHBvc3QxLmNvbQIBAjAJBgUrDgMCGgUAoIGxMBgGCSqGSIb3DQEJAzELBgkq
-hkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTAyMTIwODE3NTIyMVowIwYJKoZIhvcN
-AQkEMRYEFI/KcwJXhIg0bRzYLfAtDhxRMzghMFIGCSqGSIb3DQEJDzFFMEMwCgYI
-KoZIhvcNAwcwDgYIKoZIhvcNAwICAgCAMA0GCCqGSIb3DQMCAgFAMAcGBSsOAwIH
-MA0GCCqGSIb3DQMCAgEoMA0GCSqGSIb3DQEBAQUABEBrhZ8JVqGZ+S7dh+xKDwbF
-yRXiOQWEa2uxD1O5fD02VfGEzDSrV1sPdQ8AcM3o+ny5AyC11E4Fns2cIkXwZEwz
-
-------F0DD27AD8CDFF9AB55B87EE3A626E6D7--
-
diff --git a/demo/smime/client.p12 b/demo/smime/client.p12
deleted file mode 100644
index b7b985a..0000000
--- a/demo/smime/client.p12
+++ /dev/null
Binary files differ
diff --git a/demo/smime/client.pem b/demo/smime/client.pem
deleted file mode 100644
index 0eeeefb..0000000
--- a/demo/smime/client.pem
+++ /dev/null
@@ -1,36 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDDDCCAnWgAwIBAgIBAjANBgkqhkiG9w0BAQQFADB7MQswCQYDVQQGEwJTRzER
-MA8GA1UEChMITTJDcnlwdG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQD
-ExtNMkNyeXB0byBDZXJ0aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5n
-cHNAcG9zdDEuY29tMB4XDTAwMDkxMDA5NTgyMFoXDTAyMDkxMDA5NTgyMFowWTEL
-MAkGA1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRgwFgYDVQQDEw9NMkNyeXB0
-byBDbGllbnQxHTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tMFwwDQYJKoZI
-hvcNAQEBBQADSwAwSAJBAKM981BdHZsUlPtX7KPnk3Zow2O9YFjXl1l9vKrASdFB
-ZquCQrcOxr+HydE2YEB1SK14Cq1L87KrrvHolY7j/zcCAwEAAaOCAQQwggEAMAkG
-A1UdEwQCMAAwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRp
-ZmljYXRlMB0GA1UdDgQWBBTHEIRHidcfXfvEc2oPcoworrWCjjCBpQYDVR0jBIGd
-MIGagBT7hyNp65w6kxXlxb8pUU/+7Sg4AaF/pH0wezELMAkGA1UEBhMCU0cxETAP
-BgNVBAoTCE0yQ3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UEAxMb
-TTJDcnlwdG8gQ2VydGlmaWNhdGUgTWFzdGVyMR0wGwYJKoZIhvcNAQkBFg5uZ3Bz
-QHBvc3QxLmNvbYIBADANBgkqhkiG9w0BAQQFAAOBgQCstnFmtgRenGwTxOInIv/8
-DqpCw27CN2GclEo+2T53n4IcfRMESXywd/7FxH+/Dhy+8leiDK7xFRACQmLPt8P5
-bKQjCQtITqJsZ7dL48ggndCXmhMIoUBmzqPVdK3l861MvMjZMKNcPJjEmyL6ofg+
-bkwdIyi/5pdRFS8NzSX+vA==
------END CERTIFICATE-----
------BEGIN RSA PRIVATE KEY-----
-MIIBOgIBAAJBAKM981BdHZsUlPtX7KPnk3Zow2O9YFjXl1l9vKrASdFBZquCQrcO
-xr+HydE2YEB1SK14Cq1L87KrrvHolY7j/zcCAwEAAQJAUkHlWZmSUZMNf5nOpMkM
-hZ5E1v2Wjy4UFgRGDcTXbZm401Avwrc8006qQxQjoH94pVkwPYjEyAMubhusMFt4
-AQIhANeB4qzW/YsABYpt66x1ByiuUJE1p+QMLngeESJbc989AiEAweoMtXsNRJi4
-1xBzlKB9zljQfESYIt59SctURPfX/4MCICS9kwyOdplM/qTUCprTNM49saSf9iiN
-3xpBXgBygPWtAiEAmoIeDEB26vBxX1OJdKSIeXFE9a9GNYpn8/OiOq3smncCIGIg
-Hj9MtdZ/1uPk7jx5oZVfzN1DM7GYZHAeYeYhVR13
------END RSA PRIVATE KEY-----
------BEGIN CERTIFICATE REQUEST-----
-MIIBEzCBvgIBADBZMQswCQYDVQQGEwJTRzERMA8GA1UEChMITTJDcnlwdG8xGDAW
-BgNVBAMTD00yQ3J5cHRvIENsaWVudDEdMBsGCSqGSIb3DQEJARYObmdwc0Bwb3N0
-MS5jb20wXDANBgkqhkiG9w0BAQEFAANLADBIAkEAoz3zUF0dmxSU+1fso+eTdmjD
-Y71gWNeXWX28qsBJ0UFmq4JCtw7Gv4fJ0TZgQHVIrXgKrUvzsquu8eiVjuP/NwID
-AQABoAAwDQYJKoZIhvcNAQEEBQADQQAQho0UsOhmuUUhJrx7uXIEbo984OrOVpa6
-giAU7socmyjCzJvihmr/Nnqub+Md7rkSfDytGDN6CianGL5MROjr
------END CERTIFICATE REQUEST-----
diff --git a/demo/smime/client2.pem b/demo/smime/client2.pem
deleted file mode 100644
index 166919a..0000000
--- a/demo/smime/client2.pem
+++ /dev/null
@@ -1,36 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDDjCCAnegAwIBAgIBAzANBgkqhkiG9w0BAQQFADB7MQswCQYDVQQGEwJTRzER
-MA8GA1UEChMITTJDcnlwdG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQD
-ExtNMkNyeXB0byBDZXJ0aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5n
-cHNAcG9zdDEuY29tMB4XDTAwMTEyMDEzMDMwNVoXDTAyMTEyMDEzMDMwNVowWzEL
-MAkGA1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRowGAYDVQQDExFNMkNyeXB0
-byBDbGllbnQgMjEdMBsGCSqGSIb3DQEJARYObmdwc0Bwb3N0MS5jb20wXDANBgkq
-hkiG9w0BAQEFAANLADBIAkEAn9qneRYTKPokme3obiJa2NTz1Z2kcF3NHVh60Qod
-/TV/q4olPrZdFR2TDWt63Lgnygcsgf3u9pnhcEGk6IvntwIDAQABo4IBBDCCAQAw
-CQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2Vy
-dGlmaWNhdGUwHQYDVR0OBBYEFDKWFe6VWMhtRTE3/78+hAnSGxmvMIGlBgNVHSME
-gZ0wgZqAFPuHI2nrnDqTFeXFvylRT/7tKDgBoX+kfTB7MQswCQYDVQQGEwJTRzER
-MA8GA1UEChMITTJDcnlwdG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQD
-ExtNMkNyeXB0byBDZXJ0aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5n
-cHNAcG9zdDEuY29tggEAMA0GCSqGSIb3DQEBBAUAA4GBABpE9xt1Hlq2dQZUXHuX
-HI57vc2mlWnhhM0wnNhsNZFwfXRHCZOo/JJBhEIT3Rgyz0ErrbOr1SN96HNDKXOD
-z6bh4NxB5DZ9sRPKEBj66zDsWJVMlom+Lkeal+GkVy36vpAyP1r+cTXyc9M2Gw/o
-FBMinMHH/BXvF5GJ+UleheZe
------END CERTIFICATE-----
------BEGIN RSA PRIVATE KEY-----
-MIIBOgIBAAJBAJ/ap3kWEyj6JJnt6G4iWtjU89WdpHBdzR1YetEKHf01f6uKJT62
-XRUdkw1rety4J8oHLIH97vaZ4XBBpOiL57cCAwEAAQJANXfspprUo9MvpPEn2pbR
-Lk/kk2IcW510e0laI0uwBj50djfHqvsU5ccuVLrxowngLGrFmM3G4lnMknR2NvH8
-0QIhAMsK0AwStUNM/KyvIMikHHBOE9PrK7ARgKvlKl+0ieWPAiEAyYwonIVAtr1f
-M8vmrc6TM2YxzSq4+jyYktaaNhYw11kCIA5pmhMBUPSSBm2LkNwtKgeewzGLw/If
-i+6nubZJbnBpAiEAvJQvy4PCsTkvQr+d7zJB+O2920IGId1gxMOXNtQ8jsECIGvn
-Uz54oonshmTg+Kj2DxnUKQEzFAmQLbtFslp1m47v
------END RSA PRIVATE KEY-----
------BEGIN CERTIFICATE REQUEST-----
-MIIBFTCBwAIBADBbMQswCQYDVQQGEwJTRzERMA8GA1UEChMITTJDcnlwdG8xGjAY
-BgNVBAMTEU0yQ3J5cHRvIENsaWVudCAyMR0wGwYJKoZIhvcNAQkBFg5uZ3BzQHBv
-c3QxLmNvbTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQCf2qd5FhMo+iSZ7ehuIlrY
-1PPVnaRwXc0dWHrRCh39NX+riiU+tl0VHZMNa3rcuCfKByyB/e72meFwQaToi+e3
-AgMBAAGgADANBgkqhkiG9w0BAQQFAANBAHI5KXfL6kIRoNjR8G9/uKiPUt4uVBKF
-ecGp87M5t2a92Z0KpWOMXSHZ0LLQKqwWzALvWcPPIj6S8F6ENdwpfMk=
------END CERTIFICATE REQUEST-----
diff --git a/demo/smime/m2.se.p7 b/demo/smime/m2.se.p7
deleted file mode 100644
index 3a5bb1b..0000000
--- a/demo/smime/m2.se.p7
+++ /dev/null
@@ -1,84 +0,0 @@
-MIME-Version: 1.0
-Content-Disposition: attachment; filename="smime.p7m"
-Content-Type: application/x-pkcs7-mime; name="smime.p7m"
-Content-Transfer-Encoding: base64
-
-MIAGCSqGSIb3DQEHA6CAMIIOBwIBADGCAVkwggFVAgEAMIG9MIG3MQswCQYDVQQG
-EwJTRzEvMC0GA1UEChMmRmFzdCBTZWN1cmUgQ2hlYXAgQ2VydGlmaWNhdGVzIFB0
-ZSBMdGQxMjAwBgNVBAsTKUZhc3QgU2VjdXJlIENoZWFwIENlcnRpZmljYXRpb24g
-QXV0aG9yaXR5MSQwIgYDVQQDExtGYXN0IFNlY3VyZSBDaGVhcCBLZXlNYXN0ZXIx
-HTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tAgEDMA0GCSqGSIb3DQEBAQUA
-BIGAaH1UOF0vZjCfEDbzWAy+kni/T0AVVbTdWeCZAaADIgNrUqVJKkV8BIrAFRUO
-jNdz23gra1TRgoe+sq4qn9WBi61+f+8JUV4UHZYl4DdcIkcGvdEI7utPLFNFif2m
-oqd+kr39wuGWMonoBpzFdycSN/FRpFTrwoyXEIHj9VPCwvUwggyjBgkqhkiG9w0B
-BwEwGgYIKoZIhvcNAwIwDgICAKAECCZMYhSx21tlgIIMeGyY4Sgm4uv0a0Zu5gnx
-x1bA6wPY2W8oOqFC3jEAc6j0aP9TzxFW33W5fT/wCWCuIaS8Bm2nCozt7yhBofV2
-9mEtlahbEV1KeqwgI/RteTHD2WUvz6277O9lsB/xsreKM63WzxkpTWi0BUQBDjC1
-ncwy/74ujmZhdAD28HJie5cqhxKQd8if5/Ild3B786sxpGaSBKbJAtJYG30imbHL
-B7JTqDciCKQZzFeQBc1TOcld9VqFP2dRexmcPMxcyJN1iJe8R0g6PYpfAmLfmN6B
-fAImcgJYBpq8PYzmTi7cpJCMmzlPn7urm8Nx4DUQtzzMArmSuMfWGhu2wWLM+2Mn
-TB1cAVuO0bGgsHnr0BKW5gfQEJEIZY41Kq179RKAzI6OdJYvnKXoadEtzYI07Tup
-D+HJXLdAuU/B6E+09IS8mg2RydNyRP+lp+sOVve6L4LAH8h5pt7hoES5/qgiew09
-FPpx5xmhcGCTHJ9Ad2Xec6zAuYkVWAUfLpiy2A2NDTZnQ6EWaeWHtoAizMjHlqQY
-ZJYeXINzE4/u9ph5DTvXV2Sd57eOoaaaHmWwoV/887cdW33cQQ8LXciuzduI/b4V
-LWFm3X9eVdGEeQFoNDP5D7xwEK67flhufYClB99lt3tCfRLvvcclsd39heOex5/M
-6XeA8TeEbuukMhEe6bW2o+E736XNpziFm7hL1UGBXqbv26sN3A30H9LRMXGlZZxj
-raGBl8uxzUPi/SxERMbRrYC72x3Dev5m5I458wXEyc94GIqDqcHL0Q+za+3iyC2g
-496OsVeqtob9oshXr3rI0FjV+ejNMBcnhWeaPKLl6MOnqI76kczARZR8WrO+Dyy9
-FpgwX/DNKstuw0rLzzN7Zb+J4NPIhlHDt2Hh3KLjoFAiXPSDugKGQiceV6mg0IuS
-8HPq8rTiKFEnFtPTWxvAKIOa3dKaOiBoCue1Qm+ffV/2AB4Q4Xf0SpzgDBa6ruRF
-MImgcdeNjzu5MggGGHQtYU1uMMqhX4o2GIafVmAO5zUVYHsbQ2Lht+/x+m8nBamV
-H8AUzJQBDL10bbmZW8fh4JqwxXsdmoTKSSSKEk1+mP55DeBnP+GPA1EGbZWoI+mO
-FoHd1QKDedI/r8o9y1SkfhPxrKl0XKG+VLIUmmP+qev/7s3d5PEfg+ShkAAf2ccP
-2o+poSQKHYeOVM/RxLjS7AR96MtMl+46Cyinbl1quRjYLh84iQSP9RNVhVM06fi5
-63RHv8BAlJRnEcyiFNV/uDBYTFQ/2Gf8V9gBjYWyajnISsTsD2ZQ93jT/sjL6KpH
-Ouv7LQplVrxkZHXQgOoqd9fI1QR8qyBjoMUivv0DSKPKZo0MT/KfqUxG+DsFgOi/
-a7WW9J+XA7N2hGiP3CEqmm1pPi6IUtQj5kGmjlcEtco9syTwPSh5w+tcmVtQeu1+
-wwg53wSLHUdRUmVGqyCVV55ItkirSQt37JCDkXoivCfbdi5BI7cQ6IBhRvpBw2uV
-IA0O9/AfhXhUred974WInrjjlo0RQ4rGZutwDYWrPzWjzuPPvomih6rKQ0HH1bgb
-vdAZ+UjXtfSdory36LMg9Yb/oFejm/77NRXAo9AAf2MQvHVN00zKzDoMm4CRiJUc
-ZCC2+3ocFEs9l6jOO2tPrQpH+E69XXyqQcer18FyM3rTv81O2SbOz0IfL9vBFEsL
-ZZVifPKLt9LfRRjoqehXTxkmfQ2NmHUyksHO4aE2/OrtMVXBv35WFzLPIsX9C+yX
-r6+QPQrkG2Uad2e0YM0ipNPk4OIy5Bb+Ab6fIbHvLgLBRv0yBZ+e9OoEZ1UFC6sR
-EncKSV1fkRlemGgG2cEP6Ceq+x0zbS4A97nqQO5Hks5Hv5PqVuSaWSIjAEFihmpt
-wB41IunnO7b/jzJiNLK28e83uICuYgrPPEeYbbdGrEn65ZzdvhOQduwj0baJRp3V
-0z4boIs7oODYq0IXklvoMzwoaAPbMo2IBamMbZbY7HQbPOeI9QQTkBmKjavFRg/X
-fismhuFuVbyMQPc9uV27xpI2nRSkfN1X2L1lz+e5MMEwHqVRER3tGB1/g+WMrSGV
-ORvXam6fmkIgC4bCSAGBPtqHr2G2rzphsxESw2pbk/7ll8lGuYf3ZxovXJiLb2RB
-9j9m5TFoZ72Asplc04NDKykVOzZGWvNJCCV9zUHTyZ6X4qx+C4P6g58OvyZEf2VB
-arkD40QoEBkhNP6QLfacdFNAegWp6MwJHCDg2YIeLMfgCKkDVP+/SijiT3x7ahHO
-n3ZxKsq1bC6N7McwHB6gzkdpSSqWdtSv+fh5TNlMf7oCH0Laa/2k8S7NDpNbIeqr
-X46ECkmqPTjt5DOuEp3T5q4sOXV2Y3m7FegD2J2WrpXy+/GNgSVB2Kb7xzhR13ve
-Ipu5V+FFa6Q/jbXxp864ZFE6WuZYBYjrkBns2MaF+9RpUSIzyTYxJmB9pY0SwrzX
-2WWnxCCt7cwB1JL0jbrCz0vZvZwDRbtCyepBYel0xqKOhp1dFPCw2p45ZbQJwhKx
-nFMDUzlDZjiAoUdq5oV8TmqcjbGDmLndYawHPqD8m3g+glsCaFI89Dny8NsT0zv2
-vHCt6IbbpVY6j/Pwg9SFzWwnzGr2s5aL5MEbpzEyfiuYAe1hPdue2gWQO1rvdIBB
-zJwdqbrYb3qzJqrqrPQewSpsIzEWJmc5NjATIJOEtgM+Q4+FFTf4f1rZ2HAsK7MG
-aIMZFyjoyvqBHG/IwCh+GBLLIw3IPRJtDcKf/nDZqUCw0wHpTcXu1nHJllNmtNcI
-Xw03k7WctqlxTUBFUjiC6XcU/yAlLZ8UeyLF3+/tSyyV+Ve17cZfAH63WH+oaWL8
-yiC+UH5tpZQWCSBvCz81ezHOBefefOxeIvq5nZyEyP23ltaV/DJqj1a/5pn2VH63
-IrRlQF04ATaUAowxlNIaqD5Sk6tzPKp6nxOO3vP8xRGT1SFKMaNCuJRaZXXQvYcg
-zyiQ0vtli0g8cdbR8dSSTAP7b6CAqb2dYHwtJVUzPzWbWDIpRzrXOdoI/lze+fwA
-xYwAFoTuLLrKgbkOB8HE02ZN4exCp2dcMfwt+GCgYgCtE1/xCHd4RMg3yHxBBDQQ
-uk6dL6dXSD8cw2TqzrJRU8Xk/pLHeQCf694W2flROD/RF3avgcjnJ+0E+CJXmU9c
-+uAhFRmdgRzM6G+h2p/MF8HjZ4MZTR6vA4v6mvTLLBbwIUfVNtXIwXpFqQPXVRvA
-4Q8HmLIX2fXGzR2Nw9UU0GBitT4r1isMHCQwVK5kqw3XyH15oIXCCsE1/ftBun8n
-SCQ2OkLHuZ4JWMIYVpTtDn3jd0Gyu6x8hBK+HpX62wnKZZA8mxzMoInAFK08s0Ie
-G3m+bjX7WsdE1eM0TSBvYv2d8CNqaqxJkF/ZlxkAKV7NoP0isuRJSSHH0IcrWNR7
-9mtfxV+ccBUqqO7BmlzLYPjnN+7hOJbYsm0ZJnDZIn6Oc6t8ti+oF4QmUBQ2u7As
-8uBJLbd7TghA7afcrurQAY8gJTq4Q7/lpYZSZK+W0I4fY04YhAfjFuln8r6w9gqr
-+Iwg58dbq7MomCsg0F687kApYygyYQeCsio64tb3sXkCmDX2rdRoAELLf3AYccn+
-BW9iru372oWru/kTQTj6Uziv4TiyjUGQEYhtjweTNFTXmYrxYHgb2Hzu6TNIG9Ev
-4ORq9KL1uWSK8zJ6eL9CZ0kSr/4+SBHFbGupfGXz+fZysu3nFJ1oO86vMOFG/UU9
-24+jbRWklu0fyXZfeNzdY6arTLOX5Gpc9PRNZILoFHGyB2M9ZmMYz3hSNzY8acpk
-XDi+2ycHYeWFGxGCLio9Lc2H6IOMqJTTCpUduWvBX4tfysanUNjOuKJ3FWKWLxda
-IX1jJbPjvrQ3bg/NU/MqliLwFiMA1WkJd/paeK//J2tcOIMyhc40sigu4z65VoJ5
-AsMHlvh1dcfjz645NOx6JOpwdd04hoOxlMDtRTE/b8yjwaV2EVqXnI5WkNwCQESU
-ayIJiQqDfn35EFY8Wkmt7f6YGkpqoBDJkyNadsrcd2YVz9paAhgcM3XjC7zPi8AH
-g9UiTQiowRLcvnxkHK0LxelsQTE+ENL0rwYCt+qHBBJlcLVZhDF+qAchv+G5hmxp
-CClPyvbzOsx7ykcvItE2fpBWJu27l48dFxFviOKY7ecvJlpcTAX83N79k0aJpOC+
-TEPMdMZjIeGn004FiVj9Mo1899e2IlOlNdmj8Mv/jW4sFKpJ8m5fHv8i/ax7W33D
-0GNMrEghOH1w+QAAAAA=
-
-
-
diff --git a/demo/smime/ns.p7 b/demo/smime/ns.p7
deleted file mode 100644
index d2ab1ac..0000000
--- a/demo/smime/ns.p7
+++ /dev/null
@@ -1,53 +0,0 @@
-From: Ng Pheng Siong <ngps@post1.com>
-X-Mailer: Mozilla 4.5 [en] (WinNT; I)
-X-Accept-Language: en
-MIME-Version: 1.0
-To: ngps@post1.com
-Subject: S/MIME signing
-Content-Type: multipart/signed; protocol="application/x-pkcs7-signature"; micalg=sha1; boundary="------------msD996346BF03A805B450DC20D"
-
-This is a cryptographically signed message in MIME format.
-
---------------msD996346BF03A805B450DC20D
-Content-Type: text/plain; charset=us-ascii
-Content-Transfer-Encoding: 7bit
-
-smime -vs- pgp
-war over?
---------------msD996346BF03A805B450DC20D
-Content-Type: application/x-pkcs7-signature; name="smime.p7s"
-Content-Transfer-Encoding: base64
-Content-Disposition: attachment; filename="smime.p7s"
-Content-Description: S/MIME Cryptographic Signature
-
-MIIF8gYJKoZIhvcNAQcCoIIF4zCCBd8CAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHAaCC
-A9cwggPTMIIDPKADAgECAgEDMA0GCSqGSIb3DQEBBAUAMIG3MQswCQYDVQQGEwJTRzEvMC0G
-A1UEChMmRmFzdCBTZWN1cmUgQ2hlYXAgQ2VydGlmaWNhdGVzIFB0ZSBMdGQxMjAwBgNVBAsT
-KUZhc3QgU2VjdXJlIENoZWFwIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtG
-YXN0IFNlY3VyZSBDaGVhcCBLZXlNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEu
-Y29tMB4XDTk5MDkxNzA1NTAzOFoXDTAwMDkxNjA1NTAzOFowYDELMAkGA1UEBhMCU0cxGDAW
-BgNVBAoTD00yQ3J5cHRvIENsaWVudDEYMBYGA1UEAxMPTTJDcnlwdG8gQ2xpZW50MR0wGwYJ
-KoZIhvcNAQkBFg5uZ3BzQHBvc3QxLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
-vp8eCa+KpzNCv0MWyicUImP+WHxlrxm5EummI1Qe77U4w0k8IQuue7QIURWKDjdZI97izzeQ
-SozHvgSsjCvuJlqifMoV0v7U4iUQoZkrXO3hzwM5VNr875M95SYeBjqWDUc0v3R6tka3xhg3
-dMoEL3QR6gsiardPEwygdL7/FN0CAwEAAaOCAUMwggE/MAkGA1UdEwQCMAAwLAYJYIZIAYb4
-QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBTEHU/WosFL
-yRo8NT9ViQ8APbKBXTCB5AYDVR0jBIHcMIHZgBQOTokwY/jsgXmHJoyQ5DmTVN0c8KGBvaSB
-ujCBtzELMAkGA1UEBhMCU0cxLzAtBgNVBAoTJkZhc3QgU2VjdXJlIENoZWFwIENlcnRpZmlj
-YXRlcyBQdGUgTHRkMTIwMAYDVQQLEylGYXN0IFNlY3VyZSBDaGVhcCBDZXJ0aWZpY2F0aW9u
-IEF1dGhvcml0eTEkMCIGA1UEAxMbRmFzdCBTZWN1cmUgQ2hlYXAgS2V5TWFzdGVyMR0wGwYJ
-KoZIhvcNAQkBFg5uZ3BzQHBvc3QxLmNvbYIBADANBgkqhkiG9w0BAQQFAAOBgQBN4w1l4IXm
-DJke8XVyo3SFlre1nL/bjDB+hpYCgTQnceHAmSi6L8FljGs2KYGFePWLSCsOxA99q8lVtl7a
-sdoOtYkTluccWGqnWloyusOzlO2xgpoQxZ2iue3PT4Y4u8czMTs2AyanZyd6NdQoaYGfI2g0
-tpgiDhSqcX8r/JYYVzGCAeMwggHfAgEBMIG9MIG3MQswCQYDVQQGEwJTRzEvMC0GA1UEChMm
-RmFzdCBTZWN1cmUgQ2hlYXAgQ2VydGlmaWNhdGVzIFB0ZSBMdGQxMjAwBgNVBAsTKUZhc3Qg
-U2VjdXJlIENoZWFwIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtGYXN0IFNl
-Y3VyZSBDaGVhcCBLZXlNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tAgED
-MAkGBSsOAwIaBQCgfTAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEP
-Fw0wMDAzMzEwNTExNTJaMB4GCSqGSIb3DQEJDzERMA8wDQYIKoZIhvcNAwICASgwIwYJKoZI
-hvcNAQkEMRYEFDIu42hsp6w5K/x7ejaVgiqgPYk4MA0GCSqGSIb3DQEBAQUABIGAkipjxn6+
-NhIyRPGgrqY9zpDC8AGdt7sGFMKfxhJ+UoSb+lBH0imHSBhA/BnlfysyyDXCpit1Gxy/W/jn
-vHpI0lMLvvcKOtSQp9HUPAtawdeF6Zau8SovSBroUnxxY7DILJoKnaHheHF7G2MbYusyZCmi
-r3xZ4P0Ps3fhNEAmrH0=
---------------msD996346BF03A805B450DC20D--
-
diff --git a/demo/smime/ns.se.p7 b/demo/smime/ns.se.p7
deleted file mode 100644
index a7a75f5..0000000
--- a/demo/smime/ns.se.p7
+++ /dev/null
@@ -1,75 +0,0 @@
-MIME-Version: 1.0
-Content-Type: application/x-pkcs7-mime; name="smime.p7m"
-Content-Transfer-Encoding: base64
-Content-Disposition: attachment; filename="smime.p7m"
-Content-Description: S/MIME Encrypted Message
-
-MIAGCSqGSIb3DQEHA6CAMIACAQAxggKyMIIBVQIBADCBvTCBtzELMAkGA1UEBhMCU0cxLzAt
-BgNVBAoTJkZhc3QgU2VjdXJlIENoZWFwIENlcnRpZmljYXRlcyBQdGUgTHRkMTIwMAYDVQQL
-EylGYXN0IFNlY3VyZSBDaGVhcCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIGA1UEAxMb
-RmFzdCBTZWN1cmUgQ2hlYXAgS2V5TWFzdGVyMR0wGwYJKoZIhvcNAQkBFg5uZ3BzQHBvc3Qx
-LmNvbQIBAzANBgkqhkiG9w0BAQEFAASBgERIsZhX2nmvB4kOtcfqUpuWjK9njs8YixtPSS4w
-ugmAx3LhBMTgY1OlsbKi7etVPwEU2jSqgkwCHPeYeOQt6M9aQ66tcue7/fWjfMBfZ+tetwOb
-kpqlw//GyjhkJx2QBGPuw3Ye84ll1KA7x/CGxmk8g0YBHoLo9Xy1W1XHVUanMIIBVQIBADCB
-vTCBtzELMAkGA1UEBhMCU0cxLzAtBgNVBAoTJkZhc3QgU2VjdXJlIENoZWFwIENlcnRpZmlj
-YXRlcyBQdGUgTHRkMTIwMAYDVQQLEylGYXN0IFNlY3VyZSBDaGVhcCBDZXJ0aWZpY2F0aW9u
-IEF1dGhvcml0eTEkMCIGA1UEAxMbRmFzdCBTZWN1cmUgQ2hlYXAgS2V5TWFzdGVyMR0wGwYJ
-KoZIhvcNAQkBFg5uZ3BzQHBvc3QxLmNvbQIBBzANBgkqhkiG9w0BAQEFAASBgKFEdyFcaj2z
-7LBp/rdEiDRNkyvjZtpEc3F1tvml2jmOuRZq/Gd0Ib4ELmAuC2qZ7AG+MNwlMeCQp1PKGjCk
-3Af9hjcOX27c+qF3pSK35WOPrdQTaVLjqdNwejInEoBjGlHa83V1L/MTiD5ABOXGIZKOFS8m
-G0tPxoc3AhlYbHspMIAGCSqGSIb3DQEHATARBgUrDgMCBwQIvFFOv2EOARiggASBsBBa97DM
-xPCX8mZ2K/jjVl2LKtBP0uwG+nd48IiaoBERbJohEdzxTlIU3pj+QZ4ktmSSYo/4Os0eSCfK
-v2mG3d5SPxcE6HztA4FttvQ4IiByTQUU61vJhMoirV5Nvfkxk8i8xPMKMlJSruFBnIOteXQv
-vwVwBCIAkMhxBE9Sj+OfW5966d+LmB3yGEZa9GEW//4VbR6DNs1frEz7riUod0om5CA66bou
-8kXxGTZ5fYydBDDdrsgcU7DBTlw2XayUmYS3Gp0vQvW4l/iiYEeYh+OrKkGYQGdsb5CcZr0F
-FfT2PRAEICA58XUUrt//zi0TzBTwDKAWoJWe/QfOXXEVQsfqCl1iBBhACmC4JLQRSulBCCpA
-F3E3daztLz81ycQEIDyHXxMGZFzZQCvy51fN7eRLl+yACoXKxKtVs6EKpJq9BBDDGI8CWqTZ
-DIMC98l4AV76BIIBAFKj+L6ZG8Sew6IpE5UVq1oS42UrmUDQRrYpZX3OHC8I9pr7mtlU/V0H
-mA55PmixsjcchT6wOF2wVD9G0rBCOlUfuYNTkhR/k51floP9fk9Oy69+jXxUb7r0AF1M2b13
-XQpmnz6YPQPdPxgi8i34iT1oqRY1d4Nntmgl/3xbQ/9MGbgZQSDbduRiy+Zk3JPZzMSVWEVP
-Pt7anOrPmCKDAvlzpX9yKdyE4Ug68s2///S1JjCjGd65007oPXME3S+7WWylQXdjCe8EM/Li
-IE33DcRUFvbuo7q1ftxbwRKn32+Z1gkiG4j+DQ4fTO0RrhnTLUpaaOaX4N3psjSA/3Y+vKYE
-CAkYtbSSwRr5BAhmVVsaf0vm7QQIE77+DXI3Gt0ECIs/MQuPnwd6BAjpq83cshzQ1QQI3Soo
-r1XwQYIECES6t6POe3yxBAgmObWcpGTawQQI+6e28OKubqkESBlD4aGRdfOXkGSw5zN1pVK0
-s37qLWOsO+jClvd4EmfB/JI/ABieNmfBHx2jweIazMA2b9wylRvYp/TMiDFkRl/thDqyj/sC
-7QRIypPg5i7a745PX+HcyHhcy5lUxkpnK5pjAAHSUPTXNc/3H6PpU/8+qiPncfqNXVdoiiSa
-VMSmFMZI+YGDyf4twVuGZbdR5JV2BFCbQNJeSkEhEnZiMKshmNWXbjs4DzYlTO0Pq5D+9RYJ
-1iy/kahcms+2nDNlrVf6jH/lCTpPCM/OJWrjaTdpiFzp/eEY39qbWk5AcIFYQ7xIcARIHVPX
-uhyuO+5BmO0MdMMOL/KlhRtosKHHRG7PH9huyWYFloA4aeoiOxeXkDJk3y0NkG+nJjdM/gWT
-1J2HJi8opt0F0bn8t7MsBEgt2VgTZmkHT/yaJDInQEqrpe9PJ412M+2/kXAwt4VfYrEC3ocQ
-WQuNEpFc1kb6ZGJSYz0TvnW8DbP/GoZqQpF17p1vs1T0QhIESC1qr8SbwXjHjOdAh94Lp5jG
-b8kAl20P0hqqL+5qq661JzAdGotFN7sMOe07Xn3eaYEVe4htVHlIfYMPH2B0CYyHu9LH2ueG
-gwRQ7Dv1hygub3ioK/s9CkgAi83qUENz5RWYMtIiP7tbv34zq6DKwv0ioBY4MEKfR4cCuGzS
-6I67vTvCgXPVxW9qHtoTTDfufUR6yOOa/gvuZt4ESN3fo5Kgpm+74AMeOVR0RZ1lZ+75E9KV
-wmiBGm5ORHGSmyt3MQMW+5UEloz8mxK39O6RtKBL7iKH3d0clJn63KXvUsf2l7/8swRIIVzc
-1jGzpwOsUseKHaeLQuknjTuXAlyCTQYa3C0gEcEBElJY/TMevV+ZrlBB/nCwyaYbmH+WxxfQ
-+xF79+eIZ1+L5zGAlSNUBEhO1Gy1T77JUa+s4UUqGP+BNNsGDuR4YXWfCIA2vBfCFZVggkaD
-v1+uX2Rgim39wzMCLkXQ8ZXLWdWo7/XcllOrxJSH84uPat8EULZTtkbY1oW90JzGEJKbOkEA
-YaoQ7I0dKXnkLsY3Y54p1WW7fPQ4JLLhld2LpmZbYOntRJmn8LZWGWv9J3uYlAk9ujAfF10f
-7/qV2zDB//oKBEih8QUPicP+mSdpvRlws5RfiKmcf9W7btoNALqqA2COEOHjjJHdX9b3EVlk
-vftz5n2AbaS7fenhIl1/rbhmBfub3eHwmInRoUEESHcpUKHCEe3dtGe6vB2VXR4U/MvKScZV
-RpHv6KGj0pFZwNasoZ9W5RB0dwAbhuD+xiimlv/m9XwhIQihgTUmarVdEbYcbl1aHgRIFMEp
-bOJ4D49qYR9DXZprlST9nZTgU/R1KTcZe2LsXBNa9xxlO9NYvZCSQSuRndIIwbAXjgezK1d0
-fk+JSIyC8kaQzWBwDGdXBFDA3tUZzKed3JM+R/a8319iAemyyYgvk/izKKXncpOfCdBtVgHc
-cOC7LPs1BGxqGCyOzgD2KMQSclRZJo+siuRvJ2wlKCPjd3DHMk0IJ6EYWgRI3XuDbhKfLzEQ
-h9G5n3wQr8qizabBZ+xZEmJk7AUxA7ykEdSuLlV7qP/ujj9sZ9e/AaHG+mfjGRI01OPquZxW
-Pwt9nRpg1KqCBEjFQqB+hbkfT218E5+mFX/aotUq+tEoZ1Tg3Lq5WENZVwMNR0eFR69vN+gL
-SZU3nnLPEchS3pasz7ZBohL+kEBad4fZfKNWUa4ESO9adCvusxTvjlvf8Gu/lXU17gZuAHsj
-bMwSWyQeZKObCp7kOtK1nQCtLHkWHEpmx16eQWG57+makKYpjD4BSXFXGEwMf3Pw9AQQd6Po
-6JLMr7k5LjkOcyCe/gQIJ2ORlLJDWKMECHz5jFYLkHrLBAhPDugA9fP+MgQIQq/w/QD4YBIE
-CGeYC0G4o7ElBAj3O1FpJvdU+wQIiOZHO6By7rAECN9TZKOJa8YbBDD/7QgWqJSNhck7fNEY
-tHmopW9OWfXfXUInzaQFBtLauNRj0C2OW/zB5dgsC3+9/jYECG3bevzH5HiDBBBHiuTo8yYJ
-1FFJ/y4nIIXaBDC92swMrVUYZUpoNUjf02DsBiVP53Fon+CnKnEQ8gBCncIkb8DBnlZYeZd2
-XISBWmEECNOMqXZKxL2vBBDDg2nHASKLEobcHqmPoIQFBBhcrb6prkWNKColNlf5ss49ocnK
-68UgsNEECNJJEPZOUMW1BBApQ6CzF2t+QiJTdQwoApPzBBg8ZCeSHgypK9CWcWb2iMWiFuKc
-KUmIuskECFr2TQ/U6cWbBAisYHDp2/w4kgQISMieG/GdQlAEEGLN6GdGVz2wf1Hx93PJ4VsE
-EJRdLeaU3FsCwXEICvSKZPMEEIcEdqQkAhmsxfNoKA90QlUECDdUY0tvC48sBBBNOevphvxS
-0dwE2Lzf6gLGBAjoSuhhSYuZBAQIRKWk1TxshoAECFUuzdHGuR3zBBjlvJQjSDrEPqg7unh2
-ZaNy11cUKB07vPMECIbZbuiAcb81BBCyb6N/Aymqo24VwyE9/lTDBCCR0Sn7D8OfmpwUp0MJ
-zEdp+4eTPVu9W6bNj5cTwcG0VQQI9Z1/nYjZ93cECCZ7u+8p0rP8BAg6S5MaaL8mTQQIMt+W
-TF2XgOMEQLOZQ0FOc4oD9mBoXzN/NDmlEz0QWnZPnO/7OhVcuKPi6rtE+5RfdGDL/qxWGU6G
-0qvFT0zTodnwjpzKnYAnoeMEUDPxz4djUsMXhHzpye9vc7N2/B8QUBubRaFPp/FoLv3jjwga
-+AawOtkkW1uLku0m6zdN7YYzXTsKlMhwDd3nZS4Vm/v11AnFChiDC2LFmLw0BCC/X36boypP
-pTObDByKlN6IldnnPEi4tl/6Cxr2+28LWgQohCdg9nl3s5COEnwQW+ggcvKodHHK9SdVRscS
-J4ykS0lWZ0ns4/g6/wQIKIXduWxdKJMAAAAAAAAAAAAA
-
diff --git a/demo/smime/opaque.p7 b/demo/smime/opaque.p7
deleted file mode 100644
index a242446..0000000
--- a/demo/smime/opaque.p7
+++ /dev/null
@@ -1,47 +0,0 @@
-To: ngps@post1.com
-From: ngps@mpost1.com
-Subject: testing
-MIME-Version: 1.0
-Content-Disposition: attachment; filename="smime.p7m"
-Content-Type: application/x-pkcs7-mime; name="smime.p7m"
-Content-Transfer-Encoding: base64
-
-MIIHHAYJKoZIhvcNAQcCoIIHDTCCBwkCAQExCzAJBgUrDgMCGgUAMIICQwYJKoZI
-hvcNAQcBoIICNASCAjANClMvTUlNRSAtIFNlY3VyZSBNdWx0aXB1cnBvc2UgSW50
-ZXJuZXQgTWFpbCBFeHRlbnNpb25zIFtSRkMgMjMxMSwgUkZDIDIzMTJdIC0gDQpw
-cm92aWRlcyBhIGNvbnNpc3RlbnQgd2F5IHRvIHNlbmQgYW5kIHJlY2VpdmUgc2Vj
-dXJlIE1JTUUgZGF0YS4gQmFzZWQgb24gdGhlDQpwb3B1bGFyIEludGVybmV0IE1J
-TUUgc3RhbmRhcmQsIFMvTUlNRSBwcm92aWRlcyB0aGUgZm9sbG93aW5nIGNyeXB0
-b2dyYXBoaWMNCnNlY3VyaXR5IHNlcnZpY2VzIGZvciBlbGVjdHJvbmljIG1lc3Nh
-Z2luZyBhcHBsaWNhdGlvbnMgLSBhdXRoZW50aWNhdGlvbiwNCm1lc3NhZ2UgaW50
-ZWdyaXR5IGFuZCBub24tcmVwdWRpYXRpb24gb2Ygb3JpZ2luICh1c2luZyBkaWdp
-dGFsIHNpZ25hdHVyZXMpDQphbmQgcHJpdmFjeSBhbmQgZGF0YSBzZWN1cml0eSAo
-dXNpbmcgZW5jcnlwdGlvbikuDQoNClMvTUlNRSBpcyBidWlsdCBvbiB0aGUgUEtD
-UyAjNyBzdGFuZGFyZC4gW1BLQ1M3XQ0KDQpTL01JTUUgaXMgaW1wbGVtZW50ZWQg
-aW4gTmV0c2NhcGUgTWVzc2VuZ2VyIGFuZCBNaWNyb3NvZnQgT3V0bG9vay4NCqCC
-AxAwggMMMIICdaADAgECAgECMA0GCSqGSIb3DQEBBAUAMHsxCzAJBgNVBAYTAlNH
-MREwDwYDVQQKEwhNMkNyeXB0bzEUMBIGA1UECxMLTTJDcnlwdG8gQ0ExJDAiBgNV
-BAMTG00yQ3J5cHRvIENlcnRpZmljYXRlIE1hc3RlcjEdMBsGCSqGSIb3DQEJARYO
-bmdwc0Bwb3N0MS5jb20wHhcNMDAwOTEwMDk1ODIwWhcNMDIwOTEwMDk1ODIwWjBZ
-MQswCQYDVQQGEwJTRzERMA8GA1UEChMITTJDcnlwdG8xGDAWBgNVBAMTD00yQ3J5
-cHRvIENsaWVudDEdMBsGCSqGSIb3DQEJARYObmdwc0Bwb3N0MS5jb20wXDANBgkq
-hkiG9w0BAQEFAANLADBIAkEAoz3zUF0dmxSU+1fso+eTdmjDY71gWNeXWX28qsBJ
-0UFmq4JCtw7Gv4fJ0TZgQHVIrXgKrUvzsquu8eiVjuP/NwIDAQABo4IBBDCCAQAw
-CQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2Vy
-dGlmaWNhdGUwHQYDVR0OBBYEFMcQhEeJ1x9d+8Rzag9yjCiutYKOMIGlBgNVHSME
-gZ0wgZqAFPuHI2nrnDqTFeXFvylRT/7tKDgBoX+kfTB7MQswCQYDVQQGEwJTRzER
-MA8GA1UEChMITTJDcnlwdG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQD
-ExtNMkNyeXB0byBDZXJ0aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5n
-cHNAcG9zdDEuY29tggEAMA0GCSqGSIb3DQEBBAUAA4GBAKy2cWa2BF6cbBPE4ici
-//wOqkLDbsI3YZyUSj7ZPnefghx9EwRJfLB3/sXEf78OHL7yV6IMrvEVEAJCYs+3
-w/lspCMJC0hOomxnt0vjyCCd0JeaEwihQGbOo9V0reXzrUy8yNkwo1w8mMSbIvqh
-+D5uTB0jKL/ml1EVLw3NJf68MYIBmjCCAZYCAQEwgYAwezELMAkGA1UEBhMCU0cx
-ETAPBgNVBAoTCE0yQ3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UE
-AxMbTTJDcnlwdG8gQ2VydGlmaWNhdGUgTWFzdGVyMR0wGwYJKoZIhvcNAQkBFg5u
-Z3BzQHBvc3QxLmNvbQIBAjAJBgUrDgMCGgUAoIGxMBgGCSqGSIb3DQEJAzELBgkq
-hkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTAyMTIwODE3NTIyMVowIwYJKoZIhvcN
-AQkEMRYEFI/KcwJXhIg0bRzYLfAtDhxRMzghMFIGCSqGSIb3DQEJDzFFMEMwCgYI
-KoZIhvcNAwcwDgYIKoZIhvcNAwICAgCAMA0GCCqGSIb3DQMCAgFAMAcGBSsOAwIH
-MA0GCCqGSIb3DQMCAgEoMA0GCSqGSIb3DQEBAQUABEBrhZ8JVqGZ+S7dh+xKDwbF
-yRXiOQWEa2uxD1O5fD02VfGEzDSrV1sPdQ8AcM3o+ny5AyC11E4Fns2cIkXwZEwz
-
diff --git a/demo/smime/sendsmime.py b/demo/smime/sendsmime.py
deleted file mode 100644
index 9cc446b..0000000
--- a/demo/smime/sendsmime.py
+++ /dev/null
@@ -1,82 +0,0 @@
-#!/usr/bin/env python
-
-"""S/MIME sender.
-
-Copyright (c) 2000 Ng Pheng Siong. All rights reserved."""
-
-from M2Crypto import BIO, Rand, SMIME, X509
-import smtplib, string, sys
-
-def sendsmime(from_addr, to_addrs, subject, msg, from_key, from_cert=None, to_certs=None, smtpd='localhost'):
-
- msg_bio = BIO.MemoryBuffer(msg)
- sign = from_key
- encrypt = to_certs
-
- s = SMIME.SMIME()
- if sign:
- s.load_key(from_key, from_cert)
- p7 = s.sign(msg_bio, flags=SMIME.PKCS7_TEXT)
- msg_bio = BIO.MemoryBuffer(msg) # Recreate coz sign() has consumed it.
-
- if encrypt:
- sk = X509.X509_Stack()
- for x in to_certs:
- sk.push(X509.load_cert(x))
- s.set_x509_stack(sk)
- s.set_cipher(SMIME.Cipher('rc2_40_cbc'))
- tmp_bio = BIO.MemoryBuffer()
- if sign:
- s.write(tmp_bio, p7)
- else:
- tmp_bio.write(msg)
- p7 = s.encrypt(tmp_bio)
-
- out = BIO.MemoryBuffer()
- out.write('From: %s\r\n' % from_addr)
- out.write('To: %s\r\n' % string.join(to_addrs, ", "))
- out.write('Subject: %s\r\n' % subject)
- if encrypt:
- s.write(out, p7)
- else:
- if sign:
- s.write(out, p7, msg_bio, SMIME.PKCS7_TEXT)
- else:
- out.write('\r\n')
- out.write(msg)
- out.close()
-
- smtp = smtplib.SMTP()
- smtp.connect(smtpd)
- smtp.sendmail(from_addr, to_addrs, out.read())
- smtp.quit()
-
- # XXX Cleanup the stack and store.
-
-
-msg = """
-S/MIME - Secure Multipurpose Internet Mail Extensions [RFC 2311, RFC 2312] -
-provides a consistent way to send and receive secure MIME data. Based on the
-popular Internet MIME standard, S/MIME provides the following cryptographic
-security services for electronic messaging applications - authentication,
-message integrity and non-repudiation of origin (using digital signatures)
-and privacy and data security (using encryption).
-
-S/MIME is built on the PKCS #7 standard. [PKCS7]
-
-S/MIME is implemented in Netscape Messenger and Microsoft Outlook.
-"""
-
-
-if __name__ == '__main__':
- Rand.load_file('../randpool.dat', -1)
- sendsmime(from_addr = 'ngps@post1.com',
- to_addrs = ['jerry','ngps@post1.com'],
- subject = 'S/MIME testing',
- msg = msg,
- from_key = 'client2.pem',
- #from_key = None,
- #to_certs = None)
- to_certs = ['client.pem'])
- Rand.save_file('../randpool.dat')
-
diff --git a/demo/smime/test.py b/demo/smime/test.py
deleted file mode 100644
index a59cf9f..0000000
--- a/demo/smime/test.py
+++ /dev/null
@@ -1,192 +0,0 @@
-#!/usr/bin/env python
-
-"""S/MIME demo.
-
-Copyright (c) 2000 Ng Pheng Siong. All rights reserved."""
-
-from M2Crypto import BIO, Rand, SMIME, X509
-
-ptxt = """
-S/MIME - Secure Multipurpose Internet Mail Extensions [RFC 2311, RFC 2312] -
-provides a consistent way to send and receive secure MIME data. Based on the
-popular Internet MIME standard, S/MIME provides the following cryptographic
-security services for electronic messaging applications - authentication,
-message integrity and non-repudiation of origin (using digital signatures)
-and privacy and data security (using encryption).
-
-S/MIME is built on the PKCS #7 standard. [PKCS7]
-
-S/MIME is implemented in Netscape Messenger and Microsoft Outlook.
-"""
-
-def makebuf():
- buf = BIO.MemoryBuffer(ptxt)
- return buf
-
-def sign():
- print 'test sign & save...',
- buf = makebuf()
- s = SMIME.SMIME()
- s.load_key('client.pem')
- p7 = s.sign(buf)
- out = BIO.openfile('clear.p7', 'w')
- out.write('To: ngps@post1.com\n')
- out.write('From: ngps@post1.com\n')
- out.write('Subject: testing\n')
- buf = makebuf() # Recreate buf, because sign() has consumed it.
- s.write(out, p7, buf)
- out.close()
-
- buf = makebuf()
- p7 = s.sign(buf)
- out = BIO.openfile('opaque.p7', 'w')
- out.write('To: ngps@post1.com\n')
- out.write('From: ngps@mpost1.com\n')
- out.write('Subject: testing\n')
- s.write(out, p7)
- out.close()
- print 'ok'
-
-def verify_clear():
- print 'test load & verify clear...',
- s = SMIME.SMIME()
- x509 = X509.load_cert('client.pem')
- sk = X509.X509_Stack()
- sk.push(x509)
- s.set_x509_stack(sk)
- st = X509.X509_Store()
- st.load_info('ca.pem')
- s.set_x509_store(st)
- p7, data = SMIME.smime_load_pkcs7('clear.p7')
- v = s.verify(p7)
- if v:
- print 'ok'
- else:
- print 'not ok'
-
-def verify_opaque():
- print 'test load & verify opaque...',
- s = SMIME.SMIME()
- x509 = X509.load_cert('client.pem')
- sk = X509.X509_Stack()
- sk.push(x509)
- s.set_x509_stack(sk)
- st = X509.X509_Store()
- st.load_info('ca.pem')
- s.set_x509_store(st)
- p7, data = SMIME.smime_load_pkcs7('opaque.p7')
- v = s.verify(p7, data)
- if v:
- print 'ok'
- else:
- print 'not ok'
-
-def verify_netscape():
- print 'test load & verify netscape messager output...',
- s = SMIME.SMIME()
- #x509 = X509.load_cert('client.pem')
- sk = X509.X509_Stack()
- #sk.push(x509)
- s.set_x509_stack(sk)
- st = X509.X509_Store()
- st.load_info('ca.pem')
- s.set_x509_store(st)
- p7, data = SMIME.smime_load_pkcs7('ns.p7')
- v = s.verify(p7, data)
- print '\n', v, '\n...ok'
-
-
-def sv():
- print 'test sign/verify...',
- buf = makebuf()
- s = SMIME.SMIME()
-
- # Load a private key.
- s.load_key('client.pem')
-
- # Sign.
- p7 = s.sign(buf)
-
- # Output the stuff.
- bio = BIO.MemoryBuffer()
- s.write(bio, p7, buf)
-
- # Plumbing for verification: CA's cert.
- st = X509.X509_Store()
- st.load_info('ca.pem')
- s.set_x509_store(st)
-
- # Plumbing for verification: Signer's cert.
- x509 = X509.load_cert('client.pem')
- sk = X509.X509_Stack()
- sk.push(x509)
- s.set_x509_stack(sk)
-
- # Verify.
- p7, buf = SMIME.smime_load_pkcs7_bio(bio)
- v = s.verify(p7, flags=SMIME.PKCS7_DETACHED)
-
- if v:
- print 'ok'
- else:
- print 'not ok'
-
-def ed():
- print 'test encrypt/decrypt...',
- buf = makebuf()
- s = SMIME.SMIME()
-
- # Load target cert to encrypt to.
- x509 = X509.load_cert('client.pem')
- sk = X509.X509_Stack()
- sk.push(x509)
- s.set_x509_stack(sk)
-
- # Add a cipher.
- s.set_cipher(SMIME.Cipher('bf_cbc'))
-
- # Encrypt.
- p7 = s.encrypt(buf)
-
- # Load target's private key.
- s.load_key('client.pem')
-
- # Decrypt.
- data = s.decrypt(p7)
-
- if data:
- print 'ok'
- else:
- print 'not ok'
-
-
-def zope_test():
- print 'test zophistry...'
- f = open('client.pem')
- cert_str = f.read()
- key_bio = BIO.MemoryBuffer(cert_str)
- cert_bio = BIO.MemoryBuffer(cert_str) # XXX Kludge.
- s = SMIME.SMIME()
- s.load_key_bio(key_bio, cert_bio)
- # XXX unfinished...
-
-
-def leak_test():
- # Seems ok, not leaking.
- while 1:
- ed()
- #sv()
-
-
-if __name__ == '__main__':
- Rand.load_file('../randpool.dat', -1)
- ed()
- sign()
- verify_opaque()
- verify_clear()
- #verify_netscape()
- sv()
- #zope_test()
- #leak_test()
- Rand.save_file('../randpool.dat')
-
diff --git a/demo/smime/unsmime.py b/demo/smime/unsmime.py
deleted file mode 100644
index ffc40ad..0000000
--- a/demo/smime/unsmime.py
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/usr/bin/env python
-
-"""S/MIME demo.
-
-Copyright (c) 2000 Ng Pheng Siong. All rights reserved."""
-
-from M2Crypto import BIO, Rand, SMIME, X509
-import sys
-
-def decrypt_verify(p7file, recip_key, signer_cert, ca_cert):
- s = SMIME.SMIME()
-
- # Load decryption private key.
- s.load_key(recip_key)
-
- # Extract PKCS#7 blob from input.
- p7, bio = SMIME.smime_load_pkcs7_bio(p7file)
-
- # Decrypt.
- data = s.decrypt(p7)
-
- # Because we passed in a SignAndEnveloped blob, the output
- # of our decryption is a Signed blob. We now verify it.
-
- # Load the signer's cert.
- sk = X509.X509_Stack()
- s.set_x509_stack(sk)
-
- # Load the CA cert.
- st = X509.X509_Store()
- st.load_info(ca_cert)
- s.set_x509_store(st)
-
- # Verify.
- p7, bio = SMIME.smime_load_pkcs7_bio(BIO.MemoryBuffer(data))
- if bio is not None:
- # Netscape Messenger clear-signs, when also encrypting.
- data = s.verify(p7, bio)
- else:
- # M2Crypto's sendsmime.py opaque-signs, when also encrypting.
- data = s.verify(p7)
-
- print data
-
-
-if __name__ == '__main__':
- Rand.load_file('../randpool.dat', -1)
- decrypt_verify(BIO.File(sys.stdin), 'client.pem', 'client2.pem','ca.pem')
- Rand.save_file('../randpool.dat')
-
diff --git a/demo/ssl/README b/demo/ssl/README
deleted file mode 100644
index 07e43b8..0000000
--- a/demo/ssl/README
+++ /dev/null
@@ -1,25 +0,0 @@
- 29 Nov 00
------------
-
-This directory contains SSL clients and servers written as demos
-and testbeds.
-
-The oldest ones are s_server.py and s_client.py: these are modeled
-after the eponymous demo programs in OpenSSL. Once I got them going,
-I moved on to Medusa and other "real-world" servers. The pair has been
-in a state of neglect and quite likely no longer work with the current
-M2Crypto.
-
-My current testbeds are the echod-* servers and echo.py. These should
-always work. Note that Python on the three platforms that I test on
-are built --with-threads.
-
-
-Python 2.0's httplib introduces HTTP/1.1 functionality and an interface
-substantially different from Python 1.5.2's HTTP/1.0 interface.
-
-M2Crypto.httpslib provides both interfaces. The demo programs are
-https_cli.py and urllib_cli.py; these have been tested with
-Apache/1.3.14 (Unix) mod_ssl/2.7.1 OpenSSL/0.9.6.
-
-
diff --git a/demo/ssl/c.py b/demo/ssl/c.py
deleted file mode 100644
index bd03e6e..0000000
--- a/demo/ssl/c.py
+++ /dev/null
@@ -1,70 +0,0 @@
-#!/usr/bin/env python
-
-"""C programming in Python. Have SWIG sweat the pointers. ;-)
-
-Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
-
-from socket import *
-import sys
-
-from M2Crypto import SSL, m2
-
-HOST = '127.0.0.1'
-PORT = 9443
-req_10 = 'GET / HTTP/1.0\r\n\r\n'
-req_11 = 'GET / HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n'
-
-
-def c_10():
- c_style(HOST, PORT, req_10)
-
-
-def c_11():
- c_style(HOST, PORT, req_11)
-
-
-def c_style(HOST, PORT, req):
-
- # Set up SSL context.
- ctx = m2.ssl_ctx_new(m2.sslv3_method())
- m2.ssl_ctx_use_cert(ctx, 'client.pem')
- m2.ssl_ctx_use_privkey(ctx, 'client.pem')
-
- # Make the socket connection.
- s = socket(AF_INET, SOCK_STREAM)
- s.connect((HOST, PORT))
-
- # Set up the SSL connection.
- sbio = m2.bio_new_socket(s.fileno(), 0)
- ssl = m2.ssl_new(ctx)
- m2.ssl_set_bio(ssl, sbio, sbio)
- m2.ssl_connect(ssl)
- sslbio = m2.bio_new(m2.bio_f_ssl())
- m2.bio_set_ssl(sslbio, ssl, 0)
-
- # Push a buffering BIO over the SSL BIO.
- iobuf = m2.bio_new(m2.bio_f_buffer())
- topbio = m2.bio_push(iobuf, sslbio)
-
- # Send the request.
- m2.bio_write(sslbio, req)
-
- # Receive the response.
- while 1:
- data = m2.bio_gets(topbio, 4096)
- if not data: break
- sys.stdout.write(data)
-
- # Cleanup. May be missing some necessary steps. ;-|
- m2.bio_pop(topbio)
- m2.bio_free(iobuf)
- m2.ssl_shutdown(ssl)
- m2.ssl_free(ssl)
- m2.ssl_ctx_free(ctx)
- s.close()
-
-
-if __name__ == '__main__':
- c_10()
- c_11()
-
diff --git a/demo/ssl/c_bio.py b/demo/ssl/c_bio.py
deleted file mode 100644
index 1c20e91..0000000
--- a/demo/ssl/c_bio.py
+++ /dev/null
@@ -1,70 +0,0 @@
-#!/usr/bin/env python
-
-"""C programming in Python. Have SWIG sweat the pointers. ;-)
-
-Copyright (c) 1999-2000 Ng Pheng Siong. All rights reserved."""
-
-from socket import *
-import sys
-
-from M2Crypto import SSL, m2
-
-HOST = '127.0.0.1'
-PORT = 9443
-req_10 = 'GET / HTTP/1.0\r\n\r\n'
-req_11 = 'GET / HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n'
-
-
-def c_10():
- c_style(HOST, PORT, req_10)
-
-
-def c_11():
- c_style(HOST, PORT, req_11)
-
-
-def c_style(HOST, PORT, req):
-
- # Set up SSL context.
- ctx = m2.ssl_ctx_new(m2.sslv3_method())
- m2.ssl_ctx_use_cert(ctx, 'client.pem')
- m2.ssl_ctx_use_privkey(ctx, 'client.pem')
-
- # Make the socket connection.
- s = socket(AF_INET, SOCK_STREAM)
- s.connect((HOST, PORT))
-
- # Set up the SSL connection.
- sbio = m2.bio_new_socket(s.fileno(), 0)
- ssl = m2.ssl_new(ctx)
- m2.ssl_set_bio(ssl, sbio, sbio)
- m2.ssl_connect(ssl)
- sslbio = m2.bio_new(m2.bio_f_ssl())
- m2.bio_set_ssl(sslbio, ssl, 0)
-
- # Push a buffering BIO over the SSL BIO.
- iobuf = m2.bio_new(m2.bio_f_buffer())
- topbio = m2.bio_push(iobuf, sslbio)
-
- # Send the request.
- m2.bio_write(sslbio, req)
-
- # Receive the response.
- while 1:
- data = m2.bio_gets(topbio, 4096)
- if not data: break
- sys.stdout.write(data)
-
- # Cleanup. May be missing some necessary steps. ;-|
- m2.bio_pop(topbio)
- m2.bio_free(iobuf)
- m2.ssl_shutdown(ssl)
- m2.ssl_free(ssl)
- m2.ssl_ctx_free(ctx)
- s.close()
-
-
-if __name__ == '__main__':
- #c_10()
- c_11()
-
diff --git a/demo/ssl/ca.der b/demo/ssl/ca.der
deleted file mode 100644
index 8f4ed80..0000000
--- a/demo/ssl/ca.der
+++ /dev/null
Binary files differ
diff --git a/demo/ssl/ca.pem b/demo/ssl/ca.pem
deleted file mode 100644
index b7c84a1..0000000
--- a/demo/ssl/ca.pem
+++ /dev/null
@@ -1,20 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDWTCCAsKgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBgDELMAkGA1UEBhMCU0cx
-ETAPBgNVBAoTCE0yQ3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UE
-AxMbTTJDcnlwdG8gQ2VydGlmaWNhdGUgTWFzdGVyMSIwIAYJKoZIhvcNAQkBFhNu
-Z3BzQG5ldG1lbWV0aWMuY29tMB4XDTAxMTIxNTA1NTU0NloXDTA0MTIxNDA1NTU0
-NlowgYAxCzAJBgNVBAYTAlNHMREwDwYDVQQKEwhNMkNyeXB0bzEUMBIGA1UECxML
-TTJDcnlwdG8gQ0ExJDAiBgNVBAMTG00yQ3J5cHRvIENlcnRpZmljYXRlIE1hc3Rl
-cjEiMCAGCSqGSIb3DQEJARYTbmdwc0BuZXRtZW1ldGljLmNvbTCBnzANBgkqhkiG
-9w0BAQEFAAOBjQAwgYkCgYEAx8soJbS719LHK62VVVIQeC3oW0HvFArwPnA0LuEK
-q+LaqMOJg1rS7hvFdX03diV+XJw7cC0iECZYJNG4ii1xbY6KRmufkInaAwm54E3N
-e+YYVocaqUkcN6xVf6fwnLfPXbpFS/K2Umg11ObKMmi80JmiIdjcjRRCQZC7g1hf
-q+kCAwEAAaOB4DCB3TAdBgNVHQ4EFgQU6/qcBzEtQphfXLhiOHbt2KqBwMIwga0G
-A1UdIwSBpTCBooAU6/qcBzEtQphfXLhiOHbt2KqBwMKhgYakgYMwgYAxCzAJBgNV
-BAYTAlNHMREwDwYDVQQKEwhNMkNyeXB0bzEUMBIGA1UECxMLTTJDcnlwdG8gQ0Ex
-JDAiBgNVBAMTG00yQ3J5cHRvIENlcnRpZmljYXRlIE1hc3RlcjEiMCAGCSqGSIb3
-DQEJARYTbmdwc0BuZXRtZW1ldGljLmNvbYIBADAMBgNVHRMEBTADAQH/MA0GCSqG
-SIb3DQEBBAUAA4GBAD+I14GuS5vJmyv1k7mUMbAicsWRHZ+zrGOq9L/L2LsA+lKQ
-dAzEZE2+Zv8LBPJVltbJJhcFNJS/ZMAjEm4xlJuCpvXVMxd/M5AM29aqekWlIK7J
-vsdDL8IuzpRkMniUiNKPhmB6IPIOslvUKx6QofcE0wDh6pg4VvIbCjkpZ7gf
------END CERTIFICATE-----
diff --git a/demo/ssl/client.p12 b/demo/ssl/client.p12
deleted file mode 100644
index 9c7a640..0000000
--- a/demo/ssl/client.p12
+++ /dev/null
Binary files differ
diff --git a/demo/ssl/client.pem b/demo/ssl/client.pem
deleted file mode 100644
index c0274ad..0000000
--- a/demo/ssl/client.pem
+++ /dev/null
@@ -1,35 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDPzCCAqigAwIBAgIBBTANBgkqhkiG9w0BAQQFADCBgDELMAkGA1UEBhMCU0cx
-ETAPBgNVBAoTCE0yQ3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UE
-AxMbTTJDcnlwdG8gQ2VydGlmaWNhdGUgTWFzdGVyMSIwIAYJKoZIhvcNAQkBFhNu
-Z3BzQG5ldG1lbWV0aWMuY29tMB4XDTAzMDYyMjEzMzYyNFoXDTA0MDYyMTEzMzYy
-NFowOjELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRgwFgYDVQQDEw9N
-MkNyeXB0byBDbGllbnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOrvRK8h
-lTNZ6rSWfIR/DuNpq+gQ42FCem/ai/dLKCxWB2BMHLHVkfCtEsJpeltigIFgZ28E
-1h9Dx8RjP8R3lbTdJhv37j+3iUUq5lNXrlIWoKkyJsI4c1gC5kXke2z4uloj3W1E
-dWwOPjKxCi2OGKqwRxNzLrIlnBJ6WsP53PghAgMBAAGjggEMMIIBCDAJBgNVHRME
-AjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0
-ZTAdBgNVHQ4EFgQUMwLQdUUrkDAlEuZGt9fw/6N3mKswga0GA1UdIwSBpTCBooAU
-6/qcBzEtQphfXLhiOHbt2KqBwMKhgYakgYMwgYAxCzAJBgNVBAYTAlNHMREwDwYD
-VQQKEwhNMkNyeXB0bzEUMBIGA1UECxMLTTJDcnlwdG8gQ0ExJDAiBgNVBAMTG00y
-Q3J5cHRvIENlcnRpZmljYXRlIE1hc3RlcjEiMCAGCSqGSIb3DQEJARYTbmdwc0Bu
-ZXRtZW1ldGljLmNvbYIBADANBgkqhkiG9w0BAQQFAAOBgQBzJ2Q06/QM2f/OHBzo
-T0QpqAdWFmuclFecuKkzXOdh93cuCpJBrxBsMJMhvW10c7M9kEjW8GEt+obv2prt
-39WDZVejg83O2YUexJlUnhmA3Zc5izkOT0+VasIGSKgt/eQm9p6klk/LKcVEZGzh
-mI26dvftjo0HisrW5zfwEjzbdA==
------END CERTIFICATE-----
------BEGIN RSA PRIVATE KEY-----
-MIICXQIBAAKBgQDq70SvIZUzWeq0lnyEfw7jaavoEONhQnpv2ov3SygsVgdgTByx
-1ZHwrRLCaXpbYoCBYGdvBNYfQ8fEYz/Ed5W03SYb9+4/t4lFKuZTV65SFqCpMibC
-OHNYAuZF5Hts+LpaI91tRHVsDj4ysQotjhiqsEcTcy6yJZwSelrD+dz4IQIDAQAB
-AoGBAL8VDRBEiE3T/IoVPAGoNjvRXvjJg6c/osYHQ4BHqM0my6kPPueFhcXzfyaR
-E+vwGgUgnAA4NtAHGRwqfVsWyLNbeogKO6kEfGoLY+6wjxQrrLohSeS9EUyvqFzW
-dOC082piwzo61OK6q3iLplHPuQ6RK10VR1PQVVtpF/OuaxaBAkEA+6HpW7JTZswu
-WCxMkpT0mXBa6rEqVnkv6WiZyQoFNsqgsSotqifpcdH39mixji+sO9gaUI6uKtcU
-6SSlKRCYzQJBAO8DKaKh9Dq8U+nngc+s9NrkvfDDD0zzdoMznPmV8qQj50sPoJZF
-1nK0wMjaIRrKiMKceOHnFuJnpchKiZiEbKUCQQCk0QJ2azExjd91JV7qS+KCdhM2
-0eA3T51QNpE0GvobT1E9ebD7WLURNkRCA4T46sTXVc62oR33NXWe17/OS+6pAkAB
-FjiYPrhHlBellqHmedjbLfMXJyvoo6rESfXKxL3HtUoV80o9pK+m8d92ildgMc+R
-YvjBvjVCbko4sO4TPXbpAkAE53+iOITLFBeF3dTBh77LvDDHy4Z94knsWSzZv/aL
-26Zvjl5iZjHK6ECIe35kXzVYCWOgghI4ixHSMWOV3bt4
------END RSA PRIVATE KEY-----
diff --git a/demo/ssl/dh1024.pem b/demo/ssl/dh1024.pem
deleted file mode 100644
index 81d43f6..0000000
--- a/demo/ssl/dh1024.pem
+++ /dev/null
@@ -1,5 +0,0 @@
------BEGIN DH PARAMETERS-----
-MIGHAoGBAJf2QmHKtQXdKCjhPx1ottPb0PMTBH9A6FbaWMsTuKG/K3g6TG1Z1fkq
-/Gz/PWk/eLI9TzFgqVAuPvr3q14a1aZeVUMTgo2oO5/y2UHe6VaJ+trqCTat3xlx
-/mNbIK9HA2RgPC3gWfVLZQrY+gz3ASHHR5nXWHEyvpuZm7m3h+irAgEC
------END DH PARAMETERS-----
diff --git a/demo/ssl/echo-eg.py b/demo/ssl/echo-eg.py
deleted file mode 100644
index f7975d4..0000000
--- a/demo/ssl/echo-eg.py
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/usr/bin/env python
-
-"""Demo SSL client #1 for the HOWTO.
-
-Copyright (c) 1999-2001 Ng Pheng Siong. All rights reserved."""
-
-import getopt, sys
-from socket import gethostname
-from M2Crypto import Err, Rand, SSL, X509, threading
-
-host = '127.0.0.1'
-port = 9999
-
-optlist, optarg = getopt.getopt(sys.argv[1:], 'h:p:')
-for opt in optlist:
- if '-h' in opt:
- host = opt[1]
- elif '-p' in opt:
- port = int(opt[1])
-
-Rand.load_file('../randpool.dat', -1)
-
-ctx = SSL.Context('sslv3')
-ctx.load_cert('client.pem')
-#ctx.load_verify_info('ca.pem')
-ctx.set_verify(SSL.verify_peer, 10)
-ctx.set_info_callback()
-
-s = SSL.Connection(ctx)
-s.connect((host, port))
-print 'Host =', gethostname()
-print 'Cipher =', s.get_cipher().name()
-
-peer = s.get_peer_cert()
-print 'Server =', peer.get_subject().CN
-
-while 1:
- data = s.recv()
- if not data:
- break
- sys.stdout.write(data)
- sys.stdout.flush()
- buf = sys.stdin.readline()
- if not buf:
- break
- s.send(buf)
-
-s.close()
-
-Rand.save_file('../randpool.dat')
-
diff --git a/demo/ssl/echo.py b/demo/ssl/echo.py
deleted file mode 100644
index 912e248..0000000
--- a/demo/ssl/echo.py
+++ /dev/null
@@ -1,59 +0,0 @@
-#!/usr/bin/env python
-
-"""A simple SSL 'echo' client.
-
-Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
-
-import getopt, sys
-from socket import gethostname
-from M2Crypto import Err, Rand, SSL, X509
-
-host = '127.0.0.1'
-port = 9999
-
-optlist, optarg = getopt.getopt(sys.argv[1:], 'h:p:')
-for opt in optlist:
- if '-h' in opt:
- host = opt[1]
- elif '-p' in opt:
- port = int(opt[1])
-
-Rand.load_file('../randpool.dat', -1)
-
-ctx = SSL.Context('sslv3')
-ctx.load_cert_chain('client.pem')
-#ctx.set_verify(SSL.verify_none, 10)
-ctx.set_verify(SSL.verify_peer, 10, SSL.cb.ssl_verify_callback)
-ctx.load_verify_locations('ca.pem')
-#ctx.set_allow_unknown_ca(1)
-ctx.set_info_callback()
-
-s = SSL.Connection(ctx)
-s.connect((host, port))
-print 'Host =', gethostname()
-print 'Cipher =', s.get_cipher().name()
-
-## 2003-06-28, ngps: Depends on ctx.set_verify() above, RTFM for details.
-## v = s.get_verify_result()
-## if v != X509.V_OK:
-## s.close()
-## raise SystemExit, 'Server verification failed'
-
-peer = s.get_peer_cert()
-print 'Server =', str(peer.get_subject())
-
-while 1:
- data = s.recv()
- if not data:
- break
- sys.stdout.write(data)
- sys.stdout.flush()
- buf = sys.stdin.readline()
- if not buf:
- break
- s.send(buf)
-
-s.close()
-
-Rand.save_file('../randpool.dat')
-
diff --git a/demo/ssl/echod-async.py b/demo/ssl/echod-async.py
deleted file mode 100644
index 0881c76..0000000
--- a/demo/ssl/echod-async.py
+++ /dev/null
@@ -1,112 +0,0 @@
-#!/usr/bin/env python
-
-"""An asyncore-based SSL 'echo' server.
-
-Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
-
-import asyncore, errno, socket, time
-from M2Crypto import Rand, SSL
-import echod_lib
-
-class ssl_echo_channel(asyncore.dispatcher):
-
- buffer = 'Ye Olde Echo Servre\r\n'
-
- def __init__(self, conn):
- asyncore.dispatcher.__init__(self, conn)
- self._ssl_accepting = 1
- self.peer = self.get_peer_cert()
-
- def handle_connect(self):
- pass
-
- def handle_close(self):
- self.close()
-
- def writable(self):
- return self._ssl_accepting or (len(self.buffer) > 0)
-
- def handle_write(self):
- if self._ssl_accepting:
- s = self.socket.accept_ssl()
- if s:
- self._ssl_accepting = 0
- else:
- try:
- n = self.send(self.buffer)
- if n == -1:
- pass
- elif n == 0:
- self.handle_close()
- else:
- self.buffer = self.buffer[n:]
- except SSL.SSLError, what:
- if str(what) == 'unexpected eof':
- self.handle_close()
- return
- else:
- raise
-
- def readable(self):
- return 1
-
- def handle_read(self):
- if self._ssl_accepting:
- s = self.socket.accept_ssl()
- if s:
- self._ssl_accepting = 0
- else:
- try:
- blob = self.recv(4096)
- if blob is None:
- pass
- elif blob == '':
- self.handle_close()
- else:
- self.buffer = self.buffer + blob
- except SSL.SSLError, what:
- if str(what) == 'unexpected eof':
- self.handle_close()
- return
- else:
- raise
-
-
-class ssl_echo_server(SSL.ssl_dispatcher):
-
- channel_class=ssl_echo_channel
-
- def __init__(self, addr, port, ssl_context):
- SSL.ssl_dispatcher.__init__(self)
- self.create_socket(ssl_context)
- self.set_reuse_addr()
- self.socket.setblocking(0)
- self.bind((addr, port))
- self.listen(5)
- self.ssl_ctx=ssl_context
-
- def handle_accept(self):
- try:
- sock, addr = self.socket.accept()
- self.channel_class(sock)
- except:
- print '-'*40
- import traceback
- traceback.print_exc()
- print '-'*40
- return
-
- def writable(self):
- return 0
-
-
-if __name__=='__main__':
- Rand.load_file('../randpool.dat', -1)
- ctx = echod_lib.init_context('sslv23', 'server.pem', 'ca.pem', \
- #SSL.verify_peer | SSL.verify_fail_if_no_peer_cert)
- SSL.verify_none)
- ctx.set_tmp_dh('dh1024.pem')
- ssl_echo_server('', 9999, ctx)
- asyncore.loop()
- Rand.save_file('../randpool.dat')
-
diff --git a/demo/ssl/echod-eg1.py b/demo/ssl/echod-eg1.py
deleted file mode 100644
index 87358b7..0000000
--- a/demo/ssl/echod-eg1.py
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/usr/bin/env python
-
-"""Demo SSL server #1 for the HOWTO.
-
-Copyright (c) 1999-2001 Ng Pheng Siong. All rights reserved."""
-
-import SocketServer
-from M2Crypto import Err, Rand, SSL, threading
-
-def init_context(protocol, dhpfile, certfile, cafile, verify, verify_depth=10):
- ctx = SSL.Context(protocol)
- ctx.set_tmp_dh(dhpfile)
- ctx.load_cert(certfile)
- #ctx.load_verify_info(cafile)
- ctx.set_verify(verify, verify_depth)
- ctx.set_session_id_ctx('echod')
- ctx.set_info_callback()
- return ctx
-
-class ssl_echo_handler(SocketServer.BaseRequestHandler):
-
- buffer = 'Ye Olde Echo Servre\r\n'
-
- def handle(self):
- peer = self.request.get_peer_cert()
- if peer is not None:
- print 'Client CA =', peer.get_issuer().O
- print 'Client Subject =', peer.get_subject().CN
- self.request.write(self.buffer)
- while 1:
- buf = self.request.read()
- if not buf:
- break
- self.request.write(buf)
-
- def finish(self):
- self.request.set_shutdown(SSL.SSL_SENT_SHUTDOWN|SSL.SSL_RECEIVED_SHUTDOWN)
- self.request.close()
-
-if __name__ == '__main__':
- Rand.load_file('randpool.dat', -1)
- threading.init()
- ctx = init_context('sslv23', 'dh1024.pem', 'server.pem', 'ca.pem', SSL.verify_peer)
- s = SSL.SSLServer(('', 9999), ssl_echo_handler, ctx)
- s.serve_forever()
- threading.cleanup()
- Rand.save_file('randpool.dat')
-
-
diff --git a/demo/ssl/echod-forking.py b/demo/ssl/echod-forking.py
deleted file mode 100644
index 43faab3..0000000
--- a/demo/ssl/echod-forking.py
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/usr/bin/env python
-
-"""A forking SSL 'echo' server.
-
-Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
-
-from M2Crypto import DH, Rand, SSL
-import echod_lib
-
-class ssl_echo_handler(echod_lib.ssl_echo_handler):
- buffer = 'Ye Olde Forking Echo Servre\r\n'
-
-
-if __name__ == '__main__':
- Rand.load_file('../randpool.dat', -1)
- ctx = echod_lib.init_context('sslv23', 'server.pem', 'ca.pem',
- SSL.verify_peer | SSL.verify_fail_if_no_peer_cert)
- ctx.set_tmp_dh('dh1024.pem')
- s = SSL.ForkingSSLServer(('', 9999), ssl_echo_handler, ctx)
- s.serve_forever()
- Rand.save_file('../randpool.dat')
-
diff --git a/demo/ssl/echod-iterative.py b/demo/ssl/echod-iterative.py
deleted file mode 100644
index 2e68699..0000000
--- a/demo/ssl/echod-iterative.py
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/usr/bin/env python
-
-"""A simple iterative SSL 'echo' server.
-
-Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
-
-from M2Crypto import Rand, SSL
-import echod_lib
-
-class ssl_echo_handler(echod_lib.ssl_echo_handler):
- buffer='Ye Olde One-At-A-Time Echo Servre\r\n'
-
-
-if __name__=='__main__':
- Rand.load_file('../randpool.dat', -1)
- ctx=echod_lib.init_context('sslv23', 'server.pem', 'ca.pem', \
- SSL.verify_peer | SSL.verify_fail_if_no_peer_cert)
- #SSL.verify_none)
- ctx.set_tmp_dh('dh1024.pem')
- s=SSL.SSLServer(('', 9999), ssl_echo_handler, ctx)
- s.serve_forever()
- Rand.save_file('../randpool.dat')
-
diff --git a/demo/ssl/echod-thread.py b/demo/ssl/echod-thread.py
deleted file mode 100644
index 65db811..0000000
--- a/demo/ssl/echod-thread.py
+++ /dev/null
@@ -1,55 +0,0 @@
-#!/usr/bin/env python
-
-"""Another multi-threading SSL 'echo' server.
-
-Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
-
-from M2Crypto import Rand, SSL, threading
-import echod_lib
-
-import thread
-from socket import *
-
-buffer='Ye Newe Threading Echo Servre\r\n'
-
-def echo_handler(sslctx, sock, addr):
- sslconn = SSL.Connection(sslctx, sock)
- sslconn.setup_addr(addr)
- sslconn.setup_ssl()
- sslconn.set_accept_state()
- sslconn.accept_ssl()
- sslconn.write(buffer)
- while 1:
- try:
- buf = sslconn.read()
- if not buf:
- break
- sslconn.write(buf)
- except SSL.SSLError, what:
- if str(what) == 'unexpected eof':
- break
- else:
- raise
- except:
- break
- # Threading servers need this.
- sslconn.set_shutdown(SSL.SSL_RECEIVED_SHUTDOWN|SSL.SSL_SENT_SHUTDOWN)
- sslconn.close()
-
-
-if __name__=='__main__':
- threading.init()
- Rand.load_file('../randpool.dat', -1)
- ctx=echod_lib.init_context('sslv23', 'server.pem', 'ca.pem',
- SSL.verify_peer | SSL.verify_fail_if_no_peer_cert)
- ctx.set_tmp_dh('dh1024.pem')
- sock = socket(AF_INET, SOCK_STREAM)
- sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
- sock.bind(('', 9999))
- sock.listen(5)
- while 1:
- conn, addr = sock.accept()
- thread.start_new_thread(echo_handler, (ctx, conn, addr))
- Rand.save_file('../randpool.dat')
- threading.cleanup()
-
diff --git a/demo/ssl/echod-threading.py b/demo/ssl/echod-threading.py
deleted file mode 100644
index 81eaef3..0000000
--- a/demo/ssl/echod-threading.py
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/env python
-
-"""A multi-threading SSL 'echo' server.
-
-Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
-
-from M2Crypto import DH, Rand, SSL, threading
-import echod_lib
-
-class ssl_echo_handler(echod_lib.ssl_echo_handler):
-
- buffer='Ye Olde Threading Echo Servre\r\n'
-
- def finish(self):
- # Threading servers need this.
- self.request.set_shutdown(SSL.SSL_SENT_SHUTDOWN|SSL.SSL_RECEIVED_SHUTDOWN)
- self.request.close()
-
-
-if __name__=='__main__':
- try:
- threading.init()
- Rand.load_file('../randpool.dat', -1)
- ctx=echod_lib.init_context('sslv23', 'server.pem', 'ca.pem',
- SSL.verify_peer | SSL.verify_fail_if_no_peer_cert)
- ctx.set_tmp_dh('dh1024.pem')
- s=SSL.ThreadingSSLServer(('', 9999), ssl_echo_handler, ctx)
- s.serve_forever()
- Rand.save_file('../randpool.dat')
- except:
- threading.cleanup()
-
diff --git a/demo/ssl/echod_lib.py b/demo/ssl/echod_lib.py
deleted file mode 100644
index 7bea683..0000000
--- a/demo/ssl/echod_lib.py
+++ /dev/null
@@ -1,45 +0,0 @@
-"""Support routines for the various SSL 'echo' servers.
-
-Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
-
-import SocketServer
-from M2Crypto import SSL
-
-def init_context(protocol, certfile, cafile, verify, verify_depth=10):
- ctx = SSL.Context(protocol)
- ctx.load_cert_chain(certfile)
- ctx.load_verify_locations(cafile)
- ctx.set_client_CA_list_from_file(cafile)
- ctx.set_verify(verify, verify_depth)
- #ctx.set_allow_unknown_ca(1)
- ctx.set_session_id_ctx('echod')
- ctx.set_info_callback()
- return ctx
-
-
-class ssl_echo_handler(SocketServer.BaseRequestHandler):
-
- buffer = 'Ye Olde Echo Servre\r\n'
-
- def handle(self):
- peer = self.request.get_peer_cert()
- if peer is not None:
- print 'Client CA =', peer.get_issuer().O
- print 'Client Subject =', peer.get_subject().CN
- x = self.request.write(self.buffer)
- while 1:
- try:
- buf = self.request.read()
- if not buf:
- break
- self.request.write(buf)
- except SSL.SSLError, what:
- if str(what) == 'unexpected eof':
- break
- else:
- raise
-
- def finish(self):
- self.request.close()
-
-
diff --git a/demo/ssl/ftp_tls.py b/demo/ssl/ftp_tls.py
deleted file mode 100644
index 163d87c..0000000
--- a/demo/ssl/ftp_tls.py
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/usr/bin/env python
-
-"""Demo for M2Crypto.ftpslib's FTP/TLS client.
-
-This client interoperates with M2Crypto's Medusa-based FTP/TLS
-server as well as Peter Runestig's patched-for-TLS OpenBSD FTP
-server.
-
-Copyright (c) 1999-2004 Ng Pheng Siong. All rights reserved."""
-
-from M2Crypto import SSL, ftpslib, threading
-
-def passive():
- ctx = SSL.Context('sslv23')
- f = ftpslib.FTP_TLS(ssl_ctx=ctx)
- f.connect('127.0.0.1', 39021)
- f.auth_tls()
- f.set_pasv(1)
- f.login('ftp', 'ngps@')
- f.prot_p()
- f.retrlines('LIST')
- f.quit()
-
-def active():
- ctx = SSL.Context('sslv23')
- f = ftpslib.FTP_TLS(ssl_ctx=ctx)
- f.connect('127.0.0.1', 39021)
- f.auth_tls()
- f.set_pasv(0)
- f.login('ftp', 'ngps@')
- f.prot_p()
- f.retrlines('LIST')
- f.quit()
-
-
-if __name__ == '__main__':
- threading.init()
- active()
- passive()
- threading.cleanup()
-
diff --git a/demo/ssl/http_cli_20.py b/demo/ssl/http_cli_20.py
deleted file mode 100644
index 0ce4cef..0000000
--- a/demo/ssl/http_cli_20.py
+++ /dev/null
@@ -1,22 +0,0 @@
-import httplib, sys
-
-def test_httplib():
- h = httplib.HTTPConnection('127.0.0.1', 80)
- h.set_debuglevel(1)
- h.putrequest('GET', '/')
- h.putheader('Accept', 'text/html')
- h.putheader('Accept', 'text/plain')
- h.putheader('Connection', 'close')
- h.endheaders()
- resp = h.getresponse()
- f = resp.fp
- while 1:
- data = f.readline()
- if not data:
- break
- sys.stdout.write(data)
- f.close()
- h.close()
-
-if __name__=='__main__':
- test_httplib()
diff --git a/demo/ssl/https_cli.py b/demo/ssl/https_cli.py
deleted file mode 100644
index 543ba8f..0000000
--- a/demo/ssl/https_cli.py
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/env python
-
-"""Demonstrations of M2Crypto.httpslib.
-
-Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
-
-import sys
-from M2Crypto import Rand, SSL, httpslib, threading
-
-
-def test_httpslib():
- ctx = SSL.Context('sslv23')
- ctx.load_cert_chain('client.pem')
- ctx.load_verify_locations('ca.pem', '')
- ctx.set_verify(SSL.verify_peer, 10)
- ctx.set_info_callback()
- h = httpslib.HTTPSConnection('localhost', 19443, ssl_context=ctx)
- h.set_debuglevel(1)
- h.putrequest('GET', '/')
- h.putheader('Accept', 'text/html')
- h.putheader('Accept', 'text/plain')
- h.putheader('Connection', 'close')
- h.endheaders()
- resp = h.getresponse()
- f = resp.fp
- c = 0
- while 1:
- # Either of following two works.
- #data = f.readline(4096)
- data = resp.read(4096)
- if not data: break
- c = c + len(data)
- #print data
- sys.stdout.write(data)
- sys.stdout.flush()
- f.close()
- h.close()
-
-if __name__=='__main__':
- Rand.load_file('../randpool.dat', -1)
- #threading.init()
- test_httpslib()
- #threading.cleanup()
- Rand.save_file('../randpool.dat')
-
diff --git a/demo/ssl/https_cli_async.py b/demo/ssl/https_cli_async.py
deleted file mode 100644
index 9e7a5d0..0000000
--- a/demo/ssl/https_cli_async.py
+++ /dev/null
@@ -1,106 +0,0 @@
-#!/usr/bin/env python
-
-"""Demo for client-side ssl_dispatcher usage. Note that connect()
-is blocking. (Need fix?)
-
-This isn't really a HTTPS client; it's just a toy.
-
-Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
-
-import asyncore, sys, time
-from M2Crypto import Rand, SSL
-
-class https_client(SSL.ssl_dispatcher):
-
- def __init__(self, host, path, ssl_ctx):
- SSL.ssl_dispatcher.__init__(self)
- self.path = path
- self.buffer = 'GET %s HTTP/1.0\r\n\r\n' % self.path
- self.create_socket(ssl_ctx)
- self.socket.connect((host, 19443))
- self._can_read = 1
- self._count = 0
-
- def handle_connect(self):
- pass
-
- def readable(self):
- return self._can_read
-
- def handle_read(self):
- try:
- result = self.recv()
- if result is None:
- return
- elif result == '':
- self._can_read = 0
- sys.stdout.write('%s: total: %5d\n' % (self.path, self._count,))
- sys.stdout.flush()
- self.close()
- else:
- #print result
- l = len(result)
- self._count = self._count + l
- display = (time.time(), l, self.path)
- sys.stdout.write('%14.3f: read %5d from %s\n' % display)
- sys.stdout.flush()
- except SSL.SSLError, why:
- print 'handle_read:', why
- self.close()
- raise
-
- def writable(self):
- return (len(self.buffer) > 0)
-
- def handle_write(self):
- try:
- sent = self.send(self.buffer)
- self.buffer = self.buffer[sent:]
- except SSL.SSLError, why:
- print 'handle_write:', why
- self.close()
-
-
-if __name__ == '__main__':
- Rand.load_file('../randpool.dat', -1)
- ctx = SSL.Context()
- url = ('/jdk118/api/u-names.html',
- '/postgresql/xfunc-c.html',
- '/python2.1/modindex.html')
- for u in url:
- https_client('localhost', u, ctx)
- asyncore.loop()
- Rand.save_file('../randpool.dat')
-
-
-# Here's a sample output. Server is Apache+mod_ssl on localhost.
-# $ python https_cli_async.py
-# 991501090.682: read 278 from /python2.1/modindex.html
-# 991501090.684: read 278 from /postgresql/xfunc-c.html
-# 991501090.742: read 4096 from /postgresql/xfunc-c.html
-# 991501090.743: read 4096 from /postgresql/xfunc-c.html
-# 991501090.744: read 4096 from /postgresql/xfunc-c.html
-# 991501090.744: read 4096 from /postgresql/xfunc-c.html
-# 991501090.755: read 4096 from /postgresql/xfunc-c.html
-# 991501090.756: read 278 from /jdk118/api/u-names.html
-# 991501090.777: read 4096 from /postgresql/xfunc-c.html
-# 991501090.778: read 4096 from /postgresql/xfunc-c.html
-# 991501090.778: read 4096 from /postgresql/xfunc-c.html
-# 991501090.782: read 4096 from /postgresql/xfunc-c.html
-# 991501090.813: read 4096 from /python2.1/modindex.html
-# 991501090.839: read 4096 from /jdk118/api/u-names.html
-# 991501090.849: read 4096 from /python2.1/modindex.html
-# 991501090.873: read 3484 from /postgresql/xfunc-c.html
-# 991501090.874: read 4096 from /jdk118/api/u-names.html
-# 991501090.874: read 4096 from /python2.1/modindex.html
-#/postgresql/xfunc-c.html: total: 40626
-# 991501090.886: read 4096 from /jdk118/api/u-names.html
-# 991501090.886: read 2958 from /python2.1/modindex.html
-# 991501090.887: read 4096 from /jdk118/api/u-names.html
-#/python2.1/modindex.html: total: 15524
-# 991501090.893: read 4096 from /jdk118/api/u-names.html
-# 991501090.894: read 2484 from /jdk118/api/u-names.html
-#/jdk118/api/u-names.html: total: 23242
-# $
-
-
diff --git a/demo/ssl/https_srv.py b/demo/ssl/https_srv.py
deleted file mode 100644
index 6d12d80..0000000
--- a/demo/ssl/https_srv.py
+++ /dev/null
@@ -1,150 +0,0 @@
-"""This server extends BaseHTTPServer and SimpleHTTPServer thusly:
-1. One thread per connection.
-2. Generates directory listings.
-
-In addition, it has the following properties:
-1. Works over HTTPS only.
-2. Displays SSL handshaking and SSL session info.
-3. Performs SSL renegotiation when a magic url is requested.
-
-TODO:
-1. Cache stat() of directory entries.
-2. Fancy directory indexing.
-3. Interface ZPublisher.
-
-Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved.
-"""
-
-import os, sys
-from SimpleHTTPServer import SimpleHTTPRequestHandler
-
-from M2Crypto import Rand, SSL
-from M2Crypto.SSL.SSLServer import ThreadingSSLServer
-
-try:
- from cStringIO import StringIO
-except ImportError:
- from StringIO import StringIO
-
-
-def mkdirlist(path, url):
- dirlist = os.listdir(path)
- dirlist.sort()
- f = StringIO()
- f.write('<title>Index listing for %s</title>\r\n' % (url,))
- f.write('<h1>Index listing for %s</h1>\r\n' % (url,))
- f.write('<pre>\r\n')
- for d in dirlist:
- if os.path.isdir(os.path.join(path, d)):
- d2 = d + '/'
- else:
- d2 = d
- if url == '/':
- f.write('<a href="/%s">%s</a><br>\r\n' % (d, d2))
- else:
- f.write('<a href="%s/%s">%s</a><br>\r\n' % (url, d, d2))
- f.write('</pre>\r\n\r\n')
- f.reset()
- return f
-
-
-class HTTP_Handler(SimpleHTTPRequestHandler):
-
- server_version = "https_srv/0.1"
- reneg = 0
-
- # Cribbed from SimpleHTTPRequestHander to add the ".der" entry,
- # which facilitates installing your own certificates into browsers.
- extensions_map = {
- '': 'text/plain', # Default, *must* be present
- '.html': 'text/html',
- '.htm': 'text/html',
- '.gif': 'image/gif',
- '.jpg': 'image/jpeg',
- '.jpeg': 'image/jpeg',
- '.der': 'application/x-x509-ca-cert'
- }
-
- def send_head(self):
- if self.path[1:8] == '_reneg_':
- self.reneg = 1
- self.path = self.path[8:]
- path = self.translate_path(self.path)
- if os.path.isdir(path):
- f = mkdirlist(path, self.path)
- filetype = 'text/html'
- else:
- try:
- f = open(path, 'rb')
- filetype = self.guess_type(path)
- except IOError:
- self.send_error(404, "File not found")
- return None
- self.send_response(200)
- self.send_header("Content-type", filetype)
- self.end_headers()
- return f
-
- def do_GET(self):
- #sess = self.request.get_session()
- #self.log_message('\n%s', sess.as_text())
- f = self.send_head()
- if self.reneg:
- self.reneg = 0
- self.request.renegotiate()
- sess = self.request.get_session()
- self.log_message('\n%s', sess.as_text())
- if f:
- self.copyfile(f, self.wfile)
- f.close()
-
- def do_HEAD(self):
- #sess = self.request.get_session()
- #self.log_message('\n%s', sess.as_text())
- f = self.send_head()
- if f:
- f.close()
-
-
-class HTTPS_Server(ThreadingSSLServer):
- def __init__(self, server_addr, handler, ssl_ctx):
- ThreadingSSLServer.__init__(self, server_addr, handler, ssl_ctx)
- self.server_name = server_addr[0]
- self.server_port = server_addr[1]
-
- def finish(self):
- self.request.set_shutdown(SSL.SSL_RECEIVED_SHUTDOWN | SSL.SSL_SENT_SHUTDOWN)
- self.request.close()
-
-
-def init_context(protocol, certfile, cafile, verify, verify_depth=10):
- ctx=SSL.Context(protocol)
- ctx.load_cert(certfile)
- ctx.load_client_ca(cafile)
- ctx.load_verify_info(cafile)
- ctx.set_verify(verify, verify_depth)
- ctx.set_allow_unknown_ca(1)
- ctx.set_session_id_ctx('https_srv')
- ctx.set_info_callback()
- return ctx
-
-
-if __name__ == '__main__':
- from M2Crypto import threading as m2threading
- m2threading.init()
- if len(sys.argv) < 2:
- wdir = '.'
- else:
- wdir = sys.argv[1]
- Rand.load_file('../randpool.dat', -1)
- ctx = init_context('sslv23', 'server.pem', 'ca.pem', \
- SSL.verify_none)
- #SSL.verify_peer | SSL.verify_fail_if_no_peer_cert)
- ctx.set_tmp_dh('dh1024.pem')
- os.chdir(wdir)
- httpsd = HTTPS_Server(('', 19443), HTTP_Handler, ctx)
- httpsd.serve_forever()
- Rand.save_file('../randpool.dat')
- m2threading.cleanup()
-
-
diff --git a/demo/ssl/myapp.py b/demo/ssl/myapp.py
deleted file mode 100644
index bb024d8..0000000
--- a/demo/ssl/myapp.py
+++ /dev/null
@@ -1,30 +0,0 @@
-"""
-Sample application for socklib and somelib.
-
-Copyright (c) 2007 Open Source Applications Foundation.
-All rights reserved.
-"""
-
-# Sample application that uses socklib to override socket.ssl in order
-# to make the 3rd party library use M2Crypto for SSL, instead of python
-# stdlib SSL.
-
-import socklib # sets M2Crypto.SSL.Connection as socket.ssl
-
-# Set up the secure context for socklib
-from M2Crypto import SSL
-
-def getContext():
- ctx = SSL.Context()
- ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, 9)
- ctx.load_verify_locations('ca.pem')
- return ctx
-
-socklib.setSSLContextFactory(getContext)
-
-# Import and use 3rd party lib
-import somelib
-
-if __name__ == '__main__':
- c = somelib.HttpsGetSlash()
- c.get('verisign.com', 443)
diff --git a/demo/ssl/s_client.py b/demo/ssl/s_client.py
deleted file mode 100644
index 021e3db..0000000
--- a/demo/ssl/s_client.py
+++ /dev/null
@@ -1,108 +0,0 @@
-#!/usr/bin/env python
-
-"""An M2Crypto implementation of OpenSSL's s_client.
-
-Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
-
-from socket import *
-import getopt
-import string
-import sys
-
-from M2Crypto import SSL
-
-# s_server -www
-HOST='127.0.0.1'
-PORT=4433
-REQ='GET / HTTP/1.0\r\n\r\n'
-
-class Config:
- pass
-
-def config(args):
- options=['connect=', 'verify=', 'cert=', 'key=', 'CApath=', 'CAfile=', \
- 'reconnect', 'pause', 'showcerts', 'debug', 'nbio_test', 'state', \
- 'nbio', 'crlf', 'sslv2', 'sslv3', 'tlsv1', 'no_sslv2', 'no_sslv3', \
- 'no_tlsv1', 'bugs', 'cipher=', 'Verify=']
- optlist, optarg=getopt.getopt(args, '', options)
-
- cfg=Config()
- for opt in optlist:
- setattr(cfg, opt[0][2:], opt[1])
- for x in (('tlsv1','no_tlsv1'),('sslv3','no_sslv3'),('sslv2','no_sslv2')):
- if hasattr(cfg, x[0]) and hasattr(cfg, x[1]):
- raise ValueError, 'mutually exclusive: %s and %s' % x
-
- if hasattr(cfg, 'connect'):
- (host, port)=string.split(cfg.connect, ':')
- cfg.connect=(host, int(port))
- else:
- cfg.connect=(HOST, PORT)
-
- cfg.protocol=[]
- # First protocol found will be used.
- # Permutate the following tuple for preference.
- for p in ('tlsv1', 'sslv3', 'sslv2'):
- if hasattr(cfg, p):
- cfg.protocol.append(p)
- cfg.protocol.append('sslv23')
-
- return cfg
-
-def make_context(config):
- ctx=SSL.Context(config.protocol[0])
- if hasattr(config, 'cert'):
- cert=config.cert
- else:
- cert='client.pem'
- if hasattr(config, 'key'):
- key=config.key
- else:
- key='client.pem'
- #ctx.load_cert(cert, key)
-
- if hasattr(config, 'verify'):
- verify=SSL.verify_peer
- depth=int(config.verify)
- elif hasattr(config, 'Verify'):
- verify=SSL.verify_peer | SSL.verify_fail_if_no_peer_cert
- depth=int(config.Verify)
- else:
- verify=SSL.verify_none
- depth=10
- config.verify=verify
- config.verify_depth=depth
- ctx.set_verify(verify, depth)
-
- if hasattr(config, 'CAfile'):
- cafile=config.CAfile
- else:
- cafile='ca.pem'
- ctx.load_verify_location(cafile)
-
- return ctx
-
-def s_client(config):
- ctx=make_context(config)
- s=SSL.Connection(ctx)
- s.connect(config.connect)
- if config.verify != SSL.verify_none and not s.verify_ok():
- print 'peer verification failed'
- peer=s.get_peer_cert()
- if peer is None:
- print 'unable to get peer certificate'
- else:
- print 'peer.as_text()'
- raise SystemExit
- s.send(REQ)
- while 1:
- data=s.recv()
- if not data:
- break
- print data
- s.close()
-
-if __name__=='__main__':
- cfg=config(sys.argv[1:])
- s_client(cfg)
-
diff --git a/demo/ssl/s_server.py b/demo/ssl/s_server.py
deleted file mode 100644
index 84789a1..0000000
--- a/demo/ssl/s_server.py
+++ /dev/null
@@ -1,203 +0,0 @@
-#!/usr/bin/env python
-
-"""An M2Crypto implementation of OpenSSL's s_server.
-
-Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
-
-from socket import *
-import asyncore
-import cStringIO
-import getopt
-import string
-import sys
-
-from M2Crypto import SSL, BIO, DH, Err
-
-# s_server -www
-HOST=''
-PORT=4433
-
-class Config:
- pass
-
-def config(args):
- options=['accept=', 'context=', 'verify=', 'Verify=', 'cert=', 'key=', \
- 'dcert=', 'dkey=', 'nocert', 'crlf', 'debug', 'CApath=', 'CAfile=', \
- 'quiet', 'no_tmp_rsa', 'state', 'sslv2', 'sslv3', 'tlsv1', \
- 'no_sslv2', 'no_sslv3', 'no_tlsv1', 'bugs', 'cipher=']
- optlist, optarg=getopt.getopt(args, '', options)
-
- cfg=Config()
- for opt in optlist:
- setattr(cfg, opt[0][2:], opt[1])
- for x in (('tlsv1','no_tlsv1'),('sslv3','no_sslv3'),('sslv2','no_sslv2')):
- if hasattr(cfg, x[0]) and hasattr(cfg, x[1]):
- raise ValueError, 'mutually exclusive: %s and %s' % x
-
- if hasattr(cfg, 'accept'):
- cfg.accept=string.split(cfg.connect, ':')
- else:
- cfg.accept=(HOST, PORT)
-
- cfg.protocol=[]
- # First protocol found will be used.
- # Permutate the following tuple for preference.
- for p in ('tlsv1', 'sslv3', 'sslv2'):
- if hasattr(cfg, p):
- cfg.protocol.append(p)
- cfg.protocol.append('sslv23')
-
- return cfg
-
-RESP_HEAD="""\
-HTTP/1.0 200 ok
-Content-type: text/html
-
-<HTML><BODY BGCOLOR=\"#ffffff\">
-<pre>
-
-Emulating s_server -www
-Ciphers supported in s_server.py
-"""
-
-RESP_TAIL="""\
-</pre>
-</BODY></HTML>
-"""
-
-class channel(SSL.ssl_dispatcher):
-
- def __init__(self, conn, debug):
- SSL.ssl_dispatcher.__init__(self, conn)
- self.socket.setblocking(0)
- self.buffer=self.fixup_buffer()
- self.debug=debug
-
- def fixup_buffer(self):
- even=0
- buffer=cStringIO.StringIO()
- buffer.write(RESP_HEAD)
- for c in self.get_ciphers():
- # This formatting works for around 80 columns.
- buffer.write('%-11s:%-28s' % (c.version(), c.name()))
- if even:
- buffer.write('\r\n')
- even=1-even
- buffer.write('\r\n%s' % RESP_TAIL)
- return buffer.getvalue()
-
- def handle_connect(self):
- pass
-
- def handle_close(self):
- self.close()
-
- def handle_error(self, exc_type, exc_value, exc_traceback):
- if self.debug:
- print 'handle_error()'
- #print exc_type, exc_value, exc_traceback
- print Err.get_error()
- self.handle_close()
-
-
- def writeable(self):
- return len(self.buffer)
-
- def handle_write(self):
- n=self.send(self.buffer)
- if n==-1:
- pass
- elif n==0:
- self.handle_close()
- else:
- self.buffer=self.buffer[n:]
- if self.debug:
- print 'handle_write():', n
-
- def readable(self):
- return 1
-
- def handle_read(self):
- blob=self.recv()
- if blob is None:
- pass
- elif blob=='':
- self.handle_close()
- else:
- pass
- if self.debug:
- print 'handle_read():', blob
-
-
-class server(SSL.ssl_dispatcher):
-
- channel_class=channel
-
- def __init__(self, addr, port, config, ssl_context):
- asyncore.dispatcher.__init__(self)
- self.create_socket(ssl_context)
- self.set_reuse_addr()
- self.socket.setblocking(0)
- self.bind((addr, port))
- self.listen(5)
- self.config=config
- self.debug=config.debug
- self.ssl_ctx=ssl_context
-
- def handle_accept(self):
- sock, addr=self.accept()
- print self.ssl_ctx.get_verify_mode()
- if (self.ssl_ctx.get_verify_mode() is SSL.verify_none) or sock.verify_ok():
- self.channel_class(sock, self.debug)
- else:
- print 'client verification failed'
- sock.close()
-
- def writeable(self):
- return 0
-
-def s_server(config):
- ctx=SSL.Context(config.protocol[0])
-
- if hasattr(config, 'debug'):
- config.debug=1
- else:
- config.debug=0
-
- if hasattr(config, 'cert'):
- cert=config.cert
- else:
- cert='server.pem'
- if hasattr(config, 'key'):
- cert=config.key
- else:
- cert='server.pem'
- ctx.load_cert(cert)
-
- if hasattr(config, 'CAfile'):
- cafile=config.CAfile
- else:
- cafile='ca.pem'
- ctx.load_verify_location(cafile)
-
- if hasattr(config, 'verify'):
- verify=SSL.verify_peer
- depth=int(config.verify)
- elif hasattr(config, 'Verify'):
- verify=SSL.verify_peer | SSL.verify_fail_if_no_peer_cert
- depth=int(config.Verify)
- else:
- verify=SSL.verify_none
- depth=0
- ctx.set_verify(verify, depth)
-
- ctx.set_tmp_dh('dh1024.pem')
- #ctx.set_info_callback()
-
- server(cfg.accept[0], cfg.accept[1], cfg, ctx)
- asyncore.loop()
-
-if __name__=='__main__':
- cfg=config(sys.argv[1:])
- s_server(cfg)
-
diff --git a/demo/ssl/server.pem b/demo/ssl/server.pem
deleted file mode 100644
index 1ee9282..0000000
--- a/demo/ssl/server.pem
+++ /dev/null
@@ -1,36 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDYjCCAsugAwIBAgIBBDANBgkqhkiG9w0BAQQFADCBgDELMAkGA1UEBhMCU0cx
-ETAPBgNVBAoTCE0yQ3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UE
-AxMbTTJDcnlwdG8gQ2VydGlmaWNhdGUgTWFzdGVyMSIwIAYJKoZIhvcNAQkBFhNu
-Z3BzQG5ldG1lbWV0aWMuY29tMB4XDTAzMDYyMjEzMzAxNFoXDTA0MDYyMTEzMzAx
-NFowXTELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRIwEAYDVQQDEwls
-b2NhbGhvc3QxJzAlBgkqhkiG9w0BCQEWGGFkbWluQHNlcnZlci5leGFtcGxlLmRv
-bTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA37aKGZtFicl8xXXTLJ8/JD7c
-kd3t/teCX9i61lpaDQCKBoVrrursIvZihemMKI9g/u/+BLqt5g8mBdgUdYz0txc8
-KEbV2hj+wwOX4H3XwD0Y+DysXiNHq7/tFdmzSVHoLxpY4zYzXbxQ/p049wvIyPRp
-/y3omcnx/TEUhkn+JmkCAwEAAaOCAQwwggEIMAkGA1UdEwQCMAAwLAYJYIZIAYb4
-QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBTB
-H/mUYlww24mJlSxEtGdlwojO9zCBrQYDVR0jBIGlMIGigBTr+pwHMS1CmF9cuGI4
-du3YqoHAwqGBhqSBgzCBgDELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRv
-MRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UEAxMbTTJDcnlwdG8gQ2VydGlm
-aWNhdGUgTWFzdGVyMSIwIAYJKoZIhvcNAQkBFhNuZ3BzQG5ldG1lbWV0aWMuY29t
-ggEAMA0GCSqGSIb3DQEBBAUAA4GBAAvl6v0s3eFeGP4iAcrfysuK7jzFKhjDYuOy
-lVS3u33bZNLnMpM6OSEM9yPh4WpFCVHf+nYwC71pk4ilsLVXjKxymm2lNGcxLVuW
-iydFz4Ly9nmN7Ja9ygYT39dGAFP/wN7ELTpsbul8VfmqhNg9y81d8i/A1tK3AGA8
-0QkPQNdP
------END CERTIFICATE-----
------BEGIN RSA PRIVATE KEY-----
-MIICXAIBAAKBgQDftooZm0WJyXzFddMsnz8kPtyR3e3+14Jf2LrWWloNAIoGhWuu
-6uwi9mKF6Ywoj2D+7/4Euq3mDyYF2BR1jPS3FzwoRtXaGP7DA5fgfdfAPRj4PKxe
-I0erv+0V2bNJUegvGljjNjNdvFD+nTj3C8jI9Gn/LeiZyfH9MRSGSf4maQIDAQAB
-AoGAHpeVtv62uarl9xKvuBBm0AwQmZnhq9HIsFaw5hMg8Vo7hbzFBvx1IirTOkC/
-u+QvfW1QLVFh6m3z4ySzV4fZBtcd6F9SbSrZ0xsxIUB2NOSa1RGgiaP61bJnMMM1
-xM3O9iwM5GZc3Gqy08QOCpDl0772VJ+9Gz3FA88mrc6rHQkCQQDz6RIatFjT28n8
-1vy0nHwwZz2oXTpe/pyZPwoKj8zVsmrKhKwOw7l8ArxjP8zoHOE7AQBCXYDMNoFp
-IAF0yuqrAkEA6s0wMEdPpQeb0XHAfccyJQoeULxHdVFoz1wWmGSOm4YmQtR8/QJx
-luEgfpeRkzxBKt5Ls3MEkheIOw7xV24zOwJAMz+DaE0AZPNHS3K4ghJnHZxzng6I
-lzEUIjbWm0V/ml70hTy/EhMZw+6nOotLOHHo+QbK0SboSwAgzL/Gzo1cJQJANqpS
-38qadleRJXAQWrg3qnvyluVe1aeAeVZ9RDmVIgxXeBO0jcs12uTLBe4PzHGo0mwy
-v7K1i7XC180gzzQu5QJBAOxITT9RoWSSozPvnirHd37sn+RsrNYkV07NAa80M20Z
-DkBPHeMVkNgigrQ6L6vWmbRDGQbGcMplAxnI5ppKCoU=
------END RSA PRIVATE KEY-----
diff --git a/demo/ssl/server3.py b/demo/ssl/server3.py
deleted file mode 100644
index 99fbe97..0000000
--- a/demo/ssl/server3.py
+++ /dev/null
@@ -1,121 +0,0 @@
-#!/usr/bin/env python
-"""
-server3 from the book 'Network Security with OpenSSL', but modified to
-Python/M2Crypto from the original C implementation.
-
-Copyright (c) 2004-2005 Open Source Applications Foundation.
-Author: Heikki Toivonen
-"""
-from M2Crypto import SSL, Rand, threading, DH
-import thread
-from socket import *
-
-verbose_debug = 1
-
-def verify_callback(ok, store):
- if not ok:
- print "***Verify Not ok"
- return ok
-
-dh1024 = None
-
-def init_dhparams():
- global dh1024
- dh1024 = DH.load_params('dh1024.pem')
-
-def tmp_dh_callback(ssl, is_export, keylength):
- global dh1024
- if not dh1024:
- init_dhparams()
- return dh1024._ptr()
-
-def setup_server_ctx():
- ctx = SSL.Context('sslv23')
- if ctx.load_verify_locations('ca.pem') != 1:
- print "***No CA file"
- #if ctx.set_default_verify_paths() != 1:
- # print "***No default verify paths"
- ctx.load_cert_chain('server.pem')
- ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert,
- 10, verify_callback)
- ctx.set_options(SSL.op_all | SSL.op_no_sslv2)
- ctx.set_tmp_dh_callback(tmp_dh_callback)
- #ctx.set_tmp_dh('dh1024.pem')
- if ctx.set_cipher_list('ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH') != 1:
- print "***No valid ciphers"
- if verbose_debug:
- ctx.set_info_callback()
- return ctx
-
-def post_connection_check(peerX509, expectedHost):
- if peerX509 is None:
- print "***No peer certificate"
- # Not sure if we can do any other checks
- return 1
-
-def do_server_loop(conn):
- while 1:
- try:
- buf = conn.read()
- if not buf:
- break
- print buf
- except SSL.SSLError, what:
- if str(what) == 'unexpected eof':
- break
- else:
- raise
- except:
- break
-
- if conn.get_shutdown():
- return 1
- return 0
-
-# How about something like:
-#def server_thread(ctx, ssl, addr):
-# conn = SSL.Connection(ctx, None)
-# conn.ssl = ssl
-# conn.setup_addr(addr)
-def server_thread(ctx, sock, addr):
- conn = SSL.Connection(ctx, sock)
- conn.set_post_connection_check_callback(post_connection_check)
- conn.setup_addr(addr)
- conn.set_accept_state()
- conn.setup_ssl()
- conn.accept_ssl()
-
- post_connection_check(conn)
-
- print 'SSL Connection opened'
- if do_server_loop(conn):
- conn.close()
- else:
- conn.clear()
- print 'SSL Connection closed'
-
-
-if __name__=='__main__':
- threading.init()
- Rand.load_file('../randpool.dat', -1)
-
- ctx = setup_server_ctx()
-
- # How about something like this?
- #conn_root = SSL.Connection(ctx)
- #conn_root.bind(('127.0.0.1', 9999))
- #conn_root.listen(5)
- #while 1:
- # ssl, addr = conn_root.accept()
- # thread.start_new_thread(server_thread, (ctx, ssl, addr))
-
- sock = socket(AF_INET, SOCK_STREAM)
- sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
- sock.bind(('', 9999))
- sock.listen(5)
- while 1:
- conn, addr = sock.accept()
- thread.start_new_thread(server_thread, (ctx, conn, addr))
-
- Rand.save_file('../randpool.dat')
- threading.cleanup()
diff --git a/demo/ssl/sess.py b/demo/ssl/sess.py
deleted file mode 100644
index 23428fc..0000000
--- a/demo/ssl/sess.py
+++ /dev/null
@@ -1,89 +0,0 @@
-"""M2Crypto.SSL.Session client demo: This program requests a URL from
-a HTTPS server, saves the negotiated SSL session id, parses the HTML
-returned by the server, then requests each HREF in a separate thread
-using the saved SSL session id.
-
-Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
-
-from M2Crypto import Err, Rand, SSL, X509, threading
-m2_threading = threading; del threading
-
-import formatter, getopt, htmllib, sys
-from threading import Thread
-from socket import gethostname
-
-
-def handler(sslctx, host, port, href, recurs=0, sslsess=None):
-
- s = SSL.Connection(sslctx)
- if sslsess:
- s.set_session(sslsess)
- s.connect((host, port))
- else:
- s.connect((host, port))
- sslsess = s.get_session()
- #print sslsess.as_text()
-
- if recurs:
- p = htmllib.HTMLParser(formatter.NullFormatter())
-
- f = s.makefile("rw")
- f.write(href)
- f.flush()
-
- while 1:
- data = f.read()
- if not data:
- break
- if recurs:
- p.feed(data)
-
- if recurs:
- p.close()
-
- f.close()
-
- if recurs:
- for a in p.anchorlist:
- req = 'GET %s HTTP/1.0\r\n\r\n' % a
- thr = Thread(target=handler,
- args=(sslctx, host, port, req, recurs-1, sslsess))
- print "Thread =", thr.getName()
- thr.start()
-
-
-if __name__ == '__main__':
-
- m2_threading.init()
- Rand.load_file('../randpool.dat', -1)
-
- host = '127.0.0.1'
- port = 9443
- req = '/'
-
- optlist, optarg = getopt.getopt(sys.argv[1:], 'h:p:r:')
- for opt in optlist:
- if '-h' in opt:
- host = opt[1]
- elif '-p' in opt:
- port = int(opt[1])
- elif '-r' in opt:
- req = opt[1]
-
- ctx = SSL.Context('sslv3')
- ctx.load_cert('client.pem')
- ctx.load_verify_info('ca.pem')
- ctx.load_client_ca('ca.pem')
- ctx.set_verify(SSL.verify_none, 10)
-
- req = 'GET %s HTTP/1.0\r\n\r\n' % req
-
- start = Thread(target=handler, args=(ctx, host, port, req, 1))
- print "Thread =", start.getName()
- start.start()
- start.join()
-
- m2_threading.cleanup()
- Rand.save_file('../randpool.dat')
-
-
diff --git a/demo/ssl/sess2.py b/demo/ssl/sess2.py
deleted file mode 100644
index a3c2bf4..0000000
--- a/demo/ssl/sess2.py
+++ /dev/null
@@ -1,78 +0,0 @@
-"""M2Crypto.SSL.Session client demo2: This program creates two sockets, each
-bound to a different local address. The first creates an SSL connection, the
-second then creates another SSL connection using the first's SSL session id.
-
-(This program only works if you've ifconfig'ed your interfaces correctly,
-of course.)
-
-Copyright (c) 1999-2001 Ng Pheng Siong. All rights reserved."""
-
-from M2Crypto import Err, Rand, SSL, X509, threading
-m2_threading = threading; del threading
-
-import formatter, getopt, htmllib, sys
-from threading import Thread
-from socket import gethostname
-
-ADDR1 = '127.0.0.1', 9999
-ADDR2 = '127.0.0.2', 9999
-
-def handler(addr, sslctx, host, port, req, sslsess=None):
-
- s = SSL.Connection(sslctx)
- s.bind(addr)
- if sslsess:
- s.set_session(sslsess)
- s.connect((host, port))
- else:
- s.connect((host, port))
- sslsess = s.get_session()
- s.write(req)
- while 1:
- data = s.read(4096)
- if not data:
- break
-
- if addr != ADDR2:
- thr = Thread(target=handler,
- args=(ADDR2, sslctx, host, port, req, sslsess))
- print "Thread =", thr.getName()
- thr.start()
-
- s.close()
-
-
-if __name__ == '__main__':
-
- m2_threading.init()
- Rand.load_file('../randpool.dat', -1)
-
- host = '127.0.0.1'
- port = 443
- req = '/'
-
- optlist, optarg = getopt.getopt(sys.argv[1:], 'h:p:r:')
- for opt in optlist:
- if '-h' in opt:
- host = opt[1]
- elif '-p' in opt:
- port = int(opt[1])
- elif '-r' in opt:
- req = opt[1]
-
- ctx = SSL.Context('sslv3')
- ctx.load_cert('client.pem')
- ctx.load_verify_info('ca.pem')
- ctx.set_verify(SSL.verify_none, 10)
-
- req = 'GET %s HTTP/1.0\r\n\r\n' % req
-
- start = Thread(target=handler, args=(ADDR1, ctx, host, port, req))
- print "Thread =", start.getName()
- start.start()
- start.join()
-
- m2_threading.cleanup()
- Rand.save_file('../randpool.dat')
-
-
diff --git a/demo/ssl/sess2.ssldump.out b/demo/ssl/sess2.ssldump.out
deleted file mode 100644
index 9b383ee..0000000
--- a/demo/ssl/sess2.ssldump.out
+++ /dev/null
@@ -1,112 +0,0 @@
-New TCP connection #1: localhost(9999) <-> localhost(443)
-1 1 0.0061 (0.0061) C>S Handshake
- ClientHello
- Version 3.0
- cipher suites
- SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
- SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA
- SSL_RSA_WITH_3DES_EDE_CBC_SHA
- SSL_DHE_DSS_WITH_RC4_128_SHA
- SSL_RSA_WITH_IDEA_CBC_SHA
- SSL_RSA_WITH_RC4_128_SHA
- SSL_RSA_WITH_RC4_128_MD5
- SSL_DHE_DSS_WITH_RC2_56_CBC_SHA
- SSL_RSA_EXPORT1024_WITH_RC4_56_SHA
- SSL_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA
- SSL_RSA_EXPORT1024_WITH_DES_CBC_SHA
- SSL_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5
- SSL_RSA_EXPORT1024_WITH_RC4_56_MD5
- SSL_DHE_RSA_WITH_DES_CBC_SHA
- SSL_DHE_DSS_WITH_DES_CBC_SHA
- SSL_RSA_WITH_DES_CBC_SHA
- SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA
- SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA
- SSL_RSA_EXPORT_WITH_DES40_CBC_SHA
- SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5
- SSL_RSA_EXPORT_WITH_RC4_40_MD5
- compression methods
- NULL
-1 2 0.0068 (0.0006) S>C Handshake
- ServerHello
- Version 3.0
- session_id[32]=
- f2 6e ab c1 e6 db fa 55 4d 77 97 be 0d 28 23 fe
- 53 8a d5 3b 31 58 1d 93 35 65 10 a9 06 6b a2 a6
- cipherSuite SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
- compressionMethod NULL
-1 3 0.0846 (0.0778) S>C Handshake
- Certificate
-1 4 0.0848 (0.0001) S>C Handshake
- ServerKeyExchange
-1 5 0.0848 (0.0000) S>C Handshake
- ServerHelloDone
-1 6 0.2475 (0.1627) C>S Handshake
- ClientKeyExchange
- DiffieHellmanClientPublicValue[128]=
- 3c 8f 0f 93 8a 3a 1e 5c 07 cf 40 2f 7d bf 25 7a
- e8 2b ba 54 46 d5 54 40 22 90 38 f2 88 c3 62 8a
- ec b1 b7 f1 06 6d fa ba 46 dd f1 92 5f 44 18 44
- 8e df 33 30 64 79 e0 77 07 1f bc 10 dc 0d 6e 4b
- 4d 68 01 af 4a bf 83 62 de 87 d7 98 6c e3 9b af
- a2 a6 60 67 18 46 89 29 fa 1a 72 df 92 2d 9e 4f
- 2c b2 02 b3 ef b7 03 07 49 69 c5 b2 37 ae a1 0e
- 10 e1 79 25 a4 70 02 15 69 d9 47 2c c8 48 23 67
-1 7 0.2475 (0.0000) C>S ChangeCipherSpec
-1 8 0.2475 (0.0000) C>S Handshake
-1 9 0.3239 (0.0763) S>C ChangeCipherSpec
-1 10 0.3239 (0.0000) S>C Handshake
-1 11 0.3266 (0.0027) C>S application_data
-1 12 0.3566 (0.0299) S>C application_data
-1 13 0.3571 (0.0005) S>C Alert
-1 0.3574 (0.0003) S>C TCP FIN
-New TCP connection #2: 127.0.0.2(9999) <-> localhost(443)
-2 1 0.0039 (0.0039) C>S Handshake
- ClientHello
- Version 3.0
- resume [32]=
- f2 6e ab c1 e6 db fa 55 4d 77 97 be 0d 28 23 fe
- 53 8a d5 3b 31 58 1d 93 35 65 10 a9 06 6b a2 a6
- cipher suites
- SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
- SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA
- SSL_RSA_WITH_3DES_EDE_CBC_SHA
- SSL_DHE_DSS_WITH_RC4_128_SHA
- SSL_RSA_WITH_IDEA_CBC_SHA
- SSL_RSA_WITH_RC4_128_SHA
- SSL_RSA_WITH_RC4_128_MD5
- SSL_DHE_DSS_WITH_RC2_56_CBC_SHA
- SSL_RSA_EXPORT1024_WITH_RC4_56_SHA
- SSL_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA
- SSL_RSA_EXPORT1024_WITH_DES_CBC_SHA
- SSL_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5
- SSL_RSA_EXPORT1024_WITH_RC4_56_MD5
- SSL_DHE_RSA_WITH_DES_CBC_SHA
- SSL_DHE_DSS_WITH_DES_CBC_SHA
- SSL_RSA_WITH_DES_CBC_SHA
- SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA
- SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA
- SSL_RSA_EXPORT_WITH_DES40_CBC_SHA
- SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5
- SSL_RSA_EXPORT_WITH_RC4_40_MD5
- compression methods
- NULL
-2 2 0.0055 (0.0016) S>C Handshake
- ServerHello
- Version 3.0
- session_id[32]=
- f2 6e ab c1 e6 db fa 55 4d 77 97 be 0d 28 23 fe
- 53 8a d5 3b 31 58 1d 93 35 65 10 a9 06 6b a2 a6
- cipherSuite SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
- compressionMethod NULL
-2 3 0.0055 (0.0000) S>C ChangeCipherSpec
-2 4 0.0055 (0.0000) S>C Handshake
-2 5 0.0066 (0.0010) C>S ChangeCipherSpec
-2 6 0.0066 (0.0000) C>S Handshake
-1 14 0.3698 (0.0124) C>S Alert
-1 0.3702 (0.0004) C>S TCP FIN
-2 7 0.0996 (0.0930) C>S application_data
-2 8 0.1224 (0.0227) S>C application_data
-2 9 0.1244 (0.0019) S>C Alert
-2 10 0.1248 (0.0004) C>S Alert
-2 0.1254 (0.0005) C>S TCP FIN
-2 0.1300 (0.0046) S>C TCP FIN
diff --git a/demo/ssl/socklib.py b/demo/ssl/socklib.py
deleted file mode 100644
index ebaf6d3..0000000
--- a/demo/ssl/socklib.py
+++ /dev/null
@@ -1,46 +0,0 @@
-"""
-socklib provides a way to transparently replace socket.ssl with
-M2Crypto.SSL.Connection.
-
-Usage: Import socklib before the 3rd party module that uses socket.ssl. Also,
- call socketlib.setSSLContextFactory() to set it up with a way to get
- secure SSL contexts.
-
-Copyright (c) 2007 Open Source Applications Foundation.
-All rights reserved.
-"""
-
-sslContextFactory = None
-
-def setSSLContextFactory(factory):
- global sslContextFactory
- sslContextFactory = factory
-
-from M2Crypto.SSL import Connection, Checker
-import socket
-
-class ssl_socket(socket.socket):
- def connect(self, addr, *args):
- self.addr = addr
- return super(ssl_socket, self).connect(addr, *args)
-
- def close(self):
- if hasattr(self, 'conn'):
- self.conn.close()
- socket.socket.close(self)
-
-def ssl(sock):
- sock.conn = Connection(ctx=sslContextFactory(), sock=sock)
- sock.conn.addr = sock.addr
- sock.conn.setup_ssl()
- sock.conn.set_connect_state()
- sock.conn.connect_ssl()
- check = getattr(sock.conn, 'postConnectionCheck', sock.conn.clientPostConnectionCheck)
- if check is not None:
- if not check(sock.conn.get_peer_cert(), sock.conn.addr[0]):
- raise Checker.SSLVerificationError, 'post connection check failed'
- return sock.conn
-
-socket.socket = ssl_socket
-socket.ssl = ssl
-
diff --git a/demo/ssl/somelib.py b/demo/ssl/somelib.py
deleted file mode 100644
index 21b3491..0000000
--- a/demo/ssl/somelib.py
+++ /dev/null
@@ -1,21 +0,0 @@
-"""
-Sample 3rd party lib to use with socklib and myapp.
-
-Copyright (c) 2007 Open Source Applications Foundation.
-All rights reserved.
-"""
-# This represents some 3rd party library we don't want to modify
-
-import socket
-
-class HttpsGetSlash(object):
- def __init__(self):
- self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
-
- def get(self, host, port):
- self.socket.connect((host, port))
- ssl_sock = socket.ssl(self.socket)
- ssl_sock.write('GET / HTTP/1.0\n\n')
- print ssl_sock.read()
- self.socket.close() \ No newline at end of file
diff --git a/demo/ssl/ss.py b/demo/ssl/ss.py
deleted file mode 100644
index 3db6752..0000000
--- a/demo/ssl/ss.py
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/usr/bin/env python
-
-import os, popen2, time
-from socket import *
-
-def main0():
- cin, cout = popen2.popen2('openssl s_server')
- cout.write('Q\n')
- cout.flush()
- s = socket(AF_INET, SOCK_STREAM)
- s.connect(('', 4433))
- s.close()
-
-def main():
- pid = os.fork()
- if pid:
- time.sleep(1)
- os.kill(pid, 1)
- os.waitpid(pid, 0)
- else:
- os.execvp('openssl', ('s_server',))
-
-if __name__ == '__main__':
- main()
-
diff --git a/demo/ssl/twistedsslclient.py b/demo/ssl/twistedsslclient.py
deleted file mode 100755
index e4b79c0..0000000
--- a/demo/ssl/twistedsslclient.py
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/usr/bin/env python
-"""
-Demonstrates M2Crypto.SSL.TwistedProtocolWrapper
-
-Copyright (c) 2005 Open Source Applications Foundation. All rights reserved.
-"""
-
-import twisted.internet.protocol as protocol
-import twisted.protocols.basic as basic
-import twisted.internet.reactor as reactor
-import M2Crypto.SSL.TwistedProtocolWrapper as wrapper
-import M2Crypto.SSL as SSL
-
-class EchoClient(basic.LineReceiver):
- def connectionMade(self):
- self.sendLine('Hello World!')
-
- def lineReceived(self, line):
- print 'received: "%s"' % line
- self.transport.loseConnection()
-
-
-class EchoClientFactory(protocol.ClientFactory):
- protocol = EchoClient
-
- def clientConnectionFailed(self, connector, reason):
- print 'connection failed'
- reactor.stop()
-
- def clientConnectionLost(self, connector, reason):
- print 'connection lost'
- reactor.stop()
-
-
-class ContextFactory:
- def getContext(self):
- return SSL.Context()
-
-
-if __name__ == '__main__':
- factory = EchoClientFactory()
- wrapper.connectSSL('localhost', 8000, factory, ContextFactory())
- reactor.run() # This will block until reactor.stop() is called
diff --git a/demo/ssl/twistedsslserver.py b/demo/ssl/twistedsslserver.py
deleted file mode 100755
index 04897a0..0000000
--- a/demo/ssl/twistedsslserver.py
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/usr/bin/env python
-"""
-Demonstrates M2Crypto.SSL.TwistedProtocolWrapper
-
-Copyright (c) 2005 Open Source Applications Foundation. All rights reserved.
-"""
-
-import sys
-import M2Crypto.SSL as SSL
-import M2Crypto.SSL.TwistedProtocolWrapper as wrapper
-import twisted.internet.protocol as protocol
-import twisted.internet.reactor as reactor
-import twisted.python.log as log
-
-
-class Echo(protocol.Protocol):
- def dataReceived(self, data):
- print 'received: "%s"' % data
- self.transport.write(data)
-
- def connectionMade(self):
- print 'connection made'
-
-
-class ContextFactory:
- def getContext(self):
- ctx = SSL.Context()
- ctx.load_cert('server.pem')
- return ctx
-
-
-if __name__ == '__main__':
- log.startLogging(sys.stdout)
- factory = protocol.Factory()
- factory.protocol = Echo
- wrapper.listenSSL(8000, factory, ContextFactory())
- reactor.run()
diff --git a/demo/ssl/xmlrpc_cli.py b/demo/ssl/xmlrpc_cli.py
deleted file mode 100644
index 69647d7..0000000
--- a/demo/ssl/xmlrpc_cli.py
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/env python
-
-"""Demonstration of M2Crypto.xmlrpclib2.
-
-Copyright (c) 1999-2004 Ng Pheng Siong. All rights reserved."""
-
-from M2Crypto import Rand
-from M2Crypto.m2xmlrpclib import Server, SSL_Transport
-
-def ZServerSSL():
- # Server is Zope-2.6.4 on ZServerSSL/0.12.
- zs = Server('https://127.0.0.1:8443/', SSL_Transport())
- print zs.propertyMap()
-
-def xmlrpc_srv():
- # Server is ../https/START_xmlrpc.py or ./xmlrpc_srv.py.
- zs = Server('https://127.0.0.1:39443', SSL_Transport())
- print zs.Testing(1, 2, 3)
- print zs.BringOn('SOAP')
-
-if __name__ == '__main__':
- Rand.load_file('../randpool.dat', -1)
- #ZServerSSL()
- xmlrpc_srv()
- Rand.save_file('../randpool.dat')
-
diff --git a/demo/ssl/xmlrpc_srv.py b/demo/ssl/xmlrpc_srv.py
deleted file mode 100644
index 3811992..0000000
--- a/demo/ssl/xmlrpc_srv.py
+++ /dev/null
@@ -1,26 +0,0 @@
-"""Server demonstration of M2Crypto.xmlrpclib2.
-
-Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
-
-# M2Crypto
-from M2Crypto import DH, SSL
-from echod_lib import init_context
-
-# /F's xmlrpcserver.py.
-from xmlrpcserver import RequestHandler
-
-class xmlrpc_handler(RequestHandler):
- def call(self, method, params):
- print "XMLRPC call:", method, params
- return params
-
- def finish(self):
- self.request.set_shutdown(SSL.SSL_RECEIVED_SHUTDOWN | SSL.SSL_SENT_SHUTDOWN)
- self.request.close()
-
-if __name__ == '__main__':
- ctx = init_context('sslv23', 'server.pem', 'ca.pem', SSL.verify_none)
- ctx.set_tmp_dh('dh1024.pem')
- s = SSL.ThreadingSSLServer(('', 9443), xmlrpc_handler, ctx)
- s.serve_forever()
-
diff --git a/demo/tinderbox/build_lib.py b/demo/tinderbox/build_lib.py
deleted file mode 100644
index 2babb14..0000000
--- a/demo/tinderbox/build_lib.py
+++ /dev/null
@@ -1,162 +0,0 @@
-# Copyright (c) 2006-2007 Open Source Applications Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Trimmed down for M2Crypto build purposes
-
-import os, sys
-import glob
-import fnmatch
-import shutil
-import fileinput
-import errno
-import subprocess
-import killableprocess
-import tempfile
-
-
-_logFilename = 'tbox.log'
-_logPrefix = ''
-_logFile = None
-_logEcho = True
-_logEchoErrors = False
-
-
-def initLog(filename, prefix='', echo=True, echoErrors=False):
- """
- Initialize log file and store log parameters
-
- Note: initLog assumes it is called only once per program
- """
- global _logFilename, _logPrefix, _logFile, _logEcho, _logEchoErrors
-
- _logFilename = filename or _logFilename
- _logEcho = echo
- _logEchoErrors = echoErrors
- _logPrefix = prefix
-
- try:
- _logFile = open(_logFilename, 'w+')
- result = True
- except:
- result = False
-
- return result
-
-
-def closeLog():
- """Need to close log to flush all data."""
- _logFile.close()
-
-
-def log(msg, error=False, newline='\n'):
- """
- Output log message to an open log file or to StdOut
- """
- echo = _logEcho
-
- if _logFile is None:
- if error or _logEcho:
- echo = True
- else:
- _logFile.write('%s%s%s' % (_logPrefix, msg, newline))
-
- if error and _logEchoErrors:
- sys.stderr.write('%s%s%s' % (_logPrefix, msg, newline))
-
- if echo:
- sys.stdout.write('%s%s%s' % (_logPrefix, msg, newline))
- sys.stdout.flush()
-
-
-def setpgid_preexec_fn():
- os.setpgid(0, 0)
-
-
-def runCommand(cmd, env=None, timeout=-1, logger=log, ignorepreexec=False):
- """
- Execute the given command and log all output
-
- Success and failure codes:
-
- >>> runCommand(['true'])
- 0
- >>> runCommand(['false'])
- 1
-
- Interleaved stdout and stderr messages:
-
- >>> runCommand(['python', '-c', r'print 1;import sys;sys.stdout.flush();print >>sys.stderr, 2;print 3'])
- 1
- 2
- 3
- 0
-
- Now with timeout:
-
- >>> runCommand(['python', '-c', r'print 1;import sys;sys.stdout.flush();print >>sys.stderr, 2;print 3'], timeout=5)
- 1
- 2
- 3
- 0
-
- Setting environment variable:
-
- >>> runCommand(['python', '-c', 'import os;print os.getenv("ENVTEST")'], env={'ENVTEST': '42'})
- 42
- 0
-
- Timeout:
- >>> runCommand(['sleep', '60'], timeout=5)
- -9
- """
- redirect = True
-
- if logger == log and _logFile is None:
- redirect = False
- else:
- if timeout == -1:
- output = subprocess.PIPE
- else:
- output = tempfile.TemporaryFile()
-
- if ignorepreexec:
- preexec_fn = None
- else:
- preexec_fn = setpgid_preexec_fn
-
- if redirect:
- p = killableprocess.Popen(cmd, env=env, stdin=subprocess.PIPE, stdout=output, stderr=subprocess.STDOUT, preexec_fn=preexec_fn)
- else:
- p = killableprocess.Popen(cmd, env=env, stdin=subprocess.PIPE, preexec_fn=preexec_fn)
-
- try:
- if timeout == -1 and redirect:
- for line in p.stdout:
- logger(line[:-1])
-
- p.wait(timeout=timeout, group=True)
-
- except KeyboardInterrupt:
- try:
- p.kill(group=True)
-
- except OSError:
- p.wait(30)
-
- if timeout != -1 and redirect:
- output.seek(0)
- for line in output:
- logger(line[:-1])
-
- return p.returncode
diff --git a/demo/tinderbox/killableprocess.py b/demo/tinderbox/killableprocess.py
deleted file mode 100644
index 9c4fdb0..0000000
--- a/demo/tinderbox/killableprocess.py
+++ /dev/null
@@ -1,212 +0,0 @@
-# killableprocess - subprocesses which can be reliably killed
-#
-# Parts of this module are copied from the subprocess.py file contained
-# in the Python distribution.
-#
-# Copyright (c) 2003-2004 by Peter Astrand <astrand@lysator.liu.se>
-#
-# Additions and modifications written by Benjamin Smedberg
-# <benjamin@smedbergs.us> are Copyright (c) 2006 by the Mozilla Foundation
-# <http://www.mozilla.org/>
-#
-# By obtaining, using, and/or copying this software and/or its
-# associated documentation, you agree that you have read, understood,
-# and will comply with the following terms and conditions:
-#
-# Permission to use, copy, modify, and distribute this software and
-# its associated documentation for any purpose and without fee is
-# hereby granted, provided that the above copyright notice appears in
-# all copies, and that both that copyright notice and this permission
-# notice appear in supporting documentation, and that the name of the
-# author not be used in advertising or publicity pertaining to
-# distribution of the software without specific, written prior
-# permission.
-#
-# THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
-# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR
-# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
-# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
-# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-r"""killableprocess - Subprocesses which can be reliably killed
-
-This module is a subclass of the builtin "subprocess" module. It allows
-processes that launch subprocesses to be reliably killed on Windows (via the Popen.kill() method.
-
-It also adds a timeout argument to Wait() for a limited period of time before
-forcefully killing the process.
-
-Note: On Windows, this module requires Windows 2000 or higher (no support for
-Windows 95, 98, or NT 4.0). It also requires ctypes, which is bundled with
-Python 2.5+ or available from http://python.net/crew/theller/ctypes/
-"""
-
-import subprocess
-import sys
-import os
-import time
-import types
-
-try:
- from subprocess import CalledProcessError
-except ImportError:
- # Python 2.4 doesn't implement CalledProcessError
- class CalledProcessError(Exception):
- """This exception is raised when a process run by check_call() returns
- a non-zero exit status. The exit status will be stored in the
- returncode attribute."""
- def __init__(self, returncode, cmd):
- self.returncode = returncode
- self.cmd = cmd
- def __str__(self):
- return "Command '%s' returned non-zero exit status %d" % (self.cmd, self.returncode)
-
-mswindows = (sys.platform == "win32")
-
-if mswindows:
- import winprocess
-else:
- import signal
-
-def call(*args, **kwargs):
- waitargs = {}
- if "timeout" in kwargs:
- waitargs["timeout"] = kwargs.pop("timeout")
-
- return Popen(*args, **kwargs).wait(**waitargs)
-
-def check_call(*args, **kwargs):
- """Call a program with an optional timeout. If the program has a non-zero
- exit status, raises a CalledProcessError."""
-
- retcode = call(*args, **kwargs)
- if retcode:
- cmd = kwargs.get("args")
- if cmd is None:
- cmd = args[0]
- raise CalledProcessError(retcode, cmd)
-
-if not mswindows:
- def DoNothing(*args):
- pass
-
-class Popen(subprocess.Popen):
- if mswindows:
- def _execute_child(self, args, executable, preexec_fn, close_fds,
- cwd, env, universal_newlines, startupinfo,
- creationflags, shell,
- p2cread, p2cwrite,
- c2pread, c2pwrite,
- errread, errwrite):
- if not isinstance(args, types.StringTypes):
- args = subprocess.list2cmdline(args)
-
- if startupinfo is None:
- startupinfo = winprocess.STARTUPINFO()
-
- if None not in (p2cread, c2pwrite, errwrite):
- startupinfo.dwFlags |= winprocess.STARTF_USESTDHANDLES
-
- startupinfo.hStdInput = int(p2cread)
- startupinfo.hStdOutput = int(c2pwrite)
- startupinfo.hStdError = int(errwrite)
- if shell:
- startupinfo.dwFlags |= winprocess.STARTF_USESHOWWINDOW
- startupinfo.wShowWindow = winprocess.SW_HIDE
- comspec = os.environ.get("COMSPEC", "cmd.exe")
- args = comspec + " /c " + args
-
- # We create a new job for this process, so that we can kill
- # the process and any sub-processes
- self._job = winprocess.CreateJobObject()
-
- creationflags |= winprocess.CREATE_SUSPENDED
- creationflags |= winprocess.CREATE_UNICODE_ENVIRONMENT
-
- hp, ht, pid, tid = winprocess.CreateProcess(
- executable, args,
- None, None, # No special security
- 1, # Must inherit handles!
- creationflags,
- winprocess.EnvironmentBlock(env),
- cwd, startupinfo)
-
- self._child_created = True
- self._handle = hp
- self._thread = ht
- self.pid = pid
-
- winprocess.AssignProcessToJobObject(self._job, hp)
- winprocess.ResumeThread(ht)
-
- if p2cread is not None:
- p2cread.Close()
- if c2pwrite is not None:
- c2pwrite.Close()
- if errwrite is not None:
- errwrite.Close()
-
- def kill(self, group=True):
- """Kill the process. If group=True, all sub-processes will also be killed."""
- if mswindows:
- if group:
- winprocess.TerminateJobObject(self._job, 127)
- else:
- winprocess.TerminateProcess(self._handle, 127)
- self.returncode = 127
- else:
- if sys.platform == 'cygwin':
- cmd = "taskkill /f /pid " + str(self.pid)
- if group:
- cmd += " /t"
- os.system(cmd)
- elif group:
- os.killpg(self.pid, signal.SIGKILL)
- else:
- os.kill(self.pid, signal.SIGKILL)
- self.returncode = -9
-
- def wait(self, timeout=-1, group=True):
- """Wait for the process to terminate. Returns returncode attribute.
- If timeout seconds are reached and the process has not terminated,
- it will be forcefully killed. If timeout is -1, wait will not
- time out."""
-
- if self.returncode is not None:
- return self.returncode
-
- if mswindows:
- if timeout != -1:
- timeout = timeout * 1000
- rc = winprocess.WaitForSingleObject(self._handle, timeout)
- if rc == winprocess.WAIT_TIMEOUT:
- self.kill(group)
- else:
- self.returncode = winprocess.GetExitCodeProcess(self._handle)
- else:
- if timeout == -1:
- subprocess.Popen.wait(self)
- return self.returncode
-
- starttime = time.time()
-
- # Make sure there is a signal handler for SIGCHLD installed
- oldsignal = signal.signal(signal.SIGCHLD, DoNothing)
-
- while time.time() < starttime + timeout - 0.01:
- pid, sts = os.waitpid(self.pid, os.WNOHANG)
- if pid != 0:
- self._handle_exitstatus(sts)
- signal.signal(signal.SIGCHLD, oldsignal)
- return self.returncode
-
- # time.sleep is interrupted by signals (good!)
- newtimeout = timeout - time.time() + starttime
- time.sleep(newtimeout)
- self.kill(group)
- signal.signal(signal.SIGCHLD, oldsignal)
- subprocess.Popen.wait(self)
-
- return self.returncode
diff --git a/demo/tinderbox/slave.py b/demo/tinderbox/slave.py
deleted file mode 100755
index eaa64c0..0000000
--- a/demo/tinderbox/slave.py
+++ /dev/null
@@ -1,172 +0,0 @@
-#!/usr/bin/env python
-#
-"""
-This is a sample Tinderbox2 buildslave script.
-
-NOTE: WAIT at least 6 minutes after the last build before starting
- the next build!
-
-Create config.ini file with the following contents:
-
-[build]
-name = identify your build slave, for example Ubuntu 8.04 32-bit
-;;optional fields:
-;;uname = uname -a
-;;swig = swig -version
-;;cc = gcc --version
-;;openssl = openssl version
-;;python = python --version
-;;clean = rm -fr m2crypto
-;;svn = svn co http://svn.osafoundation.org/m2crypto/trunk m2crypto
-;;patch =
-;;build = python setup.py clean --all build
-;; OR another way to do tests without setuptools:
-;;build = PYTHONPATH=build/lib-something python tests/alltests.py
-;;test = python setup.py test
-;;wait = 3600
-;;timeout = 180
-
-[email]
-from = your email
-to = Email Heikki Toivonen to get the address
-user = smtp username
-password = smtp password
-server = smtp server
-port = smtp port
-"""
-
-import time, smtplib, os, ConfigParser, tempfile
-import build_lib as bl
-
-# Change to True when you are troubleshooting this build script
-debug_script = False
-
-# These commands assume we are running on a unix-like system where default
-# build options work and all prerequisites are installed and in PATH etc.
-DEFAULT_COMMANDS = {
- 'uname': ['uname', '-a'],
- 'swig': ['swig', '-version'],
- 'cc': ['gcc', '--version'],
- 'openssl': ['openssl', 'version'],
- 'python': ['python', '--version'],
- 'clean': ['rm', '-rf', 'm2crypto'],
- 'svn': ['svn', 'co', 'http://svn.osafoundation.org/m2crypto/trunk', 'm2crypto'],
- 'patch': [],
- 'build': ['python', 'setup.py', 'clean', '--all', 'build'],
- 'test': ['python', 'setup.py', 'test']
-}
-
-def load_config(cfg='config.ini'):
- config = {}
- cp = ConfigParser.ConfigParser()
- cp.read(cfg)
- for section in cp.sections():
- for option in cp.options(section):
- config[option] = cp.get(section, option).strip()
- return config
-
-# XXX copied from test_ssl
-def zap_servers():
- s = 's_server'
- fn = tempfile.mktemp()
- cmd = 'ps | egrep %s > %s' % (s, fn)
- os.system(cmd)
- f = open(fn)
- while 1:
- ps = f.readline()
- if not ps:
- break
- chunk = string.split(ps)
- pid, cmd = chunk[0], chunk[4]
- if cmd == s:
- os.kill(int(pid), 1)
- f.close()
- os.unlink(fn)
-
-def build(commands, config):
- status = 'success'
-
- cwd = os.getcwd()
- timeout = int(config.get('timeout') or 180)
-
- bl.initLog('tbox.log', echo=debug_script)
-
- starttime = int(time.time())
-
- for command in commands:
- cmd = config.get(command)
- if not cmd:
- cmd = DEFAULT_COMMANDS[command]
- if not cmd:
- continue
- else:
- cmd = cmd.split()
-
- bl.log('*** %s, timeout=%ds' % (' '.join(cmd), timeout))
-
- exit_code = bl.runCommand(cmd, timeout=timeout)
- if exit_code:
- bl.log('*** error exit code = %d' % exit_code)
- if command == 'test':
- status = 'test_failed'
- if os.name != 'nt':
- try:
- # If tests were killed due to timeout, we may have left
- # openssl processes running, so try killing
- zap_servers()
- except Exception, e:
- bl.log('*** error: tried to zap_servers: ' + str(e))
- else:
- status = 'build_failed'
- break
- if command == 'svn':
- os.chdir('m2crypto')
-
- timenow = int(time.time())
-
- bl.closeLog()
-
- os.chdir(cwd)
-
- return 'tbox.log', starttime, timenow, status
-
-
-def email(logpath, starttime, timenow, status, config):
- msg = """From: %(from)s
-To: %(to)s
-Subject: tree: M2Crypto
-
-
-tinderbox: tree: M2Crypto
-tinderbox: starttime: %(starttime)d
-tinderbox: timenow: %(timenow)d
-tinderbox: status: %(status)s
-tinderbox: buildname: %(buildname)s
-tinderbox: errorparser: unix
-tinderbox: END
-
-""" % {'from': config['from'], 'to': config['to'],
- 'starttime': starttime, 'timenow': timenow,
- 'status': status,
- 'buildname': config['name']}
-
- msg += open(logpath).read()
-
- server = smtplib.SMTP(host=config['server'], port=int(config['port']))
- if debug_script:
- server.set_debuglevel(1)
- server.starttls() # if your server supports STARTTLS
- if config.get('user'):
- server.login(config['user'], config['password'])
- server.sendmail(config['from'], config['to'], msg)
- server.quit()
-
-
-if __name__ == '__main__':
- config = load_config()
-
- commands = ['uname', 'swig', 'cc', 'openssl', 'python', 'clean', 'svn',
- 'patch', 'build', 'test']
-
- logpath, starttime, timenow, status = build(commands, config)
- email(logpath, starttime, timenow, status, config)
diff --git a/demo/tinderbox/winprocess.py b/demo/tinderbox/winprocess.py
deleted file mode 100644
index 4d867fe..0000000
--- a/demo/tinderbox/winprocess.py
+++ /dev/null
@@ -1,262 +0,0 @@
-# A module to expose various thread/process/job related structures and
-# methods from kernel32
-#
-# The MIT License
-#
-# Copyright (c) 2006 the Mozilla Foundation <http://www.mozilla.org>
-#
-# Permission is hereby granted, free of charge, to any person obtaining a
-# copy of this software and associated documentation files (the "Software"),
-# to deal in the Software without restriction, including without limitation
-# the rights to use, copy, modify, merge, publish, distribute, sublicense,
-# and/or sell copies of the Software, and to permit persons to whom the
-# Software is furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-# DEALINGS IN THE SOFTWARE.
-
-from ctypes import c_void_p, POINTER, sizeof, Structure, windll, WinError, WINFUNCTYPE
-from ctypes.wintypes import BOOL, BYTE, DWORD, HANDLE, LPCWSTR, LPWSTR, UINT, WORD
-
-LPVOID = c_void_p
-LPBYTE = POINTER(BYTE)
-LPDWORD = POINTER(DWORD)
-
-def ErrCheckBool(result, func, args):
- """errcheck function for Windows functions that return a BOOL True
- on success"""
- if not result:
- raise WinError()
- return args
-
-# CloseHandle()
-
-CloseHandleProto = WINFUNCTYPE(BOOL, HANDLE)
-CloseHandle = CloseHandleProto(("CloseHandle", windll.kernel32))
-CloseHandle.errcheck = ErrCheckBool
-
-# AutoHANDLE
-
-class AutoHANDLE(HANDLE):
- """Subclass of HANDLE which will call CloseHandle() on deletion."""
- def Close(self):
- if self.value:
- CloseHandle(self)
- self.value = 0
-
- def __del__(self):
- self.Close()
-
- def __int__(self):
- return self.value
-
-def ErrCheckHandle(result, func, args):
- """errcheck function for Windows functions that return a HANDLE."""
- if not result:
- raise WinError()
- return AutoHANDLE(result)
-
-# PROCESS_INFORMATION structure
-
-class PROCESS_INFORMATION(Structure):
- _fields_ = [("hProcess", HANDLE),
- ("hThread", HANDLE),
- ("dwProcessID", DWORD),
- ("dwThreadID", DWORD)]
-
- def __init__(self):
- Structure.__init__(self)
-
- self.cb = sizeof(self)
-
-LPPROCESS_INFORMATION = POINTER(PROCESS_INFORMATION)
-
-# STARTUPINFO structure
-
-class STARTUPINFO(Structure):
- _fields_ = [("cb", DWORD),
- ("lpReserved", LPWSTR),
- ("lpDesktop", LPWSTR),
- ("lpTitle", LPWSTR),
- ("dwX", DWORD),
- ("dwY", DWORD),
- ("dwXSize", DWORD),
- ("dwYSize", DWORD),
- ("dwXCountChars", DWORD),
- ("dwYCountChars", DWORD),
- ("dwFillAttribute", DWORD),
- ("dwFlags", DWORD),
- ("wShowWindow", WORD),
- ("cbReserved2", WORD),
- ("lpReserved2", LPBYTE),
- ("hStdInput", HANDLE),
- ("hStdOutput", HANDLE),
- ("hStdError", HANDLE)
- ]
-LPSTARTUPINFO = POINTER(STARTUPINFO)
-
-STARTF_USESHOWWINDOW = 0x01
-STARTF_USESIZE = 0x02
-STARTF_USEPOSITION = 0x04
-STARTF_USECOUNTCHARS = 0x08
-STARTF_USEFILLATTRIBUTE = 0x10
-STARTF_RUNFULLSCREEN = 0x20
-STARTF_FORCEONFEEDBACK = 0x40
-STARTF_FORCEOFFFEEDBACK = 0x80
-STARTF_USESTDHANDLES = 0x100
-
-# EnvironmentBlock
-
-class EnvironmentBlock:
- """An object which can be passed as the lpEnv parameter of CreateProcess.
- It is initialized with a dictionary."""
-
- def __init__(self, dict):
- if not dict:
- self._as_parameter_ = None
- else:
- values = ["%s=%s" % (key, value)
- for (key, value) in dict.iteritems()]
- values.append("")
- self._as_parameter_ = LPCWSTR("\0".join(values))
-
-# CreateProcess()
-
-CreateProcessProto = WINFUNCTYPE(BOOL, # Return type
- LPCWSTR, # lpApplicationName
- LPWSTR, # lpCommandLine
- LPVOID, # lpProcessAttributes
- LPVOID, # lpThreadAttributes
- BOOL, # bInheritHandles
- DWORD, # dwCreationFlags
- LPVOID, # lpEnvironment
- LPCWSTR, # lpCurrentDirectory
- LPSTARTUPINFO, # lpStartupInfo
- LPPROCESS_INFORMATION # lpProcessInformation
- )
-
-CreateProcessFlags = ((1, "lpApplicationName", None),
- (1, "lpCommandLine"),
- (1, "lpProcessAttributes", None),
- (1, "lpThreadAttributes", None),
- (1, "bInheritHandles", True),
- (1, "dwCreationFlags", 0),
- (1, "lpEnvironment", None),
- (1, "lpCurrentDirectory", None),
- (1, "lpStartupInfo"),
- (2, "lpProcessInformation"))
-
-def ErrCheckCreateProcess(result, func, args):
- ErrCheckBool(result, func, args)
- # return a tuple (hProcess, hThread, dwProcessID, dwThreadID)
- pi = args[9]
- return AutoHANDLE(pi.hProcess), AutoHANDLE(pi.hThread), pi.dwProcessID, pi.dwThreadID
-
-CreateProcess = CreateProcessProto(("CreateProcessW", windll.kernel32),
- CreateProcessFlags)
-CreateProcess.errcheck = ErrCheckCreateProcess
-
-CREATE_BREAKAWAY_FROM_JOB = 0x01000000
-CREATE_DEFAULT_ERROR_MODE = 0x04000000
-CREATE_NEW_CONSOLE = 0x00000010
-CREATE_NEW_PROCESS_GROUP = 0x00000200
-CREATE_NO_WINDOW = 0x08000000
-CREATE_SUSPENDED = 0x00000004
-CREATE_UNICODE_ENVIRONMENT = 0x00000400
-DEBUG_ONLY_THIS_PROCESS = 0x00000002
-DEBUG_PROCESS = 0x00000001
-DETACHED_PROCESS = 0x00000008
-
-# CreateJobObject()
-
-CreateJobObjectProto = WINFUNCTYPE(HANDLE, # Return type
- LPVOID, # lpJobAttributes
- LPCWSTR # lpName
- )
-
-CreateJobObjectFlags = ((1, "lpJobAttributes", None),
- (1, "lpName", None))
-
-CreateJobObject = CreateJobObjectProto(("CreateJobObjectW", windll.kernel32),
- CreateJobObjectFlags)
-CreateJobObject.errcheck = ErrCheckHandle
-
-# AssignProcessToJobObject()
-
-AssignProcessToJobObjectProto = WINFUNCTYPE(BOOL, # Return type
- HANDLE, # hJob
- HANDLE # hProcess
- )
-AssignProcessToJobObjectFlags = ((1, "hJob"),
- (1, "hProcess"))
-AssignProcessToJobObject = AssignProcessToJobObjectProto(
- ("AssignProcessToJobObject", windll.kernel32),
- AssignProcessToJobObjectFlags)
-AssignProcessToJobObject.errcheck = ErrCheckBool
-
-# ResumeThread()
-
-def ErrCheckResumeThread(result, func, args):
- if result == -1:
- raise WinError()
-
- return args
-
-ResumeThreadProto = WINFUNCTYPE(DWORD, # Return type
- HANDLE # hThread
- )
-ResumeThreadFlags = ((1, "hThread"),)
-ResumeThread = ResumeThreadProto(("ResumeThread", windll.kernel32),
- ResumeThreadFlags)
-ResumeThread.errcheck = ErrCheckResumeThread
-
-# TerminateJobObject()
-
-TerminateJobObjectProto = WINFUNCTYPE(BOOL, # Return type
- HANDLE, # hJob
- UINT # uExitCode
- )
-TerminateJobObjectFlags = ((1, "hJob"),
- (1, "uExitCode", 127))
-TerminateJobObject = TerminateJobObjectProto(
- ("TerminateJobObject", windll.kernel32),
- TerminateJobObjectFlags)
-TerminateJobObject.errcheck = ErrCheckBool
-
-# WaitForSingleObject()
-
-WaitForSingleObjectProto = WINFUNCTYPE(DWORD, # Return type
- HANDLE, # hHandle
- DWORD, # dwMilliseconds
- )
-WaitForSingleObjectFlags = ((1, "hHandle"),
- (1, "dwMilliseconds", -1))
-WaitForSingleObject = WaitForSingleObjectProto(
- ("WaitForSingleObject", windll.kernel32),
- WaitForSingleObjectFlags)
-
-INFINITE = -1
-WAIT_TIMEOUT = 0x0102
-WAIT_OBJECT_0 = 0x0
-WAIT_ABANDONED = 0x0080
-
-# GetExitCodeProcess()
-
-GetExitCodeProcessProto = WINFUNCTYPE(BOOL, # Return type
- HANDLE, # hProcess
- LPDWORD, # lpExitCode
- )
-GetExitCodeProcessFlags = ((1, "hProcess"),
- (2, "lpExitCode"))
-GetExitCodeProcess = GetExitCodeProcessProto(
- ("GetExitCodeProcess", windll.kernel32),
- GetExitCodeProcessFlags)
-GetExitCodeProcess.errcheck = ErrCheckBool
diff --git a/demo/x509/ca.py b/demo/x509/ca.py
deleted file mode 100644
index 446998b..0000000
--- a/demo/x509/ca.py
+++ /dev/null
@@ -1,104 +0,0 @@
-#!/usr/bin/env python
-
-"""
-How to create a CA certificate with Python.
-
-WARNING: This sample only demonstrates how to use the objects and methods,
- not how to create a safe and correct certificate.
-
-Copyright (c) 2004 Open Source Applications Foundation.
-Author: Heikki Toivonen
-"""
-
-from M2Crypto import RSA, X509, EVP, m2, Rand, Err
-
-# XXX Do I actually need more keys?
-# XXX Check return values from functions
-
-def generateRSAKey():
- return RSA.gen_key(2048, m2.RSA_F4)
-
-def makePKey(key):
- pkey = EVP.PKey()
- pkey.assign_rsa(key)
- return pkey
-
-def makeRequest(pkey):
- req = X509.Request()
- req.set_version(2)
- req.set_pubkey(pkey)
- name = X509.X509_Name()
- name.CN = 'My CA, Inc.'
- req.set_subject_name(name)
- ext1 = X509.new_extension('subjectAltName', 'DNS:foobar.example.com')
- ext2 = X509.new_extension('nsComment', 'Hello there')
- extstack = X509.X509_Extension_Stack()
- extstack.push(ext1)
- extstack.push(ext2)
-
- assert(extstack[1].get_name() == 'nsComment')
-
- req.add_extensions(extstack)
- req.sign(pkey, 'sha1')
- return req
-
-def makeCert(req, caPkey):
- pkey = req.get_pubkey()
- #woop = makePKey(generateRSAKey())
- #if not req.verify(woop.pkey):
- if not req.verify(pkey):
- # XXX What error object should I use?
- raise ValueError, 'Error verifying request'
- sub = req.get_subject()
- # If this were a real certificate request, you would display
- # all the relevant data from the request and ask a human operator
- # if you were sure. Now we just create the certificate blindly based
- # on the request.
- cert = X509.X509()
- # We know we are making CA cert now...
- # Serial defaults to 0.
- cert.set_serial_number(1)
- cert.set_version(2)
- cert.set_subject(sub)
- issuer = X509.X509_Name()
- issuer.CN = 'The Issuer Monkey'
- issuer.O = 'The Organization Otherwise Known as My CA, Inc.'
- cert.set_issuer(issuer)
- cert.set_pubkey(pkey)
- notBefore = m2.x509_get_not_before(cert.x509)
- notAfter = m2.x509_get_not_after(cert.x509)
- m2.x509_gmtime_adj(notBefore, 0)
- days = 30
- m2.x509_gmtime_adj(notAfter, 60*60*24*days)
- cert.add_ext(
- X509.new_extension('subjectAltName', 'DNS:foobar.example.com'))
- ext = X509.new_extension('nsComment', 'M2Crypto generated certificate')
- ext.set_critical(0)# Defaults to non-critical, but we can also set it
- cert.add_ext(ext)
- cert.sign(caPkey, 'sha1')
-
- assert(cert.get_ext('subjectAltName').get_name() == 'subjectAltName')
- assert(cert.get_ext_at(0).get_name() == 'subjectAltName')
- assert(cert.get_ext_at(0).get_value() == 'DNS:foobar.example.com')
-
- return cert
-
-def ca():
- key = generateRSAKey()
- pkey = makePKey(key)
- req = makeRequest(pkey)
- cert = makeCert(req, pkey)
- return (cert, pkey)
-
-if __name__ == '__main__':
- Rand.load_file('../randpool.dat', -1)
- rsa = generateRSAKey()
- pkey = makePKey(rsa)
- req = makeRequest(pkey)
- print req.as_text()
- cert = makeCert(req, pkey)
- print cert.as_text()
- print cert.as_pem()
- cert.save_pem('my_ca_cert.pem')
- rsa.save_key('my_key.pem', 'aes_256_cbc')
- Rand.save_file('../randpool.dat')
diff --git a/demo/x509/certdata2pem.py b/demo/x509/certdata2pem.py
deleted file mode 100755
index 9fd6d32..0000000
--- a/demo/x509/certdata2pem.py
+++ /dev/null
@@ -1,64 +0,0 @@
-#!/usr/bin/env python
-"""
-Small utility to convert the Mozilla-format certificates
-(/mozilla/security/nss/lib/ckfw/builtins/certdata.txt in the Mozilla CVS)
-into PEM. Got the idea from http://curl.haxx.se/docs/parse-certs.txt.
-
-Copyright (c) 2007 Open Source Applications Foundation.
-"""
-
-import array
-from M2Crypto import X509
-
-counter = 0
-value = None
-name = None
-
-out = open('cacert.pem', 'wb')
-
-for line in open('certdata.txt'):
- line = line.strip()
- if line.startswith('CKA_LABEL'):
- assert value is None
-
- label_encoding, name, dummy = line.split('"')
- label, encoding = label_encoding.split()
-
- assert encoding == 'UTF8'
-
- elif line == 'CKA_VALUE MULTILINE_OCTAL':
- assert name is not None
-
- value = array.array('c')
-
- elif value is not None and line == 'END':
- assert name is not None
-
- print 'Writing ' + name
- x509 = X509.load_cert_string(value.tostring(), X509.FORMAT_DER)
- if not x509.verify():
- print ' Skipping ' + name + ' since it does not verify'
- name = None
- value = None
- continue
- counter += 1
-
- out.write(name + '\n' + '=' * len(name) + '\n\n')
- out.write('SHA1 Fingerprint=' + x509.get_fingerprint('sha1') + '\n')
- out.write(x509.as_text())
- out.write(x509.as_pem())
- out.write('\n')
-
- name = None
- value = None
-
- elif value is not None:
- assert name is not None
-
- for number in line.split('\\'):
- if not number:
- continue
-
- value.append(chr(int(number, 8)))
-
-print 'Wrote %d certificates' % counter
diff --git a/demo/x509/client2.pem b/demo/x509/client2.pem
deleted file mode 100644
index 166919a..0000000
--- a/demo/x509/client2.pem
+++ /dev/null
@@ -1,36 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDDjCCAnegAwIBAgIBAzANBgkqhkiG9w0BAQQFADB7MQswCQYDVQQGEwJTRzER
-MA8GA1UEChMITTJDcnlwdG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQD
-ExtNMkNyeXB0byBDZXJ0aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5n
-cHNAcG9zdDEuY29tMB4XDTAwMTEyMDEzMDMwNVoXDTAyMTEyMDEzMDMwNVowWzEL
-MAkGA1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRowGAYDVQQDExFNMkNyeXB0
-byBDbGllbnQgMjEdMBsGCSqGSIb3DQEJARYObmdwc0Bwb3N0MS5jb20wXDANBgkq
-hkiG9w0BAQEFAANLADBIAkEAn9qneRYTKPokme3obiJa2NTz1Z2kcF3NHVh60Qod
-/TV/q4olPrZdFR2TDWt63Lgnygcsgf3u9pnhcEGk6IvntwIDAQABo4IBBDCCAQAw
-CQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2Vy
-dGlmaWNhdGUwHQYDVR0OBBYEFDKWFe6VWMhtRTE3/78+hAnSGxmvMIGlBgNVHSME
-gZ0wgZqAFPuHI2nrnDqTFeXFvylRT/7tKDgBoX+kfTB7MQswCQYDVQQGEwJTRzER
-MA8GA1UEChMITTJDcnlwdG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQD
-ExtNMkNyeXB0byBDZXJ0aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5n
-cHNAcG9zdDEuY29tggEAMA0GCSqGSIb3DQEBBAUAA4GBABpE9xt1Hlq2dQZUXHuX
-HI57vc2mlWnhhM0wnNhsNZFwfXRHCZOo/JJBhEIT3Rgyz0ErrbOr1SN96HNDKXOD
-z6bh4NxB5DZ9sRPKEBj66zDsWJVMlom+Lkeal+GkVy36vpAyP1r+cTXyc9M2Gw/o
-FBMinMHH/BXvF5GJ+UleheZe
------END CERTIFICATE-----
------BEGIN RSA PRIVATE KEY-----
-MIIBOgIBAAJBAJ/ap3kWEyj6JJnt6G4iWtjU89WdpHBdzR1YetEKHf01f6uKJT62
-XRUdkw1rety4J8oHLIH97vaZ4XBBpOiL57cCAwEAAQJANXfspprUo9MvpPEn2pbR
-Lk/kk2IcW510e0laI0uwBj50djfHqvsU5ccuVLrxowngLGrFmM3G4lnMknR2NvH8
-0QIhAMsK0AwStUNM/KyvIMikHHBOE9PrK7ARgKvlKl+0ieWPAiEAyYwonIVAtr1f
-M8vmrc6TM2YxzSq4+jyYktaaNhYw11kCIA5pmhMBUPSSBm2LkNwtKgeewzGLw/If
-i+6nubZJbnBpAiEAvJQvy4PCsTkvQr+d7zJB+O2920IGId1gxMOXNtQ8jsECIGvn
-Uz54oonshmTg+Kj2DxnUKQEzFAmQLbtFslp1m47v
------END RSA PRIVATE KEY-----
------BEGIN CERTIFICATE REQUEST-----
-MIIBFTCBwAIBADBbMQswCQYDVQQGEwJTRzERMA8GA1UEChMITTJDcnlwdG8xGjAY
-BgNVBAMTEU0yQ3J5cHRvIENsaWVudCAyMR0wGwYJKoZIhvcNAQkBFg5uZ3BzQHBv
-c3QxLmNvbTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQCf2qd5FhMo+iSZ7ehuIlrY
-1PPVnaRwXc0dWHrRCh39NX+riiU+tl0VHZMNa3rcuCfKByyB/e72meFwQaToi+e3
-AgMBAAGgADANBgkqhkiG9w0BAQQFAANBAHI5KXfL6kIRoNjR8G9/uKiPUt4uVBKF
-ecGp87M5t2a92Z0KpWOMXSHZ0LLQKqwWzALvWcPPIj6S8F6ENdwpfMk=
------END CERTIFICATE REQUEST-----
diff --git a/demo/x509/demo1.py b/demo/x509/demo1.py
deleted file mode 100644
index f0aa282..0000000
--- a/demo/x509/demo1.py
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/usr/bin/env python
-
-"""X.509 certificate manipulation and such.
-
-Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
-
-import os
-
-from M2Crypto import X509
-from M2Crypto.EVP import MessageDigest
-
-def demo1():
- print 'Test 1: As DER...'
- cert1 = X509.load_cert('server.pem')
- der1 = cert1.as_der()
- dgst1 = MessageDigest('sha1')
- dgst1.update(der1)
- print 'Using M2Crypto:\n', `dgst1.final()`, '\n'
-
- cert2 = os.popen('openssl x509 -inform pem -outform der -in server.pem')
- der2 = cert2.read()
- dgst2 = MessageDigest('sha1')
- dgst2.update(der2)
- print 'Openssl command line:\n', `dgst2.final()`, '\n'
-
-
-def demo2():
- print 'Test 2: As text...'
- cert = X509.load_cert('client2.pem')
- print 'version ', cert.get_version()
- print 'serial# ', cert.get_serial_number()
- print 'not before ', cert.get_not_before()
- print 'not after ', cert.get_not_after()
- issuer = cert.get_issuer()
- #print 'issuer ', issuer
- print 'issuer.C ', `issuer.C`
- print 'issuer.SP ', `issuer.SP`
- print 'issuer.L ', `issuer.L`
- print 'issuer.O ', `issuer.O`
- print 'issuer.OU ', `issuer.OU`
- print 'issuer.CN ', `issuer.CN`
- print 'issuer.Email', `issuer.Email`
- print 'subject ', cert.get_subject()
- #print cert.as_text(), '\n'
-
-def demo3():
- cert = X509.load_cert('server.pem')
- while 1:
- x = cert.get_subject()
-
-if __name__ == "__main__":
- #demo1()
- demo2()
- #demo3()
diff --git a/demo/x509/proxy_destroy.py b/demo/x509/proxy_destroy.py
deleted file mode 100644
index c79bd2f..0000000
--- a/demo/x509/proxy_destroy.py
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/usr/bin/env python
-############################################################################
-# Matt Rodriguez, LBNL MKRodriguez@lbl.gov
-############################################################################
-"""
-Script that destroys a proxy certificate file by overwriting its contents
-before the file is removed
-"""
-
-import proxylib
-import optparse, os
-
-USAGEHELP = "proxy_destroy.py file1 file2 Destroys files listed"
-JUNK = "LalalAlalaLalalALalalAlalaLalalALalalAlalaLalalALalalAlalaLalalA"
-
-def scrub_file(filename):
- """
- Overwrite the file with junk, before removing it
- """
- s = os.stat(filename)
- proxy_file = file(filename, "w")
- size = s.st_size
- while size > 64:
- proxy_file.write(JUNK)
- size -= 64
-
- proxy_file.flush()
- proxy_file.close()
- os.remove(filename)
-
-
-def main():
- parser = optparse.OptionParser()
- parser.set_usage(USAGEHELP)
- opts, args = parser.parse_args()
- if len(args) is 0:
- proxy_file = proxylib.get_proxy_filename()
- scrub_file(proxy_file)
-
- for proxy_file in args:
- scrub_file(proxy_file)
-
-if __name__ == "__main__": main()
diff --git a/demo/x509/proxy_info.py b/demo/x509/proxy_info.py
deleted file mode 100644
index ce9cdc3..0000000
--- a/demo/x509/proxy_info.py
+++ /dev/null
@@ -1,61 +0,0 @@
-#!/usr/bin/env python
-############################################################################
-# Matt Rodriguez, LBNL MKRodriguez@lbl.gov
-############################################################################
-"""
-script that displays information about a proxy certificate
-"""
-
-
-import proxylib
-import time, datetime, calendar
-import sys, optparse
-
-FILEHELP = "Location of the proxy."
-
-def print_info(proxy_cert):
- """
- Print information about the proxy cert
- """
- cert = proxy_cert.getcert()
- print "Subject: ", cert.get_subject().as_text()
- print "Issuer: ", cert.get_issuer().as_text()
- pubkey = cert.get_pubkey()
- size = pubkey.size()
- print "Strength: ", size * 8
- after = cert.get_not_after()
- after_tuple = time.strptime(str(after),"%b %d %H:%M:%S %Y %Z")
- expires = calendar.timegm(after_tuple)
- now = datetime.timedelta(seconds=time.time())
- expires = datetime.timedelta(seconds=expires)
- td = expires - now
- if td.days < 0:
- print "Time left: Proxy has expired."
- else:
- hours = td.seconds / 3600
- hours += td.days * 24
- minutes = (td.seconds % 3600) / 60
- seconds = (td.seconds % 3600) % 60
- print "Time left: %d:%d:%d" % (hours, minutes, seconds)
- fraction = round((float(td.seconds) / float(3600 * 24)), 1)
- print "Days left: ", str(td.days) + str(fraction)[1:]
-
-
-def main():
- parser = optparse.OptionParser()
- parser.add_option("-f", "--file", dest="filename", help=FILEHELP)
- (opts, args) = parser.parse_args()
- filename = opts.filename
- if filename is None:
- proxyfile = proxylib.get_proxy_filename()
- else:
- proxyfile = filename
- proxy_cert = proxylib.Proxy()
- try:
- proxy_cert.read(proxyfile)
- except IOError:
- print "The file: " + proxyfile + " does not exist."
- sys.exit(0)
- print_info(proxy_cert)
-
-if __name__ == "__main__": main()
diff --git a/demo/x509/proxy_init.py b/demo/x509/proxy_init.py
deleted file mode 100644
index 1ca5cbb..0000000
--- a/demo/x509/proxy_init.py
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/usr/bin/env python
-############################################################################
-# Matt Rodriguez, LBNL MKRodriguez@lbl.gov
-############################################################################
-"""
-script that generates a proxy certificate
-"""
-
-import proxylib
-import optparse
-import sys
-
-OUTHELP = "Location of the new proxy cert."
-CERTHELP = "Location of user certificate."
-KEYHELP = "Location of the user key."
-VALIDHELP = "h:m Proxy certificate is valid for h hours and m minutes."
-FULLPROXY = "Creates a limited proxy"
-def main():
- parser = optparse.OptionParser()
- parser.add_option('-o', '--output', dest='output', help=OUTHELP)
- parser.add_option('-c', '--cert' , dest='cert', help=CERTHELP)
- parser.add_option('-k', '--key', dest='key', help=KEYHELP)
- parser.add_option('-v', '--valid', dest='valid', help=VALIDHELP)
- parser.add_option('-l', '--limited', action="store_true",
- default=False, dest='limited', help=VALIDHELP)
- (opts, args) = parser.parse_args()
- kw = {}
- kw['cert'] = opts.cert
- kw['key'] = opts.key
- if opts.valid is None:
- valid_tuple = (12, 0)
- else:
- valid = opts.valid.split(':')
- valid_tuple = tuple(map(int, valid))
- kw['valid'] = valid_tuple
- kw['full'] = not opts.limited
- try:
- proxy_factory = proxylib.ProxyFactory(kw)
- except IOError:
- print "Can't find usercert or userkey. Use the -c or -k arguments"
- sys.exit(0)
- proxy_factory.generate()
- proxy_cert = proxy_factory.getproxy()
- if opts.output is None:
- proxy_cert.write(proxylib.get_proxy_filename())
- else:
- proxy_cert.write(opts.output)
-
-if __name__ == "__main__": main()
diff --git a/demo/x509/proxylib.py b/demo/x509/proxylib.py
deleted file mode 100644
index e0f3395..0000000
--- a/demo/x509/proxylib.py
+++ /dev/null
@@ -1,327 +0,0 @@
-############################################################################
-# Matt Rodriguez, LBNL
-#Copyright (c) 2003, The Regents of the University of California,
-#through Lawrence Berkeley National Laboratory
-#(subject to receipt of any required approvals from the U.S. Dept. of Energy).
-#All rights reserved.
-############################################################################
-"""
-API to generated proxy certificates
-"""
-import os, sys
-import struct
-import re
-import time, calendar, datetime
-
-import_regex = re.compile(r"\s*libssl.so.0.9.8\s*")
-errstr = "You must have the openssl 0.9.8 libraries in your LD_LIBRARY_PATH"""
-
-try:
- from M2Crypto import BIO, X509, RSA, EVP, ASN1
-except ImportError, ex:
- if import_regex.match(str(ex)):
- print errstr
- sys.exit(-1)
- else:
- raise ex
-
-MBSTRING_FLAG = 0x1000
-MBSTRING_ASC = MBSTRING_FLAG | 1
-KEY_USAGE_VALUE = "Digital Signature, Key Encipherment, Data Encipherment"
-PCI_VALUE_FULL = "critical, language:Inherit all"
-PCI_VALUE_LIMITED = "critical, language:1.3.6.1.4.1.3536.1.1.1.9"
-
-def create_write_file(fname, perm=0600):
- """
- Creates a file to write to while avoiding a possible race condition.
- This is essential for writing out the proxy file. Need to make sure
- there is no pre-existing file.
- """
- if os.path.exists(fname):
- os.remove(fname)
- # Make sure the file doesn't exist. Will throw an exception if
- # it does. This would only happen if the code is attacked.
- fd = os.open(fname, os.O_CREAT|os.O_EXCL|os.O_WRONLY, perm)
- f = os.fdopen(fd, 'w')
- return f
-
-
-class ProxyFactoryException(Exception):
- """
- Base class for exceptions in the ProxyFactory class
- """
-
-class Proxy:
- """
- class that holds proxy certificate information,
- consisting of an issuer cert a user cert and
- a key for the user cert
- """
- def __init__(self):
- self._key = None
- self._cert = None
- self._issuer = None
-
- def read(self, proxypath=None):
- """
- reads in a proxy certificate information
- """
- if proxypath is None:
- proxypath = get_proxy_filename()
-
- proxyfile = open(proxypath)
- bio = BIO.File(proxyfile)
- self._cert = X509.load_cert_bio(bio)
- self._key = RSA.load_key_bio(bio)
- self._issuer = X509.load_cert_bio(bio)
-
- def getcert(self):
- """
- Returns a X509 instance
- """
- return self._cert
-
- def getkey(self):
- """
- Returns a RSA instance
- """
- return self._key
-
- def getissuer(self):
- """
- Returns a X509 instance
- """
- return self._issuer
-
- def setcert(self, cert):
- """
- Sets the user cert should be a X509 instance
- """
- self._cert = cert
-
- def setkey(self, key):
- """
- Sets the user key should be a RSA instance
- """
- self._key = key
-
- def setissuer(self, issuer):
- """
- Sets the issuer cert should be a X509 instance
- """
- self._issuer = issuer
-
- def write(self, proxypath=None):
- """
- Writes the proxy information to a file
- """
- proxyfile = create_write_file(proxypath)
- bio = BIO.File(proxyfile)
- bio.write(self._cert.as_pem())
- self._key.save_key_bio(bio, cipher=None)
- bio.write(self._issuer.as_pem())
- bio.close()
- os.chmod(proxypath, 0600)
-
-
-class ProxyFactory:
- """
- Creates proxies
- """
- def __init__(self, kw={'cert':None,'key':None,'valid':(12,0),'full':True}):
-
- self._usercert = get_usercert(kw['cert'])
- self._userkey = get_userkey(kw['key'])
- self._proxycert = None
- self._proxykey = None
- self._valid = kw['valid']
- self._full = kw['full']
-
- def generate(self):
- """
- generates a new proxy like grid-proxy-init
- """
- if not self._check_valid():
- raise ProxyFactoryException("The issuer cert is expired")
- if self._proxycert is None:
- self._proxycert = X509.X509()
- key = EVP.PKey()
- self._proxykey = RSA.gen_key(512, 65537)
- key.assign_rsa(self._proxykey, capture=0)
- self._proxycert.set_pubkey(key)
- self._proxycert.set_version(2)
- self._set_times()
- issuer_name = self._usercert.get_subject()
- self._proxycert.set_issuer_name(issuer_name)
- serial_number = self._make_serial_number(self._proxycert)
- self._proxycert.set_serial_number(serial_number)
- self._set_subject()
- sign_pk = EVP.PKey()
- sign_pk.assign_rsa(self._userkey)
- self._add_extensions()
- self._proxycert.sign(sign_pk, 'md5')
-
- def set_proxycert(self, proxycert):
- """
- This method is useful if you don't
- want to pay the costs associated with
- generating a new key pair.
- """
- self._proxycert = proxycert
-
- def getproxy(self):
- """
- Return a proxy instance
- """
- proxy = Proxy()
- proxy.setissuer(self._usercert)
- proxy.setcert(self._proxycert)
- proxy.setkey(self._proxykey)
- return proxy
-
- def _set_subject(self):
- """
- Internal method that sets the subject name
- """
- subject_name = X509.X509_Name()
- serial_number = self._make_serial_number(self._proxycert)
- issuer_name = self._usercert.get_subject()
- issuer_name_txt = issuer_name.as_text()
- seq = issuer_name_txt.split(",")
- for entry in seq:
- name_component = entry.split("=")
- subject_name.add_entry_by_txt(field=name_component[0].strip(),
- type=MBSTRING_ASC,
- entry=name_component[1],len=-1,
- loc=-1, set=0)
-
-
- subject_name.add_entry_by_txt(field="CN",
- type=MBSTRING_ASC,
- entry=str(serial_number),
- len=-1, loc=-1, set=0)
-
- self._proxycert.set_subject_name(subject_name)
-
- def _set_times(self):
- """
- Internal function that sets the time on the proxy
- certificate
- """
- not_before = ASN1.ASN1_UTCTIME()
- not_after = ASN1.ASN1_UTCTIME()
- not_before.set_time(int(time.time()))
- offset = (self._valid[0] * 3600) + (self._valid[1] * 60)
- not_after.set_time(int(time.time()) + offset )
- self._proxycert.set_not_before(not_before)
- self._proxycert.set_not_after(not_after)
-
- def _make_serial_number(self, cert):
- """
- Lifted from the globus code
- """
- message_digest = EVP.MessageDigest('sha1')
- pubkey = cert.get_pubkey()
- der_encoding = pubkey.as_der()
- message_digest.update(der_encoding)
- digest = message_digest.final()
- digest_tuple = struct.unpack('BBBB', digest[:4])
- sub_hash = long(digest_tuple[0] + (digest_tuple[1] + ( digest_tuple[2] +
- ( digest_tuple[3] >> 1) * 256 ) * 256) * 256)
- return sub_hash
-
- def _add_extensions(self):
- """
- Internal method that adds the extensions to the certificate
- """
- key_usage_ext = X509.new_extension("keyUsage", KEY_USAGE_VALUE, 1)
- self._proxycert.add_ext(key_usage_ext)
- if self._full:
- pci_ext = X509.new_extension("proxyCertInfo",
- PCI_VALUE_FULL, 1, 0)
- else:
- pci_ext = X509.new_extension("proxyCertInfo",
- PCI_VALUE_LIMITED, 1, 0)
- self._proxycert.add_ext(pci_ext)
-
- def _check_valid(self):
- """
- Internal method that ensures the issuer cert has
- valid, not_before and not_after fields
- """
- before_time = self._usercert.get_not_before()
- after_time = self._usercert.get_not_after()
- before_tuple = time.strptime(str(before_time), "%b %d %H:%M:%S %Y %Z")
- after_tuple = time.strptime(str(after_time), "%b %d %H:%M:%S %Y %Z")
- starts = datetime.timedelta(seconds=calendar.timegm(before_tuple))
- expires = datetime.timedelta(seconds=calendar.timegm(after_tuple))
- now = datetime.timedelta(seconds=time.time())
- time_delta = expires - now
- #cert has expired
- if time_delta.days < 0:
- return False
- #cert is not yet valid, not likely but should still return False
- time_delta = now - starts
- if time_delta.days < 0:
- return False
-
- return True
-
-#Utility Functions
-def get_proxy_filename():
- """
- function that returns the default proxy path
- which is /tmp/x509up_uuid
- """
- if os.name == 'posix':
- proxy_filename = "x509up_u" + (str(os.getuid()))
- proxypath = os.path.join("/tmp", proxy_filename)
- elif os.name == 'nt':
- username = os.getenv("USERNAME")
- if username is None:
- raise RuntimeError("""USERNAME is not set in environment. Can't
- determine proxy file location""")
-
- proxy_filename = "x509up_u" + username
- drive = os.path.splitdrive(os.getcwd())[0]
- proxydir = drive + os.sep + "temp"
- proxypath = os.path.join(proxydir, proxy_filename)
- else:
- except_string = """get_proxy_filename is not supported on this platform
- Try explicitly specifying the location of the
- proxyfile"""
- raise RuntimeError(except_string)
- return proxypath
-
-def get_usercert(certfile=None):
- """
- function that returns a X509 instance which
- is the user cert that is expected to be a ~/.globus/usercert.pem
-
- A check is performed to ensure the certificate has valid
- before and after times.
- """
- if certfile is None:
- certfile = open(os.path.join(os.getenv("HOME"),
- ".globus","usercert.pem"))
- else:
- certfile = open(certfile)
- bio = BIO.File(certfile)
- cert = X509.load_cert_bio(bio)
- return cert
-
-def get_userkey(keyfile=None):
- """
- function that returns a X509 instance which
- is the user cert that is expected to be a ~/.globus/userkey.pem
- """
- if keyfile is None:
- keyfile = open(os.path.join(os.getenv("HOME"),
- ".globus","userkey.pem"))
- else:
- keyfile = open(keyfile)
- bio = BIO.File(keyfile)
- key = RSA.load_key_bio(bio)
- return key
-
-
diff --git a/demo/x509/server-expired.pem b/demo/x509/server-expired.pem
deleted file mode 100644
index 80ef9dc..0000000
--- a/demo/x509/server-expired.pem
+++ /dev/null
@@ -1,36 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDBjCCAm+gAwIBAgIBATANBgkqhkiG9w0BAQQFADB7MQswCQYDVQQGEwJTRzER
-MA8GA1UEChMITTJDcnlwdG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQD
-ExtNMkNyeXB0byBDZXJ0aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5n
-cHNAcG9zdDEuY29tMB4XDTAwMDkxMDA5NTEzMFoXDTAyMDkxMDA5NTEzMFowUzEL
-MAkGA1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRIwEAYDVQQDEwlsb2NhbGhv
-c3QxHTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tMFwwDQYJKoZIhvcNAQEB
-BQADSwAwSAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh
-5kwIzOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEAAaOCAQQwggEAMAkGA1UdEwQC
-MAAwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRl
-MB0GA1UdDgQWBBTPhIKSvnsmYsBVNWjj0m3M2z0qVTCBpQYDVR0jBIGdMIGagBT7
-hyNp65w6kxXlxb8pUU/+7Sg4AaF/pH0wezELMAkGA1UEBhMCU0cxETAPBgNVBAoT
-CE0yQ3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UEAxMbTTJDcnlw
-dG8gQ2VydGlmaWNhdGUgTWFzdGVyMR0wGwYJKoZIhvcNAQkBFg5uZ3BzQHBvc3Qx
-LmNvbYIBADANBgkqhkiG9w0BAQQFAAOBgQA7/CqT6PoHycTdhEStWNZde7M/2Yc6
-BoJuVwnW8YxGO8Sn6UJ4FeffZNcYZddSDKosw8LtPOeWoK3JINjAk5jiPQ2cww++
-7QGG/g5NDjxFZNDJP1dGiLAxPW6JXwov4v0FmdzfLOZ01jDcgQQZqEpYlgpuI5JE
-WUQ9Ho4EzbYCOQ==
------END CERTIFICATE-----
------BEGIN RSA PRIVATE KEY-----
-MIIBPAIBAAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh
-5kwIzOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEAAQJBAIqm/bz4NA1H++Vx5Ewx
-OcKp3w19QSaZAwlGRtsUxrP7436QjnREM3Bm8ygU11BjkPVmtrKm6AayQfCHqJoT
-ZIECIQDW0BoMoL0HOYM/mrTLhaykYAVqgIeJsPjvkEhTFXWBuQIhAM3deFAvWNu4
-nklUQ37XsCT2c9tmNt1LAT+slG2JOTTRAiAuXDtC/m3NYVwyHfFm+zKHRzHkClk2
-HjubeEgjpj32AQIhAJqMGTaZVOwevTXvvHwNEH+vRWsAYU/gbx+OQB+7VOcBAiEA
-oolb6NMg/R3enNPvS1O4UU1H8wpaF77L4yiSWlE0p4w=
------END RSA PRIVATE KEY-----
------BEGIN CERTIFICATE REQUEST-----
-MIIBDTCBuAIBADBTMQswCQYDVQQGEwJTRzERMA8GA1UEChMITTJDcnlwdG8xEjAQ
-BgNVBAMTCWxvY2FsaG9zdDEdMBsGCSqGSIb3DQEJARYObmdwc0Bwb3N0MS5jb20w
-XDANBgkqhkiG9w0BAQEFAANLADBIAkEArL57d26W9fNXvOhNlZzlPOACmvwOZ5Ad
-NgLzJ1/MfsQQJ7hHVeHmTAjM664V+fXvwUGJLziCeBo1ysWLRnl8CQIDAQABoAAw
-DQYJKoZIhvcNAQEEBQADQQA7uqbrNTjVWpF6By5ZNPvhZ4YdFgkeXFVWi5ao/TaP
-Vq4BG021fJ9nlHRtr4rotpgHDX1rr+iWeHKsx4+5DRSy
------END CERTIFICATE REQUEST-----
diff --git a/demo/x509/server.pem b/demo/x509/server.pem
deleted file mode 100644
index 1ee9282..0000000
--- a/demo/x509/server.pem
+++ /dev/null
@@ -1,36 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDYjCCAsugAwIBAgIBBDANBgkqhkiG9w0BAQQFADCBgDELMAkGA1UEBhMCU0cx
-ETAPBgNVBAoTCE0yQ3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UE
-AxMbTTJDcnlwdG8gQ2VydGlmaWNhdGUgTWFzdGVyMSIwIAYJKoZIhvcNAQkBFhNu
-Z3BzQG5ldG1lbWV0aWMuY29tMB4XDTAzMDYyMjEzMzAxNFoXDTA0MDYyMTEzMzAx
-NFowXTELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRIwEAYDVQQDEwls
-b2NhbGhvc3QxJzAlBgkqhkiG9w0BCQEWGGFkbWluQHNlcnZlci5leGFtcGxlLmRv
-bTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA37aKGZtFicl8xXXTLJ8/JD7c
-kd3t/teCX9i61lpaDQCKBoVrrursIvZihemMKI9g/u/+BLqt5g8mBdgUdYz0txc8
-KEbV2hj+wwOX4H3XwD0Y+DysXiNHq7/tFdmzSVHoLxpY4zYzXbxQ/p049wvIyPRp
-/y3omcnx/TEUhkn+JmkCAwEAAaOCAQwwggEIMAkGA1UdEwQCMAAwLAYJYIZIAYb4
-QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBTB
-H/mUYlww24mJlSxEtGdlwojO9zCBrQYDVR0jBIGlMIGigBTr+pwHMS1CmF9cuGI4
-du3YqoHAwqGBhqSBgzCBgDELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRv
-MRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UEAxMbTTJDcnlwdG8gQ2VydGlm
-aWNhdGUgTWFzdGVyMSIwIAYJKoZIhvcNAQkBFhNuZ3BzQG5ldG1lbWV0aWMuY29t
-ggEAMA0GCSqGSIb3DQEBBAUAA4GBAAvl6v0s3eFeGP4iAcrfysuK7jzFKhjDYuOy
-lVS3u33bZNLnMpM6OSEM9yPh4WpFCVHf+nYwC71pk4ilsLVXjKxymm2lNGcxLVuW
-iydFz4Ly9nmN7Ja9ygYT39dGAFP/wN7ELTpsbul8VfmqhNg9y81d8i/A1tK3AGA8
-0QkPQNdP
------END CERTIFICATE-----
------BEGIN RSA PRIVATE KEY-----
-MIICXAIBAAKBgQDftooZm0WJyXzFddMsnz8kPtyR3e3+14Jf2LrWWloNAIoGhWuu
-6uwi9mKF6Ywoj2D+7/4Euq3mDyYF2BR1jPS3FzwoRtXaGP7DA5fgfdfAPRj4PKxe
-I0erv+0V2bNJUegvGljjNjNdvFD+nTj3C8jI9Gn/LeiZyfH9MRSGSf4maQIDAQAB
-AoGAHpeVtv62uarl9xKvuBBm0AwQmZnhq9HIsFaw5hMg8Vo7hbzFBvx1IirTOkC/
-u+QvfW1QLVFh6m3z4ySzV4fZBtcd6F9SbSrZ0xsxIUB2NOSa1RGgiaP61bJnMMM1
-xM3O9iwM5GZc3Gqy08QOCpDl0772VJ+9Gz3FA88mrc6rHQkCQQDz6RIatFjT28n8
-1vy0nHwwZz2oXTpe/pyZPwoKj8zVsmrKhKwOw7l8ArxjP8zoHOE7AQBCXYDMNoFp
-IAF0yuqrAkEA6s0wMEdPpQeb0XHAfccyJQoeULxHdVFoz1wWmGSOm4YmQtR8/QJx
-luEgfpeRkzxBKt5Ls3MEkheIOw7xV24zOwJAMz+DaE0AZPNHS3K4ghJnHZxzng6I
-lzEUIjbWm0V/ml70hTy/EhMZw+6nOotLOHHo+QbK0SboSwAgzL/Gzo1cJQJANqpS
-38qadleRJXAQWrg3qnvyluVe1aeAeVZ9RDmVIgxXeBO0jcs12uTLBe4PzHGo0mwy
-v7K1i7XC180gzzQu5QJBAOxITT9RoWSSozPvnirHd37sn+RsrNYkV07NAa80M20Z
-DkBPHeMVkNgigrQ6L6vWmbRDGQbGcMplAxnI5ppKCoU=
------END RSA PRIVATE KEY-----
diff --git a/demo/x509/x509auth.py b/demo/x509/x509auth.py
deleted file mode 100644
index a1f6e4b..0000000
--- a/demo/x509/x509auth.py
+++ /dev/null
@@ -1,675 +0,0 @@
-#!/usr/bin/env python2
-#
-# vim: ts=4 sw=4 nowrap
-#
-# ChannelHandler
-# ReceiveChannel
-# SendChannel
-#
-# SocketDispatcher
-# Loop
-# Poll
-# ReadEvent
-# WriteEvent
-#
-import sys, re, time, thread, os
-import getopt
-import exceptions
-import select
-import string
-import socket
-import StringIO
-import traceback
-
-
-from errno import EALREADY, EINPROGRESS, EWOULDBLOCK, ECONNRESET, ENOTCONN, ESHUTDOWN, EINTR, EISCONN
-
-STDOUT = sys.stdout
-
-IDstdin = 0
-IDstdout = 1
-IDstderr = 2
-
-
-
-
-class ExitNow (exceptions.Exception):
- pass
-
-
-class AuthError(exceptions.Exception):
- def __init__ (self, msg):
- self.msg = msg
- def __str__ (self):
- return repr( self.msg )
-
-#----------------------------------------------------------------
-#
-# Class Security Certification
-#
-#----------------------------------------------------------------
-import M2Crypto
-import random
-import base64
-import sha
-
-class CertHandler:
-
- def __init__ ( self ):
- self.Nonce = None
- self.CurrentObj = {}
- #self.ServerName = socket.gethostbyaddr(socket.gethostname())[2][0]
- self.ServerName = 'AuthInstance'
-
- self.ObjNames = { 'C' : 'countryName', 'ST' : 'stateOrProvinceName', 'L' : 'localityName', 'O' : 'organizationName', 'OU' : 'organizationalUnitName', 'CN' : 'commonName', 'email' : 'emailAddress' }
- self.ObjMap = {}
-
- self.Params = { 'Digest' : 'sha1',
- 'Version' : 1,
- 'Serial' : 1,
- 'NotBefore' : ( 60 * 60 * 24 * 365 ),
- 'NotAfter' : ( 60 * 60 * 24 * 365 * 5 ),
- 'Issuer' : { 'countryName' : 'US', 'stateOrProvinceName' : 'florida', 'localityName' : 'tampas', 'organizationName' : 'watersprings', 'organizationalUnitName' : 'security', 'commonName' : 'Certificate Authority', 'emailAddress' : 'admin@security' },
- 'Subject' : { 'countryName' : 'US', 'stateOrProvinceName' : 'florida', 'localityName' : 'miami', 'organizationName' : 'watersprings', 'organizationalUnitName' : 'security', 'commonName' : 'Certificate Authority', 'emailAddress' : 'admin@security' }
- }
- self.KeyEnv = { 'RsaPubKey' : [ '-----BEGIN PUBLIC KEY-----', '-----END PUBLIC KEY-----' ],
- 'RsaPKey' : [ '-----BEGIN RSA PRIVATE KEY-----', '-----END RSA PRIVATE KEY-----' ],
- 'X509Cert' : [ '-----BEGIN CERTIFICATE-----', '-----END CERTIFICATE-----' ]
- }
- self.CertContainer ()
-
- self.ObjFromContainer ( ObjName='CA' )
- self.ObjFromContainer ( ObjName=self.ServerName )
- self.ServerObj = self.ObjMap[ self.ServerName ]
-
-
-
-
-
- def CertContainer (self):
- self.PemMap = { 'CA' : { 'Subject' : {'organizationalUnitName': 'security', 'organizationName': 'watersprings', 'commonName': 'Certificate Authority', 'stateOrProvinceName': 'florida', 'countryName': 'US', 'emailAddress': 'admin@security', 'localityName': 'miami'},
- 'RsaPKey' : ['MIICXQIBAAKBgQDmAl+4+XdF34D3kBN58An29mA8/D+NUHVJW+XeE96uDJ9mw8f1', 'xguVYgfpMaiVihW/qDWZRu/NhWOfheKBVNstx5OcqIjY10vBvGAG17CQZhcon8eN', 'Kufg7XzON7e5WXXD8qyklhuesHtTEGGpZ1FfA+n+D/0JF3YfTBDeYyY2VQIDAQAB', 'AoGBAI53L/Uxx7fmzUoJ2pZvoKxwRIHhuDd+e3c5zbJ1WjsyJFWRtLw9tBUOCFpf', 'YM1nHzt8I97RulzxXxiC5B45ghu3S0s+B06oEOUxNLbjsai08DKBRFqM+IZIx11r', 'IM/tZsTdJg1KtKojRu63NDtOzR6a7ggTeMge5CDKpXVWpvVtAkEA+QF/q2NnsdmL', 'ak6ALl8QwMbvwujJcjLwvecHQJmB0jO9KF60Hh4VY8mTRIMZ/r9Wf+REsQcZtmhG', 'WRr12si5qwJBAOx4R0Wd/inoXOpvKheIoKgTg01FnLhT8uiLY59CuZRr6AcTELjC', 'Kvk6LyfhspYBkUwWAEwKxJ3kMeqXG+k8z/8CQQCy+GDKzqe5LKMHxWRb7/galuG9', 'NZOUgQiHdYXA6JRmgMl0Op07CGRXVIqEs7X7Y4rIYUj99ByG/muRn88VcTABAkBQ', 'Z6V0WoBtp4DQhfP+BIr8G4Zt49miI4lY4OyC3qFTgk1m+miZKgyKqeoW2Xtr3iSV', 'hnWbZZ3tQgZnCfKHoBHpAkAmf2OvfhLxaW1PwdjBdm9tFGVbzkLFDqdqww2aHRUx', 'sXonHyVG2EDm37qW7nzmAqUgQCueMhHREZQYceDrtLLO'],
- 'X509Cert' : ['MIICpzCCAhCgAwIBAQIBATANBgkqhkiG9w0BAQUFADCBmTERMA8GA1UECxMIc2Vj', 'dXJpdHkxFTATBgNVBAoTDHdhdGVyc3ByaW5nczEeMBwGA1UEAxMVQ2VydGlmaWNh', 'dGUgQXV0aG9yaXR5MRAwDgYDVQQIEwdmbG9yaWRhMQswCQYDVQQGEwJVUzEdMBsG', 'CSqGSIb3DQEJARYOYWRtaW5Ac2VjdXJpdHkxDzANBgNVBAcTBnRhbXBhczAeFw0w', 'MzAzMzExMDQ2MDVaFw0wOTAzMjkxMDQ2MDVaMIGYMREwDwYDVQQLEwhzZWN1cml0', 'eTEVMBMGA1UEChMMd2F0ZXJzcHJpbmdzMR4wHAYDVQQDExVDZXJ0aWZpY2F0ZSBB', 'dXRob3JpdHkxEDAOBgNVBAgTB2Zsb3JpZGExCzAJBgNVBAYTAlVTMR0wGwYJKoZI', 'hvcNAQkBFg5hZG1pbkBzZWN1cml0eTEOMAwGA1UEBxMFbWlhbWkwgZ8wDQYJKoZI', 'hvcNAQEBBQADgY0AMIGJAoGBAOYCX7j5d0XfgPeQE3nwCfb2YDz8P41QdUlb5d4T', '3q4Mn2bDx/XGC5ViB+kxqJWKFb+oNZlG782FY5+F4oFU2y3Hk5yoiNjXS8G8YAbX', 'sJBmFyifx40q5+DtfM43t7lZdcPyrKSWG56we1MQYalnUV8D6f4P/QkXdh9MEN5j', 'JjZVAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAK7f4YodUnT7Ygp7BWBBDHSq/r+tY', 'H69ly3W23U5VupaIglNiNQoMqnZpVVfcuIYltajrux5TSH4gPbenCg163Ua8RvF6', 'E2JElccprbKiCf9tf8l6Rxpsall4EF+CazP56DiUD1NfGLhWp9V2ga9SoynEo1P1', 'eztMBfk01atBJ/s=']
- },
- 'AuthInstance' : { 'Subject' : {'commonName': 'AuthInstance', 'organizationalUnitName': 'security', 'emailAddress': 'ioclient@AuthInstance'},
- 'RsaPKey' : ['MIICXQIBAAKBgQCwfB6CoOQTJTd6D4ua1G/H9hwqpdVUMMjG3O8Y93vYGesZdwtT', '1iEQX/6TWACBxa7jOC8hHUHe2lsPu7imHv8dDiD59Rzets7BM88HsJTemYrxSv5G', 'uh8FloB1KEtSHeCZSlDT/tzSX4M0JfVPmtx+0FsyDOVZ6jXjRIyIKgqDlwIDAQAB', 'AoGAYc8YFatXW6j3mwU8iL2NidPC/nvTxAoZa+UL+dlG4JhUrFNGitsUjf+1ljFi', 'bomBiFod/Is7c2euqgSOrDpnheYlogv2QpnP80YUpiv9OruaB9I1zqJ7QM7PrkrH', 'm1C36DzyzVY+4DMvTV29do4Mf6CKT8xf6hXlLK/NbqwO9NkCQQDYwxwCTWxrkX08', '+0c5KaTYxfqCByxOqoiKl97p6wHxNtlzdLeFoSZD0n3Q1c2v0DIXhcBPRPPaZBWC', 'yTayMkRzAkEA0G6I5mHQVNIx18Xmc75urC0QWrum9cj5VcyRvl3KCzB2kQoXkx6v', 'y0JN6YS37rSp8vmvIFNO/oHWSuEJlFYfTQJAajWv07D8Hvj61JaLH4c4Lr9TL8M0', 'Apesr7wajaOJIBgwFFJsWh3MEg9hdqJMVok9AimXQUAX/DpuD9dn5Yib4QJBAIdt', 'Kno2V7ylDkmahk/yDcrFRPkPMD5GpOrAjnnYSqzWglNe8U5gA+zXWfQ+jZwFut7q', 'qIUiXBM1nVzttuGwy4kCQQC3MHppypSWoFqd+TaxK3MX/HoZqaoRELXdeiniOt3Z', 'gFMJ4m6D9lL4segWDoDpequjDYxv2cl+wS1+qDOyeG3J'],
- 'X509Cert' : ['MIIBxDCCAS2gAwIBAQIBATANBgkqhkiG9w0BAQUFADAAMB4XDTAzMDMzMTEwNTE1', 'N1oXDTA5MDMyOTEwNTE1N1owUDEkMCIGCSqGSIb3DQEJARYVaW9jbGllbnRAQXV0', 'aEluc3RhbmNlMREwDwYDVQQLEwhzZWN1cml0eTEVMBMGA1UEAxMMQXV0aEluc3Rh', 'bmNlMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCwfB6CoOQTJTd6D4ua1G/H', '9hwqpdVUMMjG3O8Y93vYGesZdwtT1iEQX/6TWACBxa7jOC8hHUHe2lsPu7imHv8d', 'DiD59Rzets7BM88HsJTemYrxSv5Guh8FloB1KEtSHeCZSlDT/tzSX4M0JfVPmtx+', '0FsyDOVZ6jXjRIyIKgqDlwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFsXewlXnKpH', 'uSwxavmLPUqRk7o1D5E3ByTddBe3BY5NqEXk7Y2SJFtumiuUY5/sWB/aO8Xbqj/b', '/7Cwg9+bc9QqxeeIe/YvtFOmv1ELh2BC1Nof7zSa5rLa/+gPYCoogS4mLRMuUfRk', 'tVHhpoxL1B+UXp4jNeKeTgquOjpUiyBR']
- },
- '192.168.1.20' : { 'Subject' : {'commonName': '192.168.1.20', 'organizationalUnitName': 'security', 'emailAddress': 'ioclient@192.168.1.20'},
- 'RsaPKey' : ['MIICWwIBAAKBgQDD285BGY+FHhfpRvcqupN8X2lPwUNq4G7k5kit5cyuQLfN0+eQ', 'I+VFZdtfJhCZC54dEIvNgA4I7563pRUD0S9rmN6kh/M0GgrKZjYNO+CvvG2dts26', 'MGK0eUQaSsvDf9phEA+0mSv9dsUrdyBTJBn4mXvApekYHt+mNLfCVLkM1QIDAQAB', 'AoGAMqcFB3cJ0/59Zpowz/8ip3axcKvluJ1EcLRRtY+JyML6BiQ4beGqqLD38/qP', 'LlV/1bpyvXnRp2P5IztxXORbo77IzDVzl62YesQATnecSCMLTaeOusy2EZZsjE0k', 'V2cR1rZvzyJPY+Fi8X54hiB+5IcKkPRX9LVw7+yBbBh4sKECQQD0Yi0/DGa3IetR', '9F+/jgN/VIcTd5KwMBW3Bw/+Bh78ZlZGaucpRiR1IQuD7sLTnhNS6RMJUxv10jnS', 'BGW9pjX5AkEAzSslOGFyJ5Aoy48rgC2kKwq6nFKJ/PmY92cnm0nqmwb2npbOtDxz', 'sPUdb7oYmUU/nVCJh3yb+KJIw2g9XxnUvQJAG8ybNwPTH1vlZ+Izjhe6gB5+axF8', 'BzzBC5vrDstldPKzN7lraD+JYCWNKMndMbNWoWTP/IyOrqzmVOSZKjShCQJAbzuE', 'C2QxaqeqpmnxkKWuCrPfZl8NdryvpPolK/jQG8qTrHlgibD4nCjYE7nWGkrD6Xs/', 'hNgXC56YSnDaTRQJFQJAD5GFACv9QgcMZhy1hza0yGDMSQ0WR8/y3CJhi3DPOuAf', 'MetGM1kLQR8bDFrl7yEs+Nufk8QTsE5ngZ7dGFgmuA=='],
- 'X509Cert' : ['MIIBxDCCAS2gAwIBAQIBATANBgkqhkiG9w0BAQUFADAAMB4XDTAzMDMzMTEwNTMw', 'NVoXDTA5MDMyOTEwNTMwNVowUDEkMCIGCSqGSIb3DQEJARYVaW9jbGllbnRAMTky', 'LjE2OC4xLjIwMREwDwYDVQQLEwhzZWN1cml0eTEVMBMGA1UEAxMMMTkyLjE2OC4x', 'LjIwMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDD285BGY+FHhfpRvcqupN8', 'X2lPwUNq4G7k5kit5cyuQLfN0+eQI+VFZdtfJhCZC54dEIvNgA4I7563pRUD0S9r', 'mN6kh/M0GgrKZjYNO+CvvG2dts26MGK0eUQaSsvDf9phEA+0mSv9dsUrdyBTJBn4', 'mXvApekYHt+mNLfCVLkM1QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAA5pWiXJOHCJ', 'P6kHcBITJuwv94zZ0dbHby1ljUfG/8z3Fmr8JRUcTuTtgVYH9M0O9QujIR8YLWSV', '0GeD3nkLRn0+ezam0CW0dF/Ph5vNXFP4a0DSEVv7T0G21VFmbUV3xrVeaXARFuLa', 'AtqRoSyBMajd3g0WNXDCgGEH7LvzJ5EP']
- },
- '192.168.1.26' : { 'Subject' : {'commonName': '192.168.1.26', 'organizationalUnitName': 'security', 'emailAddress': 'ioclient@192.168.1.26'},
- 'RsaPKey' : ['MIICXQIBAAKBgQC5ILRHC3wFoqG9Egb96N3iGEnVrgvQikHyXYc/jFMUgB79rVJp', 'hY1MziGkSjSyc3RFMshkjHlMlARMPCNtomIikqAQaO4Eke2SYWyaOBoTdkeOy+yZ', 't/POpoGp3nRmKGed6NNcdMd5BO01GiatUb7X/Se3Yyvmj5UcEmv/hZQGFwIDAQAB', 'AoGBALdR5FMp0zE9X437iQLsErQuOwcmpzplfnJDHYfXK/nz+TxY4m/tuQNiZ7vp', 'Y4+Gdo+Dfx7aX89uD2dycd7B2wwTziBGIEjhusD8gtralVjhBDjCowSOkezWTeY+', '2h40NB4e1uypOZb0PXWvAL/l9xN7NBGioq9zmShT5c+FFO8RAkEA4k3QSaT1ScGI', '5II5JolvPnv6yS+0dCQTn1SC2ABWbH75NDUHMGAdNIf1sqhaLSQnY9GuXhb8XqX6', 'UUhoypUHzwJBANFrqnuEuTNKR0HVD31/2trPYLfZL6/9RUsR4mlvxPb0tX+T5LVL', '5he43zbura/lZqNxt0ZVeD03LanPN7bvZzkCQQCMAToIJa6+x6YKQOpchhA1pvwb', 'NZE9fQhKvT0JpwPQsak4/EmLSxsmYarGsdLANKrN3W4ztaLCZ4r6eIKkOhkPAkBz', 'ke4wYitucbRnUTRONuvJSx599x6JCcVey0zekO7qtlsfP7e8kVk2iDCu+QLjCj8d', 'Pdk9uFc1uSi7CH8ftniJAkBLNYF0kfGC+CaTuyfnIwiBZ/tjmm4UvHfwtlaZHJYc', 'QIjimBxVA7mujrv3xIBTiDMdxUhq9YIaKIEdlveaTwPK'],
- 'X509Cert' : ['MIIBxDCCAS2gAwIBAQIBATANBgkqhkiG9w0BAQUFADAAMB4XDTAzMDMzMTEwNTQx', 'NloXDTA5MDMyOTEwNTQxNlowUDEkMCIGCSqGSIb3DQEJARYVaW9jbGllbnRAMTky', 'LjE2OC4xLjI2MREwDwYDVQQLEwhzZWN1cml0eTEVMBMGA1UEAxMMMTkyLjE2OC4x', 'LjI2MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC5ILRHC3wFoqG9Egb96N3i', 'GEnVrgvQikHyXYc/jFMUgB79rVJphY1MziGkSjSyc3RFMshkjHlMlARMPCNtomIi', 'kqAQaO4Eke2SYWyaOBoTdkeOy+yZt/POpoGp3nRmKGed6NNcdMd5BO01GiatUb7X', '/Se3Yyvmj5UcEmv/hZQGFwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAMPd5SXzpwZ+', '40SdOv/PeQ5cjieDm6QjndWE/T8nG2I5h6YRWbZPohsCClQjrTyZCMXwcUiCimuJ', 'BaMigI/YqP5THVv58Gu8DpoVZppz7uhUNS5hsuV9lxZUh1bRkUtL6n0qSTEdM34I', 'NJBJKGlf0skULg9BT4LJYTPGWJ0KosUl']
- }
- }
-
- def CreateObj ( self, ObjName='CA' ):
- self.ObjMap[ObjName] = { 'RsaPKey' : None,
- 'PsaPubKey' : None,
- 'EvpPKey' : None,
- 'EvpPubKey' : None,
- 'X509Req' : None,
- 'X509Cert' : None,
- }
- self.CurrentObj = self.ObjMap[ObjName]
-
- def ObjFromContainer (self, ObjName='CA' ):
- if not self.ObjMap.has_key( ObjName ):
- self.CreateObj ( ObjName=ObjName )
- self.PKeyFromPemRepr ( ObjName=ObjName )
- self.CertFromPemRepr ( ObjName=ObjName )
-
- def PKeyFromPemRepr ( self, ObjName=None, PemPKey=None ):
- def callback (): return ''
- if self.PemMap.has_key( ObjName ):
- UsedPemPKey = self.KeyEnv['RsaPKey'][0] + '\n' + string.join( self.PemMap[ObjName]['RsaPKey'], '\n' ) + '\n' + self.KeyEnv['RsaPKey'][1] + '\n'
- else:
- if not PemPKey:
- raise AuthError( 'no such Object "%s" in container - abort!' % ObjName )
- else:
- UsedPemPKey = PemPKey
- self.CurrentObj['RsaPKey'] = M2Crypto.RSA.load_key_string( UsedPemPKey, callback )
- self.CurrentObj['EvpPKey'] = M2Crypto.EVP.PKey ( md='sha1' )
- self.CurrentObj['EvpPKey'].assign_rsa ( self.CurrentObj['RsaPKey'] )
- self.CurrentObj['RsaPubKey'] = M2Crypto.RSA.new_pub_key( self.CurrentObj['RsaPKey'].pub () )
-
- def CertFromPemRepr ( self, ObjName=None, PemCert=None ):
- if self.PemMap.has_key( ObjName ):
- UsedPemCert = self.KeyEnv['X509Cert'][0] + '\n' + string.join( self.PemMap[ObjName]['X509Cert'], '\n' ) + '\n' + self.KeyEnv['X509Cert'][1] + '\n'
- else:
- UsedPemCert = PemCert
- self.CurrentObj['X509Cert'] = M2Crypto.X509.load_cert_string( PemCert )
- self.CurrentObj['EvpPubKey'] = self.CurrentObj['X509Cert'].get_pubkey ()
- #self.CurrentObj['RsaPubKey'] = M2Crypto.RSA.rsa_from_pkey( self.CurrentObj['EvpPubKey'] )
-
- def ObjNameFromPemCert ( self, PemCert=None ):
- """
- generate objmap structure and fill it with values from PemCert
- return ObjName string
- """
- X509Cert = M2Crypto.X509.load_cert_string( PemCert )
- Subject = X509Cert.get_subject ()
- SubjectTxt = Subject.print_ex ()
- SubjectTxtList = re.split('[\n\r]', SubjectTxt )
- SubjectMap = {}
- for Entry in SubjectTxtList:
- ( Key, Value ) = re.split('=', Entry)
- if self.ObjNames.has_key( Key ):
- SubjectMap[ self.ObjNames[Key] ] = Value
- else:
- SubjectMap[ Key ] = Value
- if not SubjectMap.has_key( 'commonName' ):
- return False
- ObjName = SubjectMap['commonName']
- if not self.ObjMap.has_key( ObjName ):
- self.CreateObj( ObjName=ObjName )
- self.CurrentObj = self.ObjMap[ObjName]
- self.CurrentObj['X509Cert'] = X509Cert
- self.CurrentObj['EvpPubKey'] = self.CurrentObj['X509Cert'].get_pubkey ()
- self.CurrentObj['RsaPubKey'] = M2Crypto.RSA.rsa_from_pkey( self.CurrentObj['EvpPubKey'] )
- else:
- self.CurrentObj = self.ObjMap[ ObjName ]
- return ObjName
-
-
-
- def ServerCert ( self ):
- self.ObjFromContainer( ObjName='X509Auth' )
-
-
- def CreatePKey ( self ):
- def PassPhraseFkt (): return ''
- RsaKeyParams = { 'KeyLength' : 1024,
- 'PubExponent' : 0x10001, # -> 65537
- 'keygen_callback' : PassPhraseFkt
- }
- self.CurrentObj['RsaPKey'] = M2Crypto.RSA.gen_key( RsaKeyParams['KeyLength'], RsaKeyParams['PubExponent'], RsaKeyParams['keygen_callback'] )
- self.CurrentObj['EvpPKey'] = M2Crypto.EVP.PKey ( md=self.Params['Digest'] )
- self.CurrentObj['EvpPKey'].assign_rsa ( self.CurrentObj['RsaPKey'] )
- #print self.EvpPKey
-
-
- def CreateCert ( self, SignEvpPKey=None ):
- """
- generate new x509 certificate
- SignEvpKey pkey to sign x509 certification, if None this x509 cert will be self signed
- """
- self.CurrentObj = self.ObjMap['CA']
- self.CreatePKey ()
- X509Cert = M2Crypto.X509.X509 ()
- X509Cert.set_version ( self.Params['Version'] )
- X509Cert.set_serial_number ( self.Params['Serial'] )
- X509Cert.set_not_before ( int( time.time() - self.Params['NotBefore'] )) # 1 year in the past
- X509Cert.set_not_after ( int( time.time() + self.Params['NotAfter'] )) # 5 years in the future
- X509Cert.set_issuer ( self.Params['Issuer'] )
- X509Cert.set_subject ( self.Params['Subject'] )
- X509Cert.set_pubkey ( self.CurrentObj['EvpPKey'] )
- if SignEvpPKey:
- X509Cert.sign ( SignEvpPKey, self.Params['Digest'] )
- else:
- X509Cert.sign ( self.CurrentObj['EvpPKey'], self.Params['Digest'] )
- self.CurrentObj['X509Cert'] = X509Cert
- self.DumpOutInternalPemRepr( ObjName='CA' )
-
-
- def CreateObjCert (self, ObjName):
- """
- generate Obj with new PKey and Request, signed by 'CA'
- ObjName the primary key to identify key-pair
- """
- # new obj
- if not self.ObjMap.has_key( ObjName ):
- self.ObjMap[ObjName] = {}
- self.CurrentObj = self.ObjMap[ObjName]
- if not self.CurrentObj.has_key( 'Subject' ):
- self.CurrentObj['Subject'] = { 'organizationalUnitName' : 'security', 'commonName' : ObjName, 'emailAddress' : 'ioclient@' + ObjName }
- # new pkey
- self.CreatePKey ()
- # new request
- self.CreateReq ( SignEvpPKey=self.ObjMap['CA']['EvpPKey'] )
- # new certification
- if not self.Req2Cert ( SignEvpPKey=self.ObjMap['CA']['EvpPKey'] ):
- print "300 error occured while verifying - abort!"
- # shipout x509 certification
- self.DumpOutInternalPemRepr( ObjName=ObjName )
-
-
- def CreateReq ( self, SignEvpPKey=None ):
- X509Req = M2Crypto.X509.Request ()
- if self.Params['Version']:
- X509Req.set_version ( self.Params['Version'] )
- X509Req.set_subject ( self.CurrentObj['Subject'] )
- X509Req.set_pubkey ( self.CurrentObj['EvpPKey'] )
- if SignEvpPKey:
- X509Req.sign ( SignEvpPKey, self.Params['Digest'] )
- else:
- X509Req.sign ( self.CurrentObj['EvpPKey'], self.Params['Digest'] )
- self.CurrentObj['X509Req'] = X509Req
-
-
- def Req2Cert ( self, SignEvpPKey=None ):
- X509Cert = M2Crypto.X509.X509 ()
- Version = self.CurrentObj['X509Req'].get_version ()
- X509Cert.set_version ( Version )
- X509Cert.set_serial ( self.Params['Serial'] )
- X509Cert.set_not_before ( int( time.time() - self.Params['NotBefore'] )) # 1 year in the past
- X509Cert.set_not_after ( int( time.time() + self.Params['NotAfter'] )) # 5 years in the future
- Issuer = self.ObjMap['CA']['X509Cert'].get_issuer ()
- X509Cert.set_issuer_name ( Issuer )
- X509Name_Subject = self.CurrentObj['X509Req'].get_subject ()
- X509Cert.set_subject_name ( X509Name_Subject )
- PKey = self.CurrentObj['X509Req'].get_pubkey ()
- EvpPKey = M2Crypto.EVP.PKey( PKey )
- X509Cert.set_pubkey ( EvpPKey )
- if SignEvpPKey:
- X509Cert.sign ( SignEvpPKey, self.Params['Digest'] )
- else:
- X509Cert.sign ( self.CurrentObj['EvpPKey'], self.Params['Digest'] )
- self.CurrentObj['X509Cert'] = X509Cert
- if self.VerifyCert ( SignEvpPKey ):
- return True
- else:
- return False
-
-
-
-
- #--------------------------------
- # CertHandler Verifying
- #--------------------------------
- def ExtractPublicKeyFromCert ( self ):
- self.CurrentObj['EvpPubKey'] = self.CurrentObj['X509Cert'].get_pubkey ()
-
- def VerifyCert ( self, EvpPKey ):
- if dir(EvpPKey).count('_ptr'):
- Result = self.CurrentObj['X509Cert'].verify ( EvpPKey._ptr() )
- else:
- Result = self.CurrentObj['X509Cert'].verify ( EvpPKey )
- if Result:
- return True
- return False
-
-
-
- #--------------------------------
- # CertHandler DumpOut
- #--------------------------------
- def DumpOutInternalPemRepr( self, ObjName='unknown', File='PyReprPem.txt' ):
- if File:
- open( File, 'w').write("\t\t\t\t'%s' : { " % ( ObjName ))
- else:
- sys.stdout.write("\t\t\t\t'%s' : { " % ( ObjName ))
- self.ShowX509CertSubject ( File )
- self.RsaPKey2PemRepr ( File, Cipher=None ) # unprotectd pkey representation
- self.X509Cert2PemRepr ( File )
- if File:
- open( File, 'a').write("\t\t\t\t\t }\n")
- else:
- sys.stdout.write("\t\t\t\t\t }\n")
-
- def ShowX509CertIssuer ( self, File=None ):
- IssuerName = self.CurrentObj['X509Cert'].get_issuer ()
- print IssuerName.print_ex ()
-
- def ShowX509CertSubject ( self, File=None ):
- Subject = self.CurrentObj['X509Cert'].get_subject ()
- SubjectTxt = Subject.print_ex ()
- SubjectTxtList = re.split('[\n\r]', SubjectTxt )
- SubjectMap = {}
- for Entry in SubjectTxtList:
- ( Key, Value ) = re.split('=', Entry)
- if self.ObjNames.has_key( Key ):
- SubjectMap[ self.ObjNames[Key] ] = Value
- else:
- SubjectMap[ Key ] = Value
- if File:
- open( File, 'a').write("'Subject' : %s,\n" % ( repr( SubjectMap ) ))
- else:
- sys.stdout.write("Subject: %s\n" % ( repr( SubjectMap ) ))
-
- def RsaPKey2PemRepr ( self, File=None, Cipher=None ):
- """
- converting pkey to PEM representation
- Cipher if set to None, the pkey will be unprotected!!!!! possible other value: 'des_ede3_cbc'
- """
- PemRsaPKey = self.CurrentObj['RsaPKey'].repr_key_pem ( cipher=Cipher )
- PemRsaPKeyList = re.split('[\n\r]', PemRsaPKey)
- if File:
- open( File, 'a').write("\t\t\t\t\t\t\t\t'RsaPKey' : %s,\n" % ( repr(PemRsaPKeyList[1:-2]) ))
- else:
- sys.stdout.write("\t\t\t\t\t\t\t\t'RsaPKey' : %s,\n" % ( repr(PemRsaPKeyList[1:-2]) ))
-
- def X509Cert2PemRepr ( self, File=None ):
- PemCert = self.CurrentObj['X509Cert'].repr_cert_pem ()
- #print PemCert
- PemCertList = re.split('[\n\r]', PemCert)
- if File:
- open( File, 'a').write("\t\t\t\t\t\t\t\t'X509Cert' : %s\n" % ( repr(PemCertList[1:-2]) ))
- else:
- sys.stdout.write("\t\t\t\t\t\t\t\t'X509Cert' : %s\n" % ( repr(PemCertList[1:-2]) ))
-
-
-
- #--------------------------------
- # CertHandler encryption / decryption
- #--------------------------------
- def CreateNonce ( self ):
- """
- creating some randomised data
- return new Nonce string
- """
- random.seed ()
- RawNonce = "%s_%f_%f" % ( os.getpid(), time.time(), random.random() )
- sha1=M2Crypto.EVP.MessageDigest('sha1')
- sha1.update( RawNonce )
- NonceDecrypted = sha1.digest()
- return NonceDecrypted
-
- def NonceEncryptPrivate ( self, NonceDecrypted, RsaPKey=None ):
- """
- creating private encrypted string from NonceDecrypted
- """
- padding = M2Crypto.RSA.pkcs1_padding
- if not RsaPKey:
- UsedRsaPKey = self.ServerObj['RsaPKey']
- else:
- UsedRsaPKey = RsaPKey
- NoncePrivEncrypted = UsedRsaPKey.private_encrypt ( NonceDecrypted, padding )
- return NoncePrivEncrypted
-
- def NonceEncryptPublic ( self, NonceDecrypted, RsaPubKey=None ):
- """
- creating public encrypted string from NonceDecrypted
- """
- padding = M2Crypto.RSA.pkcs1_padding
- if not RsaPubKey:
- UsedRsaPubKey = self.ServerObj['RsaPubKey']
- else:
- UsedRsaPubKey = RsaPubKey
- NoncePubEncrypted = UsedRsaPubKey.public_encrypt ( NonceDecrypted, padding )
- return NoncePubEncrypted
-
- def NonceDecryptPublic ( self, NoncePrivEncrypted, RsaPubKey=None ):
- """
- creating decrypted string from NoncePrivEncrypted
- """
- padding = M2Crypto.RSA.pkcs1_padding
- if not RsaPubKey:
- UsedRsaPubKey = self.ServerObj['RsaPubKey']
- else:
- UsedRsaPubKey = RsaPubKey
- try:
- NonceDecrypted = UsedRsaPubKey.public_decrypt ( NoncePrivEncrypted, padding )
- except:
- raise AuthError('decrypting of public key failed - abort!')
- return NonceDecrypted
-
- def NonceDecryptPrivate ( self, NoncePubEncrypted, RsaPKey=None ):
- padding = M2Crypto.RSA.pkcs1_padding
- if not RsaPKey:
- UsedRsaPKey = self.ServerObj['RsaPKey']
- else:
- UsedRsaPKey = RsaPKey
- NonceDecrypted = UsedRsaPKey.private_decrypt ( NoncePubEncrypted, padding )
- return NonceDecrypted
-
- def NonceVerify ( self, DecryptedNonce=None ):
- if self.CurrentObj['Nonce']['Decrypted'] == DecryptNonce:
- return True
- return False
-
- #--------------------------------
- # CertHandler authentication request
- #--------------------------------
- def ClientInit ( self, ObjName=None ):
- """
- generating AuthString
- Nonce messagedigest 'sha1', encrypted with own instance private key
- Cert own instance X509 cert, PEM encoded
- any linefeed charaters stripped out of the base64 code
- return generated Nonce and AuthString
- """
- if ObjName:
- if self.PemMap.has_key( ObjName ):
- UsedObjName = ObjName
- else:
- UsedObjName = self.ServerName
- else:
- UsedObjName = self.ServerName
-
- NonceDecrypted = self.CreateNonce ()
- NoncePrivEncrypted = re.sub('\012', '', base64.encodestring( self.NonceEncryptPrivate ( NonceDecrypted, RsaPKey=self.ServerObj['RsaPKey'] )) )
- PemCert = re.sub('\012', '', base64.encodestring( self.KeyEnv['X509Cert'][0] + '\n' + string.join( self.PemMap[UsedObjName]['X509Cert'], '\n' ) + '\n' + self.KeyEnv['X509Cert'][1] + '\n' ))
- InitString = re.sub('\012', '', base64.encodestring('%s:%s' % ( NoncePrivEncrypted, PemCert )))
- return ( NonceDecrypted, InitString )
-
-
- def ClientInitVerify ( self, InitString ):
- """
- return decrypted Nonce from AuthString and ObjName from AuthString X509 Cert
- """
- try:
- PemBaseString = base64.decodestring( InitString )
- except base64.binascii.Error, msg:
- raise base64.binascii.Error( msg )
- try:
- ( Base64Nonce, Base64Cert ) = re.split(':', PemBaseString )
- except:
- raise AuthError( 'cannot split PemBaseString into parts - abort!' )
- try:
- NoncePrivEncrypted = base64.decodestring( Base64Nonce )
- except base64.binascii.Error, msg:
- raise base64.binascii.Error( msg )
- try:
- PemCert = base64.decodestring( Base64Cert )
- except base64.binascii.Error, msg:
- raise base64.binascii.Error( msg )
- try:
- X509Cert = M2Crypto.X509.load_cert_string( PemCert )
- except:
- raise AuthError( 'cannot extract X509 cert from PEM representation - abort!' )
- EvpPKey = self.ObjMap['CA']['EvpPKey']
- if dir(EvpPKey).count('_ptr'):
- Result = X509Cert.verify ( EvpPKey._ptr() )
- else:
- Result = X509Cert.verify ( EvpPKey )
- if Result != 1:
- raise AuthError( 'verification of X509 cert with Certification Authority "CA" failed with code %d - abort!' % ( Result ))
- ClientObjName = self.ObjNameFromPemCert( PemCert=PemCert )
- try:
- NonceDecrypted = self.NonceDecryptPublic( NoncePrivEncrypted, RsaPubKey=self.CurrentObj['RsaPubKey'] )
- except:
- raise AuthError( 'wrong public key for encoding nonce - abort!' )
-
- return ( NonceDecrypted, ClientObjName )
-
-
-
-
- def ServerInit ( self, ClientObjName, ClientNonce ):
- """
- NonceServer new Nonce from server encrypted with client publickey and base64 encoded
- NonceBounce the authrequest nonce encrypted with server privatekey and base64 encoded
- PemServerCert server X509 certification PEM encoded and base64 encoded
- """
- if not self.ObjMap.has_key( ClientObjName ):
- if not self.PemMap.has_key( ClientObjName ):
- raise AuthError( 'cannot find ClientObjName - abort!' )
- else:
- self.ObjFromContainer( ObjName=ClientObjName )
- else:
- self.CurrentObj = self.ObjMap[ClientObjName]
-
- NonceDecrypted = self.CreateNonce ()
- NonceServer = re.sub('\012', '', base64.encodestring( self.NonceEncryptPublic ( NonceDecrypted, RsaPubKey=self.CurrentObj['RsaPubKey'] )) )
- NonceBounce = re.sub('\012', '', base64.encodestring( self.NonceEncryptPublic ( ClientNonce, RsaPubKey=self.CurrentObj['RsaPubKey'] )) )
- PemServerCert = re.sub('\012', '', base64.encodestring( self.KeyEnv['X509Cert'][0] + '\n' + string.join( self.PemMap[self.ServerName]['X509Cert'], '\n' ) + '\n' + self.KeyEnv['X509Cert'][1] + '\n' ) )
-
- InitString = re.sub('\012', '', base64.encodestring('%s:%s:%s' % ( NonceServer, NonceBounce, PemServerCert )) )
- return ( NonceDecrypted, InitString )
-
-
- def ServerInitVerify ( self, InitString, ObjName=None ):
- NonceDecrypted = ''
- ObjName = ''
- try:
- PemBaseString = base64.decodestring( InitString )
- except:
- return False
-
- ( NonceServer, NonceBounce, ServerCert ) = re.split(':', PemBaseString )
- NoncePubServer = base64.decodestring( NonceServer ) # NonceServer
- NoncePubBounce = base64.decodestring( NonceBounce ) # NonceBounce
- PemServerCert = base64.decodestring( ServerCert ) # PemServerCert
-
- try:
- X509Cert = M2Crypto.X509.load_cert_string( PemServerCert )
- except:
- return False
-
- # verify X509 cert
- EvpPKey = self.ObjMap['CA']['EvpPKey']
- if dir(EvpPKey).count('_ptr'):
- Result = X509Cert.verify ( EvpPKey._ptr() )
- else:
- Result = X509Cert.verify ( EvpPKey )
- if not Result:
- return False
-
- # verify Nonce from Server encrypted with my own publickey
- try:
- NonceDecrypted = self.NonceDecryptPrivate( NoncePubServer, RsaPKey=self.ServerObj['RsaPKey'] )
- except:
- return False
-
- ServerObjName = self.ObjNameFromPemCert( PemCert=PemServerCert )
-
- # verify Nonce bounced from Server encrypted with server privatekey
- try:
- NonceBounceDecrypted = self.NonceDecryptPrivate( NoncePubBounce, RsaPKey=self.CurrentObj['RsaPKey'] )
- except:
- return False
-
- return ( NonceDecrypted, NonceBounceDecrypted, ServerObjName )
-
-
-
- def ReplyInit ( self, ReplyObjName, ReplyBounce ):
- NonceDecrypted = self.CreateNonce ()
- NoncePubInit = re.sub('\012', '', base64.encodestring( self.NonceEncryptPublic ( NonceDecrypted, RsaPubKey=self.ObjMap[ ReplyObjName ]['RsaPubKey'] )) )
- NoncePubBounce = re.sub('\012', '', base64.encodestring( self.NonceEncryptPublic ( ReplyBounce, RsaPubKey=self.ObjMap[ ReplyObjName ]['RsaPubKey'] )) )
- ReplyString = re.sub('\012', '', base64.encodestring('%s:%s' % ( NoncePubInit, NoncePubBounce )) )
- return ( NonceDecrypted, ReplyString )
-
-
- def ReplyVerify ( self, ReplyString ):
- try:
- PemBaseString = base64.decodestring( ReplyString )
- except base64.binascii.Error, msg:
- raise base64.binascii.Error( msg )
- ( NoncePubInit, NoncePubBounce ) = re.split(':', PemBaseString )
-
- try:
- NoncePubInit = base64.decodestring( NoncePubInit ) # new Nonce from Remote, encrypted with own publickey
- except base64.binascii.Error, msg:
- raise base64.binascii.Error( msg )
- try:
- NoncePubBounce = base64.decodestring( NoncePubBounce ) # bounced Nonce from Remote, encrypted with Remote privatekey
- except base64.binascii.Error, msg:
- raise base64.binascii.Error( msg )
-
- # verify Nonce from Remote encrypted with my own publickey
- try:
- NonceRemote = self.NonceDecryptPrivate( NoncePubInit, RsaPKey=self.ServerObj['RsaPKey'] )
- except:
- raise AuthError( 'cannot encode nonce with own private key - abort!' )
-
- # verify Nonce bounced from Remote encrypted with Remote privatekey
- try:
- NonceBounced = self.NonceDecryptPrivate( NoncePubBounce, RsaPKey=self.ServerObj['RsaPKey'] )
- except:
- raise AuthError( 'wrong public key for encoding nonce - abort!' )
-
- return ( NonceRemote, NonceBounced )
-
-
-
-
- #-------------------------------------------------------------------------------------------
- # TEST
- #-------------------------------------------------------------------------------------------
- def CreateCAForContainer ( self ):
- self.CreateCert ()
-
- def CreateForContainer ( self, ObjName ):
- """
- create new pkey pair and x509 cert for specified objname
- result will be written in file "PyReprPem.txt"
- """
- self.ObjFromContainer ( ObjName='AuthInstance' )
- self.CreateObjCert ( ObjName=ObjName )
-
-
- def Test ( self ):
- #self.CreateCert ()
- #self.ExtractPublicKeyFromCert ()
- #self.VerifyCert ()
-
- ( ClientInitNonce, ClientInitString ) = self.ClientInit ()
- ( ClientSendNonce, ClientObjName ) = self.ClientInitVerify ( InitString=ClientInitString )
- ( ServerInitNonce, ServerInitString ) = self.ServerInit ( ClientObjName=ClientObjName, ClientNonce=ClientSendNonce )
- ( ServerSendNonce, ClientBounceNonce, ServerObjName ) = self.ServerInitVerify ( InitString=ServerInitString )
- if ClientInitNonce == ClientBounceNonce :
- print '100 Test Nonce bounced True'
- else:
- print '100 Test Nonce bounced False - abort!'
-
- ( ReplyInitNonce, ReplyInitString ) = self.ReplyInit ( ReplyObjName=ClientObjName, ReplyBounce=ServerSendNonce )
- ( ReplySendNonce, NonceBounced ) = self.ReplyVerify ( ReplyString=ReplyInitString )
- if ServerInitNonce == NonceBounced :
- print '100 Test Nonce bounced True'
- else:
- print '100 Test Nonce bounced False - abort!'
-
- ( Reply2InitNonce, Reply2InitString ) = self.ReplyInit ( ReplyObjName=ClientObjName, ReplyBounce=ServerSendNonce )
- ( Reply2SendNonce, Nonce2Bounced ) = self.ReplyVerify ( ReplyString=Reply2InitString )
- if ServerInitNonce == Nonce2Bounced :
- print '100 Test Nonce bounced True'
- else:
- print '100 Test Nonce bounced False - abort!'
-
- #self.NonceEncryptPrivate ()
- #self.NonceDecryptPublic ()
- #self.NonceVerify ()
-
-
-#-----------------------------------------------------------------------------------------------
-# MAIN
-#
-# x509auth.py --ca
-# will create a file "PyReprPem.txt" in the current directory
-# append the contents of the file to the CertContainer in this script
-#
-# x509auth.py --cert <ObjName>
-# creates a file "PyReprPem.txt" in the current directory
-# append the contents of the file to the CertContainer in this script
-#
-# x509auth.py --test
-# running authentification tests with bounced nonce
-#
-#-----------------------------------------------------------------------------------------------
-if __name__ == '__main__':
- run = CertHandler ()
-
- if len( sys.argv ) > 1:
- if sys.argv[1] == '--test':
- run.Test ()
- elif sys.argv[1] == '--ca':
- run.CreateCert()
- elif sys.argv[1] == '--cert':
- run.CreateForContainer( sys.argv[2] )
-
- sys.exit( 0 )
-
diff --git a/dev-requirements.txt b/dev-requirements.txt
new file mode 100644
index 0000000..6c4932c
--- /dev/null
+++ b/dev-requirements.txt
@@ -0,0 +1,2 @@
+wheel
+twine
diff --git a/doc/M2Crypto.SSL.rst b/doc/M2Crypto.SSL.rst
new file mode 100644
index 0000000..233c1eb
--- /dev/null
+++ b/doc/M2Crypto.SSL.rst
@@ -0,0 +1,91 @@
+SSL Package
+===========
+
+:mod:`SSL` Package
+------------------
+
+.. automodule:: M2Crypto.SSL
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`Checker` Module
+---------------------
+
+.. automodule:: M2Crypto.SSL.Checker
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`Cipher` Module
+--------------------
+
+.. automodule:: M2Crypto.SSL.Cipher
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`Connection` Module
+------------------------
+
+.. automodule:: M2Crypto.SSL.Connection
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`Context` Module
+---------------------
+
+.. automodule:: M2Crypto.SSL.Context
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`SSLServer` Module
+-----------------------
+
+.. automodule:: M2Crypto.SSL.SSLServer
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`Session` Module
+---------------------
+
+.. automodule:: M2Crypto.SSL.Session
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`TwistedProtocolWrapper` Module
+------------------------------------
+
+.. automodule:: M2Crypto.SSL.TwistedProtocolWrapper
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`cb` Module
+----------------
+
+.. automodule:: M2Crypto.SSL.cb
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`ssl_dispatcher` Module
+----------------------------
+
+.. automodule:: M2Crypto.SSL.ssl_dispatcher
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`timeout` Module
+---------------------
+
+.. automodule:: M2Crypto.SSL.timeout
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
diff --git a/doc/M2Crypto.rst b/doc/M2Crypto.rst
new file mode 100644
index 0000000..dc6c706
--- /dev/null
+++ b/doc/M2Crypto.rst
@@ -0,0 +1,218 @@
+M2Crypto Package
+================
+
+:mod:`M2Crypto` Package
+-----------------------
+
+.. automodule:: M2Crypto.__init__
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`ASN1` Module
+------------------
+
+.. automodule:: M2Crypto.ASN1
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`AuthCookie` Module
+------------------------
+
+.. automodule:: M2Crypto.AuthCookie
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`BIO` Module
+-----------------
+
+.. automodule:: M2Crypto.BIO
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`BN` Module
+----------------
+
+.. automodule:: M2Crypto.BN
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`DH` Module
+----------------
+
+.. automodule:: M2Crypto.DH
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`DSA` Module
+-----------------
+
+.. automodule:: M2Crypto.DSA
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`EC` Module
+----------------
+
+.. automodule:: M2Crypto.EC
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`EVP` Module
+-----------------
+
+.. automodule:: M2Crypto.EVP
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`Engine` Module
+--------------------
+
+.. automodule:: M2Crypto.Engine
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`Err` Module
+-----------------
+
+.. automodule:: M2Crypto.Err
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`RC4` Module
+-----------------
+
+.. automodule:: M2Crypto.RC4
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`RSA` Module
+-----------------
+
+.. automodule:: M2Crypto.RSA
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`Rand` Module
+------------------
+
+.. automodule:: M2Crypto.Rand
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`SMIME` Module
+-------------------
+
+.. automodule:: M2Crypto.SMIME
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`X509` Module
+------------------
+
+.. automodule:: M2Crypto.X509
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`callback` Module
+----------------------
+
+.. automodule:: M2Crypto.callback
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`ftpslib` Module
+---------------------
+
+.. automodule:: M2Crypto.ftpslib
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`httpslib` Module
+----------------------
+
+.. automodule:: M2Crypto.httpslib
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`m2` Module
+----------------
+
+.. automodule:: M2Crypto.m2
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`m2crypto` Module
+----------------------
+
+.. automodule:: M2Crypto.m2crypto
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`m2urllib` Module
+----------------------
+
+.. automodule:: M2Crypto.m2urllib
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`m2urllib2` Module
+-----------------------
+
+.. automodule:: M2Crypto.m2urllib2
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`m2xmlrpclib` Module
+-------------------------
+
+.. automodule:: M2Crypto.m2xmlrpclib
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`threading` Module
+-----------------------
+
+.. automodule:: M2Crypto.threading
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`util` Module
+------------------
+
+.. automodule:: M2Crypto.util
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+Subpackages
+-----------
+
+.. toctree::
+
+ M2Crypto.SSL
+
diff --git a/doc/Makefile b/doc/Makefile
new file mode 100644
index 0000000..cbe8480
--- /dev/null
+++ b/doc/Makefile
@@ -0,0 +1,153 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS =
+SPHINXBUILD = sphinx-build
+PAPER =
+BUILDDIR = .
+
+# Internal variables.
+PAPEROPT_a4 = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+# the i18n builder cannot share the environment and doctrees with the others
+I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
+
+help:
+ @echo "Please use \`make <target>' where <target> is one of"
+ @echo " html to make standalone HTML files"
+ @echo " dirhtml to make HTML files named index.html in directories"
+ @echo " singlehtml to make a single large HTML file"
+ @echo " pickle to make pickle files"
+ @echo " json to make JSON files"
+ @echo " htmlhelp to make HTML files and a HTML help project"
+ @echo " qthelp to make HTML files and a qthelp project"
+ @echo " devhelp to make HTML files and a Devhelp project"
+ @echo " epub to make an epub"
+ @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+ @echo " latexpdf to make LaTeX files and run them through pdflatex"
+ @echo " text to make text files"
+ @echo " man to make manual pages"
+ @echo " texinfo to make Texinfo files"
+ @echo " info to make Texinfo files and run them through makeinfo"
+ @echo " gettext to make PO message catalogs"
+ @echo " changes to make an overview of all changed/added/deprecated items"
+ @echo " linkcheck to check all external links for integrity"
+ @echo " doctest to run all doctests embedded in the documentation (if enabled)"
+
+clean:
+ -rm -rf $(BUILDDIR)/{doctrees,html}
+
+html:
+ $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dirhtml:
+ $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+singlehtml:
+ $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
+ @echo
+ @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
+
+pickle:
+ $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+ @echo
+ @echo "Build finished; now you can process the pickle files."
+
+json:
+ $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+ @echo
+ @echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+ $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+ @echo
+ @echo "Build finished; now you can run HTML Help Workshop with the" \
+ ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+ $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+ @echo
+ @echo "Build finished; now you can run "qcollectiongenerator" with the" \
+ ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+ @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/M2Crypto.qhcp"
+ @echo "To view the help file:"
+ @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/M2Crypto.qhc"
+
+devhelp:
+ $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
+ @echo
+ @echo "Build finished."
+ @echo "To view the help file:"
+ @echo "# mkdir -p $$HOME/.local/share/devhelp/M2Crypto"
+ @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/M2Crypto"
+ @echo "# devhelp"
+
+epub:
+ $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
+ @echo
+ @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
+
+latex:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo
+ @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+ @echo "Run \`make' in that directory to run these through (pdf)latex" \
+ "(use \`make latexpdf' here to do that automatically)."
+
+latexpdf:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo "Running LaTeX files through pdflatex..."
+ $(MAKE) -C $(BUILDDIR)/latex all-pdf
+ @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+text:
+ $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
+ @echo
+ @echo "Build finished. The text files are in $(BUILDDIR)/text."
+
+man:
+ $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+ @echo
+ @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
+
+texinfo:
+ $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+ @echo
+ @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
+ @echo "Run \`make' in that directory to run these through makeinfo" \
+ "(use \`make info' here to do that automatically)."
+
+info:
+ $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+ @echo "Running Texinfo files through makeinfo..."
+ make -C $(BUILDDIR)/texinfo info
+ @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
+
+gettext:
+ $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
+ @echo
+ @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
+
+changes:
+ $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+ @echo
+ @echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+ $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+ @echo
+ @echo "Link check complete; look for any errors in the above output " \
+ "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+ $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+ @echo "Testing of doctests in the sources finished, look at the " \
+ "results in $(BUILDDIR)/doctest/output.txt."
diff --git a/doc/ZServerSSL-HOWTO.html b/doc/ZServerSSL-HOWTO.html
deleted file mode 100644
index 78c15a9..0000000
--- a/doc/ZServerSSL-HOWTO.html
+++ /dev/null
@@ -1,271 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head>
-<base href="http://localhost:9080/home/m2/zserverssl-011-howto/" />
-
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta name="generator" content="Docutils 0.2.8: http://docutils.sourceforge.net/" />
-<title>ZServerSSL HOWTO</title>
-<meta name="author" content="Ng Pheng Siong" />
-<meta name="date" content="2003-06-22" />
-<link rel="stylesheet" href="default.css" type="text/css" />
-</head>
-<body>
-<div class="document" id="zserverssl-howto">
-<h1 class="title">ZServerSSL HOWTO</h1>
-<table class="docinfo" frame="void" rules="none">
-<col class="docinfo-name" />
-<col class="docinfo-content" />
-<tbody valign="top">
-<tr><th class="docinfo-name">Author:</th>
-<td>Ng Pheng Siong</td></tr>
-<tr class="field"><th class="docinfo-name">Id:</th><td class="field-body">ZServerSSL-HOWTO,v 1.1 2003/06/22 17:40:13 ngps Exp</td>
-</tr>
-<tr><th class="docinfo-name">Date:</th>
-<td>2003-06-22</td></tr>
-<tr class="field"><th class="docinfo-name">Web-Site:</th><td class="field-body"><a class="reference" href="http://chandlerproject.org/Projects/MeTooCrypto">http://chandlerproject.org/Projects/MeTooCrypto</a></td>
-</tr>
-</tbody>
-</table>
-<div class="contents topic" id="contents">
-<p class="topic-title"><a name="contents">Contents</a></p>
-<ul class="simple">
-<li><a class="reference" href="#introduction" id="id2" name="id2">Introduction</a></li>
-<li><a class="reference" href="#preparation" id="id3" name="id3">Preparation</a></li>
-<li><a class="reference" href="#installation" id="id4" name="id4">Installation</a></li>
-<li><a class="reference" href="#testing" id="id5" name="id5">Testing</a><ul>
-<li><a class="reference" href="#https" id="id6" name="id6">HTTPS</a></li>
-<li><a class="reference" href="#webdav-over-https" id="id7" name="id7">WebDAV-over-HTTPS</a></li>
-<li><a class="reference" href="#webdav-source-over-https" id="id8" name="id8">WebDAV-Source-over-HTTPS</a></li>
-<li><a class="reference" href="#python-with-m2crypto" id="id9" name="id9">Python with M2Crypto</a><ul>
-<li><a class="reference" href="#id1" id="id10" name="id10">HTTPS</a></li>
-<li><a class="reference" href="#xmlrpc-over-https" id="id11" name="id11">XMLRPC-over-HTTPS</a></li>
-</ul>
-</li>
-</ul>
-</li>
-<li><a class="reference" href="#conclusion" id="id12" name="id12">Conclusion</a></li>
-</ul>
-</div>
-<div class="section" id="introduction">
-<h1><a class="toc-backref" href="#id2" name="introduction">Introduction</a></h1>
-<p>ZServerSSL adds to Zope's ZServer the following:</p>
-<ul class="simple">
-<li>HTTPS server</li>
-<li>WebDAV-source-over-HTTPS server</li>
-</ul>
-<p>With the HTTPS server, ZServerSSL also provides WebDAV-over-HTTPS
-and XMLRPC-over-HTTPS access to Zope.</p>
-<p>These instructions apply to both Un*x and Windows installations of
-Zope 2.6.1. To avoid cluttering the presentation, Windows pathnames
-are shown in Un*x fashion.</p>
-</div>
-<div class="section" id="preparation">
-<h1><a class="toc-backref" href="#id3" name="preparation">Preparation</a></h1>
-<ol class="arabic simple">
-<li>Download M2Crypto 0.11, contained in the file <tt class="literal"><span class="pre">m2crypto-0.11.zip</span></tt>.</li>
-<li>Unpack <tt class="literal"><span class="pre">m2crypto-0.11.zip</span></tt>. This will create a directory
-<tt class="literal"><span class="pre">m2crypto-0.11</span></tt>. Henceforth, we refer to this directory as <tt class="literal"><span class="pre">$M2</span></tt>.</li>
-<li>Install M2Crypto per the instructions in <tt class="literal"><span class="pre">$M2/INSTALL</span></tt>.</li>
-</ol>
-<p>The ZServerSSL distribution is in <tt class="literal"><span class="pre">$M2/demo/Zope</span></tt>. We shall refer to
-this directory as <tt class="literal"><span class="pre">$ZSSL</span></tt>.</p>
-</div>
-<div class="section" id="installation">
-<h1><a class="toc-backref" href="#id4" name="installation">Installation</a></h1>
-<p>Below, we refer to your Zope top-level directory as <tt class="literal"><span class="pre">$ZOPE</span></tt>.</p>
-<ol class="arabic">
-<li><p class="first">Copy <tt class="literal"><span class="pre">$ZSSL/z2s.py</span></tt> into <tt class="literal"><span class="pre">$ZOPE</span></tt>.</p>
-</li>
-<li><p class="first">Depending on your operating system, modify <tt class="literal"><span class="pre">$ZOPE/start</span></tt> or
-<tt class="literal"><span class="pre">$ZOPE/start.bat</span></tt> to invoke <tt class="literal"><span class="pre">$ZOPE/z2s.py</span></tt>, instead of
-<tt class="literal"><span class="pre">$ZOPE/z2.py</span></tt>. The files <tt class="literal"><span class="pre">$ZSSL/starts</span></tt> and
-<tt class="literal"><span class="pre">$ZSSL/starts.bat</span></tt> serve as examples.</p>
-</li>
-<li><p class="first">Copy <tt class="literal"><span class="pre">$ZSSL/dh1024.pem</span></tt> into <tt class="literal"><span class="pre">$ZOPE</span></tt>. This file contains
-Diffie-Hellman parameters for use by the SSL protocol.</p>
-</li>
-<li><p class="first">Copy <tt class="literal"><span class="pre">$ZSSL/randpool.dat</span></tt> into <tt class="literal"><span class="pre">$ZOPE</span></tt>. This file contains seed
-material for the OpenSSL PRNG. Alternatively, create
-<tt class="literal"><span class="pre">$ZOPE/randpool.dat</span></tt> thusly:</p>
-<pre class="literal-block">
-$ dd if=/dev/urandom of=randpool.dat bs=1024 count=1
-</pre>
-</li>
-<li><p class="first">Copy <tt class="literal"><span class="pre">$ZSSL/ca.pem</span></tt> to <tt class="literal"><span class="pre">$ZOPE</span></tt>. This file contains an example
-Certification Authority (CA) certificate. For information on
-operating your own CA, see
-<a class="reference" href="http://svn.osafoundation.org/m2crypto/trunk/doc/howto.ca.html">howto.ca.html</a> or one of numerous
-similar documents available on the web.</p>
-</li>
-<li><p class="first">Copy <tt class="literal"><span class="pre">$ZSSL/server.pem</span></tt> to <tt class="literal"><span class="pre">$ZOPE</span></tt>. This file contains an RSA
-key pair and its X.509v3 certificate issued by the above CA. You
-may also create your own key/certificate bundle.</p>
-</li>
-<li><p class="first">Copy <tt class="literal"><span class="pre">$ZSSL/ZServer/HTTPS_Server.py</span></tt> to <tt class="literal"><span class="pre">$ZOPE/ZServer</span></tt>.</p>
-</li>
-<li><p class="first">Copy <tt class="literal"><span class="pre">$ZSSL/ZServer/__init__.py</span></tt> to <tt class="literal"><span class="pre">$ZOPE/ZServer</span></tt>. This
-overwrites the existing <tt class="literal"><span class="pre">$ZOPE/ZServer/__init__.py</span></tt>. Alternatively,
-apply the following patch to <tt class="literal"><span class="pre">$ZOPE/ZServer/__init__.py</span></tt>:</p>
-<pre class="literal-block">
---- __init__.py.org Sat Jun 21 23:20:41 2003
-+++ __init__.py Tue Jan 7 23:30:53 2003
-&#64;&#64; -84,6 +84,7 &#64;&#64;
- import asyncore
- from medusa import resolver, logger
- from HTTPServer import zhttp_server, zhttp_handler
-+from HTTPS_Server import zhttps_server, zhttps_handler
- from PCGIServer import PCGIServer
- from FCGIServer import FCGIServer
- from FTPServer import FTPServer
-</pre>
-</li>
-<li><p class="first">Copy <tt class="literal"><span class="pre">$ZSSL/ZServer/medusa/https_server.py</span></tt> to
-<tt class="literal"><span class="pre">$ZOPE/ZServer/medusa</span></tt>.</p>
-</li>
-<li><p class="first">Stop Zope, if it is running.</p>
-</li>
-<li><p class="first">Start Zope with ZServerSSL thusly:</p>
-<pre class="literal-block">
-./starts -X -f 9021 -w 9080 -W 9081 -y 9443 -Y 9444
-</pre>
-<p>This starts the following:</p>
-<ul class="simple">
-<li>an FTP server on port 9021</li>
-<li>a HTTP server on port 9080</li>
-<li>a WebDAV-source server on port 9081</li>
-<li>a HTTPS server on port 9443</li>
-<li>a WebDAV-source-over-HTTPS server on port 9444</li>
-</ul>
-</li>
-</ol>
-</div>
-<div class="section" id="testing">
-<h1><a class="toc-backref" href="#id5" name="testing">Testing</a></h1>
-<p>Below, we assume your Zope server is running on <tt class="literal"><span class="pre">localhost</span></tt>.</p>
-<div class="section" id="https">
-<h2><a class="toc-backref" href="#id6" name="https">HTTPS</a></h2>
-<p>This testing is done with Mozilla 1.1 on FreeBSD.</p>
-<ol class="arabic simple">
-<li>With a browser, connect to <a class="reference" href="https://localhost:9443/">https://localhost:9443/</a>. Browse
-around. Check out your browser's HTTPS informational screens.</li>
-<li>Connect to <a class="reference" href="https://localhost:9443/manage">https://localhost:9443/manage</a>. Verify that you can
-access Zope's management functionality.</li>
-</ol>
-</div>
-<div class="section" id="webdav-over-https">
-<h2><a class="toc-backref" href="#id7" name="webdav-over-https">WebDAV-over-HTTPS</a></h2>
-<p>This testing is done with Cadaver 0.21.0 on FreeBSD.</p>
-<pre class="literal-block">
-$ cadaver https://localhost:9443/
-WARNING: Untrusted server certificate presented:
-Issued to: M2Crypto, SG
-Issued by: M2Crypto, SG
-Do you wish to accept the certificate? (y/n) y
-dav:/&gt; ls
-Listing collection `/': succeeded.
-Coll: Channels 0 Jun 19 00:04
-Coll: Control_Panel 0 Jun 6 00:13
-Coll: Examples 0 Jun 6 00:12
-Coll: catalog 0 Jun 12 11:53
-Coll: ngps 0 Jun 16 15:34
-Coll: portal 0 Jun 21 15:21
-Coll: skunk 0 Jun 18 21:18
-Coll: temp_folder 0 Jun 22 17:57
-Coll: zope 0 Jun 20 15:27
- acl_users 0 Dec 30 1998
- browser_id_manager 0 Jun 6 00:12
- default.css 3037 Jun 21 16:38
- error_log 0 Jun 6 00:12
- index_html 313 Jun 12 13:36
- portal0 0 Jun 21 15:21
- session_data_manager 0 Jun 6 00:12
- standard_error_message 1365 Jan 21 2001
- standard_html_footer 50 Jun 12 12:30
- standard_html_header 80 Jan 21 2001
- standard_template.pt 282 Jun 6 00:12
- zsyncer 0 Jun 17 15:28
-dav:/&gt; quit
-Connection to `localhost' closed.
-$
-</pre>
-</div>
-<div class="section" id="webdav-source-over-https">
-<h2><a class="toc-backref" href="#id8" name="webdav-source-over-https">WebDAV-Source-over-HTTPS</a></h2>
-<p>This testing is done with Mozilla 1.1 on FreeBSD.</p>
-<ol class="arabic simple">
-<li>Open the Mozilla Composer window.</li>
-<li>Click &quot;File&quot;, &quot;Open Web Location&quot;. A dialog box appears.</li>
-<li>Enter <tt class="literal"><span class="pre">https://localhost:9444/index_html</span></tt> for the URL.</li>
-<li>Select &quot;Open in new Composer window.&quot;</li>
-<li>Click &quot;Open&quot;. A new Composer window will open with <tt class="literal"><span class="pre">index_html</span></tt>
-loaded.</li>
-</ol>
-</div>
-<div class="section" id="python-with-m2crypto">
-<h2><a class="toc-backref" href="#id9" name="python-with-m2crypto">Python with M2Crypto</a></h2>
-<p>This testing is done with M2Crypto 0.11 and Python 2.2.2 on FreeBSD.</p>
-<div class="section" id="id1">
-<h3><a class="toc-backref" href="#id10" name="id1">HTTPS</a></h3>
-<pre class="doctest-block">
-&gt;&gt;&gt; from M2Crypto import Rand, SSL, m2urllib
-&gt;&gt;&gt; url = m2urllib.FancyURLopener()
-&gt;&gt;&gt; url.addheader('Connection', 'close')
-&gt;&gt;&gt; u = url.open('https://127.0.0.1:9443/')
-send: 'GET / HTTP/1.1\r\nHost: 127.0.0.1:9443\r\nAccept-Encoding: identity\r\nUser-agent: Python-urllib/1.15\r\nConnection: close\r\n\r\n'
-reply: 'HTTP/1.1 200 OK\r\n'
-header: Server: ZServerSSL/0.11
-header: Date: Sun, 22 Jun 2003 13:42:34 GMT
-header: Connection: close
-header: Content-Type: text/html
-header: Etag:
-header: Content-Length: 535
-&gt;&gt;&gt; while 1:
-... data = u.read()
-... if not data: break
-... print data
-...
-</pre>
-<pre class="literal-block">
-&lt;html&gt;&lt;head&gt;
-&lt;base href=&quot;https://127.0.0.1:9443/&quot; /&gt;
-&lt;title&gt;Zope&lt;/title&gt;&lt;/head&gt;&lt;body bgcolor=&quot;#FFFFFF&quot;&gt;
-
-&lt;h1&gt;NgPS Desktop Portal&lt;/h1&gt;
-
-&amp;nbsp;&amp;nbsp;So many hacks.&lt;br&gt;
-&amp;nbsp;&amp;nbsp;So little time.&lt;br&gt;
-
-&lt;h2&gt;Link Farm&lt;/h2&gt;
-&lt;ul&gt;
-&lt;li&gt;&lt;a href=&quot;http://localhost:8080/portal&quot;&gt;Portal&lt;/a&gt;&lt;/li&gt;
-&lt;li&gt;&lt;a href=&quot;http://localhost/&quot;&gt;Local Apache Home Page&lt;/a&gt;&lt;/li&gt;
-&lt;/ul&gt;
-
-&lt;hr&gt;&lt;a href=&quot;http://www.zope.org/Credits&quot; target=&quot;_top&quot;&gt;&lt;img src=&quot;https://127.0.0.1:9443/p_/ZopeButton&quot; width=&quot;115&quot; height=&quot;50&quot; border=&quot;0&quot; alt=&quot;Powered by Zope&quot; /&gt;&lt;/a&gt;&lt;/body&gt;&lt;/html&gt;
-</pre>
-<pre class="doctest-block">
-&gt;&gt;&gt; u.close()
-&gt;&gt;&gt;
-</pre>
-</div>
-<div class="section" id="xmlrpc-over-https">
-<h3><a class="toc-backref" href="#id11" name="xmlrpc-over-https">XMLRPC-over-HTTPS</a></h3>
-<pre class="doctest-block">
-&gt;&gt;&gt; from M2Crypto.m2xmlrpclib import Server, SSL_Transport
-&gt;&gt;&gt; zs = Server('https://127.0.0.1:9443/', SSL_Transport())
-&gt;&gt;&gt; print zs.propertyMap()
-[{'type': 'string', 'id': 'title', 'mode': 'w'}]
-&gt;&gt;&gt;
-</pre>
-</div>
-</div>
-</div>
-<div class="section" id="conclusion">
-<h1><a class="toc-backref" href="#id12" name="conclusion">Conclusion</a></h1>
-<p>Well, it works! ;-)</p>
-</div>
-</div>
-</body>
-</html>
diff --git a/doc/ZServerSSL-HOWTO.rst b/doc/ZServerSSL-HOWTO.rst
new file mode 100644
index 0000000..91ef5af
--- /dev/null
+++ b/doc/ZServerSSL-HOWTO.rst
@@ -0,0 +1,239 @@
+:orphan:
+
+.. _zserverssl-howto:
+
+ZServerSSL-HOWTO
+################
+
+:author: Pheng Siong Ng <ngps@post1.com>
+:copyright: © 2000, 2001 by Ng Pheng Siong.
+:date: 2003-06-22
+
+.. contents::
+ :backlinks: entry
+
+.. sectnum::
+ :suffix: .
+
+Introduction
+============
+
+ZServerSSL adds to Zope's ZServer the following:
+
+- HTTPS server
+- WebDAV-source-over-HTTPS server
+
+With the HTTPS server, ZServerSSL also provides WebDAV-over-HTTPS and
+XMLRPC-over-HTTPS access to Zope.
+
+These instructions apply to both Un\*x and Windows installations of Zope
+2.6.1. To avoid cluttering the presentation, Windows pathnames are shown
+in Un\*x fashion.
+
+Preparation
+===========
+
+#. Download M2Crypto 0.11, contained in the file ``m2crypto-0.11.zip``.
+#. Unpack ``m2crypto-0.11.zip``. This will create a directory
+ ``m2crypto-0.11``. Henceforth, we refer to this directory as ``$M2``.
+#. Install M2Crypto per the instructions in ``$M2/INSTALL``.
+
+The ZServerSSL distribution is in ``$M2/demo/Zope``. We shall refer to
+this directory as ``$ZSSL``.
+
+Installation
+============
+
+Below, we refer to your Zope top-level directory as ``$ZOPE``.
+
+#. Copy ``$ZSSL/z2s.py`` into ``$ZOPE``.
+
+#. Depending on your operating system, modify ``$ZOPE/start`` or
+ ``$ZOPE/start.bat`` to invoke ``$ZOPE/z2s.py``, instead of
+ ``$ZOPE/z2.py``. The files ``$ZSSL/starts`` and ``$ZSSL/starts.bat``
+ serve as examples.
+
+#. Copy ``$ZSSL/dh1024.pem`` into ``$ZOPE``. This file contains
+ Diffie-Hellman parameters for use by the SSL protocol.
+
+#. Copy ``$ZSSL/randpool.dat`` into ``$ZOPE``. This file contains seed
+ material for the OpenSSL PRNG. Alternatively, create
+ ``$ZOPE/randpool.dat`` thusly::
+
+ $ dd if=/dev/urandom of=randpool.dat bs=1024 count=1
+
+#. Copy ``$ZSSL/ca.pem`` to ``$ZOPE``. This file contains an
+ example Certification Authority (CA) certificate. For
+ information on operating your own CA, see :ref:`howto-ca` or
+ one of numerous similar documents available on the web.
+
+#. Copy ``$ZSSL/server.pem`` to ``$ZOPE``. This file contains an RSA key
+ pair and its X.509v3 certificate issued by the above CA. You may also
+ create your own key/certificate bundle.
+
+#. Copy ``$ZSSL/ZServer/HTTPS_Server.py`` to ``$ZOPE/ZServer``.
+
+#. Copy ``$ZSSL/ZServer/__init__.py`` to ``$ZOPE/ZServer``. This
+ overwrites the existing ``$ZOPE/ZServer/__init__.py``. Alternatively,
+ apply the following patch to ``$ZOPE/ZServer/__init__.py``::
+
+ --- __init__.py.org Sat Jun 21 23:20:41 2003
+ +++ __init__.py Tue Jan 7 23:30:53 2003
+ @@ -84,6 +84,7 @@
+ import asyncore
+ from medusa import resolver, logger
+ from HTTPServer import zhttp_server, zhttp_handler
+ +from HTTPS_Server import zhttps_server, zhttps_handler
+ from PCGIServer import PCGIServer
+ from FCGIServer import FCGIServer
+ from FTPServer import FTPServer
+
+#. Copy ``$ZSSL/ZServer/medusa/https_server.py`` to
+ ``$ZOPE/ZServer/medusa``.
+
+#. Stop Zope, if it is running.
+
+#. Start Zope with ZServerSSL thusly::
+
+ ./starts -X -f 9021 -w 9080 -W 9081 -y 9443 -Y 9444
+
+ This starts the following:
+
+ - an FTP server on port 9021
+ - a HTTP server on port 9080
+ - a WebDAV-source server on port 9081
+ - a HTTPS server on port 9443
+ - a WebDAV-source-over-HTTPS server on port 9444
+
+Testing
+=======
+
+Below, we assume your Zope server is running on ``localhost``.
+
+HTTPS
+=====
+
+This testing is done with Mozilla 1.1 on FreeBSD.
+
+#. With a browser, connect to https://localhost:9443/. Browse around.
+ Check out your browser's HTTPS informational screens.
+#. Connect to https://localhost:9443/manage. Verify that you can access
+ Zope's management functionality.
+
+WebDAV-over-HTTPS
+=================
+
+This testing is done with Cadaver 0.21.0 on FreeBSD.::
+
+ $ cadaver https://localhost:9443/
+ WARNING: Untrusted server certificate presented:
+ Issued to: M2Crypto, SG
+ Issued by: M2Crypto, SG
+ Do you wish to accept the certificate? (y/n) y
+ dav:/> ls
+ Listing collection `/': succeeded.
+ Coll: Channels 0 Jun 19 00:04
+ Coll: Control_Panel 0 Jun 6 00:13
+ Coll: Examples 0 Jun 6 00:12
+ Coll: catalog 0 Jun 12 11:53
+ Coll: ngps 0 Jun 16 15:34
+ Coll: portal 0 Jun 21 15:21
+ Coll: skunk 0 Jun 18 21:18
+ Coll: temp_folder 0 Jun 22 17:57
+ Coll: zope 0 Jun 20 15:27
+ acl_users 0 Dec 30 1998
+ browser_id_manager 0 Jun 6 00:12
+ default.css 3037 Jun 21 16:38
+ error_log 0 Jun 6 00:12
+ index_html 313 Jun 12 13:36
+ portal0 0 Jun 21 15:21
+ session_data_manager 0 Jun 6 00:12
+ standard_error_message 1365 Jan 21 2001
+ standard_html_footer 50 Jun 12 12:30
+ standard_html_header 80 Jan 21 2001
+ standard_template.pt 282 Jun 6 00:12
+ zsyncer 0 Jun 17 15:28
+ dav:/> quit
+ Connection to `localhost' closed.
+ $
+
+
+WebDAV-Source-over-HTTPS
+========================
+
+This testing is done with Mozilla 1.1 on FreeBSD.
+
+#. Open the Mozilla Composer window.
+#. Click "File", "Open Web Location". A dialog box appears.
+#. Enter ``https://localhost:9444/index_html`` for the URL.
+#. Select "Open in new Composer window."
+#. Click "Open". A new Composer window will open with ``index_html``
+ loaded.
+
+Python with M2Crypto
+====================
+
+This testing is done with M2Crypto 0.11 and Python 2.2.2 on FreeBSD.
+
+HTTPS
+=====
+
+::
+
+ >>> from M2Crypto import Rand, SSL, m2urllib
+ >>> url = m2urllib.FancyURLopener()
+ >>> url.addheader('Connection', 'close')
+ >>> u = url.open('https://127.0.0.1:9443/')
+ send: 'GET / HTTP/1.1\r\nHost: 127.0.0.1:9443\r\nAccept-Encoding: identity\r\nUser-agent: Python-urllib/1.15\r\nConnection: close\r\n\r\n'
+ reply: 'HTTP/1.1 200 OK\r\n'
+ header: Server: ZServerSSL/0.11
+ header: Date: Sun, 22 Jun 2003 13:42:34 GMT
+ header: Connection: close
+ header: Content-Type: text/html
+ header: Etag:
+ header: Content-Length: 535
+ >>> while 1:
+ ... data = u.read()
+ ... if not data: break
+ ... print(data)
+ ...
+
+::
+
+ <html><head>
+ <base href="https://127.0.0.1:9443/" />
+ <title>Zope</title></head><body bgcolor="#FFFFFF">
+
+ <h1>NgPS Desktop Portal</h1>
+
+ &nbsp;&nbsp;So many hacks.<br>
+ &nbsp;&nbsp;So little time.<br>
+
+ <h2>Link Farm</h2>
+ <ul>
+ <li><a href="http://localhost:8080/portal">Portal</a></li>
+ <li><a href="http://localhost/">Local Apache Home Page</a></li>
+ </ul>
+
+ <hr><a href="http://www.zope.org/Credits" target="_top"><img src="https://127.0.0.1:9443/p_/ZopeButton" width="115" height="50" border="0" alt="Powered by Zope" /></a></body></html>
+
+::
+
+ >>> u.close()
+ >>>
+
+XMLRPC-over-HTTPS
+=================
+
+::
+
+ >>> from M2Crypto.m2xmlrpclib import Server, SSL_Transport
+ >>> zs = Server('https://127.0.0.1:9443/', SSL_Transport())
+ >>> print(zs.propertyMap())
+ [{'type': 'string', 'id': 'title', 'mode': 'w'}]
+ >>>
+
+Conclusion
+==========
+
+Well, it works! ;-)
diff --git a/doc/conf.py b/doc/conf.py
new file mode 100644
index 0000000..8530a00
--- /dev/null
+++ b/doc/conf.py
@@ -0,0 +1,285 @@
+# -*- coding: utf-8 -*-
+#
+# M2Crypto documentation build configuration file, created by
+# sphinx-quickstart on Thu Apr 20 11:15:12 2017.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys, os
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+sys.path.insert(0, os.path.abspath(os.path.join('..')))
+
+# -- General configuration -----------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = ['sphinx.ext.autodoc', 'sphinx.ext.viewcode']
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'M2Crypto'
+copyright = u'2017, Matej Cepl <mcepl@cepl.eu>'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = ''
+# The full version, including alpha/beta/rc tags.
+release = ''
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = ['_build']
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+
+# -- Options for HTML output ---------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+# html_theme = 'default'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further. For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents. If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# A shorter title for the navigation bar. Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_domain_indices = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it. The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'M2Cryptodoc'
+
+
+# -- Options for LaTeX output --------------------------------------------------
+
+latex_elements = {
+# The paper size ('letterpaper' or 'a4paper').
+#'papersize': 'letterpaper',
+
+# The font size ('10pt', '11pt' or '12pt').
+#'pointsize': '10pt',
+
+# Additional stuff for the LaTeX preamble.
+#'preamble': '',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, documentclass [howto/manual]).
+latex_documents = [
+ ('index', 'M2Crypto.tex', u'M2Crypto Documentation',
+ u'Matej Cepl \\textless{}mcepl@cepl.eu\\textgreater{}', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# If true, show page references after internal links.
+#latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#latex_show_urls = False
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_domain_indices = True
+
+
+# -- Options for manual page output --------------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+ ('index', 'm2crypto', u'M2Crypto Documentation',
+ [u'Matej Cepl <mcepl@cepl.eu>'], 1)
+]
+
+# If true, show URL addresses after external links.
+#man_show_urls = False
+
+
+# -- Options for Texinfo output ------------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+# dir menu entry, description, category)
+texinfo_documents = [
+ ('index', 'M2Crypto', u'M2Crypto Documentation',
+ u'Matej Cepl <mcepl@cepl.eu>', 'M2Crypto', 'One line description of project.',
+ 'Miscellaneous'),
+]
+
+# Documents to append as an appendix to all manuals.
+#texinfo_appendices = []
+
+# If false, no module index is generated.
+#texinfo_domain_indices = True
+
+# How to display URL addresses: 'footnote', 'no', or 'inline'.
+#texinfo_show_urls = 'footnote'
+
+
+# -- Options for Epub output ---------------------------------------------------
+
+# Bibliographic Dublin Core info.
+epub_title = u'M2Crypto'
+epub_author = u'Matej Cepl <mcepl@cepl.eu>'
+epub_publisher = u'Matej Cepl <mcepl@cepl.eu>'
+epub_copyright = u'2017, Matej Cepl <mcepl@cepl.eu>'
+
+# The language of the text. It defaults to the language option
+# or en if the language is not set.
+#epub_language = ''
+
+# The scheme of the identifier. Typical schemes are ISBN or URL.
+#epub_scheme = ''
+
+# The unique identifier of the text. This can be a ISBN number
+# or the project homepage.
+#epub_identifier = ''
+
+# A unique identification for the text.
+#epub_uid = ''
+
+# A tuple containing the cover image and cover page html template filenames.
+#epub_cover = ()
+
+# HTML files that should be inserted before the pages created by sphinx.
+# The format is a list of tuples containing the path and title.
+#epub_pre_files = []
+
+# HTML files shat should be inserted after the pages created by sphinx.
+# The format is a list of tuples containing the path and title.
+#epub_post_files = []
+
+# A list of files that should not be packed into the epub file.
+#epub_exclude_files = []
+
+# The depth of the table of contents in toc.ncx.
+#epub_tocdepth = 3
+
+# Allow duplicate toc entries.
+#epub_tocdup = True
diff --git a/doc/doctrees/M2Crypto.SSL.doctree b/doc/doctrees/M2Crypto.SSL.doctree
new file mode 100644
index 0000000..7ea180d
--- /dev/null
+++ b/doc/doctrees/M2Crypto.SSL.doctree
Binary files differ
diff --git a/doc/doctrees/M2Crypto.doctree b/doc/doctrees/M2Crypto.doctree
new file mode 100644
index 0000000..9a06cce
--- /dev/null
+++ b/doc/doctrees/M2Crypto.doctree
Binary files differ
diff --git a/doc/doctrees/ZServerSSL-HOWTO.doctree b/doc/doctrees/ZServerSSL-HOWTO.doctree
new file mode 100644
index 0000000..040bc3f
--- /dev/null
+++ b/doc/doctrees/ZServerSSL-HOWTO.doctree
Binary files differ
diff --git a/doc/doctrees/environment.pickle b/doc/doctrees/environment.pickle
new file mode 100644
index 0000000..9a85a4e
--- /dev/null
+++ b/doc/doctrees/environment.pickle
Binary files differ
diff --git a/doc/doctrees/howto.ca.doctree b/doc/doctrees/howto.ca.doctree
new file mode 100644
index 0000000..d86d193
--- /dev/null
+++ b/doc/doctrees/howto.ca.doctree
Binary files differ
diff --git a/doc/doctrees/howto.smime.doctree b/doc/doctrees/howto.smime.doctree
new file mode 100644
index 0000000..4199adb
--- /dev/null
+++ b/doc/doctrees/howto.smime.doctree
Binary files differ
diff --git a/doc/doctrees/howto.ssl.doctree b/doc/doctrees/howto.ssl.doctree
new file mode 100644
index 0000000..e90779b
--- /dev/null
+++ b/doc/doctrees/howto.ssl.doctree
Binary files differ
diff --git a/doc/doctrees/index.doctree b/doc/doctrees/index.doctree
new file mode 100644
index 0000000..cab8fd0
--- /dev/null
+++ b/doc/doctrees/index.doctree
Binary files differ
diff --git a/doc/howto.ca.html b/doc/howto.ca.html
deleted file mode 100644
index 74142d5..0000000
--- a/doc/howto.ca.html
+++ /dev/null
@@ -1,891 +0,0 @@
-<HTML
-><HEAD
-><TITLE
->HOWTO: Creating your own CA with OpenSSL</TITLE
-><META
-NAME="GENERATOR"
-CONTENT="Modular DocBook HTML Stylesheet Version 1.64
-"></HEAD
-><BODY
-CLASS="ARTICLE"
-BGCOLOR="#FFFFFF"
-TEXT="#000000"
-LINK="#0000FF"
-VLINK="#840084"
-ALINK="#0000FF"
-><DIV
-CLASS="ARTICLE"
-><DIV
-CLASS="TITLEPAGE"
-><H1
-CLASS="TITLE"
-><A
-NAME="AEN2"
->HOWTO: Creating your own CA with OpenSSL</A
-></H1
-><H3
-CLASS="AUTHOR"
-><A
-NAME="AEN4"
->Pheng Siong Ng</A
-></H3
-><DIV
-CLASS="AFFILIATION"
-><DIV
-CLASS="ADDRESS"
-><P
-CLASS="ADDRESS"
->ngps@post1.com</P
-></DIV
-></DIV
-><P
-CLASS="COPYRIGHT"
->Copyright &copy; 2000, 2001 by Ng Pheng Siong.</P
-><DIV
-CLASS="REVHISTORY"
-><TABLE
-WIDTH="100%"
-BORDER="0"
-><TR
-><TH
-ALIGN="LEFT"
-VALIGN="TOP"
-COLSPAN="3"
-><B
->Revision History</B
-></TH
-></TR
-><TR
-><TD
-ALIGN="LEFT"
->Revision $Revision: 1.1 $</TD
-><TD
-ALIGN="LEFT"
->$Date: 2003/06/22 16:41:18 $</TD
-><TD
-ALIGN="LEFT"
-></TD
-></TR
-><TR
-><TD
-ALIGN="LEFT"
-COLSPAN="3"
-></TD
-></TR
-></TABLE
-></DIV
-><HR></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="INTRODUCTION"
->Introduction</A
-></H1
-><P
->This is a HOWTO on creating your own <I
-CLASS="EMPHASIS"
->certification
- authority</I
-> (<I
-CLASS="EMPHASIS"
->CA</I
->) with OpenSSL.
- </P
-><P
->I last created a CA about a year ago, when I began work on <A
-HREF="http://chandlerproject.org/Projects/MeTooCrypto"
-TARGET="_top"
->M2Crypto</A
-> and needed
- certificates for the SSL bits. I accepted the tools' default settings
- then, e.g., certificate validity of 365 days; this meant that my
- certificates, including my CA's certificate, have now expired.
- </P
-><P
->Since I am using these certificates for M2Crypto's demonstration
- programs (and I have forgotten the passphrase to the CA's private key),
- I decided to discard the old CA and start afresh. I also decided to
- document the process, hence this HOWTO.
- </P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="PROCEDURE"
->The Procedure</A
-></H1
-><P
->I use <TT
-CLASS="FILENAME"
->CA.pl</TT
->, a Perl program written by
- Steve Hanson and bundled with OpenSSL.
- </P
-><P
->The following are the steps to create a CA:
- </P
-><DIV
-CLASS="PROCEDURE"
-><OL
-TYPE="1"
-><LI
-><P
->Choose a directory to do your CA work. All commands are executed
- within this directory. Let's call the directory <TT
-CLASS="FILENAME"
->demo</TT
->.
- </P
-></LI
-><LI
-><P
->Copy <TT
-CLASS="FILENAME"
->CA.pl</TT
-> and <TT
-CLASS="FILENAME"
->openssl.cnf</TT
->
- into <TT
-CLASS="FILENAME"
->demo</TT
->.
- </P
-></LI
-><LI
-><P
->Apply the following patch to <TT
-CLASS="FILENAME"
->CA.pl</TT
->, which
- allows it to generate a CA certificate with a validity period of 1095 days,
- i.e., 3 years:
- </P
-><PRE
-CLASS="PROGRAMLISTING"
-> --- CA.pl.org Sat Mar 31 12:40:13 2001
- +++ CA.pl Sat Mar 31 12:41:15 2001
- @@ -97,7 +97,7 @@
- } else {
- print "Making CA certificate ...\n";
- system ("$REQ -new -x509 -keyout " .
- - "${CATOP}/private/$CAKEY -out ${CATOP}/$CACERT $DAYS");
- + "${CATOP}/private/$CAKEY -out ${CATOP}/$CACERT -days 1095");
- $RET=$?;
- }
- }
- </PRE
-></LI
-><LI
-><P
->Create a new CA like this:
- </P
-><PRE
-CLASS="SCREEN"
-> <TT
-CLASS="USERINPUT"
-><B
->./CA.pl -newca
- </B
-></TT
->
- A certificate filename (or enter to create) <TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->&lt;enter&gt;</I
-></TT
-></B
-></TT
->
-
- Making CA certificate ...
- Using configuration from openssl.cnf
- Generating a 1024 bit RSA private key
- ............++++++
- ......................++++++
- writing new private key to './demoCA/private/cakey.pem'
- Enter PEM pass phrase: <TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->&lt;secret passphrase here&gt;</I
-></TT
-></B
-></TT
->
- Verifying password - Enter PEM pass phrase: <TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->&lt;secret passphrase again&gt;</I
-></TT
-></B
-></TT
->
- -----
- You are about to be asked to enter information that will be incorporated
- into your certificate request.
- What you are about to enter is what is called a Distinguished Name or a DN.
- There are quite a few fields but you can leave some blank
- For some fields there will be a default value,
- If you enter '.', the field will be left blank.
- -----
- Country Name (2 letter code) [AU]:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->SG</I
-></TT
-></B
-></TT
->
- State or Province Name (full name) [Some-State]:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->.</I
-></TT
-></B
-></TT
->
- Locality Name (eg, city) []:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->.</I
-></TT
-></B
-></TT
->.
- Organization Name (eg, company) [Internet Widgits Pty Ltd]:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->DemoCA</I
-></TT
-></B
-></TT
->
- Organizational Unit Name (eg, section) []:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->.</I
-></TT
-></B
-></TT
->
- Common Name (eg, YOUR name) []:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->DemoCA Certificate Master</I
-></TT
-></B
-></TT
->
- Email Address []:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->certmaster@democa.dom</I
-></TT
-></B
-></TT
->
- </PRE
-><P
->This creates a new CA in the directory <TT
-CLASS="FILENAME"
->demoCA</TT
->.
- The CA's self-signed certificate is in
- <TT
-CLASS="FILENAME"
->demoCA/cacert.pem</TT
-> and its RSA key pair is in
- <TT
-CLASS="FILENAME"
->demoCA/private/cakey.pem</TT
->.
- </P
-><P
-><TT
-CLASS="FILENAME"
->demoCA/private/cakey.pem</TT
-> looks like this:
- </P
-><PRE
-CLASS="SCREEN"
-> <TT
-CLASS="USERINPUT"
-><B
->cat demoCA/private/cakey.pem
- </B
-></TT
->
- -----BEGIN RSA PRIVATE KEY-----
- Proc-Type: 4,ENCRYPTED
- DEK-Info: DES-EDE3-CBC,19973A9DBBB601BA
-
- eOq9WFScNiI4/UWEUaSnGTKpJv2JYuMD3HwQox2Q3Cd4zGqVjJ6gF3exa5126cKf
- X/bMVnwbPpuFZPiAIvaLyCjT6pYeXTBbSzs7/GQnvEOv+nYnDUFWi0Qm92qLk0uy
- pFi/M1aWheN3vir2ZlAw+DW0bOOZhj8tC7Co7lMYb0YE271b6/YRPZCwQ3GXAHUJ
- +aMYxlUDrK45aCUa/1CZDzTgk7h9cDgx2QJSIvYMYytCfI3zsuZMJS8/4OXLL0bI
- lKmAc1dwB3DqGJt5XK4WJesiNfdxeCNEgAcYtEAgYZTPIApU+kTgTCIxJl2nMW7j
- ax+Q1z7g+4MpgG20WD633D4z4dTlDdz+dnLi0rvuvxiwt+dUhrqiML1tyi+Z6EBH
- jU4/cLBWev3rYfrlp4x8J9mDte0YKOk3t0wQOHqRetTsIfdtjnFp/Hu3qDmTCWjD
- z/g7PPoO/bg/B877J9WBPbL/1hXXFYo88M+2aGlPOgDcFdiOqbLb2DCscohMbbVr
- A4mgiy2kwWfIE73qiyV7yyG8FlRvr1iib+jbT3LTGf743utYAAs7HNGuOUObhoyt
- jYvBD7ACn35P5YX7KTqvqErwdijxYCaNBCnvmRtmYSaNw9Kv1UJTxc5Vx7YLwIPk
- E9KyBgKI7vPOjWBZ27+zOvNycmv1ciNtpALAw4bWtXnhCDVTHaVDy34OkheMzNCg
- 2cjcBFzOkMIjcI03KbTQXOFIQGlsTWXGzkNf/zBQ+KksT1MCj+zBXSCvlDASMckg
- kef21pGgUqPF14gKGfWX3sV4bjc1vbrRwq6zlG3nMuYqR5MtJJY9eQ==
- -----END RSA PRIVATE KEY-----
- </PRE
-></LI
-><LI
-><P
->Next, generate a certificate request.
- </P
-><PRE
-CLASS="SCREEN"
-> <TT
-CLASS="USERINPUT"
-><B
->./CA.pl -newreq
- </B
-></TT
->
- Using configuration from openssl.cnf
- Generating a 1024 bit RSA private key
- ..........++++++
- ..............++++++
- writing new private key to 'newreq.pem'
- Enter PEM pass phrase: <TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->&lt;another secret passphrase here&gt;</I
-></TT
-></B
-></TT
->
- Verifying password - Enter PEM pass phrase: <TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->&lt;another secret passphrase again&gt;</I
-></TT
-></B
-></TT
->
- -----
- You are about to be asked to enter information that will be incorporated
- into your certificate request.
- What you are about to enter is what is called a Distinguished Name or a DN.
- There are quite a few fields but you can leave some blank
- For some fields there will be a default value,
- If you enter '.', the field will be left blank.
- -----
- Country Name (2 letter code) [AU]:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->SG</I
-></TT
-></B
-></TT
->
- State or Province Name (full name) [Some-State]:.<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->.</I
-></TT
-></B
-></TT
->
- Locality Name (eg, city) []:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->.</I
-></TT
-></B
-></TT
->
- Organization Name (eg, company) [Internet Widgits Pty Ltd]:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->M2Crypto</I
-></TT
-></B
-></TT
->
- Organizational Unit Name (eg, section) []:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->.</I
-></TT
-></B
-></TT
->
- Common Name (eg, YOUR name) []:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->localhost</I
-></TT
-></B
-></TT
->
- Email Address []:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->admin@server.example.dom</I
-></TT
-></B
-></TT
->
-
- Please enter the following 'extra' attributes
- to be sent with your certificate request
- A challenge password []:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->&lt;enter&gt;</I
-></TT
-></B
-></TT
->
- An optional company name []:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->&lt;enter&gt;</I
-></TT
-></B
-></TT
->
- Request (and private key) is in newreq.pem
- </PRE
-><P
->The certificate request and private key in <TT
-CLASS="FILENAME"
->newreq.pem</TT
-> looks like this:
- </P
-><PRE
-CLASS="SCREEN"
-> <TT
-CLASS="USERINPUT"
-><B
->cat newreq.pem
- </B
-></TT
->
- -----BEGIN RSA PRIVATE KEY-----
- Proc-Type: 4,ENCRYPTED
- DEK-Info: DES-EDE3-CBC,41B2874DF3D02DD4
-
- mg611EoVkLEooSTv+qTM0Ddmm/M1jE/Jy5RD/sc3LSMhuGu9xc26OgsTJmkQuIAh
- J/B4lAw8G59VTG6DykeEtrG0rUBx4bggc7PKbFuiN423YjJODWcHvVgnPOzXMQt+
- lY4tPl5+217MRHyx2NsWGrpkQNdu3GeSPOVMl3jeQiaXupONbwQ7rj42+X/VtAJP
- W4D1NNwu8aGCPyShsEXHc/fI1WDpphYWke97pOjIZVQESFZOPty5HjIYZux4U+td
- W81xODtq2ecJXc8fn2Wpa9y5VD1LT7oJksOuL1+Z04OVaeUe4x0swM17HlBm2kVt
- fe/C/L6kN27MwZhE331VjtTjSGl4/gknqQDbLOtqT06f3OISsDJETm2itllyhgzv
- C6Fi3N03rGFmKectijC+tws5k+P+HRG6sai33usk8xPokJqA+HYSWPz1XVlpRmv4
- kdjQOdST7ovU62mOTgf3ARcduPPwuzTfxOlYONe5NioO1APVHBrInQwcpLkpOTQR
- vI4roIN+b75/nihUWGUJn/nbbBa2Yl0N5Gs1Tyiy9Z+CcRT2TfWKBBFlEUIFl7Mb
- J9fTV3DI+k+akbR4il1NkQ8EcSmCr3WpA0I9n0EHI7ZVpVaHxc0sqaPFl8YGdFHq
- 1Qk53C/w6+qPpDzT3yKFmG2LZytAAM1czvb6RbNRJJP2ZrpBwn/h99sUTo/yPfxY
- nueYmFJDm0uVNtG0icXGNUfSfnjKNTtHPAgyKGetRIC3kgJz/bo2w7EI6iEjBAzK
- l5TRm4x6ZJxwuXXMiJCehMMd8TC8ybwWO4AO19B3ebFFeTVsUgxSGA==
- -----END RSA PRIVATE KEY-----
- -----BEGIN CERTIFICATE REQUEST-----
- MIIBnTCCAQYCAQAwXTELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRIw
- EAYDVQQDEwlsb2NhbGhvc3QxJzAlBgkqhkiG9w0BCQEWGGFkbWluQHNlcnZlci5l
- eGFtcGxlLmRvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAr1nYY1Qrll1r
- uB/FqlCRrr5nvupdIN+3wF7q915tvEQoc74bnu6b8IbbGRMhzdzmvQ4SzFfVEAuM
- MuTHeybPq5th7YDrTNizKKxOBnqE2KYuX9X22A1Kh49soJJFg6kPb9MUgiZBiMlv
- tb7K3CHfgw5WagWnLl8Lb+ccvKZZl+8CAwEAAaAAMA0GCSqGSIb3DQEBBAUAA4GB
- AHpoRp5YS55CZpy+wdigQEwjL/wSluvo+WjtpvP0YoBMJu4VMKeZi405R7o8oEwi
- PdlrrliKNknFmHKIaCKTLRcU59ScA6ADEIWUzqmUzP5Cs6jrSRo3NKfg1bd09D1K
- 9rsQkRc9Urv9mRBIsredGnYECNeRaK5R1yzpOowninXC
- -----END CERTIFICATE REQUEST-----
- </PRE
-><P
->Decoding the certificate request gives the following:
- </P
-><PRE
-CLASS="SCREEN"
-> <TT
-CLASS="USERINPUT"
-><B
->openssl req -text -noout &#60; newreq.pem
- </B
-></TT
->
- Using configuration from /usr/local/pkg/openssl/openssl.cnf
- Certificate Request:
- Data:
- Version: 0 (0x0)
- Subject: C=SG, O=M2Crypto, CN=localhost/Email=admin@server.example.dom
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- RSA Public Key: (1024 bit)
- Modulus (1024 bit):
- 00:af:59:d8:63:54:2b:96:5d:6b:b8:1f:c5:aa:50:
- 91:ae:be:67:be:ea:5d:20:df:b7:c0:5e:ea:f7:5e:
- 6d:bc:44:28:73:be:1b:9e:ee:9b:f0:86:db:19:13:
- 21:cd:dc:e6:bd:0e:12:cc:57:d5:10:0b:8c:32:e4:
- c7:7b:26:cf:ab:9b:61:ed:80:eb:4c:d8:b3:28:ac:
- 4e:06:7a:84:d8:a6:2e:5f:d5:f6:d8:0d:4a:87:8f:
- 6c:a0:92:45:83:a9:0f:6f:d3:14:82:26:41:88:c9:
- 6f:b5:be:ca:dc:21:df:83:0e:56:6a:05:a7:2e:5f:
- 0b:6f:e7:1c:bc:a6:59:97:ef
- Exponent: 65537 (0x10001)
- Attributes:
- a0:00
- Signature Algorithm: md5WithRSAEncryption
- 7a:68:46:9e:58:4b:9e:42:66:9c:be:c1:d8:a0:40:4c:23:2f:
- fc:12:96:eb:e8:f9:68:ed:a6:f3:f4:62:80:4c:26:ee:15:30:
- a7:99:8b:8d:39:47:ba:3c:a0:4c:22:3d:d9:6b:ae:58:8a:36:
- 49:c5:98:72:88:68:22:93:2d:17:14:e7:d4:9c:03:a0:03:10:
- 85:94:ce:a9:94:cc:fe:42:b3:a8:eb:49:1a:37:34:a7:e0:d5:
- b7:74:f4:3d:4a:f6:bb:10:91:17:3d:52:bb:fd:99:10:48:b2:
- b7:9d:1a:76:04:08:d7:91:68:ae:51:d7:2c:e9:3a:8c:27:8a:
- 75:c2
- </PRE
-></LI
-><LI
-><P
->Now, sign the certificate request:
- </P
-><PRE
-CLASS="SCREEN"
-> <TT
-CLASS="USERINPUT"
-><B
->./CA.pl -sign
- </B
-></TT
->
- Using configuration from openssl.cnf
- Enter PEM pass phrase: <TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->&lt;CA's passphrase&gt;</I
-></TT
-></B
-></TT
->
- Check that the request matches the signature
- Signature ok
- The Subjects Distinguished Name is as follows
- countryName :PRINTABLE:'SG'
- organizationName :PRINTABLE:'M2Crypto'
- commonName :PRINTABLE:'localhost'
- emailAddress :IA5STRING:'admin@server.example.dom'
- Certificate is to be certified until Mar 31 02:57:30 2002 GMT (365 days)
- Sign the certificate? [y/n]:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->y</I
-></TT
-></B
-></TT
->
-
-
- 1 out of 1 certificate requests certified, commit? [y/n]<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->y</I
-></TT
-></B
-></TT
->
- Write out database with 1 new entries
- Data Base Updated
- Signed certificate is in newcert.pem
- </PRE
-><P
-><TT
-CLASS="FILENAME"
->newcert.pem</TT
-> looks like this:
- </P
-><PRE
-CLASS="SCREEN"
-> <TT
-CLASS="USERINPUT"
-><B
->cat newcert.pem
- </B
-></TT
->
- Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 1 (0x1)
- Signature Algorithm: md5WithRSAEncryption
- Issuer: C=SG, O=DemoCA, CN=DemoCA Certificate Master/Email=certmaster@democa.dom
- Validity
- Not Before: Mar 31 02:57:30 2001 GMT
- Not After : Mar 31 02:57:30 2002 GMT
- Subject: C=SG, O=M2Crypto, CN=localhost/Email=admin@server.example.dom
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- RSA Public Key: (1024 bit)
- Modulus (1024 bit):
- 00:af:59:d8:63:54:2b:96:5d:6b:b8:1f:c5:aa:50:
- 91:ae:be:67:be:ea:5d:20:df:b7:c0:5e:ea:f7:5e:
- 6d:bc:44:28:73:be:1b:9e:ee:9b:f0:86:db:19:13:
- 21:cd:dc:e6:bd:0e:12:cc:57:d5:10:0b:8c:32:e4:
- c7:7b:26:cf:ab:9b:61:ed:80:eb:4c:d8:b3:28:ac:
- 4e:06:7a:84:d8:a6:2e:5f:d5:f6:d8:0d:4a:87:8f:
- 6c:a0:92:45:83:a9:0f:6f:d3:14:82:26:41:88:c9:
- 6f:b5:be:ca:dc:21:df:83:0e:56:6a:05:a7:2e:5f:
- 0b:6f:e7:1c:bc:a6:59:97:ef
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints:
- Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 1 (0x1)
- Signature Algorithm: md5WithRSAEncryption
- Issuer: C=SG, O=DemoCA, CN=DemoCA Certificate Master/Email=certmaster@democa.dom
- Validity
- Not Before: Mar 31 02:57:30 2001 GMT
- Not After : Mar 31 02:57:30 2002 GMT
- Subject: C=SG, O=M2Crypto, CN=localhost/Email=admin@server.example.dom
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- RSA Public Key: (1024 bit)
- Modulus (1024 bit):
- 00:af:59:d8:63:54:2b:96:5d:6b:b8:1f:c5:aa:50:
- 91:ae:be:67:be:ea:5d:20:df:b7:c0:5e:ea:f7:5e:
- 6d:bc:44:28:73:be:1b:9e:ee:9b:f0:86:db:19:13:
- 21:cd:dc:e6:bd:0e:12:cc:57:d5:10:0b:8c:32:e4:
- c7:7b:26:cf:ab:9b:61:ed:80:eb:4c:d8:b3:28:ac:
- 4e:06:7a:84:d8:a6:2e:5f:d5:f6:d8:0d:4a:87:8f:
- 6c:a0:92:45:83:a9:0f:6f:d3:14:82:26:41:88:c9:
- 6f:b5:be:ca:dc:21:df:83:0e:56:6a:05:a7:2e:5f:
- 0b:6f:e7:1c:bc:a6:59:97:ef
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints:
- CA:FALSE
- Netscape Comment:
- OpenSSL Generated Certificate
- X509v3 Subject Key Identifier:
- B3:D6:89:88:2F:B1:15:40:EC:0A:C0:30:35:3A:B7:DA:72:73:1B:4D
- X509v3 Authority Key Identifier:
- keyid:F9:6A:A6:34:97:6B:BC:BB:5A:17:0D:19:FC:62:21:0B:00:B5:0E:29
- DirName:/C=SG/O=DemoCA/CN=DemoCA Certificate Master/Email=certmaster@democa.dom
- serial:00
-
- Signature Algorithm: md5WithRSAEncryption
- </PRE
-></LI
-><LI
-><P
->In certain situations, e.g., where your certificate and
- private key are to be used in an unattended SSL server, you may wish to
- not encrypt the private key, i.e., leave the key in the clear. This
- decision should be governed by your site's security policy and threat
- model, of course.
- </P
-><PRE
-CLASS="SCREEN"
-> <TT
-CLASS="USERINPUT"
-><B
->openssl rsa &#60; newkey.pem &#62; newkey2.pem
- </B
-></TT
->
- read RSA key
- Enter PEM pass phrase:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->&lt;secret passphrase here&gt;</I
-></TT
-></B
-></TT
->
- writing RSA key
- </PRE
-><P
-><TT
-CLASS="FILENAME"
->newkey2.pem</TT
-> looks like this:
- </P
-><PRE
-CLASS="SCREEN"
-> <TT
-CLASS="USERINPUT"
-><B
->cat newkey2.pem
- </B
-></TT
->
- -----BEGIN RSA PRIVATE KEY-----
- MIICXgIBAAKBgQCvWdhjVCuWXWu4H8WqUJGuvme+6l0g37fAXur3Xm28RChzvhue
- 7pvwhtsZEyHN3Oa9DhLMV9UQC4wy5Md7Js+rm2HtgOtM2LMorE4GeoTYpi5f1fbY
- DUqHj2ygkkWDqQ9v0xSCJkGIyW+1vsrcId+DDlZqBacuXwtv5xy8plmX7wIDAQAB
- AoGAbAkU8w3W1Qu15Hle1bJSL7GMReoreqeblOBmMAZz4by0l6sXZXJpjWXo86f/
- +dASMYTMPC4ZTYtv06N07AFbjL+kDfqDMTfzQkYMHp1LAq1Ihbq1rHWSBH5n3ekq
- KiY8JKpv8DR5Po1iKaXJFuDByGDENJwYbSRSpSK3P+vkWWECQQDkEUE/ZPqqqZkQ
- 2iWRPAsCbEID8SAraQl3DdCLYs/GgARfmmj4yUHEwkys9Jo1H8k4BdxugmaUwNi5
- YQ/CVzrXAkEAxNO80ArbGxPUmr11GHG/bGBYj1DUBkHZSc7dgxZdtUCLGNxQnNsg
- Iwq3n6j1sUzS3UW6abQ8bivYNOUcMKJAqQJBANQxFaLU4b/NQaODQ3aoBZpAfP9L
- 5eFdvbet+7zjt2r5CpikgkwOfAmDuXEltx/8LevY0CllW+nErx9zJgVrwUsCQQCu
- 76H5JiznPBDSF2FjgHWqVVdgyW4owY3mU739LHvNBLicN/RN9VPy0Suy8/CqzKT9
- lWPBXzf2k3FuUdNkRlFBAkEAmpXoybuiFR2S5Bma/ax96lVs0/VihhfC1zZP/X/F
- Br77+h9dIul+2DnyOl50zu0Sdzst1/7ay4JSDHyiBCMGSQ==
- -----END RSA PRIVATE KEY-----
- </PRE
-></LI
-></OL
-></DIV
-><P
->That's it! The certificate, <TT
-CLASS="FILENAME"
->newcert.pem</TT
->, and
- the private key - <TT
-CLASS="FILENAME"
->newkey.pem</TT
-> (encrypted) or
- <TT
-CLASS="FILENAME"
->newkey2.pem</TT
-> (unencrypted) - are now ready to be used.
- You may wish to rename the files to more intuitive names.
- </P
-><P
->You should also keep the CA's certificate <TT
-CLASS="FILENAME"
->demo/cacert.pem
- </TT
-> handy for use when developing and deploying SSL or S/MIME
- applications.
- </P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="CONCLUSION"
->Conclusion</A
-></H1
-><P
->We've walked through the basic steps in the creation of a CA and
- certificates using the tools that come with OpenSSL. We did not cover more
- advanced topics such as constraining a certificate to be SSL-only or
- S/MIME-only.
- </P
-><P
->There exist several HOWTOs similar to this one on the net. This one
- is written specifically to facilitate discussions in my other HOWTOs
- on developing SSL and S/MIME applications in
- <A
-HREF="http://www.python.org"
-TARGET="_top"
->Python</A
-> using
- <A
-HREF="http://chandlerproject.org/Projects/MeTooCrypto"
-TARGET="_top"
->M2Crypto</A
->.
- </P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="ID-KLUDGE"
-></A
-></H1
-><P
-> <TT
-CLASS="LITERAL"
->$Id:howto.ca.html 583 2007-10-01 19:23:12Z heikki $</TT
->
- </P
-></DIV
-></DIV
-></BODY
-></HTML
-> \ No newline at end of file
diff --git a/doc/howto.ca.rst b/doc/howto.ca.rst
new file mode 100644
index 0000000..e950b59
--- /dev/null
+++ b/doc/howto.ca.rst
@@ -0,0 +1,370 @@
+:orphan:
+
+.. _howto-ca:
+
+HOWTO: Creating your own CA with OpenSSL
+########################################
+
+:author: Pheng Siong Ng <ngps@post1.com>
+:copyright: © 2000, 2001 by Ng Pheng Siong.
+
+Introduction
+============
+
+This is a HOWTO on creating your own *certification authority* (*CA*)
+with OpenSSL.
+
+I last created a CA about a year ago, when I began work on
+`M2Crypto <https://gitlab.com/m2crypto/m2crypto/>`__ and needed
+certificates for the SSL bits. I accepted the tools' default
+settings then, e.g., certificate validity of 365 days; this meant
+that my certificates, including my CA's certificate, have now
+expired.
+
+Since I am using these certificates for M2Crypto's demonstration
+programs (and I have forgotten the passphrase to the CA's private
+key), I decided to discard the old CA and start afresh. I also
+decided to document the process, hence this HOWTO.
+
+The Procedure
+=============
+
+I use ``CA.pl``, a Perl program written by Steve Hanson and bundled with
+OpenSSL.
+
+The following are the steps to create a CA:
+
+1. Choose a directory to do your CA work. All commands are executed
+ within this directory. Let's call the directory ``demo``.
+
+2. Copy ``CA.pl`` and ``openssl.cnf`` into ``demo``.
+
+3. Apply the following patch to ``CA.pl``, which allows it to generate a
+ CA certificate with a validity period of 1095 days, i.e.,
+ 3 years::
+
+ --- CA.pl.org Sat Mar 31 12:40:13 2001
+ +++ CA.pl Sat Mar 31 12:41:15 2001
+ @@ -97,7 +97,7 @@
+ } else {
+ print "Making CA certificate ...\n";
+ system ("$REQ -new -x509 -keyout " .
+ - "${CATOP}/private/$CAKEY -out ${CATOP}/$CACERT $DAYS");
+ + "${CATOP}/private/$CAKEY -out ${CATOP}/$CACERT -days 1095");
+ $RET=$?;
+ }
+ }
+
+
+4. Create a new CA like this::
+
+ ./CA.pl -newca
+
+ A certificate filename (or enter to create) <enter>
+
+ Making CA certificate ...
+ Using configuration from openssl.cnf
+ Generating a 1024 bit RSA private key
+ ............++++++
+ ......................++++++
+ writing new private key to './demoCA/private/cakey.pem'
+ Enter PEM pass phrase: <secret passphrase here>
+ Verifying password - Enter PEM pass phrase: <secret passphrase again>
+ -----
+ You are about to be asked to enter information that will be incorporated
+ into your certificate request.
+ What you are about to enter is what is called a Distinguished Name or a DN.
+ There are quite a few fields but you can leave some blank
+ For some fields there will be a default value,
+ If you enter '.', the field will be left blank.
+ -----
+ Country Name (2 letter code) [AU]:SG
+ State or Province Name (full name) [Some-State]:.
+ Locality Name (eg, city) []:..
+ Organization Name (eg, company) [Internet Widgits Pty Ltd]:DemoCA
+ Organizational Unit Name (eg, section) []:.
+ Common Name (eg, YOUR name) []:DemoCA Certificate Master
+ Email Address []:certmaster@democa.dom
+
+ This creates a new CA in the directory ``demoCA``. The CA's
+ self-signed certificate is in ``demoCA/cacert.pem`` and its RSA key
+ pair is in ``demoCA/private/cakey.pem``.
+
+ ``demoCA/private/cakey.pem`` looks like this::
+
+ cat demoCA/private/cakey.pem
+
+ -----BEGIN RSA PRIVATE KEY-----
+ Proc-Type: 4,ENCRYPTED
+ DEK-Info: DES-EDE3-CBC,19973A9DBBB601BA
+
+ eOq9WFScNiI4/UWEUaSnGTKpJv2JYuMD3HwQox2Q3Cd4zGqVjJ6gF3exa5126cKf
+ X/bMVnwbPpuFZPiAIvaLyCjT6pYeXTBbSzs7/GQnvEOv+nYnDUFWi0Qm92qLk0uy
+ pFi/M1aWheN3vir2ZlAw+DW0bOOZhj8tC7Co7lMYb0YE271b6/YRPZCwQ3GXAHUJ
+ +aMYxlUDrK45aCUa/1CZDzTgk7h9cDgx2QJSIvYMYytCfI3zsuZMJS8/4OXLL0bI
+ lKmAc1dwB3DqGJt5XK4WJesiNfdxeCNEgAcYtEAgYZTPIApU+kTgTCIxJl2nMW7j
+ ax+Q1z7g+4MpgG20WD633D4z4dTlDdz+dnLi0rvuvxiwt+dUhrqiML1tyi+Z6EBH
+ jU4/cLBWev3rYfrlp4x8J9mDte0YKOk3t0wQOHqRetTsIfdtjnFp/Hu3qDmTCWjD
+ z/g7PPoO/bg/B877J9WBPbL/1hXXFYo88M+2aGlPOgDcFdiOqbLb2DCscohMbbVr
+ A4mgiy2kwWfIE73qiyV7yyG8FlRvr1iib+jbT3LTGf743utYAAs7HNGuOUObhoyt
+ jYvBD7ACn35P5YX7KTqvqErwdijxYCaNBCnvmRtmYSaNw9Kv1UJTxc5Vx7YLwIPk
+ E9KyBgKI7vPOjWBZ27+zOvNycmv1ciNtpALAw4bWtXnhCDVTHaVDy34OkheMzNCg
+ 2cjcBFzOkMIjcI03KbTQXOFIQGlsTWXGzkNf/zBQ+KksT1MCj+zBXSCvlDASMckg
+ kef21pGgUqPF14gKGfWX3sV4bjc1vbrRwq6zlG3nMuYqR5MtJJY9eQ==
+ -----END RSA PRIVATE KEY-----
+
+
+5. Next, generate a certificate request::
+
+ ./CA.pl -newreq
+
+ Using configuration from openssl.cnf
+ Generating a 1024 bit RSA private key
+ ..........++++++
+ ..............++++++
+ writing new private key to 'newreq.pem'
+ Enter PEM pass phrase: <another secret passphrase here>
+ Verifying password - Enter PEM pass phrase: <another secret passphrase again>
+ -----
+ You are about to be asked to enter information that will be incorporated
+ into your certificate request.
+ What you are about to enter is what is called a Distinguished Name or a DN.
+ There are quite a few fields but you can leave some blank
+ For some fields there will be a default value,
+ If you enter '.', the field will be left blank.
+ -----
+ Country Name (2 letter code) [AU]:SG
+ State or Province Name (full name) [Some-State]:..
+ Locality Name (eg, city) []:.
+ Organization Name (eg, company) [Internet Widgits Pty Ltd]:M2Crypto
+ Organizational Unit Name (eg, section) []:.
+ Common Name (eg, YOUR name) []:localhost
+ Email Address []:admin@server.example.dom
+
+ Please enter the following 'extra' attributes
+ to be sent with your certificate request
+ A challenge password []:<enter>
+ An optional company name []:<enter>
+ Request (and private key) is in newreq.pem
+
+\
+
+ The certificate request and private key in ``newreq.pem`` looks like
+ this::
+
+ cat newreq.pem
+
+ -----BEGIN RSA PRIVATE KEY-----
+ Proc-Type: 4,ENCRYPTED
+ DEK-Info: DES-EDE3-CBC,41B2874DF3D02DD4
+
+ mg611EoVkLEooSTv+qTM0Ddmm/M1jE/Jy5RD/sc3LSMhuGu9xc26OgsTJmkQuIAh
+ J/B4lAw8G59VTG6DykeEtrG0rUBx4bggc7PKbFuiN423YjJODWcHvVgnPOzXMQt+
+ lY4tPl5+217MRHyx2NsWGrpkQNdu3GeSPOVMl3jeQiaXupONbwQ7rj42+X/VtAJP
+ W4D1NNwu8aGCPyShsEXHc/fI1WDpphYWke97pOjIZVQESFZOPty5HjIYZux4U+td
+ W81xODtq2ecJXc8fn2Wpa9y5VD1LT7oJksOuL1+Z04OVaeUe4x0swM17HlBm2kVt
+ fe/C/L6kN27MwZhE331VjtTjSGl4/gknqQDbLOtqT06f3OISsDJETm2itllyhgzv
+ C6Fi3N03rGFmKectijC+tws5k+P+HRG6sai33usk8xPokJqA+HYSWPz1XVlpRmv4
+ kdjQOdST7ovU62mOTgf3ARcduPPwuzTfxOlYONe5NioO1APVHBrInQwcpLkpOTQR
+ vI4roIN+b75/nihUWGUJn/nbbBa2Yl0N5Gs1Tyiy9Z+CcRT2TfWKBBFlEUIFl7Mb
+ J9fTV3DI+k+akbR4il1NkQ8EcSmCr3WpA0I9n0EHI7ZVpVaHxc0sqaPFl8YGdFHq
+ 1Qk53C/w6+qPpDzT3yKFmG2LZytAAM1czvb6RbNRJJP2ZrpBwn/h99sUTo/yPfxY
+ nueYmFJDm0uVNtG0icXGNUfSfnjKNTtHPAgyKGetRIC3kgJz/bo2w7EI6iEjBAzK
+ l5TRm4x6ZJxwuXXMiJCehMMd8TC8ybwWO4AO19B3ebFFeTVsUgxSGA==
+ -----END RSA PRIVATE KEY-----
+ -----BEGIN CERTIFICATE REQUEST-----
+ MIIBnTCCAQYCAQAwXTELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRIw
+ EAYDVQQDEwlsb2NhbGhvc3QxJzAlBgkqhkiG9w0BCQEWGGFkbWluQHNlcnZlci5l
+ eGFtcGxlLmRvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAr1nYY1Qrll1r
+ uB/FqlCRrr5nvupdIN+3wF7q915tvEQoc74bnu6b8IbbGRMhzdzmvQ4SzFfVEAuM
+ MuTHeybPq5th7YDrTNizKKxOBnqE2KYuX9X22A1Kh49soJJFg6kPb9MUgiZBiMlv
+ tb7K3CHfgw5WagWnLl8Lb+ccvKZZl+8CAwEAAaAAMA0GCSqGSIb3DQEBBAUAA4GB
+ AHpoRp5YS55CZpy+wdigQEwjL/wSluvo+WjtpvP0YoBMJu4VMKeZi405R7o8oEwi
+ PdlrrliKNknFmHKIaCKTLRcU59ScA6ADEIWUzqmUzP5Cs6jrSRo3NKfg1bd09D1K
+ 9rsQkRc9Urv9mRBIsredGnYECNeRaK5R1yzpOowninXC
+ -----END CERTIFICATE REQUEST-----
+
+\
+
+ Decoding the certificate request gives the following::
+
+ openssl req -text -noout < newreq.pem
+
+ Using configuration from /usr/local/pkg/openssl/openssl.cnf
+ Certificate Request:
+ Data:
+ Version: 0 (0x0)
+ Subject: C=SG, O=M2Crypto, CN=localhost/Email=admin@server.example.dom
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public Key: (1024 bit)
+ Modulus (1024 bit):
+ 00:af:59:d8:63:54:2b:96:5d:6b:b8:1f:c5:aa:50:
+ 91:ae:be:67:be:ea:5d:20:df:b7:c0:5e:ea:f7:5e:
+ 6d:bc:44:28:73:be:1b:9e:ee:9b:f0:86:db:19:13:
+ 21:cd:dc:e6:bd:0e:12:cc:57:d5:10:0b:8c:32:e4:
+ c7:7b:26:cf:ab:9b:61:ed:80:eb:4c:d8:b3:28:ac:
+ 4e:06:7a:84:d8:a6:2e:5f:d5:f6:d8:0d:4a:87:8f:
+ 6c:a0:92:45:83:a9:0f:6f:d3:14:82:26:41:88:c9:
+ 6f:b5:be:ca:dc:21:df:83:0e:56:6a:05:a7:2e:5f:
+ 0b:6f:e7:1c:bc:a6:59:97:ef
+ Exponent: 65537 (0x10001)
+ Attributes:
+ a0:00
+ Signature Algorithm: md5WithRSAEncryption
+ 7a:68:46:9e:58:4b:9e:42:66:9c:be:c1:d8:a0:40:4c:23:2f:
+ fc:12:96:eb:e8:f9:68:ed:a6:f3:f4:62:80:4c:26:ee:15:30:
+ a7:99:8b:8d:39:47:ba:3c:a0:4c:22:3d:d9:6b:ae:58:8a:36:
+ 49:c5:98:72:88:68:22:93:2d:17:14:e7:d4:9c:03:a0:03:10:
+ 85:94:ce:a9:94:cc:fe:42:b3:a8:eb:49:1a:37:34:a7:e0:d5:
+ b7:74:f4:3d:4a:f6:bb:10:91:17:3d:52:bb:fd:99:10:48:b2:
+ b7:9d:1a:76:04:08:d7:91:68:ae:51:d7:2c:e9:3a:8c:27:8a:
+ 75:c2
+
+6. Now, sign the certificate request::
+
+ ./CA.pl -sign
+
+ Using configuration from openssl.cnf
+ Enter PEM pass phrase: <CA's passphrase>
+ Check that the request matches the signature
+ Signature ok
+ The Subjects Distinguished Name is as follows
+ countryName :PRINTABLE:'SG'
+ organizationName :PRINTABLE:'M2Crypto'
+ commonName :PRINTABLE:'localhost'
+ emailAddress :IA5STRING:'admin@server.example.dom'
+ Certificate is to be certified until Mar 31 02:57:30 2002 GMT (365 days)
+ Sign the certificate? [y/n]:y
+
+
+ 1 out of 1 certificate requests certified, commit? [y/n]y
+ Write out database with 1 new entries
+ Data Base Updated
+ Signed certificate is in newcert.pem
+
+\
+
+ ``newcert.pem`` looks like this::
+
+ cat newcert.pem
+
+ Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: md5WithRSAEncryption
+ Issuer: C=SG, O=DemoCA, CN=DemoCA Certificate Master/Email=certmaster@democa.dom
+ Validity
+ Not Before: Mar 31 02:57:30 2001 GMT
+ Not After : Mar 31 02:57:30 2002 GMT
+ Subject: C=SG, O=M2Crypto, CN=localhost/Email=admin@server.example.dom
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public Key: (1024 bit)
+ Modulus (1024 bit):
+ 00:af:59:d8:63:54:2b:96:5d:6b:b8:1f:c5:aa:50:
+ 91:ae:be:67:be:ea:5d:20:df:b7:c0:5e:ea:f7:5e:
+ 6d:bc:44:28:73:be:1b:9e:ee:9b:f0:86:db:19:13:
+ 21:cd:dc:e6:bd:0e:12:cc:57:d5:10:0b:8c:32:e4:
+ c7:7b:26:cf:ab:9b:61:ed:80:eb:4c:d8:b3:28:ac:
+ 4e:06:7a:84:d8:a6:2e:5f:d5:f6:d8:0d:4a:87:8f:
+ 6c:a0:92:45:83:a9:0f:6f:d3:14:82:26:41:88:c9:
+ 6f:b5:be:ca:dc:21:df:83:0e:56:6a:05:a7:2e:5f:
+ 0b:6f:e7:1c:bc:a6:59:97:ef
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints:
+ Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: md5WithRSAEncryption
+ Issuer: C=SG, O=DemoCA, CN=DemoCA Certificate Master/Email=certmaster@democa.dom
+ Validity
+ Not Before: Mar 31 02:57:30 2001 GMT
+ Not After : Mar 31 02:57:30 2002 GMT
+ Subject: C=SG, O=M2Crypto, CN=localhost/Email=admin@server.example.dom
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public Key: (1024 bit)
+ Modulus (1024 bit):
+ 00:af:59:d8:63:54:2b:96:5d:6b:b8:1f:c5:aa:50:
+ 91:ae:be:67:be:ea:5d:20:df:b7:c0:5e:ea:f7:5e:
+ 6d:bc:44:28:73:be:1b:9e:ee:9b:f0:86:db:19:13:
+ 21:cd:dc:e6:bd:0e:12:cc:57:d5:10:0b:8c:32:e4:
+ c7:7b:26:cf:ab:9b:61:ed:80:eb:4c:d8:b3:28:ac:
+ 4e:06:7a:84:d8:a6:2e:5f:d5:f6:d8:0d:4a:87:8f:
+ 6c:a0:92:45:83:a9:0f:6f:d3:14:82:26:41:88:c9:
+ 6f:b5:be:ca:dc:21:df:83:0e:56:6a:05:a7:2e:5f:
+ 0b:6f:e7:1c:bc:a6:59:97:ef
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints:
+ CA:FALSE
+ Netscape Comment:
+ OpenSSL Generated Certificate
+ X509v3 Subject Key Identifier:
+ B3:D6:89:88:2F:B1:15:40:EC:0A:C0:30:35:3A:B7:DA:72:73:1B:4D
+ X509v3 Authority Key Identifier:
+ keyid:F9:6A:A6:34:97:6B:BC:BB:5A:17:0D:19:FC:62:21:0B:00:B5:0E:29
+ DirName:/C=SG/O=DemoCA/CN=DemoCA Certificate Master/Email=certmaster@democa.dom
+ serial:00
+
+ Signature Algorithm: md5WithRSAEncryption
+
+7. In certain situations, e.g., where your certificate and private key
+ are to be used in an unattended SSL server, you may wish to not
+ encrypt the private key, i.e., leave the key in the clear. This
+ decision should be governed by your site's security policy and threat
+ model, of course::
+
+ openssl rsa < newkey.pem > newkey2.pem
+
+ read RSA key
+ Enter PEM pass phrase:<secret passphrase here>
+ writing RSA key
+
+ ``newkey2.pem`` looks like this::
+
+ cat newkey2.pem
+
+ -----BEGIN RSA PRIVATE KEY-----
+ MIICXgIBAAKBgQCvWdhjVCuWXWu4H8WqUJGuvme+6l0g37fAXur3Xm28RChzvhue
+ 7pvwhtsZEyHN3Oa9DhLMV9UQC4wy5Md7Js+rm2HtgOtM2LMorE4GeoTYpi5f1fbY
+ DUqHj2ygkkWDqQ9v0xSCJkGIyW+1vsrcId+DDlZqBacuXwtv5xy8plmX7wIDAQAB
+ AoGAbAkU8w3W1Qu15Hle1bJSL7GMReoreqeblOBmMAZz4by0l6sXZXJpjWXo86f/
+ +dASMYTMPC4ZTYtv06N07AFbjL+kDfqDMTfzQkYMHp1LAq1Ihbq1rHWSBH5n3ekq
+ KiY8JKpv8DR5Po1iKaXJFuDByGDENJwYbSRSpSK3P+vkWWECQQDkEUE/ZPqqqZkQ
+ 2iWRPAsCbEID8SAraQl3DdCLYs/GgARfmmj4yUHEwkys9Jo1H8k4BdxugmaUwNi5
+ YQ/CVzrXAkEAxNO80ArbGxPUmr11GHG/bGBYj1DUBkHZSc7dgxZdtUCLGNxQnNsg
+ Iwq3n6j1sUzS3UW6abQ8bivYNOUcMKJAqQJBANQxFaLU4b/NQaODQ3aoBZpAfP9L
+ 5eFdvbet+7zjt2r5CpikgkwOfAmDuXEltx/8LevY0CllW+nErx9zJgVrwUsCQQCu
+ 76H5JiznPBDSF2FjgHWqVVdgyW4owY3mU739LHvNBLicN/RN9VPy0Suy8/CqzKT9
+ lWPBXzf2k3FuUdNkRlFBAkEAmpXoybuiFR2S5Bma/ax96lVs0/VihhfC1zZP/X/F
+ Br77+h9dIul+2DnyOl50zu0Sdzst1/7ay4JSDHyiBCMGSQ==
+ -----END RSA PRIVATE KEY-----
+
+
+That's it! The certificate, ``newcert.pem``, and the private key -
+``newkey.pem`` (encrypted) or ``newkey2.pem`` (unencrypted) - are now
+ready to be used. You may wish to rename the files to more intuitive
+names.
+
+You should also keep the CA's certificate ``demo/cacert.pem`` handy
+for use when developing and deploying SSL or S/MIME applications.
+
+Conclusion
+==========
+
+We've walked through the basic steps in the creation of a CA and
+certificates using the tools that come with OpenSSL. We did not cover
+more advanced topics such as constraining a certificate to be SSL-only
+or S/MIME-only.
+
+There exist several HOWTOs similar to this one on the net. This one is
+written specifically to facilitate discussions in my other HOWTOs on
+developing SSL and S/MIME applications in
+`Python <http://www.python.org>`__ using
+`M2Crypto <https://gitlab.com/m2crypto/m2crypto/>`__.
+
diff --git a/doc/howto.smime.html b/doc/howto.smime.html
deleted file mode 100644
index 21bc5cb..0000000
--- a/doc/howto.smime.html
+++ /dev/null
@@ -1,1570 +0,0 @@
-<HTML
-><HEAD
-><TITLE
->HOWTO: Programming S/MIME in Python with M2Crypto</TITLE
-><META
-NAME="GENERATOR"
-CONTENT="Modular DocBook HTML Stylesheet Version 1.64
-"></HEAD
-><BODY
-CLASS="ARTICLE"
-BGCOLOR="#FFFFFF"
-TEXT="#000000"
-LINK="#0000FF"
-VLINK="#840084"
-ALINK="#0000FF"
-><DIV
-CLASS="ARTICLE"
-><DIV
-CLASS="TITLEPAGE"
-><H1
-CLASS="TITLE"
-><A
-NAME="AEN2"
->HOWTO: Programming S/MIME in Python with M2Crypto</A
-></H1
-><H3
-CLASS="AUTHOR"
-><A
-NAME="AEN4"
->Pheng Siong Ng</A
-></H3
-><DIV
-CLASS="AFFILIATION"
-><DIV
-CLASS="ADDRESS"
-><P
-CLASS="ADDRESS"
->ngps@post1.com</P
-></DIV
-></DIV
-><P
-CLASS="COPYRIGHT"
->Copyright &copy; 2000, 2001 by Ng Pheng Siong.</P
-><DIV
-CLASS="REVHISTORY"
-><TABLE
-WIDTH="100%"
-BORDER="0"
-><TR
-><TH
-ALIGN="LEFT"
-VALIGN="TOP"
-COLSPAN="3"
-><B
->Revision History</B
-></TH
-></TR
-><TR
-><TD
-ALIGN="LEFT"
->Revision $Id: howto.smime.html 646 2008-10-29 03:12:56Z heikki $</TD
-><TD
-ALIGN="LEFT"
-></TD
-><TD
-ALIGN="LEFT"
-></TD
-></TR
-><TR
-><TD
-ALIGN="LEFT"
-COLSPAN="3"
-></TD
-></TR
-></TABLE
-></DIV
-><HR></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="INTRODUCTION"
->Introduction</A
-></H1
-><P
-><A
-HREF="http://chandlerproject.org/Projects/MeTooCrypto"
-TARGET="_top"
->M2Crypto</A
->
- is a <A
-HREF="http://www.python.org"
-TARGET="_top"
->Python</A
->
- interface to <A
-HREF="http://www.openssl.org"
-TARGET="_top"
->OpenSSL</A
->. It makes
- available to the Python programmer SSL functionality to implement clients
- and servers, S/MIME v2, RSA, DSA, DH, symmetric ciphers, message digests and
- HMACs.
- </P
-><P
->This document demonstrates programming S/MIME with M2Crypto.
- </P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="SMIME"
->S/MIME</A
-></H1
-><P
->S/MIME - Secure Multipurpose Internet Mail Extensions
- [<SPAN
-CLASS="CITATION"
->RFC 2311, RFC 2312</SPAN
->] - provides a
- consistent way to send and receive secure MIME data. Based on the popular
- Internet MIME standard, S/MIME provides the following cryptographic security
- services for electronic messaging applications -
- <I
-CLASS="EMPHASIS"
->authentication</I
->, <I
-CLASS="EMPHASIS"
->message integrity </I
->
- and <I
-CLASS="EMPHASIS"
->non-repudiation of origin </I
-> (using <I
-CLASS="EMPHASIS"
->digital
- signatures</I
->), and <I
-CLASS="EMPHASIS"
->privacy </I
-> and <I
-CLASS="EMPHASIS"
->data
- security</I
-> (using <I
-CLASS="EMPHASIS"
->encryption</I
->).
- </P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="KEYS-AND-CERTIFICATES"
->Keys and Certificates</A
-></H1
-><P
->To create an S/MIME-signed message, you need an RSA key pair
- (this consists of a public key and a private key) and an X.509
- certificate of said public key.
- </P
-><P
->To create an S/MIME-encrypted message, you need an X.509
- certificate for each recipient.
- </P
-><P
->To create an S/MIME-signed <I
-CLASS="EMPHASIS"
->and</I
-> -encrypted
- message, first create a signed message, then encrypt the signed
- message with the recipients' certificates.
- </P
-><P
->You may generate key pairs and obtain certificates by using a
- commercial <I
-CLASS="EMPHASIS"
->certification authority</I
-> service.
- </P
-><P
->You can also do so using freely-available software. For many
- purposes, e.g., automated S/MIME messaging by system administration
- processes, this approach is cheap and effective.
- </P
-><P
->We now work through using OpenSSL to generate key pairs and
- certificates. This assumes you have OpenSSL installed properly on your
- system.
- </P
-><P
->First, we generate an X.509 certificate to be used for signing:
- </P
-><PRE
-CLASS="SCREEN"
-> <TT
-CLASS="USERINPUT"
-><B
->openssl req -newkey rsa:1024 -nodes -x509 -days 365 -out signer.pem
- </B
-></TT
->
- Using configuration from /usr/local/pkg/openssl/openssl.cnf
- Generating a 1024 bit RSA private key
- ..++++++
- ....................++++++
- writing new private key to 'privkey.pem'
- -----
- You are about to be asked to enter information that will be incorporated
- into your certificate request.
- What you are about to enter is what is called a Distinguished Name or a DN.
- There are quite a few fields but you can leave some blank
- For some fields there will be a default value,
- If you enter '.', the field will be left blank.
- -----
- Country Name (2 letter code) [AU]:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->SG</I
-></TT
-></B
-></TT
->
- State or Province Name (full name) [Some-State]:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->.</I
-></TT
-></B
-></TT
->
- Locality Name (eg, city) []:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->.</I
-></TT
-></B
-></TT
->
- Organization Name (eg, company) [Internet Widgits Pty Ltd]:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->M2Crypto</I
-></TT
-></B
-></TT
->
- Organizational Unit Name (eg, section) []:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->.</I
-></TT
-></B
-></TT
->
- Common Name (eg, YOUR name) []:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->S/MIME Sender</I
-></TT
-></B
-></TT
->
- Email Address []:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->sender@example.dom</I
-></TT
-></B
-></TT
->
- </PRE
-><P
->This generates a 1024-bit RSA key pair, unencrypted, into
- <TT
-CLASS="FILENAME"
->privkey.pem</TT
->; it also generates a self-signed X.509
- certificate for the public key into <TT
-CLASS="FILENAME"
->signer.pem</TT
->. The
- certificate is valid for 365 days, i.e., a year.
- </P
-><P
->Let's rename <TT
-CLASS="FILENAME"
->privkey.pem</TT
-> so that we know it is
- a companion of <TT
-CLASS="FILENAME"
->signer.pem</TT
->'s:
- </P
-><PRE
-CLASS="SCREEN"
-> <TT
-CLASS="USERINPUT"
-><B
->mv privkey.pem signer_key.pem</B
-></TT
->
- </PRE
-><P
->To verify the content of <TT
-CLASS="FILENAME"
->signer.pem</TT
->, execute the
- following:
- </P
-><PRE
-CLASS="SCREEN"
-> <TT
-CLASS="USERINPUT"
-><B
->openssl x509 -noout -text -in signer.pem
- </B
-></TT
->
- Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 0 (0x0)
- Signature Algorithm: md5WithRSAEncryption
- Issuer: C=SG, O=M2Crypto, CN=S/MIME Sender/Email=sender@example.dom
- Validity
- Not Before: Mar 24 12:56:16 2001 GMT
- Not After : Mar 24 12:56:16 2002 GMT
- Subject: C=SG, O=M2Crypto, CN=S/MIME Sender/Email=sender@example.dom
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- RSA Public Key: (1024 bit)
- Modulus (1024 bit):
- 00:a9:d6:e2:b5:11:3b:ae:3c:e2:17:31:70:e1:6e:
- 01:f4:19:6d:bd:2a:42:36:2b:37:34:e2:83:1d:0d:
- 11:2e:b4:99:44:db:10:67:be:97:5f:5b:1a:26:33:
- 46:23:2f:95:04:7a:35:da:9d:f9:26:88:39:9e:17:
- cd:3e:eb:a8:19:8d:a8:2a:f1:43:da:55:a9:2e:2c:
- 65:ed:04:71:42:ce:73:53:b8:ea:7e:c7:f0:23:c6:
- 63:c5:5e:68:96:64:a7:b4:2a:94:26:76:eb:79:ea:
- e3:4e:aa:82:09:4f:44:87:4a:12:62:b5:d7:1f:ca:
- f2:ce:d5:ba:7e:1f:48:fd:b9
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Subject Key Identifier:
- 29:FB:38:B6:BF:E2:40:BB:FF:D5:71:D7:D5:C4:F0:83:1A:2B:C7:99
- X509v3 Authority Key Identifier:
- keyid:29:FB:38:B6:BF:E2:40:BB:FF:D5:71:D7:D5:C4:F0:83:1A:2B:C7:99
- DirName:/C=SG/O=M2Crypto/CN=S/MIME Sender/Email=sender@example.dom
- serial:00
-
- X509v3 Basic Constraints:
- CA:TRUE
- Signature Algorithm: md5WithRSAEncryption
- 68:c8:6b:1b:fa:7c:9a:39:35:76:18:15:c9:fd:89:97:62:db:
- 7a:b0:2d:13:dd:97:e8:1b:7a:9f:22:27:83:24:9d:2e:56:ec:
- 97:89:3c:ef:16:55:80:5a:18:7c:22:d0:f6:bb:e3:a4:e8:59:
- 30:ff:99:5a:93:3e:ea:bc:ee:7f:8d:d6:7d:37:8c:ac:3d:74:
- 80:ce:7a:99:ba:27:b9:2a:a3:71:fa:a5:25:ba:47:17:df:07:
- 56:96:36:fd:60:b9:6c:96:06:e8:e3:7b:9f:4b:6a:95:71:a8:
- 34:fc:fc:b5:88:8b:c4:3f:1e:24:f6:52:47:b2:7d:44:67:d9:
- 83:e8
- </PRE
-><P
->Next, we generate a self-signed X.509 certificate for the
- recipient. Note that <TT
-CLASS="FILENAME"
->privkey.pem</TT
-> will be
- recreated.
- </P
-><PRE
-CLASS="SCREEN"
-> <TT
-CLASS="USERINPUT"
-><B
->openssl req -newkey rsa:1024 -nodes -x509 -days 365 -out recipient.pem
- </B
-></TT
->
- Using configuration from /usr/local/pkg/openssl/openssl.cnf
- Generating a 1024 bit RSA private key
- .....................................++++++
- .................++++++
- writing new private key to 'privkey.pem'
- -----
- You are about to be asked to enter information that will be incorporated
- into your certificate request.
- What you are about to enter is what is called a Distinguished Name or a DN.
- There are quite a few fields but you can leave some blank
- For some fields there will be a default value,
- If you enter '.', the field will be left blank.
- -----
- Country Name (2 letter code) [AU]:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->SG</I
-></TT
-></B
-></TT
->
- State or Province Name (full name) [Some-State]:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->.</I
-></TT
-></B
-></TT
->
- Locality Name (eg, city) []:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->.</I
-></TT
-></B
-></TT
->
- Organization Name (eg, company) [Internet Widgits Pty Ltd]:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->M2Crypto</I
-></TT
-></B
-></TT
->
- Organizational Unit Name (eg, section) []:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->.</I
-></TT
-></B
-></TT
->
- Common Name (eg, YOUR name) []:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->S/MIME Recipient</I
-></TT
-></B
-></TT
->
- Email Address []:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->recipient@example.dom</I
-></TT
-></B
-></TT
->
- </PRE
-><P
->Again, rename <TT
-CLASS="FILENAME"
->privkey.pem</TT
->:
- </P
-><PRE
-CLASS="SCREEN"
-> <TT
-CLASS="USERINPUT"
-><B
->mv privkey.pem recipient_key.pem</B
-></TT
->
- </PRE
-><P
->In the examples to follow, S/MIME Sender,
- <TT
-CLASS="EMAIL"
->&#60;<A
-HREF="mailto:sender@example.dom"
->sender@example.dom</A
->&#62;</TT
->, shall be the sender of S/MIME messages,
- while S/MIME Recipient, <TT
-CLASS="EMAIL"
->&#60;<A
-HREF="mailto:recipient@example.dom"
->recipient@example.dom</A
->&#62;</TT
->, shall be the
- recipient of S/MIME messages.
- </P
-><P
->Armed with the key pairs and certificates, we are now ready to begin
- programming S/MIME in Python.
- </P
-><DIV
-CLASS="NOTE"
-><BLOCKQUOTE
-CLASS="NOTE"
-><P
-><B
->Note: </B
->The private keys generated above are
- <I
-CLASS="EMPHASIS"
->not passphrase-protected</I
->, i.e., they are
- <I
-CLASS="EMPHASIS"
->in the clear</I
->. Anyone who has access to such a key can
- generate S/MIME-signed messages with it, and decrypt S/MIME messages
- encrypted to it's corresponding public key.
- </P
-><P
->We may passphrase-protect the keys, if we so choose. M2Crypto will
- prompt the user for the passphrase when such a key is being loaded.
- </P
-></BLOCKQUOTE
-></DIV
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="M2CRYPTO-SMIME"
->M2Crypto.SMIME</A
-></H1
-><P
->The Python programmer accesses M2Crypto's S/MIME functionality
- through class <TT
-CLASS="CLASSNAME"
->SMIME</TT
-> in the module
- <TT
-CLASS="CLASSNAME"
->M2Crypto.SMIME</TT
->. Typically, an <TT
-CLASS="CLASSNAME"
->SMIME</TT
->
- object is instantiated; the object is then set up for the intended
- operation: sign, encrypt, decrypt or verify; finally, the operation is invoked on
- the object.
- </P
-><P
-><TT
-CLASS="CLASSNAME"
->M2Crypto.SMIME</TT
-> makes extensive use of
- <TT
-CLASS="CLASSNAME"
->M2Crypto.BIO</TT
->: <TT
-CLASS="CLASSNAME"
->M2Crypto.BIO</TT
->
- is a Python abstraction of the <TT
-CLASS="CLASSNAME"
->BIO</TT
-> abstraction in
- OpenSSL. A commonly used <TT
-CLASS="CLASSNAME"
->BIO</TT
-> abstraction in M2Crypto is
- <TT
-CLASS="CLASSNAME"
->M2Crypto.BIO.MemoryBuffer</TT
->, which implements a
- memory-based file-like object, similar to Python's own
- <TT
-CLASS="CLASSNAME"
->StringIO</TT
->.
- </P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="SIGN"
->Sign</A
-></H1
-><P
->The following code demonstrates how to generate an S/MIME-signed
- message. <TT
-CLASS="FILENAME"
->randpool.dat</TT
-> contains random data which is
- used to seed OpenSSL's pseudo-random number generator via M2Crypto.
- </P
-><PRE
-CLASS="PROGRAMLISTING"
-> from M2Crypto import BIO, Rand, SMIME
-
- def makebuf(text):
- return BIO.MemoryBuffer(text)
-
- # Make a MemoryBuffer of the message.
- buf = makebuf('a sign of our times')
-
- # Seed the PRNG.
- Rand.load_file('randpool.dat', -1)
-
- # Instantiate an SMIME object; set it up; sign the buffer.
- s = SMIME.SMIME()
- s.load_key('signer_key.pem', 'signer.pem')
- p7 = s.sign(buf)
- </PRE
-><P
-><TT
-CLASS="VARNAME"
->p7</TT
-> now contains a <I
-CLASS="EMPHASIS"
->PKCS #7 signature
- blob</I
-> wrapped in an <TT
-CLASS="CLASSNAME"
->M2Crypto.SMIME.PKCS7</TT
->
- object. Note that <TT
-CLASS="VARNAME"
->buf</TT
-> has been consumed by
- <TT
-CLASS="FUNCTION"
->sign()</TT
-> and has to be recreated if it is to be used
- again.
- </P
-><P
->We may now send the signed message via SMTP. In these examples, we
- shall not do so; instead, we'll render the S/MIME output in
- mail-friendly format, and pretend that our messages are sent and
- received correctly.
- </P
-><PRE
-CLASS="PROGRAMLISTING"
-> # Recreate buf.
- buf = makebuf('a sign of our times')
-
- # Output p7 in mail-friendly format.
- out = BIO.MemoryBuffer()
- out.write('From: sender@example.dom\n')
- out.write('To: recipient@example.dom\n')
- out.write('Subject: M2Crypto S/MIME testing\n')
- s.write(out, p7, buf)
-
- print out.read()
-
- # Save the PRNG's state.
- Rand.save_file('randpool.dat')
- </PRE
-><P
->Here's the output:
- </P
-><PRE
-CLASS="SCREEN"
-> From: sender@example.dom
- To: recipient@example.dom
- Subject: M2Crypto S/MIME testing
- MIME-Version: 1.0
- Content-Type: multipart/signed ; protocol="application/x-pkcs7-signature" ; micalg=sha1 ; boundary="----3C93156FC7B4EBF49FE9C7DB7F503087"
-
- This is an S/MIME signed message
-
- ------3C93156FC7B4EBF49FE9C7DB7F503087
- a sign of our times
- ------3C93156FC7B4EBF49FE9C7DB7F503087
- Content-Type: application/x-pkcs7-signature; name="smime.p7s"
- Content-Transfer-Encoding: base64
- Content-Disposition: attachment; filename="smime.p7s"
-
- MIIE8AYJKoZIhvcNAQcCoIIE4TCCBN0CAQExCzAJBgUrDgMCGgUAMCIGCSqGSIb3
- DQEHAaAVBBNhIHNpZ24gb2Ygb3VyIHRpbWVzoIIC5zCCAuMwggJMoAMCAQICAQAw
- DQYJKoZIhvcNAQEEBQAwWzELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRv
- MRYwFAYDVQQDEw1TL01JTUUgU2VuZGVyMSEwHwYJKoZIhvcNAQkBFhJzZW5kZXJA
- ZXhhbXBsZS5kb20wHhcNMDEwMzMxMTE0MDMzWhcNMDIwMzMxMTE0MDMzWjBbMQsw
- CQYDVQQGEwJTRzERMA8GA1UEChMITTJDcnlwdG8xFjAUBgNVBAMTDVMvTUlNRSBT
- ZW5kZXIxITAfBgkqhkiG9w0BCQEWEnNlbmRlckBleGFtcGxlLmRvbTCBnzANBgkq
- hkiG9w0BAQEFAAOBjQAwgYkCgYEA5c5Tj1CHTSOxa1q2q0FYiwMWYHptJpJcvtZm
- UwrgU5sHrA8OnCM0cDXEj0KPf3cfNjHffB8HWMzI4UEgNmFXQNsxoGZ+iqwxLlNj
- y9Mh7eFW/Bjq5hNXbouSlQ0rWBRkoxV64y+t6lQehb32WfYXQbKFxFJSXzSxOx3R
- 8YhSPd0CAwEAAaOBtjCBszAdBgNVHQ4EFgQUXOyolL1t4jaBwZFRM7MS8nBLzUow
- gYMGA1UdIwR8MHqAFFzsqJS9beI2gcGRUTOzEvJwS81KoV+kXTBbMQswCQYDVQQG
- EwJTRzERMA8GA1UEChMITTJDcnlwdG8xFjAUBgNVBAMTDVMvTUlNRSBTZW5kZXIx
- ITAfBgkqhkiG9w0BCQEWEnNlbmRlckBleGFtcGxlLmRvbYIBADAMBgNVHRMEBTAD
- AQH/MA0GCSqGSIb3DQEBBAUAA4GBAHo3DrCHR86fSTVAvfiXdSswWqKtCEhUHRdC
- TLFGl4hDk2GyZxaFuqZwiURz/H7nMicymI2wkz8H/wyHFg8G3BIehURpj2v/ZWXY
- eovbgS7EZALVVkDj4hNl/IIHWd6Gtv1UODf7URbxtl3hQ9/eTWITrefT1heuPnar
- 8czydsOLMYIBujCCAbYCAQEwYDBbMQswCQYDVQQGEwJTRzERMA8GA1UEChMITTJD
- cnlwdG8xFjAUBgNVBAMTDVMvTUlNRSBTZW5kZXIxITAfBgkqhkiG9w0BCQEWEnNl
- bmRlckBleGFtcGxlLmRvbQIBADAJBgUrDgMCGgUAoIGxMBgGCSqGSIb3DQEJAzEL
- BgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTAxMDMzMTExNDUwMlowIwYJKoZI
- hvcNAQkEMRYEFOoeRUd8ExIYXfQq8BTFuKWrSP3iMFIGCSqGSIb3DQEJDzFFMEMw
- CgYIKoZIhvcNAwcwDgYIKoZIhvcNAwICAgCAMA0GCCqGSIb3DQMCAgFAMAcGBSsO
- AwIHMA0GCCqGSIb3DQMCAgEoMA0GCSqGSIb3DQEBAQUABIGAQpU8hFUtLCF6hO2t
- ec9EYJ/Imqqiiw+BxWxkUUVT81Vbjwdn9JST6+sztM5JRP2ZW+b4txEjZriYC8f3
- kv95YMTGbIsuWkJ93GrbvqoJ/CxO23r9WWRnZEm/1EZN9ZmlrYqzBTxnNRmP3Dhj
- cW8kzZwH+2/2zz2G7x1HxRWH95A=
-
- ------3C93156FC7B4EBF49FE9C7DB7F503087--
- </PRE
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="VERIFY"
->Verify</A
-></H1
-><P
->Assume the above output has been saved into <TT
-CLASS="FILENAME"
->sign.p7</TT
->.
- Let's now verify the signature:
- </P
-><PRE
-CLASS="PROGRAMLISTING"
-> from M2Crypto import SMIME, X509
-
- # Instantiate an SMIME object.
- s = SMIME.SMIME()
-
- # Load the signer's cert.
- x509 = X509.load_cert('signer.pem')
- sk = X509.X509_Stack()
- sk.push(x509)
- s.set_x509_stack(sk)
-
- # Load the signer's CA cert. In this case, because the signer's
- # cert is self-signed, it is the signer's cert itself.
- st = X509.X509_Store()
- st.load_info('signer.pem')
- s.set_x509_store(st)
-
- # Load the data, verify it.
- p7, data = SMIME.smime_load_pkcs7('sign.p7')
- v = s.verify(p7)
- print v
- print data
- print data.read()
- </PRE
-><P
->Here's the output of the above program:
- </P
-><PRE
-CLASS="SCREEN"
-> a sign of our times
- &lt;M2Crypto.BIO.BIO instance at 0x822012c&gt;
- a sign of our times
- </PRE
-><P
->Suppose, instead of loading <TT
-CLASS="FILENAME"
->signer.pem</TT
-> above,
- we load <TT
-CLASS="FILENAME"
->recipient.pem</TT
->. That is, we do a global
- substitution of <TT
-CLASS="LITERAL"
->recipient.pem</TT
-> for
- <TT
-CLASS="LITERAL"
->signer.pem</TT
-> in the above program. Here's the modified
- program's output:
- </P
-><PRE
-CLASS="SCREEN"
-> Traceback (most recent call last):
- File "./verify.py", line 22, in ?
- v = s.verify(p7)
- File "/usr/local/home/ngps/prog/m2/M2Crypto/SMIME.py", line 205, in verify
- raise SMIME_Error, Err.get_error()
- M2Crypto.SMIME.SMIME_Error: 312:error:21075075:PKCS7 routines:PKCS7_verify:certificate verify error:pk7_smime.c:213:Verify error:self signed certificate
- </PRE
-><P
->As displayed, the error is generated by line 213 of OpenSSL's
- <TT
-CLASS="FILENAME"
->pk7_smime.c</TT
-> (as of OpenSSL 0.9.6); if you are a
- C programmer, you may wish to look up the C source to explore OpenSSL's
- S/MIME implementation and understand why the error message is worded thus.
- </P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="ENCRYPT"
->Encrypt</A
-></H1
-><P
->We now demonstrate how to generate an S/MIME-encrypted message:
- </P
-><PRE
-CLASS="PROGRAMLISTING"
-> from M2Crypto import BIO, Rand, SMIME, X509
-
- def makebuf(text):
- return BIO.MemoryBuffer(text)
-
- # Make a MemoryBuffer of the message.
- buf = makebuf('a sign of our times')
-
- # Seed the PRNG.
- Rand.load_file('randpool.dat', -1)
-
- # Instantiate an SMIME object.
- s = SMIME.SMIME()
-
- # Load target cert to encrypt to.
- x509 = X509.load_cert('recipient.pem')
- sk = X509.X509_Stack()
- sk.push(x509)
- s.set_x509_stack(sk)
-
- # Set cipher: 3-key triple-DES in CBC mode.
- s.set_cipher(SMIME.Cipher('des_ede3_cbc'))
-
- # Encrypt the buffer.
- p7 = s.encrypt(buf)
-
- # Output p7 in mail-friendly format.
- out = BIO.MemoryBuffer()
- out.write('From: sender@example.dom\n')
- out.write('To: recipient@example.dom\n')
- out.write('Subject: M2Crypto S/MIME testing\n')
- s.write(out, p7)
-
- print out.read()
-
- # Save the PRNG's state.
- Rand.save_file('randpool.dat')
- </PRE
-><P
->Here's the output of the above program:
- </P
-><PRE
-CLASS="SCREEN"
-> From: sender@example.dom
- To: recipient@example.dom
- Subject: M2Crypto S/MIME testing
- MIME-Version: 1.0
- Content-Disposition: attachment; filename="smime.p7m"
- Content-Type: application/x-pkcs7-mime; name="smime.p7m"
- Content-Transfer-Encoding: base64
-
- MIIBVwYJKoZIhvcNAQcDoIIBSDCCAUQCAQAxggEAMIH9AgEAMGYwYTELMAkGA1UE
- BhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRkwFwYDVQQDExBTL01JTUUgUmVjaXBp
- ZW50MSQwIgYJKoZIhvcNAQkBFhVyZWNpcGllbnRAZXhhbXBsZS5kb20CAQAwDQYJ
- KoZIhvcNAQEBBQAEgYCBaXZ+qjpBEZwdP7gjfzfAtQitESyMwo3i+LBOw6sSDir6
- FlNDPCnkrTvqDX3Rt6X6vBtTCYOm+qiN7ujPkOU61cN7h8dvHR8YW9+0IPY80/W0
- lZ/HihSRgwTNd7LnxUUcPx8YV1id0dlmP0Hz+Lg+mHf6rqaR//JcYhX9vW4XvjA7
- BgkqhkiG9w0BBwEwFAYIKoZIhvcNAwcECMN+qya6ADywgBgHr9Jkhwn5Gsdu7BwX
- nIQfYTYcdL9I5Sk=
- </PRE
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="DECRYPT"
->Decrypt</A
-></H1
-><P
->Assume the above output has been saved into <TT
-CLASS="FILENAME"
->encrypt.p7</TT
->.
- Decrypt the message thusly:
- </P
-><PRE
-CLASS="PROGRAMLISTING"
-> from M2Crypto import BIO, SMIME, X509
-
- # Instantiate an SMIME object.
- s = SMIME.SMIME()
-
- # Load private key and cert.
- s.load_key('recipient_key.pem', 'recipient.pem')
-
- # Load the encrypted data.
- p7, data = SMIME.smime_load_pkcs7('encrypt.p7')
-
- # Decrypt p7.
- out = s.decrypt(p7)
-
- print out
- </PRE
-><P
->Here's the output:
- </P
-><PRE
-CLASS="SCREEN"
-> a sign of our times
- </PRE
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="SIGN-AND-ENCRYPT"
->Sign and Encrypt</A
-></H1
-><P
->Here's how to generate an S/MIME-signed/encrypted message:
- </P
-><PRE
-CLASS="PROGRAMLISTING"
-> from M2Crypto import BIO, Rand, SMIME, X509
-
- def makebuf(text):
- return BIO.MemoryBuffer(text)
-
- # Make a MemoryBuffer of the message.
- buf = makebuf('a sign of our times')
-
- # Seed the PRNG.
- Rand.load_file('randpool.dat', -1)
-
- # Instantiate an SMIME object.
- s = SMIME.SMIME()
-
- # Load signer's key and cert. Sign the buffer.
- s.load_key('signer_key.pem', 'signer.pem')
- p7 = s.sign(buf)
-
- # Load target cert to encrypt the signed message to.
- x509 = X509.load_cert('recipient.pem')
- sk = X509.X509_Stack()
- sk.push(x509)
- s.set_x509_stack(sk)
-
- # Set cipher: 3-key triple-DES in CBC mode.
- s.set_cipher(SMIME.Cipher('des_ede3_cbc'))
-
- # Create a temporary buffer.
- tmp = BIO.MemoryBuffer()
-
- # Write the signed message into the temporary buffer.
- s.write(tmp, p7, buf)
-
- # Encrypt the temporary buffer.
- p7 = s.encrypt(tmp)
-
- # Output p7 in mail-friendly format.
- out = BIO.MemoryBuffer()
- out.write('From: sender@example.dom\n')
- out.write('To: recipient@example.dom\n')
- out.write('Subject: M2Crypto S/MIME testing\n')
- s.write(out, p7)
-
- print out.read()
-
- # Save the PRNG's state.
- Rand.save_file('randpool.dat')
- </PRE
-><P
->Here's the output of the above program:
- </P
-><PRE
-CLASS="SCREEN"
-> From: sender@example.dom
- To: recipient@example.dom
- Subject: M2Crypto S/MIME testing
- MIME-Version: 1.0
- Content-Disposition: attachment; filename="smime.p7m"
- Content-Type: application/x-pkcs7-mime; name="smime.p7m"
- Content-Transfer-Encoding: base64
-
- MIIIwwYJKoZIhvcNAQcDoIIItDCCCLACAQAxggEAMIH9AgEAMGYwYTELMAkGA1UE
- BhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRkwFwYDVQQDExBTL01JTUUgUmVjaXBp
- ZW50MSQwIgYJKoZIhvcNAQkBFhVyZWNpcGllbnRAZXhhbXBsZS5kb20CAQAwDQYJ
- KoZIhvcNAQEBBQAEgYBlZlGupFphwhsGtIAPvDExN61qisz3oem88xoXkUW0SzoR
- B9zJFFAuQTWzdNJgrKKYikhWjDojaAc/PFl1K5dYxRgtZLB36ULJD/v/yWmxnjz8
- TvtK+Wbal2P/MH2pZ4LVERXa/snTElhCawUlwtiFz/JvY5CiF/dcwd+AwFQq4jCC
- B6UGCSqGSIb3DQEHATAUBggqhkiG9w0DBwQIRF525UfwszaAggeA85RmX6AXQMxb
- eBDz/LJeCgc3RqU1UwIsbKMquIs1S46Ebbm5nP75izPnujOkJ2hv+LNzqOWADmOl
- +CnGEq1qxTyduIgUDA2nBgCL/gVyVy+/XC9dtImUUTxtxLgYtB0ujkBNsOaENOlM
- fv4SGM3jkR+K/xlYG6HHzZGbfYyNGj2Y7yMZ1rL1m8SnRNmkCysKGTrudeNf6wT9
- J6wO9DzLTioz3ZnVr3LjsSKIb4tIp4ugqNJaLuW7m3FtZ3MAgxN68hBbJs8TZ8tL
- V/0jwUqS+grcgZEb9ymfcedxahtDUfHjRkpDpsxZzVVGkSBNcbQu92oByQVnRQ8m
- wrYLp3/eawM5AvuV7HNpTT5ZR+1t8luishHN9899IMP2Vyg0Ub67FqFypYmM2cm2
- sjAI4KpfvT00XFNvgLuYwYEKs9syGTO7hiHNQKcF44F5LYv6nTFwmFQB11dAtY9V
- ull4D2CLDx9OvyNyKwdEZB5dyV0r/uKIdkhST60V2Q9KegpzgFpoZtSKM/HPYSVH
- 1Bc9f3Q/GqZCvNZZCMx8UvRjQR8dRWDSmPJ0VXG1+wJ+fCmSPP3AuQ1/VsgPRqx2
- 56VrpGPpGut40hV8xQFbWIZ2whwWLKPFAHj8B79ZtFUzUrU6Z2rNpvv8inHc/+S/
- b6GR5s8/gucRblvd7n3OFNX5UJmPmcw9zWbu/1Dr9DY8l0nAQh21y5FGSS8B1wdE
- oD2M3Lp7JbwjQbRtnDhImqul2S4yu+m+wDD1aR2K4k3GAI7KKgOBWT0+BDClcn8A
- 4Ju6/YUbj33YlMPJgnGijLnolFy0hNW7TmWqR+8tSI3wO5eNKg4qwBnarqc3vgCV
- quVxINAXyGQCO9lzdw6hudk8/+BlweGdqhONaIWbK5z1L/SfQo6LC9MTsj7FJydq
- bc+kEbfZS8aSq7uc9axW6Ti0eAPJ8EVHtwhSBgZQRweKFBXs6HbbhMIdc4N0M7Oq
- UiFXaF6s4n2uihVP6TqXtHEjTpZoC7pC+HCYiuKXUJtaqtXBOh+y3KLvHk09YL6D
- XmTDg+UTiFsh4jKKm/BhdelbR5JbpJcj5AId76Mfr8+F/1g9ePOvsWHpQr/oIQTo
- xEkaxCmzEgP0b6caMWfMUQrbVGxBBNcqKc/ir9fGGOPHATzzq/xLcQYvK1tZhd/D
- ah/gpMPndsyvVCEuFPluWyDiM0VkwHgC2/3pJIYFHaxK64IutmPsy393rHMEB4kN
- AHau6kWK+yL9qEVH1pP2zvswQ12P7gjt3T/G3bGsmvlXkEfztfjkXo6XnjcBNf5y
- G+974AKLcjnk1gzIgarz+lAMY57Gkw4oNDMrTqVQ2OJQlvOSbllPXzH+aAiavB8W
- ZPECLLwHxD4B1AuaiAArgKl935u/TOB+yQOR8JgGsUzROyJqHJ/SC51HkebgCkL1
- aggtjgPlIBEXLZAlhpWLZ9lAQyrQpvCVJYwaOvfMmvRav4NAFNoZ2/Q7S4Tn1z+U
- XX+f+GD58P4MPMhU5IKnz4yH4nlHnAiTEvcs85TZUAXze9g/uBOwZITeGtyLi52S
- aETIr4v7SgXMepX7ThQ1Pv/jddsK/u4j2F34u0XktwCP+UrbfkE2mocdXvdzxbmd
- tZSznK2qwgVSsPOs9MhUaepbnjmNBFFBrULhrUtSglM/VX/rWNiyh0aw4XYyHhIt
- 9ZNlfEjKjJ67VEMBxBJ/ieUCouRGCxPYD1j65VT7oB3ZiyPu2F2nlUIcYNqPg1Sd
- QBCrdaOXdJ0uLwyTAUeVE+wMbgscLvWsfZcCCJHAvw9NHFMUcnrdWxAYMVETNUOn
- uryVAK7VfOldaz6z3NOSOi6nonNeHpR/sipBa4ik5xCRLT9e0S2QJgRvO9GyfAqz
- 3DIzHtxIGePFzTiUYUTxS3i2gnMX2PEe3ChTLlYWD3jNeAKz0iOzpDphIF2xHLLQ
- 1tCAqBmq/vUzALyDFFdFuTIqQZys4z/u4Dmyq9uXs421eN3v2hkVHvDy8uT2Ot29
- lg4Q5YezR1EjaW//9guL1BXbcKrTEdtxeNqtem7SpZOMTSwD2lhB8z65GrX90Cyt
- EMmaRSGYEdf5h1afL1SmKOMskbqxe1D2jG/vsXC7XX7xO/ioy0BdiJcYN1JiMOHJ
- EOzFol5I20YkiV6j+cenfQFwc/NkaSxEkR8AUHJSbvUmRQRl6r0nnsFpZdR1w7pv
- wkaT+eOpZynO4mY/ZtF6MpXJsixi6L4ZYXEbS6yHf+XGFfB0okILylmwv2bf6+Mq
- nqXlmGj3Jwq7X9/+2BDqvfpFFX5lSmItKZAobLdssjFR6roJxOqRsGia2aZ+0+U5
- VhgdITtnElgtHBaeZU5rHDswgdeLVBP+rGWnKxpJ+pLtNNi25sPYRcWFL6Erd25u
- eXiY8GEIr+u7rqBWpc9HR34sAPRs3ubbCUleT748keCbx247ImBtiDctZxcc1O86
- +0QjHP6HUT7FSo/FmT7a120S3Gd2jixGh06l/9ij5Z6mJa7Rm7TTbSjup/XISnOT
- MKWcbI1nfVOhCv3xDq2eLae+s0oVoc041ceRazqFM2TL/Z6UXRME
- </PRE
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="DECRYPT-AND-VERIFY"
->Decrypt and Verify</A
-></H1
-><P
->Suppose the above output has been saved into
- <TT
-CLASS="FILENAME"
->se.p7</TT
->. The following demonstrates how to decrypt and
- verify it:
- </P
-><PRE
-CLASS="PROGRAMLISTING"
-> from M2Crypto import BIO, SMIME, X509
-
- # Instantiate an SMIME object.
- s = SMIME.SMIME()
-
- # Load private key and cert.
- s.load_key('recipient_key.pem', 'recipient.pem')
-
- # Load the signed/encrypted data.
- p7, data = SMIME.smime_load_pkcs7('se.p7')
-
- # After the above step, 'data' == None.
- # Decrypt p7. 'out' now contains a PKCS #7 signed blob.
- out = s.decrypt(p7)
-
- # Load the signer's cert.
- x509 = X509.load_cert('signer.pem')
- sk = X509.X509_Stack()
- sk.push(x509)
- s.set_x509_stack(sk)
-
- # Load the signer's CA cert. In this case, because the signer's
- # cert is self-signed, it is the signer's cert itself.
- st = X509.X509_Store()
- st.load_info('signer.pem')
- s.set_x509_store(st)
-
- # Recall 'out' contains a PKCS #7 blob.
- # Transform 'out'; verify the resulting PKCS #7 blob.
- p7_bio = BIO.MemoryBuffer(out)
- p7, data = SMIME.smime_load_pkcs7_bio(p7_bio)
- v = s.verify(p7)
-
- print v
- </PRE
-><P
->The output is as follows:
- </P
-><PRE
-CLASS="SCREEN"
-> a sign of our times
- </PRE
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="SMTP"
->Sending S/MIME messages via SMTP</A
-></H1
-><P
->In the above examples, we've assumed that our S/MIME messages
- are sent and received automagically. The following is a Python function that
- generates S/MIME-signed/encrypted messages and sends them via SMTP:
- </P
-><PRE
-CLASS="PROGRAMLISTING"
-> from M2Crypto import BIO, SMIME, X509
- import smtplib, string, sys
-
- def sendsmime(from_addr, to_addrs, subject, msg, from_key, from_cert=None, to_certs=None, smtpd='localhost'):
-
- msg_bio = BIO.MemoryBuffer(msg)
- sign = from_key
- encrypt = to_certs
-
- s = SMIME.SMIME()
- if sign:
- s.load_key(from_key, from_cert)
- p7 = s.sign(msg_bio, flags=SMIME.PKCS7_TEXT)
- msg_bio = BIO.MemoryBuffer(msg) # Recreate coz sign() has consumed it.
-
- if encrypt:
- sk = X509.X509_Stack()
- for x in to_certs:
- sk.push(X509.load_cert(x))
- s.set_x509_stack(sk)
- s.set_cipher(SMIME.Cipher('des_ede3_cbc'))
- tmp_bio = BIO.MemoryBuffer()
- if sign:
- s.write(tmp_bio, p7)
- else:
- tmp_bio.write(msg)
- p7 = s.encrypt(tmp_bio)
-
- out = BIO.MemoryBuffer()
- out.write('From: %s\r\n' % from_addr)
- out.write('To: %s\r\n' % string.join(to_addrs, ", "))
- out.write('Subject: %s\r\n' % subject)
- if encrypt:
- s.write(out, p7)
- else:
- if sign:
- s.write(out, p7, msg_bio, SMIME.PKCS7_TEXT)
- else:
- out.write('\r\n')
- out.write(msg)
- out.close()
-
- smtp = smtplib.SMTP()
- smtp.connect(smtpd)
- smtp.sendmail(from_addr, to_addrs, out.read())
- smtp.quit()
- </PRE
-><P
->This function sends plain, S/MIME-signed, S/MIME-encrypted,
- and S/MIME-signed/encrypted messages, depending on the parameters
- <TT
-CLASS="PARAMETER"
-><I
->from_key</I
-></TT
-> and <TT
-CLASS="PARAMETER"
-><I
->to_certs</I
-></TT
->. The
- function's output interoperates with Netscape Messenger.
- </P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="VERIFYING-ORIGIN"
->Verifying origin of S/MIME messages</A
-></H1
-><P
->In our examples above that decrypt or verify messages, we skipped
- a step: verifying that the <TT
-CLASS="LITERAL"
->from</TT
-> address of the message
- matches the <TT
-CLASS="LITERAL"
->email address</TT
-> attribute in the sender's
- certificate.
- </P
-><P
->The premise of current X.509 certification practice is that the
- CA is supposed to verify your identity, and to issue a certificate with
- <TT
-CLASS="LITERAL"
->email address</TT
-> that matches your actual mail address.
- (Verisign's March 2001 failure in identity verification resulting in
- Microsoft certificates being issued to spoofers notwithstanding.)
- </P
-><P
->If you run your own CA, your certification practice is up to you, of
- course, and it would probably be part of your security policy.
- </P
-><P
->Whether your S/MIME messaging application needs to verify the
- <TT
-CLASS="LITERAL"
->from</TT
-> addresses of S/MIME messages depends on your
- security policy and your system's threat model, as always.
- </P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="NETSCAPE-MESSENGER"
->Interoperating with Netscape Messenger</A
-></H1
-><P
->Suppose S/MIME Recipient uses Netscape Messenger. To enable Messenger
- to handle S/MIME messages from S/MIME Sender, S/MIME Recipient needs
- to configure Messenger with his private key and certificate, as well as S/MIME
- Sender's certificate.
- </P
-><DIV
-CLASS="NOTE"
-><BLOCKQUOTE
-CLASS="NOTE"
-><P
-><B
->Note: </B
->Configuring Messenger's POP or IMAP settings so that it retrieves
- mail correctly is beyond the scope of this HOWTO.
- </P
-></BLOCKQUOTE
-></DIV
-><P
->The following steps demonstrate how to import S/MIME Recipient's
- private key and certificate for Messenger:
- </P
-><DIV
-CLASS="PROCEDURE"
-><OL
-TYPE="1"
-><LI
-><P
->Transform S/MIME Recipient's private key and certificate into
- <I
-CLASS="EMPHASIS"
->PKCS #12</I
-> format.
- </P
-><PRE
-CLASS="SCREEN"
-> <TT
-CLASS="USERINPUT"
-><B
->openssl pkcs12 -export -in recipient.pem -inkey recipient_key.pem -name "S/MIME Recipient" -out recipient.p12
- </B
-></TT
->
- Enter Export Password:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->&lt;enter&gt;</I
-></TT
-></B
-></TT
->
- Verifying password - Enter Export Password:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->&lt;enter&gt;</I
-></TT
-></B
-></TT
->
- </PRE
-></LI
-><LI
-><P
->Start Messenger.
- </P
-></LI
-><LI
-><P
->Click on the (open) "lock" icon at the bottom left corner of
- Messenger's window. This brings up the "Security Info" dialog box.
- </P
-></LI
-><LI
-><P
->Click on "Yours" under "Certificates".
- </P
-></LI
-><LI
-><P
->Select "Import a certificate", then pick
- <TT
-CLASS="FILENAME"
->recipient.p12</TT
-> from the ensuing file selection dialog
- box.
- </P
-></LI
-></OL
-></DIV
-><P
->Next, you need to import <TT
-CLASS="FILENAME"
->signer.pem</TT
-> as a CA
- certificate, so that Messenger will mark messages signed by S/MIME Sender as
- "trusted":
- </P
-><DIV
-CLASS="PROCEDURE"
-><OL
-TYPE="1"
-><LI
-><P
->Create a DER encoding of <TT
-CLASS="FILENAME"
->signer.pem</TT
->.
- </P
-><PRE
-CLASS="SCREEN"
-> <TT
-CLASS="USERINPUT"
-><B
->openssl x509 -inform pem -outform der -in signer.pem -out signer.der
- </B
-></TT
->
- </PRE
-></LI
-><LI
-><P
->Install <TT
-CLASS="FILENAME"
->signer.der</TT
-> into Messenger as MIME type
- <TT
-CLASS="LITERAL"
->application/x-x509-ca-cert</TT
->. You do this by downloading
- <TT
-CLASS="FILENAME"
->signer.der</TT
-> via Navigator from a HTTP or HTTPS server,
- with the correct MIME type mapping. (You may use
- <TT
-CLASS="FILENAME"
->demo/ssl/https_srv.py</TT
->, bundled with M2Crypto, for
- this purpose.) Follow the series of dialog boxes to accept
- <TT
-CLASS="FILENAME"
->signer.der</TT
-> as a CA for certifying email users.
- </P
-></LI
-></OL
-></DIV
-><P
->S/MIME Recipient is now able to decrypt and read S/MIME Sender's
- messages with Messenger. Messenger will indicate that S/MIME Sender's
- messages are signed, encrypted, or encrypted <I
-CLASS="EMPHASIS"
->and</I
->
- signed, as the case may be, via the "stamp" icon on the message window's
- top right corner.
- </P
-><P
->Clicking on the "stamp" icon brings you to the Security Info dialog
- box. Messenger informs you that the message is, say, encrypted with
- 168-bit DES-EDE3-CBC and that it is digitally signed by the private key
- corresponding to the public key contained in the certificate
- <TT
-CLASS="FILENAME"
->signer.pem</TT
->.
- </P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="MICROSOFT-OUTLOOK"
->Interoperating with Microsoft Outlook</A
-></H1
-><P
->I do not know how to do this, as I do not use Outlook. (Nor do I use
- Netscape Messenger, actually. I use Mutt, top dog of MUAs. ;-) Information on
- how to configure Outlook with keys and certificates so that it handles
- S/MIME mail is gratefully accepted.
- </P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="ZSMIME"
->ZSmime</A
-></H1
-><P
->ZSmime is a <A
-HREF="http://www.zope.org"
-TARGET="_top"
->Zope</A
->
- <I
-CLASS="EMPHASIS"
->product</I
-> that enables Zope to generate
- S/MIME-signed/encrypted messages. ZSmime demonstrates how to invoke
- M2Crypto in a web application server extension.
- </P
-><P
->ZSmime has its own <A
-HREF="http://sandbox.rulemaker.net/ngps/zope/zsmime/howto.html"
-TARGET="_top"
->HOWTO</A
->
- explaining its usage. (That HOWTO has some overlap in content with
- this document.)
- </P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="RESOURCES"
->Resources</A
-></H1
-><P
-></P
-><UL
-><LI
-STYLE="list-style-type: opencircle"
-><P
->IETF S/MIME Working Group -
- <A
-HREF="http://www.imc.org/ietf-smime"
-TARGET="_top"
-> http://www.imc.org/ietf-smime</A
->
- </P
-></LI
-><LI
-STYLE="list-style-type: opencircle"
-><P
->S/MIME and OpenPGP -
- <A
-HREF="http://www.imc.org/smime-pgpmime.html"
-TARGET="_top"
-> http://www.imc.org/smime-pgpmime.html</A
->
- </P
-></LI
-><LI
-STYLE="list-style-type: opencircle"
-><P
->S/MIME Freeware Library -
- <A
-HREF="http://www.getronicsgov.com/hot/sfl_home.htm"
-TARGET="_top"
-> http://www.getronicsgov.com/hot/sfl_home.htm</A
->
- </P
-></LI
-><LI
-STYLE="list-style-type: opencircle"
-><P
->Mozilla Network Security Services -
- <A
-HREF="http://www.mozilla.org/projects/security/pkg/nss"
-TARGET="_top"
-> http://www.mozilla.org/projects/security/pkg/nss</A
->
- </P
-></LI
-><LI
-STYLE="list-style-type: opencircle"
-><P
->S/MIME Cracking Screen Saver -
- <A
-HREF="http://www.counterpane.com/smime.html"
-TARGET="_top"
-> http://www.counterpane.com/smime.html</A
->
- </P
-></LI
-></UL
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="ID-KLUDGE"
-></A
-></H1
-><P
-> <TT
-CLASS="LITERAL"
->$Id:howto.smime.html 583 2007-10-01 19:23:12Z heikki $</TT
->
- </P
-></DIV
-></DIV
-></BODY
-></HTML
-> \ No newline at end of file
diff --git a/doc/howto.smime.rst b/doc/howto.smime.rst
new file mode 100644
index 0000000..715e7c4
--- /dev/null
+++ b/doc/howto.smime.rst
@@ -0,0 +1,778 @@
+:orphan:
+
+.. _howto-smime:
+
+HOWTO: Programming S/MIME in Python with M2Crypto
+=================================================
+
+:author: Pheng Siong Ng <ngps@post1.com>
+:copyright: © 2000, 2001 by Ng Pheng Siong.
+
+Introduction
+============
+
+`M2Crypto <https://gitlab.com/m2crypto/m2crypto/>`__ is a
+`Python <http://www.python.org>`__ interface to
+`OpenSSL <http://www.openssl.org>`__. It makes available to the Python
+programmer SSL functionality to implement clients and servers, S/MIME
+v2, RSA, DSA, DH, symmetric ciphers, message digests and HMACs.
+
+This document demonstrates programming S/MIME with M2Crypto.
+
+S/MIME
+======
+
+S/MIME - Secure Multipurpose Internet Mail Extensions [RFC 2311, RFC
+2312] - provides a consistent way to send and receive secure MIME data.
+Based on the popular Internet MIME standard, S/MIME provides the
+following cryptographic security services for electronic messaging
+applications - *authentication*, *message integrity* and
+*non-repudiation of origin* (using *digital signatures*), and *privacy*
+and *data security* (using *encryption*).
+
+Keys and Certificates
+=====================
+
+To create an S/MIME-signed message, you need an RSA key pair (this
+consists of a public key and a private key) and an X.509 certificate of
+said public key.
+
+To create an S/MIME-encrypted message, you need an X.509 certificate for
+each recipient.
+
+To create an S/MIME-signed *and* -encrypted message, first create a
+signed message, then encrypt the signed message with the recipients'
+certificates.
+
+You may generate key pairs and obtain certificates by using a commercial
+*certification authority* service.
+
+You can also do so using freely-available software. For many purposes,
+e.g., automated S/MIME messaging by system administration processes,
+this approach is cheap and effective.
+
+We now work through using OpenSSL to generate key pairs and
+certificates. This assumes you have OpenSSL installed properly on your
+system.
+
+First, we generate an X.509 certificate to be used for signing::
+
+ openssl req -newkey rsa:1024 -nodes -x509 -days 365 -out signer.pem
+
+ Using configuration from /usr/local/pkg/openssl/openssl.cnf
+ Generating a 1024 bit RSA private key
+ ..++++++
+ ....................++++++
+ writing new private key to 'privkey.pem'
+ -----
+ You are about to be asked to enter information that will be incorporated
+ into your certificate request.
+ What you are about to enter is what is called a Distinguished Name or a DN.
+ There are quite a few fields but you can leave some blank
+ For some fields there will be a default value,
+ If you enter '.', the field will be left blank.
+ -----
+ Country Name (2 letter code) [AU]:SG
+ State or Province Name (full name) [Some-State]:.
+ Locality Name (eg, city) []:.
+ Organization Name (eg, company) [Internet Widgits Pty Ltd]:M2Crypto
+ Organizational Unit Name (eg, section) []:.
+ Common Name (eg, YOUR name) []:S/MIME Sender
+ Email Address []:sender@example.dom
+
+
+This generates a 1024-bit RSA key pair, unencrypted, into
+``privkey.pem``; it also generates a self-signed X.509 certificate for
+the public key into ``signer.pem``. The certificate is valid for 365
+days, i.e., a year.
+
+Let's rename ``privkey.pem`` so that we know it is a companion of
+``signer.pem``'s::
+
+ mv privkey.pem signer_key.pem
+
+To verify the content of ``signer.pem``, execute the following::
+
+ openssl x509 -noout -text -in signer.pem
+
+ Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 0 (0x0)
+ Signature Algorithm: md5WithRSAEncryption
+ Issuer: C=SG, O=M2Crypto, CN=S/MIME Sender/Email=sender@example.dom
+ Validity
+ Not Before: Mar 24 12:56:16 2001 GMT
+ Not After : Mar 24 12:56:16 2002 GMT
+ Subject: C=SG, O=M2Crypto, CN=S/MIME Sender/Email=sender@example.dom
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public Key: (1024 bit)
+ Modulus (1024 bit):
+ 00:a9:d6:e2:b5:11:3b:ae:3c:e2:17:31:70:e1:6e:
+ 01:f4:19:6d:bd:2a:42:36:2b:37:34:e2:83:1d:0d:
+ 11:2e:b4:99:44:db:10:67:be:97:5f:5b:1a:26:33:
+ 46:23:2f:95:04:7a:35:da:9d:f9:26:88:39:9e:17:
+ cd:3e:eb:a8:19:8d:a8:2a:f1:43:da:55:a9:2e:2c:
+ 65:ed:04:71:42:ce:73:53:b8:ea:7e:c7:f0:23:c6:
+ 63:c5:5e:68:96:64:a7:b4:2a:94:26:76:eb:79:ea:
+ e3:4e:aa:82:09:4f:44:87:4a:12:62:b5:d7:1f:ca:
+ f2:ce:d5:ba:7e:1f:48:fd:b9
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 29:FB:38:B6:BF:E2:40:BB:FF:D5:71:D7:D5:C4:F0:83:1A:2B:C7:99
+ X509v3 Authority Key Identifier:
+ keyid:29:FB:38:B6:BF:E2:40:BB:FF:D5:71:D7:D5:C4:F0:83:1A:2B:C7:99
+ DirName:/C=SG/O=M2Crypto/CN=S/MIME Sender/Email=sender@example.dom
+ serial:00
+
+ X509v3 Basic Constraints:
+ CA:TRUE
+ Signature Algorithm: md5WithRSAEncryption
+ 68:c8:6b:1b:fa:7c:9a:39:35:76:18:15:c9:fd:89:97:62:db:
+ 7a:b0:2d:13:dd:97:e8:1b:7a:9f:22:27:83:24:9d:2e:56:ec:
+ 97:89:3c:ef:16:55:80:5a:18:7c:22:d0:f6:bb:e3:a4:e8:59:
+ 30:ff:99:5a:93:3e:ea:bc:ee:7f:8d:d6:7d:37:8c:ac:3d:74:
+ 80:ce:7a:99:ba:27:b9:2a:a3:71:fa:a5:25:ba:47:17:df:07:
+ 56:96:36:fd:60:b9:6c:96:06:e8:e3:7b:9f:4b:6a:95:71:a8:
+ 34:fc:fc:b5:88:8b:c4:3f:1e:24:f6:52:47:b2:7d:44:67:d9:
+ 83:e8
+
+Next, we generate a self-signed X.509 certificate for the recipient.
+Note that ``privkey.pem`` will be recreated::
+
+ openssl req -newkey rsa:1024 -nodes -x509 -days 365 -out recipient.pem
+
+ Using configuration from /usr/local/pkg/openssl/openssl.cnf
+ Generating a 1024 bit RSA private key
+ .....................................++++++
+ .................++++++
+ writing new private key to 'privkey.pem'
+ -----
+ You are about to be asked to enter information that will be incorporated
+ into your certificate request.
+ What you are about to enter is what is called a Distinguished Name or a DN.
+ There are quite a few fields but you can leave some blank
+ For some fields there will be a default value,
+ If you enter '.', the field will be left blank.
+ -----
+ Country Name (2 letter code) [AU]:SG
+ State or Province Name (full name) [Some-State]:.
+ Locality Name (eg, city) []:.
+ Organization Name (eg, company) [Internet Widgits Pty Ltd]:M2Crypto
+ Organizational Unit Name (eg, section) []:.
+ Common Name (eg, YOUR name) []:S/MIME Recipient
+ Email Address []:recipient@example.dom
+
+Again, rename ``privkey.pem``::
+
+ mv privkey.pem recipient_key.pem
+
+
+In the examples to follow, S/MIME Sender, ``<sender@example.dom>``,
+shall be the sender of S/MIME messages, while S/MIME Recipient,
+``<recipient@example.dom>``, shall be the recipient of S/MIME messages.
+
+Armed with the key pairs and certificates, we are now ready to begin
+programming S/MIME in Python.
+
+ **Note:** The private keys generated above are *not
+ passphrase-protected*, i.e., they are *in the clear*. Anyone who has
+ access to such a key can generate S/MIME-signed messages with it,
+ and decrypt S/MIME messages encrypted to it's corresponding public
+ key.
+
+ We may passphrase-protect the keys, if we so choose. M2Crypto will
+ prompt the user for the passphrase when such a key is being loaded.
+
+M2Crypto.SMIME
+==============
+
+The Python programmer accesses M2Crypto's S/MIME functionality through
+class ``SMIME`` in the module ``M2Crypto.SMIME``. Typically, an
+``SMIME`` object is instantiated; the object is then set up for the
+intended operation: sign, encrypt, decrypt or verify; finally, the
+operation is invoked on the object.
+
+``M2Crypto.SMIME`` makes extensive use of ``M2Crypto.BIO``:
+``M2Crypto.BIO`` is a Python abstraction of the ``BIO`` abstraction in
+OpenSSL. A commonly used ``BIO`` abstraction in M2Crypto is
+``M2Crypto.BIO.MemoryBuffer``, which implements a memory-based file-like
+object, similar to Python's own ``StringIO``.
+
+Sign
+====
+
+The following code demonstrates how to generate an S/MIME-signed
+message. ``randpool.dat`` contains random data which is used to seed
+OpenSSL's pseudo-random number generator via M2Crypto::
+
+ from M2Crypto import BIO, Rand, SMIME
+
+ def makebuf(text):
+ return BIO.MemoryBuffer(text)
+
+ # Make a MemoryBuffer of the message.
+ buf = makebuf('a sign of our times')
+
+ # Seed the PRNG.
+ Rand.load_file('randpool.dat', -1)
+
+ # Instantiate an SMIME object; set it up; sign the buffer.
+ s = SMIME.SMIME()
+ s.load_key('signer_key.pem', 'signer.pem')
+ p7 = s.sign(buf, SMIME.PKCS7_DETACHED)
+
+
+``p7`` now contains a *PKCS #7 signature blob* wrapped in an
+``M2Crypto.SMIME.PKCS7`` object. Note that ``buf`` has been consumed by
+``sign()`` and has to be recreated if it is to be used again.
+
+We may now send the signed message via SMTP. In these examples, we shall
+not do so; instead, we'll render the S/MIME output in mail-friendly
+format, and pretend that our messages are sent and received
+correctly::
+
+ # Recreate buf.
+ buf = makebuf('a sign of our times')
+
+ # Output p7 in mail-friendly format.
+ out = BIO.MemoryBuffer()
+ out.write('From: sender@example.dom\n')
+ out.write('To: recipient@example.dom\n')
+ out.write('Subject: M2Crypto S/MIME testing\n')
+ s.write(out, p7, buf)
+
+ print(out.read())
+
+ # Save the PRNG's state.
+ Rand.save_file('randpool.dat')
+
+Here's the output::
+
+ From: sender@example.dom
+ To: recipient@example.dom
+ Subject: M2Crypto S/MIME testing
+ MIME-Version: 1.0
+ Content-Type: multipart/signed ; protocol="application/x-pkcs7-signature" ; micalg=sha1 ; boundary="----3C93156FC7B4EBF49FE9C7DB7F503087"
+
+ This is an S/MIME signed message
+
+ ------3C93156FC7B4EBF49FE9C7DB7F503087
+ a sign of our times
+ ------3C93156FC7B4EBF49FE9C7DB7F503087
+ Content-Type: application/x-pkcs7-signature; name="smime.p7s"
+ Content-Transfer-Encoding: base64
+ Content-Disposition: attachment; filename="smime.p7s"
+
+ MIIE8AYJKoZIhvcNAQcCoIIE4TCCBN0CAQExCzAJBgUrDgMCGgUAMCIGCSqGSIb3
+ DQEHAaAVBBNhIHNpZ24gb2Ygb3VyIHRpbWVzoIIC5zCCAuMwggJMoAMCAQICAQAw
+ DQYJKoZIhvcNAQEEBQAwWzELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRv
+ MRYwFAYDVQQDEw1TL01JTUUgU2VuZGVyMSEwHwYJKoZIhvcNAQkBFhJzZW5kZXJA
+ ZXhhbXBsZS5kb20wHhcNMDEwMzMxMTE0MDMzWhcNMDIwMzMxMTE0MDMzWjBbMQsw
+ CQYDVQQGEwJTRzERMA8GA1UEChMITTJDcnlwdG8xFjAUBgNVBAMTDVMvTUlNRSBT
+ ZW5kZXIxITAfBgkqhkiG9w0BCQEWEnNlbmRlckBleGFtcGxlLmRvbTCBnzANBgkq
+ hkiG9w0BAQEFAAOBjQAwgYkCgYEA5c5Tj1CHTSOxa1q2q0FYiwMWYHptJpJcvtZm
+ UwrgU5sHrA8OnCM0cDXEj0KPf3cfNjHffB8HWMzI4UEgNmFXQNsxoGZ+iqwxLlNj
+ y9Mh7eFW/Bjq5hNXbouSlQ0rWBRkoxV64y+t6lQehb32WfYXQbKFxFJSXzSxOx3R
+ 8YhSPd0CAwEAAaOBtjCBszAdBgNVHQ4EFgQUXOyolL1t4jaBwZFRM7MS8nBLzUow
+ gYMGA1UdIwR8MHqAFFzsqJS9beI2gcGRUTOzEvJwS81KoV+kXTBbMQswCQYDVQQG
+ EwJTRzERMA8GA1UEChMITTJDcnlwdG8xFjAUBgNVBAMTDVMvTUlNRSBTZW5kZXIx
+ ITAfBgkqhkiG9w0BCQEWEnNlbmRlckBleGFtcGxlLmRvbYIBADAMBgNVHRMEBTAD
+ AQH/MA0GCSqGSIb3DQEBBAUAA4GBAHo3DrCHR86fSTVAvfiXdSswWqKtCEhUHRdC
+ TLFGl4hDk2GyZxaFuqZwiURz/H7nMicymI2wkz8H/wyHFg8G3BIehURpj2v/ZWXY
+ eovbgS7EZALVVkDj4hNl/IIHWd6Gtv1UODf7URbxtl3hQ9/eTWITrefT1heuPnar
+ 8czydsOLMYIBujCCAbYCAQEwYDBbMQswCQYDVQQGEwJTRzERMA8GA1UEChMITTJD
+ cnlwdG8xFjAUBgNVBAMTDVMvTUlNRSBTZW5kZXIxITAfBgkqhkiG9w0BCQEWEnNl
+ bmRlckBleGFtcGxlLmRvbQIBADAJBgUrDgMCGgUAoIGxMBgGCSqGSIb3DQEJAzEL
+ BgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTAxMDMzMTExNDUwMlowIwYJKoZI
+ hvcNAQkEMRYEFOoeRUd8ExIYXfQq8BTFuKWrSP3iMFIGCSqGSIb3DQEJDzFFMEMw
+ CgYIKoZIhvcNAwcwDgYIKoZIhvcNAwICAgCAMA0GCCqGSIb3DQMCAgFAMAcGBSsO
+ AwIHMA0GCCqGSIb3DQMCAgEoMA0GCSqGSIb3DQEBAQUABIGAQpU8hFUtLCF6hO2t
+ ec9EYJ/Imqqiiw+BxWxkUUVT81Vbjwdn9JST6+sztM5JRP2ZW+b4txEjZriYC8f3
+ kv95YMTGbIsuWkJ93GrbvqoJ/CxO23r9WWRnZEm/1EZN9ZmlrYqzBTxnNRmP3Dhj
+ cW8kzZwH+2/2zz2G7x1HxRWH95A=
+
+ ------3C93156FC7B4EBF49FE9C7DB7F503087--
+
+
+Verify
+======
+
+Assume the above output has been saved into ``sign.p7``. Let's now
+verify the signature::
+
+ from M2Crypto import SMIME, X509
+
+ # Instantiate an SMIME object.
+ s = SMIME.SMIME()
+
+ # Load the signer's cert.
+ x509 = X509.load_cert('signer.pem')
+ sk = X509.X509_Stack()
+ sk.push(x509)
+ s.set_x509_stack(sk)
+
+ # Load the signer's CA cert. In this case, because the signer's
+ # cert is self-signed, it is the signer's cert itself.
+ st = X509.X509_Store()
+ st.load_info('signer.pem')
+ s.set_x509_store(st)
+
+ # Load the data, verify it.
+ p7, data = SMIME.smime_load_pkcs7('sign.p7')
+ v = s.verify(p7, data)
+ print(v)
+ print(data)
+ print(data.read())
+
+Here's the output of the above program::
+
+ a sign of our times
+ <M2Crypto.BIO.BIO instance at 0x822012c>
+ a sign of our times
+
+Suppose, instead of loading ``signer.pem`` above, we load
+``recipient.pem``. That is, we do a global substitution of
+``recipient.pem`` for ``signer.pem`` in the above program. Here's the
+modified program's output::
+
+ Traceback (most recent call last):
+ File "./verify.py", line 22, in ?
+ v = s.verify(p7)
+ File "/usr/local/home/ngps/prog/m2/M2Crypto/SMIME.py", line 205, in verify
+ raise SMIME_Error, Err.get_error()
+ M2Crypto.SMIME.SMIME_Error: 312:error:21075075:PKCS7 routines:PKCS7_verify:certificate verify error:pk7_smime.c:213:Verify error:self signed certificate
+
+
+As displayed, the error is generated by line 213 of OpenSSL's
+``pk7_smime.c`` (as of OpenSSL 0.9.6); if you are a C programmer, you
+may wish to look up the C source to explore OpenSSL's S/MIME
+implementation and understand why the error message is worded thus.
+
+Encrypt
+=======
+
+We now demonstrate how to generate an S/MIME-encrypted message::
+
+ from M2Crypto import BIO, Rand, SMIME, X509
+
+ def makebuf(text):
+ return BIO.MemoryBuffer(text)
+
+ # Make a MemoryBuffer of the message.
+ buf = makebuf('a sign of our times')
+
+ # Seed the PRNG.
+ Rand.load_file('randpool.dat', -1)
+
+ # Instantiate an SMIME object.
+ s = SMIME.SMIME()
+
+ # Load target cert to encrypt to.
+ x509 = X509.load_cert('recipient.pem')
+ sk = X509.X509_Stack()
+ sk.push(x509)
+ s.set_x509_stack(sk)
+
+ # Set cipher: 3-key triple-DES in CBC mode.
+ s.set_cipher(SMIME.Cipher('des_ede3_cbc'))
+
+ # Encrypt the buffer.
+ p7 = s.encrypt(buf)
+
+ # Output p7 in mail-friendly format.
+ out = BIO.MemoryBuffer()
+ out.write('From: sender@example.dom\n')
+ out.write('To: recipient@example.dom\n')
+ out.write('Subject: M2Crypto S/MIME testing\n')
+ s.write(out, p7)
+
+ print(out.read())
+
+ # Save the PRNG's state.
+ Rand.save_file('randpool.dat')
+
+Here's the output of the above program::
+
+ From: sender@example.dom
+ To: recipient@example.dom
+ Subject: M2Crypto S/MIME testing
+ MIME-Version: 1.0
+ Content-Disposition: attachment; filename="smime.p7m"
+ Content-Type: application/x-pkcs7-mime; name="smime.p7m"
+ Content-Transfer-Encoding: base64
+
+ MIIBVwYJKoZIhvcNAQcDoIIBSDCCAUQCAQAxggEAMIH9AgEAMGYwYTELMAkGA1UE
+ BhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRkwFwYDVQQDExBTL01JTUUgUmVjaXBp
+ ZW50MSQwIgYJKoZIhvcNAQkBFhVyZWNpcGllbnRAZXhhbXBsZS5kb20CAQAwDQYJ
+ KoZIhvcNAQEBBQAEgYCBaXZ+qjpBEZwdP7gjfzfAtQitESyMwo3i+LBOw6sSDir6
+ FlNDPCnkrTvqDX3Rt6X6vBtTCYOm+qiN7ujPkOU61cN7h8dvHR8YW9+0IPY80/W0
+ lZ/HihSRgwTNd7LnxUUcPx8YV1id0dlmP0Hz+Lg+mHf6rqaR//JcYhX9vW4XvjA7
+ BgkqhkiG9w0BBwEwFAYIKoZIhvcNAwcECMN+qya6ADywgBgHr9Jkhwn5Gsdu7BwX
+ nIQfYTYcdL9I5Sk=
+
+
+Decrypt
+=======
+
+Assume the above output has been saved into ``encrypt.p7``. Decrypt the
+message thusly::
+
+ from M2Crypto import BIO, SMIME, X509
+
+ # Instantiate an SMIME object.
+ s = SMIME.SMIME()
+
+ # Load private key and cert.
+ s.load_key('recipient_key.pem', 'recipient.pem')
+
+ # Load the encrypted data.
+ p7, data = SMIME.smime_load_pkcs7('encrypt.p7')
+
+ # Decrypt p7.
+ out = s.decrypt(p7)
+
+ print(out)
+
+Here's the output::
+
+ a sign of our times
+
+
+Sign and Encrypt
+================
+
+Here's how to generate an S/MIME-signed/encrypted message::
+
+ from M2Crypto import BIO, Rand, SMIME, X509
+
+ def makebuf(text):
+ return BIO.MemoryBuffer(text)
+
+ # Make a MemoryBuffer of the message.
+ buf = makebuf('a sign of our times')
+
+ # Seed the PRNG.
+ Rand.load_file('randpool.dat', -1)
+
+ # Instantiate an SMIME object.
+ s = SMIME.SMIME()
+
+ # Load signer's key and cert. Sign the buffer.
+ s.load_key('signer_key.pem', 'signer.pem')
+ p7 = s.sign(buf)
+
+ # Load target cert to encrypt the signed message to.
+ x509 = X509.load_cert('recipient.pem')
+ sk = X509.X509_Stack()
+ sk.push(x509)
+ s.set_x509_stack(sk)
+
+ # Set cipher: 3-key triple-DES in CBC mode.
+ s.set_cipher(SMIME.Cipher('des_ede3_cbc'))
+
+ # Create a temporary buffer.
+ tmp = BIO.MemoryBuffer()
+
+ # Write the signed message into the temporary buffer.
+ s.write(tmp, p7)
+
+ # Encrypt the temporary buffer.
+ p7 = s.encrypt(tmp)
+
+ # Output p7 in mail-friendly format.
+ out = BIO.MemoryBuffer()
+ out.write('From: sender@example.dom\n')
+ out.write('To: recipient@example.dom\n')
+ out.write('Subject: M2Crypto S/MIME testing\n')
+ s.write(out, p7)
+
+ print(out.read())
+
+ # Save the PRNG's state.
+ Rand.save_file('randpool.dat')
+
+Here's the output of the above program::
+
+ From: sender@example.dom
+ To: recipient@example.dom
+ Subject: M2Crypto S/MIME testing
+ MIME-Version: 1.0
+ Content-Disposition: attachment; filename="smime.p7m"
+ Content-Type: application/x-pkcs7-mime; name="smime.p7m"
+ Content-Transfer-Encoding: base64
+
+ MIIIwwYJKoZIhvcNAQcDoIIItDCCCLACAQAxggEAMIH9AgEAMGYwYTELMAkGA1UE
+ BhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRkwFwYDVQQDExBTL01JTUUgUmVjaXBp
+ ZW50MSQwIgYJKoZIhvcNAQkBFhVyZWNpcGllbnRAZXhhbXBsZS5kb20CAQAwDQYJ
+ KoZIhvcNAQEBBQAEgYBlZlGupFphwhsGtIAPvDExN61qisz3oem88xoXkUW0SzoR
+ B9zJFFAuQTWzdNJgrKKYikhWjDojaAc/PFl1K5dYxRgtZLB36ULJD/v/yWmxnjz8
+ TvtK+Wbal2P/MH2pZ4LVERXa/snTElhCawUlwtiFz/JvY5CiF/dcwd+AwFQq4jCC
+ B6UGCSqGSIb3DQEHATAUBggqhkiG9w0DBwQIRF525UfwszaAggeA85RmX6AXQMxb
+ eBDz/LJeCgc3RqU1UwIsbKMquIs1S46Ebbm5nP75izPnujOkJ2hv+LNzqOWADmOl
+ +CnGEq1qxTyduIgUDA2nBgCL/gVyVy+/XC9dtImUUTxtxLgYtB0ujkBNsOaENOlM
+ fv4SGM3jkR+K/xlYG6HHzZGbfYyNGj2Y7yMZ1rL1m8SnRNmkCysKGTrudeNf6wT9
+ J6wO9DzLTioz3ZnVr3LjsSKIb4tIp4ugqNJaLuW7m3FtZ3MAgxN68hBbJs8TZ8tL
+ V/0jwUqS+grcgZEb9ymfcedxahtDUfHjRkpDpsxZzVVGkSBNcbQu92oByQVnRQ8m
+ wrYLp3/eawM5AvuV7HNpTT5ZR+1t8luishHN9899IMP2Vyg0Ub67FqFypYmM2cm2
+ sjAI4KpfvT00XFNvgLuYwYEKs9syGTO7hiHNQKcF44F5LYv6nTFwmFQB11dAtY9V
+ ull4D2CLDx9OvyNyKwdEZB5dyV0r/uKIdkhST60V2Q9KegpzgFpoZtSKM/HPYSVH
+ 1Bc9f3Q/GqZCvNZZCMx8UvRjQR8dRWDSmPJ0VXG1+wJ+fCmSPP3AuQ1/VsgPRqx2
+ 56VrpGPpGut40hV8xQFbWIZ2whwWLKPFAHj8B79ZtFUzUrU6Z2rNpvv8inHc/+S/
+ b6GR5s8/gucRblvd7n3OFNX5UJmPmcw9zWbu/1Dr9DY8l0nAQh21y5FGSS8B1wdE
+ oD2M3Lp7JbwjQbRtnDhImqul2S4yu+m+wDD1aR2K4k3GAI7KKgOBWT0+BDClcn8A
+ 4Ju6/YUbj33YlMPJgnGijLnolFy0hNW7TmWqR+8tSI3wO5eNKg4qwBnarqc3vgCV
+ quVxINAXyGQCO9lzdw6hudk8/+BlweGdqhONaIWbK5z1L/SfQo6LC9MTsj7FJydq
+ bc+kEbfZS8aSq7uc9axW6Ti0eAPJ8EVHtwhSBgZQRweKFBXs6HbbhMIdc4N0M7Oq
+ UiFXaF6s4n2uihVP6TqXtHEjTpZoC7pC+HCYiuKXUJtaqtXBOh+y3KLvHk09YL6D
+ XmTDg+UTiFsh4jKKm/BhdelbR5JbpJcj5AId76Mfr8+F/1g9ePOvsWHpQr/oIQTo
+ xEkaxCmzEgP0b6caMWfMUQrbVGxBBNcqKc/ir9fGGOPHATzzq/xLcQYvK1tZhd/D
+ ah/gpMPndsyvVCEuFPluWyDiM0VkwHgC2/3pJIYFHaxK64IutmPsy393rHMEB4kN
+ AHau6kWK+yL9qEVH1pP2zvswQ12P7gjt3T/G3bGsmvlXkEfztfjkXo6XnjcBNf5y
+ G+974AKLcjnk1gzIgarz+lAMY57Gkw4oNDMrTqVQ2OJQlvOSbllPXzH+aAiavB8W
+ ZPECLLwHxD4B1AuaiAArgKl935u/TOB+yQOR8JgGsUzROyJqHJ/SC51HkebgCkL1
+ aggtjgPlIBEXLZAlhpWLZ9lAQyrQpvCVJYwaOvfMmvRav4NAFNoZ2/Q7S4Tn1z+U
+ XX+f+GD58P4MPMhU5IKnz4yH4nlHnAiTEvcs85TZUAXze9g/uBOwZITeGtyLi52S
+ aETIr4v7SgXMepX7ThQ1Pv/jddsK/u4j2F34u0XktwCP+UrbfkE2mocdXvdzxbmd
+ tZSznK2qwgVSsPOs9MhUaepbnjmNBFFBrULhrUtSglM/VX/rWNiyh0aw4XYyHhIt
+ 9ZNlfEjKjJ67VEMBxBJ/ieUCouRGCxPYD1j65VT7oB3ZiyPu2F2nlUIcYNqPg1Sd
+ QBCrdaOXdJ0uLwyTAUeVE+wMbgscLvWsfZcCCJHAvw9NHFMUcnrdWxAYMVETNUOn
+ uryVAK7VfOldaz6z3NOSOi6nonNeHpR/sipBa4ik5xCRLT9e0S2QJgRvO9GyfAqz
+ 3DIzHtxIGePFzTiUYUTxS3i2gnMX2PEe3ChTLlYWD3jNeAKz0iOzpDphIF2xHLLQ
+ 1tCAqBmq/vUzALyDFFdFuTIqQZys4z/u4Dmyq9uXs421eN3v2hkVHvDy8uT2Ot29
+ lg4Q5YezR1EjaW//9guL1BXbcKrTEdtxeNqtem7SpZOMTSwD2lhB8z65GrX90Cyt
+ EMmaRSGYEdf5h1afL1SmKOMskbqxe1D2jG/vsXC7XX7xO/ioy0BdiJcYN1JiMOHJ
+ EOzFol5I20YkiV6j+cenfQFwc/NkaSxEkR8AUHJSbvUmRQRl6r0nnsFpZdR1w7pv
+ wkaT+eOpZynO4mY/ZtF6MpXJsixi6L4ZYXEbS6yHf+XGFfB0okILylmwv2bf6+Mq
+ nqXlmGj3Jwq7X9/+2BDqvfpFFX5lSmItKZAobLdssjFR6roJxOqRsGia2aZ+0+U5
+ VhgdITtnElgtHBaeZU5rHDswgdeLVBP+rGWnKxpJ+pLtNNi25sPYRcWFL6Erd25u
+ eXiY8GEIr+u7rqBWpc9HR34sAPRs3ubbCUleT748keCbx247ImBtiDctZxcc1O86
+ +0QjHP6HUT7FSo/FmT7a120S3Gd2jixGh06l/9ij5Z6mJa7Rm7TTbSjup/XISnOT
+ MKWcbI1nfVOhCv3xDq2eLae+s0oVoc041ceRazqFM2TL/Z6UXRME
+
+
+Decrypt and Verify
+==================
+
+Suppose the above output has been saved into ``se.p7``. The following
+demonstrates how to decrypt and verify it::
+
+ from M2Crypto import BIO, SMIME, X509
+
+ # Instantiate an SMIME object.
+ s = SMIME.SMIME()
+
+ # Load private key and cert.
+ s.load_key('recipient_key.pem', 'recipient.pem')
+
+ # Load the signed/encrypted data.
+ p7, data = SMIME.smime_load_pkcs7('se.p7')
+
+ # After the above step, 'data' == None.
+ # Decrypt p7. 'out' now contains a PKCS #7 signed blob.
+ out = s.decrypt(p7)
+
+ # Load the signer's cert.
+ x509 = X509.load_cert('signer.pem')
+ sk = X509.X509_Stack()
+ sk.push(x509)
+ s.set_x509_stack(sk)
+
+ # Load the signer's CA cert. In this case, because the signer's
+ # cert is self-signed, it is the signer's cert itself.
+ st = X509.X509_Store()
+ st.load_info('signer.pem')
+ s.set_x509_store(st)
+
+ # Recall 'out' contains a PKCS #7 blob.
+ # Transform 'out'; verify the resulting PKCS #7 blob.
+ p7_bio = BIO.MemoryBuffer(out)
+ p7, data = SMIME.smime_load_pkcs7_bio(p7_bio)
+ v = s.verify(p7)
+
+ print(v)
+
+
+The output is as follows::
+
+ a sign of our times
+
+
+Sending S/MIME messages via SMTP
+================================
+
+In the above examples, we've assumed that our S/MIME messages are sent
+and received automagically. The following is a Python function that
+generates S/MIME-signed/encrypted messages and sends them via
+SMTP::
+
+ from M2Crypto import BIO, SMIME, X509
+ import smtplib, string, sys
+
+ def sendsmime(from_addr, to_addrs, subject, msg, from_key, from_cert=None, to_certs=None, smtpd='localhost'):
+
+ msg_bio = BIO.MemoryBuffer(msg)
+ sign = from_key
+ encrypt = to_certs
+
+ s = SMIME.SMIME()
+ if sign:
+ s.load_key(from_key, from_cert)
+ if encrypt:
+ p7 = s.sign(msg_bio, flags=SMIME.PKCS7_TEXT)
+ else:
+ p7 = s.sign(msg_bio, flags=SMIME.PKCS7_TEXT|SMIME.PKCS7_DETACHED)
+ msg_bio = BIO.MemoryBuffer(msg) # Recreate coz sign() has consumed it.
+
+ if encrypt:
+ sk = X509.X509_Stack()
+ for x in to_certs:
+ sk.push(X509.load_cert(x))
+ s.set_x509_stack(sk)
+ s.set_cipher(SMIME.Cipher('des_ede3_cbc'))
+ tmp_bio = BIO.MemoryBuffer()
+ if sign:
+ s.write(tmp_bio, p7)
+ else:
+ tmp_bio.write(msg)
+ p7 = s.encrypt(tmp_bio)
+
+ out = BIO.MemoryBuffer()
+ out.write('From: %s\r\n' % from_addr)
+ out.write('To: %s\r\n' % string.join(to_addrs, ", "))
+ out.write('Subject: %s\r\n' % subject)
+ if encrypt:
+ s.write(out, p7)
+ else:
+ if sign:
+ s.write(out, p7, msg_bio, SMIME.PKCS7_TEXT)
+ else:
+ out.write('\r\n')
+ out.write(msg)
+ out.close()
+
+ smtp = smtplib.SMTP()
+ smtp.connect(smtpd)
+ smtp.sendmail(from_addr, to_addrs, out.read())
+ smtp.quit()
+
+
+This function sends plain, S/MIME-signed, S/MIME-encrypted, and
+S/MIME-signed/encrypted messages, depending on the parameters
+``from_key`` and ``to_certs``. The function's output interoperates with
+Netscape Messenger.
+
+Verifying origin of S/MIME messages
+===================================
+
+In our examples above that decrypt or verify messages, we skipped a
+step: verifying that the ``from`` address of the message matches the
+``email address`` attribute in the sender's certificate.
+
+The premise of current X.509 certification practice is that the CA is
+supposed to verify your identity, and to issue a certificate with
+``email address`` that matches your actual mail address. (Verisign's
+March 2001 failure in identity verification resulting in Microsoft
+certificates being issued to spoofers notwithstanding.)
+
+If you run your own CA, your certification practice is up to you, of
+course, and it would probably be part of your security policy.
+
+Whether your S/MIME messaging application needs to verify the ``from``
+addresses of S/MIME messages depends on your security policy and your
+system's threat model, as always.
+
+Interoperating with Netscape Messenger
+======================================
+
+Suppose S/MIME Recipient uses Netscape Messenger. To enable Messenger to
+handle S/MIME messages from S/MIME Sender, S/MIME Recipient needs to
+configure Messenger with his private key and certificate, as well as
+S/MIME Sender's certificate.
+
+ **Note:** Configuring Messenger's POP or IMAP settings so that it
+ retrieves mail correctly is beyond the scope of this HOWTO.
+
+The following steps demonstrate how to import S/MIME Recipient's private
+key and certificate for Messenger:
+
+1. Transform S/MIME Recipient's private key and certificate into *PKCS
+ #12* format::
+
+ openssl pkcs12 -export -in recipient.pem -inkey recipient_key.pem \
+ -name "S/MIME Recipient" -out recipient.p12
+
+ Enter Export Password:<enter>
+ Verifying password - Enter Export Password:<enter>
+
+2. Start Messenger.
+
+3. Click on the (open) "lock" icon at the bottom left corner of
+ Messenger's window. This brings up the "Security Info" dialog box.
+
+4. Click on "Yours" under "Certificates".
+
+5. Select "Import a certificate", then pick ``recipient.p12`` from the
+ ensuing file selection dialog box.
+
+Next, you need to import ``signer.pem`` as a CA certificate, so that
+Messenger will mark messages signed by S/MIME Sender as "trusted":
+
+1. Create a DER encoding of ``signer.pem``::
+
+ openssl x509 -inform pem -outform der -in signer.pem -out signer.der
+
+2. Install ``signer.der`` into Messenger as MIME type
+ ``application/x-x509-ca-cert``. You do this by downloading
+ ``signer.der`` via Navigator from a HTTP or HTTPS server, with the
+ correct MIME type mapping. (You may use ``demo/ssl/https_srv.py``,
+ bundled with M2Crypto, for this purpose.) Follow the series of dialog
+ boxes to accept ``signer.der`` as a CA for certifying email users.
+
+S/MIME Recipient is now able to decrypt and read S/MIME Sender's
+messages with Messenger. Messenger will indicate that S/MIME Sender's
+messages are signed, encrypted, or encrypted *and* signed, as the case
+may be, via the "stamp" icon on the message window's top right corner.
+
+Clicking on the "stamp" icon brings you to the Security Info dialog box.
+Messenger informs you that the message is, say, encrypted with 168-bit
+DES-EDE3-CBC and that it is digitally signed by the private key
+corresponding to the public key contained in the certificate
+``signer.pem``.
+
+Interoperating with Microsoft Outlook
+=====================================
+
+I do not know how to do this, as I do not use Outlook. (Nor do I use
+Netscape Messenger, actually. I use Mutt, top dog of MUAs. ;-)
+Information on how to configure Outlook with keys and certificates so
+that it handles S/MIME mail is gratefully accepted.
+
+ZSmime
+======
+
+ZSmime is a `Zope <http://www.zope.org>`__ *product* that enables Zope
+to generate S/MIME-signed/encrypted messages. ZSmime demonstrates how to
+invoke M2Crypto in a web application server extension.
+
+ZSmime has its own
+`HOWTO <http://sandbox.rulemaker.net/ngps/zope/zsmime/howto.html>`__
+explaining its usage. (That HOWTO has some overlap in content with this
+document.)
+
+Resources
+=========
+
+- IETF S/MIME Working Group - http://www.imc.org/ietf-smime
+
+- S/MIME and OpenPGP - http://www.imc.org/smime-pgpmime.html
+
+- S/MIME Freeware Library -
+ http://www.getronicsgov.com/hot/sfl_home.htm
+
+- Mozilla Network Security Services -
+ http://www.mozilla.org/projects/security/pkg/nss
+
+- S/MIME Cracking Screen Saver - http://www.counterpane.com/smime.html
diff --git a/doc/howto.ssl.html b/doc/howto.ssl.html
deleted file mode 100644
index 340f264..0000000
--- a/doc/howto.ssl.html
+++ /dev/null
@@ -1,206 +0,0 @@
-<HTML
-><HEAD
-><TITLE
->HOWTO: Programming SSL in Python with M2Crypto</TITLE
->
-
-</HEAD>
-<BODY
-CLASS="ARTICLE"
-BGCOLOR="#FFFFFF"
-TEXT="#000000"
-LINK="#0000FF"
-VLINK="#840084"
-ALINK="#0000FF"
->
-
-<DIV
-CLASS="TITLEPAGE"
-><H1
-CLASS="TITLE"
-><A
-NAME="AEN2"
->HOWTO: Programming SSL in Python with M2Crypto</A
-></H1
->
-<P>
-Ng Pheng Siong (ngps@netmemetic.com) and Heikki Toivonen (heikki@osafoundation.org)
-</P
-><P
-CLASS="COPYRIGHT"
->Copyright &copy; 2001, 2002 by Ng Pheng Siong.</P
->
-<P
-CLASS="COPYRIGHT"
->Portions Copyright &copy; 2006 by Open Source Applications Foundation.</P
->
-</DIV>
-
-<DIV
-CLASS="SECT1"
-><H1
-CLASS="SECT1"
-><A
-NAME="INTRODUCTION"
->Introduction</A
-></H1
-><P
-><A
-HREF="http://chandlerproject.org/Projects/MeTooCrypto"
-TARGET="_top"
->M2Crypto</A
->
- is a <A
-HREF="http://www.python.org"
-TARGET="_top"
->Python</A
->
- interface to <A
-HREF="http://www.openssl.org"
-TARGET="_top"
->OpenSSL</A
->. It makes
- available to the Python programmer SSL functionality to implement clients
- and servers, S/MIME v2, RSA, DSA, DH, symmetric ciphers, message digests and
- HMACs.
- </P
-><P
->This document demonstrates programming HTTPS with M2Crypto.
- </P
-></DIV
->
-
-
-<DIV
-CLASS="SECT1"
-><H1
-CLASS="SECT1"
-><A
-NAME="history"
->A bit of history</A
-></H1
->
-
-<p> M2Crypto was created during the time of Python 1.5, which features
- a module httplib providing client-side HTTP functionality. M2Crypto sports
- a httpslib based on httplib.
- </p>
-
- <p>
- Beginning with version 2.0, Python's socket module provided
- (rudimentary) SSL support. Also in the same version, httplib was
- enhanced with class HTTPConnection, which is more sophisticated than
- the old class HTTP, and HTTPSConnection, which does HTTPS.
- </p>
-
- <p>
- Subsequently, M2Crypto.httpslib grew a compatible (but not identical)
- class HTTPSConnection.
- </p>
-
- <p>
- The primary interface difference between the two HTTPSConnection
- classes is that M2Crypto's version accepts an M2Crypto.SSL.Context
- instance as a parameter, whereas Python 2.x's SSL support does not
- permit Pythonic control of the SSL context.
- </p>
-
- <p> Within the implementations, Python's
- <tt>HTTPSConnection</tt> employs a
- <tt>FakeSocket</tt> object, which collects all input from
- the SSL connection before returning it to the application as a
- <tt>StringIO</tt> buffer, whereas M2Crypto's
- <tt>HTTPSConnection</tt> uses a buffering
- <tt>M2Crypto.BIO.IOBuffer</tt> object that works over the
- underlying M2Crypto.SSL.Connection directly. </p>
-
- <p>Since then M2Crypto has gained a Twisted wrapper that allows securing
- Twisted SSL connections with M2Crypto.</p>
-</DIV
->
-
-
-<DIV CLASS="SECT1" id="secure" name="secure">
-<H1 CLASS="SECT1">Secure SSL</H1>
-
-<p>It is recommended that you read the book Network Security with OpenSSL by John Viega, Matt Messier and Pravir Chandra,
-ISBN 059600270X.</p>
-
-<p>Using M2Crypto does not automatically make an SSL connection secure. There are various steps that need to be made
-before we can make that claim. Let's see how a simple client can establish a secure connection:</p>
-
-<pre>
-ctx = SSL.Context()
-ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, depth=9)
-if ctx.load_verify_locations('ca.pem') != 1: raise Exception('No CA certs')
-s = SSL.Connection(ctx)
-s.connect(server_address)
-# Normal protocol (for example HTTP) commands follow
-</pre>
-
-<p>The first line creates an SSL context. The defaults allow any SSL version (except SSL version 2 which has known
-weaknesses) and sets the allowed ciphers to secure ones.</p>
-
-<p>The second line tells M2Crypto to perform certificate validation. The flags shown above are typical for clients,
-and requires the server to send a certificate. The depth parameter tells how long certificate chains are allowed -
-9 is pretty common default, although probably too long in practice.</p>
-
-<p>The third line loads the allowed root (certificate authority or CA) certificates.
-Most Linux distributions come with CA certificates in suitable format. You
-could also download the <a href="http://mxr.mozilla.org/seamonkey/source//security/nss/lib/ckfw/builtins/certdata.txt?raw=1">certdata.txt</a>
-file from the <a href="http://www.mozilla.org/projects/security/pki/nss/">NSS</a>
-project and convert it
-with the little M2Crypto utility script <a href="http://svn.osafoundation.org/m2crypto/trunk/demo/x509/certdata2pem.py">demo/x509/certdata2pem.py</a>.</p>
-
-<p>The fourth line creates an SSL connection object with the secure context.</p>
-
-<p>The fifth line connects to the server. During this time we perform the last security step: just after connection, but before
-exchanging any data, we compare the commonName (or subjectAltName DNS field) field in the certificate the server returned to the
-server address we tried to connect to. This happens automatically with SSL.Connection and the Twisted wrapper class, and anything
-that uses those. In all other cases you must do the check manually. It is recommended you call the SSL.Checker to do the actual check.</p>
-
-<p>SSL servers are different in that they typically do not require the client to send a certificate, so there is usually no certificate
-checking. Also, it is typically useless to perform host name checking.</p>
-
-</DIV>
-
-<DIV CLASS="SECT1">
-<H1 CLASS="SECT1">Code Samples</H1>
-
-<p>The best samples of how to use the various SSL objects are in the tests directory, and the test_ssl.py file specifically.
-There are additional samples in the demo directory, but they are not quaranteed to be up to date.</p>
-
-<p>NOTE: The tests and demos
-may not be secure as is. Use the information above on how to make them secure.</p>
-</DIV>
-
-<DIV
-CLASS="SECT1"
-><H1
-CLASS="SECT1"
-><A
-NAME="SSLDUMP"
->ssldump</A
-></H1
->
-<P>ssldump "is an SSLv3/TLS network protocol analyser. It identifies
- TCP connections on the chosen network interface and attempts to interpret
- them as SSLv3/TLS traffic. When it identifies SSLv3/TLS traffic, it
- decodes the records and displays them in a textual form to stdout. If
- provided with the appropriate keying material, it will also decrypt the
- connections and display the application data traffic.
- </P>
-
- <P>
- If linked with OpenSSL, ssldump can display certificates in decoded form
- and decrypt traffic (provided that it has the appropriate keying
- material)."
- </P>
-
- <P>ssldump is written by Eric Rescorla.
- </P>
-</DIV
->
-
-</BODY>
-</HTML>
diff --git a/doc/howto.ssl.rst b/doc/howto.ssl.rst
new file mode 100644
index 0000000..7f3278c
--- /dev/null
+++ b/doc/howto.ssl.rst
@@ -0,0 +1,131 @@
+:orphan:
+
+.. _howto-ssl:
+
+HOWTO: Programming SSL in Python with M2Crypto
+==============================================
+
+:author: Pheng Siong Ng <ngps@netmemetic.com> and Heikki Toivonen (heikki@osafoundation.org)
+:copyright: © 2000, 2001 by Ng Pheng Siong,
+ portions © 2006 by Open Source Applications Foundation
+
+Introduction
+============
+
+`M2Crypto <https://gitlab.com/m2crypto/m2crypto/>`__ is a
+`Python <http://www.python.org>`__ interface to
+`OpenSSL <http://www.openssl.org>`__. It makes available to the Python
+programmer SSL functionality to implement clients and servers, S/MIME
+v2, RSA, DSA, DH, symmetric ciphers, message digests and HMACs.
+
+This document demonstrates programming HTTPS with M2Crypto.
+
+A bit of history
+================
+
+M2Crypto was created during the time of Python 1.5, which features a
+module httplib providing client-side HTTP functionality. M2Crypto sports
+a httpslib based on httplib.
+
+Beginning with version 2.0, Python's socket module provided
+(rudimentary) SSL support. Also in the same version, httplib was
+enhanced with class HTTPConnection, which is more sophisticated than the
+old class HTTP, and HTTPSConnection, which does HTTPS.
+
+Subsequently, M2Crypto.httpslib grew a compatible (but not identical)
+class HTTPSConnection.
+
+The primary interface difference between the two HTTPSConnection classes
+is that M2Crypto's version accepts an M2Crypto.SSL.Context instance as a
+parameter, whereas Python 2.x's SSL support does not permit Pythonic
+control of the SSL context.
+
+Within the implementations, Python's ``HTTPSConnection`` employs a
+``FakeSocket`` object, which collects all input from the SSL connection
+before returning it to the application as a ``StringIO`` buffer, whereas
+M2Crypto's ``HTTPSConnection`` uses a buffering
+``M2Crypto.BIO.IOBuffer`` object that works over the underlying
+M2Crypto.SSL.Connection directly.
+
+Since then M2Crypto has gained a Twisted wrapper that allows securing
+Twisted SSL connections with M2Crypto.
+
+Secure SSL
+==========
+
+It is recommended that you read the book Network Security with OpenSSL
+by John Viega, Matt Messier and Pravir Chandra, ISBN 059600270X.
+
+Using M2Crypto does not automatically make an SSL connection secure.
+There are various steps that need to be made before we can make that
+claim. Let's see how a simple client can establish a secure
+connection::
+
+ ctx = SSL.Context()
+ ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, depth=9)
+ if ctx.load_verify_locations('ca.pem') != 1: raise Exception('No CA certs')
+ s = SSL.Connection(ctx)
+ s.connect(server_address)
+ # Normal protocol (for example HTTP) commands follow
+
+The first line creates an SSL context. The defaults allow any SSL
+version (except SSL version 2 which has known weaknesses) and sets the
+allowed ciphers to secure ones.
+
+The second line tells M2Crypto to perform certificate validation. The
+flags shown above are typical for clients, and requires the server to
+send a certificate. The depth parameter tells how long certificate
+chains are allowed - 9 is pretty common default, although probably too
+long in practice.
+
+The third line loads the allowed root (certificate authority or CA)
+certificates. Most Linux distributions come with CA certificates in
+suitable format. You could also download the
+`certdata.txt <http://mxr.mozilla.org/seamonkey/source//security/nss/lib/ckfw/builtins/certdata.txt?raw=1>`__
+file from the
+`NSS <http://www.mozilla.org/projects/security/pki/nss/>`__ project and
+convert it with the little M2Crypto utility script
+`demo/x509/certdata2pem.py <http://svn.osafoundation.org/m2crypto/trunk/demo/x509/certdata2pem.py>`__.
+
+The fourth line creates an SSL connection object with the secure
+context.
+
+The fifth line connects to the server. During this time we perform the
+last security step: just after connection, but before exchanging any
+data, we compare the commonName (or subjectAltName DNS field) field in
+the certificate the server returned to the server address we tried to
+connect to. This happens automatically with SSL.Connection and the
+Twisted wrapper class, and anything that uses those. In all other cases
+you must do the check manually. It is recommended you call the
+SSL.Checker to do the actual check.
+
+SSL servers are different in that they typically do not require the
+client to send a certificate, so there is usually no certificate
+checking. Also, it is typically useless to perform host name checking.
+
+Code Samples
+============
+
+The best samples of how to use the various SSL objects are in the tests
+directory, and the test\_ssl.py file specifically. There are additional
+samples in the demo directory, but they are not quaranteed to be up to
+date.
+
+NOTE: The tests and demos may not be secure as is. Use the information
+above on how to make them secure.
+
+ssldump
+=======
+
+ssldump "is an SSLv3/TLS network protocol analyser. It identifies TCP
+connections on the chosen network interface and attempts to interpret
+them as SSLv3/TLS traffic. When it identifies SSLv3/TLS traffic, it
+decodes the records and displays them in a textual form to stdout. If
+provided with the appropriate keying material, it will also decrypt the
+connections and display the application data traffic.
+
+If linked with OpenSSL, ssldump can display certificates in decoded form
+and decrypt traffic (provided that it has the appropriate keying
+material)."
+
+ssldump is written by Eric Rescorla.
diff --git a/doc/html/.buildinfo b/doc/html/.buildinfo
new file mode 100644
index 0000000..50b077b
--- /dev/null
+++ b/doc/html/.buildinfo
@@ -0,0 +1,4 @@
+# Sphinx build info version 1
+# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
+config: f47da9e27c47bb67c681b112c1dbec32
+tags: 645f666f9bcd5a90fca523b33c5a78b7
diff --git a/doc/html/M2Crypto.SSL.html b/doc/html/M2Crypto.SSL.html
new file mode 100644
index 0000000..4a81972
--- /dev/null
+++ b/doc/html/M2Crypto.SSL.html
@@ -0,0 +1,1706 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>SSL Package &#8212; M2Crypto documentation</title>
+ <link rel="stylesheet" href="_static/alabaster.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <script type="text/javascript" src="_static/language_data.js"></script>
+ <link rel="index" title="Index" href="genindex.html" />
+ <link rel="search" title="Search" href="search.html" />
+ <link rel="prev" title="M2Crypto Package" href="M2Crypto.html" />
+
+ <link rel="stylesheet" href="_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+ <div class="section" id="ssl-package">
+<h1>SSL Package<a class="headerlink" href="#ssl-package" title="Permalink to this headline">¶</a></h1>
+<div class="section" id="id1">
+<h2><code class="xref py py-mod docutils literal notranslate"><span class="pre">SSL</span></code> Package<a class="headerlink" href="#id1" title="Permalink to this headline">¶</a></h2>
+<span class="target" id="module-M2Crypto.SSL"></span><dl class="exception">
+<dt id="M2Crypto.SSL.SSLError">
+<em class="property">exception </em><code class="descclassname">M2Crypto.SSL.</code><code class="descname">SSLError</code><a class="reference internal" href="_modules/M2Crypto/SSL.html#SSLError"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.SSLError" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">Exception</span></code></p>
+</dd></dl>
+
+<dl class="exception">
+<dt id="M2Crypto.SSL.SSLTimeoutError">
+<em class="property">exception </em><code class="descclassname">M2Crypto.SSL.</code><code class="descname">SSLTimeoutError</code><a class="reference internal" href="_modules/M2Crypto/SSL.html#SSLTimeoutError"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.SSLTimeoutError" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <a class="reference internal" href="#M2Crypto.SSL.SSLError" title="M2Crypto.SSL.SSLError"><code class="xref py py-class docutils literal notranslate"><span class="pre">M2Crypto.SSL.SSLError</span></code></a>, <code class="xref py py-class docutils literal notranslate"><span class="pre">socket.timeout</span></code></p>
+</dd></dl>
+
+</div>
+<div class="section" id="module-M2Crypto.SSL.Checker">
+<span id="checker-module"></span><h2><code class="xref py py-mod docutils literal notranslate"><span class="pre">Checker</span></code> Module<a class="headerlink" href="#module-M2Crypto.SSL.Checker" title="Permalink to this headline">¶</a></h2>
+<p>SSL peer certificate checking routines</p>
+<p>Copyright (c) 2004-2007 Open Source Applications Foundation.
+All rights reserved.</p>
+<p>Copyright 2008 Heikki Toivonen. All rights reserved.</p>
+<dl class="exception">
+<dt id="M2Crypto.SSL.Checker.SSLVerificationError">
+<em class="property">exception </em><code class="descclassname">M2Crypto.SSL.Checker.</code><code class="descname">SSLVerificationError</code><a class="reference internal" href="_modules/M2Crypto/SSL/Checker.html#SSLVerificationError"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Checker.SSLVerificationError" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">Exception</span></code></p>
+</dd></dl>
+
+<dl class="exception">
+<dt id="M2Crypto.SSL.Checker.NoCertificate">
+<em class="property">exception </em><code class="descclassname">M2Crypto.SSL.Checker.</code><code class="descname">NoCertificate</code><a class="reference internal" href="_modules/M2Crypto/SSL/Checker.html#NoCertificate"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Checker.NoCertificate" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <a class="reference internal" href="#M2Crypto.SSL.Checker.SSLVerificationError" title="M2Crypto.SSL.Checker.SSLVerificationError"><code class="xref py py-class docutils literal notranslate"><span class="pre">M2Crypto.SSL.Checker.SSLVerificationError</span></code></a></p>
+</dd></dl>
+
+<dl class="exception">
+<dt id="M2Crypto.SSL.Checker.WrongCertificate">
+<em class="property">exception </em><code class="descclassname">M2Crypto.SSL.Checker.</code><code class="descname">WrongCertificate</code><a class="reference internal" href="_modules/M2Crypto/SSL/Checker.html#WrongCertificate"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Checker.WrongCertificate" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <a class="reference internal" href="#M2Crypto.SSL.Checker.SSLVerificationError" title="M2Crypto.SSL.Checker.SSLVerificationError"><code class="xref py py-class docutils literal notranslate"><span class="pre">M2Crypto.SSL.Checker.SSLVerificationError</span></code></a></p>
+</dd></dl>
+
+<dl class="exception">
+<dt id="M2Crypto.SSL.Checker.WrongHost">
+<em class="property">exception </em><code class="descclassname">M2Crypto.SSL.Checker.</code><code class="descname">WrongHost</code><span class="sig-paren">(</span><em>expectedHost</em>, <em>actualHost</em>, <em>fieldName='commonName'</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Checker.html#WrongHost"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Checker.WrongHost" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <a class="reference internal" href="#M2Crypto.SSL.Checker.SSLVerificationError" title="M2Crypto.SSL.Checker.SSLVerificationError"><code class="xref py py-class docutils literal notranslate"><span class="pre">M2Crypto.SSL.Checker.SSLVerificationError</span></code></a></p>
+</dd></dl>
+
+<dl class="class">
+<dt id="M2Crypto.SSL.Checker.Checker">
+<em class="property">class </em><code class="descclassname">M2Crypto.SSL.Checker.</code><code class="descname">Checker</code><span class="sig-paren">(</span><em>host=None</em>, <em>peerCertHash=None</em>, <em>peerCertDigest='sha1'</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Checker.html#Checker"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Checker.Checker" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
+<dl class="attribute">
+<dt id="M2Crypto.SSL.Checker.Checker.numericIpMatch">
+<code class="descname">numericIpMatch</code><em class="property"> = re.compile('^[0-9]+(\\.[0-9]+)*$')</em><a class="headerlink" href="#M2Crypto.SSL.Checker.Checker.numericIpMatch" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+</dd></dl>
+
+</div>
+<div class="section" id="module-M2Crypto.SSL.Cipher">
+<span id="cipher-module"></span><h2><code class="xref py py-mod docutils literal notranslate"><span class="pre">Cipher</span></code> Module<a class="headerlink" href="#module-M2Crypto.SSL.Cipher" title="Permalink to this headline">¶</a></h2>
+<p>SSL Ciphers</p>
+<p>Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved.</p>
+<dl class="class">
+<dt id="M2Crypto.SSL.Cipher.Cipher">
+<em class="property">class </em><code class="descclassname">M2Crypto.SSL.Cipher.</code><code class="descname">Cipher</code><span class="sig-paren">(</span><em>cipher</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Cipher.html#Cipher"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Cipher.Cipher" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
+<dl class="method">
+<dt id="M2Crypto.SSL.Cipher.Cipher.name">
+<code class="descname">name</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Cipher.html#Cipher.name"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Cipher.Cipher.name" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Cipher.Cipher.version">
+<code class="descname">version</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Cipher.html#Cipher.version"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Cipher.Cipher.version" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="M2Crypto.SSL.Cipher.Cipher_Stack">
+<em class="property">class </em><code class="descclassname">M2Crypto.SSL.Cipher.</code><code class="descname">Cipher_Stack</code><span class="sig-paren">(</span><em>stack</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Cipher.html#Cipher_Stack"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Cipher.Cipher_Stack" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
+</dd></dl>
+
+</div>
+<div class="section" id="module-M2Crypto.SSL.Connection">
+<span id="connection-module"></span><h2><code class="xref py py-mod docutils literal notranslate"><span class="pre">Connection</span></code> Module<a class="headerlink" href="#module-M2Crypto.SSL.Connection" title="Permalink to this headline">¶</a></h2>
+<dl class="class">
+<dt id="M2Crypto.SSL.Connection.Connection">
+<em class="property">class </em><code class="descclassname">M2Crypto.SSL.Connection.</code><code class="descname">Connection</code><span class="sig-paren">(</span><em>ctx</em>, <em>sock=None</em>, <em>family=&lt;AddressFamily.AF_INET: 2&gt;</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
+<p>An SSL connection.</p>
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.accept">
+<code class="descname">accept</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.accept"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.accept" title="Permalink to this definition">¶</a></dt>
+<dd><p>Accept an SSL connection.</p>
+<p>The return value is a pair (ssl, addr) where ssl is a new SSL
+connection object and addr is the address bound to the other end
+of the SSL connection.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">tuple of Connection and addr. Address can take very
+various forms (see socket documentation), for IPv4 it
+is tuple(str, int), for IPv6 a tuple of four (host,
+port, flowinfo, scopeid), where the last two are
+optional ints.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.accept_ssl">
+<code class="descname">accept_ssl</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.accept_ssl"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.accept_ssl" title="Permalink to this definition">¶</a></dt>
+<dd><p>Waits for a TLS/SSL client to initiate the TLS/SSL handshake.</p>
+<p>The communication channel must already have been set and
+assigned to the ssl by setting an underlying BIO.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body"><dl class="docutils">
+<dt>0 The TLS/SSL handshake was not successful but was shut</dt>
+<dd>down controlled and by the specifications of the
+TLS/SSL protocol. Call get_error() with the return
+value ret to find out the reason.</dd>
+<dt>1 The TLS/SSL handshake was successfully completed,</dt>
+<dd>a TLS/SSL connection has been established.</dd>
+<dt>&lt;0 The TLS/SSL handshake was not successful because</dt>
+<dd>a fatal error occurred either at the protocol level
+or a connection failure occurred. The shutdown was
+not clean. It can also occur of action is need to
+continue the operation for non-blocking BIOs. Call
+get_error() with the return value ret to find
+out the reason.</dd>
+</dl>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.bind">
+<code class="descname">bind</code><span class="sig-paren">(</span><em>addr</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.bind"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.bind" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.clear">
+<code class="descname">clear</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.clear"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.clear" title="Permalink to this definition">¶</a></dt>
+<dd><p>If there were errors in this connection, call clear() rather
+than close() to end it, so that bad sessions will be cleared
+from cache.</p>
+</dd></dl>
+
+<dl class="attribute">
+<dt id="M2Crypto.SSL.Connection.Connection.clientPostConnectionCheck">
+<code class="descname">clientPostConnectionCheck</code><em class="property"> = &lt;M2Crypto.SSL.Checker.Checker object&gt;</em><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.clientPostConnectionCheck" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.close">
+<code class="descname">close</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.close"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.close" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.connect">
+<code class="descname">connect</code><span class="sig-paren">(</span><em>addr</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.connect"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.connect" title="Permalink to this definition">¶</a></dt>
+<dd><p>Overloading socket.connect()</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>addr</strong> – addresses have various depending on their type</td>
+</tr>
+</tbody>
+</table>
+<p>:return:status of ssl_connect()</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.connect_ssl">
+<code class="descname">connect_ssl</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.connect_ssl"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.connect_ssl" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.fileno">
+<code class="descname">fileno</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.fileno"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.fileno" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.get_cipher">
+<code class="descname">get_cipher</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.get_cipher"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.get_cipher" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return an M2Crypto.SSL.Cipher object for this connection; if the
+connection has not been initialised with a cipher suite, return None.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.get_cipher_list">
+<code class="descname">get_cipher_list</code><span class="sig-paren">(</span><em>idx=0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.get_cipher_list"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.get_cipher_list" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return the cipher suites for this connection as a string object.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.get_ciphers">
+<code class="descname">get_ciphers</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.get_ciphers"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.get_ciphers" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return an M2Crypto.SSL.Cipher_Stack object for this
+connection; if the connection has not been initialised with
+cipher suites, return None.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.get_context">
+<code class="descname">get_context</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.get_context"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.get_context" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return the Context object associated with this connection.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.get_default_session_timeout">
+<code class="descname">get_default_session_timeout</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.get_default_session_timeout"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.get_default_session_timeout" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.get_peer_cert">
+<code class="descname">get_peer_cert</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.get_peer_cert"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.get_peer_cert" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return the peer certificate.</p>
+<p>If the peer did not provide a certificate, return None.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.get_peer_cert_chain">
+<code class="descname">get_peer_cert_chain</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.get_peer_cert_chain"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.get_peer_cert_chain" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return the peer certificate chain; if the peer did not provide
+a certificate chain, return None.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Warning:</th><td class="field-body">The returned chain will be valid only for as long as the
+connection object is alive. Once the connection object
+gets freed, the chain will be freed as well.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.get_session">
+<code class="descname">get_session</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.get_session"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.get_session" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.get_shutdown">
+<code class="descname">get_shutdown</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.get_shutdown"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.get_shutdown" title="Permalink to this definition">¶</a></dt>
+<dd><p>Get the current shutdown mode of the Connection.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.get_socket_read_timeout">
+<code class="descname">get_socket_read_timeout</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.get_socket_read_timeout"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.get_socket_read_timeout" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.get_socket_write_timeout">
+<code class="descname">get_socket_write_timeout</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.get_socket_write_timeout"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.get_socket_write_timeout" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.get_state">
+<code class="descname">get_state</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.get_state"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.get_state" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return the SSL state of this connection.</p>
+<p>During its use, an SSL objects passes several states. The state
+is internally maintained. Querying the state information is not
+very informative before or when a connection has been
+established. It however can be of significant interest during
+the handshake.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">6 letter string indicating the current state of the SSL
+object ssl.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.get_verify_depth">
+<code class="descname">get_verify_depth</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.get_verify_depth"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.get_verify_depth" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return the peer certificate verification depth.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.get_verify_mode">
+<code class="descname">get_verify_mode</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.get_verify_mode"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.get_verify_mode" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return the peer certificate verification mode.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.get_verify_result">
+<code class="descname">get_verify_result</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.get_verify_result"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.get_verify_result" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return the peer certificate verification result.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.get_version">
+<code class="descname">get_version</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.get_version"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.get_version" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return the TLS/SSL protocol version for this connection.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.getpeername">
+<code class="descname">getpeername</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.getpeername"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.getpeername" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return the remote address to which the socket is connected.</p>
+<p>This is useful to find out the port number of a remote IPv4/v6 socket,
+for instance.
+On some systems this function is not supported.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body"></td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.getsockname">
+<code class="descname">getsockname</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.getsockname"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.getsockname" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return the socket’s own address.</p>
+<p>This is useful to find out the port number of an IPv4/v6 socket,
+for instance. (The format of the address returned depends
+on the address family – see above.)</p>
+<p>:return:socket’s address as addr type</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.getsockopt">
+<code class="descname">getsockopt</code><span class="sig-paren">(</span><em>level</em>, <em>optname</em>, <em>buflen=None</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.getsockopt"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.getsockopt" title="Permalink to this definition">¶</a></dt>
+<dd><p>Get the value of the given socket option.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>level</strong> – level at which the option resides.
+To manipulate options at the sockets API level, level is
+specified as socket.SOL_SOCKET. To manipulate options at
+any other level the protocol number of the appropriate
+protocol controlling the option is supplied. For example,
+to indicate that an option is to be interpreted by the
+TCP protocol, level should be set to the protocol number
+of socket.SOL_TCP; see getprotoent(3).</li>
+<li><strong>optname</strong> – The value of the given socket option is
+described in the Unix man page getsockopt(2)). The needed
+symbolic constants (SO_* etc.) are defined in the socket
+module.</li>
+<li><strong>buflen</strong> – If it is absent, an integer option is assumed
+and its integer value is returned by the function. If
+buflen is present, it specifies the maximum length of the
+buffer used to receive the option in, and this buffer is
+returned as a bytes object.</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">Either integer or bytes value of the option. It is up
+to the caller to decode the contents of the buffer (see
+the optional built-in module struct for a way to decode
+C structures encoded as byte strings).</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.listen">
+<code class="descname">listen</code><span class="sig-paren">(</span><em>qlen=5</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.listen"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.listen" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.m2_bio_free">
+<code class="descname">m2_bio_free</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.m2_bio_free" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="attribute">
+<dt id="M2Crypto.SSL.Connection.Connection.m2_bio_noclose">
+<code class="descname">m2_bio_noclose</code><em class="property"> = 0</em><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.m2_bio_noclose" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.m2_ssl_free">
+<code class="descname">m2_ssl_free</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.m2_ssl_free" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.makefile">
+<code class="descname">makefile</code><span class="sig-paren">(</span><em>mode='rb'</em>, <em>bufsize=-1</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.makefile"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.makefile" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.pending">
+<code class="descname">pending</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.pending"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.pending" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return the numbers of octets that can be read from the connection.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.read">
+<code class="descname">read</code><span class="sig-paren">(</span><em>size=1024</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.read"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.read" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.recv">
+<code class="descname">recv</code><span class="sig-paren">(</span><em>size=1024</em><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.recv" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.recv_into">
+<code class="descname">recv_into</code><span class="sig-paren">(</span><em>buff</em>, <em>nbytes=0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.recv_into"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.recv_into" title="Permalink to this definition">¶</a></dt>
+<dd><p>A version of recv() that stores its data into a buffer rather
+than creating a new string. Receive up to buffersize bytes from
+the socket. If buffersize is not specified (or 0), receive up
+to the size available in the given buffer.</p>
+<p>If buff is bytearray, it will have after return length of the
+actually returned number of bytes. If buff is memoryview, then
+the size of buff won’t change (it cannot), but all bytes after
+the number of returned bytes will be NULL.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>buffer</strong> – a buffer for the received bytes</li>
+<li><strong>nbytes</strong> – maximum number of bytes to read</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">number of bytes read</p>
+</td>
+</tr>
+</tbody>
+</table>
+<p>See recv() for documentation about the flags.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.renegotiate">
+<code class="descname">renegotiate</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.renegotiate"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.renegotiate" title="Permalink to this definition">¶</a></dt>
+<dd><p>Renegotiate this connection’s SSL parameters.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.send">
+<code class="descname">send</code><span class="sig-paren">(</span><em>data</em><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.send" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.sendall">
+<code class="descname">sendall</code><span class="sig-paren">(</span><em>data</em><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.sendall" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.serverPostConnectionCheck">
+<code class="descname">serverPostConnectionCheck</code><span class="sig-paren">(</span><em>**kw</em><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.serverPostConnectionCheck" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.set1_host">
+<code class="descname">set1_host</code><span class="sig-paren">(</span><em>name</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.set1_host"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.set1_host" title="Permalink to this definition">¶</a></dt>
+<dd><p>Set the requested hostname to check in the server certificate.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.set_accept_state">
+<code class="descname">set_accept_state</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.set_accept_state"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.set_accept_state" title="Permalink to this definition">¶</a></dt>
+<dd><p>Sets Connection to work in the server mode.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.set_bio">
+<code class="descname">set_bio</code><span class="sig-paren">(</span><em>readbio</em>, <em>writebio</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.set_bio"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.set_bio" title="Permalink to this definition">¶</a></dt>
+<dd><p>Explicitly set read and write bios</p>
+<p>Connects the BIOs for the read and write operations of the
+TLS/SSL (encrypted) side of ssl.</p>
+<p>The SSL engine inherits the behaviour of both BIO objects,
+respectively. If a BIO is non-blocking, the Connection will also
+have non-blocking behaviour.</p>
+<p>If there was already a BIO connected to Connection, BIO_free()
+will be called (for both the reading and writing side, if
+different).</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>readbio</strong> – BIO for reading</li>
+<li><strong>writebio</strong> – BIO for writing.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.set_cipher_list">
+<code class="descname">set_cipher_list</code><span class="sig-paren">(</span><em>cipher_list</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.set_cipher_list"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.set_cipher_list" title="Permalink to this definition">¶</a></dt>
+<dd><p>Set the cipher suites for this connection.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.set_client_CA_list_from_context">
+<code class="descname">set_client_CA_list_from_context</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.set_client_CA_list_from_context"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.set_client_CA_list_from_context" title="Permalink to this definition">¶</a></dt>
+<dd><p>Set the acceptable client CA list. If the client
+returns a certificate, it must have been issued by
+one of the CAs listed in context.</p>
+<p>Makes sense only for servers.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.set_client_CA_list_from_file">
+<code class="descname">set_client_CA_list_from_file</code><span class="sig-paren">(</span><em>cafile</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.set_client_CA_list_from_file"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.set_client_CA_list_from_file" title="Permalink to this definition">¶</a></dt>
+<dd><p>Set the acceptable client CA list.</p>
+<p>If the client returns a certificate, it must have been issued by
+one of the CAs listed in cafile.</p>
+<p>Makes sense only for servers.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>cafile</strong> – Filename from which to load the CA list.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><dl class="docutils">
+<dt>0 A failure while manipulating the STACK_OF(X509_NAME)</dt>
+<dd>object occurred or the X509_NAME could not be
+extracted from cacert. Check the error stack to find
+out the reason.</dd>
+</dl>
+<p>1 The operation succeeded.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.set_connect_state">
+<code class="descname">set_connect_state</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.set_connect_state"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.set_connect_state" title="Permalink to this definition">¶</a></dt>
+<dd><p>Sets Connection to work in the client mode.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.set_post_connection_check_callback">
+<code class="descname">set_post_connection_check_callback</code><span class="sig-paren">(</span><em>postConnectionCheck</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.set_post_connection_check_callback"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.set_post_connection_check_callback" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.set_session">
+<code class="descname">set_session</code><span class="sig-paren">(</span><em>session</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.set_session"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.set_session" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.set_session_id_ctx">
+<code class="descname">set_session_id_ctx</code><span class="sig-paren">(</span><em>id</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.set_session_id_ctx"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.set_session_id_ctx" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.set_shutdown">
+<code class="descname">set_shutdown</code><span class="sig-paren">(</span><em>mode</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.set_shutdown"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.set_shutdown" title="Permalink to this definition">¶</a></dt>
+<dd><p>Sets the shutdown state of the Connection to mode.</p>
+<p>The shutdown state of an ssl connection is a bitmask of (use
+m2.SSL_* constants):</p>
+<p>0 No shutdown setting, yet.</p>
+<dl class="docutils">
+<dt>SSL_SENT_SHUTDOWN</dt>
+<dd>A “close notify†shutdown alert was sent to the peer, the
+connection is being considered closed and the session is
+closed and correct.</dd>
+<dt>SSL_RECEIVED_SHUTDOWN</dt>
+<dd>A shutdown alert was received form the peer, either a normal
+“close notify†or a fatal error.</dd>
+</dl>
+<p>SSL_SENT_SHUTDOWN and SSL_RECEIVED_SHUTDOWN can be set at the
+same time.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>mode</strong> – set the mode bitmask.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.set_socket_read_timeout">
+<code class="descname">set_socket_read_timeout</code><span class="sig-paren">(</span><em>timeo</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.set_socket_read_timeout"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.set_socket_read_timeout" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.set_socket_write_timeout">
+<code class="descname">set_socket_write_timeout</code><span class="sig-paren">(</span><em>timeo</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.set_socket_write_timeout"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.set_socket_write_timeout" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.set_ssl_close_flag">
+<code class="descname">set_ssl_close_flag</code><span class="sig-paren">(</span><em>flag</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.set_ssl_close_flag"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.set_ssl_close_flag" title="Permalink to this definition">¶</a></dt>
+<dd><p>By default, SSL struct will be freed in __del__. Call with
+m2.bio_close to override this default.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>flag</strong> – either m2.bio_close or m2.bio_noclose</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.set_tlsext_host_name">
+<code class="descname">set_tlsext_host_name</code><span class="sig-paren">(</span><em>name</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.set_tlsext_host_name"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.set_tlsext_host_name" title="Permalink to this definition">¶</a></dt>
+<dd><p>Set the requested hostname for the SNI (Server Name Indication)
+extension.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.setblocking">
+<code class="descname">setblocking</code><span class="sig-paren">(</span><em>mode</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.setblocking"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.setblocking" title="Permalink to this definition">¶</a></dt>
+<dd><p>Set this connection’s underlying socket to _mode_.</p>
+<p>Set blocking or non-blocking mode of the socket: if flag is 0,
+the socket is set to non-blocking, else to blocking mode.
+Initially all sockets are in blocking mode. In non-blocking mode,
+if a recv() call doesn’t find any data, or if a send() call can’t
+immediately dispose of the data, a error exception is raised;
+in blocking mode, the calls block until they can proceed.
+s.setblocking(0) is equivalent to s.settimeout(0.0);
+s.setblocking(1) is equivalent to s.settimeout(None).</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>mode</strong> – new mode to be set</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.setsockopt">
+<code class="descname">setsockopt</code><span class="sig-paren">(</span><em>level</em>, <em>optname</em>, <em>value=None</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.setsockopt"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.setsockopt" title="Permalink to this definition">¶</a></dt>
+<dd><p>Set the value of the given socket option.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>level</strong> – same as with getsockopt() above</li>
+<li><strong>optname</strong> – same as with getsockopt() above</li>
+<li><strong>value</strong> – an integer or a string representing a buffer. In
+the latter case it is up to the caller to ensure
+that the string contains the proper bits (see the
+optional built-in module struct for a way to
+encode C structures as strings).</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">None for success or the error handler for failure.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.settimeout">
+<code class="descname">settimeout</code><span class="sig-paren">(</span><em>timeout</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.settimeout"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.settimeout" title="Permalink to this definition">¶</a></dt>
+<dd><p>Set this connection’s underlying socket’s timeout to _timeout_.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.setup_addr">
+<code class="descname">setup_addr</code><span class="sig-paren">(</span><em>addr</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.setup_addr"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.setup_addr" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.setup_ssl">
+<code class="descname">setup_ssl</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.setup_ssl"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.setup_ssl" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.shutdown">
+<code class="descname">shutdown</code><span class="sig-paren">(</span><em>how</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.shutdown"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.shutdown" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.ssl_get_error">
+<code class="descname">ssl_get_error</code><span class="sig-paren">(</span><em>ret</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.ssl_get_error"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.ssl_get_error" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.verify_ok">
+<code class="descname">verify_ok</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.verify_ok"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.verify_ok" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Connection.Connection.write">
+<code class="descname">write</code><span class="sig-paren">(</span><em>data</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Connection.html#Connection.write"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Connection.Connection.write" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+</dd></dl>
+
+</div>
+<div class="section" id="module-M2Crypto.SSL.Context">
+<span id="context-module"></span><h2><code class="xref py py-mod docutils literal notranslate"><span class="pre">Context</span></code> Module<a class="headerlink" href="#module-M2Crypto.SSL.Context" title="Permalink to this headline">¶</a></h2>
+<dl class="function">
+<dt id="M2Crypto.SSL.Context.ctxmap">
+<code class="descclassname">M2Crypto.SSL.Context.</code><code class="descname">ctxmap</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Context.html#ctxmap"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Context.ctxmap" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="class">
+<dt id="M2Crypto.SSL.Context.Context">
+<em class="property">class </em><code class="descclassname">M2Crypto.SSL.Context.</code><code class="descname">Context</code><span class="sig-paren">(</span><em>protocol='tls'</em>, <em>weak_crypto=None</em>, <em>post_connection_check=None</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Context.html#Context"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Context.Context" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
+<p>‘Context’ for SSL connections.</p>
+<dl class="method">
+<dt id="M2Crypto.SSL.Context.Context.add_session">
+<code class="descname">add_session</code><span class="sig-paren">(</span><em>session</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Context.html#Context.add_session"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Context.Context.add_session" title="Permalink to this definition">¶</a></dt>
+<dd><p>Add the session to the context.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>session</strong> – the session to be added.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><dl class="docutils">
+<dt>0 The operation failed. It was tried to add the same</dt>
+<dd>(identical) session twice.</dd>
+</dl>
+<p>1 The operation succeeded.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Context.Context.close">
+<code class="descname">close</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Context.html#Context.close"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Context.Context.close" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Context.Context.get_allow_unknown_ca">
+<code class="descname">get_allow_unknown_ca</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Context.html#Context.get_allow_unknown_ca"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Context.Context.get_allow_unknown_ca" title="Permalink to this definition">¶</a></dt>
+<dd><p>Get the context’s setting that accepts/rejects a peer
+certificate if the certificate’s CA is unknown.</p>
+<p>FIXME 2Bconverted to bool</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Context.Context.get_cert_store">
+<code class="descname">get_cert_store</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Context.html#Context.get_cert_store"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Context.Context.get_cert_store" title="Permalink to this definition">¶</a></dt>
+<dd><p>Get the certificate store associated with this context.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Warning:</th><td class="field-body">The store is NOT refcounted, and as such can not be relied
+to be valid once the context goes away or is changed.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Context.Context.get_session_cache_mode">
+<code class="descname">get_session_cache_mode</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Context.html#Context.get_session_cache_mode"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Context.Context.get_session_cache_mode" title="Permalink to this definition">¶</a></dt>
+<dd><p>Gets the current session caching.</p>
+<p>The mode is set to m2.SSL_SESS_CACHE_* constants.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">the previously set cache mode value.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Context.Context.get_session_timeout">
+<code class="descname">get_session_timeout</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Context.html#Context.get_session_timeout"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Context.Context.get_session_timeout" title="Permalink to this definition">¶</a></dt>
+<dd><p>Get current session timeout.</p>
+<p>Whenever a new session is created, it is assigned a maximum
+lifetime. This lifetime is specified by storing the creation
+time of the session and the timeout value valid at this time. If
+the actual time is later than creation time plus timeout, the
+session is not reused.</p>
+<p>Due to this realization, all sessions behave according to the
+timeout value valid at the time of the session negotiation.
+Changes of the timeout value do not affect already established
+sessions.</p>
+<p>Expired sessions are removed from the internal session cache,
+whenever SSL_CTX_flush_sessions(3) is called, either directly by
+the application or automatically (see
+SSL_CTX_set_session_cache_mode(3))</p>
+<p>The default value for session timeout is decided on a per
+protocol basis, see SSL_get_default_timeout(3). All currently
+supported protocols have the same default timeout value of 300
+seconds.</p>
+<p>SSL_CTX_set_timeout() returns the previously set timeout value.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">the currently set timeout value.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Context.Context.get_verify_depth">
+<code class="descname">get_verify_depth</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Context.html#Context.get_verify_depth"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Context.Context.get_verify_depth" title="Permalink to this definition">¶</a></dt>
+<dd><p>Returns the verification mode currently set in the SSL Context.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Context.Context.get_verify_mode">
+<code class="descname">get_verify_mode</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Context.html#Context.get_verify_mode"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Context.Context.get_verify_mode" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Context.Context.load_cert">
+<code class="descname">load_cert</code><span class="sig-paren">(</span><em>certfile</em>, <em>keyfile=None</em>, <em>callback=&lt;function passphrase_callback&gt;</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Context.html#Context.load_cert"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Context.Context.load_cert" title="Permalink to this definition">¶</a></dt>
+<dd><p>Load certificate and private key into the context.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>certfile</strong> – File that contains the PEM-encoded certificate.</li>
+<li><strong>keyfile</strong> – File that contains the PEM-encoded private key.
+Default value of None indicates that the private key
+is to be found in ‘certfile’.</li>
+<li><strong>callback</strong> – Callable object to be invoked if the private key is
+passphrase-protected. Default callback provides a
+simple terminal-style input for the passphrase.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Context.Context.load_cert_chain">
+<code class="descname">load_cert_chain</code><span class="sig-paren">(</span><em>certchainfile</em>, <em>keyfile=None</em>, <em>callback=&lt;function passphrase_callback&gt;</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Context.html#Context.load_cert_chain"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Context.Context.load_cert_chain" title="Permalink to this definition">¶</a></dt>
+<dd><p>Load certificate chain and private key into the context.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>certchainfile</strong> – File object containing the PEM-encoded
+certificate chain.</li>
+<li><strong>keyfile</strong> – File object containing the PEM-encoded private
+key. Default value of None indicates that the
+private key is to be found in ‘certchainfile’.</li>
+<li><strong>callback</strong> – Callable object to be invoked if the private key
+is passphrase-protected. Default callback
+provides a simple terminal-style input for the
+passphrase.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Context.Context.load_client_CA">
+<code class="descname">load_client_CA</code><span class="sig-paren">(</span><em>cafile</em><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.SSL.Context.Context.load_client_CA" title="Permalink to this definition">¶</a></dt>
+<dd><p>Load CA certs into the context. These CA certs are sent to the
+peer during <em>SSLv3 certificate request</em>.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>cafile</strong> – File object containing one or more PEM-encoded CA
+certificates concatenated together.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Context.Context.load_client_ca">
+<code class="descname">load_client_ca</code><span class="sig-paren">(</span><em>cafile</em><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.SSL.Context.Context.load_client_ca" title="Permalink to this definition">¶</a></dt>
+<dd><p>Load CA certs into the context. These CA certs are sent to the
+peer during <em>SSLv3 certificate request</em>.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>cafile</strong> – File object containing one or more PEM-encoded CA
+certificates concatenated together.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Context.Context.load_verify_info">
+<code class="descname">load_verify_info</code><span class="sig-paren">(</span><em>cafile=None</em>, <em>capath=None</em><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.SSL.Context.Context.load_verify_info" title="Permalink to this definition">¶</a></dt>
+<dd><p>Load CA certs into the context.</p>
+<p>These CA certs are used during verification of the peer’s
+certificate.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>cafile</strong> – File containing one or more PEM-encoded CA
+certificates concatenated together.</li>
+<li><strong>capath</strong> – Directory containing PEM-encoded CA certificates
+(one certificate per file).</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last"><dl class="docutils">
+<dt>0 if the operation failed because CAfile and CApath are NULL</dt>
+<dd><p class="first last">or the processing at one of the locations specified failed.
+Check the error stack to find out the reason.</p>
+</dd>
+</dl>
+<p>1 The operation succeeded.</p>
+</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Context.Context.load_verify_locations">
+<code class="descname">load_verify_locations</code><span class="sig-paren">(</span><em>cafile=None</em>, <em>capath=None</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Context.html#Context.load_verify_locations"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Context.Context.load_verify_locations" title="Permalink to this definition">¶</a></dt>
+<dd><p>Load CA certs into the context.</p>
+<p>These CA certs are used during verification of the peer’s
+certificate.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>cafile</strong> – File containing one or more PEM-encoded CA
+certificates concatenated together.</li>
+<li><strong>capath</strong> – Directory containing PEM-encoded CA certificates
+(one certificate per file).</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last"><dl class="docutils">
+<dt>0 if the operation failed because CAfile and CApath are NULL</dt>
+<dd><p class="first last">or the processing at one of the locations specified failed.
+Check the error stack to find out the reason.</p>
+</dd>
+</dl>
+<p>1 The operation succeeded.</p>
+</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Context.Context.m2_ssl_ctx_free">
+<code class="descname">m2_ssl_ctx_free</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.SSL.Context.Context.m2_ssl_ctx_free" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Context.Context.remove_session">
+<code class="descname">remove_session</code><span class="sig-paren">(</span><em>session</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Context.html#Context.remove_session"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Context.Context.remove_session" title="Permalink to this definition">¶</a></dt>
+<dd><p>Remove the session from the context.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>session</strong> – the session to be removed.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><dl class="docutils">
+<dt>0 The operation failed. The session was not found in</dt>
+<dd>the cache.</dd>
+</dl>
+<p>1 The operation succeeded.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Context.Context.set_allow_unknown_ca">
+<code class="descname">set_allow_unknown_ca</code><span class="sig-paren">(</span><em>ok</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Context.html#Context.set_allow_unknown_ca"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Context.Context.set_allow_unknown_ca" title="Permalink to this definition">¶</a></dt>
+<dd><p>Set the context to accept/reject a peer certificate if the
+certificate’s CA is unknown.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>ok</strong> – True to accept, False to reject.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Context.Context.set_cipher_list">
+<code class="descname">set_cipher_list</code><span class="sig-paren">(</span><em>cipher_list</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Context.html#Context.set_cipher_list"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Context.Context.set_cipher_list" title="Permalink to this definition">¶</a></dt>
+<dd><p>Sets the list of available ciphers.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>cipher_list</strong> – The format of the string is described in
+ciphers(1).</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">1 if any cipher could be selected and 0 on complete
+failure.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Context.Context.set_client_CA_list_from_file">
+<code class="descname">set_client_CA_list_from_file</code><span class="sig-paren">(</span><em>cafile</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Context.html#Context.set_client_CA_list_from_file"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Context.Context.set_client_CA_list_from_file" title="Permalink to this definition">¶</a></dt>
+<dd><p>Load CA certs into the context. These CA certs are sent to the
+peer during <em>SSLv3 certificate request</em>.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>cafile</strong> – File object containing one or more PEM-encoded CA
+certificates concatenated together.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Context.Context.set_default_verify_paths">
+<code class="descname">set_default_verify_paths</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Context.html#Context.set_default_verify_paths"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Context.Context.set_default_verify_paths" title="Permalink to this definition">¶</a></dt>
+<dd><p>Specifies that the default locations from which CA certs are
+loaded should be used.</p>
+<p>There is one default directory and one default file. The default
+CA certificates directory is called “certs†in the default
+OpenSSL directory. Alternatively the SSL_CERT_DIR environment
+variable can be defined to override this location. The default
+CA certificates file is called “cert.pem†in the default OpenSSL
+directory. Alternatively the SSL_CERT_FILE environment variable
+can be defined to override this location.</p>
+<dl class="docutils">
+<dt>&#64;return 0 if the operation failed. A missing default location is</dt>
+<dd><blockquote class="first">
+<div>still treated as a success. No error code is set.</div></blockquote>
+<p class="last">1 The operation succeeded.</p>
+</dd>
+</dl>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Context.Context.set_info_callback">
+<code class="descname">set_info_callback</code><span class="sig-paren">(</span><em>callback=&lt;function ssl_info_callback&gt;</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Context.html#Context.set_info_callback"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Context.Context.set_info_callback" title="Permalink to this definition">¶</a></dt>
+<dd><p>Set a callback function to get state information.</p>
+<p>It can be used to get state information about the SSL
+connections that are created from this context.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>callback</strong> – Callback function. The default prints
+information to stderr.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Context.Context.set_options">
+<code class="descname">set_options</code><span class="sig-paren">(</span><em>op</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Context.html#Context.set_options"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Context.Context.set_options" title="Permalink to this definition">¶</a></dt>
+<dd><p>Adds the options set via bitmask in options to the Context.</p>
+<p>!!! Options already set before are not cleared!</p>
+<p>The behaviour of the SSL library can be changed by setting
+several options. The options are coded as bitmasks and can be
+combined by a logical or operation (|).</p>
+<p>SSL.Context.set_options() and SSL.set_options() affect the
+(external) protocol behaviour of the SSL library. The (internal)
+behaviour of the API can be changed by using the similar
+SSL.Context.set_mode() and SSL.set_mode() functions.</p>
+<p>During a handshake, the option settings of the SSL object are
+used. When a new SSL object is created from a context using
+SSL(), the current option setting is copied. Changes to ctx
+do not affect already created SSL objects. SSL.clear() does not
+affect the settings.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>op</strong> – bitmask of additional options specified in
+SSL_CTX_set_options(3) manpage.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">the new options bitmask after adding options.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Context.Context.set_session_cache_mode">
+<code class="descname">set_session_cache_mode</code><span class="sig-paren">(</span><em>mode</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Context.html#Context.set_session_cache_mode"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Context.Context.set_session_cache_mode" title="Permalink to this definition">¶</a></dt>
+<dd><p>Enables/disables session caching.</p>
+<p>The mode is set by using m2.SSL_SESS_CACHE_* constants.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>mode</strong> – new mode value.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">the previously set cache mode value.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Context.Context.set_session_id_ctx">
+<code class="descname">set_session_id_ctx</code><span class="sig-paren">(</span><em>id</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Context.html#Context.set_session_id_ctx"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Context.Context.set_session_id_ctx" title="Permalink to this definition">¶</a></dt>
+<dd><p>Sets the session id for the SSL.Context w/in a session can be reused.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>id</strong> – Sessions are generated within a certain context. When
+exporting/importing sessions with
+i2d_SSL_SESSION/d2i_SSL_SESSION it would be possible,
+to re-import a session generated from another context
+(e.g. another application), which might lead to
+malfunctions. Therefore each application must set its
+own session id context sid_ctx which is used to
+distinguish the contexts and is stored in exported
+sessions. The sid_ctx can be any kind of binary data
+with a given length, it is therefore possible to use
+e.g. the name of the application and/or the hostname
+and/or service name.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Context.Context.set_session_timeout">
+<code class="descname">set_session_timeout</code><span class="sig-paren">(</span><em>timeout</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Context.html#Context.set_session_timeout"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Context.Context.set_session_timeout" title="Permalink to this definition">¶</a></dt>
+<dd><p>Set new session timeout.</p>
+<p>See self.get_session_timeout() for explanation of the session
+timeouts.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>timeout</strong> – new timeout value.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">the previously set timeout value.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Context.Context.set_tmp_dh">
+<code class="descname">set_tmp_dh</code><span class="sig-paren">(</span><em>dhpfile</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Context.html#Context.set_tmp_dh"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Context.Context.set_tmp_dh" title="Permalink to this definition">¶</a></dt>
+<dd><p>Load ephemeral DH parameters into the context.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>dhpfile</strong> – Filename of the file containing the PEM-encoded
+DH parameters.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Context.Context.set_tmp_dh_callback">
+<code class="descname">set_tmp_dh_callback</code><span class="sig-paren">(</span><em>callback=None</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Context.html#Context.set_tmp_dh_callback"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Context.Context.set_tmp_dh_callback" title="Permalink to this definition">¶</a></dt>
+<dd><p>Sets the callback function for SSL.Context.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>callback</strong> – Callable to be used when a DH parameters are required.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Context.Context.set_tmp_rsa">
+<code class="descname">set_tmp_rsa</code><span class="sig-paren">(</span><em>rsa</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Context.html#Context.set_tmp_rsa"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Context.Context.set_tmp_rsa" title="Permalink to this definition">¶</a></dt>
+<dd><p>Load ephemeral RSA key into the context.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>rsa</strong> – RSA.RSA instance.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Context.Context.set_tmp_rsa_callback">
+<code class="descname">set_tmp_rsa_callback</code><span class="sig-paren">(</span><em>callback=None</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Context.html#Context.set_tmp_rsa_callback"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Context.Context.set_tmp_rsa_callback" title="Permalink to this definition">¶</a></dt>
+<dd><p>Sets the callback function to be used when
+a temporary/ephemeral RSA key is required.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Context.Context.set_verify">
+<code class="descname">set_verify</code><span class="sig-paren">(</span><em>mode</em>, <em>depth</em>, <em>callback=None</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Context.html#Context.set_verify"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Context.Context.set_verify" title="Permalink to this definition">¶</a></dt>
+<dd><p>Set verify options. Most applications will need to call this
+method with the right options to make a secure SSL connection.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>mode</strong> – The verification mode to use. Typically at least
+SSL.verify_peer is used. Clients would also typically
+add SSL.verify_fail_if_no_peer_cert.</li>
+<li><strong>depth</strong> – The maximum allowed depth of the certificate chain
+returned by the peer.</li>
+<li><strong>callback</strong> – Callable that can be used to specify custom
+verification checks.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.SSL.Context.map">
+<code class="descclassname">M2Crypto.SSL.Context.</code><code class="descname">map</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.SSL.Context.map" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+</div>
+<div class="section" id="module-M2Crypto.SSL.SSLServer">
+<span id="sslserver-module"></span><h2><code class="xref py py-mod docutils literal notranslate"><span class="pre">SSLServer</span></code> Module<a class="headerlink" href="#module-M2Crypto.SSL.SSLServer" title="Permalink to this headline">¶</a></h2>
+<dl class="class">
+<dt id="M2Crypto.SSL.SSLServer.SSLServer">
+<em class="property">class </em><code class="descclassname">M2Crypto.SSL.SSLServer.</code><code class="descname">SSLServer</code><span class="sig-paren">(</span><em>server_address</em>, <em>RequestHandlerClass</em>, <em>ssl_context</em>, <em>bind_and_activate=True</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/SSLServer.html#SSLServer"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.SSLServer.SSLServer" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">socketserver.TCPServer</span></code></p>
+<dl class="method">
+<dt id="M2Crypto.SSL.SSLServer.SSLServer.handle_error">
+<code class="descname">handle_error</code><span class="sig-paren">(</span><em>request</em>, <em>client_address</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/SSLServer.html#SSLServer.handle_error"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.SSLServer.SSLServer.handle_error" title="Permalink to this definition">¶</a></dt>
+<dd><p>Handle an error gracefully. May be overridden.</p>
+<p>The default is to print a traceback and continue.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.SSLServer.SSLServer.handle_request">
+<code class="descname">handle_request</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/SSLServer.html#SSLServer.handle_request"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.SSLServer.SSLServer.handle_request" title="Permalink to this definition">¶</a></dt>
+<dd><p>Handle one request, possibly blocking.</p>
+<p>Respects self.timeout.</p>
+</dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="M2Crypto.SSL.SSLServer.ForkingSSLServer">
+<em class="property">class </em><code class="descclassname">M2Crypto.SSL.SSLServer.</code><code class="descname">ForkingSSLServer</code><span class="sig-paren">(</span><em>server_address</em>, <em>RequestHandlerClass</em>, <em>ssl_context</em>, <em>bind_and_activate=True</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/SSLServer.html#ForkingSSLServer"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.SSLServer.ForkingSSLServer" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">socketserver.ForkingMixIn</span></code>, <a class="reference internal" href="#M2Crypto.SSL.SSLServer.SSLServer" title="M2Crypto.SSL.SSLServer.SSLServer"><code class="xref py py-class docutils literal notranslate"><span class="pre">M2Crypto.SSL.SSLServer.SSLServer</span></code></a></p>
+</dd></dl>
+
+<dl class="class">
+<dt id="M2Crypto.SSL.SSLServer.ThreadingSSLServer">
+<em class="property">class </em><code class="descclassname">M2Crypto.SSL.SSLServer.</code><code class="descname">ThreadingSSLServer</code><span class="sig-paren">(</span><em>server_address</em>, <em>RequestHandlerClass</em>, <em>ssl_context</em>, <em>bind_and_activate=True</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/SSLServer.html#ThreadingSSLServer"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.SSLServer.ThreadingSSLServer" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">socketserver.ThreadingMixIn</span></code>, <a class="reference internal" href="#M2Crypto.SSL.SSLServer.SSLServer" title="M2Crypto.SSL.SSLServer.SSLServer"><code class="xref py py-class docutils literal notranslate"><span class="pre">M2Crypto.SSL.SSLServer.SSLServer</span></code></a></p>
+</dd></dl>
+
+</div>
+<div class="section" id="module-M2Crypto.SSL.Session">
+<span id="session-module"></span><h2><code class="xref py py-mod docutils literal notranslate"><span class="pre">Session</span></code> Module<a class="headerlink" href="#module-M2Crypto.SSL.Session" title="Permalink to this headline">¶</a></h2>
+<p>SSL Session</p>
+<p>Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved.</p>
+<dl class="class">
+<dt id="M2Crypto.SSL.Session.Session">
+<em class="property">class </em><code class="descclassname">M2Crypto.SSL.Session.</code><code class="descname">Session</code><span class="sig-paren">(</span><em>session</em>, <em>_pyfree=0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Session.html#Session"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Session.Session" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
+<dl class="method">
+<dt id="M2Crypto.SSL.Session.Session.as_der">
+<code class="descname">as_der</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Session.html#Session.as_der"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Session.Session.as_der" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Session.Session.as_text">
+<code class="descname">as_text</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Session.html#Session.as_text"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Session.Session.as_text" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Session.Session.get_time">
+<code class="descname">get_time</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Session.html#Session.get_time"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Session.Session.get_time" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Session.Session.get_timeout">
+<code class="descname">get_timeout</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Session.html#Session.get_timeout"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Session.Session.get_timeout" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Session.Session.m2_ssl_session_free">
+<code class="descname">m2_ssl_session_free</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.SSL.Session.Session.m2_ssl_session_free" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Session.Session.set_time">
+<code class="descname">set_time</code><span class="sig-paren">(</span><em>t</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Session.html#Session.set_time"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Session.Session.set_time" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Session.Session.set_timeout">
+<code class="descname">set_timeout</code><span class="sig-paren">(</span><em>t</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Session.html#Session.set_timeout"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Session.Session.set_timeout" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.Session.Session.write_bio">
+<code class="descname">write_bio</code><span class="sig-paren">(</span><em>bio</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Session.html#Session.write_bio"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Session.Session.write_bio" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.SSL.Session.load_session">
+<code class="descclassname">M2Crypto.SSL.Session.</code><code class="descname">load_session</code><span class="sig-paren">(</span><em>pemfile</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/Session.html#load_session"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.Session.load_session" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+</div>
+<div class="section" id="module-M2Crypto.SSL.TwistedProtocolWrapper">
+<span id="twistedprotocolwrapper-module"></span><h2><code class="xref py py-mod docutils literal notranslate"><span class="pre">TwistedProtocolWrapper</span></code> Module<a class="headerlink" href="#module-M2Crypto.SSL.TwistedProtocolWrapper" title="Permalink to this headline">¶</a></h2>
+<p>Make Twisted use M2Crypto for SSL</p>
+<p>Copyright (c) 2004-2007 Open Source Applications Foundation.
+All rights reserved.</p>
+<p>FIXME THIS HAS NOT BEEN FINISHED. NEITHER PEP484 NOR PORT PYTHON3 HAS
+BEEN FINISHED. THE FURTHER WORK WILL BE DONE WHEN THE STATUS OF TWISTED
+IN THE PYTHON 3 (AND ASYNCIO) WORLD WILL BE CLEAR.</p>
+<dl class="function">
+<dt id="M2Crypto.SSL.TwistedProtocolWrapper.connectSSL">
+<code class="descclassname">M2Crypto.SSL.TwistedProtocolWrapper.</code><code class="descname">connectSSL</code><span class="sig-paren">(</span><em>host</em>, <em>port</em>, <em>factory</em>, <em>contextFactory</em>, <em>timeout=30</em>, <em>bindAddress=None</em>, <em>reactor=&lt;twisted.internet.epollreactor.EPollReactor object&gt;</em>, <em>postConnectionCheck=&lt;M2Crypto.SSL.Checker.Checker object&gt;</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/TwistedProtocolWrapper.html#connectSSL"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.TwistedProtocolWrapper.connectSSL" title="Permalink to this definition">¶</a></dt>
+<dd><p>A convenience function to start an SSL/TLS connection using Twisted.</p>
+<p>See IReactorSSL interface in Twisted.</p>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.SSL.TwistedProtocolWrapper.connectTCP">
+<code class="descclassname">M2Crypto.SSL.TwistedProtocolWrapper.</code><code class="descname">connectTCP</code><span class="sig-paren">(</span><em>host</em>, <em>port</em>, <em>factory</em>, <em>timeout=30</em>, <em>bindAddress=None</em>, <em>reactor=&lt;twisted.internet.epollreactor.EPollReactor object&gt;</em>, <em>postConnectionCheck=&lt;M2Crypto.SSL.Checker.Checker object&gt;</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/TwistedProtocolWrapper.html#connectTCP"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.TwistedProtocolWrapper.connectTCP" title="Permalink to this definition">¶</a></dt>
+<dd><p>A convenience function to start a TCP connection using Twisted.</p>
+<p>NOTE: You must call startTLS(ctx) to go into SSL/TLS mode.</p>
+<p>See IReactorTCP interface in Twisted.</p>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.SSL.TwistedProtocolWrapper.listenSSL">
+<code class="descclassname">M2Crypto.SSL.TwistedProtocolWrapper.</code><code class="descname">listenSSL</code><span class="sig-paren">(</span><em>port</em>, <em>factory</em>, <em>contextFactory</em>, <em>backlog=5</em>, <em>interface=''</em>, <em>reactor=&lt;twisted.internet.epollreactor.EPollReactor object&gt;</em>, <em>postConnectionCheck=&lt;function _alwaysSucceedsPostConnectionCheck&gt;</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/TwistedProtocolWrapper.html#listenSSL"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.TwistedProtocolWrapper.listenSSL" title="Permalink to this definition">¶</a></dt>
+<dd><p>A convenience function to listen for SSL/TLS connections using Twisted.</p>
+<p>See IReactorSSL interface in Twisted.</p>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.SSL.TwistedProtocolWrapper.listenTCP">
+<code class="descclassname">M2Crypto.SSL.TwistedProtocolWrapper.</code><code class="descname">listenTCP</code><span class="sig-paren">(</span><em>port</em>, <em>factory</em>, <em>backlog=5</em>, <em>interface=''</em>, <em>reactor=&lt;twisted.internet.epollreactor.EPollReactor object&gt;</em>, <em>postConnectionCheck=None</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/TwistedProtocolWrapper.html#listenTCP"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.TwistedProtocolWrapper.listenTCP" title="Permalink to this definition">¶</a></dt>
+<dd><p>A convenience function to listen for TCP connections using Twisted.</p>
+<p>NOTE: You must call startTLS(ctx) to go into SSL/TLS mode.</p>
+<p>See IReactorTCP interface in Twisted.</p>
+</dd></dl>
+
+<dl class="class">
+<dt id="M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper">
+<em class="property">class </em><code class="descclassname">M2Crypto.SSL.TwistedProtocolWrapper.</code><code class="descname">TLSProtocolWrapper</code><span class="sig-paren">(</span><em>factory</em>, <em>wrappedProtocol</em>, <em>startPassThrough</em>, <em>client</em>, <em>contextFactory</em>, <em>postConnectionCheck</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/TwistedProtocolWrapper.html#TLSProtocolWrapper"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">twisted.protocols.policies.ProtocolWrapper</span></code></p>
+<p>A SSL/TLS protocol wrapper to be used with Twisted. Typically
+you would not use this class directly. Use connectTCP,
+connectSSL, listenTCP, listenSSL functions defined above,
+which will hook in this class.</p>
+<dl class="method">
+<dt id="M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper.clear">
+<code class="descname">clear</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/TwistedProtocolWrapper.html#TLSProtocolWrapper.clear"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper.clear" title="Permalink to this definition">¶</a></dt>
+<dd><p>Clear this instance, after which it is ready for reuse.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper.connectionLost">
+<code class="descname">connectionLost</code><span class="sig-paren">(</span><em>reason</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/TwistedProtocolWrapper.html#TLSProtocolWrapper.connectionLost"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper.connectionLost" title="Permalink to this definition">¶</a></dt>
+<dd><p>Called when the connection is shut down.</p>
+<p>Clear any circular references here, and any external references
+to this Protocol. The connection has been closed.</p>
+<p>&#64;type reason: L{twisted.python.failure.Failure}</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper.connectionMade">
+<code class="descname">connectionMade</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/TwistedProtocolWrapper.html#TLSProtocolWrapper.connectionMade"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper.connectionMade" title="Permalink to this definition">¶</a></dt>
+<dd><p>Called when a connection is made.</p>
+<p>This may be considered the initializer of the protocol, because
+it is called when the connection is completed. For clients,
+this is called once the connection to the server has been
+established; for servers, this is called after an accept() call
+stops blocking and a socket has been received. If you need to
+send any greeting or initial message, do it here.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper.dataReceived">
+<code class="descname">dataReceived</code><span class="sig-paren">(</span><em>data</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/TwistedProtocolWrapper.html#TLSProtocolWrapper.dataReceived"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper.dataReceived" title="Permalink to this definition">¶</a></dt>
+<dd><p>Called whenever data is received.</p>
+<p>Use this method to translate to a higher-level message. Usually, some
+callback will be made upon the receipt of each complete protocol
+message.</p>
+<dl class="docutils">
+<dt>&#64;param data: a string of indeterminate length. Please keep in mind</dt>
+<dd>that you will probably need to buffer some data, as partial
+(or multiple) protocol messages may be received! I recommend
+that unit tests for protocols call through to this method with
+differing chunk sizes, down to one byte at a time.</dd>
+</dl>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper.loseConnection">
+<code class="descname">loseConnection</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/TwistedProtocolWrapper.html#TLSProtocolWrapper.loseConnection"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper.loseConnection" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper.startTLS">
+<code class="descname">startTLS</code><span class="sig-paren">(</span><em>ctx</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/TwistedProtocolWrapper.html#TLSProtocolWrapper.startTLS"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper.startTLS" title="Permalink to this definition">¶</a></dt>
+<dd><p>Start SSL/TLS. If this is not called, this instance just passes data
+through untouched.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper.write">
+<code class="descname">write</code><span class="sig-paren">(</span><em>data</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/TwistedProtocolWrapper.html#TLSProtocolWrapper.write"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper.write" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper.writeSequence">
+<code class="descname">writeSequence</code><span class="sig-paren">(</span><em>data</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/TwistedProtocolWrapper.html#TLSProtocolWrapper.writeSequence"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper.writeSequence" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+</dd></dl>
+
+</div>
+<div class="section" id="module-M2Crypto.SSL.cb">
+<span id="cb-module"></span><h2><code class="xref py py-mod docutils literal notranslate"><span class="pre">cb</span></code> Module<a class="headerlink" href="#module-M2Crypto.SSL.cb" title="Permalink to this headline">¶</a></h2>
+<dl class="function">
+<dt id="M2Crypto.SSL.cb.ssl_verify_callback_stub">
+<code class="descclassname">M2Crypto.SSL.cb.</code><code class="descname">ssl_verify_callback_stub</code><span class="sig-paren">(</span><em>ssl_ctx_ptr</em>, <em>x509_ptr</em>, <em>errnum</em>, <em>errdepth</em>, <em>ok</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/cb.html#ssl_verify_callback_stub"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.cb.ssl_verify_callback_stub" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.SSL.cb.ssl_verify_callback">
+<code class="descclassname">M2Crypto.SSL.cb.</code><code class="descname">ssl_verify_callback</code><span class="sig-paren">(</span><em>ssl_ctx_ptr</em>, <em>x509_ptr</em>, <em>errnum</em>, <em>errdepth</em>, <em>ok</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/cb.html#ssl_verify_callback"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.cb.ssl_verify_callback" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.SSL.cb.ssl_verify_callback_allow_unknown_ca">
+<code class="descclassname">M2Crypto.SSL.cb.</code><code class="descname">ssl_verify_callback_allow_unknown_ca</code><span class="sig-paren">(</span><em>ok</em>, <em>store</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/cb.html#ssl_verify_callback_allow_unknown_ca"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.cb.ssl_verify_callback_allow_unknown_ca" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.SSL.cb.ssl_info_callback">
+<code class="descclassname">M2Crypto.SSL.cb.</code><code class="descname">ssl_info_callback</code><span class="sig-paren">(</span><em>where</em>, <em>ret</em>, <em>ssl_ptr</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/cb.html#ssl_info_callback"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.cb.ssl_info_callback" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+</div>
+<div class="section" id="module-M2Crypto.SSL.ssl_dispatcher">
+<span id="ssl-dispatcher-module"></span><h2><code class="xref py py-mod docutils literal notranslate"><span class="pre">ssl_dispatcher</span></code> Module<a class="headerlink" href="#module-M2Crypto.SSL.ssl_dispatcher" title="Permalink to this headline">¶</a></h2>
+<dl class="class">
+<dt id="M2Crypto.SSL.ssl_dispatcher.ssl_dispatcher">
+<em class="property">class </em><code class="descclassname">M2Crypto.SSL.ssl_dispatcher.</code><code class="descname">ssl_dispatcher</code><span class="sig-paren">(</span><em>sock=None</em>, <em>map=None</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/ssl_dispatcher.html#ssl_dispatcher"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.ssl_dispatcher.ssl_dispatcher" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">asyncore.dispatcher</span></code></p>
+<dl class="method">
+<dt id="M2Crypto.SSL.ssl_dispatcher.ssl_dispatcher.connect">
+<code class="descname">connect</code><span class="sig-paren">(</span><em>addr</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/ssl_dispatcher.html#ssl_dispatcher.connect"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.ssl_dispatcher.ssl_dispatcher.connect" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.ssl_dispatcher.ssl_dispatcher.create_socket">
+<code class="descname">create_socket</code><span class="sig-paren">(</span><em>ssl_context</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/ssl_dispatcher.html#ssl_dispatcher.create_socket"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.ssl_dispatcher.ssl_dispatcher.create_socket" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.ssl_dispatcher.ssl_dispatcher.recv">
+<code class="descname">recv</code><span class="sig-paren">(</span><em>buffer_size=4096</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/ssl_dispatcher.html#ssl_dispatcher.recv"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.ssl_dispatcher.ssl_dispatcher.recv" title="Permalink to this definition">¶</a></dt>
+<dd><p>Receive data over SSL.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SSL.ssl_dispatcher.ssl_dispatcher.send">
+<code class="descname">send</code><span class="sig-paren">(</span><em>buffer</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/ssl_dispatcher.html#ssl_dispatcher.send"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.ssl_dispatcher.ssl_dispatcher.send" title="Permalink to this definition">¶</a></dt>
+<dd><p>Send data over SSL.</p>
+</dd></dl>
+
+</dd></dl>
+
+</div>
+<div class="section" id="module-M2Crypto.SSL.timeout">
+<span id="timeout-module"></span><h2><code class="xref py py-mod docutils literal notranslate"><span class="pre">timeout</span></code> Module<a class="headerlink" href="#module-M2Crypto.SSL.timeout" title="Permalink to this headline">¶</a></h2>
+<p>Support for SSL socket timeouts.</p>
+<p>Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved.</p>
+<p>Copyright 2008 Heikki Toivonen. All rights reserved.</p>
+<dl class="class">
+<dt id="M2Crypto.SSL.timeout.timeout">
+<em class="property">class </em><code class="descclassname">M2Crypto.SSL.timeout.</code><code class="descname">timeout</code><span class="sig-paren">(</span><em>sec=600</em>, <em>microsec=0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/timeout.html#timeout"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.timeout.timeout" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
+<dl class="method">
+<dt id="M2Crypto.SSL.timeout.timeout.pack">
+<code class="descname">pack</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/timeout.html#timeout.pack"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.timeout.timeout.pack" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.SSL.timeout.struct_to_timeout">
+<code class="descclassname">M2Crypto.SSL.timeout.</code><code class="descname">struct_to_timeout</code><span class="sig-paren">(</span><em>binstr</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/timeout.html#struct_to_timeout"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.timeout.struct_to_timeout" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.SSL.timeout.struct_size">
+<code class="descclassname">M2Crypto.SSL.timeout.</code><code class="descname">struct_size</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SSL/timeout.html#struct_size"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SSL.timeout.struct_size" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+</div>
+</div>
+
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="index.html">M2Crypto</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul class="current">
+<li class="toctree-l1 current"><a class="reference internal" href="M2Crypto.html">M2Crypto Package</a><ul class="current">
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#id1"><code class="docutils literal notranslate"><span class="pre">M2Crypto</span></code> Package</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.ASN1"><code class="docutils literal notranslate"><span class="pre">ASN1</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.AuthCookie"><code class="docutils literal notranslate"><span class="pre">AuthCookie</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.BIO"><code class="docutils literal notranslate"><span class="pre">BIO</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.BN"><code class="docutils literal notranslate"><span class="pre">BN</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.DH"><code class="docutils literal notranslate"><span class="pre">DH</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.DSA"><code class="docutils literal notranslate"><span class="pre">DSA</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.EC"><code class="docutils literal notranslate"><span class="pre">EC</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.EVP"><code class="docutils literal notranslate"><span class="pre">EVP</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.Engine"><code class="docutils literal notranslate"><span class="pre">Engine</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.Err"><code class="docutils literal notranslate"><span class="pre">Err</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.RC4"><code class="docutils literal notranslate"><span class="pre">RC4</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.RSA"><code class="docutils literal notranslate"><span class="pre">RSA</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.Rand"><code class="docutils literal notranslate"><span class="pre">Rand</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.SMIME"><code class="docutils literal notranslate"><span class="pre">SMIME</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.X509"><code class="docutils literal notranslate"><span class="pre">X509</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.callback"><code class="docutils literal notranslate"><span class="pre">callback</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.ftpslib"><code class="docutils literal notranslate"><span class="pre">ftpslib</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.httpslib"><code class="docutils literal notranslate"><span class="pre">httpslib</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.m2"><code class="docutils literal notranslate"><span class="pre">m2</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.m2crypto"><code class="docutils literal notranslate"><span class="pre">m2crypto</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.m2urllib"><code class="docutils literal notranslate"><span class="pre">m2urllib</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.m2urllib2"><code class="docutils literal notranslate"><span class="pre">m2urllib2</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.m2xmlrpclib"><code class="docutils literal notranslate"><span class="pre">m2xmlrpclib</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.threading"><code class="docutils literal notranslate"><span class="pre">threading</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.util"><code class="docutils literal notranslate"><span class="pre">util</span></code> Module</a></li>
+<li class="toctree-l2 current"><a class="reference internal" href="M2Crypto.html#subpackages">Subpackages</a><ul class="current">
+<li class="toctree-l3 current"><a class="current reference internal" href="#">SSL Package</a><ul>
+<li class="toctree-l4"><a class="reference internal" href="#id1"><code class="docutils literal notranslate"><span class="pre">SSL</span></code> Package</a></li>
+<li class="toctree-l4"><a class="reference internal" href="#module-M2Crypto.SSL.Checker"><code class="docutils literal notranslate"><span class="pre">Checker</span></code> Module</a></li>
+<li class="toctree-l4"><a class="reference internal" href="#module-M2Crypto.SSL.Cipher"><code class="docutils literal notranslate"><span class="pre">Cipher</span></code> Module</a></li>
+<li class="toctree-l4"><a class="reference internal" href="#module-M2Crypto.SSL.Connection"><code class="docutils literal notranslate"><span class="pre">Connection</span></code> Module</a></li>
+<li class="toctree-l4"><a class="reference internal" href="#module-M2Crypto.SSL.Context"><code class="docutils literal notranslate"><span class="pre">Context</span></code> Module</a></li>
+<li class="toctree-l4"><a class="reference internal" href="#module-M2Crypto.SSL.SSLServer"><code class="docutils literal notranslate"><span class="pre">SSLServer</span></code> Module</a></li>
+<li class="toctree-l4"><a class="reference internal" href="#module-M2Crypto.SSL.Session"><code class="docutils literal notranslate"><span class="pre">Session</span></code> Module</a></li>
+<li class="toctree-l4"><a class="reference internal" href="#module-M2Crypto.SSL.TwistedProtocolWrapper"><code class="docutils literal notranslate"><span class="pre">TwistedProtocolWrapper</span></code> Module</a></li>
+<li class="toctree-l4"><a class="reference internal" href="#module-M2Crypto.SSL.cb"><code class="docutils literal notranslate"><span class="pre">cb</span></code> Module</a></li>
+<li class="toctree-l4"><a class="reference internal" href="#module-M2Crypto.SSL.ssl_dispatcher"><code class="docutils literal notranslate"><span class="pre">ssl_dispatcher</span></code> Module</a></li>
+<li class="toctree-l4"><a class="reference internal" href="#module-M2Crypto.SSL.timeout"><code class="docutils literal notranslate"><span class="pre">timeout</span></code> Module</a></li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="index.html">Documentation overview</a><ul>
+ <li><a href="M2Crypto.html">M2Crypto Package</a><ul>
+ <li>Previous: <a href="M2Crypto.html" title="previous chapter">M2Crypto Package</a></li>
+ </ul></li>
+ </ul></li>
+</ul>
+</div>
+<div id="searchbox" style="display: none" role="search">
+ <h3>Quick search</h3>
+ <div class="searchformwrapper">
+ <form class="search" action="search.html" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ </div>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer">
+ &copy;2017, Matej Cepl <mcepl@cepl.eu>.
+
+ |
+ Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
+ &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
+
+ |
+ <a href="_sources/M2Crypto.SSL.rst.txt"
+ rel="nofollow">Page source</a>
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/M2Crypto.html b/doc/html/M2Crypto.html
new file mode 100644
index 0000000..b659a5e
--- /dev/null
+++ b/doc/html/M2Crypto.html
@@ -0,0 +1,4874 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>M2Crypto Package &#8212; M2Crypto documentation</title>
+ <link rel="stylesheet" href="_static/alabaster.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <script type="text/javascript" src="_static/language_data.js"></script>
+ <link rel="index" title="Index" href="genindex.html" />
+ <link rel="search" title="Search" href="search.html" />
+ <link rel="next" title="SSL Package" href="M2Crypto.SSL.html" />
+ <link rel="prev" title="Welcome to M2Crypto’s documentation!" href="index.html" />
+
+ <link rel="stylesheet" href="_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+ <div class="section" id="m2crypto-package">
+<h1>M2Crypto Package<a class="headerlink" href="#m2crypto-package" title="Permalink to this headline">¶</a></h1>
+<div class="section" id="id1">
+<h2><code class="xref py py-mod docutils literal notranslate"><span class="pre">M2Crypto</span></code> Package<a class="headerlink" href="#id1" title="Permalink to this headline">¶</a></h2>
+<span class="target" id="module-M2Crypto.__init__"></span></div>
+<div class="section" id="module-M2Crypto.ASN1">
+<span id="asn1-module"></span><h2><code class="xref py py-mod docutils literal notranslate"><span class="pre">ASN1</span></code> Module<a class="headerlink" href="#module-M2Crypto.ASN1" title="Permalink to this headline">¶</a></h2>
+<dl class="class">
+<dt id="M2Crypto.ASN1.ASN1_Integer">
+<em class="property">class </em><code class="descclassname">M2Crypto.ASN1.</code><code class="descname">ASN1_Integer</code><span class="sig-paren">(</span><em>asn1int</em>, <em>_pyfree=0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/ASN1.html#ASN1_Integer"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.ASN1.ASN1_Integer" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
+<dl class="method">
+<dt id="M2Crypto.ASN1.ASN1_Integer.m2_asn1_integer_free">
+<code class="descname">m2_asn1_integer_free</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.ASN1.ASN1_Integer.m2_asn1_integer_free" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="M2Crypto.ASN1.ASN1_Object">
+<em class="property">class </em><code class="descclassname">M2Crypto.ASN1.</code><code class="descname">ASN1_Object</code><span class="sig-paren">(</span><em>asn1obj</em>, <em>_pyfree=0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/ASN1.html#ASN1_Object"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.ASN1.ASN1_Object" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
+<dl class="method">
+<dt id="M2Crypto.ASN1.ASN1_Object.m2_asn1_object_free">
+<code class="descname">m2_asn1_object_free</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.ASN1.ASN1_Object.m2_asn1_object_free" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="M2Crypto.ASN1.ASN1_String">
+<em class="property">class </em><code class="descclassname">M2Crypto.ASN1.</code><code class="descname">ASN1_String</code><span class="sig-paren">(</span><em>asn1str</em>, <em>_pyfree=0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/ASN1.html#ASN1_String"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.ASN1.ASN1_String" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
+<dl class="method">
+<dt id="M2Crypto.ASN1.ASN1_String.as_text">
+<code class="descname">as_text</code><span class="sig-paren">(</span><em>flags=0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/ASN1.html#ASN1_String.as_text"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.ASN1.ASN1_String.as_text" title="Permalink to this definition">¶</a></dt>
+<dd><p>Output an ASN1_STRING structure according to the set flags.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>flags</strong> – determine the format of the output by using
+predetermined constants, see ASN1_STRING_print_ex(3)
+manpage for their meaning.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">output an ASN1_STRING structure.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.ASN1.ASN1_String.m2_asn1_string_free">
+<code class="descname">m2_asn1_string_free</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.ASN1.ASN1_String.m2_asn1_string_free" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="M2Crypto.ASN1.ASN1_TIME">
+<em class="property">class </em><code class="descclassname">M2Crypto.ASN1.</code><code class="descname">ASN1_TIME</code><span class="sig-paren">(</span><em>asn1_time=None</em>, <em>_pyfree=0</em>, <em>asn1_utctime=None</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/ASN1.html#ASN1_TIME"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.ASN1.ASN1_TIME" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
+<dl class="method">
+<dt id="M2Crypto.ASN1.ASN1_TIME.get_datetime">
+<code class="descname">get_datetime</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/ASN1.html#ASN1_TIME.get_datetime"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.ASN1.ASN1_TIME.get_datetime" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.ASN1.ASN1_TIME.m2_asn1_time_free">
+<code class="descname">m2_asn1_time_free</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.ASN1.ASN1_TIME.m2_asn1_time_free" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.ASN1.ASN1_TIME.set_datetime">
+<code class="descname">set_datetime</code><span class="sig-paren">(</span><em>date</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/ASN1.html#ASN1_TIME.set_datetime"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.ASN1.ASN1_TIME.set_datetime" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.ASN1.ASN1_TIME.set_string">
+<code class="descname">set_string</code><span class="sig-paren">(</span><em>string</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/ASN1.html#ASN1_TIME.set_string"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.ASN1.ASN1_TIME.set_string" title="Permalink to this definition">¶</a></dt>
+<dd><p>Set time from UTC string.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.ASN1.ASN1_TIME.set_time">
+<code class="descname">set_time</code><span class="sig-paren">(</span><em>time</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/ASN1.html#ASN1_TIME.set_time"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.ASN1.ASN1_TIME.set_time" title="Permalink to this definition">¶</a></dt>
+<dd><p>Set time from seconds since epoch (int).</p>
+</dd></dl>
+
+</dd></dl>
+
+<dl class="attribute">
+<dt id="M2Crypto.ASN1.ASN1_UTCTIME">
+<code class="descclassname">M2Crypto.ASN1.</code><code class="descname">ASN1_UTCTIME</code><a class="headerlink" href="#M2Crypto.ASN1.ASN1_UTCTIME" title="Permalink to this definition">¶</a></dt>
+<dd><p>alias of <a class="reference internal" href="#M2Crypto.ASN1.ASN1_TIME" title="M2Crypto.ASN1.ASN1_TIME"><code class="xref py py-class docutils literal notranslate"><span class="pre">M2Crypto.ASN1.ASN1_TIME</span></code></a></p>
+</dd></dl>
+
+<dl class="class">
+<dt id="M2Crypto.ASN1.LocalTimezone">
+<em class="property">class </em><code class="descclassname">M2Crypto.ASN1.</code><code class="descname">LocalTimezone</code><a class="reference internal" href="_modules/M2Crypto/ASN1.html#LocalTimezone"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.ASN1.LocalTimezone" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">datetime.tzinfo</span></code></p>
+<p>Localtimezone from datetime manual.</p>
+<dl class="method">
+<dt id="M2Crypto.ASN1.LocalTimezone.dst">
+<code class="descname">dst</code><span class="sig-paren">(</span><em>dt</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/ASN1.html#LocalTimezone.dst"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.ASN1.LocalTimezone.dst" title="Permalink to this definition">¶</a></dt>
+<dd><p>datetime -&gt; DST offset as timedelta positive east of UTC.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.ASN1.LocalTimezone.tzname">
+<code class="descname">tzname</code><span class="sig-paren">(</span><em>dt</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/ASN1.html#LocalTimezone.tzname"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.ASN1.LocalTimezone.tzname" title="Permalink to this definition">¶</a></dt>
+<dd><p>datetime -&gt; string name of time zone.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.ASN1.LocalTimezone.utcoffset">
+<code class="descname">utcoffset</code><span class="sig-paren">(</span><em>dt</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/ASN1.html#LocalTimezone.utcoffset"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.ASN1.LocalTimezone.utcoffset" title="Permalink to this definition">¶</a></dt>
+<dd><p>datetime -&gt; timedelta showing offset from UTC, negative values indicating West of UTC</p>
+</dd></dl>
+
+</dd></dl>
+
+</div>
+<div class="section" id="module-M2Crypto.AuthCookie">
+<span id="authcookie-module"></span><h2><code class="xref py py-mod docutils literal notranslate"><span class="pre">AuthCookie</span></code> Module<a class="headerlink" href="#module-M2Crypto.AuthCookie" title="Permalink to this headline">¶</a></h2>
+<dl class="class">
+<dt id="M2Crypto.AuthCookie.AuthCookie">
+<em class="property">class </em><code class="descclassname">M2Crypto.AuthCookie.</code><code class="descname">AuthCookie</code><span class="sig-paren">(</span><em>expiry</em>, <em>data</em>, <em>dough</em>, <em>mac</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/AuthCookie.html#AuthCookie"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.AuthCookie.AuthCookie" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
+<dl class="method">
+<dt id="M2Crypto.AuthCookie.AuthCookie.data">
+<code class="descname">data</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/AuthCookie.html#AuthCookie.data"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.AuthCookie.AuthCookie.data" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return the data portion of the cookie.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.AuthCookie.AuthCookie.expiry">
+<code class="descname">expiry</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/AuthCookie.html#AuthCookie.expiry"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.AuthCookie.AuthCookie.expiry" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return the cookie’s expiry time.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.AuthCookie.AuthCookie.headerValue">
+<code class="descname">headerValue</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/AuthCookie.html#AuthCookie.headerValue"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.AuthCookie.AuthCookie.headerValue" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.AuthCookie.AuthCookie.isExpired">
+<code class="descname">isExpired</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/AuthCookie.html#AuthCookie.isExpired"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.AuthCookie.AuthCookie.isExpired" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return 1 if the cookie has expired, 0 otherwise.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.AuthCookie.AuthCookie.mac">
+<code class="descname">mac</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/AuthCookie.html#AuthCookie.mac"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.AuthCookie.AuthCookie.mac" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return the cookie’s MAC.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.AuthCookie.AuthCookie.name">
+<code class="descname">name</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/AuthCookie.html#AuthCookie.name"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.AuthCookie.AuthCookie.name" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.AuthCookie.AuthCookie.output">
+<code class="descname">output</code><span class="sig-paren">(</span><em>header='Set-Cookie:'</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/AuthCookie.html#AuthCookie.output"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.AuthCookie.AuthCookie.output" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return the cookie’s output in “Set-Cookie†format.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.AuthCookie.AuthCookie.value">
+<code class="descname">value</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/AuthCookie.html#AuthCookie.value"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.AuthCookie.AuthCookie.value" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return the cookie’s output minus the “Set-Cookie: †portion.</p>
+</dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="M2Crypto.AuthCookie.AuthCookieJar">
+<em class="property">class </em><code class="descclassname">M2Crypto.AuthCookie.</code><code class="descname">AuthCookieJar</code><a class="reference internal" href="_modules/M2Crypto/AuthCookie.html#AuthCookieJar"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.AuthCookie.AuthCookieJar" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
+<dl class="method">
+<dt id="M2Crypto.AuthCookie.AuthCookieJar.isGoodCookie">
+<code class="descname">isGoodCookie</code><span class="sig-paren">(</span><em>cookie</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/AuthCookie.html#AuthCookieJar.isGoodCookie"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.AuthCookie.AuthCookieJar.isGoodCookie" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.AuthCookie.AuthCookieJar.isGoodCookieString">
+<code class="descname">isGoodCookieString</code><span class="sig-paren">(</span><em>cookie_str</em>, <em>_debug=False</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/AuthCookie.html#AuthCookieJar.isGoodCookieString"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.AuthCookie.AuthCookieJar.isGoodCookieString" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.AuthCookie.AuthCookieJar.makeCookie">
+<code class="descname">makeCookie</code><span class="sig-paren">(</span><em>expiry</em>, <em>data</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/AuthCookie.html#AuthCookieJar.makeCookie"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.AuthCookie.AuthCookieJar.makeCookie" title="Permalink to this definition">¶</a></dt>
+<dd><p>Make a cookie</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>expiry</strong> – expiration time (float in seconds)</li>
+<li><strong>data</strong> – cookie content</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">AuthCookie object</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.AuthCookie.mix">
+<code class="descclassname">M2Crypto.AuthCookie.</code><code class="descname">mix</code><span class="sig-paren">(</span><em>expiry</em>, <em>data</em>, <em>format='exp=%f&amp;data=%s&amp;digest='</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/AuthCookie.html#mix"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.AuthCookie.mix" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.AuthCookie.unmix">
+<code class="descclassname">M2Crypto.AuthCookie.</code><code class="descname">unmix</code><span class="sig-paren">(</span><em>dough</em>, <em>regex=re.compile('exp=(\\d+\\.\\d+)&amp;data=(.+)&amp;digest=(\\S*)')</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/AuthCookie.html#unmix"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.AuthCookie.unmix" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.AuthCookie.unmix3">
+<code class="descclassname">M2Crypto.AuthCookie.</code><code class="descname">unmix3</code><span class="sig-paren">(</span><em>dough</em>, <em>regex=re.compile('exp=(\\d+\\.\\d+)&amp;data=(.+)&amp;digest=(\\S*)')</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/AuthCookie.html#unmix3"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.AuthCookie.unmix3" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+</div>
+<div class="section" id="module-M2Crypto.BIO">
+<span id="bio-module"></span><h2><code class="xref py py-mod docutils literal notranslate"><span class="pre">BIO</span></code> Module<a class="headerlink" href="#module-M2Crypto.BIO" title="Permalink to this headline">¶</a></h2>
+<dl class="class">
+<dt id="M2Crypto.BIO.BIO">
+<em class="property">class </em><code class="descclassname">M2Crypto.BIO.</code><code class="descname">BIO</code><span class="sig-paren">(</span><em>bio=None</em>, <em>_pyfree=0</em>, <em>_close_cb=None</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/BIO.html#BIO"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.BIO.BIO" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
+<p>Abstract object interface to the BIO API.</p>
+<dl class="method">
+<dt id="M2Crypto.BIO.BIO.bio_ptr">
+<code class="descname">bio_ptr</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.BIO.BIO.bio_ptr" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.BIO.BIO.close">
+<code class="descname">close</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/BIO.html#BIO.close"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.BIO.BIO.close" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.BIO.BIO.fileno">
+<code class="descname">fileno</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/BIO.html#BIO.fileno"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.BIO.BIO.fileno" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.BIO.BIO.flush">
+<code class="descname">flush</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/BIO.html#BIO.flush"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.BIO.BIO.flush" title="Permalink to this definition">¶</a></dt>
+<dd><p>Flush the buffers.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">1 for success, and 0 or -1 for failure</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.BIO.BIO.m2_bio_free">
+<code class="descname">m2_bio_free</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.BIO.BIO.m2_bio_free" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.BIO.BIO.read">
+<code class="descname">read</code><span class="sig-paren">(</span><em>size=None</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/BIO.html#BIO.read"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.BIO.BIO.read" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.BIO.BIO.readable">
+<code class="descname">readable</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/BIO.html#BIO.readable"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.BIO.BIO.readable" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.BIO.BIO.readline">
+<code class="descname">readline</code><span class="sig-paren">(</span><em>size=4096</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/BIO.html#BIO.readline"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.BIO.BIO.readline" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.BIO.BIO.readlines">
+<code class="descname">readlines</code><span class="sig-paren">(</span><em>sizehint='ignored'</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/BIO.html#BIO.readlines"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.BIO.BIO.readlines" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.BIO.BIO.reset">
+<code class="descname">reset</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/BIO.html#BIO.reset"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.BIO.BIO.reset" title="Permalink to this definition">¶</a></dt>
+<dd><p>Set the bio to its initial state.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">1 for success, and 0 or -1 for failure</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.BIO.BIO.seek">
+<code class="descname">seek</code><span class="sig-paren">(</span><em>off</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/BIO.html#BIO.seek"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.BIO.BIO.seek" title="Permalink to this definition">¶</a></dt>
+<dd><p>Seek to the specified absolute offset.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.BIO.BIO.should_read">
+<code class="descname">should_read</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/BIO.html#BIO.should_read"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.BIO.BIO.should_read" title="Permalink to this definition">¶</a></dt>
+<dd><p>Should we read more data?</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.BIO.BIO.should_retry">
+<code class="descname">should_retry</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/BIO.html#BIO.should_retry"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.BIO.BIO.should_retry" title="Permalink to this definition">¶</a></dt>
+<dd><p>Can the call be attempted again, or was there an error
+ie do_handshake</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.BIO.BIO.should_write">
+<code class="descname">should_write</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/BIO.html#BIO.should_write"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.BIO.BIO.should_write" title="Permalink to this definition">¶</a></dt>
+<dd><p>Should we write more data?</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.BIO.BIO.tell">
+<code class="descname">tell</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/BIO.html#BIO.tell"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.BIO.BIO.tell" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return the current offset.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.BIO.BIO.write">
+<code class="descname">write</code><span class="sig-paren">(</span><em>data</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/BIO.html#BIO.write"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.BIO.BIO.write" title="Permalink to this definition">¶</a></dt>
+<dd><p>Write data to BIO.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">either data written, or [0, -1] for nothing written,
+-2 not implemented</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.BIO.BIO.write_close">
+<code class="descname">write_close</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/BIO.html#BIO.write_close"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.BIO.BIO.write_close" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.BIO.BIO.writeable">
+<code class="descname">writeable</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/BIO.html#BIO.writeable"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.BIO.BIO.writeable" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+</dd></dl>
+
+<dl class="exception">
+<dt id="M2Crypto.BIO.BIOError">
+<em class="property">exception </em><code class="descclassname">M2Crypto.BIO.</code><code class="descname">BIOError</code><a class="reference internal" href="_modules/M2Crypto/BIO.html#BIOError"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.BIO.BIOError" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">ValueError</span></code></p>
+</dd></dl>
+
+<dl class="class">
+<dt id="M2Crypto.BIO.CipherStream">
+<em class="property">class </em><code class="descclassname">M2Crypto.BIO.</code><code class="descname">CipherStream</code><span class="sig-paren">(</span><em>obio</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/BIO.html#CipherStream"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.BIO.CipherStream" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <a class="reference internal" href="#M2Crypto.BIO.BIO" title="M2Crypto.BIO.BIO"><code class="xref py py-class docutils literal notranslate"><span class="pre">M2Crypto.BIO.BIO</span></code></a></p>
+<p>Object interface to BIO_f_cipher.</p>
+<dl class="attribute">
+<dt id="M2Crypto.BIO.CipherStream.SALT_LEN">
+<code class="descname">SALT_LEN</code><em class="property"> = 8</em><a class="headerlink" href="#M2Crypto.BIO.CipherStream.SALT_LEN" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.BIO.CipherStream.close">
+<code class="descname">close</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/BIO.html#CipherStream.close"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.BIO.CipherStream.close" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.BIO.CipherStream.m2_bio_free">
+<code class="descname">m2_bio_free</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.BIO.CipherStream.m2_bio_free" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.BIO.CipherStream.m2_bio_pop">
+<code class="descname">m2_bio_pop</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.BIO.CipherStream.m2_bio_pop" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.BIO.CipherStream.set_cipher">
+<code class="descname">set_cipher</code><span class="sig-paren">(</span><em>algo</em>, <em>key</em>, <em>iv</em>, <em>op</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/BIO.html#CipherStream.set_cipher"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.BIO.CipherStream.set_cipher" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.BIO.CipherStream.write_close">
+<code class="descname">write_close</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/BIO.html#CipherStream.write_close"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.BIO.CipherStream.write_close" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="M2Crypto.BIO.File">
+<em class="property">class </em><code class="descclassname">M2Crypto.BIO.</code><code class="descname">File</code><span class="sig-paren">(</span><em>pyfile</em>, <em>close_pyfile=1</em>, <em>mode='rb'</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/BIO.html#File"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.BIO.File" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <a class="reference internal" href="#M2Crypto.BIO.BIO" title="M2Crypto.BIO.BIO"><code class="xref py py-class docutils literal notranslate"><span class="pre">M2Crypto.BIO.BIO</span></code></a></p>
+<p>Object interface to BIO_s_pyfd.</p>
+<p>This class interfaces Python to OpenSSL functions that expect BIO. For
+general file manipulation in Python, use Python’s builtin file object.</p>
+<dl class="method">
+<dt id="M2Crypto.BIO.File.close">
+<code class="descname">close</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/BIO.html#File.close"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.BIO.File.close" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.BIO.File.flush">
+<code class="descname">flush</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/BIO.html#File.flush"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.BIO.File.flush" title="Permalink to this definition">¶</a></dt>
+<dd><p>Flush the buffers.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">1 for success, and 0 or -1 for failure</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.BIO.File.reset">
+<code class="descname">reset</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/BIO.html#File.reset"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.BIO.File.reset" title="Permalink to this definition">¶</a></dt>
+<dd><p>Set the bio to its initial state.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">0 for success, and -1 for failure</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="M2Crypto.BIO.IOBuffer">
+<em class="property">class </em><code class="descclassname">M2Crypto.BIO.</code><code class="descname">IOBuffer</code><span class="sig-paren">(</span><em>under_bio</em>, <em>mode='rwb'</em>, <em>_pyfree=1</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/BIO.html#IOBuffer"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.BIO.IOBuffer" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <a class="reference internal" href="#M2Crypto.BIO.BIO" title="M2Crypto.BIO.BIO"><code class="xref py py-class docutils literal notranslate"><span class="pre">M2Crypto.BIO.BIO</span></code></a></p>
+<p>Object interface to BIO_f_buffer.</p>
+<p>Its principal function is to be BIO_push()’ed on top of a BIO_f_ssl, so
+that makefile() of said underlying SSL socket works.</p>
+<dl class="method">
+<dt id="M2Crypto.BIO.IOBuffer.close">
+<code class="descname">close</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/BIO.html#IOBuffer.close"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.BIO.IOBuffer.close" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.BIO.IOBuffer.m2_bio_free">
+<code class="descname">m2_bio_free</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.BIO.IOBuffer.m2_bio_free" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.BIO.IOBuffer.m2_bio_pop">
+<code class="descname">m2_bio_pop</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.BIO.IOBuffer.m2_bio_pop" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="M2Crypto.BIO.MemoryBuffer">
+<em class="property">class </em><code class="descclassname">M2Crypto.BIO.</code><code class="descname">MemoryBuffer</code><span class="sig-paren">(</span><em>data=None</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/BIO.html#MemoryBuffer"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.BIO.MemoryBuffer" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <a class="reference internal" href="#M2Crypto.BIO.BIO" title="M2Crypto.BIO.BIO"><code class="xref py py-class docutils literal notranslate"><span class="pre">M2Crypto.BIO.BIO</span></code></a></p>
+<p>Object interface to BIO_s_mem.</p>
+<p>Empirical testing suggests that this class performs less well than
+cStringIO, because cStringIO is implemented in C, whereas this class
+is implemented in Python. Thus, the recommended practice is to use
+cStringIO for regular work and convert said cStringIO object to
+a MemoryBuffer object only when necessary.</p>
+<dl class="method">
+<dt id="M2Crypto.BIO.MemoryBuffer.close">
+<code class="descname">close</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.BIO.MemoryBuffer.close" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.BIO.MemoryBuffer.getvalue">
+<code class="descname">getvalue</code><span class="sig-paren">(</span><em>size=0</em><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.BIO.MemoryBuffer.getvalue" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.BIO.MemoryBuffer.read">
+<code class="descname">read</code><span class="sig-paren">(</span><em>size=0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/BIO.html#MemoryBuffer.read"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.BIO.MemoryBuffer.read" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.BIO.MemoryBuffer.read_all">
+<code class="descname">read_all</code><span class="sig-paren">(</span><em>size=0</em><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.BIO.MemoryBuffer.read_all" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.BIO.MemoryBuffer.write_close">
+<code class="descname">write_close</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/BIO.html#MemoryBuffer.write_close"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.BIO.MemoryBuffer.write_close" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="M2Crypto.BIO.SSLBio">
+<em class="property">class </em><code class="descclassname">M2Crypto.BIO.</code><code class="descname">SSLBio</code><span class="sig-paren">(</span><em>_pyfree=1</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/BIO.html#SSLBio"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.BIO.SSLBio" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <a class="reference internal" href="#M2Crypto.BIO.BIO" title="M2Crypto.BIO.BIO"><code class="xref py py-class docutils literal notranslate"><span class="pre">M2Crypto.BIO.BIO</span></code></a></p>
+<p>Object interface to BIO_f_ssl.</p>
+<dl class="method">
+<dt id="M2Crypto.BIO.SSLBio.do_handshake">
+<code class="descname">do_handshake</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/BIO.html#SSLBio.do_handshake"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.BIO.SSLBio.do_handshake" title="Permalink to this definition">¶</a></dt>
+<dd><p>Do the handshake.</p>
+<p>Return 1 if the handshake completes
+Return 0 or a negative number if there is a problem</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.BIO.SSLBio.set_ssl">
+<code class="descname">set_ssl</code><span class="sig-paren">(</span><em>conn</em>, <em>close_flag=0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/BIO.html#SSLBio.set_ssl"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.BIO.SSLBio.set_ssl" title="Permalink to this definition">¶</a></dt>
+<dd><p>Sets the bio to the SSL pointer which is
+contained in the connection object.</p>
+</dd></dl>
+
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.BIO.openfile">
+<code class="descclassname">M2Crypto.BIO.</code><code class="descname">openfile</code><span class="sig-paren">(</span><em>filename</em>, <em>mode='rb'</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/BIO.html#openfile"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.BIO.openfile" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+</div>
+<div class="section" id="module-M2Crypto.BN">
+<span id="bn-module"></span><h2><code class="xref py py-mod docutils literal notranslate"><span class="pre">BN</span></code> Module<a class="headerlink" href="#module-M2Crypto.BN" title="Permalink to this headline">¶</a></h2>
+<dl class="function">
+<dt id="M2Crypto.BN.rand">
+<code class="descclassname">M2Crypto.BN.</code><code class="descname">rand</code><span class="sig-paren">(</span><em>bits</em>, <em>top=-1</em>, <em>bottom=0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/BN.html#rand"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.BN.rand" title="Permalink to this definition">¶</a></dt>
+<dd><p>Generate cryptographically strong random number.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>bits</strong> – Length of random number in bits.</li>
+<li><strong>top</strong> – If -1, the most significant bit can be 0. If 0, the most
+significant bit is 1, and if 1, the two most significant
+bits will be 1.</li>
+<li><strong>bottom</strong> – If bottom is true, the number will be odd.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.BN.rand_range">
+<code class="descclassname">M2Crypto.BN.</code><code class="descname">rand_range</code><span class="sig-paren">(</span><em>range</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/BN.html#rand_range"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.BN.rand_range" title="Permalink to this definition">¶</a></dt>
+<dd><p>Generate a random number in a range.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>range</strong> – Upper limit for range.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">A random number in the range [0, range)</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.BN.randfname">
+<code class="descclassname">M2Crypto.BN.</code><code class="descname">randfname</code><span class="sig-paren">(</span><em>length</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/BN.html#randfname"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.BN.randfname" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return a random filename, which is simply a string where all
+the characters are from the set [a-zA-Z0-9].</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>length</strong> – Length of filename to return.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">random filename string</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+</div>
+<div class="section" id="module-M2Crypto.DH">
+<span id="dh-module"></span><h2><code class="xref py py-mod docutils literal notranslate"><span class="pre">DH</span></code> Module<a class="headerlink" href="#module-M2Crypto.DH" title="Permalink to this headline">¶</a></h2>
+<dl class="class">
+<dt id="M2Crypto.DH.DH">
+<em class="property">class </em><code class="descclassname">M2Crypto.DH.</code><code class="descname">DH</code><span class="sig-paren">(</span><em>dh</em>, <em>_pyfree=0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/DH.html#DH"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.DH.DH" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
+<p>Object interface to the Diffie-Hellman key exchange protocol.</p>
+<dl class="method">
+<dt id="M2Crypto.DH.DH.check_params">
+<code class="descname">check_params</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/DH.html#DH.check_params"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.DH.DH.check_params" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.DH.DH.compute_key">
+<code class="descname">compute_key</code><span class="sig-paren">(</span><em>pubkey</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/DH.html#DH.compute_key"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.DH.DH.compute_key" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.DH.DH.gen_key">
+<code class="descname">gen_key</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/DH.html#DH.gen_key"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.DH.DH.gen_key" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.DH.DH.m2_dh_free">
+<code class="descname">m2_dh_free</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.DH.DH.m2_dh_free" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.DH.DH.print_params">
+<code class="descname">print_params</code><span class="sig-paren">(</span><em>bio</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/DH.html#DH.print_params"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.DH.DH.print_params" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+</dd></dl>
+
+<dl class="exception">
+<dt id="M2Crypto.DH.DHError">
+<em class="property">exception </em><code class="descclassname">M2Crypto.DH.</code><code class="descname">DHError</code><a class="reference internal" href="_modules/M2Crypto/DH.html#DHError"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.DH.DHError" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">Exception</span></code></p>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.DH.gen_params">
+<code class="descclassname">M2Crypto.DH.</code><code class="descname">gen_params</code><span class="sig-paren">(</span><em>plen</em>, <em>g</em>, <em>callback=&lt;function genparam_callback&gt;</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/DH.html#gen_params"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.DH.gen_params" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.DH.load_params">
+<code class="descclassname">M2Crypto.DH.</code><code class="descname">load_params</code><span class="sig-paren">(</span><em>file</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/DH.html#load_params"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.DH.load_params" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.DH.load_params_bio">
+<code class="descclassname">M2Crypto.DH.</code><code class="descname">load_params_bio</code><span class="sig-paren">(</span><em>bio</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/DH.html#load_params_bio"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.DH.load_params_bio" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.DH.set_params">
+<code class="descclassname">M2Crypto.DH.</code><code class="descname">set_params</code><span class="sig-paren">(</span><em>p</em>, <em>g</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/DH.html#set_params"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.DH.set_params" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+</div>
+<div class="section" id="module-M2Crypto.DSA">
+<span id="dsa-module"></span><h2><code class="xref py py-mod docutils literal notranslate"><span class="pre">DSA</span></code> Module<a class="headerlink" href="#module-M2Crypto.DSA" title="Permalink to this headline">¶</a></h2>
+<dl class="class">
+<dt id="M2Crypto.DSA.DSA">
+<em class="property">class </em><code class="descclassname">M2Crypto.DSA.</code><code class="descname">DSA</code><span class="sig-paren">(</span><em>dsa</em>, <em>_pyfree=0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/DSA.html#DSA"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.DSA.DSA" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
+<p>This class is a context supporting DSA key and parameter
+values, signing and verifying.</p>
+<p>Simple example:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">M2Crypto</span> <span class="k">import</span> <span class="n">EVP</span><span class="p">,</span> <span class="n">DSA</span><span class="p">,</span> <span class="n">util</span>
+
+<span class="n">message</span> <span class="o">=</span> <span class="s1">&#39;Kilroy was here!&#39;</span>
+<span class="n">md</span> <span class="o">=</span> <span class="n">EVP</span><span class="o">.</span><span class="n">MessageDigest</span><span class="p">(</span><span class="s1">&#39;sha1&#39;</span><span class="p">)</span>
+<span class="n">md</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">message</span><span class="p">)</span>
+<span class="n">digest</span> <span class="o">=</span> <span class="n">md</span><span class="o">.</span><span class="n">final</span><span class="p">()</span>
+
+<span class="n">dsa</span> <span class="o">=</span> <span class="n">DSA</span><span class="o">.</span><span class="n">gen_params</span><span class="p">(</span><span class="mi">1024</span><span class="p">)</span>
+<span class="n">dsa</span><span class="o">.</span><span class="n">gen_key</span><span class="p">()</span>
+<span class="n">r</span><span class="p">,</span> <span class="n">s</span> <span class="o">=</span> <span class="n">dsa</span><span class="o">.</span><span class="n">sign</span><span class="p">(</span><span class="n">digest</span><span class="p">)</span>
+<span class="n">good</span> <span class="o">=</span> <span class="n">dsa</span><span class="o">.</span><span class="n">verify</span><span class="p">(</span><span class="n">digest</span><span class="p">,</span> <span class="n">r</span><span class="p">,</span> <span class="n">s</span><span class="p">)</span>
+<span class="k">if</span> <span class="n">good</span><span class="p">:</span>
+ <span class="nb">print</span><span class="p">(</span><span class="s1">&#39; ** success **&#39;</span><span class="p">)</span>
+<span class="k">else</span><span class="p">:</span>
+ <span class="nb">print</span><span class="p">(</span><span class="s1">&#39; ** verification failed **&#39;</span><span class="p">)</span>
+</pre></div>
+</div>
+<dl class="method">
+<dt id="M2Crypto.DSA.DSA.check_key">
+<code class="descname">check_key</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/DSA.html#DSA.check_key"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.DSA.DSA.check_key" title="Permalink to this definition">¶</a></dt>
+<dd><p>Check to be sure the DSA object has a valid private key.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">1 (true) if a valid private key</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.DSA.DSA.gen_key">
+<code class="descname">gen_key</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/DSA.html#DSA.gen_key"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.DSA.DSA.gen_key" title="Permalink to this definition">¶</a></dt>
+<dd><p>Generate a key pair.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.DSA.DSA.m2_dsa_free">
+<code class="descname">m2_dsa_free</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.DSA.DSA.m2_dsa_free" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.DSA.DSA.save_key">
+<code class="descname">save_key</code><span class="sig-paren">(</span><em>filename</em>, <em>cipher='aes_128_cbc'</em>, <em>callback=&lt;function passphrase_callback&gt;</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/DSA.html#DSA.save_key"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.DSA.DSA.save_key" title="Permalink to this definition">¶</a></dt>
+<dd><p>Save the DSA key pair to a file.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>filename</strong> – Save the DSA key pair to this file.</li>
+<li><strong>cipher</strong> – name of symmetric key algorithm and mode
+to encrypt the private key.</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">1 (true) if successful</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.DSA.DSA.save_key_bio">
+<code class="descname">save_key_bio</code><span class="sig-paren">(</span><em>bio</em>, <em>cipher='aes_128_cbc'</em>, <em>callback=&lt;function passphrase_callback&gt;</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/DSA.html#DSA.save_key_bio"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.DSA.DSA.save_key_bio" title="Permalink to this definition">¶</a></dt>
+<dd><p>Save DSA key pair to a BIO object.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>bio</strong> – Save DSA parameters to this object.</li>
+<li><strong>cipher</strong> – name of symmetric key algorithm and mode
+to encrypt the private key.</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">1 (true) if successful</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.DSA.DSA.save_params">
+<code class="descname">save_params</code><span class="sig-paren">(</span><em>filename</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/DSA.html#DSA.save_params"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.DSA.DSA.save_params" title="Permalink to this definition">¶</a></dt>
+<dd><p>Save the DSA parameters to a file.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>filename</strong> – Save the DSA parameters to this file.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">1 (true) if successful</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.DSA.DSA.save_params_bio">
+<code class="descname">save_params_bio</code><span class="sig-paren">(</span><em>bio</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/DSA.html#DSA.save_params_bio"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.DSA.DSA.save_params_bio" title="Permalink to this definition">¶</a></dt>
+<dd><p>Save DSA parameters to a BIO object.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>bio</strong> – Save DSA parameters to this object.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">1 (true) if successful</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.DSA.DSA.save_pub_key">
+<code class="descname">save_pub_key</code><span class="sig-paren">(</span><em>filename</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/DSA.html#DSA.save_pub_key"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.DSA.DSA.save_pub_key" title="Permalink to this definition">¶</a></dt>
+<dd><p>Save the DSA public key (with parameters) to a file.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>filename</strong> – Save DSA public key (with parameters)
+to this file.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">1 (true) if successful</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.DSA.DSA.save_pub_key_bio">
+<code class="descname">save_pub_key_bio</code><span class="sig-paren">(</span><em>bio</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/DSA.html#DSA.save_pub_key_bio"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.DSA.DSA.save_pub_key_bio" title="Permalink to this definition">¶</a></dt>
+<dd><p>Save DSA public key (with parameters) to a BIO object.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>bio</strong> – Save DSA public key (with parameters)
+to this object.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">1 (true) if successful</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.DSA.DSA.set_params">
+<code class="descname">set_params</code><span class="sig-paren">(</span><em>p</em>, <em>q</em>, <em>g</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/DSA.html#DSA.set_params"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.DSA.DSA.set_params" title="Permalink to this definition">¶</a></dt>
+<dd><p>Set new parameters.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>p</strong> – MPI binary representation … format that consists of
+the number’s length in bytes represented as a 4-byte
+big-endian number, and the number itself in big-endian
+format, where the most significant bit signals
+a negative number (the representation of numbers with
+the MSB set is prefixed with null byte).</li>
+<li><strong>q</strong> – ditto</li>
+<li><strong>g</strong> – ditto</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+<dl class="docutils">
+<dt>&#64;warning: This does not change the private key, so it may be</dt>
+<dd>unsafe to use this method. It is better to use
+gen_params function to create a new DSA object.</dd>
+</dl>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.DSA.DSA.sign">
+<code class="descname">sign</code><span class="sig-paren">(</span><em>digest</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/DSA.html#DSA.sign"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.DSA.DSA.sign" title="Permalink to this definition">¶</a></dt>
+<dd><p>Sign the digest.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>digest</strong> – SHA-1 hash of message (same as output
+from MessageDigest, a “byte stringâ€)</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">DSA signature, a tuple of two values, r and s,
+both “byte stringsâ€.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.DSA.DSA.sign_asn1">
+<code class="descname">sign_asn1</code><span class="sig-paren">(</span><em>digest</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/DSA.html#DSA.sign_asn1"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.DSA.DSA.sign_asn1" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.DSA.DSA.verify">
+<code class="descname">verify</code><span class="sig-paren">(</span><em>digest</em>, <em>r</em>, <em>s</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/DSA.html#DSA.verify"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.DSA.DSA.verify" title="Permalink to this definition">¶</a></dt>
+<dd><p>Verify a newly calculated digest against the signature
+values r and s.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>digest</strong> – SHA-1 hash of message (same as output
+from MessageDigest, a “byte stringâ€)</li>
+<li><strong>r</strong> – r value of the signature, a “byte stringâ€</li>
+<li><strong>s</strong> – s value of the signature, a “byte stringâ€</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">1 (true) if verify succeeded, 0 if failed</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.DSA.DSA.verify_asn1">
+<code class="descname">verify_asn1</code><span class="sig-paren">(</span><em>digest</em>, <em>blob</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/DSA.html#DSA.verify_asn1"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.DSA.DSA.verify_asn1" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+</dd></dl>
+
+<dl class="exception">
+<dt id="M2Crypto.DSA.DSAError">
+<em class="property">exception </em><code class="descclassname">M2Crypto.DSA.</code><code class="descname">DSAError</code><a class="reference internal" href="_modules/M2Crypto/DSA.html#DSAError"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.DSA.DSAError" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">Exception</span></code></p>
+</dd></dl>
+
+<dl class="class">
+<dt id="M2Crypto.DSA.DSA_pub">
+<em class="property">class </em><code class="descclassname">M2Crypto.DSA.</code><code class="descname">DSA_pub</code><span class="sig-paren">(</span><em>dsa</em>, <em>_pyfree=0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/DSA.html#DSA_pub"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.DSA.DSA_pub" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <a class="reference internal" href="#M2Crypto.DSA.DSA" title="M2Crypto.DSA.DSA"><code class="xref py py-class docutils literal notranslate"><span class="pre">M2Crypto.DSA.DSA</span></code></a></p>
+<p>This class is a DSA context that only supports a public key
+and verification. It does NOT support a private key or
+signing.</p>
+<dl class="method">
+<dt id="M2Crypto.DSA.DSA_pub.check_key">
+<code class="descname">check_key</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/DSA.html#DSA_pub.check_key"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.DSA.DSA_pub.check_key" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">does DSA_pub contain a pub key?</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.DSA.DSA_pub.save_key">
+<code class="descname">save_key</code><span class="sig-paren">(</span><em>filename</em><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.DSA.DSA_pub.save_key" title="Permalink to this definition">¶</a></dt>
+<dd><p>Save the DSA public key (with parameters) to a file.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>filename</strong> – Save DSA public key (with parameters)
+to this file.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">1 (true) if successful</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.DSA.DSA_pub.save_key_bio">
+<code class="descname">save_key_bio</code><span class="sig-paren">(</span><em>bio</em><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.DSA.DSA_pub.save_key_bio" title="Permalink to this definition">¶</a></dt>
+<dd><p>Save DSA public key (with parameters) to a BIO object.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>bio</strong> – Save DSA public key (with parameters)
+to this object.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">1 (true) if successful</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.DSA.DSA_pub.sign">
+<code class="descname">sign</code><span class="sig-paren">(</span><em>*argv</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/DSA.html#DSA_pub.sign"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.DSA.DSA_pub.sign" title="Permalink to this definition">¶</a></dt>
+<dd><p>Sign the digest.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>digest</strong> – SHA-1 hash of message (same as output
+from MessageDigest, a “byte stringâ€)</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">DSA signature, a tuple of two values, r and s,
+both “byte stringsâ€.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.DSA.DSA_pub.sign_asn1">
+<code class="descname">sign_asn1</code><span class="sig-paren">(</span><em>*argv</em><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.DSA.DSA_pub.sign_asn1" title="Permalink to this definition">¶</a></dt>
+<dd><p>Sign the digest.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>digest</strong> – SHA-1 hash of message (same as output
+from MessageDigest, a “byte stringâ€)</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">DSA signature, a tuple of two values, r and s,
+both “byte stringsâ€.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.DSA.gen_params">
+<code class="descclassname">M2Crypto.DSA.</code><code class="descname">gen_params</code><span class="sig-paren">(</span><em>bits</em>, <em>callback=&lt;function genparam_callback&gt;</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/DSA.html#gen_params"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.DSA.gen_params" title="Permalink to this definition">¶</a></dt>
+<dd><p>Factory function that generates DSA parameters and
+instantiates a DSA object from the output.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>bits</strong> – The length of the prime to be generated. If
+‘bits’ &lt; 512, it is set to 512.</li>
+<li><strong>callback</strong> – A Python callback object that will be
+invoked during parameter generation; it usual
+purpose is to provide visual feedback.</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">instance of DSA.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.DSA.load_key">
+<code class="descclassname">M2Crypto.DSA.</code><code class="descname">load_key</code><span class="sig-paren">(</span><em>file</em>, <em>callback=&lt;function passphrase_callback&gt;</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/DSA.html#load_key"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.DSA.load_key" title="Permalink to this definition">¶</a></dt>
+<dd><p>Factory function that instantiates a DSA object from a
+PEM encoded DSA key pair.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>file</strong> – Names the file (a path) that contains the PEM
+representation of the DSA key pair.</li>
+<li><strong>callback</strong> – A Python callback object that will be
+invoked if the DSA key pair is
+passphrase-protected.</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">instance of DSA.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.DSA.load_key_bio">
+<code class="descclassname">M2Crypto.DSA.</code><code class="descname">load_key_bio</code><span class="sig-paren">(</span><em>bio</em>, <em>callback=&lt;function passphrase_callback&gt;</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/DSA.html#load_key_bio"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.DSA.load_key_bio" title="Permalink to this definition">¶</a></dt>
+<dd><p>Factory function that instantiates a DSA object from a
+PEM encoded DSA key pair.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>bio</strong> – Contains the PEM representation of the DSA
+key pair.</li>
+<li><strong>callback</strong> – A Python callback object that will be
+invoked if the DSA key pair is
+passphrase-protected.</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">instance of DSA.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.DSA.load_params">
+<code class="descclassname">M2Crypto.DSA.</code><code class="descname">load_params</code><span class="sig-paren">(</span><em>file</em>, <em>callback=&lt;function passphrase_callback&gt;</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/DSA.html#load_params"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.DSA.load_params" title="Permalink to this definition">¶</a></dt>
+<dd><p>Factory function that instantiates a DSA object with DSA
+parameters from a file.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>file</strong> – Names the file (a path) that contains the PEM
+representation of the DSA parameters.</li>
+<li><strong>callback</strong> – A Python callback object that will be
+invoked if the DSA parameters file is
+passphrase-protected.</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">instance of DSA.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.DSA.load_params_bio">
+<code class="descclassname">M2Crypto.DSA.</code><code class="descname">load_params_bio</code><span class="sig-paren">(</span><em>bio</em>, <em>callback=&lt;function passphrase_callback&gt;</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/DSA.html#load_params_bio"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.DSA.load_params_bio" title="Permalink to this definition">¶</a></dt>
+<dd><p>Factory function that instantiates a DSA object with DSA
+parameters from a M2Crypto.BIO object.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>bio</strong> – Contains the PEM representation of the DSA
+parameters.</li>
+<li><strong>callback</strong> – A Python callback object that will be
+invoked if the DSA parameters file is
+passphrase-protected.</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">instance of DSA.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.DSA.load_pub_key">
+<code class="descclassname">M2Crypto.DSA.</code><code class="descname">load_pub_key</code><span class="sig-paren">(</span><em>file</em>, <em>callback=&lt;function passphrase_callback&gt;</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/DSA.html#load_pub_key"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.DSA.load_pub_key" title="Permalink to this definition">¶</a></dt>
+<dd><p>Factory function that instantiates a DSA_pub object using
+a DSA public key contained in PEM file. The PEM file
+must contain the parameters in addition to the public key.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>file</strong> – Names the file (a path) that contains the PEM
+representation of the DSA public key.</li>
+<li><strong>callback</strong> – A Python callback object that will be
+invoked should the DSA public key be
+passphrase-protected.</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">instance of DSA_pub.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.DSA.load_pub_key_bio">
+<code class="descclassname">M2Crypto.DSA.</code><code class="descname">load_pub_key_bio</code><span class="sig-paren">(</span><em>bio</em>, <em>callback=&lt;function passphrase_callback&gt;</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/DSA.html#load_pub_key_bio"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.DSA.load_pub_key_bio" title="Permalink to this definition">¶</a></dt>
+<dd><p>Factory function that instantiates a DSA_pub object using
+a DSA public key contained in PEM format. The PEM
+must contain the parameters in addition to the public key.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>bio</strong> – Contains the PEM representation of the DSA
+public key (with params).</li>
+<li><strong>callback</strong> – A Python callback object that will be
+invoked should the DSA public key be
+passphrase-protected.</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">instance of DSA_pub.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.DSA.pub_key_from_params">
+<code class="descclassname">M2Crypto.DSA.</code><code class="descname">pub_key_from_params</code><span class="sig-paren">(</span><em>p</em>, <em>q</em>, <em>g</em>, <em>pub</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/DSA.html#pub_key_from_params"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.DSA.pub_key_from_params" title="Permalink to this definition">¶</a></dt>
+<dd><p>Factory function that instantiates a DSA_pub object using
+the parameters and public key specified.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>p</strong> – value of p</li>
+<li><strong>q</strong> – value of q</li>
+<li><strong>g</strong> – value of g</li>
+<li><strong>pub</strong> – value of the public key</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">instance of DSA_pub.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.DSA.set_params">
+<code class="descclassname">M2Crypto.DSA.</code><code class="descname">set_params</code><span class="sig-paren">(</span><em>p</em>, <em>q</em>, <em>g</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/DSA.html#set_params"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.DSA.set_params" title="Permalink to this definition">¶</a></dt>
+<dd><p>Factory function that instantiates a DSA object with DSA
+parameters.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>p</strong> – value of p, a “byte stringâ€</li>
+<li><strong>q</strong> – value of q, a “byte stringâ€</li>
+<li><strong>g</strong> – value of g, a “byte stringâ€</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">instance of DSA.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+</div>
+<div class="section" id="module-M2Crypto.EC">
+<span id="ec-module"></span><h2><code class="xref py py-mod docutils literal notranslate"><span class="pre">EC</span></code> Module<a class="headerlink" href="#module-M2Crypto.EC" title="Permalink to this headline">¶</a></h2>
+<dl class="class">
+<dt id="M2Crypto.EC.EC">
+<em class="property">class </em><code class="descclassname">M2Crypto.EC.</code><code class="descname">EC</code><span class="sig-paren">(</span><em>ec</em>, <em>_pyfree=0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EC.html#EC"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EC.EC" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
+<p>Object interface to a EC key pair.</p>
+<dl class="method">
+<dt id="M2Crypto.EC.EC.as_pem">
+<code class="descname">as_pem</code><span class="sig-paren">(</span><em>cipher='aes_128_cbc'</em>, <em>callback=&lt;function passphrase_callback&gt;</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EC.html#EC.as_pem"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EC.EC.as_pem" title="Permalink to this definition">¶</a></dt>
+<dd><p>Returns the key(pair) as a string in PEM format.
+If no password is passed and the cipher is set
+it exits with error</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.EC.EC.check_key">
+<code class="descname">check_key</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EC.html#EC.check_key"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EC.EC.check_key" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.EC.EC.compute_dh_key">
+<code class="descname">compute_dh_key</code><span class="sig-paren">(</span><em>pub_key</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EC.html#EC.compute_dh_key"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EC.EC.compute_dh_key" title="Permalink to this definition">¶</a></dt>
+<dd><p>Compute the ECDH shared key of this key pair and the given public
+key object. They must both use the same curve. Returns the
+shared key in binary as a buffer object. No Key Derivation Function is
+applied.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.EC.EC.gen_key">
+<code class="descname">gen_key</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EC.html#EC.gen_key"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EC.EC.gen_key" title="Permalink to this definition">¶</a></dt>
+<dd><p>Generates the key pair from its parameters. Use:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">keypair</span> <span class="o">=</span> <span class="n">EC</span><span class="o">.</span><span class="n">gen_params</span><span class="p">(</span><span class="n">curve</span><span class="p">)</span>
+<span class="n">keypair</span><span class="o">.</span><span class="n">gen_key</span><span class="p">()</span>
+</pre></div>
+</div>
+<p>to create an EC key pair.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.EC.EC.m2_ec_key_free">
+<code class="descname">m2_ec_key_free</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.EC.EC.m2_ec_key_free" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.EC.EC.pub">
+<code class="descname">pub</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EC.html#EC.pub"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EC.EC.pub" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.EC.EC.save_key">
+<code class="descname">save_key</code><span class="sig-paren">(</span><em>file</em>, <em>cipher='aes_128_cbc'</em>, <em>callback=&lt;function passphrase_callback&gt;</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EC.html#EC.save_key"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EC.EC.save_key" title="Permalink to this definition">¶</a></dt>
+<dd><p>Save the key pair to a file in PEM format.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>file</strong> – Name of filename to save key to.</li>
+<li><strong>cipher</strong> – Symmetric cipher to protect the key. The default
+cipher is ‘aes_128_cbc’. If cipher is None, then
+the key is saved in the clear.</li>
+<li><strong>callback</strong> – A Python callable object that is invoked
+to acquire a passphrase with which to protect
+the key. The default is
+util.passphrase_callback.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.EC.EC.save_key_bio">
+<code class="descname">save_key_bio</code><span class="sig-paren">(</span><em>bio</em>, <em>cipher='aes_128_cbc'</em>, <em>callback=&lt;function passphrase_callback&gt;</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EC.html#EC.save_key_bio"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EC.EC.save_key_bio" title="Permalink to this definition">¶</a></dt>
+<dd><p>Save the key pair to an M2Crypto.BIO.BIO object in PEM format.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>bio</strong> – M2Crypto.BIO.BIO object to save key to.</li>
+<li><strong>cipher</strong> – Symmetric cipher to protect the key. The default
+cipher is ‘aes_128_cbc’. If cipher is None, then
+the key is saved in the clear.</li>
+<li><strong>callback</strong> – A Python callable object that is invoked
+to acquire a passphrase with which to protect
+the key. The default is
+util.passphrase_callback.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.EC.EC.save_pub_key">
+<code class="descname">save_pub_key</code><span class="sig-paren">(</span><em>file</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EC.html#EC.save_pub_key"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EC.EC.save_pub_key" title="Permalink to this definition">¶</a></dt>
+<dd><p>Save the public key to a filename in PEM format.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>file</strong> – Name of filename to save key to.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.EC.EC.save_pub_key_bio">
+<code class="descname">save_pub_key_bio</code><span class="sig-paren">(</span><em>bio</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EC.html#EC.save_pub_key_bio"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EC.EC.save_pub_key_bio" title="Permalink to this definition">¶</a></dt>
+<dd><p>Save the public key to an M2Crypto.BIO.BIO object in PEM format.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>bio</strong> – M2Crypto.BIO.BIO object to save key to.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.EC.EC.sign_dsa">
+<code class="descname">sign_dsa</code><span class="sig-paren">(</span><em>digest</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EC.html#EC.sign_dsa"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EC.EC.sign_dsa" title="Permalink to this definition">¶</a></dt>
+<dd><p>Sign the given digest using ECDSA. Returns a tuple (r,s), the two
+ECDSA signature parameters.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.EC.EC.sign_dsa_asn1">
+<code class="descname">sign_dsa_asn1</code><span class="sig-paren">(</span><em>digest</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EC.html#EC.sign_dsa_asn1"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EC.EC.sign_dsa_asn1" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.EC.EC.verify_dsa">
+<code class="descname">verify_dsa</code><span class="sig-paren">(</span><em>digest</em>, <em>r</em>, <em>s</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EC.html#EC.verify_dsa"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EC.EC.verify_dsa" title="Permalink to this definition">¶</a></dt>
+<dd><p>Verify the given digest using ECDSA. r and s are the ECDSA
+signature parameters.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.EC.EC.verify_dsa_asn1">
+<code class="descname">verify_dsa_asn1</code><span class="sig-paren">(</span><em>digest</em>, <em>blob</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EC.html#EC.verify_dsa_asn1"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EC.EC.verify_dsa_asn1" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+</dd></dl>
+
+<dl class="exception">
+<dt id="M2Crypto.EC.ECError">
+<em class="property">exception </em><code class="descclassname">M2Crypto.EC.</code><code class="descname">ECError</code><a class="reference internal" href="_modules/M2Crypto/EC.html#ECError"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EC.ECError" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">Exception</span></code></p>
+</dd></dl>
+
+<dl class="class">
+<dt id="M2Crypto.EC.EC_pub">
+<em class="property">class </em><code class="descclassname">M2Crypto.EC.</code><code class="descname">EC_pub</code><span class="sig-paren">(</span><em>ec</em>, <em>_pyfree=0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EC.html#EC_pub"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EC.EC_pub" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <a class="reference internal" href="#M2Crypto.EC.EC" title="M2Crypto.EC.EC"><code class="xref py py-class docutils literal notranslate"><span class="pre">M2Crypto.EC.EC</span></code></a></p>
+<p>Object interface to an EC public key.
+((don’t like this implementation inheritance))</p>
+<dl class="method">
+<dt id="M2Crypto.EC.EC_pub.get_der">
+<code class="descname">get_der</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EC.html#EC_pub.get_der"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EC.EC_pub.get_der" title="Permalink to this definition">¶</a></dt>
+<dd><p>Returns the public key in DER format as a buffer object.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.EC.EC_pub.get_key">
+<code class="descname">get_key</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EC.html#EC_pub.get_key"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EC.EC_pub.get_key" title="Permalink to this definition">¶</a></dt>
+<dd><p>Returns the public key as a byte string.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.EC.EC_pub.save_key">
+<code class="descname">save_key</code><span class="sig-paren">(</span><em>file</em><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.EC.EC_pub.save_key" title="Permalink to this definition">¶</a></dt>
+<dd><p>Save the public key to a filename in PEM format.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>file</strong> – Name of filename to save key to.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.EC.EC_pub.save_key_bio">
+<code class="descname">save_key_bio</code><span class="sig-paren">(</span><em>bio</em><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.EC.EC_pub.save_key_bio" title="Permalink to this definition">¶</a></dt>
+<dd><p>Save the public key to an M2Crypto.BIO.BIO object in PEM format.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>bio</strong> – M2Crypto.BIO.BIO object to save key to.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.EC.ec_error">
+<code class="descclassname">M2Crypto.EC.</code><code class="descname">ec_error</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EC.html#ec_error"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EC.ec_error" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.EC.gen_params">
+<code class="descclassname">M2Crypto.EC.</code><code class="descname">gen_params</code><span class="sig-paren">(</span><em>curve</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EC.html#gen_params"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EC.gen_params" title="Permalink to this definition">¶</a></dt>
+<dd><p>Factory function that generates EC parameters and
+instantiates a EC object from the output.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>curve</strong> – This is the OpenSSL nid of the curve to use.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.EC.get_builtin_curves">
+<code class="descclassname">M2Crypto.EC.</code><code class="descname">get_builtin_curves</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EC.html#get_builtin_curves"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EC.get_builtin_curves" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.EC.load_key">
+<code class="descclassname">M2Crypto.EC.</code><code class="descname">load_key</code><span class="sig-paren">(</span><em>file</em>, <em>callback=&lt;function passphrase_callback&gt;</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EC.html#load_key"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EC.load_key" title="Permalink to this definition">¶</a></dt>
+<dd><p>Factory function that instantiates a EC object.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>file</strong> – Names the filename that contains the PEM representation
+of the EC key pair.</li>
+<li><strong>callback</strong> – Python callback object that will be invoked
+if the EC key pair is passphrase-protected.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.EC.load_key_bio">
+<code class="descclassname">M2Crypto.EC.</code><code class="descname">load_key_bio</code><span class="sig-paren">(</span><em>bio</em>, <em>callback=&lt;function passphrase_callback&gt;</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EC.html#load_key_bio"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EC.load_key_bio" title="Permalink to this definition">¶</a></dt>
+<dd><p>Factory function that instantiates a EC object.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>bio</strong> – M2Crypto.BIO object that contains the PEM
+representation of the EC key pair.</li>
+<li><strong>callback</strong> – Python callback object that will be invoked
+if the EC key pair is passphrase-protected.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.EC.load_key_string">
+<code class="descclassname">M2Crypto.EC.</code><code class="descname">load_key_string</code><span class="sig-paren">(</span><em>string</em>, <em>callback=&lt;function passphrase_callback&gt;</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EC.html#load_key_string"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EC.load_key_string" title="Permalink to this definition">¶</a></dt>
+<dd><p>Load an EC key pair from a string.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>string</strong> – String containing EC key pair in PEM format.</li>
+<li><strong>callback</strong> – A Python callable object that is invoked
+to acquire a passphrase with which to unlock the
+key. The default is util.passphrase_callback.</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">M2Crypto.EC.EC object.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.EC.load_key_string_pubkey">
+<code class="descclassname">M2Crypto.EC.</code><code class="descname">load_key_string_pubkey</code><span class="sig-paren">(</span><em>string</em>, <em>callback=&lt;function passphrase_callback&gt;</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EC.html#load_key_string_pubkey"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EC.load_key_string_pubkey" title="Permalink to this definition">¶</a></dt>
+<dd><p>Load an M2Crypto.EC.PKey from a public key as a string.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>string</strong> – String containing the key in PEM format.</li>
+<li><strong>callback</strong> – A Python callable object that is invoked
+to acquire a passphrase with which to protect the
+key.</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">M2Crypto.EC.PKey object.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.EC.load_pub_key">
+<code class="descclassname">M2Crypto.EC.</code><code class="descname">load_pub_key</code><span class="sig-paren">(</span><em>file</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EC.html#load_pub_key"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EC.load_pub_key" title="Permalink to this definition">¶</a></dt>
+<dd><p>Load an EC public key from filename.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>file</strong> – Name of filename containing EC public key in PEM
+format.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">M2Crypto.EC.EC_pub object.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.EC.load_pub_key_bio">
+<code class="descclassname">M2Crypto.EC.</code><code class="descname">load_pub_key_bio</code><span class="sig-paren">(</span><em>bio</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EC.html#load_pub_key_bio"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EC.load_pub_key_bio" title="Permalink to this definition">¶</a></dt>
+<dd><p>Load an EC public key from an M2Crypto.BIO.BIO object.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>bio</strong> – M2Crypto.BIO.BIO object containing EC public key in PEM
+format.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">M2Crypto.EC.EC_pub object.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.EC.pub_key_from_der">
+<code class="descclassname">M2Crypto.EC.</code><code class="descname">pub_key_from_der</code><span class="sig-paren">(</span><em>der</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EC.html#pub_key_from_der"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EC.pub_key_from_der" title="Permalink to this definition">¶</a></dt>
+<dd><p>Create EC_pub from DER.</p>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.EC.pub_key_from_params">
+<code class="descclassname">M2Crypto.EC.</code><code class="descname">pub_key_from_params</code><span class="sig-paren">(</span><em>curve</em>, <em>bytes</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EC.html#pub_key_from_params"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EC.pub_key_from_params" title="Permalink to this definition">¶</a></dt>
+<dd><p>Create EC_pub from curve name and octet string.</p>
+</dd></dl>
+
+</div>
+<div class="section" id="module-M2Crypto.EVP">
+<span id="evp-module"></span><h2><code class="xref py py-mod docutils literal notranslate"><span class="pre">EVP</span></code> Module<a class="headerlink" href="#module-M2Crypto.EVP" title="Permalink to this headline">¶</a></h2>
+<dl class="class">
+<dt id="M2Crypto.EVP.Cipher">
+<em class="property">class </em><code class="descclassname">M2Crypto.EVP.</code><code class="descname">Cipher</code><span class="sig-paren">(</span><em>alg</em>, <em>key</em>, <em>iv</em>, <em>op</em>, <em>key_as_bytes=0</em>, <em>d='md5'</em>, <em>salt=b'12345678'</em>, <em>i=1</em>, <em>padding=1</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EVP.html#Cipher"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EVP.Cipher" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
+<dl class="method">
+<dt id="M2Crypto.EVP.Cipher.final">
+<code class="descname">final</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EVP.html#Cipher.final"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EVP.Cipher.final" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.EVP.Cipher.m2_cipher_ctx_free">
+<code class="descname">m2_cipher_ctx_free</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.EVP.Cipher.m2_cipher_ctx_free" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.EVP.Cipher.set_padding">
+<code class="descname">set_padding</code><span class="sig-paren">(</span><em>padding=1</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EVP.html#Cipher.set_padding"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EVP.Cipher.set_padding" title="Permalink to this definition">¶</a></dt>
+<dd><p>Actually always return 1</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.EVP.Cipher.update">
+<code class="descname">update</code><span class="sig-paren">(</span><em>data</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EVP.html#Cipher.update"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EVP.Cipher.update" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+</dd></dl>
+
+<dl class="exception">
+<dt id="M2Crypto.EVP.EVPError">
+<em class="property">exception </em><code class="descclassname">M2Crypto.EVP.</code><code class="descname">EVPError</code><a class="reference internal" href="_modules/M2Crypto/EVP.html#EVPError"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EVP.EVPError" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">ValueError</span></code></p>
+</dd></dl>
+
+<dl class="class">
+<dt id="M2Crypto.EVP.HMAC">
+<em class="property">class </em><code class="descclassname">M2Crypto.EVP.</code><code class="descname">HMAC</code><span class="sig-paren">(</span><em>key</em>, <em>algo='sha1'</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EVP.html#HMAC"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EVP.HMAC" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
+<dl class="method">
+<dt id="M2Crypto.EVP.HMAC.digest">
+<code class="descname">digest</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.EVP.HMAC.digest" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.EVP.HMAC.final">
+<code class="descname">final</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EVP.html#HMAC.final"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EVP.HMAC.final" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.EVP.HMAC.m2_hmac_ctx_free">
+<code class="descname">m2_hmac_ctx_free</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.EVP.HMAC.m2_hmac_ctx_free" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.EVP.HMAC.reset">
+<code class="descname">reset</code><span class="sig-paren">(</span><em>key</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EVP.html#HMAC.reset"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EVP.HMAC.reset" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.EVP.HMAC.update">
+<code class="descname">update</code><span class="sig-paren">(</span><em>data</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EVP.html#HMAC.update"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EVP.HMAC.update" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="M2Crypto.EVP.MessageDigest">
+<em class="property">class </em><code class="descclassname">M2Crypto.EVP.</code><code class="descname">MessageDigest</code><span class="sig-paren">(</span><em>algo</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EVP.html#MessageDigest"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EVP.MessageDigest" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
+<p>Message Digest</p>
+<dl class="method">
+<dt id="M2Crypto.EVP.MessageDigest.digest">
+<code class="descname">digest</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.EVP.MessageDigest.digest" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.EVP.MessageDigest.final">
+<code class="descname">final</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EVP.html#MessageDigest.final"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EVP.MessageDigest.final" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.EVP.MessageDigest.m2_md_ctx_free">
+<code class="descname">m2_md_ctx_free</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.EVP.MessageDigest.m2_md_ctx_free" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.EVP.MessageDigest.update">
+<code class="descname">update</code><span class="sig-paren">(</span><em>data</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EVP.html#MessageDigest.update"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EVP.MessageDigest.update" title="Permalink to this definition">¶</a></dt>
+<dd><p>Add data to be digested.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">-1 for Python error, 1 for success, 0 for OpenSSL failure.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="M2Crypto.EVP.PKey">
+<em class="property">class </em><code class="descclassname">M2Crypto.EVP.</code><code class="descname">PKey</code><span class="sig-paren">(</span><em>pkey=None</em>, <em>_pyfree=0</em>, <em>md='sha1'</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EVP.html#PKey"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EVP.PKey" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
+<p>Public Key</p>
+<dl class="method">
+<dt id="M2Crypto.EVP.PKey.as_der">
+<code class="descname">as_der</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EVP.html#PKey.as_der"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EVP.PKey.as_der" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return key in DER format in a string</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.EVP.PKey.as_pem">
+<code class="descname">as_pem</code><span class="sig-paren">(</span><em>cipher='aes_128_cbc'</em>, <em>callback=&lt;function passphrase_callback&gt;</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EVP.html#PKey.as_pem"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EVP.PKey.as_pem" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return key in PEM format in a string.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>cipher</strong> – Symmetric cipher to protect the key. The default
+cipher is <code class="docutils literal notranslate"><span class="pre">'aes_128_cbc'</span></code>. If cipher is None,
+then the key is saved in the clear.</li>
+<li><strong>callback</strong> – A Python callable object that is invoked
+to acquire a passphrase with which to protect
+the key. The default is
+util.passphrase_callback.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.EVP.PKey.assign_rsa">
+<code class="descname">assign_rsa</code><span class="sig-paren">(</span><em>rsa</em>, <em>capture=1</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EVP.html#PKey.assign_rsa"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EVP.PKey.assign_rsa" title="Permalink to this definition">¶</a></dt>
+<dd><p>Assign the RSA key pair to self.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>rsa</strong> – M2Crypto.RSA.RSA object to be assigned to self.</li>
+<li><strong>capture</strong> – If true (default), this PKey object will own the RSA
+object, meaning that once the PKey object gets
+deleted it is no longer safe to use the RSA object.</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">Return 1 for success and 0 for failure.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.EVP.PKey.final">
+<code class="descname">final</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.EVP.PKey.final" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return signature.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">The signature.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.EVP.PKey.get_modulus">
+<code class="descname">get_modulus</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EVP.html#PKey.get_modulus"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EVP.PKey.get_modulus" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return the modulus in hex format.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.EVP.PKey.get_rsa">
+<code class="descname">get_rsa</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EVP.html#PKey.get_rsa"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EVP.PKey.get_rsa" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return the underlying RSA key if that is what the EVP
+instance is holding.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.EVP.PKey.m2_md_ctx_free">
+<code class="descname">m2_md_ctx_free</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.EVP.PKey.m2_md_ctx_free" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.EVP.PKey.m2_pkey_free">
+<code class="descname">m2_pkey_free</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.EVP.PKey.m2_pkey_free" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.EVP.PKey.reset_context">
+<code class="descname">reset_context</code><span class="sig-paren">(</span><em>md='sha1'</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EVP.html#PKey.reset_context"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EVP.PKey.reset_context" title="Permalink to this definition">¶</a></dt>
+<dd><p>Reset internal message digest context.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>md</strong> – The message digest algorithm.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.EVP.PKey.save_key">
+<code class="descname">save_key</code><span class="sig-paren">(</span><em>file</em>, <em>cipher='aes_128_cbc'</em>, <em>callback=&lt;function passphrase_callback&gt;</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EVP.html#PKey.save_key"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EVP.PKey.save_key" title="Permalink to this definition">¶</a></dt>
+<dd><p>Save the key pair to a file in PEM format.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>file</strong> – Name of file to save key to.</li>
+<li><strong>cipher</strong> – Symmetric cipher to protect the key. The default
+cipher is ‘aes_128_cbc’. If cipher is None, then
+the key is saved in the clear.</li>
+<li><strong>callback</strong> – A Python callable object that is invoked
+to acquire a passphrase with which to protect
+the key. The default is
+util.passphrase_callback.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.EVP.PKey.save_key_bio">
+<code class="descname">save_key_bio</code><span class="sig-paren">(</span><em>bio</em>, <em>cipher='aes_128_cbc'</em>, <em>callback=&lt;function passphrase_callback&gt;</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EVP.html#PKey.save_key_bio"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EVP.PKey.save_key_bio" title="Permalink to this definition">¶</a></dt>
+<dd><p>Save the key pair to the M2Crypto.BIO object ‘bio’ in PEM format.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>bio</strong> – M2Crypto.BIO object to save key to.</li>
+<li><strong>cipher</strong> – Symmetric cipher to protect the key. The default
+cipher is ‘aes_128_cbc’. If cipher is None, then
+the key is saved in the clear.</li>
+<li><strong>callback</strong> – A Python callable object that is invoked
+to acquire a passphrase with which to protect
+the key. The default is
+util.passphrase_callback.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.EVP.PKey.sign_final">
+<code class="descname">sign_final</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EVP.html#PKey.sign_final"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EVP.PKey.sign_final" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return signature.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">The signature.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.EVP.PKey.sign_init">
+<code class="descname">sign_init</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EVP.html#PKey.sign_init"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EVP.PKey.sign_init" title="Permalink to this definition">¶</a></dt>
+<dd><p>Initialise signing operation with self.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.EVP.PKey.sign_update">
+<code class="descname">sign_update</code><span class="sig-paren">(</span><em>data</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EVP.html#PKey.sign_update"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EVP.PKey.sign_update" title="Permalink to this definition">¶</a></dt>
+<dd><p>Feed data to signing operation.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>data</strong> – Data to be signed.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.EVP.PKey.size">
+<code class="descname">size</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EVP.html#PKey.size"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EVP.PKey.size" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return the size of the key in bytes.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.EVP.PKey.update">
+<code class="descname">update</code><span class="sig-paren">(</span><em>data</em><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.EVP.PKey.update" title="Permalink to this definition">¶</a></dt>
+<dd><p>Feed data to signing operation.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>data</strong> – Data to be signed.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.EVP.PKey.verify_final">
+<code class="descname">verify_final</code><span class="sig-paren">(</span><em>sign</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EVP.html#PKey.verify_final"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EVP.PKey.verify_final" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return result of verification.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>sign</strong> – Signature to use for verification</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">Result of verification: 1 for success, 0 for failure, -1 on
+other error.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.EVP.PKey.verify_init">
+<code class="descname">verify_init</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EVP.html#PKey.verify_init"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EVP.PKey.verify_init" title="Permalink to this definition">¶</a></dt>
+<dd><p>Initialise signature verification operation with self.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.EVP.PKey.verify_update">
+<code class="descname">verify_update</code><span class="sig-paren">(</span><em>data</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EVP.html#PKey.verify_update"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EVP.PKey.verify_update" title="Permalink to this definition">¶</a></dt>
+<dd><p>Feed data to verification operation.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>data</strong> – Data to be verified.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">-1 on Python error, 1 for success, 0 for OpenSSL error</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.EVP.hmac">
+<code class="descclassname">M2Crypto.EVP.</code><code class="descname">hmac</code><span class="sig-paren">(</span><em>key</em>, <em>data</em>, <em>algo='sha1'</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EVP.html#hmac"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EVP.hmac" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.EVP.load_key">
+<code class="descclassname">M2Crypto.EVP.</code><code class="descname">load_key</code><span class="sig-paren">(</span><em>file</em>, <em>callback=&lt;function passphrase_callback&gt;</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EVP.html#load_key"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EVP.load_key" title="Permalink to this definition">¶</a></dt>
+<dd><p>Load an M2Crypto.EVP.PKey from file.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>file</strong> – Name of file containing the key in PEM format.</li>
+<li><strong>callback</strong> – A Python callable object that is invoked
+to acquire a passphrase with which to protect the
+key.</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">M2Crypto.EVP.PKey object.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.EVP.load_key_bio">
+<code class="descclassname">M2Crypto.EVP.</code><code class="descname">load_key_bio</code><span class="sig-paren">(</span><em>bio</em>, <em>callback=&lt;function passphrase_callback&gt;</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EVP.html#load_key_bio"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EVP.load_key_bio" title="Permalink to this definition">¶</a></dt>
+<dd><p>Load an M2Crypto.EVP.PKey from an M2Crypto.BIO object.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>bio</strong> – M2Crypto.BIO object containing the key in PEM format.</li>
+<li><strong>callback</strong> – A Python callable object that is invoked
+to acquire a passphrase with which to protect the
+key.</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">M2Crypto.EVP.PKey object.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.EVP.load_key_bio_pubkey">
+<code class="descclassname">M2Crypto.EVP.</code><code class="descname">load_key_bio_pubkey</code><span class="sig-paren">(</span><em>bio</em>, <em>callback=&lt;function passphrase_callback&gt;</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EVP.html#load_key_bio_pubkey"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EVP.load_key_bio_pubkey" title="Permalink to this definition">¶</a></dt>
+<dd><p>Load an M2Crypto.EVP.PKey from a public key as a M2Crypto.BIO object.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>bio</strong> – M2Crypto.BIO object containing the key in PEM format.</li>
+<li><strong>callback</strong> – A Python callable object that is invoked
+to acquire a passphrase with which to protect the
+key.</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">M2Crypto.EVP.PKey object.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.EVP.load_key_string">
+<code class="descclassname">M2Crypto.EVP.</code><code class="descname">load_key_string</code><span class="sig-paren">(</span><em>string</em>, <em>callback=&lt;function passphrase_callback&gt;</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EVP.html#load_key_string"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EVP.load_key_string" title="Permalink to this definition">¶</a></dt>
+<dd><p>Load an M2Crypto.EVP.PKey from a string.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>string</strong> – String containing the key in PEM format.</li>
+<li><strong>callback</strong> – A Python callable object that is invoked
+to acquire a passphrase with which to protect the
+key.</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">M2Crypto.EVP.PKey object.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.EVP.load_key_string_pubkey">
+<code class="descclassname">M2Crypto.EVP.</code><code class="descname">load_key_string_pubkey</code><span class="sig-paren">(</span><em>string</em>, <em>callback=&lt;function passphrase_callback&gt;</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EVP.html#load_key_string_pubkey"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EVP.load_key_string_pubkey" title="Permalink to this definition">¶</a></dt>
+<dd><p>Load an M2Crypto.EVP.PKey from a public key as a string.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>string</strong> – String containing the key in PEM format.</li>
+<li><strong>callback</strong> – A Python callable object that is invoked
+to acquire a passphrase with which to protect the
+key.</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">M2Crypto.EVP.PKey object.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.EVP.pbkdf2">
+<code class="descclassname">M2Crypto.EVP.</code><code class="descname">pbkdf2</code><span class="sig-paren">(</span><em>password</em>, <em>salt</em>, <em>iter</em>, <em>keylen</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/EVP.html#pbkdf2"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.EVP.pbkdf2" title="Permalink to this definition">¶</a></dt>
+<dd><p>Derive a key from password using PBKDF2 algorithm specified in RFC 2898.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>password</strong> – Derive the key from this password.</li>
+<li><strong>salt</strong> – Salt.</li>
+<li><strong>iter</strong> – Number of iterations to perform.</li>
+<li><strong>keylen</strong> – Length of key to produce.</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">Key.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+</div>
+<div class="section" id="module-M2Crypto.Engine">
+<span id="engine-module"></span><h2><code class="xref py py-mod docutils literal notranslate"><span class="pre">Engine</span></code> Module<a class="headerlink" href="#module-M2Crypto.Engine" title="Permalink to this headline">¶</a></h2>
+<dl class="class">
+<dt id="M2Crypto.Engine.Engine">
+<em class="property">class </em><code class="descclassname">M2Crypto.Engine.</code><code class="descname">Engine</code><span class="sig-paren">(</span><em>id=None</em>, <em>_ptr=None</em>, <em>_pyfree=1</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/Engine.html#Engine"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.Engine.Engine" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
+<p>Wrapper for ENGINE object.</p>
+<dl class="method">
+<dt id="M2Crypto.Engine.Engine.ctrl_cmd_string">
+<code class="descname">ctrl_cmd_string</code><span class="sig-paren">(</span><em>cmd</em>, <em>arg</em>, <em>optional=0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/Engine.html#Engine.ctrl_cmd_string"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.Engine.Engine.ctrl_cmd_string" title="Permalink to this definition">¶</a></dt>
+<dd><p>Call ENGINE_ctrl_cmd_string</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.Engine.Engine.finish">
+<code class="descname">finish</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/Engine.html#Engine.finish"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.Engine.Engine.finish" title="Permalink to this definition">¶</a></dt>
+<dd><p>Release a functional and structural reference to the engine.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.Engine.Engine.get_id">
+<code class="descname">get_id</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/Engine.html#Engine.get_id"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.Engine.Engine.get_id" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return engine id</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.Engine.Engine.get_name">
+<code class="descname">get_name</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/Engine.html#Engine.get_name"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.Engine.Engine.get_name" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return engine name</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.Engine.Engine.init">
+<code class="descname">init</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/Engine.html#Engine.init"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.Engine.Engine.init" title="Permalink to this definition">¶</a></dt>
+<dd><p>Obtain a functional reference to the engine.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">0 on error, non-zero on success.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.Engine.Engine.load_certificate">
+<code class="descname">load_certificate</code><span class="sig-paren">(</span><em>name</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/Engine.html#Engine.load_certificate"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.Engine.Engine.load_certificate" title="Permalink to this definition">¶</a></dt>
+<dd><p>Load certificate from engine (e.g from smartcard).
+NOTE: This function may be not implemented by engine!</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.Engine.Engine.load_private_key">
+<code class="descname">load_private_key</code><span class="sig-paren">(</span><em>name</em>, <em>pin=None</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/Engine.html#Engine.load_private_key"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.Engine.Engine.load_private_key" title="Permalink to this definition">¶</a></dt>
+<dd><p>Load private key with engine methods (e.g from smartcard).
+If pin is not set it will be asked</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.Engine.Engine.load_public_key">
+<code class="descname">load_public_key</code><span class="sig-paren">(</span><em>name</em>, <em>pin=None</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/Engine.html#Engine.load_public_key"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.Engine.Engine.load_public_key" title="Permalink to this definition">¶</a></dt>
+<dd><p>Load public key with engine methods (e.g from smartcard).</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.Engine.Engine.m2_engine_free">
+<code class="descname">m2_engine_free</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.Engine.Engine.m2_engine_free" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.Engine.Engine.set_default">
+<code class="descname">set_default</code><span class="sig-paren">(</span><em>methods=65535</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/Engine.html#Engine.set_default"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.Engine.Engine.set_default" title="Permalink to this definition">¶</a></dt>
+<dd><p>Use this engine as default for methods specified in argument</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>methods</strong> – Possible values are bitwise OR of m2.ENGINE_METHOD_*</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+</dd></dl>
+
+<dl class="exception">
+<dt id="M2Crypto.Engine.EngineError">
+<em class="property">exception </em><code class="descclassname">M2Crypto.Engine.</code><code class="descname">EngineError</code><a class="reference internal" href="_modules/M2Crypto/Engine.html#EngineError"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.Engine.EngineError" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">Exception</span></code></p>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.Engine.cleanup">
+<code class="descclassname">M2Crypto.Engine.</code><code class="descname">cleanup</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/Engine.html#cleanup"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.Engine.cleanup" title="Permalink to this definition">¶</a></dt>
+<dd><p>If you load any engines, you need to clean up after your application
+is finished with the engines.</p>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.Engine.load_dynamic">
+<code class="descclassname">M2Crypto.Engine.</code><code class="descname">load_dynamic</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/Engine.html#load_dynamic"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.Engine.load_dynamic" title="Permalink to this definition">¶</a></dt>
+<dd><p>Load dynamic engine</p>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.Engine.load_dynamic_engine">
+<code class="descclassname">M2Crypto.Engine.</code><code class="descname">load_dynamic_engine</code><span class="sig-paren">(</span><em>id</em>, <em>sopath</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/Engine.html#load_dynamic_engine"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.Engine.load_dynamic_engine" title="Permalink to this definition">¶</a></dt>
+<dd><p>Load and return dymanic engine from sopath and assign id to it</p>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.Engine.load_openssl">
+<code class="descclassname">M2Crypto.Engine.</code><code class="descname">load_openssl</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/Engine.html#load_openssl"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.Engine.load_openssl" title="Permalink to this definition">¶</a></dt>
+<dd><p>Load openssl engine</p>
+</dd></dl>
+
+</div>
+<div class="section" id="module-M2Crypto.Err">
+<span id="err-module"></span><h2><code class="xref py py-mod docutils literal notranslate"><span class="pre">Err</span></code> Module<a class="headerlink" href="#module-M2Crypto.Err" title="Permalink to this headline">¶</a></h2>
+<dl class="exception">
+<dt id="M2Crypto.Err.M2CryptoError">
+<em class="property">exception </em><code class="descclassname">M2Crypto.Err.</code><code class="descname">M2CryptoError</code><a class="reference internal" href="_modules/M2Crypto/Err.html#M2CryptoError"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.Err.M2CryptoError" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">Exception</span></code></p>
+</dd></dl>
+
+<dl class="exception">
+<dt id="M2Crypto.Err.SSLError">
+<em class="property">exception </em><code class="descclassname">M2Crypto.Err.</code><code class="descname">SSLError</code><span class="sig-paren">(</span><em>err</em>, <em>client_addr</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/Err.html#SSLError"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.Err.SSLError" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">Exception</span></code></p>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.Err.get_error">
+<code class="descclassname">M2Crypto.Err.</code><code class="descname">get_error</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/Err.html#get_error"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.Err.get_error" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.Err.get_error_code">
+<code class="descclassname">M2Crypto.Err.</code><code class="descname">get_error_code</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/Err.html#get_error_code"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.Err.get_error_code" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.Err.get_error_func">
+<code class="descclassname">M2Crypto.Err.</code><code class="descname">get_error_func</code><span class="sig-paren">(</span><em>err</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/Err.html#get_error_func"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.Err.get_error_func" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.Err.get_error_lib">
+<code class="descclassname">M2Crypto.Err.</code><code class="descname">get_error_lib</code><span class="sig-paren">(</span><em>err</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/Err.html#get_error_lib"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.Err.get_error_lib" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.Err.get_error_message">
+<code class="descclassname">M2Crypto.Err.</code><code class="descname">get_error_message</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/Err.html#get_error_message"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.Err.get_error_message" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.Err.get_error_reason">
+<code class="descclassname">M2Crypto.Err.</code><code class="descname">get_error_reason</code><span class="sig-paren">(</span><em>err</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/Err.html#get_error_reason"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.Err.get_error_reason" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.Err.get_x509_verify_error">
+<code class="descclassname">M2Crypto.Err.</code><code class="descname">get_x509_verify_error</code><span class="sig-paren">(</span><em>err</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/Err.html#get_x509_verify_error"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.Err.get_x509_verify_error" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.Err.peek_error_code">
+<code class="descclassname">M2Crypto.Err.</code><code class="descname">peek_error_code</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/Err.html#peek_error_code"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.Err.peek_error_code" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+</div>
+<div class="section" id="module-M2Crypto.RC4">
+<span id="rc4-module"></span><h2><code class="xref py py-mod docutils literal notranslate"><span class="pre">RC4</span></code> Module<a class="headerlink" href="#module-M2Crypto.RC4" title="Permalink to this headline">¶</a></h2>
+<dl class="class">
+<dt id="M2Crypto.RC4.RC4">
+<em class="property">class </em><code class="descclassname">M2Crypto.RC4.</code><code class="descname">RC4</code><span class="sig-paren">(</span><em>key=None</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/RC4.html#RC4"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.RC4.RC4" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
+<p>Object interface to the stream cipher RC4.</p>
+<dl class="method">
+<dt id="M2Crypto.RC4.RC4.final">
+<code class="descname">final</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/RC4.html#RC4.final"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.RC4.RC4.final" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.RC4.RC4.rc4_free">
+<code class="descname">rc4_free</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.RC4.RC4.rc4_free" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.RC4.RC4.set_key">
+<code class="descname">set_key</code><span class="sig-paren">(</span><em>key</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/RC4.html#RC4.set_key"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.RC4.RC4.set_key" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.RC4.RC4.update">
+<code class="descname">update</code><span class="sig-paren">(</span><em>data</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/RC4.html#RC4.update"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.RC4.RC4.update" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+</dd></dl>
+
+</div>
+<div class="section" id="module-M2Crypto.RSA">
+<span id="rsa-module"></span><h2><code class="xref py py-mod docutils literal notranslate"><span class="pre">RSA</span></code> Module<a class="headerlink" href="#module-M2Crypto.RSA" title="Permalink to this headline">¶</a></h2>
+<dl class="class">
+<dt id="M2Crypto.RSA.RSA">
+<em class="property">class </em><code class="descclassname">M2Crypto.RSA.</code><code class="descname">RSA</code><span class="sig-paren">(</span><em>rsa</em>, <em>_pyfree=0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/RSA.html#RSA"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.RSA.RSA" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
+<p>RSA Key Pair.</p>
+<dl class="method">
+<dt id="M2Crypto.RSA.RSA.as_pem">
+<code class="descname">as_pem</code><span class="sig-paren">(</span><em>cipher='aes_128_cbc'</em>, <em>callback=&lt;function passphrase_callback&gt;</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/RSA.html#RSA.as_pem"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.RSA.RSA.as_pem" title="Permalink to this definition">¶</a></dt>
+<dd><p>Returns the key(pair) as a string in PEM format.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.RSA.RSA.check_key">
+<code class="descname">check_key</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/RSA.html#RSA.check_key"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.RSA.RSA.check_key" title="Permalink to this definition">¶</a></dt>
+<dd><p>Validate RSA keys.</p>
+<p>It checks that p and q are in fact prime, and that n = p*q.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">returns 1 if rsa is a valid RSA key, and 0 otherwise.
+-1 is returned if an error occurs while checking the key.
+If the key is invalid or an error occurred, the reason
+code can be obtained using ERR_get_error(3).</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.RSA.RSA.m2_rsa_free">
+<code class="descname">m2_rsa_free</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.RSA.RSA.m2_rsa_free" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.RSA.RSA.private_decrypt">
+<code class="descname">private_decrypt</code><span class="sig-paren">(</span><em>data</em>, <em>padding</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/RSA.html#RSA.private_decrypt"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.RSA.RSA.private_decrypt" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.RSA.RSA.private_encrypt">
+<code class="descname">private_encrypt</code><span class="sig-paren">(</span><em>data</em>, <em>padding</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/RSA.html#RSA.private_encrypt"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.RSA.RSA.private_encrypt" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.RSA.RSA.pub">
+<code class="descname">pub</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/RSA.html#RSA.pub"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.RSA.RSA.pub" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.RSA.RSA.public_decrypt">
+<code class="descname">public_decrypt</code><span class="sig-paren">(</span><em>data</em>, <em>padding</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/RSA.html#RSA.public_decrypt"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.RSA.RSA.public_decrypt" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.RSA.RSA.public_encrypt">
+<code class="descname">public_encrypt</code><span class="sig-paren">(</span><em>data</em>, <em>padding</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/RSA.html#RSA.public_encrypt"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.RSA.RSA.public_encrypt" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.RSA.RSA.save_key">
+<code class="descname">save_key</code><span class="sig-paren">(</span><em>file</em>, <em>cipher='aes_128_cbc'</em>, <em>callback=&lt;function passphrase_callback&gt;</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/RSA.html#RSA.save_key"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.RSA.RSA.save_key" title="Permalink to this definition">¶</a></dt>
+<dd><p>Save the key pair to a file in PEM format.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>file</strong> – Name of file to save key to.</li>
+<li><strong>cipher</strong> – Symmetric cipher to protect the key. The default
+cipher is ‘aes_128_cbc’. If cipher is None, then
+the key is saved in the clear.</li>
+<li><strong>callback</strong> – A Python callable object that is invoked
+to acquire a passphrase with which to protect
+the key. The default is
+util.passphrase_callback.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.RSA.RSA.save_key_bio">
+<code class="descname">save_key_bio</code><span class="sig-paren">(</span><em>bio</em>, <em>cipher='aes_128_cbc'</em>, <em>callback=&lt;function passphrase_callback&gt;</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/RSA.html#RSA.save_key_bio"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.RSA.RSA.save_key_bio" title="Permalink to this definition">¶</a></dt>
+<dd><p>Save the key pair to an M2Crypto.BIO.BIO object in PEM format.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>bio</strong> – M2Crypto.BIO.BIO object to save key to.</li>
+<li><strong>cipher</strong> – Symmetric cipher to protect the key. The default
+cipher is ‘aes_128_cbc’. If cipher is None, then
+the key is saved in the clear.</li>
+<li><strong>callback</strong> – A Python callable object that is invoked
+to acquire a passphrase with which to protect
+the key. The default is
+util.passphrase_callback.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.RSA.RSA.save_key_der">
+<code class="descname">save_key_der</code><span class="sig-paren">(</span><em>file</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/RSA.html#RSA.save_key_der"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.RSA.RSA.save_key_der" title="Permalink to this definition">¶</a></dt>
+<dd><p>Save the key pair to a file in DER format.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>file</strong> – Filename to save key to</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.RSA.RSA.save_key_der_bio">
+<code class="descname">save_key_der_bio</code><span class="sig-paren">(</span><em>bio</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/RSA.html#RSA.save_key_der_bio"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.RSA.RSA.save_key_der_bio" title="Permalink to this definition">¶</a></dt>
+<dd><p>Save the key pair to an M2Crypto.BIO.BIO object in DER format.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>bio</strong> – M2Crypto.BIO.BIO object to save key to.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.RSA.RSA.save_pem">
+<code class="descname">save_pem</code><span class="sig-paren">(</span><em>file</em>, <em>cipher='aes_128_cbc'</em>, <em>callback=&lt;function passphrase_callback&gt;</em><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.RSA.RSA.save_pem" title="Permalink to this definition">¶</a></dt>
+<dd><p>Save the key pair to a file in PEM format.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>file</strong> – Name of file to save key to.</li>
+<li><strong>cipher</strong> – Symmetric cipher to protect the key. The default
+cipher is ‘aes_128_cbc’. If cipher is None, then
+the key is saved in the clear.</li>
+<li><strong>callback</strong> – A Python callable object that is invoked
+to acquire a passphrase with which to protect
+the key. The default is
+util.passphrase_callback.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.RSA.RSA.save_pub_key">
+<code class="descname">save_pub_key</code><span class="sig-paren">(</span><em>file</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/RSA.html#RSA.save_pub_key"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.RSA.RSA.save_pub_key" title="Permalink to this definition">¶</a></dt>
+<dd><p>Save the public key to a file in PEM format.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>file</strong> – Name of file to save key to.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.RSA.RSA.save_pub_key_bio">
+<code class="descname">save_pub_key_bio</code><span class="sig-paren">(</span><em>bio</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/RSA.html#RSA.save_pub_key_bio"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.RSA.RSA.save_pub_key_bio" title="Permalink to this definition">¶</a></dt>
+<dd><p>Save the public key to an M2Crypto.BIO.BIO object in PEM format.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>bio</strong> – M2Crypto.BIO.BIO object to save key to.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.RSA.RSA.sign">
+<code class="descname">sign</code><span class="sig-paren">(</span><em>digest</em>, <em>algo='sha1'</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/RSA.html#RSA.sign"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.RSA.RSA.sign" title="Permalink to this definition">¶</a></dt>
+<dd><p>Signs a digest with the private key</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>digest</strong> – A digest created by using the digest method</li>
+<li><strong>algo</strong> – The method that created the digest.
+Legal values like ‘sha1’,’sha224’, ‘sha256’,
+‘ripemd160’, and ‘md5’.</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">a string which is the signature</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.RSA.RSA.sign_rsassa_pss">
+<code class="descname">sign_rsassa_pss</code><span class="sig-paren">(</span><em>digest</em>, <em>algo='sha1'</em>, <em>salt_length=20</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/RSA.html#RSA.sign_rsassa_pss"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.RSA.RSA.sign_rsassa_pss" title="Permalink to this definition">¶</a></dt>
+<dd><p>Signs a digest with the private key using RSASSA-PSS</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>digest</strong> – A digest created by using the digest method</li>
+<li><strong>salt_length</strong> – The length of the salt to use</li>
+<li><strong>algo</strong> – The hash algorithm to use
+Legal values like ‘sha1’,’sha224’, ‘sha256’,
+‘ripemd160’, and ‘md5’.</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">a string which is the signature</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.RSA.RSA.verify">
+<code class="descname">verify</code><span class="sig-paren">(</span><em>data</em>, <em>signature</em>, <em>algo='sha1'</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/RSA.html#RSA.verify"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.RSA.RSA.verify" title="Permalink to this definition">¶</a></dt>
+<dd><p>Verifies the signature with the public key</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>data</strong> – Data that has been signed</li>
+<li><strong>signature</strong> – The signature signed with the private key</li>
+<li><strong>algo</strong> – The method use to create digest from the data
+before it was signed. Legal values like
+‘sha1’,’sha224’, ‘sha256’, ‘ripemd160’, and ‘md5’.</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">1 or 0, depending on whether the signature was
+verified or not.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.RSA.RSA.verify_rsassa_pss">
+<code class="descname">verify_rsassa_pss</code><span class="sig-paren">(</span><em>data</em>, <em>signature</em>, <em>algo='sha1'</em>, <em>salt_length=20</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/RSA.html#RSA.verify_rsassa_pss"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.RSA.RSA.verify_rsassa_pss" title="Permalink to this definition">¶</a></dt>
+<dd><p>Verifies the signature RSASSA-PSS</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>data</strong> – Data that has been signed</li>
+<li><strong>signature</strong> – The signature signed with RSASSA-PSS</li>
+<li><strong>salt_length</strong> – The length of the salt that was used</li>
+<li><strong>algo</strong> – The hash algorithm to use
+Legal values are for example ‘sha1’,’sha224’,
+‘sha256’, ‘ripemd160’, and ‘md5’.</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">1 or 0, depending on whether the signature was
+verified or not.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+</dd></dl>
+
+<dl class="exception">
+<dt id="M2Crypto.RSA.RSAError">
+<em class="property">exception </em><code class="descclassname">M2Crypto.RSA.</code><code class="descname">RSAError</code><a class="reference internal" href="_modules/M2Crypto/RSA.html#RSAError"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.RSA.RSAError" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">Exception</span></code></p>
+</dd></dl>
+
+<dl class="class">
+<dt id="M2Crypto.RSA.RSA_pub">
+<em class="property">class </em><code class="descclassname">M2Crypto.RSA.</code><code class="descname">RSA_pub</code><span class="sig-paren">(</span><em>rsa</em>, <em>_pyfree=0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/RSA.html#RSA_pub"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.RSA.RSA_pub" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <a class="reference internal" href="#M2Crypto.RSA.RSA" title="M2Crypto.RSA.RSA"><code class="xref py py-class docutils literal notranslate"><span class="pre">M2Crypto.RSA.RSA</span></code></a></p>
+<p>Object interface to an RSA public key.</p>
+<dl class="method">
+<dt id="M2Crypto.RSA.RSA_pub.check_key">
+<code class="descname">check_key</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/RSA.html#RSA_pub.check_key"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.RSA.RSA_pub.check_key" title="Permalink to this definition">¶</a></dt>
+<dd><p>Validate RSA keys.</p>
+<p>It checks that p and q are in fact prime, and that n = p*q.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">returns 1 if rsa is a valid RSA key, and 0 otherwise.
+-1 is returned if an error occurs while checking the key.
+If the key is invalid or an error occurred, the reason
+code can be obtained using ERR_get_error(3).</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.RSA.RSA_pub.private_decrypt">
+<code class="descname">private_decrypt</code><span class="sig-paren">(</span><em>*argv</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/RSA.html#RSA_pub.private_decrypt"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.RSA.RSA_pub.private_decrypt" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.RSA.RSA_pub.private_encrypt">
+<code class="descname">private_encrypt</code><span class="sig-paren">(</span><em>*argv</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/RSA.html#RSA_pub.private_encrypt"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.RSA.RSA_pub.private_encrypt" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.RSA.RSA_pub.save_key">
+<code class="descname">save_key</code><span class="sig-paren">(</span><em>file</em>, <em>*args</em>, <em>**kw</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/RSA.html#RSA_pub.save_key"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.RSA.RSA_pub.save_key" title="Permalink to this definition">¶</a></dt>
+<dd><p>Save public key to file.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.RSA.RSA_pub.save_key_bio">
+<code class="descname">save_key_bio</code><span class="sig-paren">(</span><em>bio</em>, <em>*args</em>, <em>**kw</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/RSA.html#RSA_pub.save_key_bio"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.RSA.RSA_pub.save_key_bio" title="Permalink to this definition">¶</a></dt>
+<dd><p>Save public key to BIO.</p>
+</dd></dl>
+
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.RSA.gen_key">
+<code class="descclassname">M2Crypto.RSA.</code><code class="descname">gen_key</code><span class="sig-paren">(</span><em>bits</em>, <em>e</em>, <em>callback=&lt;function keygen_callback&gt;</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/RSA.html#gen_key"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.RSA.gen_key" title="Permalink to this definition">¶</a></dt>
+<dd><p>Generate an RSA key pair.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>bits</strong> – Key length, in bits.</li>
+<li><strong>e</strong> – The RSA public exponent.</li>
+<li><strong>callback</strong> – A Python callable object that is invoked
+during key generation; its usual purpose is to
+provide visual feedback. The default callback is
+keygen_callback.</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">M2Crypto.RSA.RSA object.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.RSA.keygen_callback">
+<code class="descclassname">M2Crypto.RSA.</code><code class="descname">keygen_callback</code><span class="sig-paren">(</span><em>p</em>, <em>n</em>, <em>out=&lt;_io.TextIOWrapper name='&lt;stdout&gt;' mode='w' encoding='UTF-8'&gt;</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/RSA.html#keygen_callback"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.RSA.keygen_callback" title="Permalink to this definition">¶</a></dt>
+<dd><p>Default callback for gen_key().</p>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.RSA.load_key">
+<code class="descclassname">M2Crypto.RSA.</code><code class="descname">load_key</code><span class="sig-paren">(</span><em>file</em>, <em>callback=&lt;function passphrase_callback&gt;</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/RSA.html#load_key"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.RSA.load_key" title="Permalink to this definition">¶</a></dt>
+<dd><p>Load an RSA key pair from file.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>file</strong> – Name of file containing RSA public key in PEM format.</li>
+<li><strong>callback</strong> – A Python callable object that is invoked
+to acquire a passphrase with which to unlock the
+key. The default is util.passphrase_callback.</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">M2Crypto.RSA.RSA object.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.RSA.load_key_bio">
+<code class="descclassname">M2Crypto.RSA.</code><code class="descname">load_key_bio</code><span class="sig-paren">(</span><em>bio</em>, <em>callback=&lt;function passphrase_callback&gt;</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/RSA.html#load_key_bio"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.RSA.load_key_bio" title="Permalink to this definition">¶</a></dt>
+<dd><p>Load an RSA key pair from an M2Crypto.BIO.BIO object.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>bio</strong> – M2Crypto.BIO.BIO object containing RSA key pair in PEM
+format.</li>
+<li><strong>callback</strong> – A Python callable object that is invoked
+to acquire a passphrase with which to unlock the
+key. The default is util.passphrase_callback.</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">M2Crypto.RSA.RSA object.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.RSA.load_key_string">
+<code class="descclassname">M2Crypto.RSA.</code><code class="descname">load_key_string</code><span class="sig-paren">(</span><em>string</em>, <em>callback=&lt;function passphrase_callback&gt;</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/RSA.html#load_key_string"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.RSA.load_key_string" title="Permalink to this definition">¶</a></dt>
+<dd><p>Load an RSA key pair from a string.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>string</strong> – String containing RSA key pair in PEM format.</li>
+<li><strong>callback</strong> – A Python callable object that is invoked
+to acquire a passphrase with which to unlock the
+key. The default is util.passphrase_callback.</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">M2Crypto.RSA.RSA object.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.RSA.load_pub_key">
+<code class="descclassname">M2Crypto.RSA.</code><code class="descname">load_pub_key</code><span class="sig-paren">(</span><em>file</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/RSA.html#load_pub_key"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.RSA.load_pub_key" title="Permalink to this definition">¶</a></dt>
+<dd><p>Load an RSA public key from file.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>file</strong> – Name of file containing RSA public key in PEM format.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">M2Crypto.RSA.RSA_pub object.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.RSA.load_pub_key_bio">
+<code class="descclassname">M2Crypto.RSA.</code><code class="descname">load_pub_key_bio</code><span class="sig-paren">(</span><em>bio</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/RSA.html#load_pub_key_bio"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.RSA.load_pub_key_bio" title="Permalink to this definition">¶</a></dt>
+<dd><p>Load an RSA public key from an M2Crypto.BIO.BIO object.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>bio</strong> – M2Crypto.BIO.BIO object containing RSA public key in PEM
+format.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">M2Crypto.RSA.RSA_pub object.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.RSA.new_pub_key">
+<code class="descclassname">M2Crypto.RSA.</code><code class="descname">new_pub_key</code><span class="sig-paren">(</span><em>e_n</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/RSA.html#new_pub_key"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.RSA.new_pub_key" title="Permalink to this definition">¶</a></dt>
+<dd><p>Instantiate an RSA_pub object from an (e, n) tuple.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>e</strong> – The RSA public exponent; it is a string in OpenSSL’s MPINT
+format - 4-byte big-endian bit-count followed by the
+appropriate number of bits.</li>
+<li><strong>n</strong> – The RSA composite of primes; it is a string in OpenSSL’s
+MPINT format - 4-byte big-endian bit-count followed by the
+appropriate number of bits.</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">M2Crypto.RSA.RSA_pub object.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.RSA.rsa_error">
+<code class="descclassname">M2Crypto.RSA.</code><code class="descname">rsa_error</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/RSA.html#rsa_error"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.RSA.rsa_error" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+</div>
+<div class="section" id="module-M2Crypto.Rand">
+<span id="rand-module"></span><h2><code class="xref py py-mod docutils literal notranslate"><span class="pre">Rand</span></code> Module<a class="headerlink" href="#module-M2Crypto.Rand" title="Permalink to this headline">¶</a></h2>
+<p>M2Crypto wrapper for OpenSSL PRNG. Requires OpenSSL 0.9.5 and above.</p>
+<p>Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved.
+Copyright (c) 2014-2017 Matej Cepl. All rights reserved.</p>
+<p>See LICENCE for the license information.</p>
+<dl class="function">
+<dt id="M2Crypto.Rand.rand_seed">
+<code class="descclassname">M2Crypto.Rand.</code><code class="descname">rand_seed</code><span class="sig-paren">(</span><em>seed</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/Rand.html#rand_seed"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.Rand.rand_seed" title="Permalink to this definition">¶</a></dt>
+<dd><p>Equivalent to rand_add() when len(seed) == entropy.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>seed</strong> – added data (see description at rand_add)</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.Rand.rand_add">
+<code class="descclassname">M2Crypto.Rand.</code><code class="descname">rand_add</code><span class="sig-paren">(</span><em>blob</em>, <em>entropy</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/Rand.html#rand_add"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.Rand.rand_add" title="Permalink to this definition">¶</a></dt>
+<dd><p>Mixes blob into the PRNG state.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>blob</strong> – added data</li>
+<li><strong>entropy</strong> – (the lower bound of) an estimate of how much randomness
+is contained in blob, measured in bytes.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+<p>Thus, if the data at buf are unpredictable to an adversary, this
+increases the uncertainty about the state and makes the PRNG output less
+predictable. Suitable input comes from user interaction (random key
+presses, mouse movements) and certain hardware events.</p>
+<p>Details about sources of randomness and how to estimate their entropy
+can be found in the literature, e.g. RFC 1750.</p>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.Rand.load_file">
+<code class="descclassname">M2Crypto.Rand.</code><code class="descname">load_file</code><span class="sig-paren">(</span><em>filename</em>, <em>max_bytes</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/Rand.html#load_file"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.Rand.load_file" title="Permalink to this definition">¶</a></dt>
+<dd><p>Read a number of bytes from file filename and adds them to the PRNG.</p>
+<p>If max_bytes is non-negative, up to to max_bytes are read; starting with
+OpenSSL 0.9.5, if max_bytes is -1, the complete file is read.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>filename</strong> – </li>
+<li><strong>max_bytes</strong> – </li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">the number of bytes read.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.Rand.save_file">
+<code class="descclassname">M2Crypto.Rand.</code><code class="descname">save_file</code><span class="sig-paren">(</span><em>filename</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/Rand.html#save_file"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.Rand.save_file" title="Permalink to this definition">¶</a></dt>
+<dd><p>Write a number of random bytes (currently 1024) to file.</p>
+<p>The file then can be used to initialize the PRNG by calling load_file() in
+a later session.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>filename</strong> – </td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">returns the number of bytes written, and -1 if the bytes
+written were generated without appropriate seed.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.Rand.rand_bytes">
+<code class="descclassname">M2Crypto.Rand.</code><code class="descname">rand_bytes</code><span class="sig-paren">(</span><em>num</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/Rand.html#rand_bytes"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.Rand.rand_bytes" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return n cryptographically strong pseudo-random bytes.</p>
+<p>An error occurs if the PRNG has not been seeded with enough randomness
+to ensure an unpredictable byte sequence.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>num</strong> – number of bytes to be returned</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">random bytes</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.Rand.rand_pseudo_bytes">
+<code class="descclassname">M2Crypto.Rand.</code><code class="descname">rand_pseudo_bytes</code><span class="sig-paren">(</span><em>num</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/Rand.html#rand_pseudo_bytes"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.Rand.rand_pseudo_bytes" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return num pseudo-random bytes into buf.</p>
+<p>Pseudo-random byte sequences generated by this method will be unique
+if they are of sufficient length, but are not necessarily
+unpredictable. They can be used for non-cryptographic purposes and for
+certain purposes in cryptographic protocols, but usually not for key
+generation etc.</p>
+<p>Output of the function is mixed into the entropy pool before
+retrieving the new pseudo-random bytes unless disabled at compile
+time (see FAQ).</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>num</strong> – number of bytes to be returned</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">random bytes</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.Rand.rand_file_name">
+<code class="descclassname">M2Crypto.Rand.</code><code class="descname">rand_file_name</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/Rand.html#rand_file_name"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.Rand.rand_file_name" title="Permalink to this definition">¶</a></dt>
+<dd><p>Generate a default path for the random seed file.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">string with the filename.
+The seed file is $RANDFILE if that environment variable
+is set, $HOME/.rnd otherwise. If $HOME is not set either,
+an error occurs.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.Rand.rand_status">
+<code class="descclassname">M2Crypto.Rand.</code><code class="descname">rand_status</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/Rand.html#rand_status"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.Rand.rand_status" title="Permalink to this definition">¶</a></dt>
+<dd><p>Check whether there is enough entropy in PRNG.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">1 if the PRNG has been seeded with enough
+data, 0 otherwise.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+</div>
+<div class="section" id="module-M2Crypto.SMIME">
+<span id="smime-module"></span><h2><code class="xref py py-mod docutils literal notranslate"><span class="pre">SMIME</span></code> Module<a class="headerlink" href="#module-M2Crypto.SMIME" title="Permalink to this headline">¶</a></h2>
+<dl class="class">
+<dt id="M2Crypto.SMIME.Cipher">
+<em class="property">class </em><code class="descclassname">M2Crypto.SMIME.</code><code class="descname">Cipher</code><span class="sig-paren">(</span><em>algo</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SMIME.html#Cipher"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SMIME.Cipher" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
+<p>Object interface to EVP_CIPHER without all the frills of
+M2Crypto.EVP.Cipher.</p>
+</dd></dl>
+
+<dl class="class">
+<dt id="M2Crypto.SMIME.PKCS7">
+<em class="property">class </em><code class="descclassname">M2Crypto.SMIME.</code><code class="descname">PKCS7</code><span class="sig-paren">(</span><em>pkcs7=None</em>, <em>_pyfree=0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SMIME.html#PKCS7"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SMIME.PKCS7" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
+<dl class="method">
+<dt id="M2Crypto.SMIME.PKCS7.get0_signers">
+<code class="descname">get0_signers</code><span class="sig-paren">(</span><em>certs</em>, <em>flags=0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SMIME.html#PKCS7.get0_signers"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SMIME.PKCS7.get0_signers" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SMIME.PKCS7.m2_pkcs7_free">
+<code class="descname">m2_pkcs7_free</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.SMIME.PKCS7.m2_pkcs7_free" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SMIME.PKCS7.type">
+<code class="descname">type</code><span class="sig-paren">(</span><em>text_name=0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SMIME.html#PKCS7.type"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SMIME.PKCS7.type" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SMIME.PKCS7.write">
+<code class="descname">write</code><span class="sig-paren">(</span><em>bio</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SMIME.html#PKCS7.write"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SMIME.PKCS7.write" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SMIME.PKCS7.write_der">
+<code class="descname">write_der</code><span class="sig-paren">(</span><em>bio</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SMIME.html#PKCS7.write_der"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SMIME.PKCS7.write_der" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+</dd></dl>
+
+<dl class="exception">
+<dt id="M2Crypto.SMIME.PKCS7_Error">
+<em class="property">exception </em><code class="descclassname">M2Crypto.SMIME.</code><code class="descname">PKCS7_Error</code><a class="reference internal" href="_modules/M2Crypto/SMIME.html#PKCS7_Error"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SMIME.PKCS7_Error" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">Exception</span></code></p>
+</dd></dl>
+
+<dl class="class">
+<dt id="M2Crypto.SMIME.SMIME">
+<em class="property">class </em><code class="descclassname">M2Crypto.SMIME.</code><code class="descname">SMIME</code><a class="reference internal" href="_modules/M2Crypto/SMIME.html#SMIME"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SMIME.SMIME" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
+<dl class="method">
+<dt id="M2Crypto.SMIME.SMIME.decrypt">
+<code class="descname">decrypt</code><span class="sig-paren">(</span><em>pkcs7</em>, <em>flags=0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SMIME.html#SMIME.decrypt"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SMIME.SMIME.decrypt" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SMIME.SMIME.encrypt">
+<code class="descname">encrypt</code><span class="sig-paren">(</span><em>data_bio</em>, <em>flags=0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SMIME.html#SMIME.encrypt"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SMIME.SMIME.encrypt" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SMIME.SMIME.load_key">
+<code class="descname">load_key</code><span class="sig-paren">(</span><em>keyfile</em>, <em>certfile=None</em>, <em>callback=&lt;function passphrase_callback&gt;</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SMIME.html#SMIME.load_key"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SMIME.SMIME.load_key" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SMIME.SMIME.load_key_bio">
+<code class="descname">load_key_bio</code><span class="sig-paren">(</span><em>keybio</em>, <em>certbio=None</em>, <em>callback=&lt;function passphrase_callback&gt;</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SMIME.html#SMIME.load_key_bio"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SMIME.SMIME.load_key_bio" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SMIME.SMIME.set_cipher">
+<code class="descname">set_cipher</code><span class="sig-paren">(</span><em>cipher</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SMIME.html#SMIME.set_cipher"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SMIME.SMIME.set_cipher" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SMIME.SMIME.set_x509_stack">
+<code class="descname">set_x509_stack</code><span class="sig-paren">(</span><em>stack</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SMIME.html#SMIME.set_x509_stack"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SMIME.SMIME.set_x509_stack" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SMIME.SMIME.set_x509_store">
+<code class="descname">set_x509_store</code><span class="sig-paren">(</span><em>store</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SMIME.html#SMIME.set_x509_store"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SMIME.SMIME.set_x509_store" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SMIME.SMIME.sign">
+<code class="descname">sign</code><span class="sig-paren">(</span><em>data_bio</em>, <em>flags=0</em>, <em>algo='sha1'</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SMIME.html#SMIME.sign"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SMIME.SMIME.sign" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SMIME.SMIME.unset_cipher">
+<code class="descname">unset_cipher</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SMIME.html#SMIME.unset_cipher"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SMIME.SMIME.unset_cipher" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SMIME.SMIME.unset_key">
+<code class="descname">unset_key</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SMIME.html#SMIME.unset_key"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SMIME.SMIME.unset_key" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SMIME.SMIME.unset_x509_stack">
+<code class="descname">unset_x509_stack</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SMIME.html#SMIME.unset_x509_stack"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SMIME.SMIME.unset_x509_stack" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SMIME.SMIME.unset_x509_store">
+<code class="descname">unset_x509_store</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SMIME.html#SMIME.unset_x509_store"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SMIME.SMIME.unset_x509_store" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SMIME.SMIME.verify">
+<code class="descname">verify</code><span class="sig-paren">(</span><em>pkcs7</em>, <em>data_bio=None</em>, <em>flags=0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SMIME.html#SMIME.verify"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SMIME.SMIME.verify" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.SMIME.SMIME.write">
+<code class="descname">write</code><span class="sig-paren">(</span><em>out_bio</em>, <em>pkcs7</em>, <em>data_bio=None</em>, <em>flags=0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SMIME.html#SMIME.write"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SMIME.SMIME.write" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+</dd></dl>
+
+<dl class="exception">
+<dt id="M2Crypto.SMIME.SMIME_Error">
+<em class="property">exception </em><code class="descclassname">M2Crypto.SMIME.</code><code class="descname">SMIME_Error</code><a class="reference internal" href="_modules/M2Crypto/SMIME.html#SMIME_Error"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SMIME.SMIME_Error" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">Exception</span></code></p>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.SMIME.load_pkcs7">
+<code class="descclassname">M2Crypto.SMIME.</code><code class="descname">load_pkcs7</code><span class="sig-paren">(</span><em>p7file</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SMIME.html#load_pkcs7"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SMIME.load_pkcs7" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.SMIME.load_pkcs7_bio">
+<code class="descclassname">M2Crypto.SMIME.</code><code class="descname">load_pkcs7_bio</code><span class="sig-paren">(</span><em>p7_bio</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SMIME.html#load_pkcs7_bio"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SMIME.load_pkcs7_bio" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.SMIME.load_pkcs7_bio_der">
+<code class="descclassname">M2Crypto.SMIME.</code><code class="descname">load_pkcs7_bio_der</code><span class="sig-paren">(</span><em>p7_bio</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SMIME.html#load_pkcs7_bio_der"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SMIME.load_pkcs7_bio_der" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.SMIME.load_pkcs7_der">
+<code class="descclassname">M2Crypto.SMIME.</code><code class="descname">load_pkcs7_der</code><span class="sig-paren">(</span><em>p7file</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SMIME.html#load_pkcs7_der"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SMIME.load_pkcs7_der" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.SMIME.smime_load_pkcs7">
+<code class="descclassname">M2Crypto.SMIME.</code><code class="descname">smime_load_pkcs7</code><span class="sig-paren">(</span><em>p7file</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SMIME.html#smime_load_pkcs7"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SMIME.smime_load_pkcs7" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.SMIME.smime_load_pkcs7_bio">
+<code class="descclassname">M2Crypto.SMIME.</code><code class="descname">smime_load_pkcs7_bio</code><span class="sig-paren">(</span><em>p7_bio</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SMIME.html#smime_load_pkcs7_bio"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SMIME.smime_load_pkcs7_bio" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.SMIME.text_crlf">
+<code class="descclassname">M2Crypto.SMIME.</code><code class="descname">text_crlf</code><span class="sig-paren">(</span><em>text</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SMIME.html#text_crlf"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SMIME.text_crlf" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.SMIME.text_crlf_bio">
+<code class="descclassname">M2Crypto.SMIME.</code><code class="descname">text_crlf_bio</code><span class="sig-paren">(</span><em>bio_in</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/SMIME.html#text_crlf_bio"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.SMIME.text_crlf_bio" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+</div>
+<div class="section" id="module-M2Crypto.X509">
+<span id="x509-module"></span><h2><code class="xref py py-mod docutils literal notranslate"><span class="pre">X509</span></code> Module<a class="headerlink" href="#module-M2Crypto.X509" title="Permalink to this headline">¶</a></h2>
+<dl class="class">
+<dt id="M2Crypto.X509.CRL">
+<em class="property">class </em><code class="descclassname">M2Crypto.X509.</code><code class="descname">CRL</code><span class="sig-paren">(</span><em>crl=None</em>, <em>_pyfree=0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#CRL"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.CRL" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
+<p>X509 Certificate Revocation List</p>
+<dl class="method">
+<dt id="M2Crypto.X509.CRL.as_text">
+<code class="descname">as_text</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#CRL.as_text"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.CRL.as_text" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return CRL in PEM format in a string.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">String containing the CRL in PEM format.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.CRL.m2_x509_crl_free">
+<code class="descname">m2_x509_crl_free</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.X509.CRL.m2_x509_crl_free" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="M2Crypto.X509.Request">
+<em class="property">class </em><code class="descclassname">M2Crypto.X509.</code><code class="descname">Request</code><span class="sig-paren">(</span><em>req=None</em>, <em>_pyfree=0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#Request"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.Request" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
+<p>X509 Certificate Request.</p>
+<dl class="method">
+<dt id="M2Crypto.X509.Request.add_extensions">
+<code class="descname">add_extensions</code><span class="sig-paren">(</span><em>ext_stack</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#Request.add_extensions"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.Request.add_extensions" title="Permalink to this definition">¶</a></dt>
+<dd><p>Add X509 extensions to this request.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>ext_stack</strong> – Stack of extensions to add.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">1 for success and 0 for failure</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.Request.as_der">
+<code class="descname">as_der</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#Request.as_der"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.Request.as_der" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.Request.as_pem">
+<code class="descname">as_pem</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#Request.as_pem"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.Request.as_pem" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.Request.as_text">
+<code class="descname">as_text</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#Request.as_text"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.Request.as_text" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.Request.get_pubkey">
+<code class="descname">get_pubkey</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#Request.get_pubkey"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.Request.get_pubkey" title="Permalink to this definition">¶</a></dt>
+<dd><p>Get the public key for the request.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">Public key from the request.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.Request.get_subject">
+<code class="descname">get_subject</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#Request.get_subject"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.Request.get_subject" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.Request.get_version">
+<code class="descname">get_version</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#Request.get_version"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.Request.get_version" title="Permalink to this definition">¶</a></dt>
+<dd><p>Get version.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">Returns version.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.Request.m2_x509_req_free">
+<code class="descname">m2_x509_req_free</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.X509.Request.m2_x509_req_free" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.Request.save">
+<code class="descname">save</code><span class="sig-paren">(</span><em>filename</em>, <em>format=1</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#Request.save"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.Request.save" title="Permalink to this definition">¶</a></dt>
+<dd><p>Saves X.509 certificate request to a file. Default output
+format is PEM.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>filename</strong> – Name of the file the request will be saved to.</li>
+<li><strong>format</strong> – Controls what output format is used to save the
+request. Either FORMAT_PEM or FORMAT_DER to save
+in PEM or DER format. Raises ValueError if an
+unknown format is used.</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">1 for success, 0 for failure.
+The error code can be obtained by ERR_get_error.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.Request.save_pem">
+<code class="descname">save_pem</code><span class="sig-paren">(</span><em>filename</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#Request.save_pem"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.Request.save_pem" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.Request.set_pubkey">
+<code class="descname">set_pubkey</code><span class="sig-paren">(</span><em>pkey</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#Request.set_pubkey"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.Request.set_pubkey" title="Permalink to this definition">¶</a></dt>
+<dd><p>Set the public key for the request.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>pkey</strong> – Public key</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">Return 1 for success and 0 for failure.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.Request.set_subject">
+<code class="descname">set_subject</code><span class="sig-paren">(</span><em>name</em><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.X509.Request.set_subject" title="Permalink to this definition">¶</a></dt>
+<dd><p>Set subject name.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>name</strong> – subjectName field.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">1 for success and 0 for failure</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.Request.set_subject_name">
+<code class="descname">set_subject_name</code><span class="sig-paren">(</span><em>name</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#Request.set_subject_name"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.Request.set_subject_name" title="Permalink to this definition">¶</a></dt>
+<dd><p>Set subject name.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>name</strong> – subjectName field.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">1 for success and 0 for failure</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.Request.set_version">
+<code class="descname">set_version</code><span class="sig-paren">(</span><em>version</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#Request.set_version"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.Request.set_version" title="Permalink to this definition">¶</a></dt>
+<dd><p>Set version.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>version</strong> – Version number.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">Returns 0 on failure.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.Request.sign">
+<code class="descname">sign</code><span class="sig-paren">(</span><em>pkey</em>, <em>md</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#Request.sign"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.Request.sign" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>pkey</strong> – PKey to be signed</li>
+<li><strong>md</strong> – used algorigthm</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">1 for success and 0 for failure</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.Request.verify">
+<code class="descname">verify</code><span class="sig-paren">(</span><em>pkey</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#Request.verify"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.Request.verify" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>pkey</strong> – PKey to be verified</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">1 for success and 0 for failure</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="M2Crypto.X509.X509">
+<em class="property">class </em><code class="descclassname">M2Crypto.X509.</code><code class="descname">X509</code><span class="sig-paren">(</span><em>x509=None</em>, <em>_pyfree=0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
+<p>X.509 Certificate</p>
+<dl class="method">
+<dt id="M2Crypto.X509.X509.add_ext">
+<code class="descname">add_ext</code><span class="sig-paren">(</span><em>ext</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509.add_ext"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509.add_ext" title="Permalink to this definition">¶</a></dt>
+<dd><p>Add X509 extension to this certificate.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>ext</strong> – Extension</td>
+</tr>
+</tbody>
+</table>
+<p>:return 1 for success and 0 for failure</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509.as_der">
+<code class="descname">as_der</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509.as_der"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509.as_der" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509.as_pem">
+<code class="descname">as_pem</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509.as_pem"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509.as_pem" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509.as_text">
+<code class="descname">as_text</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509.as_text"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509.as_text" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509.check_ca">
+<code class="descname">check_ca</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509.check_ca"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509.check_ca" title="Permalink to this definition">¶</a></dt>
+<dd><p>Check if the certificate is a Certificate Authority (CA) certificate.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">0 if the certificate is not CA, nonzero otherwise.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Requires:</th><td class="field-body">OpenSSL 0.9.8 or newer</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509.check_purpose">
+<code class="descname">check_purpose</code><span class="sig-paren">(</span><em>id</em>, <em>ca</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509.check_purpose"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509.check_purpose" title="Permalink to this definition">¶</a></dt>
+<dd><p>Check if the certificate’s purpose matches the asked purpose.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>id</strong> – Purpose id. See X509_PURPOSE_* constants.</li>
+<li><strong>ca</strong> – 1 if the certificate should be CA, 0 otherwise.</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">0 if the certificate purpose does not match, nonzero
+otherwise.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509.get_ext">
+<code class="descname">get_ext</code><span class="sig-paren">(</span><em>name</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509.get_ext"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509.get_ext" title="Permalink to this definition">¶</a></dt>
+<dd><p>Get X509 extension by name.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>name</strong> – Name of the extension</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">X509_Extension</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509.get_ext_at">
+<code class="descname">get_ext_at</code><span class="sig-paren">(</span><em>index</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509.get_ext_at"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509.get_ext_at" title="Permalink to this definition">¶</a></dt>
+<dd><p>Get X509 extension by index.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>index</strong> – Name of the extension</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">X509_Extension</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509.get_ext_count">
+<code class="descname">get_ext_count</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509.get_ext_count"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509.get_ext_count" title="Permalink to this definition">¶</a></dt>
+<dd><p>Get X509 extension count.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509.get_fingerprint">
+<code class="descname">get_fingerprint</code><span class="sig-paren">(</span><em>md='md5'</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509.get_fingerprint"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509.get_fingerprint" title="Permalink to this definition">¶</a></dt>
+<dd><p>Get the fingerprint of the certificate.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>md</strong> – Message digest algorithm to use.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">String containing the fingerprint in hex format.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509.get_issuer">
+<code class="descname">get_issuer</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509.get_issuer"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509.get_issuer" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509.get_not_after">
+<code class="descname">get_not_after</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509.get_not_after"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509.get_not_after" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509.get_not_before">
+<code class="descname">get_not_before</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509.get_not_before"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509.get_not_before" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509.get_pubkey">
+<code class="descname">get_pubkey</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509.get_pubkey"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509.get_pubkey" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509.get_serial_number">
+<code class="descname">get_serial_number</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509.get_serial_number"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509.get_serial_number" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509.get_subject">
+<code class="descname">get_subject</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509.get_subject"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509.get_subject" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509.get_version">
+<code class="descname">get_version</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509.get_version"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509.get_version" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509.m2_x509_free">
+<code class="descname">m2_x509_free</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.X509.X509.m2_x509_free" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509.save">
+<code class="descname">save</code><span class="sig-paren">(</span><em>filename</em>, <em>format=1</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509.save"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509.save" title="Permalink to this definition">¶</a></dt>
+<dd><p>Saves X.509 certificate to a file. Default output
+format is PEM.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>filename</strong> – Name of the file the cert will be saved to.</li>
+<li><strong>format</strong> – Controls what output format is used to save the cert.
+Either FORMAT_PEM or FORMAT_DER to save in PEM or
+DER format. Raises a ValueError if an unknow
+format is used.</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">1 for success or 0 for failure</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509.save_pem">
+<code class="descname">save_pem</code><span class="sig-paren">(</span><em>filename</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509.save_pem"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509.save_pem" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>filename</strong> – name of the file to be loaded</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">1 for success or 0 for failure</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509.set_issuer">
+<code class="descname">set_issuer</code><span class="sig-paren">(</span><em>name</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509.set_issuer"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509.set_issuer" title="Permalink to this definition">¶</a></dt>
+<dd><p>Set issuer name.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>name</strong> – subjectName field.</td>
+</tr>
+</tbody>
+</table>
+<p>:return 1 for success and 0 for failure</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509.set_issuer_name">
+<code class="descname">set_issuer_name</code><span class="sig-paren">(</span><em>name</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509.set_issuer_name"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509.set_issuer_name" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">1 on success, 0 on failure</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509.set_not_after">
+<code class="descname">set_not_after</code><span class="sig-paren">(</span><em>asn1_time</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509.set_not_after"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509.set_not_after" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">1 on success, 0 on failure</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509.set_not_before">
+<code class="descname">set_not_before</code><span class="sig-paren">(</span><em>asn1_time</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509.set_not_before"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509.set_not_before" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">1 on success, 0 on failure</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509.set_pubkey">
+<code class="descname">set_pubkey</code><span class="sig-paren">(</span><em>pkey</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509.set_pubkey"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509.set_pubkey" title="Permalink to this definition">¶</a></dt>
+<dd><p>Set the public key for the certificate</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>pkey</strong> – Public key</td>
+</tr>
+</tbody>
+</table>
+<p>:return 1 for success and 0 for failure</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509.set_serial_number">
+<code class="descname">set_serial_number</code><span class="sig-paren">(</span><em>serial</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509.set_serial_number"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509.set_serial_number" title="Permalink to this definition">¶</a></dt>
+<dd><p>Set serial number.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>serial</strong> – Serial number.</td>
+</tr>
+</tbody>
+</table>
+<p>:return 1 for success and 0 for failure.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509.set_subject">
+<code class="descname">set_subject</code><span class="sig-paren">(</span><em>name</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509.set_subject"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509.set_subject" title="Permalink to this definition">¶</a></dt>
+<dd><p>Set subject name.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>name</strong> – subjectName field.</td>
+</tr>
+</tbody>
+</table>
+<p>:return 1 for success and 0 for failure</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509.set_subject_name">
+<code class="descname">set_subject_name</code><span class="sig-paren">(</span><em>name</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509.set_subject_name"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509.set_subject_name" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">1 on success, 0 on failure</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509.set_version">
+<code class="descname">set_version</code><span class="sig-paren">(</span><em>version</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509.set_version"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509.set_version" title="Permalink to this definition">¶</a></dt>
+<dd><p>Set version of the certificate.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>version</strong> – Version number.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">Returns 0 on failure.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509.sign">
+<code class="descname">sign</code><span class="sig-paren">(</span><em>pkey</em>, <em>md</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509.sign"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509.sign" title="Permalink to this definition">¶</a></dt>
+<dd><p>Sign the certificate.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>pkey</strong> – Public key</li>
+<li><strong>md</strong> – Message digest algorithm to use for signing,
+for example ‘sha1’.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+<p>:return int</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509.verify">
+<code class="descname">verify</code><span class="sig-paren">(</span><em>pkey=None</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509.verify"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509.verify" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+</dd></dl>
+
+<dl class="exception">
+<dt id="M2Crypto.X509.X509Error">
+<em class="property">exception </em><code class="descclassname">M2Crypto.X509.</code><code class="descname">X509Error</code><a class="reference internal" href="_modules/M2Crypto/X509.html#X509Error"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509Error" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">ValueError</span></code></p>
+</dd></dl>
+
+<dl class="class">
+<dt id="M2Crypto.X509.X509_Extension">
+<em class="property">class </em><code class="descclassname">M2Crypto.X509.</code><code class="descname">X509_Extension</code><span class="sig-paren">(</span><em>x509_ext_ptr=None</em>, <em>_pyfree=1</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509_Extension"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509_Extension" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
+<p>X509 Extension</p>
+<dl class="method">
+<dt id="M2Crypto.X509.X509_Extension.get_critical">
+<code class="descname">get_critical</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509_Extension.get_critical"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509_Extension.get_critical" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return whether or not this is a critical extension.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">Nonzero if this is a critical extension.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509_Extension.get_name">
+<code class="descname">get_name</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509_Extension.get_name"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509_Extension.get_name" title="Permalink to this definition">¶</a></dt>
+<dd><p>Get the extension name, for example ‘subjectAltName’.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509_Extension.get_value">
+<code class="descname">get_value</code><span class="sig-paren">(</span><em>flag=0</em>, <em>indent=0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509_Extension.get_value"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509_Extension.get_value" title="Permalink to this definition">¶</a></dt>
+<dd><p>Get the extension value, for example ‘<a class="reference external" href="DNS:www.example.com">DNS:www.example.com</a>’.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>flag</strong> – Flag to control what and how to print.</li>
+<li><strong>indent</strong> – How many spaces to print before actual value.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509_Extension.m2_x509_extension_free">
+<code class="descname">m2_x509_extension_free</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.X509.X509_Extension.m2_x509_extension_free" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509_Extension.set_critical">
+<code class="descname">set_critical</code><span class="sig-paren">(</span><em>critical=1</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509_Extension.set_critical"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509_Extension.set_critical" title="Permalink to this definition">¶</a></dt>
+<dd><p>Mark this extension critical or noncritical. By default an
+extension is not critical.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>critical</strong> – Nonzero sets this extension as critical.
+Calling this method without arguments will
+set this extension to critical.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">1 for success, 0 for failure</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="M2Crypto.X509.X509_Extension_Stack">
+<em class="property">class </em><code class="descclassname">M2Crypto.X509.</code><code class="descname">X509_Extension_Stack</code><span class="sig-paren">(</span><em>stack=None</em>, <em>_pyfree=0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509_Extension_Stack"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509_Extension_Stack" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
+<p>X509 Extension Stack</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Warning:</th><td class="field-body">Do not modify the underlying OpenSSL stack
+except through this interface, or use any OpenSSL
+functions that do so indirectly. Doing so will get the
+OpenSSL stack and the internal pystack of this class out
+of sync, leading to python memory leaks, exceptions or
+even python crashes!</td>
+</tr>
+</tbody>
+</table>
+<dl class="method">
+<dt id="M2Crypto.X509.X509_Extension_Stack.m2_sk_x509_extension_free">
+<code class="descname">m2_sk_x509_extension_free</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.X509.X509_Extension_Stack.m2_sk_x509_extension_free" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509_Extension_Stack.pop">
+<code class="descname">pop</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509_Extension_Stack.pop"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509_Extension_Stack.pop" title="Permalink to this definition">¶</a></dt>
+<dd><p>Pop X509_Extension object from the stack.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">X509_Extension popped</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509_Extension_Stack.push">
+<code class="descname">push</code><span class="sig-paren">(</span><em>x509_ext</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509_Extension_Stack.push"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509_Extension_Stack.push" title="Permalink to this definition">¶</a></dt>
+<dd><p>Push X509_Extension object onto the stack.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>x509_ext</strong> – X509_Extension object to be pushed onto the stack.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">The number of extensions on the stack.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="M2Crypto.X509.X509_Name">
+<em class="property">class </em><code class="descclassname">M2Crypto.X509.</code><code class="descname">X509_Name</code><span class="sig-paren">(</span><em>x509_name=None</em>, <em>_pyfree=0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509_Name"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509_Name" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
+<p>X509 Name</p>
+<dl class="method">
+<dt id="M2Crypto.X509.X509_Name.add_entry_by_txt">
+<code class="descname">add_entry_by_txt</code><span class="sig-paren">(</span><em>field</em>, <em>type</em>, <em>entry</em>, <em>len</em>, <em>loc</em>, <em>set</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509_Name.add_entry_by_txt"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509_Name.add_entry_by_txt" title="Permalink to this definition">¶</a></dt>
+<dd><p>Add X509_Name field whose name is identified by its name.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>field</strong> – name of the entry</li>
+<li><strong>type</strong> – use MBSTRING_ASC or MBSTRING_UTF8
+(or standard ASN1 type like V_ASN1_IA5STRING)</li>
+<li><strong>entry</strong> – value</li>
+<li><strong>len</strong> – buf_len of the entry
+(-1 and the length is computed automagically)</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+<p>The <code class="docutils literal notranslate"><span class="pre">loc</span></code> and <code class="docutils literal notranslate"><span class="pre">set</span></code> parameters determine where a new entry
+should be added.
+For almost all applications loc can be set to -1 and set to 0.
+This adds a new entry to the end of name as a single valued
+RelativeDistinguishedName (RDN).</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>loc</strong> – determines the index where the new entry is
+inserted: if it is -1 it is appended.</li>
+<li><strong>set</strong> – determines how the new type is added. If it is zero
+a new RDN is created.
+If set is -1 or 1 it is added to the previous or next RDN
+structure respectively. This will then be a multivalued
+RDN: since multivalues RDNs are very seldom used set is
+almost always set to zero.</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">1 for success of 0 if an error occurred.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509_Name.as_der">
+<code class="descname">as_der</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509_Name.as_der"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509_Name.as_der" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509_Name.as_hash">
+<code class="descname">as_hash</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509_Name.as_hash"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509_Name.as_hash" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509_Name.as_text">
+<code class="descname">as_text</code><span class="sig-paren">(</span><em>indent=0</em>, <em>flags=0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509_Name.as_text"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509_Name.as_text" title="Permalink to this definition">¶</a></dt>
+<dd><p>as_text returns the name as a string.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>indent</strong> – Each line in multiline format is indented
+by this many spaces.</li>
+<li><strong>flags</strong> – Flags that control how the output should be formatted.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509_Name.entry_count">
+<code class="descname">entry_count</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509_Name.entry_count"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509_Name.entry_count" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509_Name.get_entries_by_nid">
+<code class="descname">get_entries_by_nid</code><span class="sig-paren">(</span><em>nid</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509_Name.get_entries_by_nid"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509_Name.get_entries_by_nid" title="Permalink to this definition">¶</a></dt>
+<dd><p>Retrieve the next index matching nid.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>nid</strong> – name of the entry (as m2.NID* constants)</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">list of X509_Name_Entry items</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509_Name.m2_x509_name_free">
+<code class="descname">m2_x509_name_free</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.X509.X509_Name.m2_x509_name_free" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="attribute">
+<dt id="M2Crypto.X509.X509_Name.nid">
+<code class="descname">nid</code><em class="property"> = {'C': 14, 'CN': 13, 'Email': 48, 'GN': 99, 'L': 15, 'O': 17, 'OU': 18, 'SN': 100, 'SP': 16, 'ST': 16, 'commonName': 13, 'emailAddress': 48, 'givenName': 99, 'localityName': 15, 'organizationName': 17, 'organizationUnitName': 18, 'serialNumber': 105, 'stateOrProvinceName': 16, 'surname': 100}</em><a class="headerlink" href="#M2Crypto.X509.X509_Name.nid" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="M2Crypto.X509.X509_Name_Entry">
+<em class="property">class </em><code class="descclassname">M2Crypto.X509.</code><code class="descname">X509_Name_Entry</code><span class="sig-paren">(</span><em>x509_name_entry</em>, <em>_pyfree=0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509_Name_Entry"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509_Name_Entry" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
+<p>X509 Name Entry</p>
+<dl class="method">
+<dt id="M2Crypto.X509.X509_Name_Entry.create_by_txt">
+<code class="descname">create_by_txt</code><span class="sig-paren">(</span><em>field</em>, <em>type</em>, <em>entry</em>, <em>len</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509_Name_Entry.create_by_txt"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509_Name_Entry.create_by_txt" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509_Name_Entry.get_data">
+<code class="descname">get_data</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509_Name_Entry.get_data"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509_Name_Entry.get_data" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509_Name_Entry.get_object">
+<code class="descname">get_object</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509_Name_Entry.get_object"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509_Name_Entry.get_object" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509_Name_Entry.m2_x509_name_entry_free">
+<code class="descname">m2_x509_name_entry_free</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.X509.X509_Name_Entry.m2_x509_name_entry_free" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509_Name_Entry.set_data">
+<code class="descname">set_data</code><span class="sig-paren">(</span><em>data</em>, <em>type=4097</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509_Name_Entry.set_data"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509_Name_Entry.set_data" title="Permalink to this definition">¶</a></dt>
+<dd><p>Sets the field name to asn1obj</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>data</strong> – data in a binary form to be set</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">0 on failure, 1 on success</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509_Name_Entry.set_object">
+<code class="descname">set_object</code><span class="sig-paren">(</span><em>asn1obj</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509_Name_Entry.set_object"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509_Name_Entry.set_object" title="Permalink to this definition">¶</a></dt>
+<dd><p>Sets the field name to asn1obj</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>asn1obj</strong> – </td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">0 on failure, 1 on success</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="M2Crypto.X509.X509_Stack">
+<em class="property">class </em><code class="descclassname">M2Crypto.X509.</code><code class="descname">X509_Stack</code><span class="sig-paren">(</span><em>stack=None</em>, <em>_pyfree=0</em>, <em>_pyfree_x509=0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509_Stack"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509_Stack" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
+<p>X509 Stack</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Warning:</th><td class="field-body">Do not modify the underlying OpenSSL stack
+except through this interface, or use any OpenSSL
+functions that do so indirectly. Doing so will get the
+OpenSSL stack and the internal pystack of this class out
+of sync, leading to python memory leaks, exceptions or
+even python crashes!</td>
+</tr>
+</tbody>
+</table>
+<dl class="method">
+<dt id="M2Crypto.X509.X509_Stack.as_der">
+<code class="descname">as_der</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509_Stack.as_der"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509_Stack.as_der" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return the stack as a DER encoded string</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509_Stack.m2_sk_x509_free">
+<code class="descname">m2_sk_x509_free</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.X509.X509_Stack.m2_sk_x509_free" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509_Stack.pop">
+<code class="descname">pop</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509_Stack.pop"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509_Stack.pop" title="Permalink to this definition">¶</a></dt>
+<dd><p>pop a certificate from the stack.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">X509 object that was popped, or None if there is
+nothing to pop.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509_Stack.push">
+<code class="descname">push</code><span class="sig-paren">(</span><em>x509</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509_Stack.push"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509_Stack.push" title="Permalink to this definition">¶</a></dt>
+<dd><p>push an X509 certificate onto the stack.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>x509</strong> – X509 object.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">The number of X509 objects currently on the stack.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="M2Crypto.X509.X509_Store">
+<em class="property">class </em><code class="descclassname">M2Crypto.X509.</code><code class="descname">X509_Store</code><span class="sig-paren">(</span><em>store=None</em>, <em>_pyfree=0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509_Store"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509_Store" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
+<p>X509 Store</p>
+<dl class="method">
+<dt id="M2Crypto.X509.X509_Store.add_cert">
+<code class="descname">add_cert</code><span class="sig-paren">(</span><em>x509</em><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.X509.X509_Store.add_cert" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509_Store.add_x509">
+<code class="descname">add_x509</code><span class="sig-paren">(</span><em>x509</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509_Store.add_x509"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509_Store.add_x509" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509_Store.load_info">
+<code class="descname">load_info</code><span class="sig-paren">(</span><em>file</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509_Store.load_info"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509_Store.load_info" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>file</strong> – filename</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">1 on success, 0 on failure</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509_Store.load_locations">
+<code class="descname">load_locations</code><span class="sig-paren">(</span><em>file</em><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.X509.X509_Store.load_locations" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>file</strong> – filename</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">1 on success, 0 on failure</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509_Store.m2_x509_store_free">
+<code class="descname">m2_x509_store_free</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.X509.X509_Store.m2_x509_store_free" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509_Store.set_verify_cb">
+<code class="descname">set_verify_cb</code><span class="sig-paren">(</span><em>callback=None</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509_Store.set_verify_cb"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509_Store.set_verify_cb" title="Permalink to this definition">¶</a></dt>
+<dd><p>Set callback which will be called when the store is verified.
+Wrapper over OpenSSL X509_STORE_set_verify_cb().</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>callback</strong> – Callable to specify verification options.
+Type of the callable must be:
+(int, X509_Store_Context) -&gt; int.
+If None: set the standard options.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Note:</th><td class="field-body">compile-time or run-time errors in the callback would result
+in mysterious errors during verification, which could be hard
+to trace.</td>
+</tr>
+<tr class="field-odd field"><th class="field-name">Note:</th><td class="field-body">Python exceptions raised in callbacks do not propagate to
+verify() call.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">None</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="M2Crypto.X509.X509_Store_Context">
+<em class="property">class </em><code class="descclassname">M2Crypto.X509.</code><code class="descname">X509_Store_Context</code><span class="sig-paren">(</span><em>x509_store_ctx</em>, <em>_pyfree=0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509_Store_Context"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509_Store_Context" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
+<p>X509 Store Context</p>
+<dl class="method">
+<dt id="M2Crypto.X509.X509_Store_Context.get1_chain">
+<code class="descname">get1_chain</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509_Store_Context.get1_chain"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509_Store_Context.get1_chain" title="Permalink to this definition">¶</a></dt>
+<dd><p>Get certificate chain.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">Reference counted (i.e. safe to use even after the store
+context goes away) stack of certificates in the chain.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509_Store_Context.get_current_cert">
+<code class="descname">get_current_cert</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509_Store_Context.get_current_cert"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509_Store_Context.get_current_cert" title="Permalink to this definition">¶</a></dt>
+<dd><p>Get current X.509 certificate.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Warning:</th><td class="field-body">The returned certificate is NOT refcounted, so you can not
+rely on it being valid once the store context goes
+away or is modified.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509_Store_Context.get_error">
+<code class="descname">get_error</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509_Store_Context.get_error"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509_Store_Context.get_error" title="Permalink to this definition">¶</a></dt>
+<dd><p>Get error code.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509_Store_Context.get_error_depth">
+<code class="descname">get_error_depth</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#X509_Store_Context.get_error_depth"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.X509_Store_Context.get_error_depth" title="Permalink to this definition">¶</a></dt>
+<dd><p>Get error depth.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.X509.X509_Store_Context.m2_x509_store_ctx_free">
+<code class="descname">m2_x509_store_ctx_free</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.X509.X509_Store_Context.m2_x509_store_ctx_free" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.X509.load_cert">
+<code class="descclassname">M2Crypto.X509.</code><code class="descname">load_cert</code><span class="sig-paren">(</span><em>file</em>, <em>format=1</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#load_cert"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.load_cert" title="Permalink to this definition">¶</a></dt>
+<dd><p>Load certificate from file.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>file</strong> – Name of file containing certificate in either DER or
+PEM format.</li>
+<li><strong>format</strong> – Describes the format of the file to be loaded,
+either PEM or DER.</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">M2Crypto.X509.X509 object.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.X509.load_cert_bio">
+<code class="descclassname">M2Crypto.X509.</code><code class="descname">load_cert_bio</code><span class="sig-paren">(</span><em>bio</em>, <em>format=1</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#load_cert_bio"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.load_cert_bio" title="Permalink to this definition">¶</a></dt>
+<dd><p>Load certificate from a bio.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>bio</strong> – BIO pointing at a certificate in either DER or PEM format.</li>
+<li><strong>format</strong> – Describes the format of the cert to be loaded,
+either PEM or DER (via constants FORMAT_PEM
+and FORMAT_FORMAT_DER)</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">M2Crypto.X509.X509 object.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.X509.load_cert_der_string">
+<code class="descclassname">M2Crypto.X509.</code><code class="descname">load_cert_der_string</code><span class="sig-paren">(</span><em>string</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#load_cert_der_string"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.load_cert_der_string" title="Permalink to this definition">¶</a></dt>
+<dd><p>Load certificate from a string.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>string</strong> – String containing a certificate in DER format.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">M2Crypto.X509.X509 object.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.X509.load_cert_string">
+<code class="descclassname">M2Crypto.X509.</code><code class="descname">load_cert_string</code><span class="sig-paren">(</span><em>string</em>, <em>format=1</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#load_cert_string"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.load_cert_string" title="Permalink to this definition">¶</a></dt>
+<dd><p>Load certificate from a string.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>string</strong> – String containing a certificate in either DER or PEM format.</li>
+<li><strong>format</strong> – Describes the format of the cert to be loaded,
+either PEM or DER (via constants FORMAT_PEM
+and FORMAT_FORMAT_DER)</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">M2Crypto.X509.X509 object.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.X509.load_crl">
+<code class="descclassname">M2Crypto.X509.</code><code class="descname">load_crl</code><span class="sig-paren">(</span><em>file</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#load_crl"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.load_crl" title="Permalink to this definition">¶</a></dt>
+<dd><p>Load CRL from file.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>file</strong> – Name of file containing CRL in PEM format.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">M2Crypto.X509.CRL object.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.X509.load_request">
+<code class="descclassname">M2Crypto.X509.</code><code class="descname">load_request</code><span class="sig-paren">(</span><em>file</em>, <em>format=1</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#load_request"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.load_request" title="Permalink to this definition">¶</a></dt>
+<dd><p>Load certificate request from file.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>file</strong> – Name of file containing certificate request in
+either PEM or DER format.</li>
+<li><strong>format</strong> – Describes the format of the file to be loaded,
+either PEM or DER. (using constants FORMAT_PEM
+and FORMAT_DER)</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">Request object.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.X509.load_request_bio">
+<code class="descclassname">M2Crypto.X509.</code><code class="descname">load_request_bio</code><span class="sig-paren">(</span><em>bio</em>, <em>format=1</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#load_request_bio"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.load_request_bio" title="Permalink to this definition">¶</a></dt>
+<dd><p>Load certificate request from a bio.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>bio</strong> – BIO pointing at a certificate request in
+either DER or PEM format.</li>
+<li><strong>format</strong> – Describes the format of the request to be loaded,
+either PEM or DER. (using constants FORMAT_PEM
+and FORMAT_DER)</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">M2Crypto.X509.Request object.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.X509.load_request_der_string">
+<code class="descclassname">M2Crypto.X509.</code><code class="descname">load_request_der_string</code><span class="sig-paren">(</span><em>string</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#load_request_der_string"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.load_request_der_string" title="Permalink to this definition">¶</a></dt>
+<dd><p>Load certificate request from a string.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>string</strong> – String containing a certificate request in DER format.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">M2Crypto.X509.Request object.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.X509.load_request_string">
+<code class="descclassname">M2Crypto.X509.</code><code class="descname">load_request_string</code><span class="sig-paren">(</span><em>string</em>, <em>format=1</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#load_request_string"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.load_request_string" title="Permalink to this definition">¶</a></dt>
+<dd><p>Load certificate request from a string.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>string</strong> – String containing a certificate request in
+either DER or PEM format.</li>
+<li><strong>format</strong> – Describes the format of the request to be loaded,
+either PEM or DER. (using constants FORMAT_PEM
+and FORMAT_DER)</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">M2Crypto.X509.Request object.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.X509.new_extension">
+<code class="descclassname">M2Crypto.X509.</code><code class="descname">new_extension</code><span class="sig-paren">(</span><em>name</em>, <em>value</em>, <em>critical=0</em>, <em>_pyfree=1</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#new_extension"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.new_extension" title="Permalink to this definition">¶</a></dt>
+<dd><p>Create new X509_Extension instance.</p>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.X509.new_stack_from_der">
+<code class="descclassname">M2Crypto.X509.</code><code class="descname">new_stack_from_der</code><span class="sig-paren">(</span><em>der_string</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#new_stack_from_der"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.new_stack_from_der" title="Permalink to this definition">¶</a></dt>
+<dd><p>Create a new X509_Stack from DER string.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">X509_Stack</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.X509.x509_store_default_cb">
+<code class="descclassname">M2Crypto.X509.</code><code class="descname">x509_store_default_cb</code><span class="sig-paren">(</span><em>ok</em>, <em>ctx</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/X509.html#x509_store_default_cb"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.X509.x509_store_default_cb" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+</div>
+<div class="section" id="module-M2Crypto.callback">
+<span id="callback-module"></span><h2><code class="xref py py-mod docutils literal notranslate"><span class="pre">callback</span></code> Module<a class="headerlink" href="#module-M2Crypto.callback" title="Permalink to this headline">¶</a></h2>
+</div>
+<div class="section" id="module-M2Crypto.ftpslib">
+<span id="ftpslib-module"></span><h2><code class="xref py py-mod docutils literal notranslate"><span class="pre">ftpslib</span></code> Module<a class="headerlink" href="#module-M2Crypto.ftpslib" title="Permalink to this headline">¶</a></h2>
+<dl class="class">
+<dt id="M2Crypto.ftpslib.FTP_TLS">
+<em class="property">class </em><code class="descclassname">M2Crypto.ftpslib.</code><code class="descname">FTP_TLS</code><span class="sig-paren">(</span><em>host=None</em>, <em>ssl_ctx=None</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/ftpslib.html#FTP_TLS"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.ftpslib.FTP_TLS" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">ftplib.FTP</span></code></p>
+<p>Python OO interface to client-side FTP/TLS.</p>
+<dl class="method">
+<dt id="M2Crypto.ftpslib.FTP_TLS.auth_ssl">
+<code class="descname">auth_ssl</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/ftpslib.html#FTP_TLS.auth_ssl"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.ftpslib.FTP_TLS.auth_ssl" title="Permalink to this definition">¶</a></dt>
+<dd><p>Secure the control connection per AUTH SSL, aka AUTH TLS-P.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.ftpslib.FTP_TLS.auth_tls">
+<code class="descname">auth_tls</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/ftpslib.html#FTP_TLS.auth_tls"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.ftpslib.FTP_TLS.auth_tls" title="Permalink to this definition">¶</a></dt>
+<dd><p>Secure the control connection per AUTH TLS, aka AUTH TLS-C.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.ftpslib.FTP_TLS.ntransfercmd">
+<code class="descname">ntransfercmd</code><span class="sig-paren">(</span><em>cmd</em>, <em>rest=None</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/ftpslib.html#FTP_TLS.ntransfercmd"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.ftpslib.FTP_TLS.ntransfercmd" title="Permalink to this definition">¶</a></dt>
+<dd><p>Initiate a data transfer.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.ftpslib.FTP_TLS.prot_c">
+<code class="descname">prot_c</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/ftpslib.html#FTP_TLS.prot_c"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.ftpslib.FTP_TLS.prot_c" title="Permalink to this definition">¶</a></dt>
+<dd><p>Set up data connection in the clear.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.ftpslib.FTP_TLS.prot_p">
+<code class="descname">prot_p</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/ftpslib.html#FTP_TLS.prot_p"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.ftpslib.FTP_TLS.prot_p" title="Permalink to this definition">¶</a></dt>
+<dd><p>Set up secure data connection.</p>
+</dd></dl>
+
+</dd></dl>
+
+</div>
+<div class="section" id="module-M2Crypto.httpslib">
+<span id="httpslib-module"></span><h2><code class="xref py py-mod docutils literal notranslate"><span class="pre">httpslib</span></code> Module<a class="headerlink" href="#module-M2Crypto.httpslib" title="Permalink to this headline">¶</a></h2>
+<dl class="class">
+<dt id="M2Crypto.httpslib.HTTPSConnection">
+<em class="property">class </em><code class="descclassname">M2Crypto.httpslib.</code><code class="descname">HTTPSConnection</code><span class="sig-paren">(</span><em>host</em>, <em>port=None</em>, <em>strict=None</em>, <em>**ssl</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/httpslib.html#HTTPSConnection"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.httpslib.HTTPSConnection" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">http.client.HTTPConnection</span></code></p>
+<p>This class allows communication via SSL using M2Crypto.</p>
+<dl class="method">
+<dt id="M2Crypto.httpslib.HTTPSConnection.close">
+<code class="descname">close</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/httpslib.html#HTTPSConnection.close"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.httpslib.HTTPSConnection.close" title="Permalink to this definition">¶</a></dt>
+<dd><p>Close the connection to the HTTP server.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.httpslib.HTTPSConnection.connect">
+<code class="descname">connect</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/httpslib.html#HTTPSConnection.connect"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.httpslib.HTTPSConnection.connect" title="Permalink to this definition">¶</a></dt>
+<dd><p>Connect to the host and port specified in __init__.</p>
+</dd></dl>
+
+<dl class="attribute">
+<dt id="M2Crypto.httpslib.HTTPSConnection.default_port">
+<code class="descname">default_port</code><em class="property"> = 443</em><a class="headerlink" href="#M2Crypto.httpslib.HTTPSConnection.default_port" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.httpslib.HTTPSConnection.get_session">
+<code class="descname">get_session</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/httpslib.html#HTTPSConnection.get_session"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.httpslib.HTTPSConnection.get_session" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.httpslib.HTTPSConnection.set_session">
+<code class="descname">set_session</code><span class="sig-paren">(</span><em>session</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/httpslib.html#HTTPSConnection.set_session"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.httpslib.HTTPSConnection.set_session" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="M2Crypto.httpslib.ProxyHTTPSConnection">
+<em class="property">class </em><code class="descclassname">M2Crypto.httpslib.</code><code class="descname">ProxyHTTPSConnection</code><span class="sig-paren">(</span><em>host</em>, <em>port=None</em>, <em>strict=None</em>, <em>username=None</em>, <em>password=None</em>, <em>**ssl</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/httpslib.html#ProxyHTTPSConnection"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.httpslib.ProxyHTTPSConnection" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <a class="reference internal" href="#M2Crypto.httpslib.HTTPSConnection" title="M2Crypto.httpslib.HTTPSConnection"><code class="xref py py-class docutils literal notranslate"><span class="pre">M2Crypto.httpslib.HTTPSConnection</span></code></a></p>
+<p>An HTTPS Connection that uses a proxy and the CONNECT request.</p>
+<p>When the connection is initiated, CONNECT is first sent to the proxy (along
+with authorization headers, if supplied). If successful, an SSL connection
+will be established over the socket through the proxy and to the target
+host.</p>
+<p>Finally, the actual request is sent over the SSL connection tunneling
+through the proxy.</p>
+<dl class="method">
+<dt id="M2Crypto.httpslib.ProxyHTTPSConnection.connect">
+<code class="descname">connect</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/httpslib.html#ProxyHTTPSConnection.connect"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.httpslib.ProxyHTTPSConnection.connect" title="Permalink to this definition">¶</a></dt>
+<dd><p>Connect to the host and port specified in __init__.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.httpslib.ProxyHTTPSConnection.endheaders">
+<code class="descname">endheaders</code><span class="sig-paren">(</span><em>*args</em>, <em>**kwargs</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/httpslib.html#ProxyHTTPSConnection.endheaders"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.httpslib.ProxyHTTPSConnection.endheaders" title="Permalink to this definition">¶</a></dt>
+<dd><p>Indicate that the last header line has been sent to the server.</p>
+<p>This method sends the request to the server. The optional message_body
+argument can be used to pass a message body associated with the
+request.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.httpslib.ProxyHTTPSConnection.putheader">
+<code class="descname">putheader</code><span class="sig-paren">(</span><em>header</em>, <em>value</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/httpslib.html#ProxyHTTPSConnection.putheader"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.httpslib.ProxyHTTPSConnection.putheader" title="Permalink to this definition">¶</a></dt>
+<dd><p>Send a request header line to the server.</p>
+<p>For example: h.putheader(‘Accept’, ‘text/html’)</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.httpslib.ProxyHTTPSConnection.putrequest">
+<code class="descname">putrequest</code><span class="sig-paren">(</span><em>method</em>, <em>url</em>, <em>skip_host=0</em>, <em>skip_accept_encoding=0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/httpslib.html#ProxyHTTPSConnection.putrequest"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.httpslib.ProxyHTTPSConnection.putrequest" title="Permalink to this definition">¶</a></dt>
+<dd><p>putrequest is called before connect, so can interpret url and get
+real host/port to be used to make CONNECT request to proxy</p>
+</dd></dl>
+
+</dd></dl>
+
+</div>
+<div class="section" id="module-M2Crypto.m2">
+<span id="m2-module"></span><h2><code class="xref py py-mod docutils literal notranslate"><span class="pre">m2</span></code> Module<a class="headerlink" href="#module-M2Crypto.m2" title="Permalink to this headline">¶</a></h2>
+</div>
+<div class="section" id="module-M2Crypto.m2crypto">
+<span id="m2crypto-module"></span><h2><code class="xref py py-mod docutils literal notranslate"><span class="pre">m2crypto</span></code> Module<a class="headerlink" href="#module-M2Crypto.m2crypto" title="Permalink to this headline">¶</a></h2>
+</div>
+<div class="section" id="module-M2Crypto.m2urllib">
+<span id="m2urllib-module"></span><h2><code class="xref py py-mod docutils literal notranslate"><span class="pre">m2urllib</span></code> Module<a class="headerlink" href="#module-M2Crypto.m2urllib" title="Permalink to this headline">¶</a></h2>
+<dl class="function">
+<dt id="M2Crypto.m2urllib.open_https">
+<code class="descclassname">M2Crypto.m2urllib.</code><code class="descname">open_https</code><span class="sig-paren">(</span><em>self</em>, <em>url</em>, <em>data=None</em>, <em>ssl_context=None</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/m2urllib.html#open_https"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.m2urllib.open_https" title="Permalink to this definition">¶</a></dt>
+<dd><p>Open URL over the SSL connection.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>url</strong> – URL to be opened</li>
+<li><strong>data</strong> – data for the POST request</li>
+<li><strong>ssl_context</strong> – SSL.Context to be used</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last"></p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+</div>
+<div class="section" id="module-M2Crypto.m2urllib2">
+<span id="m2urllib2-module"></span><h2><code class="xref py py-mod docutils literal notranslate"><span class="pre">m2urllib2</span></code> Module<a class="headerlink" href="#module-M2Crypto.m2urllib2" title="Permalink to this headline">¶</a></h2>
+<dl class="class">
+<dt id="M2Crypto.m2urllib2.HTTPSHandler">
+<em class="property">class </em><code class="descclassname">M2Crypto.m2urllib2.</code><code class="descname">HTTPSHandler</code><span class="sig-paren">(</span><em>ssl_context=None</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/m2urllib2.html#HTTPSHandler"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.m2urllib2.HTTPSHandler" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">urllib.request.AbstractHTTPHandler</span></code></p>
+<dl class="method">
+<dt id="M2Crypto.m2urllib2.HTTPSHandler.https_open">
+<code class="descname">https_open</code><span class="sig-paren">(</span><em>req</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/m2urllib2.html#HTTPSHandler.https_open"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.m2urllib2.HTTPSHandler.https_open" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return an addinfourl object for the request, using http_class.</p>
+<p>http_class must implement the HTTPConnection API from httplib.
+The addinfourl return value is a file-like object. It also
+has methods and attributes including:</p>
+<blockquote>
+<div><ul class="simple">
+<li>info(): return a mimetools.Message object for the headers</li>
+<li>geturl(): return the original request URL</li>
+<li>code: HTTP status code</li>
+</ul>
+</div></blockquote>
+</dd></dl>
+
+<dl class="method">
+<dt id="M2Crypto.m2urllib2.HTTPSHandler.https_request">
+<code class="descname">https_request</code><span class="sig-paren">(</span><em>request</em><span class="sig-paren">)</span><a class="headerlink" href="#M2Crypto.m2urllib2.HTTPSHandler.https_request" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.m2urllib2.build_opener">
+<code class="descclassname">M2Crypto.m2urllib2.</code><code class="descname">build_opener</code><span class="sig-paren">(</span><em>ssl_context=None</em>, <em>*handlers</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/m2urllib2.html#build_opener"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.m2urllib2.build_opener" title="Permalink to this definition">¶</a></dt>
+<dd><p>Create an opener object from a list of handlers.</p>
+<p>The opener will use several default handlers, including support
+for HTTP and FTP.</p>
+<p>If any of the handlers passed as arguments are subclasses of the
+default handlers, the default handlers will not be used.</p>
+</dd></dl>
+
+</div>
+<div class="section" id="module-M2Crypto.m2xmlrpclib">
+<span id="m2xmlrpclib-module"></span><h2><code class="xref py py-mod docutils literal notranslate"><span class="pre">m2xmlrpclib</span></code> Module<a class="headerlink" href="#module-M2Crypto.m2xmlrpclib" title="Permalink to this headline">¶</a></h2>
+<dl class="class">
+<dt id="M2Crypto.m2xmlrpclib.SSL_Transport">
+<em class="property">class </em><code class="descclassname">M2Crypto.m2xmlrpclib.</code><code class="descname">SSL_Transport</code><span class="sig-paren">(</span><em>ssl_context=None</em>, <em>*args</em>, <em>**kw</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/m2xmlrpclib.html#SSL_Transport"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.m2xmlrpclib.SSL_Transport" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">xmlrpc.client.Transport</span></code></p>
+<dl class="method">
+<dt id="M2Crypto.m2xmlrpclib.SSL_Transport.request">
+<code class="descname">request</code><span class="sig-paren">(</span><em>host</em>, <em>handler</em>, <em>request_body</em>, <em>verbose=0</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/m2xmlrpclib.html#SSL_Transport.request"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.m2xmlrpclib.SSL_Transport.request" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="attribute">
+<dt id="M2Crypto.m2xmlrpclib.SSL_Transport.user_agent">
+<code class="descname">user_agent</code><em class="property"> = 'M2Crypto_XMLRPC/0.33.0 - Python-xmlrpc/3.7'</em><a class="headerlink" href="#M2Crypto.m2xmlrpclib.SSL_Transport.user_agent" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+</dd></dl>
+
+</div>
+<div class="section" id="module-M2Crypto.threading">
+<span id="threading-module"></span><h2><code class="xref py py-mod docutils literal notranslate"><span class="pre">threading</span></code> Module<a class="headerlink" href="#module-M2Crypto.threading" title="Permalink to this headline">¶</a></h2>
+<dl class="function">
+<dt id="M2Crypto.threading.cleanup">
+<code class="descclassname">M2Crypto.threading.</code><code class="descname">cleanup</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/threading.html#cleanup"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.threading.cleanup" title="Permalink to this definition">¶</a></dt>
+<dd><p>End and cleanup threading support.</p>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.threading.init">
+<code class="descclassname">M2Crypto.threading.</code><code class="descname">init</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/threading.html#init"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.threading.init" title="Permalink to this definition">¶</a></dt>
+<dd><p>Initialize threading support.</p>
+</dd></dl>
+
+</div>
+<div class="section" id="module-M2Crypto.util">
+<span id="util-module"></span><h2><code class="xref py py-mod docutils literal notranslate"><span class="pre">util</span></code> Module<a class="headerlink" href="#module-M2Crypto.util" title="Permalink to this headline">¶</a></h2>
+<dl class="exception">
+<dt id="M2Crypto.util.UtilError">
+<em class="property">exception </em><code class="descclassname">M2Crypto.util.</code><code class="descname">UtilError</code><a class="reference internal" href="_modules/M2Crypto/util.html#UtilError"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.util.UtilError" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">Exception</span></code></p>
+</dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.util.bin_to_hex">
+<code class="descclassname">M2Crypto.util.</code><code class="descname">bin_to_hex</code><span class="sig-paren">(</span><em>b</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/util.html#bin_to_hex"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.util.bin_to_hex" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.util.genparam_callback">
+<code class="descclassname">M2Crypto.util.</code><code class="descname">genparam_callback</code><span class="sig-paren">(</span><em>p</em>, <em>n</em>, <em>out=&lt;_io.TextIOWrapper name='&lt;stdout&gt;' mode='w' encoding='UTF-8'&gt;</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/util.html#genparam_callback"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.util.genparam_callback" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.util.no_passphrase_callback">
+<code class="descclassname">M2Crypto.util.</code><code class="descname">no_passphrase_callback</code><span class="sig-paren">(</span><em>*args</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/util.html#no_passphrase_callback"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.util.no_passphrase_callback" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.util.octx_to_num">
+<code class="descclassname">M2Crypto.util.</code><code class="descname">octx_to_num</code><span class="sig-paren">(</span><em>x</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/util.html#octx_to_num"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.util.octx_to_num" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.util.passphrase_callback">
+<code class="descclassname">M2Crypto.util.</code><code class="descname">passphrase_callback</code><span class="sig-paren">(</span><em>v</em>, <em>prompt1='Enter passphrase:'</em>, <em>prompt2='Verify passphrase:'</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/util.html#passphrase_callback"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.util.passphrase_callback" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.util.pkcs5_pad">
+<code class="descclassname">M2Crypto.util.</code><code class="descname">pkcs5_pad</code><span class="sig-paren">(</span><em>data</em>, <em>blklen=8</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/util.html#pkcs5_pad"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.util.pkcs5_pad" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.util.pkcs7_pad">
+<code class="descclassname">M2Crypto.util.</code><code class="descname">pkcs7_pad</code><span class="sig-paren">(</span><em>data</em>, <em>blklen</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/util.html#pkcs7_pad"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.util.pkcs7_pad" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="function">
+<dt id="M2Crypto.util.quiet_genparam_callback">
+<code class="descclassname">M2Crypto.util.</code><code class="descname">quiet_genparam_callback</code><span class="sig-paren">(</span><em>p</em>, <em>n</em>, <em>out</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/M2Crypto/util.html#quiet_genparam_callback"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#M2Crypto.util.quiet_genparam_callback" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+</div>
+<div class="section" id="subpackages">
+<h2>Subpackages<a class="headerlink" href="#subpackages" title="Permalink to this headline">¶</a></h2>
+<div class="toctree-wrapper compound">
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="M2Crypto.SSL.html">SSL Package</a><ul>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.SSL.html#id1"><code class="docutils literal notranslate"><span class="pre">SSL</span></code> Package</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.SSL.html#module-M2Crypto.SSL.Checker"><code class="docutils literal notranslate"><span class="pre">Checker</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.SSL.html#module-M2Crypto.SSL.Cipher"><code class="docutils literal notranslate"><span class="pre">Cipher</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.SSL.html#module-M2Crypto.SSL.Connection"><code class="docutils literal notranslate"><span class="pre">Connection</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.SSL.html#module-M2Crypto.SSL.Context"><code class="docutils literal notranslate"><span class="pre">Context</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.SSL.html#module-M2Crypto.SSL.SSLServer"><code class="docutils literal notranslate"><span class="pre">SSLServer</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.SSL.html#module-M2Crypto.SSL.Session"><code class="docutils literal notranslate"><span class="pre">Session</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.SSL.html#module-M2Crypto.SSL.TwistedProtocolWrapper"><code class="docutils literal notranslate"><span class="pre">TwistedProtocolWrapper</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.SSL.html#module-M2Crypto.SSL.cb"><code class="docutils literal notranslate"><span class="pre">cb</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.SSL.html#module-M2Crypto.SSL.ssl_dispatcher"><code class="docutils literal notranslate"><span class="pre">ssl_dispatcher</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.SSL.html#module-M2Crypto.SSL.timeout"><code class="docutils literal notranslate"><span class="pre">timeout</span></code> Module</a></li>
+</ul>
+</li>
+</ul>
+</div>
+</div>
+</div>
+
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="index.html">M2Crypto</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul class="current">
+<li class="toctree-l1 current"><a class="current reference internal" href="#">M2Crypto Package</a><ul>
+<li class="toctree-l2"><a class="reference internal" href="#id1"><code class="docutils literal notranslate"><span class="pre">M2Crypto</span></code> Package</a></li>
+<li class="toctree-l2"><a class="reference internal" href="#module-M2Crypto.ASN1"><code class="docutils literal notranslate"><span class="pre">ASN1</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="#module-M2Crypto.AuthCookie"><code class="docutils literal notranslate"><span class="pre">AuthCookie</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="#module-M2Crypto.BIO"><code class="docutils literal notranslate"><span class="pre">BIO</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="#module-M2Crypto.BN"><code class="docutils literal notranslate"><span class="pre">BN</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="#module-M2Crypto.DH"><code class="docutils literal notranslate"><span class="pre">DH</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="#module-M2Crypto.DSA"><code class="docutils literal notranslate"><span class="pre">DSA</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="#module-M2Crypto.EC"><code class="docutils literal notranslate"><span class="pre">EC</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="#module-M2Crypto.EVP"><code class="docutils literal notranslate"><span class="pre">EVP</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="#module-M2Crypto.Engine"><code class="docutils literal notranslate"><span class="pre">Engine</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="#module-M2Crypto.Err"><code class="docutils literal notranslate"><span class="pre">Err</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="#module-M2Crypto.RC4"><code class="docutils literal notranslate"><span class="pre">RC4</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="#module-M2Crypto.RSA"><code class="docutils literal notranslate"><span class="pre">RSA</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="#module-M2Crypto.Rand"><code class="docutils literal notranslate"><span class="pre">Rand</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="#module-M2Crypto.SMIME"><code class="docutils literal notranslate"><span class="pre">SMIME</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="#module-M2Crypto.X509"><code class="docutils literal notranslate"><span class="pre">X509</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="#module-M2Crypto.callback"><code class="docutils literal notranslate"><span class="pre">callback</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="#module-M2Crypto.ftpslib"><code class="docutils literal notranslate"><span class="pre">ftpslib</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="#module-M2Crypto.httpslib"><code class="docutils literal notranslate"><span class="pre">httpslib</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="#module-M2Crypto.m2"><code class="docutils literal notranslate"><span class="pre">m2</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="#module-M2Crypto.m2crypto"><code class="docutils literal notranslate"><span class="pre">m2crypto</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="#module-M2Crypto.m2urllib"><code class="docutils literal notranslate"><span class="pre">m2urllib</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="#module-M2Crypto.m2urllib2"><code class="docutils literal notranslate"><span class="pre">m2urllib2</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="#module-M2Crypto.m2xmlrpclib"><code class="docutils literal notranslate"><span class="pre">m2xmlrpclib</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="#module-M2Crypto.threading"><code class="docutils literal notranslate"><span class="pre">threading</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="#module-M2Crypto.util"><code class="docutils literal notranslate"><span class="pre">util</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="#subpackages">Subpackages</a><ul>
+<li class="toctree-l3"><a class="reference internal" href="M2Crypto.SSL.html">SSL Package</a></li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="index.html">Documentation overview</a><ul>
+ <li>Previous: <a href="index.html" title="previous chapter">Welcome to M2Crypto’s documentation!</a></li>
+ <li>Next: <a href="M2Crypto.SSL.html" title="next chapter">SSL Package</a></li>
+ </ul></li>
+</ul>
+</div>
+<div id="searchbox" style="display: none" role="search">
+ <h3>Quick search</h3>
+ <div class="searchformwrapper">
+ <form class="search" action="search.html" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ </div>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer">
+ &copy;2017, Matej Cepl <mcepl@cepl.eu>.
+
+ |
+ Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
+ &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
+
+ |
+ <a href="_sources/M2Crypto.rst.txt"
+ rel="nofollow">Page source</a>
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/ZServerSSL-HOWTO.html b/doc/html/ZServerSSL-HOWTO.html
new file mode 100644
index 0000000..67023d0
--- /dev/null
+++ b/doc/html/ZServerSSL-HOWTO.html
@@ -0,0 +1,355 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>1.   ZServerSSL-HOWTO &#8212; M2Crypto documentation</title>
+ <link rel="stylesheet" href="_static/alabaster.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <script type="text/javascript" src="_static/language_data.js"></script>
+ <link rel="index" title="Index" href="genindex.html" />
+ <link rel="search" title="Search" href="search.html" />
+
+ <link rel="stylesheet" href="_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+ <div class="section" id="zserverssl-howto">
+<span id="id1"></span><h1><a class="toc-backref" href="#id3">1.&nbsp;&nbsp;&nbsp;ZServerSSL-HOWTO</a><a class="headerlink" href="#zserverssl-howto" title="Permalink to this headline">¶</a></h1>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">author:</th><td class="field-body">Pheng Siong Ng &lt;<a class="reference external" href="mailto:ngps&#37;&#52;&#48;post1&#46;com">ngps<span>&#64;</span>post1<span>&#46;</span>com</a>&gt;</td>
+</tr>
+<tr class="field-even field"><th class="field-name">copyright:</th><td class="field-body">© 2000, 2001 by Ng Pheng Siong.</td>
+</tr>
+<tr class="field-odd field"><th class="field-name">date:</th><td class="field-body">2003-06-22</td>
+</tr>
+</tbody>
+</table>
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="auto-toc simple">
+<li><a class="reference internal" href="#zserverssl-howto" id="id3">1.&nbsp;&nbsp;&nbsp;ZServerSSL-HOWTO</a><ul class="auto-toc">
+<li><a class="reference internal" href="#introduction" id="id4">1.1.&nbsp;&nbsp;&nbsp;Introduction</a></li>
+<li><a class="reference internal" href="#preparation" id="id5">1.2.&nbsp;&nbsp;&nbsp;Preparation</a></li>
+<li><a class="reference internal" href="#installation" id="id6">1.3.&nbsp;&nbsp;&nbsp;Installation</a></li>
+<li><a class="reference internal" href="#testing" id="id7">1.4.&nbsp;&nbsp;&nbsp;Testing</a></li>
+<li><a class="reference internal" href="#https" id="id8">1.5.&nbsp;&nbsp;&nbsp;HTTPS</a></li>
+<li><a class="reference internal" href="#webdav-over-https" id="id9">1.6.&nbsp;&nbsp;&nbsp;WebDAV-over-HTTPS</a></li>
+<li><a class="reference internal" href="#webdav-source-over-https" id="id10">1.7.&nbsp;&nbsp;&nbsp;WebDAV-Source-over-HTTPS</a></li>
+<li><a class="reference internal" href="#python-with-m2crypto" id="id11">1.8.&nbsp;&nbsp;&nbsp;Python with M2Crypto</a></li>
+<li><a class="reference internal" href="#id2" id="id12">1.9.&nbsp;&nbsp;&nbsp;HTTPS</a></li>
+<li><a class="reference internal" href="#xmlrpc-over-https" id="id13">1.10.&nbsp;&nbsp;&nbsp;XMLRPC-over-HTTPS</a></li>
+<li><a class="reference internal" href="#conclusion" id="id14">1.11.&nbsp;&nbsp;&nbsp;Conclusion</a></li>
+</ul>
+</li>
+</ul>
+</div>
+<div class="section" id="introduction">
+<h2><a class="toc-backref" href="#id4">1.1.&nbsp;&nbsp;&nbsp;Introduction</a><a class="headerlink" href="#introduction" title="Permalink to this headline">¶</a></h2>
+<p>ZServerSSL adds to Zope’s ZServer the following:</p>
+<ul class="simple">
+<li>HTTPS server</li>
+<li>WebDAV-source-over-HTTPS server</li>
+</ul>
+<p>With the HTTPS server, ZServerSSL also provides WebDAV-over-HTTPS and
+XMLRPC-over-HTTPS access to Zope.</p>
+<p>These instructions apply to both Un*x and Windows installations of Zope
+2.6.1. To avoid cluttering the presentation, Windows pathnames are shown
+in Un*x fashion.</p>
+</div>
+<div class="section" id="preparation">
+<h2><a class="toc-backref" href="#id5">1.2.&nbsp;&nbsp;&nbsp;Preparation</a><a class="headerlink" href="#preparation" title="Permalink to this headline">¶</a></h2>
+<ol class="arabic simple">
+<li>Download M2Crypto 0.11, contained in the file <code class="docutils literal notranslate"><span class="pre">m2crypto-0.11.zip</span></code>.</li>
+<li>Unpack <code class="docutils literal notranslate"><span class="pre">m2crypto-0.11.zip</span></code>. This will create a directory
+<code class="docutils literal notranslate"><span class="pre">m2crypto-0.11</span></code>. Henceforth, we refer to this directory as <code class="docutils literal notranslate"><span class="pre">$M2</span></code>.</li>
+<li>Install M2Crypto per the instructions in <code class="docutils literal notranslate"><span class="pre">$M2/INSTALL</span></code>.</li>
+</ol>
+<p>The ZServerSSL distribution is in <code class="docutils literal notranslate"><span class="pre">$M2/demo/Zope</span></code>. We shall refer to
+this directory as <code class="docutils literal notranslate"><span class="pre">$ZSSL</span></code>.</p>
+</div>
+<div class="section" id="installation">
+<h2><a class="toc-backref" href="#id6">1.3.&nbsp;&nbsp;&nbsp;Installation</a><a class="headerlink" href="#installation" title="Permalink to this headline">¶</a></h2>
+<p>Below, we refer to your Zope top-level directory as <code class="docutils literal notranslate"><span class="pre">$ZOPE</span></code>.</p>
+<ol class="arabic">
+<li><p class="first">Copy <code class="docutils literal notranslate"><span class="pre">$ZSSL/z2s.py</span></code> into <code class="docutils literal notranslate"><span class="pre">$ZOPE</span></code>.</p>
+</li>
+<li><p class="first">Depending on your operating system, modify <code class="docutils literal notranslate"><span class="pre">$ZOPE/start</span></code> or
+<code class="docutils literal notranslate"><span class="pre">$ZOPE/start.bat</span></code> to invoke <code class="docutils literal notranslate"><span class="pre">$ZOPE/z2s.py</span></code>, instead of
+<code class="docutils literal notranslate"><span class="pre">$ZOPE/z2.py</span></code>. The files <code class="docutils literal notranslate"><span class="pre">$ZSSL/starts</span></code> and <code class="docutils literal notranslate"><span class="pre">$ZSSL/starts.bat</span></code>
+serve as examples.</p>
+</li>
+<li><p class="first">Copy <code class="docutils literal notranslate"><span class="pre">$ZSSL/dh1024.pem</span></code> into <code class="docutils literal notranslate"><span class="pre">$ZOPE</span></code>. This file contains
+Diffie-Hellman parameters for use by the SSL protocol.</p>
+</li>
+<li><p class="first">Copy <code class="docutils literal notranslate"><span class="pre">$ZSSL/randpool.dat</span></code> into <code class="docutils literal notranslate"><span class="pre">$ZOPE</span></code>. This file contains seed
+material for the OpenSSL PRNG. Alternatively, create
+<code class="docutils literal notranslate"><span class="pre">$ZOPE/randpool.dat</span></code> thusly:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ dd if=/dev/urandom of=randpool.dat bs=1024 count=1
+</pre></div>
+</div>
+</li>
+<li><p class="first">Copy <code class="docutils literal notranslate"><span class="pre">$ZSSL/ca.pem</span></code> to <code class="docutils literal notranslate"><span class="pre">$ZOPE</span></code>. This file contains an
+example Certification Authority (CA) certificate. For
+information on operating your own CA, see <a class="reference internal" href="howto.ca.html#howto-ca"><span class="std std-ref">HOWTO: Creating your own CA with OpenSSL</span></a> or
+one of numerous similar documents available on the web.</p>
+</li>
+<li><p class="first">Copy <code class="docutils literal notranslate"><span class="pre">$ZSSL/server.pem</span></code> to <code class="docutils literal notranslate"><span class="pre">$ZOPE</span></code>. This file contains an RSA key
+pair and its X.509v3 certificate issued by the above CA. You may also
+create your own key/certificate bundle.</p>
+</li>
+<li><p class="first">Copy <code class="docutils literal notranslate"><span class="pre">$ZSSL/ZServer/HTTPS_Server.py</span></code> to <code class="docutils literal notranslate"><span class="pre">$ZOPE/ZServer</span></code>.</p>
+</li>
+<li><p class="first">Copy <code class="docutils literal notranslate"><span class="pre">$ZSSL/ZServer/__init__.py</span></code> to <code class="docutils literal notranslate"><span class="pre">$ZOPE/ZServer</span></code>. This
+overwrites the existing <code class="docutils literal notranslate"><span class="pre">$ZOPE/ZServer/__init__.py</span></code>. Alternatively,
+apply the following patch to <code class="docutils literal notranslate"><span class="pre">$ZOPE/ZServer/__init__.py</span></code>:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">---</span> <span class="fm">__init__</span><span class="o">.</span><span class="n">py</span><span class="o">.</span><span class="n">org</span> <span class="n">Sat</span> <span class="n">Jun</span> <span class="mi">21</span> <span class="mi">23</span><span class="p">:</span><span class="mi">20</span><span class="p">:</span><span class="mi">41</span> <span class="mi">2003</span>
+<span class="o">+++</span> <span class="fm">__init__</span><span class="o">.</span><span class="n">py</span> <span class="n">Tue</span> <span class="n">Jan</span> <span class="mi">7</span> <span class="mi">23</span><span class="p">:</span><span class="mi">30</span><span class="p">:</span><span class="mi">53</span> <span class="mi">2003</span>
+<span class="o">@@</span> <span class="o">-</span><span class="mi">84</span><span class="p">,</span><span class="mi">6</span> <span class="o">+</span><span class="mi">84</span><span class="p">,</span><span class="mi">7</span> <span class="o">@@</span>
+ <span class="kn">import</span> <span class="nn">asyncore</span>
+ <span class="kn">from</span> <span class="nn">medusa</span> <span class="k">import</span> <span class="n">resolver</span><span class="p">,</span> <span class="n">logger</span>
+ <span class="kn">from</span> <span class="nn">HTTPServer</span> <span class="k">import</span> <span class="n">zhttp_server</span><span class="p">,</span> <span class="n">zhttp_handler</span>
+<span class="o">+</span><span class="kn">from</span> <span class="nn">HTTPS_Server</span> <span class="k">import</span> <span class="n">zhttps_server</span><span class="p">,</span> <span class="n">zhttps_handler</span>
+ <span class="kn">from</span> <span class="nn">PCGIServer</span> <span class="k">import</span> <span class="n">PCGIServer</span>
+ <span class="kn">from</span> <span class="nn">FCGIServer</span> <span class="k">import</span> <span class="n">FCGIServer</span>
+ <span class="kn">from</span> <span class="nn">FTPServer</span> <span class="k">import</span> <span class="n">FTPServer</span>
+</pre></div>
+</div>
+</li>
+<li><p class="first">Copy <code class="docutils literal notranslate"><span class="pre">$ZSSL/ZServer/medusa/https_server.py</span></code> to
+<code class="docutils literal notranslate"><span class="pre">$ZOPE/ZServer/medusa</span></code>.</p>
+</li>
+<li><p class="first">Stop Zope, if it is running.</p>
+</li>
+<li><p class="first">Start Zope with ZServerSSL thusly:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">./</span><span class="n">starts</span> <span class="o">-</span><span class="n">X</span> <span class="o">-</span><span class="n">f</span> <span class="mi">9021</span> <span class="o">-</span><span class="n">w</span> <span class="mi">9080</span> <span class="o">-</span><span class="n">W</span> <span class="mi">9081</span> <span class="o">-</span><span class="n">y</span> <span class="mi">9443</span> <span class="o">-</span><span class="n">Y</span> <span class="mi">9444</span>
+</pre></div>
+</div>
+<p>This starts the following:</p>
+<ul class="simple">
+<li>an FTP server on port 9021</li>
+<li>a HTTP server on port 9080</li>
+<li>a WebDAV-source server on port 9081</li>
+<li>a HTTPS server on port 9443</li>
+<li>a WebDAV-source-over-HTTPS server on port 9444</li>
+</ul>
+</li>
+</ol>
+</div>
+<div class="section" id="testing">
+<h2><a class="toc-backref" href="#id7">1.4.&nbsp;&nbsp;&nbsp;Testing</a><a class="headerlink" href="#testing" title="Permalink to this headline">¶</a></h2>
+<p>Below, we assume your Zope server is running on <code class="docutils literal notranslate"><span class="pre">localhost</span></code>.</p>
+</div>
+<div class="section" id="https">
+<h2><a class="toc-backref" href="#id8">1.5.&nbsp;&nbsp;&nbsp;HTTPS</a><a class="headerlink" href="#https" title="Permalink to this headline">¶</a></h2>
+<p>This testing is done with Mozilla 1.1 on FreeBSD.</p>
+<ol class="arabic simple">
+<li>With a browser, connect to <a class="reference external" href="https://localhost:9443/">https://localhost:9443/</a>. Browse around.
+Check out your browser’s HTTPS informational screens.</li>
+<li>Connect to <a class="reference external" href="https://localhost:9443/manage">https://localhost:9443/manage</a>. Verify that you can access
+Zope’s management functionality.</li>
+</ol>
+</div>
+<div class="section" id="webdav-over-https">
+<h2><a class="toc-backref" href="#id9">1.6.&nbsp;&nbsp;&nbsp;WebDAV-over-HTTPS</a><a class="headerlink" href="#webdav-over-https" title="Permalink to this headline">¶</a></h2>
+<p>This testing is done with Cadaver 0.21.0 on FreeBSD.:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ cadaver https://localhost:9443/
+WARNING: Untrusted server certificate presented:
+Issued to: M2Crypto, SG
+Issued by: M2Crypto, SG
+Do you wish to accept the certificate? (y/n) y
+dav:/&gt; ls
+Listing collection `/&#39;: succeeded.
+Coll: Channels 0 Jun 19 00:04
+Coll: Control_Panel 0 Jun 6 00:13
+Coll: Examples 0 Jun 6 00:12
+Coll: catalog 0 Jun 12 11:53
+Coll: ngps 0 Jun 16 15:34
+Coll: portal 0 Jun 21 15:21
+Coll: skunk 0 Jun 18 21:18
+Coll: temp_folder 0 Jun 22 17:57
+Coll: zope 0 Jun 20 15:27
+ acl_users 0 Dec 30 1998
+ browser_id_manager 0 Jun 6 00:12
+ default.css 3037 Jun 21 16:38
+ error_log 0 Jun 6 00:12
+ index_html 313 Jun 12 13:36
+ portal0 0 Jun 21 15:21
+ session_data_manager 0 Jun 6 00:12
+ standard_error_message 1365 Jan 21 2001
+ standard_html_footer 50 Jun 12 12:30
+ standard_html_header 80 Jan 21 2001
+ standard_template.pt 282 Jun 6 00:12
+ zsyncer 0 Jun 17 15:28
+dav:/&gt; quit
+Connection to `localhost&#39; closed.
+$
+</pre></div>
+</div>
+</div>
+<div class="section" id="webdav-source-over-https">
+<h2><a class="toc-backref" href="#id10">1.7.&nbsp;&nbsp;&nbsp;WebDAV-Source-over-HTTPS</a><a class="headerlink" href="#webdav-source-over-https" title="Permalink to this headline">¶</a></h2>
+<p>This testing is done with Mozilla 1.1 on FreeBSD.</p>
+<ol class="arabic simple">
+<li>Open the Mozilla Composer window.</li>
+<li>Click “Fileâ€, “Open Web Locationâ€. A dialog box appears.</li>
+<li>Enter <code class="docutils literal notranslate"><span class="pre">https://localhost:9444/index_html</span></code> for the URL.</li>
+<li>Select “Open in new Composer window.â€</li>
+<li>Click “Openâ€. A new Composer window will open with <code class="docutils literal notranslate"><span class="pre">index_html</span></code>
+loaded.</li>
+</ol>
+</div>
+<div class="section" id="python-with-m2crypto">
+<h2><a class="toc-backref" href="#id11">1.8.&nbsp;&nbsp;&nbsp;Python with M2Crypto</a><a class="headerlink" href="#python-with-m2crypto" title="Permalink to this headline">¶</a></h2>
+<p>This testing is done with M2Crypto 0.11 and Python 2.2.2 on FreeBSD.</p>
+</div>
+<div class="section" id="id2">
+<h2><a class="toc-backref" href="#id12">1.9.&nbsp;&nbsp;&nbsp;HTTPS</a><a class="headerlink" href="#id2" title="Permalink to this headline">¶</a></h2>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">M2Crypto</span> <span class="k">import</span> <span class="n">Rand</span><span class="p">,</span> <span class="n">SSL</span><span class="p">,</span> <span class="n">m2urllib</span>
+<span class="gp">&gt;&gt;&gt; </span><span class="n">url</span> <span class="o">=</span> <span class="n">m2urllib</span><span class="o">.</span><span class="n">FancyURLopener</span><span class="p">()</span>
+<span class="gp">&gt;&gt;&gt; </span><span class="n">url</span><span class="o">.</span><span class="n">addheader</span><span class="p">(</span><span class="s1">&#39;Connection&#39;</span><span class="p">,</span> <span class="s1">&#39;close&#39;</span><span class="p">)</span>
+<span class="gp">&gt;&gt;&gt; </span><span class="n">u</span> <span class="o">=</span> <span class="n">url</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="s1">&#39;https://127.0.0.1:9443/&#39;</span><span class="p">)</span>
+<span class="go">send: &#39;GET / HTTP/1.1\r\nHost: 127.0.0.1:9443\r\nAccept-Encoding: identity\r\nUser-agent: Python-urllib/1.15\r\nConnection: close\r\n\r\n&#39;</span>
+<span class="go">reply: &#39;HTTP/1.1 200 OK\r\n&#39;</span>
+<span class="go">header: Server: ZServerSSL/0.11</span>
+<span class="go">header: Date: Sun, 22 Jun 2003 13:42:34 GMT</span>
+<span class="go">header: Connection: close</span>
+<span class="go">header: Content-Type: text/html</span>
+<span class="go">header: Etag:</span>
+<span class="go">header: Content-Length: 535</span>
+<span class="gp">&gt;&gt;&gt; </span><span class="k">while</span> <span class="mi">1</span><span class="p">:</span>
+<span class="gp">... </span> <span class="n">data</span> <span class="o">=</span> <span class="n">u</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
+<span class="gp">... </span> <span class="k">if</span> <span class="ow">not</span> <span class="n">data</span><span class="p">:</span> <span class="k">break</span>
+<span class="gp">... </span> <span class="nb">print</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
+<span class="gp">...</span>
+</pre></div>
+</div>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">&lt;</span><span class="n">html</span><span class="o">&gt;&lt;</span><span class="n">head</span><span class="o">&gt;</span>
+<span class="o">&lt;</span><span class="n">base</span> <span class="n">href</span><span class="o">=</span><span class="s2">&quot;https://127.0.0.1:9443/&quot;</span> <span class="o">/&gt;</span>
+<span class="o">&lt;</span><span class="n">title</span><span class="o">&gt;</span><span class="n">Zope</span><span class="o">&lt;/</span><span class="n">title</span><span class="o">&gt;&lt;/</span><span class="n">head</span><span class="o">&gt;&lt;</span><span class="n">body</span> <span class="n">bgcolor</span><span class="o">=</span><span class="s2">&quot;#FFFFFF&quot;</span><span class="o">&gt;</span>
+
+<span class="o">&lt;</span><span class="n">h1</span><span class="o">&gt;</span><span class="n">NgPS</span> <span class="n">Desktop</span> <span class="n">Portal</span><span class="o">&lt;/</span><span class="n">h1</span><span class="o">&gt;</span>
+
+<span class="o">&amp;</span><span class="n">nbsp</span><span class="p">;</span><span class="o">&amp;</span><span class="n">nbsp</span><span class="p">;</span><span class="n">So</span> <span class="n">many</span> <span class="n">hacks</span><span class="o">.&lt;</span><span class="n">br</span><span class="o">&gt;</span>
+<span class="o">&amp;</span><span class="n">nbsp</span><span class="p">;</span><span class="o">&amp;</span><span class="n">nbsp</span><span class="p">;</span><span class="n">So</span> <span class="n">little</span> <span class="n">time</span><span class="o">.&lt;</span><span class="n">br</span><span class="o">&gt;</span>
+
+<span class="o">&lt;</span><span class="n">h2</span><span class="o">&gt;</span><span class="n">Link</span> <span class="n">Farm</span><span class="o">&lt;/</span><span class="n">h2</span><span class="o">&gt;</span>
+<span class="o">&lt;</span><span class="n">ul</span><span class="o">&gt;</span>
+<span class="o">&lt;</span><span class="n">li</span><span class="o">&gt;&lt;</span><span class="n">a</span> <span class="n">href</span><span class="o">=</span><span class="s2">&quot;http://localhost:8080/portal&quot;</span><span class="o">&gt;</span><span class="n">Portal</span><span class="o">&lt;/</span><span class="n">a</span><span class="o">&gt;&lt;/</span><span class="n">li</span><span class="o">&gt;</span>
+<span class="o">&lt;</span><span class="n">li</span><span class="o">&gt;&lt;</span><span class="n">a</span> <span class="n">href</span><span class="o">=</span><span class="s2">&quot;http://localhost/&quot;</span><span class="o">&gt;</span><span class="n">Local</span> <span class="n">Apache</span> <span class="n">Home</span> <span class="n">Page</span><span class="o">&lt;/</span><span class="n">a</span><span class="o">&gt;&lt;/</span><span class="n">li</span><span class="o">&gt;</span>
+<span class="o">&lt;/</span><span class="n">ul</span><span class="o">&gt;</span>
+
+<span class="o">&lt;</span><span class="n">hr</span><span class="o">&gt;&lt;</span><span class="n">a</span> <span class="n">href</span><span class="o">=</span><span class="s2">&quot;http://www.zope.org/Credits&quot;</span> <span class="n">target</span><span class="o">=</span><span class="s2">&quot;_top&quot;</span><span class="o">&gt;&lt;</span><span class="n">img</span> <span class="n">src</span><span class="o">=</span><span class="s2">&quot;https://127.0.0.1:9443/p_/ZopeButton&quot;</span> <span class="n">width</span><span class="o">=</span><span class="s2">&quot;115&quot;</span> <span class="n">height</span><span class="o">=</span><span class="s2">&quot;50&quot;</span> <span class="n">border</span><span class="o">=</span><span class="s2">&quot;0&quot;</span> <span class="n">alt</span><span class="o">=</span><span class="s2">&quot;Powered by Zope&quot;</span> <span class="o">/&gt;&lt;/</span><span class="n">a</span><span class="o">&gt;&lt;/</span><span class="n">body</span><span class="o">&gt;&lt;/</span><span class="n">html</span><span class="o">&gt;</span>
+</pre></div>
+</div>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">u</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
+<span class="go">&gt;&gt;&gt;</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="xmlrpc-over-https">
+<h2><a class="toc-backref" href="#id13">1.10.&nbsp;&nbsp;&nbsp;XMLRPC-over-HTTPS</a><a class="headerlink" href="#xmlrpc-over-https" title="Permalink to this headline">¶</a></h2>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">M2Crypto.m2xmlrpclib</span> <span class="k">import</span> <span class="n">Server</span><span class="p">,</span> <span class="n">SSL_Transport</span>
+<span class="gp">&gt;&gt;&gt; </span><span class="n">zs</span> <span class="o">=</span> <span class="n">Server</span><span class="p">(</span><span class="s1">&#39;https://127.0.0.1:9443/&#39;</span><span class="p">,</span> <span class="n">SSL_Transport</span><span class="p">())</span>
+<span class="gp">&gt;&gt;&gt; </span><span class="nb">print</span><span class="p">(</span><span class="n">zs</span><span class="o">.</span><span class="n">propertyMap</span><span class="p">())</span>
+<span class="go">[{&#39;type&#39;: &#39;string&#39;, &#39;id&#39;: &#39;title&#39;, &#39;mode&#39;: &#39;w&#39;}]</span>
+<span class="go">&gt;&gt;&gt;</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="conclusion">
+<h2><a class="toc-backref" href="#id14">1.11.&nbsp;&nbsp;&nbsp;Conclusion</a><a class="headerlink" href="#conclusion" title="Permalink to this headline">¶</a></h2>
+<p>Well, it works! ;-)</p>
+</div>
+</div>
+
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="index.html">M2Crypto</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="M2Crypto.html">M2Crypto Package</a></li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="index.html">Documentation overview</a><ul>
+ </ul></li>
+</ul>
+</div>
+<div id="searchbox" style="display: none" role="search">
+ <h3>Quick search</h3>
+ <div class="searchformwrapper">
+ <form class="search" action="search.html" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ </div>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer">
+ &copy;2017, Matej Cepl <mcepl@cepl.eu>.
+
+ |
+ Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
+ &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
+
+ |
+ <a href="_sources/ZServerSSL-HOWTO.rst.txt"
+ rel="nofollow">Page source</a>
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/_modules/M2Crypto/ASN1.html b/doc/html/_modules/M2Crypto/ASN1.html
new file mode 100644
index 0000000..bac4c1b
--- /dev/null
+++ b/doc/html/_modules/M2Crypto/ASN1.html
@@ -0,0 +1,357 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>M2Crypto.ASN1 &#8212; M2Crypto documentation</title>
+ <link rel="stylesheet" href="../../_static/alabaster.css" type="text/css" />
+ <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../../_static/jquery.js"></script>
+ <script type="text/javascript" src="../../_static/underscore.js"></script>
+ <script type="text/javascript" src="../../_static/doctools.js"></script>
+ <script type="text/javascript" src="../../_static/language_data.js"></script>
+ <link rel="index" title="Index" href="../../genindex.html" />
+ <link rel="search" title="Search" href="../../search.html" />
+
+ <link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+ <h1>Source code for M2Crypto.ASN1</h1><div class="highlight"><pre>
+<span></span><span class="kn">from</span> <span class="nn">__future__</span> <span class="k">import</span> <span class="n">absolute_import</span>
+
+<span class="sd">&quot;&quot;&quot;</span>
+<span class="sd">M2Crypto wrapper for OpenSSL ASN1 API.</span>
+
+<span class="sd">Copyright (c) 1999-2004 Ng Pheng Siong. All rights reserved.</span>
+
+<span class="sd">Portions created by Open Source Applications Foundation (OSAF) are</span>
+<span class="sd">Copyright (C) 2005 OSAF. All Rights Reserved.</span>
+<span class="sd">&quot;&quot;&quot;</span>
+
+<span class="kn">import</span> <span class="nn">datetime</span>
+<span class="kn">import</span> <span class="nn">time</span>
+
+<span class="kn">from</span> <span class="nn">M2Crypto</span> <span class="k">import</span> <span class="n">BIO</span><span class="p">,</span> <span class="n">m2</span><span class="p">,</span> <span class="n">py27plus</span><span class="p">,</span> <span class="n">six</span>
+<span class="k">if</span> <span class="n">py27plus</span><span class="p">:</span>
+ <span class="kn">from</span> <span class="nn">typing</span> <span class="k">import</span> <span class="n">Any</span><span class="p">,</span> <span class="n">Callable</span><span class="p">,</span> <span class="n">Optional</span><span class="p">,</span> <span class="n">Tuple</span> <span class="c1"># noqa</span>
+
+<span class="n">MBSTRING_FLAG</span> <span class="o">=</span> <span class="mh">0x1000</span>
+<span class="n">MBSTRING_ASC</span> <span class="o">=</span> <span class="n">MBSTRING_FLAG</span> <span class="o">|</span> <span class="mi">1</span>
+<span class="n">MBSTRING_BMP</span> <span class="o">=</span> <span class="n">MBSTRING_FLAG</span> <span class="o">|</span> <span class="mi">2</span>
+
+
+<div class="viewcode-block" id="ASN1_Integer"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.ASN1.ASN1_Integer">[docs]</a><span class="k">class</span> <span class="nc">ASN1_Integer</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+
+ <span class="n">m2_asn1_integer_free</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">asn1_integer_free</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">asn1int</span><span class="p">,</span> <span class="n">_pyfree</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
+ <span class="c1"># type: (ASN1_Integer, int) -&gt; None</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">asn1int</span> <span class="o">=</span> <span class="n">asn1int</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_pyfree</span> <span class="o">=</span> <span class="n">_pyfree</span>
+
+ <span class="k">def</span> <span class="nf">__cmp__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
+ <span class="c1"># type: (ASN1_Integer) -&gt; int</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">ASN1_Integer</span><span class="p">):</span>
+ <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span>
+ <span class="s2">&quot;Comparisons supported only between ANS1_Integer objects&quot;</span><span class="p">)</span>
+
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">asn1_integer_cmp</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">asn1int</span><span class="p">,</span> <span class="n">other</span><span class="o">.</span><span class="n">asn1int</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">__del__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pyfree</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">m2_asn1_integer_free</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">asn1int</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">__int__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">asn1_integer_get</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">asn1int</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="ASN1_String"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.ASN1.ASN1_String">[docs]</a><span class="k">class</span> <span class="nc">ASN1_String</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+
+ <span class="n">m2_asn1_string_free</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">asn1_string_free</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">asn1str</span><span class="p">,</span> <span class="n">_pyfree</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
+ <span class="c1"># type: (ASN1_String, int) -&gt; None</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">asn1str</span> <span class="o">=</span> <span class="n">asn1str</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_pyfree</span> <span class="o">=</span> <span class="n">_pyfree</span>
+
+ <span class="k">def</span> <span class="nf">__bytes__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; bytes</span>
+ <span class="n">buf</span> <span class="o">=</span> <span class="n">BIO</span><span class="o">.</span><span class="n">MemoryBuffer</span><span class="p">()</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">asn1_string_print</span><span class="p">(</span><span class="n">buf</span><span class="o">.</span><span class="n">bio_ptr</span><span class="p">(),</span> <span class="bp">self</span><span class="o">.</span><span class="n">asn1str</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">buf</span><span class="o">.</span><span class="n">read_all</span><span class="p">()</span>
+
+ <span class="k">def</span> <span class="nf">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; str</span>
+ <span class="k">return</span> <span class="n">six</span><span class="o">.</span><span class="n">ensure_text</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="fm">__bytes__</span><span class="p">())</span>
+
+ <span class="k">def</span> <span class="nf">__del__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;_pyfree&#39;</span><span class="p">,</span> <span class="mi">0</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">m2_asn1_string_free</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">asn1str</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">_ptr</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">asn1str</span>
+
+<div class="viewcode-block" id="ASN1_String.as_text"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.ASN1.ASN1_String.as_text">[docs]</a> <span class="k">def</span> <span class="nf">as_text</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">flags</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
+ <span class="c1"># type: (int) -&gt; str</span>
+ <span class="sd">&quot;&quot;&quot;Output an ASN1_STRING structure according to the set flags.</span>
+
+<span class="sd"> :param flags: determine the format of the output by using</span>
+<span class="sd"> predetermined constants, see ASN1_STRING_print_ex(3)</span>
+<span class="sd"> manpage for their meaning.</span>
+<span class="sd"> :return: output an ASN1_STRING structure.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">buf</span> <span class="o">=</span> <span class="n">BIO</span><span class="o">.</span><span class="n">MemoryBuffer</span><span class="p">()</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">asn1_string_print_ex</span><span class="p">(</span><span class="n">buf</span><span class="o">.</span><span class="n">bio_ptr</span><span class="p">(),</span> <span class="bp">self</span><span class="o">.</span><span class="n">asn1str</span><span class="p">,</span> <span class="n">flags</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">six</span><span class="o">.</span><span class="n">ensure_text</span><span class="p">(</span><span class="n">buf</span><span class="o">.</span><span class="n">read_all</span><span class="p">())</span></div></div>
+
+
+<div class="viewcode-block" id="ASN1_Object"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.ASN1.ASN1_Object">[docs]</a><span class="k">class</span> <span class="nc">ASN1_Object</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+
+ <span class="n">m2_asn1_object_free</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">asn1_object_free</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">asn1obj</span><span class="p">,</span> <span class="n">_pyfree</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
+ <span class="c1"># type: (ASN1_Object, int) -&gt; None</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">asn1obj</span> <span class="o">=</span> <span class="n">asn1obj</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_pyfree</span> <span class="o">=</span> <span class="n">_pyfree</span>
+
+ <span class="k">def</span> <span class="nf">__del__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pyfree</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">m2_asn1_object_free</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">asn1obj</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">_ptr</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">asn1obj</span></div>
+
+
+<span class="k">class</span> <span class="nc">_UTC</span><span class="p">(</span><span class="n">datetime</span><span class="o">.</span><span class="n">tzinfo</span><span class="p">):</span>
+ <span class="k">def</span> <span class="nf">tzname</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">dt</span><span class="p">):</span>
+ <span class="c1"># type: (Optional[datetime.datetime]) -&gt; str</span>
+ <span class="k">return</span> <span class="s2">&quot;UTC&quot;</span>
+
+ <span class="k">def</span> <span class="nf">dst</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">dt</span><span class="p">):</span>
+ <span class="c1"># type: (Optional[datetime.datetime]) -&gt; datetime.timedelta</span>
+ <span class="k">return</span> <span class="n">datetime</span><span class="o">.</span><span class="n">timedelta</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">utcoffset</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">dt</span><span class="p">):</span>
+ <span class="c1"># type: (Optional[datetime.datetime]) -&gt; datetime.timedelta</span>
+ <span class="k">return</span> <span class="n">datetime</span><span class="o">.</span><span class="n">timedelta</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="k">return</span> <span class="s2">&quot;&lt;Timezone: </span><span class="si">%s</span><span class="s2">&gt;&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">tzname</span><span class="p">(</span><span class="kc">None</span><span class="p">)</span>
+
+
+<span class="n">UTC</span> <span class="o">=</span> <span class="n">_UTC</span><span class="p">()</span> <span class="c1"># type: _UTC</span>
+
+
+<div class="viewcode-block" id="LocalTimezone"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.ASN1.LocalTimezone">[docs]</a><span class="k">class</span> <span class="nc">LocalTimezone</span><span class="p">(</span><span class="n">datetime</span><span class="o">.</span><span class="n">tzinfo</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Localtimezone from datetime manual.&quot;&quot;&quot;</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_stdoffset</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">timedelta</span><span class="p">(</span><span class="n">seconds</span><span class="o">=-</span><span class="n">time</span><span class="o">.</span><span class="n">timezone</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">time</span><span class="o">.</span><span class="n">daylight</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_dstoffset</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">timedelta</span><span class="p">(</span><span class="n">seconds</span><span class="o">=-</span><span class="n">time</span><span class="o">.</span><span class="n">altzone</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_dstoffset</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_stdoffset</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_dstdiff</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dstoffset</span> <span class="o">-</span> <span class="bp">self</span><span class="o">.</span><span class="n">_stdoffset</span>
+
+<div class="viewcode-block" id="LocalTimezone.utcoffset"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.ASN1.LocalTimezone.utcoffset">[docs]</a> <span class="k">def</span> <span class="nf">utcoffset</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">dt</span><span class="p">):</span>
+ <span class="c1"># type: (datetime.datetime) -&gt; datetime.timedelta</span>
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_isdst</span><span class="p">(</span><span class="n">dt</span><span class="p">):</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dstoffset</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_stdoffset</span></div>
+
+<div class="viewcode-block" id="LocalTimezone.dst"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.ASN1.LocalTimezone.dst">[docs]</a> <span class="k">def</span> <span class="nf">dst</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">dt</span><span class="p">):</span>
+ <span class="c1"># type: (datetime.datetime) -&gt; datetime.timedelta</span>
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_isdst</span><span class="p">(</span><span class="n">dt</span><span class="p">):</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dstdiff</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">datetime</span><span class="o">.</span><span class="n">timedelta</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="LocalTimezone.tzname"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.ASN1.LocalTimezone.tzname">[docs]</a> <span class="k">def</span> <span class="nf">tzname</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">dt</span><span class="p">):</span>
+ <span class="c1"># type: (datetime.datetime) -&gt; str</span>
+ <span class="k">return</span> <span class="n">time</span><span class="o">.</span><span class="n">tzname</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">_isdst</span><span class="p">(</span><span class="n">dt</span><span class="p">)</span><span class="o">.</span><span class="n">real</span><span class="p">]</span></div>
+
+ <span class="k">def</span> <span class="nf">_isdst</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">dt</span><span class="p">):</span>
+ <span class="c1"># type: (datetime.datetime) -&gt; bool</span>
+ <span class="n">tt</span> <span class="o">=</span> <span class="p">(</span><span class="n">dt</span><span class="o">.</span><span class="n">year</span><span class="p">,</span> <span class="n">dt</span><span class="o">.</span><span class="n">month</span><span class="p">,</span> <span class="n">dt</span><span class="o">.</span><span class="n">day</span><span class="p">,</span>
+ <span class="n">dt</span><span class="o">.</span><span class="n">hour</span><span class="p">,</span> <span class="n">dt</span><span class="o">.</span><span class="n">minute</span><span class="p">,</span> <span class="n">dt</span><span class="o">.</span><span class="n">second</span><span class="p">,</span>
+ <span class="n">dt</span><span class="o">.</span><span class="n">weekday</span><span class="p">(),</span> <span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span>
+ <span class="n">stamp</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">mktime</span><span class="p">(</span><span class="n">tt</span><span class="p">)</span>
+ <span class="n">tt</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">localtime</span><span class="p">(</span><span class="n">stamp</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">tt</span><span class="o">.</span><span class="n">tm_isdst</span> <span class="o">&gt;</span> <span class="mi">0</span></div>
+
+
+<div class="viewcode-block" id="ASN1_TIME"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.ASN1.ASN1_TIME">[docs]</a><span class="k">class</span> <span class="nc">ASN1_TIME</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+ <span class="n">_ssl_months</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;Jan&quot;</span><span class="p">,</span> <span class="s2">&quot;Feb&quot;</span><span class="p">,</span> <span class="s2">&quot;Mar&quot;</span><span class="p">,</span> <span class="s2">&quot;Apr&quot;</span><span class="p">,</span> <span class="s2">&quot;May&quot;</span><span class="p">,</span> <span class="s2">&quot;Jun&quot;</span><span class="p">,</span> <span class="s2">&quot;Jul&quot;</span><span class="p">,</span> <span class="s2">&quot;Aug&quot;</span><span class="p">,</span>
+ <span class="s2">&quot;Sep&quot;</span><span class="p">,</span> <span class="s2">&quot;Oct&quot;</span><span class="p">,</span> <span class="s2">&quot;Nov&quot;</span><span class="p">,</span> <span class="s2">&quot;Dec&quot;</span><span class="p">]</span>
+ <span class="n">m2_asn1_time_free</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">asn1_time_free</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">asn1_time</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">_pyfree</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">asn1_utctime</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="c1"># type: (Optional[ASN1_TIME], Optional[int], Optional[ASN1_TIME]) -&gt; None</span>
+ <span class="c1"># handle old keyword parameter</span>
+ <span class="k">if</span> <span class="n">asn1_time</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">asn1_time</span> <span class="o">=</span> <span class="n">asn1_utctime</span>
+ <span class="k">if</span> <span class="n">asn1_time</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">asn1_time_type_check</span><span class="p">(</span><span class="n">asn1_time</span><span class="p">),</span> \
+ <span class="s2">&quot;&#39;asn1_time&#39; type error&#39;&quot;</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">asn1_time</span> <span class="o">=</span> <span class="n">asn1_time</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_pyfree</span> <span class="o">=</span> <span class="n">_pyfree</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">asn1_time</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">asn1_time_new</span><span class="p">()</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_pyfree</span> <span class="o">=</span> <span class="mi">1</span>
+
+ <span class="k">def</span> <span class="nf">__del__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;_pyfree&#39;</span><span class="p">,</span> <span class="mi">0</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">m2_asn1_time_free</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">asn1_time</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; str</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">asn1_time_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">asn1_time</span><span class="p">),</span> \
+ <span class="s2">&quot;&#39;asn1_time&#39; type error&#39;&quot;</span>
+ <span class="n">buf</span> <span class="o">=</span> <span class="n">BIO</span><span class="o">.</span><span class="n">MemoryBuffer</span><span class="p">()</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">asn1_time_print</span><span class="p">(</span><span class="n">buf</span><span class="o">.</span><span class="n">bio_ptr</span><span class="p">(),</span> <span class="bp">self</span><span class="o">.</span><span class="n">asn1_time</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">six</span><span class="o">.</span><span class="n">ensure_text</span><span class="p">(</span><span class="n">buf</span><span class="o">.</span><span class="n">read_all</span><span class="p">())</span>
+
+ <span class="k">def</span> <span class="nf">_ptr</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">asn1_time_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">asn1_time</span><span class="p">),</span> \
+ <span class="s2">&quot;&#39;asn1_time&#39; type error&#39;&quot;</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">asn1_time</span>
+
+<div class="viewcode-block" id="ASN1_TIME.set_string"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.ASN1.ASN1_TIME.set_string">[docs]</a> <span class="k">def</span> <span class="nf">set_string</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">string</span><span class="p">):</span>
+ <span class="c1"># type: (bytes) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;Set time from UTC string.&quot;&quot;&quot;</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">asn1_time_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">asn1_time</span><span class="p">),</span> \
+ <span class="s2">&quot;&#39;asn1_time&#39; type error&#39;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">asn1_time_set_string</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">asn1_time</span><span class="p">,</span> <span class="n">string</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="ASN1_TIME.set_time"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.ASN1.ASN1_TIME.set_time">[docs]</a> <span class="k">def</span> <span class="nf">set_time</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">time</span><span class="p">):</span>
+ <span class="c1"># type: (int) -&gt; ASN1_TIME</span>
+ <span class="sd">&quot;&quot;&quot;Set time from seconds since epoch (int).&quot;&quot;&quot;</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">asn1_time_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">asn1_time</span><span class="p">),</span> \
+ <span class="s2">&quot;&#39;asn1_time&#39; type error&#39;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">asn1_time_set</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">asn1_time</span><span class="p">,</span> <span class="n">time</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="ASN1_TIME.get_datetime"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.ASN1.ASN1_TIME.get_datetime">[docs]</a> <span class="k">def</span> <span class="nf">get_datetime</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; ASN1_TIME</span>
+ <span class="n">date</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
+
+ <span class="n">timezone</span> <span class="o">=</span> <span class="kc">None</span>
+ <span class="k">if</span> <span class="s1">&#39; &#39;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">date</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;Invalid date: </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">date</span><span class="p">)</span>
+ <span class="n">month</span><span class="p">,</span> <span class="n">rest</span> <span class="o">=</span> <span class="n">date</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">month</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_ssl_months</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;Invalid date </span><span class="si">%s</span><span class="s2">: Invalid month: </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span>
+ <span class="p">(</span><span class="n">date</span><span class="p">,</span> <span class="n">month</span><span class="p">))</span>
+ <span class="k">if</span> <span class="n">rest</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="s1">&#39; GMT&#39;</span><span class="p">):</span>
+ <span class="n">timezone</span> <span class="o">=</span> <span class="n">UTC</span>
+ <span class="n">rest</span> <span class="o">=</span> <span class="n">rest</span><span class="p">[:</span><span class="o">-</span><span class="mi">4</span><span class="p">]</span>
+ <span class="k">if</span> <span class="s1">&#39;.&#39;</span> <span class="ow">in</span> <span class="n">rest</span><span class="p">:</span>
+ <span class="n">dt</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">strptime</span><span class="p">(</span><span class="n">rest</span><span class="p">,</span> <span class="s2">&quot;</span><span class="si">%d</span><span class="s2"> %H:%M:%S.</span><span class="si">%f</span><span class="s2"> %Y&quot;</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">dt</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">strptime</span><span class="p">(</span><span class="n">rest</span><span class="p">,</span> <span class="s2">&quot;</span><span class="si">%d</span><span class="s2"> %H:%M:%S %Y&quot;</span><span class="p">)</span>
+ <span class="n">dt</span> <span class="o">=</span> <span class="n">dt</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">month</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_ssl_months</span><span class="o">.</span><span class="n">index</span><span class="p">(</span><span class="n">month</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">timezone</span><span class="p">:</span>
+ <span class="n">dt</span> <span class="o">=</span> <span class="n">dt</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">tzinfo</span><span class="o">=</span><span class="n">UTC</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">dt</span></div>
+
+<div class="viewcode-block" id="ASN1_TIME.set_datetime"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.ASN1.ASN1_TIME.set_datetime">[docs]</a> <span class="k">def</span> <span class="nf">set_datetime</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">date</span><span class="p">):</span>
+ <span class="c1"># type: (datetime.datetime) -&gt; ASN1_TIME</span>
+ <span class="n">local</span> <span class="o">=</span> <span class="n">LocalTimezone</span><span class="p">()</span>
+ <span class="k">if</span> <span class="n">date</span><span class="o">.</span><span class="n">tzinfo</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">date</span> <span class="o">=</span> <span class="n">date</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">tzinfo</span><span class="o">=</span><span class="n">local</span><span class="p">)</span>
+ <span class="n">date</span> <span class="o">=</span> <span class="n">date</span><span class="o">.</span><span class="n">astimezone</span><span class="p">(</span><span class="n">local</span><span class="p">)</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">set_time</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">mktime</span><span class="p">(</span><span class="n">date</span><span class="o">.</span><span class="n">timetuple</span><span class="p">())))</span></div></div>
+
+
+<span class="n">ASN1_UTCTIME</span> <span class="o">=</span> <span class="n">ASN1_TIME</span>
+</pre></div>
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="../../index.html">M2Crypto</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="../../M2Crypto.html">M2Crypto Package</a></li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="../../index.html">Documentation overview</a><ul>
+ <li><a href="../index.html">Module code</a><ul>
+ </ul></li>
+ </ul></li>
+</ul>
+</div>
+<div id="searchbox" style="display: none" role="search">
+ <h3>Quick search</h3>
+ <div class="searchformwrapper">
+ <form class="search" action="../../search.html" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ </div>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer">
+ &copy;2017, Matej Cepl <mcepl@cepl.eu>.
+
+ |
+ Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
+ &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
+
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/_modules/M2Crypto/AuthCookie.html b/doc/html/_modules/M2Crypto/AuthCookie.html
new file mode 100644
index 0000000..3b2d629
--- /dev/null
+++ b/doc/html/_modules/M2Crypto/AuthCookie.html
@@ -0,0 +1,273 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>M2Crypto.AuthCookie &#8212; M2Crypto documentation</title>
+ <link rel="stylesheet" href="../../_static/alabaster.css" type="text/css" />
+ <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../../_static/jquery.js"></script>
+ <script type="text/javascript" src="../../_static/underscore.js"></script>
+ <script type="text/javascript" src="../../_static/doctools.js"></script>
+ <script type="text/javascript" src="../../_static/language_data.js"></script>
+ <link rel="index" title="Index" href="../../genindex.html" />
+ <link rel="search" title="Search" href="../../search.html" />
+
+ <link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+ <h1>Source code for M2Crypto.AuthCookie</h1><div class="highlight"><pre>
+<span></span><span class="kn">from</span> <span class="nn">__future__</span> <span class="k">import</span> <span class="n">absolute_import</span>
+
+<span class="sd">&quot;&quot;&quot;Secure Authenticator Cookies</span>
+
+<span class="sd">Copyright (c) 1999-2002 Ng Pheng Siong. All rights reserved.&quot;&quot;&quot;</span>
+
+<span class="kn">import</span> <span class="nn">logging</span>
+<span class="kn">import</span> <span class="nn">re</span>
+<span class="kn">import</span> <span class="nn">time</span>
+
+<span class="kn">from</span> <span class="nn">M2Crypto</span> <span class="k">import</span> <span class="n">Rand</span><span class="p">,</span> <span class="n">m2</span><span class="p">,</span> <span class="n">py27plus</span><span class="p">,</span> <span class="n">six</span><span class="p">,</span> <span class="n">util</span>
+<span class="kn">from</span> <span class="nn">M2Crypto.six.moves.http_cookies</span> <span class="k">import</span> <span class="n">SimpleCookie</span> <span class="c1"># pylint: disable=no-name-in-module,import-error</span>
+
+<span class="k">if</span> <span class="n">py27plus</span><span class="p">:</span>
+ <span class="kn">from</span> <span class="nn">typing</span> <span class="k">import</span> <span class="n">re</span> <span class="k">as</span> <span class="n">type_re</span><span class="p">,</span> <span class="n">AnyStr</span><span class="p">,</span> <span class="n">Dict</span><span class="p">,</span> <span class="n">Optional</span><span class="p">,</span> <span class="n">Union</span> <span class="c1"># noqa</span>
+
+<span class="n">_MIX_FORMAT</span> <span class="o">=</span> <span class="s1">&#39;exp=</span><span class="si">%f</span><span class="s1">&amp;data=</span><span class="si">%s</span><span class="s1">&amp;digest=&#39;</span>
+<span class="n">_MIX_RE</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;exp=(\d+\.\d+)&amp;data=(.+)&amp;digest=(\S*)&#39;</span><span class="p">)</span>
+
+<span class="n">log</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="vm">__name__</span><span class="p">)</span>
+
+
+<div class="viewcode-block" id="mix"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.AuthCookie.mix">[docs]</a><span class="k">def</span> <span class="nf">mix</span><span class="p">(</span><span class="n">expiry</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="nb">format</span><span class="o">=</span><span class="n">_MIX_FORMAT</span><span class="p">):</span>
+ <span class="c1"># type: (float, AnyStr, str) -&gt; AnyStr</span>
+ <span class="k">return</span> <span class="nb">format</span> <span class="o">%</span> <span class="p">(</span><span class="n">expiry</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="unmix"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.AuthCookie.unmix">[docs]</a><span class="k">def</span> <span class="nf">unmix</span><span class="p">(</span><span class="n">dough</span><span class="p">,</span> <span class="n">regex</span><span class="o">=</span><span class="n">_MIX_RE</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr, type_re) -&gt; object</span>
+ <span class="n">mo</span> <span class="o">=</span> <span class="n">regex</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">dough</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">mo</span><span class="p">:</span>
+ <span class="k">return</span> <span class="nb">float</span><span class="p">(</span><span class="n">mo</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="mi">1</span><span class="p">)),</span> <span class="n">mo</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">return</span> <span class="kc">None</span></div>
+
+
+<div class="viewcode-block" id="unmix3"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.AuthCookie.unmix3">[docs]</a><span class="k">def</span> <span class="nf">unmix3</span><span class="p">(</span><span class="n">dough</span><span class="p">,</span> <span class="n">regex</span><span class="o">=</span><span class="n">_MIX_RE</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr, type_re) -&gt; Optional[tuple[float, AnyStr, AnyStr]]</span>
+ <span class="n">mo</span> <span class="o">=</span> <span class="n">regex</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">dough</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">mo</span><span class="p">:</span>
+ <span class="k">return</span> <span class="nb">float</span><span class="p">(</span><span class="n">mo</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="mi">1</span><span class="p">)),</span> <span class="n">mo</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="mi">2</span><span class="p">),</span> <span class="n">mo</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">return</span> <span class="kc">None</span></div>
+
+
+<span class="n">_TOKEN</span> <span class="o">=</span> <span class="s1">&#39;_M2AUTH_&#39;</span> <span class="c1"># type: str</span>
+
+
+<div class="viewcode-block" id="AuthCookieJar"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.AuthCookie.AuthCookieJar">[docs]</a><span class="k">class</span> <span class="nc">AuthCookieJar</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+
+ <span class="n">_keylen</span> <span class="o">=</span> <span class="mi">20</span> <span class="c1"># type: int</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_key</span> <span class="o">=</span> <span class="n">Rand</span><span class="o">.</span><span class="n">rand_bytes</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_keylen</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">_hmac</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
+ <span class="c1"># type: (bytes, str) -&gt; str</span>
+ <span class="k">return</span> <span class="n">util</span><span class="o">.</span><span class="n">bin_to_hex</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">hmac</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">six</span><span class="o">.</span><span class="n">ensure_binary</span><span class="p">(</span><span class="n">data</span><span class="p">),</span> <span class="n">m2</span><span class="o">.</span><span class="n">sha1</span><span class="p">()))</span>
+
+<div class="viewcode-block" id="AuthCookieJar.makeCookie"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.AuthCookie.AuthCookieJar.makeCookie">[docs]</a> <span class="k">def</span> <span class="nf">makeCookie</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">expiry</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
+ <span class="c1"># type: (float, str) -&gt; AuthCookie</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Make a cookie</span>
+
+<span class="sd"> :param expiry: expiration time (float in seconds)</span>
+<span class="sd"> :param data: cookie content</span>
+<span class="sd"> :return: AuthCookie object</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expiry</span><span class="p">,</span> <span class="p">(</span><span class="n">six</span><span class="o">.</span><span class="n">integer_types</span><span class="p">,</span> <span class="nb">float</span><span class="p">)):</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">&#39;Expiration time must be number, not &quot;</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">expiry</span><span class="p">)</span>
+ <span class="n">dough</span> <span class="o">=</span> <span class="n">mix</span><span class="p">(</span><span class="n">expiry</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">AuthCookie</span><span class="p">(</span><span class="n">expiry</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">dough</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_hmac</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_key</span><span class="p">,</span> <span class="n">dough</span><span class="p">))</span></div>
+
+<div class="viewcode-block" id="AuthCookieJar.isGoodCookie"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.AuthCookie.AuthCookieJar.isGoodCookie">[docs]</a> <span class="k">def</span> <span class="nf">isGoodCookie</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">cookie</span><span class="p">):</span>
+ <span class="c1"># type: (AuthCookie) -&gt; Union[bool, int]</span>
+ <span class="k">assert</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">cookie</span><span class="p">,</span> <span class="n">AuthCookie</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">cookie</span><span class="o">.</span><span class="n">isExpired</span><span class="p">():</span>
+ <span class="k">return</span> <span class="mi">0</span>
+ <span class="n">c</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">makeCookie</span><span class="p">(</span><span class="n">cookie</span><span class="o">.</span><span class="n">_expiry</span><span class="p">,</span> <span class="n">cookie</span><span class="o">.</span><span class="n">_data</span><span class="p">)</span>
+ <span class="k">return</span> <span class="p">(</span><span class="n">c</span><span class="o">.</span><span class="n">_expiry</span> <span class="o">==</span> <span class="n">cookie</span><span class="o">.</span><span class="n">_expiry</span><span class="p">)</span> \
+ <span class="ow">and</span> <span class="p">(</span><span class="n">c</span><span class="o">.</span><span class="n">_data</span> <span class="o">==</span> <span class="n">cookie</span><span class="o">.</span><span class="n">_data</span><span class="p">)</span> \
+ <span class="ow">and</span> <span class="p">(</span><span class="n">c</span><span class="o">.</span><span class="n">_mac</span> <span class="o">==</span> <span class="n">cookie</span><span class="o">.</span><span class="n">_mac</span><span class="p">)</span> \
+ <span class="ow">and</span> <span class="p">(</span><span class="n">c</span><span class="o">.</span><span class="n">output</span><span class="p">()</span> <span class="o">==</span> <span class="n">cookie</span><span class="o">.</span><span class="n">output</span><span class="p">())</span></div>
+
+<div class="viewcode-block" id="AuthCookieJar.isGoodCookieString"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.AuthCookie.AuthCookieJar.isGoodCookieString">[docs]</a> <span class="k">def</span> <span class="nf">isGoodCookieString</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">cookie_str</span><span class="p">,</span> <span class="n">_debug</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
+ <span class="c1"># type: (Union[dict, bytes], bool) -&gt; Union[bool, int]</span>
+ <span class="n">c</span> <span class="o">=</span> <span class="n">SimpleCookie</span><span class="p">()</span>
+ <span class="n">c</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="n">cookie_str</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">_TOKEN</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">c</span><span class="p">:</span>
+ <span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s1">&#39;_TOKEN not in c (keys = </span><span class="si">%s</span><span class="s1">)&#39;</span><span class="p">,</span> <span class="nb">dir</span><span class="p">(</span><span class="n">c</span><span class="p">))</span>
+ <span class="k">return</span> <span class="mi">0</span>
+ <span class="n">undough</span> <span class="o">=</span> <span class="n">unmix3</span><span class="p">(</span><span class="n">c</span><span class="p">[</span><span class="n">_TOKEN</span><span class="p">]</span><span class="o">.</span><span class="n">value</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">undough</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s1">&#39;undough is None&#39;</span><span class="p">)</span>
+ <span class="k">return</span> <span class="mi">0</span>
+ <span class="n">exp</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">mac</span> <span class="o">=</span> <span class="n">undough</span>
+ <span class="n">c2</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">makeCookie</span><span class="p">(</span><span class="n">exp</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">_debug</span> <span class="ow">and</span> <span class="p">(</span><span class="n">c2</span><span class="o">.</span><span class="n">_mac</span> <span class="o">==</span> <span class="n">mac</span><span class="p">):</span>
+ <span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s1">&#39;cookie_str = </span><span class="si">%s</span><span class="s1">&#39;</span><span class="p">,</span> <span class="n">cookie_str</span><span class="p">)</span>
+ <span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s1">&#39;c2.isExpired = </span><span class="si">%s</span><span class="s1">&#39;</span><span class="p">,</span> <span class="n">c2</span><span class="o">.</span><span class="n">isExpired</span><span class="p">())</span>
+ <span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s1">&#39;mac = </span><span class="si">%s</span><span class="s1">&#39;</span><span class="p">,</span> <span class="n">mac</span><span class="p">)</span>
+ <span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s1">&#39;c2._mac = </span><span class="si">%s</span><span class="s1">&#39;</span><span class="p">,</span> <span class="n">c2</span><span class="o">.</span><span class="n">_mac</span><span class="p">)</span>
+ <span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s1">&#39;c2._mac == mac: </span><span class="si">%s</span><span class="s1">&#39;</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">c2</span><span class="o">.</span><span class="n">_mac</span> <span class="o">==</span> <span class="n">mac</span><span class="p">))</span>
+ <span class="k">return</span> <span class="p">(</span><span class="ow">not</span> <span class="n">c2</span><span class="o">.</span><span class="n">isExpired</span><span class="p">())</span> <span class="ow">and</span> <span class="p">(</span><span class="n">c2</span><span class="o">.</span><span class="n">_mac</span> <span class="o">==</span> <span class="n">mac</span><span class="p">)</span></div></div>
+
+
+<div class="viewcode-block" id="AuthCookie"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.AuthCookie.AuthCookie">[docs]</a><span class="k">class</span> <span class="nc">AuthCookie</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">expiry</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">dough</span><span class="p">,</span> <span class="n">mac</span><span class="p">):</span>
+ <span class="c1"># type: (float, str, str, str) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Create new authentication cookie</span>
+
+<span class="sd"> :param expiry: expiration time (in seconds)</span>
+<span class="sd"> :param data: cookie payload (as a string)</span>
+<span class="sd"> :param dough: expiry &amp; data concatenated to URL compliant</span>
+<span class="sd"> string</span>
+<span class="sd"> :param mac: SHA1-based HMAC of dough and random key</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_expiry</span> <span class="o">=</span> <span class="n">expiry</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_data</span> <span class="o">=</span> <span class="n">data</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_mac</span> <span class="o">=</span> <span class="n">mac</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_cookie</span> <span class="o">=</span> <span class="n">SimpleCookie</span><span class="p">()</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_cookie</span><span class="p">[</span><span class="n">_TOKEN</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="si">%s%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">dough</span><span class="p">,</span> <span class="n">mac</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_name</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="si">%s%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">dough</span><span class="p">,</span> <span class="n">mac</span><span class="p">)</span> <span class="c1"># WebKit only.</span>
+
+<div class="viewcode-block" id="AuthCookie.expiry"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.AuthCookie.AuthCookie.expiry">[docs]</a> <span class="k">def</span> <span class="nf">expiry</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; float</span>
+ <span class="sd">&quot;&quot;&quot;Return the cookie&#39;s expiry time.&quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_expiry</span></div>
+
+<div class="viewcode-block" id="AuthCookie.data"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.AuthCookie.AuthCookie.data">[docs]</a> <span class="k">def</span> <span class="nf">data</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; str</span>
+ <span class="sd">&quot;&quot;&quot;Return the data portion of the cookie.&quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_data</span></div>
+
+<div class="viewcode-block" id="AuthCookie.mac"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.AuthCookie.AuthCookie.mac">[docs]</a> <span class="k">def</span> <span class="nf">mac</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; str</span>
+ <span class="sd">&quot;&quot;&quot;Return the cookie&#39;s MAC.&quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_mac</span></div>
+
+<div class="viewcode-block" id="AuthCookie.output"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.AuthCookie.AuthCookie.output">[docs]</a> <span class="k">def</span> <span class="nf">output</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">header</span><span class="o">=</span><span class="s2">&quot;Set-Cookie:&quot;</span><span class="p">):</span>
+ <span class="c1"># type: (Optional[str]) -&gt; str</span>
+ <span class="sd">&quot;&quot;&quot;Return the cookie&#39;s output in &quot;Set-Cookie&quot; format.&quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_cookie</span><span class="o">.</span><span class="n">output</span><span class="p">(</span><span class="n">header</span><span class="o">=</span><span class="n">header</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="AuthCookie.value"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.AuthCookie.AuthCookie.value">[docs]</a> <span class="k">def</span> <span class="nf">value</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; str</span>
+ <span class="sd">&quot;&quot;&quot;Return the cookie&#39;s output minus the &quot;Set-Cookie: &quot; portion.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_cookie</span><span class="p">[</span><span class="n">_TOKEN</span><span class="p">]</span><span class="o">.</span><span class="n">value</span></div>
+
+<div class="viewcode-block" id="AuthCookie.isExpired"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.AuthCookie.AuthCookie.isExpired">[docs]</a> <span class="k">def</span> <span class="nf">isExpired</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; bool</span>
+ <span class="sd">&quot;&quot;&quot;Return 1 if the cookie has expired, 0 otherwise.&quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="nb">isinstance</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_expiry</span><span class="p">,</span> <span class="p">(</span><span class="nb">float</span><span class="p">,</span> <span class="n">six</span><span class="o">.</span><span class="n">integer_types</span><span class="p">))</span> <span class="ow">and</span> \
+ <span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">&gt;</span> <span class="bp">self</span><span class="o">.</span><span class="n">_expiry</span><span class="p">)</span></div>
+
+ <span class="c1"># Following two methods are for WebKit only.</span>
+ <span class="c1"># I may wish to push them to WKAuthCookie, but they are part</span>
+ <span class="c1"># of the API now. Oh well.</span>
+<div class="viewcode-block" id="AuthCookie.name"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.AuthCookie.AuthCookie.name">[docs]</a> <span class="k">def</span> <span class="nf">name</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; str</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name</span></div>
+
+<div class="viewcode-block" id="AuthCookie.headerValue"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.AuthCookie.AuthCookie.headerValue">[docs]</a> <span class="k">def</span> <span class="nf">headerValue</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; str</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">value</span><span class="p">()</span></div></div>
+</pre></div>
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="../../index.html">M2Crypto</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="../../M2Crypto.html">M2Crypto Package</a></li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="../../index.html">Documentation overview</a><ul>
+ <li><a href="../index.html">Module code</a><ul>
+ </ul></li>
+ </ul></li>
+</ul>
+</div>
+<div id="searchbox" style="display: none" role="search">
+ <h3>Quick search</h3>
+ <div class="searchformwrapper">
+ <form class="search" action="../../search.html" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ </div>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer">
+ &copy;2017, Matej Cepl <mcepl@cepl.eu>.
+
+ |
+ Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
+ &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
+
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/_modules/M2Crypto/BIO.html b/doc/html/_modules/M2Crypto/BIO.html
new file mode 100644
index 0000000..212c05d
--- /dev/null
+++ b/doc/html/_modules/M2Crypto/BIO.html
@@ -0,0 +1,494 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>M2Crypto.BIO &#8212; M2Crypto documentation</title>
+ <link rel="stylesheet" href="../../_static/alabaster.css" type="text/css" />
+ <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../../_static/jquery.js"></script>
+ <script type="text/javascript" src="../../_static/underscore.js"></script>
+ <script type="text/javascript" src="../../_static/doctools.js"></script>
+ <script type="text/javascript" src="../../_static/language_data.js"></script>
+ <link rel="index" title="Index" href="../../genindex.html" />
+ <link rel="search" title="Search" href="../../search.html" />
+
+ <link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+ <h1>Source code for M2Crypto.BIO</h1><div class="highlight"><pre>
+<span></span><span class="kn">from</span> <span class="nn">__future__</span> <span class="k">import</span> <span class="n">absolute_import</span>
+
+<span class="sd">&quot;&quot;&quot;M2Crypto wrapper for OpenSSL BIO API.</span>
+
+<span class="sd">Copyright (c) 1999-2004 Ng Pheng Siong. All rights reserved.&quot;&quot;&quot;</span>
+
+<span class="kn">import</span> <span class="nn">logging</span>
+
+<span class="kn">from</span> <span class="nn">M2Crypto</span> <span class="k">import</span> <span class="n">m2</span><span class="p">,</span> <span class="n">py27plus</span><span class="p">,</span> <span class="n">six</span>
+<span class="k">if</span> <span class="n">py27plus</span><span class="p">:</span>
+ <span class="kn">from</span> <span class="nn">typing</span> <span class="k">import</span> <span class="n">AnyStr</span><span class="p">,</span> <span class="n">Callable</span><span class="p">,</span> <span class="n">Iterable</span><span class="p">,</span> <span class="n">Optional</span><span class="p">,</span> <span class="n">Union</span> <span class="c1"># noqa</span>
+
+<span class="n">log</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s1">&#39;BIO&#39;</span><span class="p">)</span>
+
+
+<div class="viewcode-block" id="BIOError"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.BIO.BIOError">[docs]</a><span class="k">class</span> <span class="nc">BIOError</span><span class="p">(</span><span class="ne">ValueError</span><span class="p">):</span>
+ <span class="k">pass</span></div>
+
+
+<span class="n">m2</span><span class="o">.</span><span class="n">bio_init</span><span class="p">(</span><span class="n">BIOError</span><span class="p">)</span>
+
+
+<div class="viewcode-block" id="BIO"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.BIO.BIO">[docs]</a><span class="k">class</span> <span class="nc">BIO</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Abstract object interface to the BIO API.&quot;&quot;&quot;</span>
+
+ <span class="n">m2_bio_free</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">bio_free</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bio</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">_pyfree</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">_close_cb</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="c1"># type: (Optional[BIO], int, Optional[Callable]) -&gt; None</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">bio</span> <span class="o">=</span> <span class="n">bio</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_pyfree</span> <span class="o">=</span> <span class="n">_pyfree</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_close_cb</span> <span class="o">=</span> <span class="n">_close_cb</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">closed</span> <span class="o">=</span> <span class="mi">0</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">write_closed</span> <span class="o">=</span> <span class="mi">0</span>
+
+ <span class="k">def</span> <span class="nf">__del__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pyfree</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">m2_bio_free</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">bio</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">_ptr</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">bio</span>
+
+ <span class="c1"># Deprecated.</span>
+ <span class="n">bio_ptr</span> <span class="o">=</span> <span class="n">_ptr</span>
+
+<div class="viewcode-block" id="BIO.fileno"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.BIO.BIO.fileno">[docs]</a> <span class="k">def</span> <span class="nf">fileno</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">bio_get_fd</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">bio</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="BIO.readable"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.BIO.BIO.readable">[docs]</a> <span class="k">def</span> <span class="nf">readable</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; bool</span>
+ <span class="k">return</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">closed</span></div>
+
+<div class="viewcode-block" id="BIO.read"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.BIO.BIO.read">[docs]</a> <span class="k">def</span> <span class="nf">read</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">size</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="c1"># type: (int) -&gt; Union[bytes, bytearray]</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">readable</span><span class="p">():</span>
+ <span class="k">raise</span> <span class="ne">IOError</span><span class="p">(</span><span class="s1">&#39;cannot read&#39;</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">size</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">buf</span> <span class="o">=</span> <span class="nb">bytearray</span><span class="p">()</span>
+ <span class="k">while</span> <span class="mi">1</span><span class="p">:</span>
+ <span class="n">data</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">bio_read</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">bio</span><span class="p">,</span> <span class="mi">4096</span><span class="p">)</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">data</span><span class="p">:</span>
+ <span class="k">break</span>
+ <span class="n">buf</span> <span class="o">+=</span> <span class="n">data</span>
+ <span class="k">return</span> <span class="n">buf</span>
+ <span class="k">elif</span> <span class="n">size</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
+ <span class="k">return</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span>
+ <span class="k">elif</span> <span class="n">size</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">&#39;read count is negative&#39;</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">return</span> <span class="nb">bytes</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">bio_read</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">bio</span><span class="p">,</span> <span class="n">size</span><span class="p">))</span></div>
+
+<div class="viewcode-block" id="BIO.readline"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.BIO.BIO.readline">[docs]</a> <span class="k">def</span> <span class="nf">readline</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">size</span><span class="o">=</span><span class="mi">4096</span><span class="p">):</span>
+ <span class="c1"># type: (int) -&gt; bytes</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">readable</span><span class="p">():</span>
+ <span class="k">raise</span> <span class="ne">IOError</span><span class="p">(</span><span class="s1">&#39;cannot read&#39;</span><span class="p">)</span>
+ <span class="n">buf</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">bio_gets</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">bio</span><span class="p">,</span> <span class="n">size</span><span class="p">)</span>
+ <span class="n">buf</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span> <span class="k">if</span> <span class="n">buf</span> <span class="ow">is</span> <span class="kc">None</span> <span class="k">else</span> <span class="n">buf</span>
+ <span class="k">return</span> <span class="n">six</span><span class="o">.</span><span class="n">ensure_binary</span><span class="p">(</span><span class="n">buf</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="BIO.readlines"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.BIO.BIO.readlines">[docs]</a> <span class="k">def</span> <span class="nf">readlines</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">sizehint</span><span class="o">=</span><span class="s1">&#39;ignored&#39;</span><span class="p">):</span>
+ <span class="c1"># type: (Union[AnyStr, int]) -&gt; Iterable[bytes]</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">readable</span><span class="p">():</span>
+ <span class="k">raise</span> <span class="ne">IOError</span><span class="p">(</span><span class="s1">&#39;cannot read&#39;</span><span class="p">)</span>
+ <span class="n">lines</span> <span class="o">=</span> <span class="p">[]</span>
+ <span class="k">while</span> <span class="mi">1</span><span class="p">:</span>
+ <span class="n">buf</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">bio_gets</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">bio</span><span class="p">,</span> <span class="mi">4096</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">buf</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">break</span>
+ <span class="n">lines</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">six</span><span class="o">.</span><span class="n">ensure_binary</span><span class="p">(</span><span class="n">buf</span><span class="p">))</span>
+ <span class="k">return</span> <span class="n">lines</span></div>
+
+<div class="viewcode-block" id="BIO.writeable"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.BIO.BIO.writeable">[docs]</a> <span class="k">def</span> <span class="nf">writeable</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; bool</span>
+ <span class="k">return</span> <span class="p">(</span><span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">closed</span><span class="p">)</span> <span class="ow">and</span> <span class="p">(</span><span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">write_closed</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="BIO.write"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.BIO.BIO.write">[docs]</a> <span class="k">def</span> <span class="nf">write</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;Write data to BIO.</span>
+
+<span class="sd"> :return: either data written, or [0, -1] for nothing written,</span>
+<span class="sd"> -2 not implemented</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">writeable</span><span class="p">():</span>
+ <span class="k">raise</span> <span class="ne">IOError</span><span class="p">(</span><span class="s1">&#39;cannot write&#39;</span><span class="p">)</span>
+ <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">six</span><span class="o">.</span><span class="n">text_type</span><span class="p">):</span>
+ <span class="n">data</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;utf8&#39;</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">bio_write</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">bio</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="BIO.write_close"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.BIO.BIO.write_close">[docs]</a> <span class="k">def</span> <span class="nf">write_close</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">write_closed</span> <span class="o">=</span> <span class="mi">1</span></div>
+
+<div class="viewcode-block" id="BIO.flush"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.BIO.BIO.flush">[docs]</a> <span class="k">def</span> <span class="nf">flush</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;Flush the buffers.</span>
+
+<span class="sd"> :return: 1 for success, and 0 or -1 for failure</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">bio_flush</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">bio</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="BIO.reset"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.BIO.BIO.reset">[docs]</a> <span class="k">def</span> <span class="nf">reset</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;Set the bio to its initial state.</span>
+
+<span class="sd"> :return: 1 for success, and 0 or -1 for failure</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">bio_reset</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">bio</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="BIO.close"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.BIO.BIO.close">[docs]</a> <span class="k">def</span> <span class="nf">close</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">closed</span> <span class="o">=</span> <span class="mi">1</span>
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_close_cb</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_close_cb</span><span class="p">()</span></div>
+
+<div class="viewcode-block" id="BIO.should_retry"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.BIO.BIO.should_retry">[docs]</a> <span class="k">def</span> <span class="nf">should_retry</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Can the call be attempted again, or was there an error</span>
+<span class="sd"> ie do_handshake</span>
+
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">bio_should_retry</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">bio</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="BIO.should_read"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.BIO.BIO.should_read">[docs]</a> <span class="k">def</span> <span class="nf">should_read</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;Should we read more data?&quot;&quot;&quot;</span>
+
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">bio_should_read</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">bio</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="BIO.should_write"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.BIO.BIO.should_write">[docs]</a> <span class="k">def</span> <span class="nf">should_write</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;Should we write more data?&quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">bio_should_write</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">bio</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="BIO.tell"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.BIO.BIO.tell">[docs]</a> <span class="k">def</span> <span class="nf">tell</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Return the current offset.&quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">bio_tell</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">bio</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="BIO.seek"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.BIO.BIO.seek">[docs]</a> <span class="k">def</span> <span class="nf">seek</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">off</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Seek to the specified absolute offset.&quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">bio_seek</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">bio</span><span class="p">,</span> <span class="n">off</span><span class="p">)</span></div>
+
+ <span class="k">def</span> <span class="nf">__enter__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="k">return</span> <span class="bp">self</span>
+
+ <span class="k">def</span> <span class="nf">__exit__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">):</span>
+ <span class="c1"># type: (*Any) -&gt; int</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">close</span><span class="p">()</span></div>
+
+
+<div class="viewcode-block" id="MemoryBuffer"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.BIO.MemoryBuffer">[docs]</a><span class="k">class</span> <span class="nc">MemoryBuffer</span><span class="p">(</span><span class="n">BIO</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Object interface to BIO_s_mem.</span>
+
+<span class="sd"> Empirical testing suggests that this class performs less well than</span>
+<span class="sd"> cStringIO, because cStringIO is implemented in C, whereas this class</span>
+<span class="sd"> is implemented in Python. Thus, the recommended practice is to use</span>
+<span class="sd"> cStringIO for regular work and convert said cStringIO object to</span>
+<span class="sd"> a MemoryBuffer object only when necessary.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="c1"># type: (Optional[bytes]) -&gt; None</span>
+ <span class="nb">super</span><span class="p">(</span><span class="n">MemoryBuffer</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">data</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="nb">bytes</span><span class="p">):</span>
+ <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span>
+ <span class="s2">&quot;data must be bytes or None, not </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="n">data</span><span class="p">)</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span> <span class="p">))</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">bio</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">bio_new</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">bio_s_mem</span><span class="p">())</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_pyfree</span> <span class="o">=</span> <span class="mi">1</span>
+ <span class="k">if</span> <span class="n">data</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">bio_write</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">bio</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">__len__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">bio_ctrl_pending</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">bio</span><span class="p">)</span>
+
+<div class="viewcode-block" id="MemoryBuffer.read"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.BIO.MemoryBuffer.read">[docs]</a> <span class="k">def</span> <span class="nf">read</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">size</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
+ <span class="c1"># type: (int) -&gt; bytes</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">readable</span><span class="p">():</span>
+ <span class="k">raise</span> <span class="ne">IOError</span><span class="p">(</span><span class="s1">&#39;cannot read&#39;</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">size</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">bio_read</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">bio</span><span class="p">,</span> <span class="n">size</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">bio_read</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">bio</span><span class="p">,</span> <span class="n">m2</span><span class="o">.</span><span class="n">bio_ctrl_pending</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">bio</span><span class="p">))</span></div>
+
+ <span class="c1"># Backwards-compatibility.</span>
+ <span class="n">getvalue</span> <span class="o">=</span> <span class="n">read_all</span> <span class="o">=</span> <span class="n">read</span>
+
+<div class="viewcode-block" id="MemoryBuffer.write_close"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.BIO.MemoryBuffer.write_close">[docs]</a> <span class="k">def</span> <span class="nf">write_close</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="nb">super</span><span class="p">(</span><span class="n">MemoryBuffer</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">write_close</span><span class="p">()</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">bio_set_mem_eof_return</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">bio</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span></div>
+
+ <span class="n">close</span> <span class="o">=</span> <span class="n">write_close</span></div>
+
+
+<div class="viewcode-block" id="File"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.BIO.File">[docs]</a><span class="k">class</span> <span class="nc">File</span><span class="p">(</span><span class="n">BIO</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Object interface to BIO_s_pyfd.</span>
+
+<span class="sd"> This class interfaces Python to OpenSSL functions that expect BIO. For</span>
+<span class="sd"> general file manipulation in Python, use Python&#39;s builtin file object.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">pyfile</span><span class="p">,</span> <span class="n">close_pyfile</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="s1">&#39;rb&#39;</span><span class="p">):</span>
+ <span class="c1"># type: (Union[io.BytesIO, AnyStr], int, AnyStr) -&gt; None</span>
+ <span class="nb">super</span><span class="p">(</span><span class="n">File</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">_pyfree</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
+
+ <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">pyfile</span><span class="p">,</span> <span class="n">six</span><span class="o">.</span><span class="n">string_types</span><span class="p">):</span>
+ <span class="n">pyfile</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">pyfile</span><span class="p">,</span> <span class="n">mode</span><span class="p">)</span>
+
+ <span class="c1"># This is for downward compatibility, but I don&#39;t think, that it is</span>
+ <span class="c1"># good practice to have two handles for the same file. Whats about</span>
+ <span class="c1"># concurrent write access? Last write, last wins? Especially since Py3</span>
+ <span class="c1"># has its own buffer management. See:</span>
+ <span class="c1">#</span>
+ <span class="c1"># https://docs.python.org/3.3/c-api/file.html</span>
+ <span class="c1">#</span>
+ <span class="n">pyfile</span><span class="o">.</span><span class="n">flush</span><span class="p">()</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">fname</span> <span class="o">=</span> <span class="n">pyfile</span><span class="o">.</span><span class="n">name</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">pyfile</span> <span class="o">=</span> <span class="n">pyfile</span>
+ <span class="c1"># Be wary of https://github.com/openssl/openssl/pull/1925</span>
+ <span class="c1"># BIO_new_fd is NEVER to be used before OpenSSL 1.1.1</span>
+ <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">m2</span><span class="p">,</span> <span class="s2">&quot;bio_new_pyfd&quot;</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">bio</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">bio_new_pyfd</span><span class="p">(</span><span class="n">pyfile</span><span class="o">.</span><span class="n">fileno</span><span class="p">(),</span> <span class="n">m2</span><span class="o">.</span><span class="n">bio_noclose</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">bio</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">bio_new_pyfile</span><span class="p">(</span><span class="n">pyfile</span><span class="p">,</span> <span class="n">m2</span><span class="o">.</span><span class="n">bio_noclose</span><span class="p">)</span>
+
+ <span class="bp">self</span><span class="o">.</span><span class="n">close_pyfile</span> <span class="o">=</span> <span class="n">close_pyfile</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">closed</span> <span class="o">=</span> <span class="kc">False</span>
+
+<div class="viewcode-block" id="File.flush"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.BIO.File.flush">[docs]</a> <span class="k">def</span> <span class="nf">flush</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="nb">super</span><span class="p">(</span><span class="n">File</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">flush</span><span class="p">()</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">pyfile</span><span class="o">.</span><span class="n">flush</span><span class="p">()</span></div>
+
+<div class="viewcode-block" id="File.close"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.BIO.File.close">[docs]</a> <span class="k">def</span> <span class="nf">close</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">flush</span><span class="p">()</span>
+ <span class="nb">super</span><span class="p">(</span><span class="n">File</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">close_pyfile</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">pyfile</span><span class="o">.</span><span class="n">close</span><span class="p">()</span></div>
+
+<div class="viewcode-block" id="File.reset"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.BIO.File.reset">[docs]</a> <span class="k">def</span> <span class="nf">reset</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;Set the bio to its initial state.</span>
+
+<span class="sd"> :return: 0 for success, and -1 for failure</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="nb">super</span><span class="p">(</span><span class="n">File</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">reset</span><span class="p">()</span></div>
+
+ <span class="k">def</span> <span class="nf">__del__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">closed</span><span class="p">:</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">bio_free</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">bio</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="openfile"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.BIO.openfile">[docs]</a><span class="k">def</span> <span class="nf">openfile</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="s1">&#39;rb&#39;</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr, AnyStr) -&gt; File</span>
+ <span class="k">try</span><span class="p">:</span>
+ <span class="n">f</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="n">mode</span><span class="p">)</span>
+ <span class="k">except</span> <span class="ne">IOError</span> <span class="k">as</span> <span class="n">ex</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="n">BIOError</span><span class="p">(</span><span class="n">ex</span><span class="o">.</span><span class="n">args</span><span class="p">)</span>
+
+ <span class="k">return</span> <span class="n">File</span><span class="p">(</span><span class="n">f</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="IOBuffer"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.BIO.IOBuffer">[docs]</a><span class="k">class</span> <span class="nc">IOBuffer</span><span class="p">(</span><span class="n">BIO</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Object interface to BIO_f_buffer.</span>
+
+<span class="sd"> Its principal function is to be BIO_push()&#39;ed on top of a BIO_f_ssl, so</span>
+<span class="sd"> that makefile() of said underlying SSL socket works.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+
+ <span class="n">m2_bio_pop</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">bio_pop</span>
+ <span class="n">m2_bio_free</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">bio_free</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">under_bio</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="s1">&#39;rwb&#39;</span><span class="p">,</span> <span class="n">_pyfree</span><span class="o">=</span><span class="mi">1</span><span class="p">):</span>
+ <span class="c1"># type: (BIO, str, int) -&gt; None</span>
+ <span class="nb">super</span><span class="p">(</span><span class="n">IOBuffer</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">_pyfree</span><span class="o">=</span><span class="n">_pyfree</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">io</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">bio_new</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">bio_f_buffer</span><span class="p">())</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">bio</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">bio_push</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">io</span><span class="p">,</span> <span class="n">under_bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span>
+ <span class="c1"># This reference keeps the underlying BIO alive while we&#39;re not closed.</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_under_bio</span> <span class="o">=</span> <span class="n">under_bio</span>
+ <span class="k">if</span> <span class="s1">&#39;w&#39;</span> <span class="ow">in</span> <span class="n">mode</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">write_closed</span> <span class="o">=</span> <span class="mi">0</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">write_closed</span> <span class="o">=</span> <span class="mi">1</span>
+
+ <span class="k">def</span> <span class="nf">__del__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;_pyfree&#39;</span><span class="p">,</span> <span class="mi">0</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">m2_bio_pop</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">bio</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">m2_bio_free</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">io</span><span class="p">)</span>
+
+<div class="viewcode-block" id="IOBuffer.close"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.BIO.IOBuffer.close">[docs]</a> <span class="k">def</span> <span class="nf">close</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="n">BIO</span><span class="o">.</span><span class="n">close</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span></div></div>
+
+
+<div class="viewcode-block" id="CipherStream"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.BIO.CipherStream">[docs]</a><span class="k">class</span> <span class="nc">CipherStream</span><span class="p">(</span><span class="n">BIO</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Object interface to BIO_f_cipher.&quot;&quot;&quot;</span>
+
+ <span class="n">SALT_LEN</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">PKCS5_SALT_LEN</span>
+
+ <span class="n">m2_bio_pop</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">bio_pop</span>
+ <span class="n">m2_bio_free</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">bio_free</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obio</span><span class="p">):</span>
+ <span class="c1"># type: (BIO) -&gt; None</span>
+ <span class="nb">super</span><span class="p">(</span><span class="n">CipherStream</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">_pyfree</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">obio</span> <span class="o">=</span> <span class="n">obio</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">bio</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">bio_new</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">bio_f_cipher</span><span class="p">())</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">closed</span> <span class="o">=</span> <span class="mi">0</span>
+
+ <span class="k">def</span> <span class="nf">__del__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;closed&#39;</span><span class="p">,</span> <span class="mi">1</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
+
+<div class="viewcode-block" id="CipherStream.close"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.BIO.CipherStream.close">[docs]</a> <span class="k">def</span> <span class="nf">close</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">m2_bio_pop</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">bio</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">m2_bio_free</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">bio</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">closed</span> <span class="o">=</span> <span class="mi">1</span></div>
+
+<div class="viewcode-block" id="CipherStream.write_close"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.BIO.CipherStream.write_close">[docs]</a> <span class="k">def</span> <span class="nf">write_close</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">obio</span><span class="o">.</span><span class="n">write_close</span><span class="p">()</span></div>
+
+<div class="viewcode-block" id="CipherStream.set_cipher"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.BIO.CipherStream.set_cipher">[docs]</a> <span class="k">def</span> <span class="nf">set_cipher</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">algo</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">iv</span><span class="p">,</span> <span class="n">op</span><span class="p">):</span>
+ <span class="c1"># type: (str, AnyStr, AnyStr, int) -&gt; None</span>
+ <span class="n">cipher</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">m2</span><span class="p">,</span> <span class="n">algo</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">cipher</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">&#39;unknown cipher&#39;</span><span class="p">,</span> <span class="n">algo</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="nb">bytes</span><span class="p">):</span>
+ <span class="n">key</span> <span class="o">=</span> <span class="n">key</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;utf8&#39;</span><span class="p">)</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">iv</span><span class="p">,</span> <span class="nb">bytes</span><span class="p">):</span>
+ <span class="n">iv</span> <span class="o">=</span> <span class="n">iv</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;utf8&#39;</span><span class="p">)</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">bio_set_cipher</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">bio</span><span class="p">,</span> <span class="n">cipher</span><span class="p">(),</span> <span class="n">key</span><span class="p">,</span> <span class="n">iv</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">op</span><span class="p">))</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">bio_push</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">bio</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">obio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span></div></div>
+
+
+<div class="viewcode-block" id="SSLBio"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.BIO.SSLBio">[docs]</a><span class="k">class</span> <span class="nc">SSLBio</span><span class="p">(</span><span class="n">BIO</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Object interface to BIO_f_ssl.&quot;&quot;&quot;</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">_pyfree</span><span class="o">=</span><span class="mi">1</span><span class="p">):</span>
+ <span class="c1"># type: (int) -&gt; None</span>
+ <span class="nb">super</span><span class="p">(</span><span class="n">SSLBio</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">_pyfree</span><span class="o">=</span><span class="n">_pyfree</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">bio</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">bio_new</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">bio_f_ssl</span><span class="p">())</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">closed</span> <span class="o">=</span> <span class="mi">0</span>
+
+<div class="viewcode-block" id="SSLBio.set_ssl"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.BIO.SSLBio.set_ssl">[docs]</a> <span class="k">def</span> <span class="nf">set_ssl</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">conn</span><span class="p">,</span> <span class="n">close_flag</span><span class="o">=</span><span class="n">m2</span><span class="o">.</span><span class="n">bio_noclose</span><span class="p">):</span>
+ <span class="c1"># type: (Connection, int) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Sets the bio to the SSL pointer which is</span>
+<span class="sd"> contained in the connection object.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_pyfree</span> <span class="o">=</span> <span class="mi">0</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">bio_set_ssl</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">bio</span><span class="p">,</span> <span class="n">conn</span><span class="o">.</span><span class="n">ssl</span><span class="p">,</span> <span class="n">close_flag</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">close_flag</span> <span class="o">==</span> <span class="n">m2</span><span class="o">.</span><span class="n">bio_noclose</span><span class="p">:</span>
+ <span class="n">conn</span><span class="o">.</span><span class="n">set_ssl_close_flag</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">bio_close</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="SSLBio.do_handshake"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.BIO.SSLBio.do_handshake">[docs]</a> <span class="k">def</span> <span class="nf">do_handshake</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;Do the handshake.</span>
+
+<span class="sd"> Return 1 if the handshake completes</span>
+<span class="sd"> Return 0 or a negative number if there is a problem</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">bio_do_handshake</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">bio</span><span class="p">)</span></div></div>
+</pre></div>
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="../../index.html">M2Crypto</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="../../M2Crypto.html">M2Crypto Package</a></li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="../../index.html">Documentation overview</a><ul>
+ <li><a href="../index.html">Module code</a><ul>
+ </ul></li>
+ </ul></li>
+</ul>
+</div>
+<div id="searchbox" style="display: none" role="search">
+ <h3>Quick search</h3>
+ <div class="searchformwrapper">
+ <form class="search" action="../../search.html" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ </div>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer">
+ &copy;2017, Matej Cepl <mcepl@cepl.eu>.
+
+ |
+ Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
+ &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
+
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/_modules/M2Crypto/BN.html b/doc/html/_modules/M2Crypto/BN.html
new file mode 100644
index 0000000..b8287fb
--- /dev/null
+++ b/doc/html/_modules/M2Crypto/BN.html
@@ -0,0 +1,162 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>M2Crypto.BN &#8212; M2Crypto documentation</title>
+ <link rel="stylesheet" href="../../_static/alabaster.css" type="text/css" />
+ <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../../_static/jquery.js"></script>
+ <script type="text/javascript" src="../../_static/underscore.js"></script>
+ <script type="text/javascript" src="../../_static/doctools.js"></script>
+ <script type="text/javascript" src="../../_static/language_data.js"></script>
+ <link rel="index" title="Index" href="../../genindex.html" />
+ <link rel="search" title="Search" href="../../search.html" />
+
+ <link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+ <h1>Source code for M2Crypto.BN</h1><div class="highlight"><pre>
+<span></span><span class="kn">from</span> <span class="nn">__future__</span> <span class="k">import</span> <span class="n">absolute_import</span>
+
+<span class="sd">&quot;&quot;&quot;</span>
+<span class="sd">M2Crypto wrapper for OpenSSL BN (BIGNUM) API.</span>
+
+<span class="sd">Copyright (c) 2005 Open Source Applications Foundation. All rights reserved.</span>
+<span class="sd">&quot;&quot;&quot;</span>
+
+<span class="kn">from</span> <span class="nn">M2Crypto</span> <span class="k">import</span> <span class="n">m2</span><span class="p">,</span> <span class="n">util</span>
+<span class="k">if</span> <span class="n">util</span><span class="o">.</span><span class="n">py27plus</span><span class="p">:</span>
+ <span class="kn">from</span> <span class="nn">typing</span> <span class="k">import</span> <span class="n">Optional</span> <span class="c1"># noqa</span>
+
+
+<div class="viewcode-block" id="rand"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.BN.rand">[docs]</a><span class="k">def</span> <span class="nf">rand</span><span class="p">(</span><span class="n">bits</span><span class="p">,</span> <span class="n">top</span><span class="o">=-</span><span class="mi">1</span><span class="p">,</span> <span class="n">bottom</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
+ <span class="c1"># type: (int, int, int) -&gt; Optional[int]</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Generate cryptographically strong random number.</span>
+
+<span class="sd"> :param bits: Length of random number in bits.</span>
+<span class="sd"> :param top: If -1, the most significant bit can be 0. If 0, the most</span>
+<span class="sd"> significant bit is 1, and if 1, the two most significant</span>
+<span class="sd"> bits will be 1.</span>
+<span class="sd"> :param bottom: If bottom is true, the number will be odd.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">bn_rand</span><span class="p">(</span><span class="n">bits</span><span class="p">,</span> <span class="n">top</span><span class="p">,</span> <span class="n">bottom</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="rand_range"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.BN.rand_range">[docs]</a><span class="k">def</span> <span class="nf">rand_range</span><span class="p">(</span><span class="nb">range</span><span class="p">):</span>
+ <span class="c1"># type: (int) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Generate a random number in a range.</span>
+
+<span class="sd"> :param range: Upper limit for range.</span>
+<span class="sd"> :return: A random number in the range [0, range)</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">bn_rand_range</span><span class="p">(</span><span class="nb">range</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="randfname"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.BN.randfname">[docs]</a><span class="k">def</span> <span class="nf">randfname</span><span class="p">(</span><span class="n">length</span><span class="p">):</span>
+ <span class="c1"># type: (int) -&gt; str</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Return a random filename, which is simply a string where all</span>
+<span class="sd"> the characters are from the set [a-zA-Z0-9].</span>
+
+<span class="sd"> :param length: Length of filename to return.</span>
+<span class="sd"> :return: random filename string</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="kn">import</span> <span class="nn">warnings</span>
+ <span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span>
+ <span class="s2">&quot;Don&#39;t use BN.randfname(), use tempfile methods instead.&quot;</span><span class="p">,</span>
+ <span class="ne">DeprecationWarning</span><span class="p">,</span> <span class="n">stacklevel</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
+ <span class="n">letters</span> <span class="o">=</span> <span class="s1">&#39;abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890&#39;</span>
+ <span class="n">lettersLen</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">letters</span><span class="p">)</span>
+ <span class="n">fname</span> <span class="o">=</span> <span class="p">[]</span> <span class="c1"># type: list</span>
+ <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">length</span><span class="p">):</span>
+ <span class="n">fname</span> <span class="o">+=</span> <span class="p">[</span><span class="n">letters</span><span class="p">[</span><span class="n">m2</span><span class="o">.</span><span class="n">bn_rand_range</span><span class="p">(</span><span class="n">lettersLen</span><span class="p">)]]</span>
+
+ <span class="k">return</span> <span class="s1">&#39;&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">fname</span><span class="p">)</span></div>
+</pre></div>
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="../../index.html">M2Crypto</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="../../M2Crypto.html">M2Crypto Package</a></li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="../../index.html">Documentation overview</a><ul>
+ <li><a href="../index.html">Module code</a><ul>
+ </ul></li>
+ </ul></li>
+</ul>
+</div>
+<div id="searchbox" style="display: none" role="search">
+ <h3>Quick search</h3>
+ <div class="searchformwrapper">
+ <form class="search" action="../../search.html" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ </div>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer">
+ &copy;2017, Matej Cepl <mcepl@cepl.eu>.
+
+ |
+ Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
+ &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
+
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/_modules/M2Crypto/DH.html b/doc/html/_modules/M2Crypto/DH.html
new file mode 100644
index 0000000..0e6d33a
--- /dev/null
+++ b/doc/html/_modules/M2Crypto/DH.html
@@ -0,0 +1,217 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>M2Crypto.DH &#8212; M2Crypto documentation</title>
+ <link rel="stylesheet" href="../../_static/alabaster.css" type="text/css" />
+ <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../../_static/jquery.js"></script>
+ <script type="text/javascript" src="../../_static/underscore.js"></script>
+ <script type="text/javascript" src="../../_static/doctools.js"></script>
+ <script type="text/javascript" src="../../_static/language_data.js"></script>
+ <link rel="index" title="Index" href="../../genindex.html" />
+ <link rel="search" title="Search" href="../../search.html" />
+
+ <link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+ <h1>Source code for M2Crypto.DH</h1><div class="highlight"><pre>
+<span></span><span class="kn">from</span> <span class="nn">__future__</span> <span class="k">import</span> <span class="n">absolute_import</span>
+
+<span class="sd">&quot;&quot;&quot;M2Crypto wrapper for OpenSSL DH API.</span>
+
+<span class="sd">Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved.&quot;&quot;&quot;</span>
+
+<span class="kn">from</span> <span class="nn">M2Crypto</span> <span class="k">import</span> <span class="n">BIO</span><span class="p">,</span> <span class="n">m2</span><span class="p">,</span> <span class="n">util</span>
+<span class="kn">from</span> <span class="nn">M2Crypto.util</span> <span class="k">import</span> <span class="n">genparam_callback</span>
+<span class="k">if</span> <span class="n">util</span><span class="o">.</span><span class="n">py27plus</span><span class="p">:</span>
+ <span class="kn">from</span> <span class="nn">typing</span> <span class="k">import</span> <span class="n">AnyStr</span><span class="p">,</span> <span class="n">Callable</span> <span class="c1"># noqa</span>
+
+
+<div class="viewcode-block" id="DHError"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.DH.DHError">[docs]</a><span class="k">class</span> <span class="nc">DHError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
+ <span class="k">pass</span></div>
+
+<span class="n">m2</span><span class="o">.</span><span class="n">dh_init</span><span class="p">(</span><span class="n">DHError</span><span class="p">)</span>
+
+
+<div class="viewcode-block" id="DH"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.DH.DH">[docs]</a><span class="k">class</span> <span class="nc">DH</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Object interface to the Diffie-Hellman key exchange protocol.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+
+ <span class="n">m2_dh_free</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">dh_free</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">dh</span><span class="p">,</span> <span class="n">_pyfree</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
+ <span class="c1"># type: (bytes, int) -&gt; None</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">dh_type_check</span><span class="p">(</span><span class="n">dh</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">dh</span> <span class="o">=</span> <span class="n">dh</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_pyfree</span> <span class="o">=</span> <span class="n">_pyfree</span>
+
+ <span class="k">def</span> <span class="nf">__del__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;_pyfree&#39;</span><span class="p">,</span> <span class="mi">0</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">m2_dh_free</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dh</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">__len__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">dh_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dh</span><span class="p">),</span> <span class="s2">&quot;&#39;dh&#39; type error&quot;</span>
+ <span class="k">return</span> <span class="nb">int</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">dh_size</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dh</span><span class="p">))</span>
+
+ <span class="k">def</span> <span class="nf">__getattr__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
+ <span class="c1"># type: (str) -&gt; bytes</span>
+ <span class="k">if</span> <span class="n">name</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">&#39;p&#39;</span><span class="p">,</span> <span class="s1">&#39;g&#39;</span><span class="p">,</span> <span class="s1">&#39;pub&#39;</span><span class="p">,</span> <span class="s1">&#39;priv&#39;</span><span class="p">):</span>
+ <span class="n">method</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">m2</span><span class="p">,</span> <span class="s1">&#39;dh_get_</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">name</span><span class="p">,))</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">dh_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dh</span><span class="p">),</span> <span class="s2">&quot;&#39;dh&#39; type error&quot;</span>
+ <span class="k">return</span> <span class="n">method</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dh</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">AttributeError</span>
+
+ <span class="k">def</span> <span class="nf">__setattr__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
+ <span class="c1"># type: (str, bytes) -&gt; bytes</span>
+ <span class="k">if</span> <span class="n">name</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">&#39;p&#39;</span><span class="p">,</span> <span class="s1">&#39;g&#39;</span><span class="p">):</span>
+ <span class="k">raise</span> <span class="n">DHError</span><span class="p">(</span><span class="s1">&#39;set (p, g) via set_params()&#39;</span><span class="p">)</span>
+ <span class="k">elif</span> <span class="n">name</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">&#39;pub&#39;</span><span class="p">,</span> <span class="s1">&#39;priv&#39;</span><span class="p">):</span>
+ <span class="k">raise</span> <span class="n">DHError</span><span class="p">(</span><span class="s1">&#39;generate (pub, priv) via gen_key()&#39;</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="vm">__dict__</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span>
+
+ <span class="k">def</span> <span class="nf">_ptr</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">dh</span>
+
+<div class="viewcode-block" id="DH.check_params"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.DH.DH.check_params">[docs]</a> <span class="k">def</span> <span class="nf">check_params</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">dh_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dh</span><span class="p">),</span> <span class="s2">&quot;&#39;dh&#39; type error&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">dh_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dh</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="DH.gen_key"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.DH.DH.gen_key">[docs]</a> <span class="k">def</span> <span class="nf">gen_key</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">dh_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dh</span><span class="p">),</span> <span class="s2">&quot;&#39;dh&#39; type error&quot;</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">dh_generate_key</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dh</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="DH.compute_key"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.DH.DH.compute_key">[docs]</a> <span class="k">def</span> <span class="nf">compute_key</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">pubkey</span><span class="p">):</span>
+ <span class="c1"># type: (bytes) -&gt; bytes</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">dh_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dh</span><span class="p">),</span> <span class="s2">&quot;&#39;dh&#39; type error&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">dh_compute_key</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dh</span><span class="p">,</span> <span class="n">pubkey</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="DH.print_params"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.DH.DH.print_params">[docs]</a> <span class="k">def</span> <span class="nf">print_params</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bio</span><span class="p">):</span>
+ <span class="c1"># type: (BIO.BIO) -&gt; int</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">dh_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dh</span><span class="p">),</span> <span class="s2">&quot;&#39;dh&#39; type error&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">dhparams_print</span><span class="p">(</span><span class="n">bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span> <span class="bp">self</span><span class="o">.</span><span class="n">dh</span><span class="p">)</span></div></div>
+
+
+<div class="viewcode-block" id="gen_params"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.DH.gen_params">[docs]</a><span class="k">def</span> <span class="nf">gen_params</span><span class="p">(</span><span class="n">plen</span><span class="p">,</span> <span class="n">g</span><span class="p">,</span> <span class="n">callback</span><span class="o">=</span><span class="n">genparam_callback</span><span class="p">):</span>
+ <span class="c1"># type: (int, int, Optional[Callable]) -&gt; DH</span>
+ <span class="n">dh_parms</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">dh_generate_parameters</span><span class="p">(</span><span class="n">plen</span><span class="p">,</span> <span class="n">g</span><span class="p">,</span> <span class="n">callback</span><span class="p">)</span>
+ <span class="n">dh_obj</span> <span class="o">=</span> <span class="n">DH</span><span class="p">(</span><span class="n">dh_parms</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">dh_obj</span></div>
+
+
+<div class="viewcode-block" id="load_params"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.DH.load_params">[docs]</a><span class="k">def</span> <span class="nf">load_params</span><span class="p">(</span><span class="n">file</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr) -&gt; DH</span>
+ <span class="k">with</span> <span class="n">BIO</span><span class="o">.</span><span class="n">openfile</span><span class="p">(</span><span class="n">file</span><span class="p">)</span> <span class="k">as</span> <span class="n">bio</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">load_params_bio</span><span class="p">(</span><span class="n">bio</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="load_params_bio"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.DH.load_params_bio">[docs]</a><span class="k">def</span> <span class="nf">load_params_bio</span><span class="p">(</span><span class="n">bio</span><span class="p">):</span>
+ <span class="c1"># type: (BIO.BIO) -&gt; DH</span>
+ <span class="k">return</span> <span class="n">DH</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">dh_read_parameters</span><span class="p">(</span><span class="n">bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">()),</span> <span class="mi">1</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="set_params"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.DH.set_params">[docs]</a><span class="k">def</span> <span class="nf">set_params</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
+ <span class="c1"># type: (bytes, bytes) -&gt; DH</span>
+ <span class="n">dh</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">dh_new</span><span class="p">()</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">dh_set_pg</span><span class="p">(</span><span class="n">dh</span><span class="p">,</span> <span class="n">p</span><span class="p">,</span> <span class="n">g</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">DH</span><span class="p">(</span><span class="n">dh</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span></div>
+
+
+<span class="c1"># def free_params(cptr):</span>
+<span class="c1"># m2.dh_free(cptr)</span>
+
+
+<span class="n">DH_GENERATOR_2</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">DH_GENERATOR_2</span>
+<span class="n">DH_GENERATOR_5</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">DH_GENERATOR_5</span>
+</pre></div>
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="../../index.html">M2Crypto</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="../../M2Crypto.html">M2Crypto Package</a></li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="../../index.html">Documentation overview</a><ul>
+ <li><a href="../index.html">Module code</a><ul>
+ </ul></li>
+ </ul></li>
+</ul>
+</div>
+<div id="searchbox" style="display: none" role="search">
+ <h3>Quick search</h3>
+ <div class="searchformwrapper">
+ <form class="search" action="../../search.html" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ </div>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer">
+ &copy;2017, Matej Cepl <mcepl@cepl.eu>.
+
+ |
+ Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
+ &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
+
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/_modules/M2Crypto/DSA.html b/doc/html/_modules/M2Crypto/DSA.html
new file mode 100644
index 0000000..6d97c52
--- /dev/null
+++ b/doc/html/_modules/M2Crypto/DSA.html
@@ -0,0 +1,552 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>M2Crypto.DSA &#8212; M2Crypto documentation</title>
+ <link rel="stylesheet" href="../../_static/alabaster.css" type="text/css" />
+ <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../../_static/jquery.js"></script>
+ <script type="text/javascript" src="../../_static/underscore.js"></script>
+ <script type="text/javascript" src="../../_static/doctools.js"></script>
+ <script type="text/javascript" src="../../_static/language_data.js"></script>
+ <link rel="index" title="Index" href="../../genindex.html" />
+ <link rel="search" title="Search" href="../../search.html" />
+
+ <link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+ <h1>Source code for M2Crypto.DSA</h1><div class="highlight"><pre>
+<span></span><span class="kn">from</span> <span class="nn">__future__</span> <span class="k">import</span> <span class="n">absolute_import</span><span class="p">,</span> <span class="n">print_function</span>
+
+<span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> M2Crypto wrapper for OpenSSL DSA API.</span>
+
+<span class="sd"> Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved.</span>
+
+<span class="sd"> Portions created by Open Source Applications Foundation (OSAF) are</span>
+<span class="sd"> Copyright (C) 2004 OSAF. All Rights Reserved.</span>
+<span class="sd">&quot;&quot;&quot;</span>
+
+<span class="kn">from</span> <span class="nn">M2Crypto</span> <span class="k">import</span> <span class="n">BIO</span><span class="p">,</span> <span class="n">m2</span><span class="p">,</span> <span class="n">util</span>
+<span class="k">if</span> <span class="n">util</span><span class="o">.</span><span class="n">py27plus</span><span class="p">:</span>
+ <span class="kn">from</span> <span class="nn">typing</span> <span class="k">import</span> <span class="n">AnyStr</span><span class="p">,</span> <span class="n">Callable</span><span class="p">,</span> <span class="n">Tuple</span> <span class="c1"># noqa</span>
+
+
+<div class="viewcode-block" id="DSAError"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.DSA.DSAError">[docs]</a><span class="k">class</span> <span class="nc">DSAError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
+ <span class="k">pass</span></div>
+
+<span class="n">m2</span><span class="o">.</span><span class="n">dsa_init</span><span class="p">(</span><span class="n">DSAError</span><span class="p">)</span>
+
+
+<div class="viewcode-block" id="DSA"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.DSA.DSA">[docs]</a><span class="k">class</span> <span class="nc">DSA</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> This class is a context supporting DSA key and parameter</span>
+<span class="sd"> values, signing and verifying.</span>
+
+<span class="sd"> Simple example::</span>
+
+<span class="sd"> from M2Crypto import EVP, DSA, util</span>
+
+<span class="sd"> message = &#39;Kilroy was here!&#39;</span>
+<span class="sd"> md = EVP.MessageDigest(&#39;sha1&#39;)</span>
+<span class="sd"> md.update(message)</span>
+<span class="sd"> digest = md.final()</span>
+
+<span class="sd"> dsa = DSA.gen_params(1024)</span>
+<span class="sd"> dsa.gen_key()</span>
+<span class="sd"> r, s = dsa.sign(digest)</span>
+<span class="sd"> good = dsa.verify(digest, r, s)</span>
+<span class="sd"> if good:</span>
+<span class="sd"> print(&#39; ** success **&#39;)</span>
+<span class="sd"> else:</span>
+<span class="sd"> print(&#39; ** verification failed **&#39;)</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+
+ <span class="n">m2_dsa_free</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">dsa_free</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">dsa</span><span class="p">,</span> <span class="n">_pyfree</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
+ <span class="c1"># type: (bytes, int) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Use one of the factory functions to create an instance.</span>
+<span class="sd"> :param dsa: binary representation of OpenSSL DSA type</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">dsa_type_check</span><span class="p">(</span><span class="n">dsa</span><span class="p">),</span> <span class="s2">&quot;&#39;dsa&#39; type error&quot;</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">dsa</span> <span class="o">=</span> <span class="n">dsa</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_pyfree</span> <span class="o">=</span> <span class="n">_pyfree</span>
+
+ <span class="k">def</span> <span class="nf">__del__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;_pyfree&#39;</span><span class="p">,</span> <span class="mi">0</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">m2_dsa_free</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dsa</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">__len__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Return the key length.</span>
+
+<span class="sd"> :return: the DSA key length in bits</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">dsa_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dsa</span><span class="p">),</span> <span class="s2">&quot;&#39;dsa&#39; type error&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">dsa_keylen</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dsa</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">__getattr__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
+ <span class="c1"># type: (str) -&gt; bytes</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Return specified DSA parameters and key values.</span>
+
+<span class="sd"> :param name: name of variable to be returned. Must be</span>
+<span class="sd"> one of &#39;p&#39;, &#39;q&#39;, &#39;g&#39;, &#39;pub&#39;, &#39;priv&#39;.</span>
+<span class="sd"> :return: value of specified variable (a &quot;byte string&quot;)</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">if</span> <span class="n">name</span> <span class="ow">in</span> <span class="p">[</span><span class="s1">&#39;p&#39;</span><span class="p">,</span> <span class="s1">&#39;q&#39;</span><span class="p">,</span> <span class="s1">&#39;g&#39;</span><span class="p">,</span> <span class="s1">&#39;pub&#39;</span><span class="p">,</span> <span class="s1">&#39;priv&#39;</span><span class="p">]:</span>
+ <span class="n">method</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">m2</span><span class="p">,</span> <span class="s1">&#39;dsa_get_</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">name</span><span class="p">,))</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">dsa_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dsa</span><span class="p">),</span> <span class="s2">&quot;&#39;dsa&#39; type error&quot;</span>
+ <span class="k">return</span> <span class="n">method</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dsa</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">AttributeError</span>
+
+ <span class="k">def</span> <span class="nf">__setattr__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
+ <span class="c1"># type: (str, bytes) -&gt; None</span>
+ <span class="k">if</span> <span class="n">name</span> <span class="ow">in</span> <span class="p">[</span><span class="s1">&#39;p&#39;</span><span class="p">,</span> <span class="s1">&#39;q&#39;</span><span class="p">,</span> <span class="s1">&#39;g&#39;</span><span class="p">]:</span>
+ <span class="k">raise</span> <span class="n">DSAError</span><span class="p">(</span><span class="s1">&#39;set (p, q, g) via set_params()&#39;</span><span class="p">)</span>
+ <span class="k">elif</span> <span class="n">name</span> <span class="ow">in</span> <span class="p">[</span><span class="s1">&#39;pub&#39;</span><span class="p">,</span> <span class="s1">&#39;priv&#39;</span><span class="p">]:</span>
+ <span class="k">raise</span> <span class="n">DSAError</span><span class="p">(</span><span class="s1">&#39;generate (pub, priv) via gen_key()&#39;</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="vm">__dict__</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span>
+
+<div class="viewcode-block" id="DSA.set_params"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.DSA.DSA.set_params">[docs]</a> <span class="k">def</span> <span class="nf">set_params</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">p</span><span class="p">,</span> <span class="n">q</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
+ <span class="c1"># type: (bytes, bytes, bytes) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Set new parameters.</span>
+
+<span class="sd"> :param p: MPI binary representation ... format that consists of</span>
+<span class="sd"> the number&#39;s length in bytes represented as a 4-byte</span>
+<span class="sd"> big-endian number, and the number itself in big-endian</span>
+<span class="sd"> format, where the most significant bit signals</span>
+<span class="sd"> a negative number (the representation of numbers with</span>
+<span class="sd"> the MSB set is prefixed with null byte).</span>
+<span class="sd"> :param q: ditto</span>
+<span class="sd"> :param g: ditto</span>
+
+<span class="sd"> @warning: This does not change the private key, so it may be</span>
+<span class="sd"> unsafe to use this method. It is better to use</span>
+<span class="sd"> gen_params function to create a new DSA object.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">dsa_set_pqg</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dsa</span><span class="p">,</span> <span class="n">p</span><span class="p">,</span> <span class="n">q</span><span class="p">,</span> <span class="n">g</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="DSA.gen_key"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.DSA.DSA.gen_key">[docs]</a> <span class="k">def</span> <span class="nf">gen_key</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Generate a key pair.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">dsa_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dsa</span><span class="p">),</span> <span class="s2">&quot;&#39;dsa&#39; type error&quot;</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">dsa_gen_key</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dsa</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="DSA.save_params"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.DSA.DSA.save_params">[docs]</a> <span class="k">def</span> <span class="nf">save_params</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">filename</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Save the DSA parameters to a file.</span>
+
+<span class="sd"> :param filename: Save the DSA parameters to this file.</span>
+<span class="sd"> :return: 1 (true) if successful</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">with</span> <span class="n">BIO</span><span class="o">.</span><span class="n">openfile</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="s1">&#39;wb&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">bio</span><span class="p">:</span>
+ <span class="n">ret</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">dsa_write_params_bio</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dsa</span><span class="p">,</span> <span class="n">bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span>
+
+ <span class="k">return</span> <span class="n">ret</span></div>
+
+<div class="viewcode-block" id="DSA.save_params_bio"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.DSA.DSA.save_params_bio">[docs]</a> <span class="k">def</span> <span class="nf">save_params_bio</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bio</span><span class="p">):</span>
+ <span class="c1"># type: (BIO.BIO) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Save DSA parameters to a BIO object.</span>
+
+<span class="sd"> :param bio: Save DSA parameters to this object.</span>
+<span class="sd"> :return: 1 (true) if successful</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">dsa_write_params_bio</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dsa</span><span class="p">,</span> <span class="n">bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span></div>
+
+<div class="viewcode-block" id="DSA.save_key"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.DSA.DSA.save_key">[docs]</a> <span class="k">def</span> <span class="nf">save_key</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="n">cipher</span><span class="o">=</span><span class="s1">&#39;aes_128_cbc&#39;</span><span class="p">,</span>
+ <span class="n">callback</span><span class="o">=</span><span class="n">util</span><span class="o">.</span><span class="n">passphrase_callback</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr, str, Callable) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Save the DSA key pair to a file.</span>
+
+<span class="sd"> :param filename: Save the DSA key pair to this file.</span>
+<span class="sd"> :param cipher: name of symmetric key algorithm and mode</span>
+<span class="sd"> to encrypt the private key.</span>
+<span class="sd"> :return: 1 (true) if successful</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">with</span> <span class="n">BIO</span><span class="o">.</span><span class="n">openfile</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="s1">&#39;wb&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">bio</span><span class="p">:</span>
+ <span class="n">ret</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">save_key_bio</span><span class="p">(</span><span class="n">bio</span><span class="p">,</span> <span class="n">cipher</span><span class="p">,</span> <span class="n">callback</span><span class="p">)</span>
+
+ <span class="k">return</span> <span class="n">ret</span></div>
+
+<div class="viewcode-block" id="DSA.save_key_bio"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.DSA.DSA.save_key_bio">[docs]</a> <span class="k">def</span> <span class="nf">save_key_bio</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bio</span><span class="p">,</span> <span class="n">cipher</span><span class="o">=</span><span class="s1">&#39;aes_128_cbc&#39;</span><span class="p">,</span>
+ <span class="n">callback</span><span class="o">=</span><span class="n">util</span><span class="o">.</span><span class="n">passphrase_callback</span><span class="p">):</span>
+ <span class="c1"># type: (BIO.BIO, str, Callable) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Save DSA key pair to a BIO object.</span>
+
+<span class="sd"> :param bio: Save DSA parameters to this object.</span>
+<span class="sd"> :param cipher: name of symmetric key algorithm and mode</span>
+<span class="sd"> to encrypt the private key.</span>
+<span class="sd"> :return: 1 (true) if successful</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">if</span> <span class="n">cipher</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">dsa_write_key_bio_no_cipher</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dsa</span><span class="p">,</span>
+ <span class="n">bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span> <span class="n">callback</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">ciph</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">m2</span><span class="p">,</span> <span class="n">cipher</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">ciph</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="n">DSAError</span><span class="p">(</span><span class="s1">&#39;no such cipher: </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">cipher</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">ciph</span> <span class="o">=</span> <span class="n">ciph</span><span class="p">()</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">dsa_write_key_bio</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dsa</span><span class="p">,</span> <span class="n">bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span> <span class="n">ciph</span><span class="p">,</span> <span class="n">callback</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="DSA.save_pub_key"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.DSA.DSA.save_pub_key">[docs]</a> <span class="k">def</span> <span class="nf">save_pub_key</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">filename</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Save the DSA public key (with parameters) to a file.</span>
+
+<span class="sd"> :param filename: Save DSA public key (with parameters)</span>
+<span class="sd"> to this file.</span>
+<span class="sd"> :return: 1 (true) if successful</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">with</span> <span class="n">BIO</span><span class="o">.</span><span class="n">openfile</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="s1">&#39;wb&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">bio</span><span class="p">:</span>
+ <span class="n">ret</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">save_pub_key_bio</span><span class="p">(</span><span class="n">bio</span><span class="p">)</span>
+
+ <span class="k">return</span> <span class="n">ret</span></div>
+
+<div class="viewcode-block" id="DSA.save_pub_key_bio"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.DSA.DSA.save_pub_key_bio">[docs]</a> <span class="k">def</span> <span class="nf">save_pub_key_bio</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bio</span><span class="p">):</span>
+ <span class="c1"># type: (BIO.BIO) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Save DSA public key (with parameters) to a BIO object.</span>
+
+<span class="sd"> :param bio: Save DSA public key (with parameters)</span>
+<span class="sd"> to this object.</span>
+<span class="sd"> :return: 1 (true) if successful</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">dsa_write_pub_key_bio</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dsa</span><span class="p">,</span> <span class="n">bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span></div>
+
+<div class="viewcode-block" id="DSA.sign"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.DSA.DSA.sign">[docs]</a> <span class="k">def</span> <span class="nf">sign</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">digest</span><span class="p">):</span>
+ <span class="c1"># type: (bytes) -&gt; Tuple[bytes, bytes]</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Sign the digest.</span>
+
+<span class="sd"> :param digest: SHA-1 hash of message (same as output</span>
+<span class="sd"> from MessageDigest, a &quot;byte string&quot;)</span>
+<span class="sd"> :return: DSA signature, a tuple of two values, r and s,</span>
+<span class="sd"> both &quot;byte strings&quot;.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">check_key</span><span class="p">(),</span> <span class="s1">&#39;key is not initialised&#39;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">dsa_sign</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dsa</span><span class="p">,</span> <span class="n">digest</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="DSA.verify"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.DSA.DSA.verify">[docs]</a> <span class="k">def</span> <span class="nf">verify</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">digest</span><span class="p">,</span> <span class="n">r</span><span class="p">,</span> <span class="n">s</span><span class="p">):</span>
+ <span class="c1"># type: (bytes, bytes, bytes) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Verify a newly calculated digest against the signature</span>
+<span class="sd"> values r and s.</span>
+
+<span class="sd"> :param digest: SHA-1 hash of message (same as output</span>
+<span class="sd"> from MessageDigest, a &quot;byte string&quot;)</span>
+<span class="sd"> :param r: r value of the signature, a &quot;byte string&quot;</span>
+<span class="sd"> :param s: s value of the signature, a &quot;byte string&quot;</span>
+<span class="sd"> :return: 1 (true) if verify succeeded, 0 if failed</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">check_key</span><span class="p">(),</span> <span class="s1">&#39;key is not initialised&#39;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">dsa_verify</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dsa</span><span class="p">,</span> <span class="n">digest</span><span class="p">,</span> <span class="n">r</span><span class="p">,</span> <span class="n">s</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="DSA.sign_asn1"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.DSA.DSA.sign_asn1">[docs]</a> <span class="k">def</span> <span class="nf">sign_asn1</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">digest</span><span class="p">):</span>
+ <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">check_key</span><span class="p">(),</span> <span class="s1">&#39;key is not initialised&#39;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">dsa_sign_asn1</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dsa</span><span class="p">,</span> <span class="n">digest</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="DSA.verify_asn1"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.DSA.DSA.verify_asn1">[docs]</a> <span class="k">def</span> <span class="nf">verify_asn1</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">digest</span><span class="p">,</span> <span class="n">blob</span><span class="p">):</span>
+ <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">check_key</span><span class="p">(),</span> <span class="s1">&#39;key is not initialised&#39;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">dsa_verify_asn1</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dsa</span><span class="p">,</span> <span class="n">digest</span><span class="p">,</span> <span class="n">blob</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="DSA.check_key"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.DSA.DSA.check_key">[docs]</a> <span class="k">def</span> <span class="nf">check_key</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Check to be sure the DSA object has a valid private key.</span>
+
+<span class="sd"> :return: 1 (true) if a valid private key</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">dsa_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dsa</span><span class="p">),</span> <span class="s2">&quot;&#39;dsa&#39; type error&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">dsa_check_key</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dsa</span><span class="p">)</span></div></div>
+
+
+<div class="viewcode-block" id="DSA_pub"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.DSA.DSA_pub">[docs]</a><span class="k">class</span> <span class="nc">DSA_pub</span><span class="p">(</span><span class="n">DSA</span><span class="p">):</span>
+
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> This class is a DSA context that only supports a public key</span>
+<span class="sd"> and verification. It does NOT support a private key or</span>
+<span class="sd"> signing.</span>
+
+<span class="sd"> &quot;&quot;&quot;</span>
+
+<div class="viewcode-block" id="DSA_pub.sign"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.DSA.DSA_pub.sign">[docs]</a> <span class="k">def</span> <span class="nf">sign</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">argv</span><span class="p">):</span>
+ <span class="c1"># type: (*Any) -&gt; None</span>
+ <span class="k">raise</span> <span class="n">DSAError</span><span class="p">(</span><span class="s1">&#39;DSA_pub object has no private key&#39;</span><span class="p">)</span></div>
+
+ <span class="n">sign_asn1</span> <span class="o">=</span> <span class="n">sign</span>
+
+<div class="viewcode-block" id="DSA_pub.check_key"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.DSA.DSA_pub.check_key">[docs]</a> <span class="k">def</span> <span class="nf">check_key</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> :return: does DSA_pub contain a pub key?</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">dsa_check_pub_key</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dsa</span><span class="p">)</span></div>
+
+ <span class="n">save_key</span> <span class="o">=</span> <span class="n">DSA</span><span class="o">.</span><span class="n">save_pub_key</span>
+
+ <span class="n">save_key_bio</span> <span class="o">=</span> <span class="n">DSA</span><span class="o">.</span><span class="n">save_pub_key_bio</span></div>
+
+<span class="c1"># --------------------------------------------------------------</span>
+<span class="c1"># factories and other functions</span>
+
+
+<div class="viewcode-block" id="gen_params"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.DSA.gen_params">[docs]</a><span class="k">def</span> <span class="nf">gen_params</span><span class="p">(</span><span class="n">bits</span><span class="p">,</span> <span class="n">callback</span><span class="o">=</span><span class="n">util</span><span class="o">.</span><span class="n">genparam_callback</span><span class="p">):</span>
+ <span class="c1"># type: (int, Callable) -&gt; DSA</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Factory function that generates DSA parameters and</span>
+<span class="sd"> instantiates a DSA object from the output.</span>
+
+<span class="sd"> :param bits: The length of the prime to be generated. If</span>
+<span class="sd"> &#39;bits&#39; &lt; 512, it is set to 512.</span>
+<span class="sd"> :param callback: A Python callback object that will be</span>
+<span class="sd"> invoked during parameter generation; it usual</span>
+<span class="sd"> purpose is to provide visual feedback.</span>
+<span class="sd"> :return: instance of DSA.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">dsa</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">dsa_generate_parameters</span><span class="p">(</span><span class="n">bits</span><span class="p">,</span> <span class="n">callback</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">DSA</span><span class="p">(</span><span class="n">dsa</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="set_params"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.DSA.set_params">[docs]</a><span class="k">def</span> <span class="nf">set_params</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">q</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
+ <span class="c1"># type: (bytes, bytes, bytes) -&gt; DSA</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Factory function that instantiates a DSA object with DSA</span>
+<span class="sd"> parameters.</span>
+
+<span class="sd"> :param p: value of p, a &quot;byte string&quot;</span>
+<span class="sd"> :param q: value of q, a &quot;byte string&quot;</span>
+<span class="sd"> :param g: value of g, a &quot;byte string&quot;</span>
+<span class="sd"> :return: instance of DSA.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">dsa</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">dsa_new</span><span class="p">()</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">dsa_set_pqg</span><span class="p">(</span><span class="n">dsa</span><span class="p">,</span> <span class="n">p</span><span class="p">,</span> <span class="n">q</span><span class="p">,</span> <span class="n">g</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">DSA</span><span class="p">(</span><span class="n">dsa</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="load_params"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.DSA.load_params">[docs]</a><span class="k">def</span> <span class="nf">load_params</span><span class="p">(</span><span class="n">file</span><span class="p">,</span> <span class="n">callback</span><span class="o">=</span><span class="n">util</span><span class="o">.</span><span class="n">passphrase_callback</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr, Callable) -&gt; DSA</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Factory function that instantiates a DSA object with DSA</span>
+<span class="sd"> parameters from a file.</span>
+
+<span class="sd"> :param file: Names the file (a path) that contains the PEM</span>
+<span class="sd"> representation of the DSA parameters.</span>
+<span class="sd"> :param callback: A Python callback object that will be</span>
+<span class="sd"> invoked if the DSA parameters file is</span>
+<span class="sd"> passphrase-protected.</span>
+<span class="sd"> :return: instance of DSA.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">with</span> <span class="n">BIO</span><span class="o">.</span><span class="n">openfile</span><span class="p">(</span><span class="n">file</span><span class="p">)</span> <span class="k">as</span> <span class="n">bio</span><span class="p">:</span>
+ <span class="n">ret</span> <span class="o">=</span> <span class="n">load_params_bio</span><span class="p">(</span><span class="n">bio</span><span class="p">,</span> <span class="n">callback</span><span class="p">)</span>
+
+ <span class="k">return</span> <span class="n">ret</span></div>
+
+
+<div class="viewcode-block" id="load_params_bio"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.DSA.load_params_bio">[docs]</a><span class="k">def</span> <span class="nf">load_params_bio</span><span class="p">(</span><span class="n">bio</span><span class="p">,</span> <span class="n">callback</span><span class="o">=</span><span class="n">util</span><span class="o">.</span><span class="n">passphrase_callback</span><span class="p">):</span>
+ <span class="c1"># type: (BIO.BIO, Callable) -&gt; DSA</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Factory function that instantiates a DSA object with DSA</span>
+<span class="sd"> parameters from a M2Crypto.BIO object.</span>
+
+<span class="sd"> :param bio: Contains the PEM representation of the DSA</span>
+<span class="sd"> parameters.</span>
+<span class="sd"> :param callback: A Python callback object that will be</span>
+<span class="sd"> invoked if the DSA parameters file is</span>
+<span class="sd"> passphrase-protected.</span>
+<span class="sd"> :return: instance of DSA.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">dsa</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">dsa_read_params</span><span class="p">(</span><span class="n">bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span> <span class="n">callback</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">DSA</span><span class="p">(</span><span class="n">dsa</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="load_key"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.DSA.load_key">[docs]</a><span class="k">def</span> <span class="nf">load_key</span><span class="p">(</span><span class="n">file</span><span class="p">,</span> <span class="n">callback</span><span class="o">=</span><span class="n">util</span><span class="o">.</span><span class="n">passphrase_callback</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr, Callable) -&gt; DSA</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Factory function that instantiates a DSA object from a</span>
+<span class="sd"> PEM encoded DSA key pair.</span>
+
+<span class="sd"> :param file: Names the file (a path) that contains the PEM</span>
+<span class="sd"> representation of the DSA key pair.</span>
+<span class="sd"> :param callback: A Python callback object that will be</span>
+<span class="sd"> invoked if the DSA key pair is</span>
+<span class="sd"> passphrase-protected.</span>
+<span class="sd"> :return: instance of DSA.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">with</span> <span class="n">BIO</span><span class="o">.</span><span class="n">openfile</span><span class="p">(</span><span class="n">file</span><span class="p">)</span> <span class="k">as</span> <span class="n">bio</span><span class="p">:</span>
+ <span class="n">ret</span> <span class="o">=</span> <span class="n">load_key_bio</span><span class="p">(</span><span class="n">bio</span><span class="p">,</span> <span class="n">callback</span><span class="p">)</span>
+
+ <span class="k">return</span> <span class="n">ret</span></div>
+
+
+<div class="viewcode-block" id="load_key_bio"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.DSA.load_key_bio">[docs]</a><span class="k">def</span> <span class="nf">load_key_bio</span><span class="p">(</span><span class="n">bio</span><span class="p">,</span> <span class="n">callback</span><span class="o">=</span><span class="n">util</span><span class="o">.</span><span class="n">passphrase_callback</span><span class="p">):</span>
+ <span class="c1"># type: (BIO.BIO, Callable) -&gt; DSA</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Factory function that instantiates a DSA object from a</span>
+<span class="sd"> PEM encoded DSA key pair.</span>
+
+<span class="sd"> :param bio: Contains the PEM representation of the DSA</span>
+<span class="sd"> key pair.</span>
+<span class="sd"> :param callback: A Python callback object that will be</span>
+<span class="sd"> invoked if the DSA key pair is</span>
+<span class="sd"> passphrase-protected.</span>
+<span class="sd"> :return: instance of DSA.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">dsa</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">dsa_read_key</span><span class="p">(</span><span class="n">bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span> <span class="n">callback</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">DSA</span><span class="p">(</span><span class="n">dsa</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="pub_key_from_params"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.DSA.pub_key_from_params">[docs]</a><span class="k">def</span> <span class="nf">pub_key_from_params</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">q</span><span class="p">,</span> <span class="n">g</span><span class="p">,</span> <span class="n">pub</span><span class="p">):</span>
+ <span class="c1"># type: (bytes, bytes, bytes, bytes) -&gt; DSA_pub</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Factory function that instantiates a DSA_pub object using</span>
+<span class="sd"> the parameters and public key specified.</span>
+
+<span class="sd"> :param p: value of p</span>
+<span class="sd"> :param q: value of q</span>
+<span class="sd"> :param g: value of g</span>
+<span class="sd"> :param pub: value of the public key</span>
+<span class="sd"> :return: instance of DSA_pub.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">dsa</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">dsa_new</span><span class="p">()</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">dsa_set_pqg</span><span class="p">(</span><span class="n">dsa</span><span class="p">,</span> <span class="n">p</span><span class="p">,</span> <span class="n">q</span><span class="p">,</span> <span class="n">g</span><span class="p">)</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">dsa_set_pub</span><span class="p">(</span><span class="n">dsa</span><span class="p">,</span> <span class="n">pub</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">DSA_pub</span><span class="p">(</span><span class="n">dsa</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="load_pub_key"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.DSA.load_pub_key">[docs]</a><span class="k">def</span> <span class="nf">load_pub_key</span><span class="p">(</span><span class="n">file</span><span class="p">,</span> <span class="n">callback</span><span class="o">=</span><span class="n">util</span><span class="o">.</span><span class="n">passphrase_callback</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr, Callable) -&gt; DSA_pub</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Factory function that instantiates a DSA_pub object using</span>
+<span class="sd"> a DSA public key contained in PEM file. The PEM file</span>
+<span class="sd"> must contain the parameters in addition to the public key.</span>
+
+<span class="sd"> :param file: Names the file (a path) that contains the PEM</span>
+<span class="sd"> representation of the DSA public key.</span>
+<span class="sd"> :param callback: A Python callback object that will be</span>
+<span class="sd"> invoked should the DSA public key be</span>
+<span class="sd"> passphrase-protected.</span>
+<span class="sd"> :return: instance of DSA_pub.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">with</span> <span class="n">BIO</span><span class="o">.</span><span class="n">openfile</span><span class="p">(</span><span class="n">file</span><span class="p">)</span> <span class="k">as</span> <span class="n">bio</span><span class="p">:</span>
+ <span class="n">ret</span> <span class="o">=</span> <span class="n">load_pub_key_bio</span><span class="p">(</span><span class="n">bio</span><span class="p">,</span> <span class="n">callback</span><span class="p">)</span>
+
+ <span class="k">return</span> <span class="n">ret</span></div>
+
+
+<div class="viewcode-block" id="load_pub_key_bio"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.DSA.load_pub_key_bio">[docs]</a><span class="k">def</span> <span class="nf">load_pub_key_bio</span><span class="p">(</span><span class="n">bio</span><span class="p">,</span> <span class="n">callback</span><span class="o">=</span><span class="n">util</span><span class="o">.</span><span class="n">passphrase_callback</span><span class="p">):</span>
+ <span class="c1"># type: (BIO.BIO, Callable) -&gt; DSA_pub</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Factory function that instantiates a DSA_pub object using</span>
+<span class="sd"> a DSA public key contained in PEM format. The PEM</span>
+<span class="sd"> must contain the parameters in addition to the public key.</span>
+
+<span class="sd"> :param bio: Contains the PEM representation of the DSA</span>
+<span class="sd"> public key (with params).</span>
+<span class="sd"> :param callback: A Python callback object that will be</span>
+<span class="sd"> invoked should the DSA public key be</span>
+<span class="sd"> passphrase-protected.</span>
+<span class="sd"> :return: instance of DSA_pub.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">dsapub</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">dsa_read_pub_key</span><span class="p">(</span><span class="n">bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span> <span class="n">callback</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">DSA_pub</span><span class="p">(</span><span class="n">dsapub</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span></div>
+</pre></div>
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="../../index.html">M2Crypto</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="../../M2Crypto.html">M2Crypto Package</a></li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="../../index.html">Documentation overview</a><ul>
+ <li><a href="../index.html">Module code</a><ul>
+ </ul></li>
+ </ul></li>
+</ul>
+</div>
+<div id="searchbox" style="display: none" role="search">
+ <h3>Quick search</h3>
+ <div class="searchformwrapper">
+ <form class="search" action="../../search.html" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ </div>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer">
+ &copy;2017, Matej Cepl <mcepl@cepl.eu>.
+
+ |
+ Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
+ &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
+
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/_modules/M2Crypto/EC.html b/doc/html/_modules/M2Crypto/EC.html
new file mode 100644
index 0000000..8b62996
--- /dev/null
+++ b/doc/html/_modules/M2Crypto/EC.html
@@ -0,0 +1,563 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>M2Crypto.EC &#8212; M2Crypto documentation</title>
+ <link rel="stylesheet" href="../../_static/alabaster.css" type="text/css" />
+ <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../../_static/jquery.js"></script>
+ <script type="text/javascript" src="../../_static/underscore.js"></script>
+ <script type="text/javascript" src="../../_static/doctools.js"></script>
+ <script type="text/javascript" src="../../_static/language_data.js"></script>
+ <link rel="index" title="Index" href="../../genindex.html" />
+ <link rel="search" title="Search" href="../../search.html" />
+
+ <link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+ <h1>Source code for M2Crypto.EC</h1><div class="highlight"><pre>
+<span></span><span class="kn">from</span> <span class="nn">__future__</span> <span class="k">import</span> <span class="n">absolute_import</span>
+
+<span class="sd">&quot;&quot;&quot;</span>
+<span class="sd">M2Crypto wrapper for OpenSSL ECDH/ECDSA API.</span>
+
+<span class="sd">@requires: OpenSSL 0.9.8 or newer</span>
+
+<span class="sd">Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved.</span>
+
+<span class="sd">Portions copyright (c) 2005-2006 Vrije Universiteit Amsterdam.</span>
+<span class="sd">All rights reserved.&quot;&quot;&quot;</span>
+
+<span class="kn">from</span> <span class="nn">M2Crypto</span> <span class="k">import</span> <span class="n">BIO</span><span class="p">,</span> <span class="n">Err</span><span class="p">,</span> <span class="n">EVP</span><span class="p">,</span> <span class="n">m2</span><span class="p">,</span> <span class="n">util</span>
+<span class="k">if</span> <span class="n">util</span><span class="o">.</span><span class="n">py27plus</span><span class="p">:</span>
+ <span class="kn">from</span> <span class="nn">typing</span> <span class="k">import</span> <span class="n">AnyStr</span><span class="p">,</span> <span class="n">Callable</span><span class="p">,</span> <span class="n">Dict</span><span class="p">,</span> <span class="n">Optional</span><span class="p">,</span> <span class="n">Tuple</span><span class="p">,</span> <span class="n">Union</span> <span class="c1"># noqa</span>
+
+<span class="n">EC_Key</span> <span class="o">=</span> <span class="nb">bytes</span>
+
+
+<div class="viewcode-block" id="ECError"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EC.ECError">[docs]</a><span class="k">class</span> <span class="nc">ECError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
+ <span class="k">pass</span></div>
+
+<span class="n">m2</span><span class="o">.</span><span class="n">ec_init</span><span class="p">(</span><span class="n">ECError</span><span class="p">)</span>
+
+<span class="c1"># Curve identifier constants</span>
+<span class="n">NID_secp112r1</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_secp112r1</span> <span class="c1"># type: int</span>
+<span class="n">NID_secp112r2</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_secp112r2</span> <span class="c1"># type: int</span>
+<span class="n">NID_secp128r1</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_secp128r1</span> <span class="c1"># type: int</span>
+<span class="n">NID_secp128r2</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_secp128r2</span> <span class="c1"># type: int</span>
+<span class="n">NID_secp160k1</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_secp160k1</span> <span class="c1"># type: int</span>
+<span class="n">NID_secp160r1</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_secp160r1</span> <span class="c1"># type: int</span>
+<span class="n">NID_secp160r2</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_secp160r2</span> <span class="c1"># type: int</span>
+<span class="n">NID_secp192k1</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_secp192k1</span> <span class="c1"># type: int</span>
+<span class="n">NID_secp224k1</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_secp224k1</span> <span class="c1"># type: int</span>
+<span class="n">NID_secp224r1</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_secp224r1</span> <span class="c1"># type: int</span>
+<span class="n">NID_secp256k1</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_secp256k1</span> <span class="c1"># type: int</span>
+<span class="n">NID_secp384r1</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_secp384r1</span> <span class="c1"># type: int</span>
+<span class="n">NID_secp521r1</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_secp521r1</span> <span class="c1"># type: int</span>
+<span class="n">NID_sect113r1</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_sect113r1</span> <span class="c1"># type: int</span>
+<span class="n">NID_sect113r2</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_sect113r2</span> <span class="c1"># type: int</span>
+<span class="n">NID_sect131r1</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_sect131r1</span> <span class="c1"># type: int</span>
+<span class="n">NID_sect131r2</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_sect131r2</span> <span class="c1"># type: int</span>
+<span class="n">NID_sect163k1</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_sect163k1</span> <span class="c1"># type: int</span>
+<span class="n">NID_sect163r1</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_sect163r1</span> <span class="c1"># type: int</span>
+<span class="n">NID_sect163r2</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_sect163r2</span> <span class="c1"># type: int</span>
+<span class="n">NID_sect193r1</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_sect193r1</span> <span class="c1"># type: int</span>
+<span class="n">NID_sect193r2</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_sect193r2</span> <span class="c1"># type: int</span>
+<span class="c1"># default for secg.org TLS test server</span>
+<span class="n">NID_sect233k1</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_sect233k1</span> <span class="c1"># type: int</span>
+<span class="n">NID_sect233r1</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_sect233r1</span> <span class="c1"># type: int</span>
+<span class="n">NID_sect239k1</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_sect239k1</span> <span class="c1"># type: int</span>
+<span class="n">NID_sect283k1</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_sect283k1</span> <span class="c1"># type: int</span>
+<span class="n">NID_sect283r1</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_sect283r1</span> <span class="c1"># type: int</span>
+<span class="n">NID_sect409k1</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_sect409k1</span> <span class="c1"># type: int</span>
+<span class="n">NID_sect409r1</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_sect409r1</span> <span class="c1"># type: int</span>
+<span class="n">NID_sect571k1</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_sect571k1</span> <span class="c1"># type: int</span>
+<span class="n">NID_sect571r1</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_sect571r1</span> <span class="c1"># type: int</span>
+
+<span class="n">NID_prime192v1</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_X9_62_prime192v1</span> <span class="c1"># type: int</span>
+<span class="n">NID_prime192v2</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_X9_62_prime192v2</span> <span class="c1"># type: int</span>
+<span class="n">NID_prime192v3</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_X9_62_prime192v3</span> <span class="c1"># type: int</span>
+<span class="n">NID_prime239v1</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_X9_62_prime239v1</span> <span class="c1"># type: int</span>
+<span class="n">NID_prime239v2</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_X9_62_prime239v2</span> <span class="c1"># type: int</span>
+<span class="n">NID_prime239v3</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_X9_62_prime239v3</span> <span class="c1"># type: int</span>
+<span class="n">NID_prime256v1</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_X9_62_prime256v1</span> <span class="c1"># type: int</span>
+<span class="n">NID_c2pnb163v1</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_X9_62_c2pnb163v1</span> <span class="c1"># type: int</span>
+<span class="n">NID_c2pnb163v2</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_X9_62_c2pnb163v2</span> <span class="c1"># type: int</span>
+<span class="n">NID_c2pnb163v3</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_X9_62_c2pnb163v3</span> <span class="c1"># type: int</span>
+<span class="n">NID_c2pnb176v1</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_X9_62_c2pnb176v1</span> <span class="c1"># type: int</span>
+<span class="n">NID_c2tnb191v1</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_X9_62_c2tnb191v1</span> <span class="c1"># type: int</span>
+<span class="n">NID_c2tnb191v2</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_X9_62_c2tnb191v2</span> <span class="c1"># type: int</span>
+<span class="n">NID_c2tnb191v3</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_X9_62_c2tnb191v3</span> <span class="c1"># type: int</span>
+<span class="n">NID_c2pnb208w1</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_X9_62_c2pnb208w1</span> <span class="c1"># type: int</span>
+<span class="n">NID_c2tnb239v1</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_X9_62_c2tnb239v1</span> <span class="c1"># type: int</span>
+<span class="n">NID_c2tnb239v2</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_X9_62_c2tnb239v2</span> <span class="c1"># type: int</span>
+<span class="n">NID_c2tnb239v3</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_X9_62_c2tnb239v3</span> <span class="c1"># type: int</span>
+<span class="n">NID_c2pnb272w1</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_X9_62_c2pnb272w1</span> <span class="c1"># type: int</span>
+<span class="n">NID_c2pnb304w1</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_X9_62_c2pnb304w1</span> <span class="c1"># type: int</span>
+<span class="n">NID_c2tnb359v1</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_X9_62_c2tnb359v1</span> <span class="c1"># type: int</span>
+<span class="n">NID_c2pnb368w1</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_X9_62_c2pnb368w1</span> <span class="c1"># type: int</span>
+<span class="n">NID_c2tnb431r1</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_X9_62_c2tnb431r1</span> <span class="c1"># type: int</span>
+
+<span class="c1"># To preserve compatibility with older names</span>
+<span class="n">NID_X9_62_prime192v1</span> <span class="o">=</span> <span class="n">NID_prime192v1</span> <span class="c1"># type: int</span>
+<span class="n">NID_X9_62_prime192v2</span> <span class="o">=</span> <span class="n">NID_prime192v2</span> <span class="c1"># type: int</span>
+<span class="n">NID_X9_62_prime192v3</span> <span class="o">=</span> <span class="n">NID_prime192v3</span> <span class="c1"># type: int</span>
+<span class="n">NID_X9_62_prime239v1</span> <span class="o">=</span> <span class="n">NID_prime239v1</span> <span class="c1"># type: int</span>
+<span class="n">NID_X9_62_prime239v2</span> <span class="o">=</span> <span class="n">NID_prime239v2</span> <span class="c1"># type: int</span>
+<span class="n">NID_X9_62_prime239v3</span> <span class="o">=</span> <span class="n">NID_prime239v3</span> <span class="c1"># type: int</span>
+<span class="n">NID_X9_62_prime256v1</span> <span class="o">=</span> <span class="n">NID_prime256v1</span> <span class="c1"># type: int</span>
+<span class="n">NID_X9_62_c2pnb163v1</span> <span class="o">=</span> <span class="n">NID_c2pnb163v1</span> <span class="c1"># type: int</span>
+<span class="n">NID_X9_62_c2pnb163v2</span> <span class="o">=</span> <span class="n">NID_c2pnb163v2</span> <span class="c1"># type: int</span>
+<span class="n">NID_X9_62_c2pnb163v3</span> <span class="o">=</span> <span class="n">NID_c2pnb163v3</span> <span class="c1"># type: int</span>
+<span class="n">NID_X9_62_c2pnb176v1</span> <span class="o">=</span> <span class="n">NID_c2pnb176v1</span> <span class="c1"># type: int</span>
+<span class="n">NID_X9_62_c2tnb191v1</span> <span class="o">=</span> <span class="n">NID_c2tnb191v1</span> <span class="c1"># type: int</span>
+<span class="n">NID_X9_62_c2tnb191v2</span> <span class="o">=</span> <span class="n">NID_c2tnb191v2</span> <span class="c1"># type: int</span>
+<span class="n">NID_X9_62_c2tnb191v3</span> <span class="o">=</span> <span class="n">NID_c2tnb191v3</span> <span class="c1"># type: int</span>
+<span class="n">NID_X9_62_c2pnb208w1</span> <span class="o">=</span> <span class="n">NID_c2pnb208w1</span> <span class="c1"># type: int</span>
+<span class="n">NID_X9_62_c2tnb239v1</span> <span class="o">=</span> <span class="n">NID_c2tnb239v1</span> <span class="c1"># type: int</span>
+<span class="n">NID_X9_62_c2tnb239v2</span> <span class="o">=</span> <span class="n">NID_c2tnb239v2</span> <span class="c1"># type: int</span>
+<span class="n">NID_X9_62_c2tnb239v3</span> <span class="o">=</span> <span class="n">NID_c2tnb239v3</span> <span class="c1"># type: int</span>
+<span class="n">NID_X9_62_c2pnb272w1</span> <span class="o">=</span> <span class="n">NID_c2pnb272w1</span> <span class="c1"># type: int</span>
+<span class="n">NID_X9_62_c2pnb304w1</span> <span class="o">=</span> <span class="n">NID_c2pnb304w1</span> <span class="c1"># type: int</span>
+<span class="n">NID_X9_62_c2tnb359v1</span> <span class="o">=</span> <span class="n">NID_c2tnb359v1</span> <span class="c1"># type: int</span>
+<span class="n">NID_X9_62_c2pnb368w1</span> <span class="o">=</span> <span class="n">NID_c2pnb368w1</span> <span class="c1"># type: int</span>
+<span class="n">NID_X9_62_c2tnb431r1</span> <span class="o">=</span> <span class="n">NID_c2tnb431r1</span> <span class="c1"># type: int</span>
+
+<span class="n">NID_wap_wsg_idm_ecid_wtls1</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_wap_wsg_idm_ecid_wtls1</span> <span class="c1"># type: int</span>
+<span class="n">NID_wap_wsg_idm_ecid_wtls3</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_wap_wsg_idm_ecid_wtls3</span> <span class="c1"># type: int</span>
+<span class="n">NID_wap_wsg_idm_ecid_wtls4</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_wap_wsg_idm_ecid_wtls4</span> <span class="c1"># type: int</span>
+<span class="n">NID_wap_wsg_idm_ecid_wtls5</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_wap_wsg_idm_ecid_wtls5</span> <span class="c1"># type: int</span>
+<span class="n">NID_wap_wsg_idm_ecid_wtls6</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_wap_wsg_idm_ecid_wtls6</span> <span class="c1"># type: int</span>
+<span class="n">NID_wap_wsg_idm_ecid_wtls7</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_wap_wsg_idm_ecid_wtls7</span> <span class="c1"># type: int</span>
+<span class="n">NID_wap_wsg_idm_ecid_wtls8</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_wap_wsg_idm_ecid_wtls8</span> <span class="c1"># type: int</span>
+<span class="n">NID_wap_wsg_idm_ecid_wtls9</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_wap_wsg_idm_ecid_wtls9</span> <span class="c1"># type: int</span>
+<span class="n">NID_wap_wsg_idm_ecid_wtls10</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_wap_wsg_idm_ecid_wtls10</span> <span class="c1"># type: int</span>
+<span class="n">NID_wap_wsg_idm_ecid_wtls11</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_wap_wsg_idm_ecid_wtls11</span> <span class="c1"># type: int</span>
+<span class="n">NID_wap_wsg_idm_ecid_wtls12</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_wap_wsg_idm_ecid_wtls12</span> <span class="c1"># type: int</span>
+
+<span class="c1"># The following two curves, according to OpenSSL, have a</span>
+<span class="c1"># &quot;Questionable extension field!&quot; and are not supported by</span>
+<span class="c1"># the OpenSSL inverse function. ECError: no inverse.</span>
+<span class="c1"># As such they cannot be used for signing. They might,</span>
+<span class="c1"># however, be usable for encryption but that has not</span>
+<span class="c1"># been tested. Until thir usefulness can be established,</span>
+<span class="c1"># they are not supported at this time.</span>
+<span class="c1"># NID_ipsec3 = m2.NID_ipsec3</span>
+<span class="c1"># NID_ipsec4 = m2.NID_ipsec4</span>
+
+
+<div class="viewcode-block" id="EC"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EC.EC">[docs]</a><span class="k">class</span> <span class="nc">EC</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Object interface to a EC key pair.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+
+ <span class="n">m2_ec_key_free</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">ec_key_free</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">ec</span><span class="p">,</span> <span class="n">_pyfree</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
+ <span class="c1"># type: (EC, int) -&gt; None</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">ec_key_type_check</span><span class="p">(</span><span class="n">ec</span><span class="p">),</span> <span class="s2">&quot;&#39;ec&#39; type error&quot;</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">ec</span> <span class="o">=</span> <span class="n">ec</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_pyfree</span> <span class="o">=</span> <span class="n">_pyfree</span>
+
+ <span class="k">def</span> <span class="nf">__del__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;_pyfree&#39;</span><span class="p">,</span> <span class="mi">0</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">m2_ec_key_free</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ec</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">__len__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">ec_key_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ec</span><span class="p">),</span> <span class="s2">&quot;&#39;ec&#39; type error&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ec_key_keylen</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ec</span><span class="p">)</span>
+
+<div class="viewcode-block" id="EC.gen_key"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EC.EC.gen_key">[docs]</a> <span class="k">def</span> <span class="nf">gen_key</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Generates the key pair from its parameters. Use::</span>
+
+<span class="sd"> keypair = EC.gen_params(curve)</span>
+<span class="sd"> keypair.gen_key()</span>
+
+<span class="sd"> to create an EC key pair.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">ec_key_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ec</span><span class="p">),</span> <span class="s2">&quot;&#39;ec&#39; type error&quot;</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">ec_key_gen_key</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ec</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="EC.pub"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EC.EC.pub">[docs]</a> <span class="k">def</span> <span class="nf">pub</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; EC_pub</span>
+ <span class="c1"># Don&#39;t let python free</span>
+ <span class="k">return</span> <span class="n">EC_pub</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ec</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="EC.sign_dsa"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EC.EC.sign_dsa">[docs]</a> <span class="k">def</span> <span class="nf">sign_dsa</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">digest</span><span class="p">):</span>
+ <span class="c1"># type: (bytes) -&gt; Tuple[bytes, bytes]</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Sign the given digest using ECDSA. Returns a tuple (r,s), the two</span>
+<span class="sd"> ECDSA signature parameters.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">_check_key_type</span><span class="p">(),</span> <span class="s2">&quot;&#39;ec&#39; type error&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ecdsa_sign</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ec</span><span class="p">,</span> <span class="n">digest</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="EC.verify_dsa"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EC.EC.verify_dsa">[docs]</a> <span class="k">def</span> <span class="nf">verify_dsa</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">digest</span><span class="p">,</span> <span class="n">r</span><span class="p">,</span> <span class="n">s</span><span class="p">):</span>
+ <span class="c1"># type: (bytes, bytes, bytes) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Verify the given digest using ECDSA. r and s are the ECDSA</span>
+<span class="sd"> signature parameters.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">_check_key_type</span><span class="p">(),</span> <span class="s2">&quot;&#39;ec&#39; type error&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ecdsa_verify</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ec</span><span class="p">,</span> <span class="n">digest</span><span class="p">,</span> <span class="n">r</span><span class="p">,</span> <span class="n">s</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="EC.sign_dsa_asn1"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EC.EC.sign_dsa_asn1">[docs]</a> <span class="k">def</span> <span class="nf">sign_dsa_asn1</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">digest</span><span class="p">):</span>
+ <span class="c1"># type: (bytes) -&gt; bytes</span>
+ <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">_check_key_type</span><span class="p">(),</span> <span class="s2">&quot;&#39;ec&#39; type error&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ecdsa_sign_asn1</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ec</span><span class="p">,</span> <span class="n">digest</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="EC.verify_dsa_asn1"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EC.EC.verify_dsa_asn1">[docs]</a> <span class="k">def</span> <span class="nf">verify_dsa_asn1</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">digest</span><span class="p">,</span> <span class="n">blob</span><span class="p">):</span>
+ <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">_check_key_type</span><span class="p">(),</span> <span class="s2">&quot;&#39;ec&#39; type error&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ecdsa_verify_asn1</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ec</span><span class="p">,</span> <span class="n">digest</span><span class="p">,</span> <span class="n">blob</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="EC.compute_dh_key"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EC.EC.compute_dh_key">[docs]</a> <span class="k">def</span> <span class="nf">compute_dh_key</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">pub_key</span><span class="p">):</span>
+ <span class="c1"># type: (EC) -&gt; Optional[bytes]</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Compute the ECDH shared key of this key pair and the given public</span>
+<span class="sd"> key object. They must both use the same curve. Returns the</span>
+<span class="sd"> shared key in binary as a buffer object. No Key Derivation Function is</span>
+<span class="sd"> applied.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">check_key</span><span class="p">(),</span> <span class="s1">&#39;key is not initialised&#39;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ecdh_compute_key</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ec</span><span class="p">,</span> <span class="n">pub_key</span><span class="o">.</span><span class="n">ec</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="EC.save_key_bio"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EC.EC.save_key_bio">[docs]</a> <span class="k">def</span> <span class="nf">save_key_bio</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bio</span><span class="p">,</span> <span class="n">cipher</span><span class="o">=</span><span class="s1">&#39;aes_128_cbc&#39;</span><span class="p">,</span>
+ <span class="n">callback</span><span class="o">=</span><span class="n">util</span><span class="o">.</span><span class="n">passphrase_callback</span><span class="p">):</span>
+ <span class="c1"># type: (BIO.BIO, Optional[str], Callable) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Save the key pair to an M2Crypto.BIO.BIO object in PEM format.</span>
+
+<span class="sd"> :param bio: M2Crypto.BIO.BIO object to save key to.</span>
+
+<span class="sd"> :param cipher: Symmetric cipher to protect the key. The default</span>
+<span class="sd"> cipher is &#39;aes_128_cbc&#39;. If cipher is None, then</span>
+<span class="sd"> the key is saved in the clear.</span>
+
+<span class="sd"> :param callback: A Python callable object that is invoked</span>
+<span class="sd"> to acquire a passphrase with which to protect</span>
+<span class="sd"> the key. The default is</span>
+<span class="sd"> util.passphrase_callback.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">if</span> <span class="n">cipher</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ec_key_write_bio_no_cipher</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ec</span><span class="p">,</span> <span class="n">bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span> <span class="n">callback</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">ciph</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">m2</span><span class="p">,</span> <span class="n">cipher</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">ciph</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">&#39;not such cipher </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">cipher</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ec_key_write_bio</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ec</span><span class="p">,</span> <span class="n">bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span> <span class="n">ciph</span><span class="p">(),</span> <span class="n">callback</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="EC.save_key"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EC.EC.save_key">[docs]</a> <span class="k">def</span> <span class="nf">save_key</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">file</span><span class="p">,</span> <span class="n">cipher</span><span class="o">=</span><span class="s1">&#39;aes_128_cbc&#39;</span><span class="p">,</span>
+ <span class="n">callback</span><span class="o">=</span><span class="n">util</span><span class="o">.</span><span class="n">passphrase_callback</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr, Optional[str], Callable) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Save the key pair to a file in PEM format.</span>
+
+<span class="sd"> :param file: Name of filename to save key to.</span>
+
+<span class="sd"> :param cipher: Symmetric cipher to protect the key. The default</span>
+<span class="sd"> cipher is &#39;aes_128_cbc&#39;. If cipher is None, then</span>
+<span class="sd"> the key is saved in the clear.</span>
+
+<span class="sd"> :param callback: A Python callable object that is invoked</span>
+<span class="sd"> to acquire a passphrase with which to protect</span>
+<span class="sd"> the key. The default is</span>
+<span class="sd"> util.passphrase_callback.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">with</span> <span class="n">BIO</span><span class="o">.</span><span class="n">openfile</span><span class="p">(</span><span class="n">file</span><span class="p">,</span> <span class="s1">&#39;wb&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">bio</span><span class="p">:</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">save_key_bio</span><span class="p">(</span><span class="n">bio</span><span class="p">,</span> <span class="n">cipher</span><span class="p">,</span> <span class="n">callback</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="EC.save_pub_key_bio"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EC.EC.save_pub_key_bio">[docs]</a> <span class="k">def</span> <span class="nf">save_pub_key_bio</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bio</span><span class="p">):</span>
+ <span class="c1"># type: (BIO.BIO) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Save the public key to an M2Crypto.BIO.BIO object in PEM format.</span>
+
+<span class="sd"> :param bio: M2Crypto.BIO.BIO object to save key to.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ec_key_write_pubkey</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ec</span><span class="p">,</span> <span class="n">bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span></div>
+
+<div class="viewcode-block" id="EC.save_pub_key"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EC.EC.save_pub_key">[docs]</a> <span class="k">def</span> <span class="nf">save_pub_key</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">file</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Save the public key to a filename in PEM format.</span>
+
+<span class="sd"> :param file: Name of filename to save key to.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">with</span> <span class="n">BIO</span><span class="o">.</span><span class="n">openfile</span><span class="p">(</span><span class="n">file</span><span class="p">,</span> <span class="s1">&#39;wb&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">bio</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ec_key_write_pubkey</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ec</span><span class="p">,</span> <span class="n">bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span></div>
+
+<div class="viewcode-block" id="EC.as_pem"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EC.EC.as_pem">[docs]</a> <span class="k">def</span> <span class="nf">as_pem</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">cipher</span><span class="o">=</span><span class="s1">&#39;aes_128_cbc&#39;</span><span class="p">,</span> <span class="n">callback</span><span class="o">=</span><span class="n">util</span><span class="o">.</span><span class="n">passphrase_callback</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Returns the key(pair) as a string in PEM format.</span>
+<span class="sd"> If no password is passed and the cipher is set</span>
+<span class="sd"> it exits with error</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">with</span> <span class="n">BIO</span><span class="o">.</span><span class="n">MemoryBuffer</span><span class="p">()</span> <span class="k">as</span> <span class="n">bio</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">save_key_bio</span><span class="p">(</span><span class="n">bio</span><span class="p">,</span> <span class="n">cipher</span><span class="p">,</span> <span class="n">callback</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">bio</span><span class="o">.</span><span class="n">read</span><span class="p">()</span></div>
+
+ <span class="k">def</span> <span class="nf">_check_key_type</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ec_key_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ec</span><span class="p">)</span>
+
+<div class="viewcode-block" id="EC.check_key"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EC.EC.check_key">[docs]</a> <span class="k">def</span> <span class="nf">check_key</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">ec_key_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ec</span><span class="p">),</span> <span class="s2">&quot;&#39;ec&#39; type error&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ec_key_check_key</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ec</span><span class="p">)</span></div></div>
+
+
+<div class="viewcode-block" id="EC_pub"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EC.EC_pub">[docs]</a><span class="k">class</span> <span class="nc">EC_pub</span><span class="p">(</span><span class="n">EC</span><span class="p">):</span>
+
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Object interface to an EC public key.</span>
+<span class="sd"> ((don&#39;t like this implementation inheritance))</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">ec</span><span class="p">,</span> <span class="n">_pyfree</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
+ <span class="c1"># type: (EC, int) -&gt; None</span>
+ <span class="n">EC</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">ec</span><span class="p">,</span> <span class="n">_pyfree</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">der</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1"># type: Optional[bytes]</span>
+
+<div class="viewcode-block" id="EC_pub.get_der"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EC.EC_pub.get_der">[docs]</a> <span class="k">def</span> <span class="nf">get_der</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; bytes</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Returns the public key in DER format as a buffer object.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">check_key</span><span class="p">(),</span> <span class="s1">&#39;key is not initialised&#39;</span>
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">der</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">der</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">ec_key_get_public_der</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ec</span><span class="p">)</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">der</span></div>
+
+<div class="viewcode-block" id="EC_pub.get_key"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EC.EC_pub.get_key">[docs]</a> <span class="k">def</span> <span class="nf">get_key</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; bytes</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Returns the public key as a byte string.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">check_key</span><span class="p">(),</span> <span class="s1">&#39;key is not initialised&#39;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ec_key_get_public_key</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ec</span><span class="p">)</span></div>
+
+ <span class="n">save_key</span> <span class="o">=</span> <span class="n">EC</span><span class="o">.</span><span class="n">save_pub_key</span>
+
+ <span class="n">save_key_bio</span> <span class="o">=</span> <span class="n">EC</span><span class="o">.</span><span class="n">save_pub_key_bio</span></div>
+
+
+<div class="viewcode-block" id="gen_params"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EC.gen_params">[docs]</a><span class="k">def</span> <span class="nf">gen_params</span><span class="p">(</span><span class="n">curve</span><span class="p">):</span>
+ <span class="c1"># type: (int) -&gt; EC</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Factory function that generates EC parameters and</span>
+<span class="sd"> instantiates a EC object from the output.</span>
+
+<span class="sd"> :param curve: This is the OpenSSL nid of the curve to use.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">assert</span> <span class="n">curve</span> <span class="ow">in</span> <span class="p">[</span><span class="n">x</span><span class="p">[</span><span class="s1">&#39;NID&#39;</span><span class="p">]</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">m2</span><span class="o">.</span><span class="n">ec_get_builtin_curves</span><span class="p">()],</span> \
+ <span class="s1">&#39;Elliptic curve </span><span class="si">%s</span><span class="s1"> is not available on this system.&#39;</span> <span class="o">%</span> \
+ <span class="n">m2</span><span class="o">.</span><span class="n">obj_nid2sn</span><span class="p">(</span><span class="n">curve</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">EC</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">ec_key_new_by_curve_name</span><span class="p">(</span><span class="n">curve</span><span class="p">),</span> <span class="mi">1</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="load_key"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EC.load_key">[docs]</a><span class="k">def</span> <span class="nf">load_key</span><span class="p">(</span><span class="n">file</span><span class="p">,</span> <span class="n">callback</span><span class="o">=</span><span class="n">util</span><span class="o">.</span><span class="n">passphrase_callback</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr, Callable) -&gt; EC</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Factory function that instantiates a EC object.</span>
+
+<span class="sd"> :param file: Names the filename that contains the PEM representation</span>
+<span class="sd"> of the EC key pair.</span>
+
+<span class="sd"> :param callback: Python callback object that will be invoked</span>
+<span class="sd"> if the EC key pair is passphrase-protected.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">with</span> <span class="n">BIO</span><span class="o">.</span><span class="n">openfile</span><span class="p">(</span><span class="n">file</span><span class="p">)</span> <span class="k">as</span> <span class="n">bio</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">load_key_bio</span><span class="p">(</span><span class="n">bio</span><span class="p">,</span> <span class="n">callback</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="load_key_string"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EC.load_key_string">[docs]</a><span class="k">def</span> <span class="nf">load_key_string</span><span class="p">(</span><span class="n">string</span><span class="p">,</span> <span class="n">callback</span><span class="o">=</span><span class="n">util</span><span class="o">.</span><span class="n">passphrase_callback</span><span class="p">):</span>
+ <span class="c1"># type: (str, Callable) -&gt; EC</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Load an EC key pair from a string.</span>
+
+<span class="sd"> :param string: String containing EC key pair in PEM format.</span>
+
+<span class="sd"> :param callback: A Python callable object that is invoked</span>
+<span class="sd"> to acquire a passphrase with which to unlock the</span>
+<span class="sd"> key. The default is util.passphrase_callback.</span>
+
+<span class="sd"> :return: M2Crypto.EC.EC object.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">with</span> <span class="n">BIO</span><span class="o">.</span><span class="n">MemoryBuffer</span><span class="p">(</span><span class="n">string</span><span class="p">)</span> <span class="k">as</span> <span class="n">bio</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">load_key_bio</span><span class="p">(</span><span class="n">bio</span><span class="p">,</span> <span class="n">callback</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="load_key_bio"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EC.load_key_bio">[docs]</a><span class="k">def</span> <span class="nf">load_key_bio</span><span class="p">(</span><span class="n">bio</span><span class="p">,</span> <span class="n">callback</span><span class="o">=</span><span class="n">util</span><span class="o">.</span><span class="n">passphrase_callback</span><span class="p">):</span>
+ <span class="c1"># type: (BIO.BIO, Callable) -&gt; EC</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Factory function that instantiates a EC object.</span>
+
+<span class="sd"> :param bio: M2Crypto.BIO object that contains the PEM</span>
+<span class="sd"> representation of the EC key pair.</span>
+
+<span class="sd"> :param callback: Python callback object that will be invoked</span>
+<span class="sd"> if the EC key pair is passphrase-protected.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">EC</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">ec_key_read_bio</span><span class="p">(</span><span class="n">bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span> <span class="n">callback</span><span class="p">),</span> <span class="mi">1</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="load_pub_key"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EC.load_pub_key">[docs]</a><span class="k">def</span> <span class="nf">load_pub_key</span><span class="p">(</span><span class="n">file</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr) -&gt; EC_pub</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Load an EC public key from filename.</span>
+
+<span class="sd"> :param file: Name of filename containing EC public key in PEM</span>
+<span class="sd"> format.</span>
+
+<span class="sd"> :return: M2Crypto.EC.EC_pub object.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">with</span> <span class="n">BIO</span><span class="o">.</span><span class="n">openfile</span><span class="p">(</span><span class="n">file</span><span class="p">)</span> <span class="k">as</span> <span class="n">bio</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">load_pub_key_bio</span><span class="p">(</span><span class="n">bio</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="load_key_string_pubkey"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EC.load_key_string_pubkey">[docs]</a><span class="k">def</span> <span class="nf">load_key_string_pubkey</span><span class="p">(</span><span class="n">string</span><span class="p">,</span> <span class="n">callback</span><span class="o">=</span><span class="n">util</span><span class="o">.</span><span class="n">passphrase_callback</span><span class="p">):</span>
+ <span class="c1"># type: (str, Callable) -&gt; PKey</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Load an M2Crypto.EC.PKey from a public key as a string.</span>
+
+<span class="sd"> :param string: String containing the key in PEM format.</span>
+
+<span class="sd"> :param callback: A Python callable object that is invoked</span>
+<span class="sd"> to acquire a passphrase with which to protect the</span>
+<span class="sd"> key.</span>
+
+<span class="sd"> :return: M2Crypto.EC.PKey object.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">with</span> <span class="n">BIO</span><span class="o">.</span><span class="n">MemoryBuffer</span><span class="p">(</span><span class="n">string</span><span class="p">)</span> <span class="k">as</span> <span class="n">bio</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">EVP</span><span class="o">.</span><span class="n">load_key_bio_pubkey</span><span class="p">(</span><span class="n">bio</span><span class="p">,</span> <span class="n">callback</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="load_pub_key_bio"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EC.load_pub_key_bio">[docs]</a><span class="k">def</span> <span class="nf">load_pub_key_bio</span><span class="p">(</span><span class="n">bio</span><span class="p">):</span>
+ <span class="c1"># type: (BIO.BIO) -&gt; EC_pub</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Load an EC public key from an M2Crypto.BIO.BIO object.</span>
+
+<span class="sd"> :param bio: M2Crypto.BIO.BIO object containing EC public key in PEM</span>
+<span class="sd"> format.</span>
+
+<span class="sd"> :return: M2Crypto.EC.EC_pub object.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">ec</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">ec_key_read_pubkey</span><span class="p">(</span><span class="n">bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span>
+ <span class="k">if</span> <span class="n">ec</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">ec_error</span><span class="p">()</span>
+ <span class="k">return</span> <span class="n">EC_pub</span><span class="p">(</span><span class="n">ec</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="ec_error"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EC.ec_error">[docs]</a><span class="k">def</span> <span class="nf">ec_error</span><span class="p">():</span>
+ <span class="c1"># type: () -&gt; ECError</span>
+ <span class="k">raise</span> <span class="n">ECError</span><span class="p">(</span><span class="n">Err</span><span class="o">.</span><span class="n">get_error_message</span><span class="p">())</span></div>
+
+
+<div class="viewcode-block" id="pub_key_from_der"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EC.pub_key_from_der">[docs]</a><span class="k">def</span> <span class="nf">pub_key_from_der</span><span class="p">(</span><span class="n">der</span><span class="p">):</span>
+ <span class="c1"># type: (bytes) -&gt; EC_pub</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Create EC_pub from DER.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">EC_pub</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">ec_key_from_pubkey_der</span><span class="p">(</span><span class="n">der</span><span class="p">),</span> <span class="mi">1</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="pub_key_from_params"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EC.pub_key_from_params">[docs]</a><span class="k">def</span> <span class="nf">pub_key_from_params</span><span class="p">(</span><span class="n">curve</span><span class="p">,</span> <span class="nb">bytes</span><span class="p">):</span>
+ <span class="c1"># type: (bytes, bytes) -&gt; EC_pub</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Create EC_pub from curve name and octet string.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">EC_pub</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">ec_key_from_pubkey_params</span><span class="p">(</span><span class="n">curve</span><span class="p">,</span> <span class="nb">bytes</span><span class="p">),</span> <span class="mi">1</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="get_builtin_curves"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EC.get_builtin_curves">[docs]</a><span class="k">def</span> <span class="nf">get_builtin_curves</span><span class="p">():</span>
+ <span class="c1"># type: () -&gt; Tuple[Dict[str, Union[int, str]]]</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ec_get_builtin_curves</span><span class="p">()</span></div>
+</pre></div>
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="../../index.html">M2Crypto</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="../../M2Crypto.html">M2Crypto Package</a></li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="../../index.html">Documentation overview</a><ul>
+ <li><a href="../index.html">Module code</a><ul>
+ </ul></li>
+ </ul></li>
+</ul>
+</div>
+<div id="searchbox" style="display: none" role="search">
+ <h3>Quick search</h3>
+ <div class="searchformwrapper">
+ <form class="search" action="../../search.html" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ </div>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer">
+ &copy;2017, Matej Cepl <mcepl@cepl.eu>.
+
+ |
+ Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
+ &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
+
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/_modules/M2Crypto/EVP.html b/doc/html/_modules/M2Crypto/EVP.html
new file mode 100644
index 0000000..4aebc66
--- /dev/null
+++ b/doc/html/_modules/M2Crypto/EVP.html
@@ -0,0 +1,571 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>M2Crypto.EVP &#8212; M2Crypto documentation</title>
+ <link rel="stylesheet" href="../../_static/alabaster.css" type="text/css" />
+ <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../../_static/jquery.js"></script>
+ <script type="text/javascript" src="../../_static/underscore.js"></script>
+ <script type="text/javascript" src="../../_static/doctools.js"></script>
+ <script type="text/javascript" src="../../_static/language_data.js"></script>
+ <link rel="index" title="Index" href="../../genindex.html" />
+ <link rel="search" title="Search" href="../../search.html" />
+
+ <link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+ <h1>Source code for M2Crypto.EVP</h1><div class="highlight"><pre>
+<span></span><span class="kn">from</span> <span class="nn">__future__</span> <span class="k">import</span> <span class="n">absolute_import</span>
+
+<span class="sd">&quot;&quot;&quot;M2Crypto wrapper for OpenSSL EVP API.</span>
+
+<span class="sd">Copyright (c) 1999-2004 Ng Pheng Siong. All rights reserved.</span>
+
+<span class="sd">Portions Copyright (c) 2004-2007 Open Source Applications Foundation.</span>
+<span class="sd">Author: Heikki Toivonen</span>
+<span class="sd">&quot;&quot;&quot;</span>
+
+<span class="kn">import</span> <span class="nn">logging</span>
+<span class="kn">from</span> <span class="nn">M2Crypto</span> <span class="k">import</span> <span class="n">BIO</span><span class="p">,</span> <span class="n">Err</span><span class="p">,</span> <span class="n">RSA</span><span class="p">,</span> <span class="n">m2</span><span class="p">,</span> <span class="n">util</span>
+<span class="k">if</span> <span class="n">util</span><span class="o">.</span><span class="n">py27plus</span><span class="p">:</span>
+ <span class="kn">from</span> <span class="nn">typing</span> <span class="k">import</span> <span class="n">AnyStr</span><span class="p">,</span> <span class="n">Optional</span><span class="p">,</span> <span class="n">Callable</span> <span class="c1"># noqa</span>
+
+<span class="n">log</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s1">&#39;EVP&#39;</span><span class="p">)</span>
+
+<div class="viewcode-block" id="EVPError"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EVP.EVPError">[docs]</a><span class="k">class</span> <span class="nc">EVPError</span><span class="p">(</span><span class="ne">ValueError</span><span class="p">):</span>
+ <span class="k">pass</span></div>
+
+<span class="n">m2</span><span class="o">.</span><span class="n">evp_init</span><span class="p">(</span><span class="n">EVPError</span><span class="p">)</span>
+
+
+<div class="viewcode-block" id="pbkdf2"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EVP.pbkdf2">[docs]</a><span class="k">def</span> <span class="nf">pbkdf2</span><span class="p">(</span><span class="n">password</span><span class="p">,</span> <span class="n">salt</span><span class="p">,</span> <span class="nb">iter</span><span class="p">,</span> <span class="n">keylen</span><span class="p">):</span>
+ <span class="c1"># type: (bytes, bytes, int, int) -&gt; bytes</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Derive a key from password using PBKDF2 algorithm specified in RFC 2898.</span>
+
+<span class="sd"> :param password: Derive the key from this password.</span>
+<span class="sd"> :param salt: Salt.</span>
+<span class="sd"> :param iter: Number of iterations to perform.</span>
+<span class="sd"> :param keylen: Length of key to produce.</span>
+<span class="sd"> :return: Key.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">pkcs5_pbkdf2_hmac_sha1</span><span class="p">(</span><span class="n">password</span><span class="p">,</span> <span class="n">salt</span><span class="p">,</span> <span class="nb">iter</span><span class="p">,</span> <span class="n">keylen</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="MessageDigest"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EVP.MessageDigest">[docs]</a><span class="k">class</span> <span class="nc">MessageDigest</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Message Digest</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">m2_md_ctx_free</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">md_ctx_free</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">algo</span><span class="p">):</span>
+ <span class="c1"># type: (str) -&gt; None</span>
+ <span class="n">md</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">m2</span><span class="p">,</span> <span class="n">algo</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> <span class="c1"># type: Optional[Callable]</span>
+ <span class="k">if</span> <span class="n">md</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="c1"># if the digest algorithm isn&#39;t found as an attribute of the m2</span>
+ <span class="c1"># module, try to look up the digest using get_digestbyname()</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">md</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">get_digestbyname</span><span class="p">(</span><span class="n">algo</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">md</span> <span class="o">=</span> <span class="n">md</span><span class="p">()</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">ctx</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">md_ctx_new</span><span class="p">()</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">digest_init</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">md</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">__del__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;ctx&#39;</span><span class="p">,</span> <span class="kc">None</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">m2_md_ctx_free</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">)</span>
+
+<div class="viewcode-block" id="MessageDigest.update"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EVP.MessageDigest.update">[docs]</a> <span class="k">def</span> <span class="nf">update</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
+ <span class="c1"># type: (bytes) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Add data to be digested.</span>
+
+<span class="sd"> :return: -1 for Python error, 1 for success, 0 for OpenSSL failure.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">digest_update</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="MessageDigest.final"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EVP.MessageDigest.final">[docs]</a> <span class="k">def</span> <span class="nf">final</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">digest_final</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">)</span></div>
+
+ <span class="c1"># Deprecated.</span>
+ <span class="n">digest</span> <span class="o">=</span> <span class="n">final</span></div>
+
+
+<div class="viewcode-block" id="HMAC"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EVP.HMAC">[docs]</a><span class="k">class</span> <span class="nc">HMAC</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+
+ <span class="n">m2_hmac_ctx_free</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">hmac_ctx_free</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">algo</span><span class="o">=</span><span class="s1">&#39;sha1&#39;</span><span class="p">):</span>
+ <span class="c1"># type: (bytes, str) -&gt; None</span>
+ <span class="n">md</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">m2</span><span class="p">,</span> <span class="n">algo</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">md</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">&#39;unknown algorithm&#39;</span><span class="p">,</span> <span class="n">algo</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">md</span> <span class="o">=</span> <span class="n">md</span><span class="p">()</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">ctx</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">hmac_ctx_new</span><span class="p">()</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">hmac_init</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">md</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">__del__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;ctx&#39;</span><span class="p">,</span> <span class="kc">None</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">m2_hmac_ctx_free</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">)</span>
+
+<div class="viewcode-block" id="HMAC.reset"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EVP.HMAC.reset">[docs]</a> <span class="k">def</span> <span class="nf">reset</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">):</span>
+ <span class="c1"># type: (bytes) -&gt; None</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">hmac_init</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">md</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="HMAC.update"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EVP.HMAC.update">[docs]</a> <span class="k">def</span> <span class="nf">update</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
+ <span class="c1"># type: (bytes) -&gt; None</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">hmac_update</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="HMAC.final"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EVP.HMAC.final">[docs]</a> <span class="k">def</span> <span class="nf">final</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; bytes</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">hmac_final</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">)</span></div>
+
+ <span class="n">digest</span> <span class="o">=</span> <span class="n">final</span></div>
+
+
+<div class="viewcode-block" id="hmac"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EVP.hmac">[docs]</a><span class="k">def</span> <span class="nf">hmac</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">algo</span><span class="o">=</span><span class="s1">&#39;sha1&#39;</span><span class="p">):</span>
+ <span class="c1"># type: (bytes, bytes, str) -&gt; bytes</span>
+ <span class="n">md</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">m2</span><span class="p">,</span> <span class="n">algo</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">md</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">&#39;unknown algorithm&#39;</span><span class="p">,</span> <span class="n">algo</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">hmac</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">md</span><span class="p">())</span></div>
+
+
+<div class="viewcode-block" id="Cipher"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EVP.Cipher">[docs]</a><span class="k">class</span> <span class="nc">Cipher</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+
+ <span class="n">m2_cipher_ctx_free</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">cipher_ctx_free</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">alg</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">iv</span><span class="p">,</span> <span class="n">op</span><span class="p">,</span> <span class="n">key_as_bytes</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">d</span><span class="o">=</span><span class="s1">&#39;md5&#39;</span><span class="p">,</span>
+ <span class="n">salt</span><span class="o">=</span><span class="sa">b</span><span class="s1">&#39;12345678&#39;</span><span class="p">,</span> <span class="n">i</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">padding</span><span class="o">=</span><span class="mi">1</span><span class="p">):</span>
+ <span class="c1"># type: (str, bytes, bytes, object, int, str, bytes, int, int) -&gt; None</span>
+ <span class="n">cipher</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">m2</span><span class="p">,</span> <span class="n">alg</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">cipher</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">&#39;unknown cipher&#39;</span><span class="p">,</span> <span class="n">alg</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">cipher</span> <span class="o">=</span> <span class="n">cipher</span><span class="p">()</span>
+ <span class="k">if</span> <span class="n">key_as_bytes</span><span class="p">:</span>
+ <span class="n">kmd</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">m2</span><span class="p">,</span> <span class="n">d</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">kmd</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">&#39;unknown message digest&#39;</span><span class="p">,</span> <span class="n">d</span><span class="p">)</span>
+ <span class="n">key</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">bytes_to_key</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">cipher</span><span class="p">,</span> <span class="n">kmd</span><span class="p">(),</span> <span class="n">key</span><span class="p">,</span> <span class="n">salt</span><span class="p">,</span> <span class="n">iv</span><span class="p">,</span> <span class="n">i</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">ctx</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">cipher_ctx_new</span><span class="p">()</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">cipher_init</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">cipher</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">iv</span><span class="p">,</span> <span class="n">op</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">set_padding</span><span class="p">(</span><span class="n">padding</span><span class="p">)</span>
+ <span class="k">del</span> <span class="n">key</span>
+
+ <span class="k">def</span> <span class="nf">__del__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;ctx&#39;</span><span class="p">,</span> <span class="kc">None</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">m2_cipher_ctx_free</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">)</span>
+
+<div class="viewcode-block" id="Cipher.update"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EVP.Cipher.update">[docs]</a> <span class="k">def</span> <span class="nf">update</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
+ <span class="c1"># type: (bytes) -&gt; bytes</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">cipher_update</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Cipher.final"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EVP.Cipher.final">[docs]</a> <span class="k">def</span> <span class="nf">final</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; bytes</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">cipher_final</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Cipher.set_padding"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EVP.Cipher.set_padding">[docs]</a> <span class="k">def</span> <span class="nf">set_padding</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">padding</span><span class="o">=</span><span class="mi">1</span><span class="p">):</span>
+ <span class="c1"># type: (int) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Actually always return 1</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">cipher_set_padding</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">,</span> <span class="n">padding</span><span class="p">)</span></div></div>
+
+
+<div class="viewcode-block" id="PKey"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EVP.PKey">[docs]</a><span class="k">class</span> <span class="nc">PKey</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Public Key</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+
+ <span class="n">m2_pkey_free</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">pkey_free</span>
+ <span class="n">m2_md_ctx_free</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">md_ctx_free</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">pkey</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">_pyfree</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">md</span><span class="o">=</span><span class="s1">&#39;sha1&#39;</span><span class="p">):</span>
+ <span class="c1"># type: (Optional[bytes], int, str) -&gt; None</span>
+ <span class="k">if</span> <span class="n">pkey</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">pkey</span> <span class="o">=</span> <span class="n">pkey</span> <span class="c1"># type: bytes</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_pyfree</span> <span class="o">=</span> <span class="n">_pyfree</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">pkey</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">pkey_new</span><span class="p">()</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_pyfree</span> <span class="o">=</span> <span class="mi">1</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_set_context</span><span class="p">(</span><span class="n">md</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">__del__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;_pyfree&#39;</span><span class="p">,</span> <span class="mi">0</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">m2_pkey_free</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">pkey</span><span class="p">)</span>
+ <span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;ctx&#39;</span><span class="p">,</span> <span class="kc">None</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">m2_md_ctx_free</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">_ptr</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">pkey</span>
+
+ <span class="k">def</span> <span class="nf">_set_context</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">md</span><span class="p">):</span>
+ <span class="c1"># type: (str) -&gt; None</span>
+ <span class="n">mda</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">m2</span><span class="p">,</span> <span class="n">md</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> <span class="c1"># type: Optional[Callable]</span>
+ <span class="k">if</span> <span class="n">mda</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">&#39;unknown message digest&#39;</span><span class="p">,</span> <span class="n">md</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">md</span> <span class="o">=</span> <span class="n">mda</span><span class="p">()</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">ctx</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">md_ctx_new</span><span class="p">()</span> <span class="c1"># type: Context</span>
+
+<div class="viewcode-block" id="PKey.reset_context"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EVP.PKey.reset_context">[docs]</a> <span class="k">def</span> <span class="nf">reset_context</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">md</span><span class="o">=</span><span class="s1">&#39;sha1&#39;</span><span class="p">):</span>
+ <span class="c1"># type: (str) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Reset internal message digest context.</span>
+
+<span class="sd"> :param md: The message digest algorithm.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_set_context</span><span class="p">(</span><span class="n">md</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="PKey.sign_init"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EVP.PKey.sign_init">[docs]</a> <span class="k">def</span> <span class="nf">sign_init</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Initialise signing operation with self.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">sign_init</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">md</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="PKey.sign_update"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EVP.PKey.sign_update">[docs]</a> <span class="k">def</span> <span class="nf">sign_update</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
+ <span class="c1"># type: (bytes) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Feed data to signing operation.</span>
+
+<span class="sd"> :param data: Data to be signed.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">sign_update</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="PKey.sign_final"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EVP.PKey.sign_final">[docs]</a> <span class="k">def</span> <span class="nf">sign_final</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; bytes</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Return signature.</span>
+
+<span class="sd"> :return: The signature.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">sign_final</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">pkey</span><span class="p">)</span></div>
+
+ <span class="c1"># Deprecated</span>
+ <span class="n">update</span> <span class="o">=</span> <span class="n">sign_update</span>
+ <span class="n">final</span> <span class="o">=</span> <span class="n">sign_final</span>
+
+<div class="viewcode-block" id="PKey.verify_init"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EVP.PKey.verify_init">[docs]</a> <span class="k">def</span> <span class="nf">verify_init</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Initialise signature verification operation with self.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">verify_init</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">md</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="PKey.verify_update"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EVP.PKey.verify_update">[docs]</a> <span class="k">def</span> <span class="nf">verify_update</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
+ <span class="c1"># type: (bytes) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Feed data to verification operation.</span>
+
+<span class="sd"> :param data: Data to be verified.</span>
+<span class="sd"> :return: -1 on Python error, 1 for success, 0 for OpenSSL error</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">verify_update</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="PKey.verify_final"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EVP.PKey.verify_final">[docs]</a> <span class="k">def</span> <span class="nf">verify_final</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">sign</span><span class="p">):</span>
+ <span class="c1"># type: (bytes) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Return result of verification.</span>
+
+<span class="sd"> :param sign: Signature to use for verification</span>
+<span class="sd"> :return: Result of verification: 1 for success, 0 for failure, -1 on</span>
+<span class="sd"> other error.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">verify_final</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">,</span> <span class="n">sign</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">pkey</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="PKey.assign_rsa"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EVP.PKey.assign_rsa">[docs]</a> <span class="k">def</span> <span class="nf">assign_rsa</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">rsa</span><span class="p">,</span> <span class="n">capture</span><span class="o">=</span><span class="mi">1</span><span class="p">):</span>
+ <span class="c1"># type: (RSA.RSA, int) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Assign the RSA key pair to self.</span>
+
+<span class="sd"> :param rsa: M2Crypto.RSA.RSA object to be assigned to self.</span>
+
+<span class="sd"> :param capture: If true (default), this PKey object will own the RSA</span>
+<span class="sd"> object, meaning that once the PKey object gets</span>
+<span class="sd"> deleted it is no longer safe to use the RSA object.</span>
+
+<span class="sd"> :return: Return 1 for success and 0 for failure.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">if</span> <span class="n">capture</span><span class="p">:</span>
+ <span class="n">ret</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">pkey_assign_rsa</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">pkey</span><span class="p">,</span> <span class="n">rsa</span><span class="o">.</span><span class="n">rsa</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">ret</span><span class="p">:</span>
+ <span class="n">rsa</span><span class="o">.</span><span class="n">_pyfree</span> <span class="o">=</span> <span class="mi">0</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">ret</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">pkey_set1_rsa</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">pkey</span><span class="p">,</span> <span class="n">rsa</span><span class="o">.</span><span class="n">rsa</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">ret</span></div>
+
+<div class="viewcode-block" id="PKey.get_rsa"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EVP.PKey.get_rsa">[docs]</a> <span class="k">def</span> <span class="nf">get_rsa</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; RSA.RSA_pub</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Return the underlying RSA key if that is what the EVP</span>
+<span class="sd"> instance is holding.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">rsa_ptr</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">pkey_get1_rsa</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">pkey</span><span class="p">)</span>
+
+ <span class="n">rsa</span> <span class="o">=</span> <span class="n">RSA</span><span class="o">.</span><span class="n">RSA_pub</span><span class="p">(</span><span class="n">rsa_ptr</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">rsa</span></div>
+
+<div class="viewcode-block" id="PKey.save_key"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EVP.PKey.save_key">[docs]</a> <span class="k">def</span> <span class="nf">save_key</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">file</span><span class="p">,</span> <span class="n">cipher</span><span class="o">=</span><span class="s1">&#39;aes_128_cbc&#39;</span><span class="p">,</span>
+ <span class="n">callback</span><span class="o">=</span><span class="n">util</span><span class="o">.</span><span class="n">passphrase_callback</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr, Optional[str], Callable) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Save the key pair to a file in PEM format.</span>
+
+<span class="sd"> :param file: Name of file to save key to.</span>
+
+<span class="sd"> :param cipher: Symmetric cipher to protect the key. The default</span>
+<span class="sd"> cipher is &#39;aes_128_cbc&#39;. If cipher is None, then</span>
+<span class="sd"> the key is saved in the clear.</span>
+
+<span class="sd"> :param callback: A Python callable object that is invoked</span>
+<span class="sd"> to acquire a passphrase with which to protect</span>
+<span class="sd"> the key. The default is</span>
+<span class="sd"> util.passphrase_callback.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">with</span> <span class="n">BIO</span><span class="o">.</span><span class="n">openfile</span><span class="p">(</span><span class="n">file</span><span class="p">,</span> <span class="s1">&#39;wb&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">bio</span><span class="p">:</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">save_key_bio</span><span class="p">(</span><span class="n">bio</span><span class="p">,</span> <span class="n">cipher</span><span class="p">,</span> <span class="n">callback</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="PKey.save_key_bio"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EVP.PKey.save_key_bio">[docs]</a> <span class="k">def</span> <span class="nf">save_key_bio</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bio</span><span class="p">,</span> <span class="n">cipher</span><span class="o">=</span><span class="s1">&#39;aes_128_cbc&#39;</span><span class="p">,</span>
+ <span class="n">callback</span><span class="o">=</span><span class="n">util</span><span class="o">.</span><span class="n">passphrase_callback</span><span class="p">):</span>
+ <span class="c1"># type: (BIO.BIO, Optional[str], Callable) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Save the key pair to the M2Crypto.BIO object &#39;bio&#39; in PEM format.</span>
+
+<span class="sd"> :param bio: M2Crypto.BIO object to save key to.</span>
+
+<span class="sd"> :param cipher: Symmetric cipher to protect the key. The default</span>
+<span class="sd"> cipher is &#39;aes_128_cbc&#39;. If cipher is None, then</span>
+<span class="sd"> the key is saved in the clear.</span>
+
+<span class="sd"> :param callback: A Python callable object that is invoked</span>
+<span class="sd"> to acquire a passphrase with which to protect</span>
+<span class="sd"> the key. The default is</span>
+<span class="sd"> util.passphrase_callback.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">if</span> <span class="n">cipher</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">pkey_write_pem_no_cipher</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">pkey</span><span class="p">,</span> <span class="n">bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span> <span class="n">callback</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">proto</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">m2</span><span class="p">,</span> <span class="n">cipher</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">proto</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">&#39;no such cipher </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">cipher</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">pkey_write_pem</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">pkey</span><span class="p">,</span> <span class="n">bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span> <span class="n">proto</span><span class="p">(),</span> <span class="n">callback</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="PKey.as_pem"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EVP.PKey.as_pem">[docs]</a> <span class="k">def</span> <span class="nf">as_pem</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">cipher</span><span class="o">=</span><span class="s1">&#39;aes_128_cbc&#39;</span><span class="p">,</span> <span class="n">callback</span><span class="o">=</span><span class="n">util</span><span class="o">.</span><span class="n">passphrase_callback</span><span class="p">):</span>
+ <span class="c1"># type: (Optional[str], Callable) -&gt; bytes</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Return key in PEM format in a string.</span>
+
+<span class="sd"> :param cipher: Symmetric cipher to protect the key. The default</span>
+<span class="sd"> cipher is ``&#39;aes_128_cbc&#39;``. If cipher is None,</span>
+<span class="sd"> then the key is saved in the clear.</span>
+
+<span class="sd"> :param callback: A Python callable object that is invoked</span>
+<span class="sd"> to acquire a passphrase with which to protect</span>
+<span class="sd"> the key. The default is</span>
+<span class="sd"> util.passphrase_callback.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">bio</span> <span class="o">=</span> <span class="n">BIO</span><span class="o">.</span><span class="n">MemoryBuffer</span><span class="p">()</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">save_key_bio</span><span class="p">(</span><span class="n">bio</span><span class="p">,</span> <span class="n">cipher</span><span class="p">,</span> <span class="n">callback</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">bio</span><span class="o">.</span><span class="n">read_all</span><span class="p">()</span></div>
+
+<div class="viewcode-block" id="PKey.as_der"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EVP.PKey.as_der">[docs]</a> <span class="k">def</span> <span class="nf">as_der</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; bytes</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Return key in DER format in a string</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">buf</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">pkey_as_der</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">pkey</span><span class="p">)</span>
+ <span class="n">bio</span> <span class="o">=</span> <span class="n">BIO</span><span class="o">.</span><span class="n">MemoryBuffer</span><span class="p">(</span><span class="n">buf</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">bio</span><span class="o">.</span><span class="n">read_all</span><span class="p">()</span></div>
+
+<div class="viewcode-block" id="PKey.size"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EVP.PKey.size">[docs]</a> <span class="k">def</span> <span class="nf">size</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Return the size of the key in bytes.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">pkey_size</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">pkey</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="PKey.get_modulus"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EVP.PKey.get_modulus">[docs]</a> <span class="k">def</span> <span class="nf">get_modulus</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; Optional[bytes]</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Return the modulus in hex format.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">pkey_get_modulus</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">pkey</span><span class="p">)</span></div></div>
+
+
+<div class="viewcode-block" id="load_key"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EVP.load_key">[docs]</a><span class="k">def</span> <span class="nf">load_key</span><span class="p">(</span><span class="n">file</span><span class="p">,</span> <span class="n">callback</span><span class="o">=</span><span class="n">util</span><span class="o">.</span><span class="n">passphrase_callback</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr, Callable) -&gt; PKey</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Load an M2Crypto.EVP.PKey from file.</span>
+
+<span class="sd"> :param file: Name of file containing the key in PEM format.</span>
+
+<span class="sd"> :param callback: A Python callable object that is invoked</span>
+<span class="sd"> to acquire a passphrase with which to protect the</span>
+<span class="sd"> key.</span>
+
+<span class="sd"> :return: M2Crypto.EVP.PKey object.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">with</span> <span class="n">BIO</span><span class="o">.</span><span class="n">openfile</span><span class="p">(</span><span class="n">file</span><span class="p">,</span> <span class="s1">&#39;r&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">bio</span><span class="p">:</span>
+ <span class="n">cptr</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">pkey_read_pem</span><span class="p">(</span><span class="n">bio</span><span class="o">.</span><span class="n">bio</span><span class="p">,</span> <span class="n">callback</span><span class="p">)</span>
+
+ <span class="k">return</span> <span class="n">PKey</span><span class="p">(</span><span class="n">cptr</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="load_key_bio"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EVP.load_key_bio">[docs]</a><span class="k">def</span> <span class="nf">load_key_bio</span><span class="p">(</span><span class="n">bio</span><span class="p">,</span> <span class="n">callback</span><span class="o">=</span><span class="n">util</span><span class="o">.</span><span class="n">passphrase_callback</span><span class="p">):</span>
+ <span class="c1"># type: (BIO.BIO, Callable) -&gt; PKey</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Load an M2Crypto.EVP.PKey from an M2Crypto.BIO object.</span>
+
+<span class="sd"> :param bio: M2Crypto.BIO object containing the key in PEM format.</span>
+
+<span class="sd"> :param callback: A Python callable object that is invoked</span>
+<span class="sd"> to acquire a passphrase with which to protect the</span>
+<span class="sd"> key.</span>
+
+<span class="sd"> :return: M2Crypto.EVP.PKey object.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">cptr</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">pkey_read_pem</span><span class="p">(</span><span class="n">bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span> <span class="n">callback</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">PKey</span><span class="p">(</span><span class="n">cptr</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="load_key_bio_pubkey"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EVP.load_key_bio_pubkey">[docs]</a><span class="k">def</span> <span class="nf">load_key_bio_pubkey</span><span class="p">(</span><span class="n">bio</span><span class="p">,</span> <span class="n">callback</span><span class="o">=</span><span class="n">util</span><span class="o">.</span><span class="n">passphrase_callback</span><span class="p">):</span>
+ <span class="c1"># type: (BIO.BIO, Callable) -&gt; PKey</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Load an M2Crypto.EVP.PKey from a public key as a M2Crypto.BIO object.</span>
+
+<span class="sd"> :param bio: M2Crypto.BIO object containing the key in PEM format.</span>
+
+<span class="sd"> :param callback: A Python callable object that is invoked</span>
+<span class="sd"> to acquire a passphrase with which to protect the</span>
+<span class="sd"> key.</span>
+
+<span class="sd"> :return: M2Crypto.EVP.PKey object.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">cptr</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">pkey_read_pem_pubkey</span><span class="p">(</span><span class="n">bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span> <span class="n">callback</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">cptr</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="n">EVPError</span><span class="p">(</span><span class="n">Err</span><span class="o">.</span><span class="n">get_error</span><span class="p">())</span>
+ <span class="k">return</span> <span class="n">PKey</span><span class="p">(</span><span class="n">cptr</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="load_key_string"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EVP.load_key_string">[docs]</a><span class="k">def</span> <span class="nf">load_key_string</span><span class="p">(</span><span class="n">string</span><span class="p">,</span> <span class="n">callback</span><span class="o">=</span><span class="n">util</span><span class="o">.</span><span class="n">passphrase_callback</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr, Callable) -&gt; PKey</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Load an M2Crypto.EVP.PKey from a string.</span>
+
+<span class="sd"> :param string: String containing the key in PEM format.</span>
+
+<span class="sd"> :param callback: A Python callable object that is invoked</span>
+<span class="sd"> to acquire a passphrase with which to protect the</span>
+<span class="sd"> key.</span>
+
+<span class="sd"> :return: M2Crypto.EVP.PKey object.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">bio</span> <span class="o">=</span> <span class="n">BIO</span><span class="o">.</span><span class="n">MemoryBuffer</span><span class="p">(</span><span class="n">string</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">load_key_bio</span><span class="p">(</span><span class="n">bio</span><span class="p">,</span> <span class="n">callback</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="load_key_string_pubkey"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.EVP.load_key_string_pubkey">[docs]</a><span class="k">def</span> <span class="nf">load_key_string_pubkey</span><span class="p">(</span><span class="n">string</span><span class="p">,</span> <span class="n">callback</span><span class="o">=</span><span class="n">util</span><span class="o">.</span><span class="n">passphrase_callback</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr, Callable) -&gt; PKey</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Load an M2Crypto.EVP.PKey from a public key as a string.</span>
+
+<span class="sd"> :param string: String containing the key in PEM format.</span>
+
+<span class="sd"> :param callback: A Python callable object that is invoked</span>
+<span class="sd"> to acquire a passphrase with which to protect the</span>
+<span class="sd"> key.</span>
+
+<span class="sd"> :return: M2Crypto.EVP.PKey object.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">bio</span> <span class="o">=</span> <span class="n">BIO</span><span class="o">.</span><span class="n">MemoryBuffer</span><span class="p">(</span><span class="n">string</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">load_key_bio_pubkey</span><span class="p">(</span><span class="n">bio</span><span class="p">,</span> <span class="n">callback</span><span class="p">)</span></div>
+</pre></div>
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="../../index.html">M2Crypto</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="../../M2Crypto.html">M2Crypto Package</a></li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="../../index.html">Documentation overview</a><ul>
+ <li><a href="../index.html">Module code</a><ul>
+ </ul></li>
+ </ul></li>
+</ul>
+</div>
+<div id="searchbox" style="display: none" role="search">
+ <h3>Quick search</h3>
+ <div class="searchformwrapper">
+ <form class="search" action="../../search.html" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ </div>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer">
+ &copy;2017, Matej Cepl <mcepl@cepl.eu>.
+
+ |
+ Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
+ &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
+
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/_modules/M2Crypto/Engine.html b/doc/html/_modules/M2Crypto/Engine.html
new file mode 100644
index 0000000..4d8474c
--- /dev/null
+++ b/doc/html/_modules/M2Crypto/Engine.html
@@ -0,0 +1,254 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>M2Crypto.Engine &#8212; M2Crypto documentation</title>
+ <link rel="stylesheet" href="../../_static/alabaster.css" type="text/css" />
+ <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../../_static/jquery.js"></script>
+ <script type="text/javascript" src="../../_static/underscore.js"></script>
+ <script type="text/javascript" src="../../_static/doctools.js"></script>
+ <script type="text/javascript" src="../../_static/language_data.js"></script>
+ <link rel="index" title="Index" href="../../genindex.html" />
+ <link rel="search" title="Search" href="../../search.html" />
+
+ <link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+ <h1>Source code for M2Crypto.Engine</h1><div class="highlight"><pre>
+<span></span><span class="c1"># vim: sts=4 sw=4 et</span>
+<span class="kn">from</span> <span class="nn">__future__</span> <span class="k">import</span> <span class="n">absolute_import</span>
+
+<span class="sd">&quot;&quot;&quot;</span>
+<span class="sd">M2Crypto wrapper for OpenSSL ENGINE API.</span>
+
+<span class="sd">Pavel Shramov</span>
+<span class="sd">IMEC MSU</span>
+<span class="sd">&quot;&quot;&quot;</span>
+
+<span class="kn">from</span> <span class="nn">M2Crypto</span> <span class="k">import</span> <span class="n">EVP</span><span class="p">,</span> <span class="n">Err</span><span class="p">,</span> <span class="n">X509</span><span class="p">,</span> <span class="n">m2</span><span class="p">,</span> <span class="n">six</span><span class="p">,</span> <span class="n">util</span>
+<span class="k">if</span> <span class="n">util</span><span class="o">.</span><span class="n">py27plus</span><span class="p">:</span>
+ <span class="kn">from</span> <span class="nn">typing</span> <span class="k">import</span> <span class="n">AnyStr</span><span class="p">,</span> <span class="n">Callable</span><span class="p">,</span> <span class="n">Optional</span> <span class="c1"># noqa</span>
+
+
+<div class="viewcode-block" id="EngineError"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.Engine.EngineError">[docs]</a><span class="k">class</span> <span class="nc">EngineError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
+ <span class="k">pass</span></div>
+
+<span class="n">m2</span><span class="o">.</span><span class="n">engine_init_error</span><span class="p">(</span><span class="n">EngineError</span><span class="p">)</span>
+
+
+<div class="viewcode-block" id="Engine"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.Engine.Engine">[docs]</a><span class="k">class</span> <span class="nc">Engine</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Wrapper for ENGINE object.&quot;&quot;&quot;</span>
+
+ <span class="n">m2_engine_free</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">engine_free</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">id</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">_ptr</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">_pyfree</span><span class="o">=</span><span class="mi">1</span><span class="p">):</span>
+ <span class="c1"># type: (Optional[bytes], Optional[bytes], int) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;Create new Engine from ENGINE pointer or obtain by id&quot;&quot;&quot;</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">_ptr</span> <span class="ow">and</span> <span class="ow">not</span> <span class="nb">id</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;No engine id specified&quot;</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_ptr</span> <span class="o">=</span> <span class="n">_ptr</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_ptr</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_ptr</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">engine_by_id</span><span class="p">(</span><span class="nb">id</span><span class="p">)</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_ptr</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;Unknown engine: </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="nb">id</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_pyfree</span> <span class="o">=</span> <span class="n">_pyfree</span>
+
+ <span class="k">def</span> <span class="nf">__del__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;_pyfree&#39;</span><span class="p">,</span> <span class="mi">0</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">m2_engine_free</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_ptr</span><span class="p">)</span>
+
+<div class="viewcode-block" id="Engine.init"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.Engine.Engine.init">[docs]</a> <span class="k">def</span> <span class="nf">init</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;Obtain a functional reference to the engine.</span>
+
+<span class="sd"> :return: 0 on error, non-zero on success.&quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">engine_init</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_ptr</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Engine.finish"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.Engine.Engine.finish">[docs]</a> <span class="k">def</span> <span class="nf">finish</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;Release a functional and structural reference to the engine.&quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">engine_finish</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_ptr</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Engine.ctrl_cmd_string"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.Engine.Engine.ctrl_cmd_string">[docs]</a> <span class="k">def</span> <span class="nf">ctrl_cmd_string</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">cmd</span><span class="p">,</span> <span class="n">arg</span><span class="p">,</span> <span class="n">optional</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr, Optional[AnyStr], int) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;Call ENGINE_ctrl_cmd_string&quot;&quot;&quot;</span>
+ <span class="n">cmd</span> <span class="o">=</span> <span class="n">six</span><span class="o">.</span><span class="n">ensure_str</span><span class="p">(</span><span class="n">cmd</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">arg</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">arg</span> <span class="o">=</span> <span class="n">six</span><span class="o">.</span><span class="n">ensure_str</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">m2</span><span class="o">.</span><span class="n">engine_ctrl_cmd_string</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_ptr</span><span class="p">,</span> <span class="n">cmd</span><span class="p">,</span> <span class="n">arg</span><span class="p">,</span> <span class="n">optional</span><span class="p">):</span>
+ <span class="k">raise</span> <span class="n">EngineError</span><span class="p">(</span><span class="n">Err</span><span class="o">.</span><span class="n">get_error</span><span class="p">())</span></div>
+
+<div class="viewcode-block" id="Engine.get_name"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.Engine.Engine.get_name">[docs]</a> <span class="k">def</span> <span class="nf">get_name</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; bytes</span>
+ <span class="sd">&quot;&quot;&quot;Return engine name&quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">engine_get_name</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_ptr</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Engine.get_id"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.Engine.Engine.get_id">[docs]</a> <span class="k">def</span> <span class="nf">get_id</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; bytes</span>
+ <span class="sd">&quot;&quot;&quot;Return engine id&quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">engine_get_id</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_ptr</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Engine.set_default"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.Engine.Engine.set_default">[docs]</a> <span class="k">def</span> <span class="nf">set_default</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">methods</span><span class="o">=</span><span class="n">m2</span><span class="o">.</span><span class="n">ENGINE_METHOD_ALL</span><span class="p">):</span>
+ <span class="c1"># type: (int) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Use this engine as default for methods specified in argument</span>
+
+<span class="sd"> :param methods: Possible values are bitwise OR of m2.ENGINE_METHOD_*</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">engine_set_default</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_ptr</span><span class="p">,</span> <span class="n">methods</span><span class="p">)</span></div>
+
+ <span class="k">def</span> <span class="nf">_engine_load_key</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">func</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">pin</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="c1"># type: (Callable, bytes, Optional[bytes]) -&gt; EVP.PKey</span>
+ <span class="sd">&quot;&quot;&quot;Helper function for loading keys&quot;&quot;&quot;</span>
+ <span class="n">ui</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">ui_openssl</span><span class="p">()</span>
+ <span class="n">cbd</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">engine_pkcs11_data_new</span><span class="p">(</span><span class="n">pin</span><span class="p">)</span>
+ <span class="k">try</span><span class="p">:</span>
+ <span class="n">kptr</span> <span class="o">=</span> <span class="n">func</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_ptr</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">ui</span><span class="p">,</span> <span class="n">cbd</span><span class="p">)</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">kptr</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="n">EngineError</span><span class="p">(</span><span class="n">Err</span><span class="o">.</span><span class="n">get_error</span><span class="p">())</span>
+ <span class="n">key</span> <span class="o">=</span> <span class="n">EVP</span><span class="o">.</span><span class="n">PKey</span><span class="p">(</span><span class="n">kptr</span><span class="p">,</span> <span class="n">_pyfree</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
+ <span class="k">finally</span><span class="p">:</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">engine_pkcs11_data_free</span><span class="p">(</span><span class="n">cbd</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">key</span>
+
+<div class="viewcode-block" id="Engine.load_private_key"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.Engine.Engine.load_private_key">[docs]</a> <span class="k">def</span> <span class="nf">load_private_key</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">pin</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="c1"># type: (bytes, Optional[bytes]) -&gt; X509.X509</span>
+ <span class="sd">&quot;&quot;&quot;Load private key with engine methods (e.g from smartcard).</span>
+<span class="sd"> If pin is not set it will be asked</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_engine_load_key</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">engine_load_private_key</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">pin</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Engine.load_public_key"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.Engine.Engine.load_public_key">[docs]</a> <span class="k">def</span> <span class="nf">load_public_key</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">pin</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="c1"># type: (bytes, Optional[bytes]) -&gt; EVP.PKey</span>
+ <span class="sd">&quot;&quot;&quot;Load public key with engine methods (e.g from smartcard).&quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_engine_load_key</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">engine_load_public_key</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">pin</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Engine.load_certificate"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.Engine.Engine.load_certificate">[docs]</a> <span class="k">def</span> <span class="nf">load_certificate</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
+ <span class="c1"># type: (bytes) -&gt; X509.X509</span>
+ <span class="sd">&quot;&quot;&quot;Load certificate from engine (e.g from smartcard).</span>
+<span class="sd"> NOTE: This function may be not implemented by engine!&quot;&quot;&quot;</span>
+ <span class="n">cptr</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">engine_load_certificate</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_ptr</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">cptr</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="n">EngineError</span><span class="p">(</span><span class="s2">&quot;Certificate or card not found&quot;</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">X509</span><span class="o">.</span><span class="n">X509</span><span class="p">(</span><span class="n">cptr</span><span class="p">,</span> <span class="n">_pyfree</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span></div></div>
+
+
+<div class="viewcode-block" id="load_dynamic_engine"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.Engine.load_dynamic_engine">[docs]</a><span class="k">def</span> <span class="nf">load_dynamic_engine</span><span class="p">(</span><span class="nb">id</span><span class="p">,</span> <span class="n">sopath</span><span class="p">):</span>
+ <span class="c1"># type: (bytes, AnyStr) -&gt; Engine</span>
+ <span class="sd">&quot;&quot;&quot;Load and return dymanic engine from sopath and assign id to it&quot;&quot;&quot;</span>
+ <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">sopath</span><span class="p">,</span> <span class="n">six</span><span class="o">.</span><span class="n">text_type</span><span class="p">):</span>
+ <span class="n">sopath</span> <span class="o">=</span> <span class="n">sopath</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;utf8&#39;</span><span class="p">)</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">engine_load_dynamic</span><span class="p">()</span>
+ <span class="n">e</span> <span class="o">=</span> <span class="n">Engine</span><span class="p">(</span><span class="s1">&#39;dynamic&#39;</span><span class="p">)</span>
+ <span class="n">e</span><span class="o">.</span><span class="n">ctrl_cmd_string</span><span class="p">(</span><span class="s1">&#39;SO_PATH&#39;</span><span class="p">,</span> <span class="n">sopath</span><span class="p">)</span>
+ <span class="n">e</span><span class="o">.</span><span class="n">ctrl_cmd_string</span><span class="p">(</span><span class="s1">&#39;ID&#39;</span><span class="p">,</span> <span class="nb">id</span><span class="p">)</span>
+ <span class="n">e</span><span class="o">.</span><span class="n">ctrl_cmd_string</span><span class="p">(</span><span class="s1">&#39;LIST_ADD&#39;</span><span class="p">,</span> <span class="s1">&#39;1&#39;</span><span class="p">)</span>
+ <span class="n">e</span><span class="o">.</span><span class="n">ctrl_cmd_string</span><span class="p">(</span><span class="s1">&#39;LOAD&#39;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">e</span></div>
+
+
+<div class="viewcode-block" id="load_dynamic"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.Engine.load_dynamic">[docs]</a><span class="k">def</span> <span class="nf">load_dynamic</span><span class="p">():</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;Load dynamic engine&quot;&quot;&quot;</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">engine_load_dynamic</span><span class="p">()</span></div>
+
+
+<div class="viewcode-block" id="load_openssl"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.Engine.load_openssl">[docs]</a><span class="k">def</span> <span class="nf">load_openssl</span><span class="p">():</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;Load openssl engine&quot;&quot;&quot;</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">engine_load_openssl</span><span class="p">()</span></div>
+
+
+<div class="viewcode-block" id="cleanup"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.Engine.cleanup">[docs]</a><span class="k">def</span> <span class="nf">cleanup</span><span class="p">():</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;If you load any engines, you need to clean up after your application</span>
+<span class="sd"> is finished with the engines.&quot;&quot;&quot;</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">engine_cleanup</span><span class="p">()</span></div>
+</pre></div>
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="../../index.html">M2Crypto</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="../../M2Crypto.html">M2Crypto Package</a></li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="../../index.html">Documentation overview</a><ul>
+ <li><a href="../index.html">Module code</a><ul>
+ </ul></li>
+ </ul></li>
+</ul>
+</div>
+<div id="searchbox" style="display: none" role="search">
+ <h3>Quick search</h3>
+ <div class="searchformwrapper">
+ <form class="search" action="../../search.html" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ </div>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer">
+ &copy;2017, Matej Cepl <mcepl@cepl.eu>.
+
+ |
+ Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
+ &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
+
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/_modules/M2Crypto/Err.html b/doc/html/_modules/M2Crypto/Err.html
new file mode 100644
index 0000000..1688939
--- /dev/null
+++ b/doc/html/_modules/M2Crypto/Err.html
@@ -0,0 +1,177 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>M2Crypto.Err &#8212; M2Crypto documentation</title>
+ <link rel="stylesheet" href="../../_static/alabaster.css" type="text/css" />
+ <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../../_static/jquery.js"></script>
+ <script type="text/javascript" src="../../_static/underscore.js"></script>
+ <script type="text/javascript" src="../../_static/doctools.js"></script>
+ <script type="text/javascript" src="../../_static/language_data.js"></script>
+ <link rel="index" title="Index" href="../../genindex.html" />
+ <link rel="search" title="Search" href="../../search.html" />
+
+ <link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+ <h1>Source code for M2Crypto.Err</h1><div class="highlight"><pre>
+<span></span><span class="kn">from</span> <span class="nn">__future__</span> <span class="k">import</span> <span class="n">absolute_import</span>
+
+<span class="sd">&quot;&quot;&quot;M2Crypto wrapper for OpenSSL Error API.</span>
+
+<span class="sd">Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved.&quot;&quot;&quot;</span>
+
+<span class="kn">from</span> <span class="nn">M2Crypto</span> <span class="k">import</span> <span class="n">BIO</span><span class="p">,</span> <span class="n">m2</span><span class="p">,</span> <span class="n">py27plus</span><span class="p">,</span> <span class="n">util</span><span class="p">,</span> <span class="n">six</span> <span class="c1"># noqa</span>
+<span class="k">if</span> <span class="n">py27plus</span><span class="p">:</span>
+ <span class="kn">from</span> <span class="nn">typing</span> <span class="k">import</span> <span class="n">Optional</span> <span class="c1"># noqa</span>
+
+
+<div class="viewcode-block" id="get_error"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.Err.get_error">[docs]</a><span class="k">def</span> <span class="nf">get_error</span><span class="p">():</span>
+ <span class="c1"># type: () -&gt; Optional[str]</span>
+ <span class="n">err</span> <span class="o">=</span> <span class="n">BIO</span><span class="o">.</span><span class="n">MemoryBuffer</span><span class="p">()</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">err_print_errors</span><span class="p">(</span><span class="n">err</span><span class="o">.</span><span class="n">bio_ptr</span><span class="p">())</span>
+ <span class="n">err_msg</span> <span class="o">=</span> <span class="n">err</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
+ <span class="k">if</span> <span class="n">err_msg</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">six</span><span class="o">.</span><span class="n">ensure_text</span><span class="p">(</span><span class="n">err_msg</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="get_error_code"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.Err.get_error_code">[docs]</a><span class="k">def</span> <span class="nf">get_error_code</span><span class="p">():</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">err_get_error</span><span class="p">()</span></div>
+
+
+<div class="viewcode-block" id="peek_error_code"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.Err.peek_error_code">[docs]</a><span class="k">def</span> <span class="nf">peek_error_code</span><span class="p">():</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">err_peek_error</span><span class="p">()</span></div>
+
+
+<div class="viewcode-block" id="get_error_lib"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.Err.get_error_lib">[docs]</a><span class="k">def</span> <span class="nf">get_error_lib</span><span class="p">(</span><span class="n">err</span><span class="p">):</span>
+ <span class="c1"># type: (int) -&gt; str</span>
+ <span class="k">return</span> <span class="n">six</span><span class="o">.</span><span class="n">ensure_text</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">err_lib_error_string</span><span class="p">(</span><span class="n">err</span><span class="p">))</span></div>
+
+
+<div class="viewcode-block" id="get_error_func"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.Err.get_error_func">[docs]</a><span class="k">def</span> <span class="nf">get_error_func</span><span class="p">(</span><span class="n">err</span><span class="p">):</span>
+ <span class="c1"># type: (int) -&gt; str</span>
+ <span class="k">return</span> <span class="n">six</span><span class="o">.</span><span class="n">ensure_text</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">err_func_error_string</span><span class="p">(</span><span class="n">err</span><span class="p">))</span></div>
+
+
+<div class="viewcode-block" id="get_error_reason"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.Err.get_error_reason">[docs]</a><span class="k">def</span> <span class="nf">get_error_reason</span><span class="p">(</span><span class="n">err</span><span class="p">):</span>
+ <span class="c1"># type: (int) -&gt; str</span>
+ <span class="k">return</span> <span class="n">six</span><span class="o">.</span><span class="n">ensure_text</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">err_reason_error_string</span><span class="p">(</span><span class="n">err</span><span class="p">))</span></div>
+
+
+<div class="viewcode-block" id="get_error_message"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.Err.get_error_message">[docs]</a><span class="k">def</span> <span class="nf">get_error_message</span><span class="p">():</span>
+ <span class="c1"># type: () -&gt; str</span>
+ <span class="k">return</span> <span class="n">six</span><span class="o">.</span><span class="n">ensure_text</span><span class="p">(</span><span class="n">get_error_reason</span><span class="p">(</span><span class="n">get_error_code</span><span class="p">()))</span></div>
+
+
+<div class="viewcode-block" id="get_x509_verify_error"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.Err.get_x509_verify_error">[docs]</a><span class="k">def</span> <span class="nf">get_x509_verify_error</span><span class="p">(</span><span class="n">err</span><span class="p">):</span>
+ <span class="c1"># type: (int) -&gt; str</span>
+ <span class="k">return</span> <span class="n">six</span><span class="o">.</span><span class="n">ensure_text</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">x509_get_verify_error</span><span class="p">(</span><span class="n">err</span><span class="p">))</span></div>
+
+
+<div class="viewcode-block" id="SSLError"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.Err.SSLError">[docs]</a><span class="k">class</span> <span class="nc">SSLError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">err</span><span class="p">,</span> <span class="n">client_addr</span><span class="p">):</span>
+ <span class="c1"># type: (int, util.AddrType) -&gt; None</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">err</span> <span class="o">=</span> <span class="n">err</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">client_addr</span> <span class="o">=</span> <span class="n">client_addr</span>
+
+ <span class="k">def</span> <span class="nf">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; str</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">client_addr</span><span class="p">,</span> <span class="n">six</span><span class="o">.</span><span class="n">text_type</span><span class="p">):</span>
+ <span class="n">s</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">client_addr</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s1">&#39;utf8&#39;</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">s</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">client_addr</span>
+ <span class="k">return</span> <span class="s2">&quot;</span><span class="si">%s</span><span class="s2">: </span><span class="si">%s</span><span class="s2">: </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">get_error_func</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">err</span><span class="p">),</span> <span class="n">s</span><span class="p">,</span>
+ <span class="n">get_error_reason</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">err</span><span class="p">))</span></div>
+
+
+<div class="viewcode-block" id="M2CryptoError"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.Err.M2CryptoError">[docs]</a><span class="k">class</span> <span class="nc">M2CryptoError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
+ <span class="k">pass</span></div>
+</pre></div>
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="../../index.html">M2Crypto</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="../../M2Crypto.html">M2Crypto Package</a></li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="../../index.html">Documentation overview</a><ul>
+ <li><a href="../index.html">Module code</a><ul>
+ </ul></li>
+ </ul></li>
+</ul>
+</div>
+<div id="searchbox" style="display: none" role="search">
+ <h3>Quick search</h3>
+ <div class="searchformwrapper">
+ <form class="search" action="../../search.html" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ </div>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer">
+ &copy;2017, Matej Cepl <mcepl@cepl.eu>.
+
+ |
+ Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
+ &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
+
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/_modules/M2Crypto/RC4.html b/doc/html/_modules/M2Crypto/RC4.html
new file mode 100644
index 0000000..95456f5
--- /dev/null
+++ b/doc/html/_modules/M2Crypto/RC4.html
@@ -0,0 +1,140 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>M2Crypto.RC4 &#8212; M2Crypto documentation</title>
+ <link rel="stylesheet" href="../../_static/alabaster.css" type="text/css" />
+ <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../../_static/jquery.js"></script>
+ <script type="text/javascript" src="../../_static/underscore.js"></script>
+ <script type="text/javascript" src="../../_static/doctools.js"></script>
+ <script type="text/javascript" src="../../_static/language_data.js"></script>
+ <link rel="index" title="Index" href="../../genindex.html" />
+ <link rel="search" title="Search" href="../../search.html" />
+
+ <link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+ <h1>Source code for M2Crypto.RC4</h1><div class="highlight"><pre>
+<span></span><span class="kn">from</span> <span class="nn">__future__</span> <span class="k">import</span> <span class="n">absolute_import</span>
+
+<span class="sd">&quot;&quot;&quot;M2Crypto wrapper for OpenSSL RC4 API.</span>
+
+<span class="sd">Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved.&quot;&quot;&quot;</span>
+
+<span class="kn">from</span> <span class="nn">M2Crypto.m2</span> <span class="k">import</span> <span class="n">rc4_free</span><span class="p">,</span> <span class="n">rc4_new</span><span class="p">,</span> <span class="n">rc4_set_key</span><span class="p">,</span> <span class="n">rc4_update</span>
+
+
+<div class="viewcode-block" id="RC4"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.RC4.RC4">[docs]</a><span class="k">class</span> <span class="nc">RC4</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Object interface to the stream cipher RC4.&quot;&quot;&quot;</span>
+
+ <span class="n">rc4_free</span> <span class="o">=</span> <span class="n">rc4_free</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="c1"># type: (bytes) -&gt; None</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">cipher</span> <span class="o">=</span> <span class="n">rc4_new</span><span class="p">()</span>
+ <span class="k">if</span> <span class="n">key</span><span class="p">:</span>
+ <span class="n">rc4_set_key</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">cipher</span><span class="p">,</span> <span class="n">key</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">__del__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;cipher&#39;</span><span class="p">,</span> <span class="kc">None</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">rc4_free</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">cipher</span><span class="p">)</span>
+
+<div class="viewcode-block" id="RC4.set_key"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.RC4.RC4.set_key">[docs]</a> <span class="k">def</span> <span class="nf">set_key</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">):</span>
+ <span class="c1"># type: (bytes) -&gt; None</span>
+ <span class="n">rc4_set_key</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">cipher</span><span class="p">,</span> <span class="n">key</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="RC4.update"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.RC4.RC4.update">[docs]</a> <span class="k">def</span> <span class="nf">update</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
+ <span class="c1"># type: (bytes) -&gt; bytes</span>
+ <span class="k">return</span> <span class="n">rc4_update</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">cipher</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="RC4.final"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.RC4.RC4.final">[docs]</a> <span class="k">def</span> <span class="nf">final</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; str</span>
+ <span class="k">return</span> <span class="s1">&#39;&#39;</span></div></div>
+</pre></div>
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="../../index.html">M2Crypto</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="../../M2Crypto.html">M2Crypto Package</a></li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="../../index.html">Documentation overview</a><ul>
+ <li><a href="../index.html">Module code</a><ul>
+ </ul></li>
+ </ul></li>
+</ul>
+</div>
+<div id="searchbox" style="display: none" role="search">
+ <h3>Quick search</h3>
+ <div class="searchformwrapper">
+ <form class="search" action="../../search.html" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ </div>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer">
+ &copy;2017, Matej Cepl <mcepl@cepl.eu>.
+
+ |
+ Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
+ &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
+
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/_modules/M2Crypto/RSA.html b/doc/html/_modules/M2Crypto/RSA.html
new file mode 100644
index 0000000..172316b
--- /dev/null
+++ b/doc/html/_modules/M2Crypto/RSA.html
@@ -0,0 +1,570 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>M2Crypto.RSA &#8212; M2Crypto documentation</title>
+ <link rel="stylesheet" href="../../_static/alabaster.css" type="text/css" />
+ <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../../_static/jquery.js"></script>
+ <script type="text/javascript" src="../../_static/underscore.js"></script>
+ <script type="text/javascript" src="../../_static/doctools.js"></script>
+ <script type="text/javascript" src="../../_static/language_data.js"></script>
+ <link rel="index" title="Index" href="../../genindex.html" />
+ <link rel="search" title="Search" href="../../search.html" />
+
+ <link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+ <h1>Source code for M2Crypto.RSA</h1><div class="highlight"><pre>
+<span></span><span class="kn">from</span> <span class="nn">__future__</span> <span class="k">import</span> <span class="n">absolute_import</span>
+
+<span class="sd">&quot;&quot;&quot;M2Crypto wrapper for OpenSSL RSA API.</span>
+
+<span class="sd">Copyright (c) 1999-2004 Ng Pheng Siong. All rights reserved.&quot;&quot;&quot;</span>
+
+<span class="kn">import</span> <span class="nn">sys</span>
+
+<span class="kn">from</span> <span class="nn">M2Crypto</span> <span class="k">import</span> <span class="n">BIO</span><span class="p">,</span> <span class="n">Err</span><span class="p">,</span> <span class="n">m2</span><span class="p">,</span> <span class="n">util</span>
+<span class="k">if</span> <span class="n">util</span><span class="o">.</span><span class="n">py27plus</span><span class="p">:</span>
+ <span class="kn">from</span> <span class="nn">typing</span> <span class="k">import</span> <span class="n">Any</span><span class="p">,</span> <span class="n">AnyStr</span><span class="p">,</span> <span class="n">Callable</span><span class="p">,</span> <span class="n">Dict</span><span class="p">,</span> <span class="n">List</span><span class="p">,</span> <span class="n">IO</span><span class="p">,</span> <span class="n">Optional</span><span class="p">,</span> <span class="n">Tuple</span> <span class="c1"># noqa</span>
+
+
+<div class="viewcode-block" id="RSAError"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.RSA.RSAError">[docs]</a><span class="k">class</span> <span class="nc">RSAError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
+ <span class="k">pass</span></div>
+
+<span class="n">m2</span><span class="o">.</span><span class="n">rsa_init</span><span class="p">(</span><span class="n">RSAError</span><span class="p">)</span>
+
+<span class="n">no_padding</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">no_padding</span>
+<span class="n">pkcs1_padding</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">pkcs1_padding</span>
+<span class="n">sslv23_padding</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">sslv23_padding</span>
+<span class="n">pkcs1_oaep_padding</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">pkcs1_oaep_padding</span>
+
+
+<div class="viewcode-block" id="RSA"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.RSA.RSA">[docs]</a><span class="k">class</span> <span class="nc">RSA</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> RSA Key Pair.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+
+ <span class="n">m2_rsa_free</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">rsa_free</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">rsa</span><span class="p">,</span> <span class="n">_pyfree</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
+ <span class="c1"># type: (bytes, int) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> :param rsa: binary representation of OpenSSL RSA type</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">rsa_type_check</span><span class="p">(</span><span class="n">rsa</span><span class="p">),</span> <span class="s2">&quot;&#39;rsa&#39; type error&quot;</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">rsa</span> <span class="o">=</span> <span class="n">rsa</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_pyfree</span> <span class="o">=</span> <span class="n">_pyfree</span>
+
+ <span class="k">def</span> <span class="nf">__del__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;_pyfree&#39;</span><span class="p">,</span> <span class="mi">0</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">m2_rsa_free</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">rsa</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">__len__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="k">return</span> <span class="nb">int</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">rsa_size</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">rsa</span><span class="p">)</span> <span class="o">&lt;&lt;</span> <span class="mi">3</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">__getattr__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
+ <span class="c1"># type: (str) -&gt; bytes</span>
+ <span class="k">if</span> <span class="n">name</span> <span class="o">==</span> <span class="s1">&#39;e&#39;</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">rsa_get_e</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">rsa</span><span class="p">)</span>
+ <span class="k">elif</span> <span class="n">name</span> <span class="o">==</span> <span class="s1">&#39;n&#39;</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">rsa_get_n</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">rsa</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">AttributeError</span>
+
+<div class="viewcode-block" id="RSA.pub"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.RSA.RSA.pub">[docs]</a> <span class="k">def</span> <span class="nf">pub</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; Tuple[bytes, bytes]</span>
+ <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">check_key</span><span class="p">(),</span> <span class="s1">&#39;key is not initialised&#39;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">rsa_get_e</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">rsa</span><span class="p">),</span> <span class="n">m2</span><span class="o">.</span><span class="n">rsa_get_n</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">rsa</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="RSA.public_encrypt"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.RSA.RSA.public_encrypt">[docs]</a> <span class="k">def</span> <span class="nf">public_encrypt</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">padding</span><span class="p">):</span>
+ <span class="c1"># type: (bytes, int) -&gt; bytes</span>
+ <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">check_key</span><span class="p">(),</span> <span class="s1">&#39;key is not initialised&#39;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">rsa_public_encrypt</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">rsa</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">padding</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="RSA.public_decrypt"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.RSA.RSA.public_decrypt">[docs]</a> <span class="k">def</span> <span class="nf">public_decrypt</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">padding</span><span class="p">):</span>
+ <span class="c1"># type: (bytes, int) -&gt; bytes</span>
+ <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">check_key</span><span class="p">(),</span> <span class="s1">&#39;key is not initialised&#39;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">rsa_public_decrypt</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">rsa</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">padding</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="RSA.private_encrypt"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.RSA.RSA.private_encrypt">[docs]</a> <span class="k">def</span> <span class="nf">private_encrypt</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">padding</span><span class="p">):</span>
+ <span class="c1"># type: (bytes, int) -&gt; bytes</span>
+ <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">check_key</span><span class="p">(),</span> <span class="s1">&#39;key is not initialised&#39;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">rsa_private_encrypt</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">rsa</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">padding</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="RSA.private_decrypt"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.RSA.RSA.private_decrypt">[docs]</a> <span class="k">def</span> <span class="nf">private_decrypt</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">padding</span><span class="p">):</span>
+ <span class="c1"># type: (bytes, int) -&gt; bytes</span>
+ <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">check_key</span><span class="p">(),</span> <span class="s1">&#39;key is not initialised&#39;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">rsa_private_decrypt</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">rsa</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">padding</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="RSA.save_key_bio"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.RSA.RSA.save_key_bio">[docs]</a> <span class="k">def</span> <span class="nf">save_key_bio</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bio</span><span class="p">,</span> <span class="n">cipher</span><span class="o">=</span><span class="s1">&#39;aes_128_cbc&#39;</span><span class="p">,</span>
+ <span class="n">callback</span><span class="o">=</span><span class="n">util</span><span class="o">.</span><span class="n">passphrase_callback</span><span class="p">):</span>
+ <span class="c1"># type: (BIO.BIO, Optional[str], Callable) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Save the key pair to an M2Crypto.BIO.BIO object in PEM format.</span>
+
+<span class="sd"> :param bio: M2Crypto.BIO.BIO object to save key to.</span>
+
+<span class="sd"> :param cipher: Symmetric cipher to protect the key. The default</span>
+<span class="sd"> cipher is &#39;aes_128_cbc&#39;. If cipher is None, then</span>
+<span class="sd"> the key is saved in the clear.</span>
+
+<span class="sd"> :param callback: A Python callable object that is invoked</span>
+<span class="sd"> to acquire a passphrase with which to protect</span>
+<span class="sd"> the key. The default is</span>
+<span class="sd"> util.passphrase_callback.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">if</span> <span class="n">cipher</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">rsa_write_key_no_cipher</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">rsa</span><span class="p">,</span> <span class="n">bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span> <span class="n">callback</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">ciph</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">m2</span><span class="p">,</span> <span class="n">cipher</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">ciph</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="n">RSAError</span><span class="p">(</span><span class="s1">&#39;not such cipher </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">cipher</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">ciph</span> <span class="o">=</span> <span class="n">ciph</span><span class="p">()</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">rsa_write_key</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">rsa</span><span class="p">,</span> <span class="n">bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span> <span class="n">ciph</span><span class="p">,</span> <span class="n">callback</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="RSA.save_key"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.RSA.RSA.save_key">[docs]</a> <span class="k">def</span> <span class="nf">save_key</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">file</span><span class="p">,</span> <span class="n">cipher</span><span class="o">=</span><span class="s1">&#39;aes_128_cbc&#39;</span><span class="p">,</span>
+ <span class="n">callback</span><span class="o">=</span><span class="n">util</span><span class="o">.</span><span class="n">passphrase_callback</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr, Optional[str], Callable) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Save the key pair to a file in PEM format.</span>
+
+<span class="sd"> :param file: Name of file to save key to.</span>
+
+<span class="sd"> :param cipher: Symmetric cipher to protect the key. The default</span>
+<span class="sd"> cipher is &#39;aes_128_cbc&#39;. If cipher is None, then</span>
+<span class="sd"> the key is saved in the clear.</span>
+
+<span class="sd"> :param callback: A Python callable object that is invoked</span>
+<span class="sd"> to acquire a passphrase with which to protect</span>
+<span class="sd"> the key. The default is</span>
+<span class="sd"> util.passphrase_callback.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">with</span> <span class="n">BIO</span><span class="o">.</span><span class="n">openfile</span><span class="p">(</span><span class="n">file</span><span class="p">,</span> <span class="s1">&#39;wb&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">bio</span><span class="p">:</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">save_key_bio</span><span class="p">(</span><span class="n">bio</span><span class="p">,</span> <span class="n">cipher</span><span class="p">,</span> <span class="n">callback</span><span class="p">)</span></div>
+
+ <span class="n">save_pem</span> <span class="o">=</span> <span class="n">save_key</span>
+
+<div class="viewcode-block" id="RSA.as_pem"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.RSA.RSA.as_pem">[docs]</a> <span class="k">def</span> <span class="nf">as_pem</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">cipher</span><span class="o">=</span><span class="s1">&#39;aes_128_cbc&#39;</span><span class="p">,</span> <span class="n">callback</span><span class="o">=</span><span class="n">util</span><span class="o">.</span><span class="n">passphrase_callback</span><span class="p">):</span>
+ <span class="c1"># type: (Optional[str], Callable) -&gt; bytes</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Returns the key(pair) as a string in PEM format.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">bio</span> <span class="o">=</span> <span class="n">BIO</span><span class="o">.</span><span class="n">MemoryBuffer</span><span class="p">()</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">save_key_bio</span><span class="p">(</span><span class="n">bio</span><span class="p">,</span> <span class="n">cipher</span><span class="p">,</span> <span class="n">callback</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">bio</span><span class="o">.</span><span class="n">read</span><span class="p">()</span></div>
+
+<div class="viewcode-block" id="RSA.save_key_der_bio"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.RSA.RSA.save_key_der_bio">[docs]</a> <span class="k">def</span> <span class="nf">save_key_der_bio</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bio</span><span class="p">):</span>
+ <span class="c1"># type: (BIO.BIO) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Save the key pair to an M2Crypto.BIO.BIO object in DER format.</span>
+
+<span class="sd"> :param bio: M2Crypto.BIO.BIO object to save key to.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">rsa_write_key_der</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">rsa</span><span class="p">,</span> <span class="n">bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span></div>
+
+<div class="viewcode-block" id="RSA.save_key_der"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.RSA.RSA.save_key_der">[docs]</a> <span class="k">def</span> <span class="nf">save_key_der</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">file</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Save the key pair to a file in DER format.</span>
+
+<span class="sd"> :param file: Filename to save key to</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">with</span> <span class="n">BIO</span><span class="o">.</span><span class="n">openfile</span><span class="p">(</span><span class="n">file</span><span class="p">,</span> <span class="s1">&#39;wb&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">bio</span><span class="p">:</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">save_key_der_bio</span><span class="p">(</span><span class="n">bio</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="RSA.save_pub_key_bio"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.RSA.RSA.save_pub_key_bio">[docs]</a> <span class="k">def</span> <span class="nf">save_pub_key_bio</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bio</span><span class="p">):</span>
+ <span class="c1"># type: (BIO.BIO) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Save the public key to an M2Crypto.BIO.BIO object in PEM format.</span>
+
+<span class="sd"> :param bio: M2Crypto.BIO.BIO object to save key to.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">rsa_write_pub_key</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">rsa</span><span class="p">,</span> <span class="n">bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span></div>
+
+<div class="viewcode-block" id="RSA.save_pub_key"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.RSA.RSA.save_pub_key">[docs]</a> <span class="k">def</span> <span class="nf">save_pub_key</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">file</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Save the public key to a file in PEM format.</span>
+
+<span class="sd"> :param file: Name of file to save key to.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">with</span> <span class="n">BIO</span><span class="o">.</span><span class="n">openfile</span><span class="p">(</span><span class="n">file</span><span class="p">,</span> <span class="s1">&#39;wb&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">bio</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">rsa_write_pub_key</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">rsa</span><span class="p">,</span> <span class="n">bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span></div>
+
+<div class="viewcode-block" id="RSA.check_key"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.RSA.RSA.check_key">[docs]</a> <span class="k">def</span> <span class="nf">check_key</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Validate RSA keys.</span>
+
+<span class="sd"> It checks that p and q are in fact prime, and that n = p*q.</span>
+
+<span class="sd"> :return: returns 1 if rsa is a valid RSA key, and 0 otherwise.</span>
+<span class="sd"> -1 is returned if an error occurs while checking the key.</span>
+<span class="sd"> If the key is invalid or an error occurred, the reason</span>
+<span class="sd"> code can be obtained using ERR_get_error(3).</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">rsa_check_key</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">rsa</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="RSA.sign_rsassa_pss"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.RSA.RSA.sign_rsassa_pss">[docs]</a> <span class="k">def</span> <span class="nf">sign_rsassa_pss</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">digest</span><span class="p">,</span> <span class="n">algo</span><span class="o">=</span><span class="s1">&#39;sha1&#39;</span><span class="p">,</span> <span class="n">salt_length</span><span class="o">=</span><span class="mi">20</span><span class="p">):</span>
+ <span class="c1"># type: (bytes, str, int) -&gt; bytes</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Signs a digest with the private key using RSASSA-PSS</span>
+
+<span class="sd"> :param digest: A digest created by using the digest method</span>
+
+<span class="sd"> :param salt_length: The length of the salt to use</span>
+
+<span class="sd"> :param algo: The hash algorithm to use</span>
+<span class="sd"> Legal values like &#39;sha1&#39;,&#39;sha224&#39;, &#39;sha256&#39;,</span>
+<span class="sd"> &#39;ripemd160&#39;, and &#39;md5&#39;.</span>
+
+<span class="sd"> :return: a string which is the signature</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="nb">hash</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">m2</span><span class="p">,</span> <span class="n">algo</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
+
+ <span class="k">if</span> <span class="nb">hash</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="n">RSAError</span><span class="p">(</span><span class="s1">&#39;not such hash algorithm </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">algo</span><span class="p">)</span>
+
+ <span class="n">signature</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">rsa_padding_add_pkcs1_pss</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">rsa</span><span class="p">,</span> <span class="n">digest</span><span class="p">,</span> <span class="nb">hash</span><span class="p">(),</span> <span class="n">salt_length</span><span class="p">)</span>
+
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">private_encrypt</span><span class="p">(</span><span class="n">signature</span><span class="p">,</span> <span class="n">m2</span><span class="o">.</span><span class="n">no_padding</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="RSA.verify_rsassa_pss"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.RSA.RSA.verify_rsassa_pss">[docs]</a> <span class="k">def</span> <span class="nf">verify_rsassa_pss</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">signature</span><span class="p">,</span> <span class="n">algo</span><span class="o">=</span><span class="s1">&#39;sha1&#39;</span><span class="p">,</span> <span class="n">salt_length</span><span class="o">=</span><span class="mi">20</span><span class="p">):</span>
+ <span class="c1"># type: (bytes, bytes, str, int) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Verifies the signature RSASSA-PSS</span>
+
+<span class="sd"> :param data: Data that has been signed</span>
+
+<span class="sd"> :param signature: The signature signed with RSASSA-PSS</span>
+
+<span class="sd"> :param salt_length: The length of the salt that was used</span>
+
+<span class="sd"> :param algo: The hash algorithm to use</span>
+<span class="sd"> Legal values are for example &#39;sha1&#39;,&#39;sha224&#39;,</span>
+<span class="sd"> &#39;sha256&#39;, &#39;ripemd160&#39;, and &#39;md5&#39;.</span>
+
+<span class="sd"> :return: 1 or 0, depending on whether the signature was</span>
+<span class="sd"> verified or not.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="nb">hash</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">m2</span><span class="p">,</span> <span class="n">algo</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
+
+ <span class="k">if</span> <span class="nb">hash</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="n">RSAError</span><span class="p">(</span><span class="s1">&#39;not such hash algorithm </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">algo</span><span class="p">)</span>
+
+ <span class="n">plain_signature</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">public_decrypt</span><span class="p">(</span><span class="n">signature</span><span class="p">,</span> <span class="n">m2</span><span class="o">.</span><span class="n">no_padding</span><span class="p">)</span>
+
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">rsa_verify_pkcs1_pss</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">rsa</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">plain_signature</span><span class="p">,</span> <span class="nb">hash</span><span class="p">(),</span> <span class="n">salt_length</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="RSA.sign"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.RSA.RSA.sign">[docs]</a> <span class="k">def</span> <span class="nf">sign</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">digest</span><span class="p">,</span> <span class="n">algo</span><span class="o">=</span><span class="s1">&#39;sha1&#39;</span><span class="p">):</span>
+ <span class="c1"># type: (bytes, str) -&gt; bytes</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Signs a digest with the private key</span>
+
+<span class="sd"> :param digest: A digest created by using the digest method</span>
+
+<span class="sd"> :param algo: The method that created the digest.</span>
+<span class="sd"> Legal values like &#39;sha1&#39;,&#39;sha224&#39;, &#39;sha256&#39;,</span>
+<span class="sd"> &#39;ripemd160&#39;, and &#39;md5&#39;.</span>
+
+<span class="sd"> :return: a string which is the signature</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">digest_type</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">m2</span><span class="p">,</span> <span class="s1">&#39;NID_&#39;</span> <span class="o">+</span> <span class="n">algo</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">digest_type</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">&#39;unknown algorithm&#39;</span><span class="p">,</span> <span class="n">algo</span><span class="p">)</span>
+
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">rsa_sign</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">rsa</span><span class="p">,</span> <span class="n">digest</span><span class="p">,</span> <span class="n">digest_type</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="RSA.verify"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.RSA.RSA.verify">[docs]</a> <span class="k">def</span> <span class="nf">verify</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">signature</span><span class="p">,</span> <span class="n">algo</span><span class="o">=</span><span class="s1">&#39;sha1&#39;</span><span class="p">):</span>
+ <span class="c1"># type: (bytes, bytes, str) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Verifies the signature with the public key</span>
+
+<span class="sd"> :param data: Data that has been signed</span>
+
+<span class="sd"> :param signature: The signature signed with the private key</span>
+
+<span class="sd"> :param algo: The method use to create digest from the data</span>
+<span class="sd"> before it was signed. Legal values like</span>
+<span class="sd"> &#39;sha1&#39;,&#39;sha224&#39;, &#39;sha256&#39;, &#39;ripemd160&#39;, and &#39;md5&#39;.</span>
+
+<span class="sd"> :return: 1 or 0, depending on whether the signature was</span>
+<span class="sd"> verified or not.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">digest_type</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">m2</span><span class="p">,</span> <span class="s1">&#39;NID_&#39;</span> <span class="o">+</span> <span class="n">algo</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">digest_type</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">&#39;unknown algorithm&#39;</span><span class="p">,</span> <span class="n">algo</span><span class="p">)</span>
+
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">rsa_verify</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">rsa</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">signature</span><span class="p">,</span> <span class="n">digest_type</span><span class="p">)</span></div></div>
+
+
+<div class="viewcode-block" id="RSA_pub"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.RSA.RSA_pub">[docs]</a><span class="k">class</span> <span class="nc">RSA_pub</span><span class="p">(</span><span class="n">RSA</span><span class="p">):</span>
+
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Object interface to an RSA public key.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+
+ <span class="k">def</span> <span class="nf">__setattr__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
+ <span class="c1"># type: (str, bytes) -&gt; None</span>
+ <span class="k">if</span> <span class="n">name</span> <span class="ow">in</span> <span class="p">[</span><span class="s1">&#39;e&#39;</span><span class="p">,</span> <span class="s1">&#39;n&#39;</span><span class="p">]:</span>
+ <span class="k">raise</span> <span class="n">RSAError</span><span class="p">(</span><span class="s1">&#39;use factory function new_pub_key() to set (e, n)&#39;</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="vm">__dict__</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span>
+
+<div class="viewcode-block" id="RSA_pub.private_encrypt"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.RSA.RSA_pub.private_encrypt">[docs]</a> <span class="k">def</span> <span class="nf">private_encrypt</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">argv</span><span class="p">):</span>
+ <span class="c1"># type: (*Any) -&gt; None</span>
+ <span class="k">raise</span> <span class="n">RSAError</span><span class="p">(</span><span class="s1">&#39;RSA_pub object has no private key&#39;</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="RSA_pub.private_decrypt"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.RSA.RSA_pub.private_decrypt">[docs]</a> <span class="k">def</span> <span class="nf">private_decrypt</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">argv</span><span class="p">):</span>
+ <span class="c1"># type: (*Any) -&gt; None</span>
+ <span class="k">raise</span> <span class="n">RSAError</span><span class="p">(</span><span class="s1">&#39;RSA_pub object has no private key&#39;</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="RSA_pub.save_key"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.RSA.RSA_pub.save_key">[docs]</a> <span class="k">def</span> <span class="nf">save_key</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">file</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kw</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr, *Any, **Any) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Save public key to file.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">save_pub_key</span><span class="p">(</span><span class="n">file</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="RSA_pub.save_key_bio"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.RSA.RSA_pub.save_key_bio">[docs]</a> <span class="k">def</span> <span class="nf">save_key_bio</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bio</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kw</span><span class="p">):</span>
+ <span class="c1"># type: (BIO.BIO, *Any, **Any) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Save public key to BIO.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">save_pub_key_bio</span><span class="p">(</span><span class="n">bio</span><span class="p">)</span></div>
+
+ <span class="c1"># save_key_der</span>
+
+ <span class="c1"># save_key_der_bio</span>
+
+<div class="viewcode-block" id="RSA_pub.check_key"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.RSA.RSA_pub.check_key">[docs]</a> <span class="k">def</span> <span class="nf">check_key</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">rsa_check_pub_key</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">rsa</span><span class="p">)</span></div></div>
+
+
+<div class="viewcode-block" id="rsa_error"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.RSA.rsa_error">[docs]</a><span class="k">def</span> <span class="nf">rsa_error</span><span class="p">():</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="k">raise</span> <span class="n">RSAError</span><span class="p">(</span><span class="n">Err</span><span class="o">.</span><span class="n">get_error_message</span><span class="p">())</span></div>
+
+
+<div class="viewcode-block" id="keygen_callback"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.RSA.keygen_callback">[docs]</a><span class="k">def</span> <span class="nf">keygen_callback</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">n</span><span class="p">,</span> <span class="n">out</span><span class="o">=</span><span class="n">sys</span><span class="o">.</span><span class="n">stdout</span><span class="p">):</span>
+ <span class="c1"># type: (int, Any, IO[str]) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Default callback for gen_key().</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">ch</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;.&#39;</span><span class="p">,</span> <span class="s1">&#39;+&#39;</span><span class="p">,</span> <span class="s1">&#39;*&#39;</span><span class="p">,</span> <span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">]</span>
+ <span class="n">out</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">ch</span><span class="p">[</span><span class="n">p</span><span class="p">])</span>
+ <span class="n">out</span><span class="o">.</span><span class="n">flush</span><span class="p">()</span></div>
+
+
+<div class="viewcode-block" id="gen_key"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.RSA.gen_key">[docs]</a><span class="k">def</span> <span class="nf">gen_key</span><span class="p">(</span><span class="n">bits</span><span class="p">,</span> <span class="n">e</span><span class="p">,</span> <span class="n">callback</span><span class="o">=</span><span class="n">keygen_callback</span><span class="p">):</span>
+ <span class="c1"># type: (int, int, Callable) -&gt; RSA</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Generate an RSA key pair.</span>
+
+<span class="sd"> :param bits: Key length, in bits.</span>
+
+<span class="sd"> :param e: The RSA public exponent.</span>
+
+<span class="sd"> :param callback: A Python callable object that is invoked</span>
+<span class="sd"> during key generation; its usual purpose is to</span>
+<span class="sd"> provide visual feedback. The default callback is</span>
+<span class="sd"> keygen_callback.</span>
+
+<span class="sd"> :return: M2Crypto.RSA.RSA object.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">RSA</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">rsa_generate_key</span><span class="p">(</span><span class="n">bits</span><span class="p">,</span> <span class="n">e</span><span class="p">,</span> <span class="n">callback</span><span class="p">),</span> <span class="mi">1</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="load_key"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.RSA.load_key">[docs]</a><span class="k">def</span> <span class="nf">load_key</span><span class="p">(</span><span class="n">file</span><span class="p">,</span> <span class="n">callback</span><span class="o">=</span><span class="n">util</span><span class="o">.</span><span class="n">passphrase_callback</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr, Callable) -&gt; RSA</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Load an RSA key pair from file.</span>
+
+<span class="sd"> :param file: Name of file containing RSA public key in PEM format.</span>
+
+<span class="sd"> :param callback: A Python callable object that is invoked</span>
+<span class="sd"> to acquire a passphrase with which to unlock the</span>
+<span class="sd"> key. The default is util.passphrase_callback.</span>
+
+<span class="sd"> :return: M2Crypto.RSA.RSA object.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">with</span> <span class="n">BIO</span><span class="o">.</span><span class="n">openfile</span><span class="p">(</span><span class="n">file</span><span class="p">)</span> <span class="k">as</span> <span class="n">bio</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">load_key_bio</span><span class="p">(</span><span class="n">bio</span><span class="p">,</span> <span class="n">callback</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="load_key_bio"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.RSA.load_key_bio">[docs]</a><span class="k">def</span> <span class="nf">load_key_bio</span><span class="p">(</span><span class="n">bio</span><span class="p">,</span> <span class="n">callback</span><span class="o">=</span><span class="n">util</span><span class="o">.</span><span class="n">passphrase_callback</span><span class="p">):</span>
+ <span class="c1"># type: (BIO.BIO, Callable) -&gt; RSA</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Load an RSA key pair from an M2Crypto.BIO.BIO object.</span>
+
+<span class="sd"> :param bio: M2Crypto.BIO.BIO object containing RSA key pair in PEM</span>
+<span class="sd"> format.</span>
+
+<span class="sd"> :param callback: A Python callable object that is invoked</span>
+<span class="sd"> to acquire a passphrase with which to unlock the</span>
+<span class="sd"> key. The default is util.passphrase_callback.</span>
+
+<span class="sd"> :return: M2Crypto.RSA.RSA object.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">rsa</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">rsa_read_key</span><span class="p">(</span><span class="n">bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span> <span class="n">callback</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">rsa</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">rsa_error</span><span class="p">()</span>
+ <span class="k">return</span> <span class="n">RSA</span><span class="p">(</span><span class="n">rsa</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="load_key_string"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.RSA.load_key_string">[docs]</a><span class="k">def</span> <span class="nf">load_key_string</span><span class="p">(</span><span class="n">string</span><span class="p">,</span> <span class="n">callback</span><span class="o">=</span><span class="n">util</span><span class="o">.</span><span class="n">passphrase_callback</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr, Callable) -&gt; RSA</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Load an RSA key pair from a string.</span>
+
+<span class="sd"> :param string: String containing RSA key pair in PEM format.</span>
+
+<span class="sd"> :param callback: A Python callable object that is invoked</span>
+<span class="sd"> to acquire a passphrase with which to unlock the</span>
+<span class="sd"> key. The default is util.passphrase_callback.</span>
+
+<span class="sd"> :return: M2Crypto.RSA.RSA object.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">bio</span> <span class="o">=</span> <span class="n">BIO</span><span class="o">.</span><span class="n">MemoryBuffer</span><span class="p">(</span><span class="n">string</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">load_key_bio</span><span class="p">(</span><span class="n">bio</span><span class="p">,</span> <span class="n">callback</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="load_pub_key"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.RSA.load_pub_key">[docs]</a><span class="k">def</span> <span class="nf">load_pub_key</span><span class="p">(</span><span class="n">file</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr) -&gt; RSA_pub</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Load an RSA public key from file.</span>
+
+<span class="sd"> :param file: Name of file containing RSA public key in PEM format.</span>
+
+<span class="sd"> :return: M2Crypto.RSA.RSA_pub object.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">with</span> <span class="n">BIO</span><span class="o">.</span><span class="n">openfile</span><span class="p">(</span><span class="n">file</span><span class="p">)</span> <span class="k">as</span> <span class="n">bio</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">load_pub_key_bio</span><span class="p">(</span><span class="n">bio</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="load_pub_key_bio"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.RSA.load_pub_key_bio">[docs]</a><span class="k">def</span> <span class="nf">load_pub_key_bio</span><span class="p">(</span><span class="n">bio</span><span class="p">):</span>
+ <span class="c1"># type: (BIO.BIO) -&gt; RSA_pub</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Load an RSA public key from an M2Crypto.BIO.BIO object.</span>
+
+<span class="sd"> :param bio: M2Crypto.BIO.BIO object containing RSA public key in PEM</span>
+<span class="sd"> format.</span>
+
+<span class="sd"> :return: M2Crypto.RSA.RSA_pub object.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">rsa</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">rsa_read_pub_key</span><span class="p">(</span><span class="n">bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span>
+ <span class="k">if</span> <span class="n">rsa</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">rsa_error</span><span class="p">()</span>
+ <span class="k">return</span> <span class="n">RSA_pub</span><span class="p">(</span><span class="n">rsa</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="new_pub_key"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.RSA.new_pub_key">[docs]</a><span class="k">def</span> <span class="nf">new_pub_key</span><span class="p">(</span><span class="n">e_n</span><span class="p">):</span>
+ <span class="c1"># type: (Tuple[bytes, bytes]) -&gt; RSA_pub</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Instantiate an RSA_pub object from an (e, n) tuple.</span>
+
+<span class="sd"> :param e: The RSA public exponent; it is a string in OpenSSL&#39;s MPINT</span>
+<span class="sd"> format - 4-byte big-endian bit-count followed by the</span>
+<span class="sd"> appropriate number of bits.</span>
+
+<span class="sd"> :param n: The RSA composite of primes; it is a string in OpenSSL&#39;s</span>
+<span class="sd"> MPINT format - 4-byte big-endian bit-count followed by the</span>
+<span class="sd"> appropriate number of bits.</span>
+
+<span class="sd"> :return: M2Crypto.RSA.RSA_pub object.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">n</span><span class="p">)</span> <span class="o">=</span> <span class="n">e_n</span>
+ <span class="n">rsa</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">rsa_new</span><span class="p">()</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">rsa_set_en</span><span class="p">(</span><span class="n">rsa</span><span class="p">,</span> <span class="n">e</span><span class="p">,</span> <span class="n">n</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">RSA_pub</span><span class="p">(</span><span class="n">rsa</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span></div>
+</pre></div>
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="../../index.html">M2Crypto</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="../../M2Crypto.html">M2Crypto Package</a></li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="../../index.html">Documentation overview</a><ul>
+ <li><a href="../index.html">Module code</a><ul>
+ </ul></li>
+ </ul></li>
+</ul>
+</div>
+<div id="searchbox" style="display: none" role="search">
+ <h3>Quick search</h3>
+ <div class="searchformwrapper">
+ <form class="search" action="../../search.html" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ </div>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer">
+ &copy;2017, Matej Cepl <mcepl@cepl.eu>.
+
+ |
+ Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
+ &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
+
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/_modules/M2Crypto/Rand.html b/doc/html/_modules/M2Crypto/Rand.html
new file mode 100644
index 0000000..b2fa075
--- /dev/null
+++ b/doc/html/_modules/M2Crypto/Rand.html
@@ -0,0 +1,251 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>M2Crypto.Rand &#8212; M2Crypto documentation</title>
+ <link rel="stylesheet" href="../../_static/alabaster.css" type="text/css" />
+ <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../../_static/jquery.js"></script>
+ <script type="text/javascript" src="../../_static/underscore.js"></script>
+ <script type="text/javascript" src="../../_static/doctools.js"></script>
+ <script type="text/javascript" src="../../_static/language_data.js"></script>
+ <link rel="index" title="Index" href="../../genindex.html" />
+ <link rel="search" title="Search" href="../../search.html" />
+
+ <link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+ <h1>Source code for M2Crypto.Rand</h1><div class="highlight"><pre>
+<span></span><span class="sd">&quot;&quot;&quot;M2Crypto wrapper for OpenSSL PRNG. Requires OpenSSL 0.9.5 and above.</span>
+
+<span class="sd">Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved.</span>
+<span class="sd">Copyright (c) 2014-2017 Matej Cepl. All rights reserved.</span>
+
+<span class="sd">See LICENCE for the license information.</span>
+<span class="sd">&quot;&quot;&quot;</span>
+<span class="kn">from</span> <span class="nn">__future__</span> <span class="k">import</span> <span class="n">absolute_import</span>
+
+<span class="kn">from</span> <span class="nn">M2Crypto</span> <span class="k">import</span> <span class="n">m2</span><span class="p">,</span> <span class="n">py27plus</span><span class="p">,</span> <span class="n">six</span>
+<span class="k">if</span> <span class="n">py27plus</span><span class="p">:</span>
+ <span class="kn">from</span> <span class="nn">typing</span> <span class="k">import</span> <span class="n">AnyStr</span><span class="p">,</span> <span class="n">Tuple</span> <span class="c1"># noqa</span>
+
+
+<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;rand_seed&#39;</span><span class="p">,</span> <span class="s1">&#39;rand_add&#39;</span><span class="p">,</span> <span class="s1">&#39;load_file&#39;</span><span class="p">,</span> <span class="s1">&#39;save_file&#39;</span><span class="p">,</span> <span class="s1">&#39;rand_bytes&#39;</span><span class="p">,</span>
+ <span class="s1">&#39;rand_pseudo_bytes&#39;</span><span class="p">,</span> <span class="s1">&#39;rand_file_name&#39;</span><span class="p">,</span> <span class="s1">&#39;rand_status&#39;</span><span class="p">]</span>
+
+
+<span class="k">class</span> <span class="nc">RandError</span><span class="p">(</span><span class="ne">ValueError</span><span class="p">):</span>
+ <span class="k">pass</span>
+
+<span class="n">m2</span><span class="o">.</span><span class="n">rand_init</span><span class="p">(</span><span class="n">RandError</span><span class="p">)</span>
+
+
+<div class="viewcode-block" id="rand_add"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.Rand.rand_add">[docs]</a><span class="k">def</span> <span class="nf">rand_add</span><span class="p">(</span><span class="n">blob</span><span class="p">,</span> <span class="n">entropy</span><span class="p">):</span>
+ <span class="c1"># type: (bytes, float) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Mixes blob into the PRNG state.</span>
+
+<span class="sd"> :param blob: added data</span>
+<span class="sd"> :param entropy: (the lower bound of) an estimate of how much randomness</span>
+<span class="sd"> is contained in blob, measured in bytes.</span>
+
+<span class="sd"> Thus, if the data at buf are unpredictable to an adversary, this</span>
+<span class="sd"> increases the uncertainty about the state and makes the PRNG output less</span>
+<span class="sd"> predictable. Suitable input comes from user interaction (random key</span>
+<span class="sd"> presses, mouse movements) and certain hardware events.</span>
+
+<span class="sd"> Details about sources of randomness and how to estimate their entropy</span>
+<span class="sd"> can be found in the literature, e.g. RFC 1750.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">rand_add</span><span class="p">(</span><span class="n">blob</span><span class="p">,</span> <span class="n">entropy</span><span class="p">)</span> <span class="c1"># pylint: disable=no-member</span></div>
+
+
+<div class="viewcode-block" id="rand_seed"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.Rand.rand_seed">[docs]</a><span class="k">def</span> <span class="nf">rand_seed</span><span class="p">(</span><span class="n">seed</span><span class="p">):</span>
+ <span class="c1"># type: (bytes) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Equivalent to rand_add() when len(seed) == entropy.</span>
+
+<span class="sd"> :param seed: added data (see description at rand_add)</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">rand_seed</span><span class="p">(</span><span class="n">seed</span><span class="p">)</span> <span class="c1"># pylint: disable=no-member</span></div>
+
+
+<div class="viewcode-block" id="rand_status"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.Rand.rand_status">[docs]</a><span class="k">def</span> <span class="nf">rand_status</span><span class="p">():</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Check whether there is enough entropy in PRNG.</span>
+
+<span class="sd"> :return: 1 if the PRNG has been seeded with enough</span>
+<span class="sd"> data, 0 otherwise.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">rand_status</span><span class="p">()</span> <span class="c1"># pylint: disable=no-member</span></div>
+
+
+<div class="viewcode-block" id="rand_file_name"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.Rand.rand_file_name">[docs]</a><span class="k">def</span> <span class="nf">rand_file_name</span><span class="p">():</span>
+ <span class="c1"># type: () -&gt; str</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Generate a default path for the random seed file.</span>
+
+<span class="sd"> :return: string with the filename.</span>
+<span class="sd"> The seed file is $RANDFILE if that environment variable</span>
+<span class="sd"> is set, $HOME/.rnd otherwise. If $HOME is not set either,</span>
+<span class="sd"> an error occurs.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">six</span><span class="o">.</span><span class="n">ensure_text</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">rand_file_name</span><span class="p">())</span> <span class="c1"># pylint: disable=no-member</span></div>
+
+
+<div class="viewcode-block" id="load_file"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.Rand.load_file">[docs]</a><span class="k">def</span> <span class="nf">load_file</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="n">max_bytes</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr, int) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Read a number of bytes from file filename and adds them to the PRNG.</span>
+
+<span class="sd"> If max_bytes is non-negative, up to to max_bytes are read; starting with</span>
+<span class="sd"> OpenSSL 0.9.5, if max_bytes is -1, the complete file is read.</span>
+
+<span class="sd"> :param filename:</span>
+<span class="sd"> :param max_bytes:</span>
+<span class="sd"> :return: the number of bytes read.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">rand_load_file</span><span class="p">(</span><span class="n">six</span><span class="o">.</span><span class="n">ensure_str</span><span class="p">(</span><span class="n">filename</span><span class="p">),</span> <span class="n">max_bytes</span><span class="p">)</span> <span class="c1"># pylint: disable=no-member</span></div>
+
+
+<div class="viewcode-block" id="save_file"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.Rand.save_file">[docs]</a><span class="k">def</span> <span class="nf">save_file</span><span class="p">(</span><span class="n">filename</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Write a number of random bytes (currently 1024) to file.</span>
+
+<span class="sd"> The file then can be used to initialize the PRNG by calling load_file() in</span>
+<span class="sd"> a later session.</span>
+
+<span class="sd"> :param filename:</span>
+<span class="sd"> :return: returns the number of bytes written, and -1 if the bytes</span>
+<span class="sd"> written were generated without appropriate seed.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">rand_save_file</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span> <span class="c1"># pylint: disable=no-member</span></div>
+
+
+<div class="viewcode-block" id="rand_bytes"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.Rand.rand_bytes">[docs]</a><span class="k">def</span> <span class="nf">rand_bytes</span><span class="p">(</span><span class="n">num</span><span class="p">):</span>
+ <span class="c1"># type: (int) -&gt; bytes</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Return n cryptographically strong pseudo-random bytes.</span>
+
+<span class="sd"> An error occurs if the PRNG has not been seeded with enough randomness</span>
+<span class="sd"> to ensure an unpredictable byte sequence.</span>
+
+<span class="sd"> :param num: number of bytes to be returned</span>
+<span class="sd"> :return: random bytes</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">rand_bytes</span><span class="p">(</span><span class="n">num</span><span class="p">)</span> <span class="c1"># pylint: disable=no-member</span></div>
+
+
+<div class="viewcode-block" id="rand_pseudo_bytes"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.Rand.rand_pseudo_bytes">[docs]</a><span class="k">def</span> <span class="nf">rand_pseudo_bytes</span><span class="p">(</span><span class="n">num</span><span class="p">):</span>
+ <span class="c1"># type: (int) -&gt; Tuple[bytes, int]</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Return num pseudo-random bytes into buf.</span>
+
+<span class="sd"> Pseudo-random byte sequences generated by this method will be unique</span>
+<span class="sd"> if they are of sufficient length, but are not necessarily</span>
+<span class="sd"> unpredictable. They can be used for non-cryptographic purposes and for</span>
+<span class="sd"> certain purposes in cryptographic protocols, but usually not for key</span>
+<span class="sd"> generation etc.</span>
+
+<span class="sd"> Output of the function is mixed into the entropy pool before</span>
+<span class="sd"> retrieving the new pseudo-random bytes unless disabled at compile</span>
+<span class="sd"> time (see FAQ).</span>
+
+<span class="sd"> :param num: number of bytes to be returned</span>
+<span class="sd"> :return: random bytes</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="kn">import</span> <span class="nn">warnings</span>
+ <span class="k">if</span> <span class="n">m2</span><span class="o">.</span><span class="n">OPENSSL_VERSION_NUMBER</span> <span class="o">&gt;=</span> <span class="mh">0x10100000</span><span class="p">:</span>
+ <span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span><span class="s1">&#39;The underlying OpenSSL method has been &#39;</span> <span class="o">+</span>
+ <span class="s1">&#39;deprecated. Use Rand.rand_bytes instead.&#39;</span><span class="p">,</span>
+ <span class="ne">DeprecationWarning</span><span class="p">)</span>
+
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">rand_pseudo_bytes</span><span class="p">(</span><span class="n">num</span><span class="p">)</span> <span class="c1"># pylint: disable=no-member</span></div>
+</pre></div>
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="../../index.html">M2Crypto</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="../../M2Crypto.html">M2Crypto Package</a></li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="../../index.html">Documentation overview</a><ul>
+ <li><a href="../index.html">Module code</a><ul>
+ </ul></li>
+ </ul></li>
+</ul>
+</div>
+<div id="searchbox" style="display: none" role="search">
+ <h3>Quick search</h3>
+ <div class="searchformwrapper">
+ <form class="search" action="../../search.html" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ </div>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer">
+ &copy;2017, Matej Cepl <mcepl@cepl.eu>.
+
+ |
+ Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
+ &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
+
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/_modules/M2Crypto/SMIME.html b/doc/html/_modules/M2Crypto/SMIME.html
new file mode 100644
index 0000000..dbd0bb3
--- /dev/null
+++ b/doc/html/_modules/M2Crypto/SMIME.html
@@ -0,0 +1,395 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>M2Crypto.SMIME &#8212; M2Crypto documentation</title>
+ <link rel="stylesheet" href="../../_static/alabaster.css" type="text/css" />
+ <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../../_static/jquery.js"></script>
+ <script type="text/javascript" src="../../_static/underscore.js"></script>
+ <script type="text/javascript" src="../../_static/doctools.js"></script>
+ <script type="text/javascript" src="../../_static/language_data.js"></script>
+ <link rel="index" title="Index" href="../../genindex.html" />
+ <link rel="search" title="Search" href="../../search.html" />
+
+ <link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+ <h1>Source code for M2Crypto.SMIME</h1><div class="highlight"><pre>
+<span></span><span class="kn">from</span> <span class="nn">__future__</span> <span class="k">import</span> <span class="n">absolute_import</span>
+
+<span class="sd">&quot;&quot;&quot;M2Crypto wrapper for OpenSSL S/MIME API.</span>
+
+<span class="sd">Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved.&quot;&quot;&quot;</span>
+
+<span class="kn">from</span> <span class="nn">M2Crypto</span> <span class="k">import</span> <span class="n">BIO</span><span class="p">,</span> <span class="n">EVP</span><span class="p">,</span> <span class="n">Err</span><span class="p">,</span> <span class="n">X509</span><span class="p">,</span> <span class="n">m2</span><span class="p">,</span> <span class="n">util</span>
+<span class="k">if</span> <span class="n">util</span><span class="o">.</span><span class="n">py27plus</span><span class="p">:</span>
+ <span class="kn">from</span> <span class="nn">typing</span> <span class="k">import</span> <span class="n">AnyStr</span><span class="p">,</span> <span class="n">Callable</span><span class="p">,</span> <span class="n">Optional</span> <span class="c1"># noqa</span>
+
+<span class="n">PKCS7_TEXT</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">PKCS7_TEXT</span> <span class="c1"># type: int</span>
+<span class="n">PKCS7_NOCERTS</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">PKCS7_NOCERTS</span> <span class="c1"># type: int</span>
+<span class="n">PKCS7_NOSIGS</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">PKCS7_NOSIGS</span> <span class="c1"># type: int</span>
+<span class="n">PKCS7_NOCHAIN</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">PKCS7_NOCHAIN</span> <span class="c1"># type: int</span>
+<span class="n">PKCS7_NOINTERN</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">PKCS7_NOINTERN</span> <span class="c1"># type: int</span>
+<span class="n">PKCS7_NOVERIFY</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">PKCS7_NOVERIFY</span> <span class="c1"># type: int</span>
+<span class="n">PKCS7_DETACHED</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">PKCS7_DETACHED</span> <span class="c1"># type: int</span>
+<span class="n">PKCS7_BINARY</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">PKCS7_BINARY</span> <span class="c1"># type: int</span>
+<span class="n">PKCS7_NOATTR</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">PKCS7_NOATTR</span> <span class="c1"># type: int</span>
+
+<span class="n">PKCS7_SIGNED</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">PKCS7_SIGNED</span> <span class="c1"># type: int</span>
+<span class="n">PKCS7_ENVELOPED</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">PKCS7_ENVELOPED</span> <span class="c1"># type: int</span>
+<span class="n">PKCS7_SIGNED_ENVELOPED</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">PKCS7_SIGNED_ENVELOPED</span> <span class="c1"># Deprecated</span>
+<span class="n">PKCS7_DATA</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">PKCS7_DATA</span> <span class="c1"># type: int</span>
+
+
+<div class="viewcode-block" id="PKCS7_Error"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.SMIME.PKCS7_Error">[docs]</a><span class="k">class</span> <span class="nc">PKCS7_Error</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
+ <span class="k">pass</span></div>
+
+<span class="n">m2</span><span class="o">.</span><span class="n">pkcs7_init</span><span class="p">(</span><span class="n">PKCS7_Error</span><span class="p">)</span>
+
+
+<div class="viewcode-block" id="PKCS7"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.SMIME.PKCS7">[docs]</a><span class="k">class</span> <span class="nc">PKCS7</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+
+ <span class="n">m2_pkcs7_free</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">pkcs7_free</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">pkcs7</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">_pyfree</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
+ <span class="c1"># type: (Optional[bytes], int) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;PKCS7 object.</span>
+
+<span class="sd"> :param pkcs7: binary representation of</span>
+<span class="sd"> the OpenSSL type PKCS7</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">if</span> <span class="n">pkcs7</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">pkcs7</span> <span class="o">=</span> <span class="n">pkcs7</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_pyfree</span> <span class="o">=</span> <span class="n">_pyfree</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">pkcs7</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">pkcs7_new</span><span class="p">()</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_pyfree</span> <span class="o">=</span> <span class="mi">1</span>
+
+ <span class="k">def</span> <span class="nf">__del__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;_pyfree&#39;</span><span class="p">,</span> <span class="mi">0</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">m2_pkcs7_free</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">pkcs7</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">_ptr</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">pkcs7</span>
+
+<div class="viewcode-block" id="PKCS7.type"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.SMIME.PKCS7.type">[docs]</a> <span class="k">def</span> <span class="nf">type</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">text_name</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
+ <span class="c1"># type: (int) -&gt; int</span>
+ <span class="k">if</span> <span class="n">text_name</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">pkcs7_type_sn</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">pkcs7</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">pkcs7_type_nid</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">pkcs7</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="PKCS7.write"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.SMIME.PKCS7.write">[docs]</a> <span class="k">def</span> <span class="nf">write</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bio</span><span class="p">):</span>
+ <span class="c1"># type: (BIO.BIO) -&gt; int</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">pkcs7_write_bio</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">pkcs7</span><span class="p">,</span> <span class="n">bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span></div>
+
+<div class="viewcode-block" id="PKCS7.write_der"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.SMIME.PKCS7.write_der">[docs]</a> <span class="k">def</span> <span class="nf">write_der</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bio</span><span class="p">):</span>
+ <span class="c1"># type: (BIO.BIO) -&gt; int</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">pkcs7_write_bio_der</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">pkcs7</span><span class="p">,</span> <span class="n">bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span></div>
+
+<div class="viewcode-block" id="PKCS7.get0_signers"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.SMIME.PKCS7.get0_signers">[docs]</a> <span class="k">def</span> <span class="nf">get0_signers</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">certs</span><span class="p">,</span> <span class="n">flags</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
+ <span class="c1"># type: (X509.X509_Stack, int) -&gt; X509.X509_Stack</span>
+ <span class="k">return</span> <span class="n">X509</span><span class="o">.</span><span class="n">X509_Stack</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">pkcs7_get0_signers</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">pkcs7</span><span class="p">,</span>
+ <span class="n">certs</span><span class="o">.</span><span class="n">stack</span><span class="p">,</span> <span class="n">flags</span><span class="p">),</span> <span class="mi">1</span><span class="p">)</span></div></div>
+
+
+<div class="viewcode-block" id="load_pkcs7"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.SMIME.load_pkcs7">[docs]</a><span class="k">def</span> <span class="nf">load_pkcs7</span><span class="p">(</span><span class="n">p7file</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr) -&gt; PKCS7</span>
+ <span class="k">with</span> <span class="n">BIO</span><span class="o">.</span><span class="n">openfile</span><span class="p">(</span><span class="n">p7file</span><span class="p">,</span> <span class="s1">&#39;r&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">bio</span><span class="p">:</span>
+ <span class="n">p7_ptr</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">pkcs7_read_bio</span><span class="p">(</span><span class="n">bio</span><span class="o">.</span><span class="n">bio</span><span class="p">)</span>
+
+ <span class="k">return</span> <span class="n">PKCS7</span><span class="p">(</span><span class="n">p7_ptr</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="load_pkcs7_der"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.SMIME.load_pkcs7_der">[docs]</a><span class="k">def</span> <span class="nf">load_pkcs7_der</span><span class="p">(</span><span class="n">p7file</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr) -&gt; PKCS7</span>
+ <span class="k">with</span> <span class="n">BIO</span><span class="o">.</span><span class="n">openfile</span><span class="p">(</span><span class="n">p7file</span><span class="p">,</span> <span class="s1">&#39;rb&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">bio</span><span class="p">:</span>
+ <span class="n">p7_ptr</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">pkcs7_read_bio_der</span><span class="p">(</span><span class="n">bio</span><span class="o">.</span><span class="n">bio</span><span class="p">)</span>
+
+ <span class="k">return</span> <span class="n">PKCS7</span><span class="p">(</span><span class="n">p7_ptr</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="load_pkcs7_bio"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.SMIME.load_pkcs7_bio">[docs]</a><span class="k">def</span> <span class="nf">load_pkcs7_bio</span><span class="p">(</span><span class="n">p7_bio</span><span class="p">):</span>
+ <span class="c1"># type: (BIO.BIO) -&gt; PKCS7</span>
+ <span class="n">p7_ptr</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">pkcs7_read_bio</span><span class="p">(</span><span class="n">p7_bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span>
+ <span class="k">return</span> <span class="n">PKCS7</span><span class="p">(</span><span class="n">p7_ptr</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="load_pkcs7_bio_der"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.SMIME.load_pkcs7_bio_der">[docs]</a><span class="k">def</span> <span class="nf">load_pkcs7_bio_der</span><span class="p">(</span><span class="n">p7_bio</span><span class="p">):</span>
+ <span class="c1"># type: (BIO.BIO) -&gt; PKCS7</span>
+ <span class="n">p7_ptr</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">pkcs7_read_bio_der</span><span class="p">(</span><span class="n">p7_bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span>
+ <span class="k">return</span> <span class="n">PKCS7</span><span class="p">(</span><span class="n">p7_ptr</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="smime_load_pkcs7"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.SMIME.smime_load_pkcs7">[docs]</a><span class="k">def</span> <span class="nf">smime_load_pkcs7</span><span class="p">(</span><span class="n">p7file</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr) -&gt; PKCS7</span>
+ <span class="n">bio</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">bio_new_file</span><span class="p">(</span><span class="n">p7file</span><span class="p">,</span> <span class="s1">&#39;r&#39;</span><span class="p">)</span>
+
+ <span class="k">try</span><span class="p">:</span>
+ <span class="n">p7_ptr</span><span class="p">,</span> <span class="n">bio_ptr</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">smime_read_pkcs7</span><span class="p">(</span><span class="n">bio</span><span class="p">)</span>
+ <span class="k">finally</span><span class="p">:</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">bio_free</span><span class="p">(</span><span class="n">bio</span><span class="p">)</span>
+
+ <span class="k">if</span> <span class="n">bio_ptr</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">PKCS7</span><span class="p">(</span><span class="n">p7_ptr</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="kc">None</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">PKCS7</span><span class="p">(</span><span class="n">p7_ptr</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="n">BIO</span><span class="o">.</span><span class="n">BIO</span><span class="p">(</span><span class="n">bio_ptr</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="smime_load_pkcs7_bio"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.SMIME.smime_load_pkcs7_bio">[docs]</a><span class="k">def</span> <span class="nf">smime_load_pkcs7_bio</span><span class="p">(</span><span class="n">p7_bio</span><span class="p">):</span>
+ <span class="c1"># type: (BIO.BIO) -&gt; PKCS7</span>
+ <span class="n">p7_ptr</span><span class="p">,</span> <span class="n">bio_ptr</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">smime_read_pkcs7</span><span class="p">(</span><span class="n">p7_bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span>
+ <span class="k">if</span> <span class="n">p7_ptr</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="n">SMIME_Error</span><span class="p">(</span><span class="n">Err</span><span class="o">.</span><span class="n">get_error</span><span class="p">())</span>
+ <span class="k">if</span> <span class="n">bio_ptr</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">PKCS7</span><span class="p">(</span><span class="n">p7_ptr</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="kc">None</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">PKCS7</span><span class="p">(</span><span class="n">p7_ptr</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="n">BIO</span><span class="o">.</span><span class="n">BIO</span><span class="p">(</span><span class="n">bio_ptr</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="Cipher"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.SMIME.Cipher">[docs]</a><span class="k">class</span> <span class="nc">Cipher</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Object interface to EVP_CIPHER without all the frills of</span>
+<span class="sd"> M2Crypto.EVP.Cipher.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">algo</span><span class="p">):</span>
+ <span class="c1"># type: (str) -&gt; None</span>
+ <span class="n">cipher</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">m2</span><span class="p">,</span> <span class="n">algo</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">cipher</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">&#39;unknown cipher&#39;</span><span class="p">,</span> <span class="n">algo</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">cipher</span> <span class="o">=</span> <span class="n">cipher</span><span class="p">()</span>
+
+ <span class="k">def</span> <span class="nf">_ptr</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">cipher</span></div>
+
+
+<div class="viewcode-block" id="SMIME_Error"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.SMIME.SMIME_Error">[docs]</a><span class="k">class</span> <span class="nc">SMIME_Error</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
+ <span class="k">pass</span></div>
+
+<span class="n">m2</span><span class="o">.</span><span class="n">smime_init</span><span class="p">(</span><span class="n">SMIME_Error</span><span class="p">)</span>
+
+
+<span class="c1"># FIXME class has no __init__ method</span>
+<div class="viewcode-block" id="SMIME"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.SMIME.SMIME">[docs]</a><span class="k">class</span> <span class="nc">SMIME</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+<div class="viewcode-block" id="SMIME.load_key"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.SMIME.SMIME.load_key">[docs]</a> <span class="k">def</span> <span class="nf">load_key</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">keyfile</span><span class="p">,</span> <span class="n">certfile</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
+ <span class="n">callback</span><span class="o">=</span><span class="n">util</span><span class="o">.</span><span class="n">passphrase_callback</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr, Optional[AnyStr], Callable) -&gt; None</span>
+ <span class="k">if</span> <span class="n">certfile</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">certfile</span> <span class="o">=</span> <span class="n">keyfile</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">pkey</span> <span class="o">=</span> <span class="n">EVP</span><span class="o">.</span><span class="n">load_key</span><span class="p">(</span><span class="n">keyfile</span><span class="p">,</span> <span class="n">callback</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">x509</span> <span class="o">=</span> <span class="n">X509</span><span class="o">.</span><span class="n">load_cert</span><span class="p">(</span><span class="n">certfile</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="SMIME.load_key_bio"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.SMIME.SMIME.load_key_bio">[docs]</a> <span class="k">def</span> <span class="nf">load_key_bio</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">keybio</span><span class="p">,</span> <span class="n">certbio</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
+ <span class="n">callback</span><span class="o">=</span><span class="n">util</span><span class="o">.</span><span class="n">passphrase_callback</span><span class="p">):</span>
+ <span class="c1"># type: (BIO.BIO, Optional[BIO.BIO], Callable) -&gt; None</span>
+ <span class="k">if</span> <span class="n">certbio</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">certbio</span> <span class="o">=</span> <span class="n">keybio</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">pkey</span> <span class="o">=</span> <span class="n">EVP</span><span class="o">.</span><span class="n">load_key_bio</span><span class="p">(</span><span class="n">keybio</span><span class="p">,</span> <span class="n">callback</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">x509</span> <span class="o">=</span> <span class="n">X509</span><span class="o">.</span><span class="n">load_cert_bio</span><span class="p">(</span><span class="n">certbio</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="SMIME.set_x509_stack"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.SMIME.SMIME.set_x509_stack">[docs]</a> <span class="k">def</span> <span class="nf">set_x509_stack</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">stack</span><span class="p">):</span>
+ <span class="c1"># type: (X509.X509_Stack) -&gt; None</span>
+ <span class="k">assert</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">X509</span><span class="o">.</span><span class="n">X509_Stack</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">x509_stack</span> <span class="o">=</span> <span class="n">stack</span></div>
+
+<div class="viewcode-block" id="SMIME.set_x509_store"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.SMIME.SMIME.set_x509_store">[docs]</a> <span class="k">def</span> <span class="nf">set_x509_store</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">store</span><span class="p">):</span>
+ <span class="c1"># type: (X509.X509_Store) -&gt; None</span>
+ <span class="k">assert</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">store</span><span class="p">,</span> <span class="n">X509</span><span class="o">.</span><span class="n">X509_Store</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">x509_store</span> <span class="o">=</span> <span class="n">store</span></div>
+
+<div class="viewcode-block" id="SMIME.set_cipher"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.SMIME.SMIME.set_cipher">[docs]</a> <span class="k">def</span> <span class="nf">set_cipher</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">cipher</span><span class="p">):</span>
+ <span class="c1"># type: (Cipher) -&gt; None</span>
+ <span class="k">assert</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">cipher</span><span class="p">,</span> <span class="n">Cipher</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">cipher</span> <span class="o">=</span> <span class="n">cipher</span></div>
+
+<div class="viewcode-block" id="SMIME.unset_key"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.SMIME.SMIME.unset_key">[docs]</a> <span class="k">def</span> <span class="nf">unset_key</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">pkey</span>
+ <span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">x509</span></div>
+
+<div class="viewcode-block" id="SMIME.unset_x509_stack"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.SMIME.SMIME.unset_x509_stack">[docs]</a> <span class="k">def</span> <span class="nf">unset_x509_stack</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">x509_stack</span></div>
+
+<div class="viewcode-block" id="SMIME.unset_x509_store"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.SMIME.SMIME.unset_x509_store">[docs]</a> <span class="k">def</span> <span class="nf">unset_x509_store</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">x509_store</span></div>
+
+<div class="viewcode-block" id="SMIME.unset_cipher"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.SMIME.SMIME.unset_cipher">[docs]</a> <span class="k">def</span> <span class="nf">unset_cipher</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">cipher</span></div>
+
+<div class="viewcode-block" id="SMIME.encrypt"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.SMIME.SMIME.encrypt">[docs]</a> <span class="k">def</span> <span class="nf">encrypt</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data_bio</span><span class="p">,</span> <span class="n">flags</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
+ <span class="c1"># type: (BIO.BIO, int) -&gt; PKCS7</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;cipher&#39;</span><span class="p">):</span>
+ <span class="k">raise</span> <span class="n">SMIME_Error</span><span class="p">(</span><span class="s1">&#39;no cipher: use set_cipher()&#39;</span><span class="p">)</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;x509_stack&#39;</span><span class="p">):</span>
+ <span class="k">raise</span> <span class="n">SMIME_Error</span><span class="p">(</span><span class="s1">&#39;no recipient certs: use set_x509_stack()&#39;</span><span class="p">)</span>
+
+ <span class="n">pkcs7</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">pkcs7_encrypt</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509_stack</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span> <span class="n">data_bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">cipher</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span> <span class="n">flags</span><span class="p">)</span>
+
+ <span class="k">return</span> <span class="n">PKCS7</span><span class="p">(</span><span class="n">pkcs7</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="SMIME.decrypt"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.SMIME.SMIME.decrypt">[docs]</a> <span class="k">def</span> <span class="nf">decrypt</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">pkcs7</span><span class="p">,</span> <span class="n">flags</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
+ <span class="c1"># type: (PKCS7, int) -&gt; Optional[bytes]</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;pkey&#39;</span><span class="p">):</span>
+ <span class="k">raise</span> <span class="n">SMIME_Error</span><span class="p">(</span><span class="s1">&#39;no private key: use load_key()&#39;</span><span class="p">)</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;x509&#39;</span><span class="p">):</span>
+ <span class="k">raise</span> <span class="n">SMIME_Error</span><span class="p">(</span><span class="s1">&#39;no certificate: load_key() used incorrectly?&#39;</span><span class="p">)</span>
+ <span class="n">blob</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">pkcs7_decrypt</span><span class="p">(</span><span class="n">pkcs7</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span> <span class="bp">self</span><span class="o">.</span><span class="n">pkey</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span> <span class="n">flags</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">blob</span></div>
+
+<div class="viewcode-block" id="SMIME.sign"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.SMIME.SMIME.sign">[docs]</a> <span class="k">def</span> <span class="nf">sign</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data_bio</span><span class="p">,</span> <span class="n">flags</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">algo</span><span class="o">=</span><span class="s1">&#39;sha1&#39;</span><span class="p">):</span>
+ <span class="c1"># type: (BIO.BIO, int, Optional[str]) -&gt; PKCS7</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;pkey&#39;</span><span class="p">):</span>
+ <span class="k">raise</span> <span class="n">SMIME_Error</span><span class="p">(</span><span class="s1">&#39;no private key: use load_key()&#39;</span><span class="p">)</span>
+
+ <span class="nb">hash</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">m2</span><span class="p">,</span> <span class="n">algo</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
+
+ <span class="k">if</span> <span class="nb">hash</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="n">SMIME_Error</span><span class="p">(</span><span class="s1">&#39;no such hash algorithm </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">algo</span><span class="p">)</span>
+
+ <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;x509_stack&#39;</span><span class="p">):</span>
+ <span class="n">pkcs7</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">pkcs7_sign1</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span> <span class="bp">self</span><span class="o">.</span><span class="n">pkey</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">x509_stack</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span>
+ <span class="n">data_bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span> <span class="nb">hash</span><span class="p">(),</span> <span class="n">flags</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">PKCS7</span><span class="p">(</span><span class="n">pkcs7</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">pkcs7</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">pkcs7_sign0</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span> <span class="bp">self</span><span class="o">.</span><span class="n">pkey</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span>
+ <span class="n">data_bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span> <span class="nb">hash</span><span class="p">(),</span> <span class="n">flags</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">PKCS7</span><span class="p">(</span><span class="n">pkcs7</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="SMIME.verify"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.SMIME.SMIME.verify">[docs]</a> <span class="k">def</span> <span class="nf">verify</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">pkcs7</span><span class="p">,</span> <span class="n">data_bio</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">flags</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
+ <span class="c1"># type: (PKCS7, BIO.BIO, int) -&gt; Optional[bytes]</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;x509_stack&#39;</span><span class="p">):</span>
+ <span class="k">raise</span> <span class="n">SMIME_Error</span><span class="p">(</span><span class="s1">&#39;no signer certs: use set_x509_stack()&#39;</span><span class="p">)</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;x509_store&#39;</span><span class="p">):</span>
+ <span class="k">raise</span> <span class="n">SMIME_Error</span><span class="p">(</span><span class="s1">&#39;no x509 cert store: use set_x509_store()&#39;</span><span class="p">)</span>
+ <span class="k">assert</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">pkcs7</span><span class="p">,</span> <span class="n">PKCS7</span><span class="p">),</span> <span class="s1">&#39;pkcs7 not an instance of PKCS7&#39;</span>
+ <span class="n">p7</span> <span class="o">=</span> <span class="n">pkcs7</span><span class="o">.</span><span class="n">_ptr</span><span class="p">()</span>
+ <span class="k">if</span> <span class="n">data_bio</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">blob</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">pkcs7_verify0</span><span class="p">(</span><span class="n">p7</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">x509_stack</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">x509_store</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span> <span class="n">flags</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">blob</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">pkcs7_verify1</span><span class="p">(</span><span class="n">p7</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">x509_stack</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">x509_store</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span>
+ <span class="n">data_bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span> <span class="n">flags</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">blob</span></div>
+
+<div class="viewcode-block" id="SMIME.write"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.SMIME.SMIME.write">[docs]</a> <span class="k">def</span> <span class="nf">write</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">out_bio</span><span class="p">,</span> <span class="n">pkcs7</span><span class="p">,</span> <span class="n">data_bio</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">flags</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
+ <span class="c1"># type: (BIO.BIO, PKCS7, Optional[BIO.BIO], int) -&gt; int</span>
+ <span class="k">assert</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">pkcs7</span><span class="p">,</span> <span class="n">PKCS7</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">data_bio</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">smime_write_pkcs7</span><span class="p">(</span><span class="n">out_bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span> <span class="n">pkcs7</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span> <span class="n">flags</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">smime_write_pkcs7_multi</span><span class="p">(</span><span class="n">out_bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span> <span class="n">pkcs7</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span>
+ <span class="n">data_bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span> <span class="n">flags</span><span class="p">)</span></div></div>
+
+
+<div class="viewcode-block" id="text_crlf"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.SMIME.text_crlf">[docs]</a><span class="k">def</span> <span class="nf">text_crlf</span><span class="p">(</span><span class="n">text</span><span class="p">):</span>
+ <span class="c1"># type: (bytes) -&gt; bytes</span>
+ <span class="n">bio_in</span> <span class="o">=</span> <span class="n">BIO</span><span class="o">.</span><span class="n">MemoryBuffer</span><span class="p">(</span><span class="n">text</span><span class="p">)</span>
+ <span class="n">bio_out</span> <span class="o">=</span> <span class="n">BIO</span><span class="o">.</span><span class="n">MemoryBuffer</span><span class="p">()</span>
+ <span class="k">if</span> <span class="n">m2</span><span class="o">.</span><span class="n">smime_crlf_copy</span><span class="p">(</span><span class="n">bio_in</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span> <span class="n">bio_out</span><span class="o">.</span><span class="n">_ptr</span><span class="p">()):</span>
+ <span class="k">return</span> <span class="n">bio_out</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="n">SMIME_Error</span><span class="p">(</span><span class="n">Err</span><span class="o">.</span><span class="n">get_error</span><span class="p">())</span></div>
+
+
+<div class="viewcode-block" id="text_crlf_bio"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.SMIME.text_crlf_bio">[docs]</a><span class="k">def</span> <span class="nf">text_crlf_bio</span><span class="p">(</span><span class="n">bio_in</span><span class="p">):</span>
+ <span class="c1"># type: (BIO.BIO) -&gt; BIO.BIO</span>
+ <span class="n">bio_out</span> <span class="o">=</span> <span class="n">BIO</span><span class="o">.</span><span class="n">MemoryBuffer</span><span class="p">()</span>
+ <span class="k">if</span> <span class="n">m2</span><span class="o">.</span><span class="n">smime_crlf_copy</span><span class="p">(</span><span class="n">bio_in</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span> <span class="n">bio_out</span><span class="o">.</span><span class="n">_ptr</span><span class="p">()):</span>
+ <span class="k">return</span> <span class="n">bio_out</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="n">SMIME_Error</span><span class="p">(</span><span class="n">Err</span><span class="o">.</span><span class="n">get_error</span><span class="p">())</span></div>
+</pre></div>
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="../../index.html">M2Crypto</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="../../M2Crypto.html">M2Crypto Package</a></li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="../../index.html">Documentation overview</a><ul>
+ <li><a href="../index.html">Module code</a><ul>
+ </ul></li>
+ </ul></li>
+</ul>
+</div>
+<div id="searchbox" style="display: none" role="search">
+ <h3>Quick search</h3>
+ <div class="searchformwrapper">
+ <form class="search" action="../../search.html" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ </div>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer">
+ &copy;2017, Matej Cepl <mcepl@cepl.eu>.
+
+ |
+ Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
+ &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
+
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/_modules/M2Crypto/SSL.html b/doc/html/_modules/M2Crypto/SSL.html
new file mode 100644
index 0000000..ff0aa7a
--- /dev/null
+++ b/doc/html/_modules/M2Crypto/SSL.html
@@ -0,0 +1,145 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>M2Crypto.SSL &#8212; M2Crypto documentation</title>
+ <link rel="stylesheet" href="../../_static/alabaster.css" type="text/css" />
+ <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../../_static/jquery.js"></script>
+ <script type="text/javascript" src="../../_static/underscore.js"></script>
+ <script type="text/javascript" src="../../_static/doctools.js"></script>
+ <script type="text/javascript" src="../../_static/language_data.js"></script>
+ <link rel="index" title="Index" href="../../genindex.html" />
+ <link rel="search" title="Search" href="../../search.html" />
+
+ <link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+ <h1>Source code for M2Crypto.SSL</h1><div class="highlight"><pre>
+<span></span><span class="kn">from</span> <span class="nn">__future__</span> <span class="k">import</span> <span class="n">absolute_import</span>
+
+<span class="sd">&quot;&quot;&quot;M2Crypto SSL services.</span>
+
+<span class="sd">Copyright (c) 1999-2004 Ng Pheng Siong. All rights reserved.&quot;&quot;&quot;</span>
+
+<span class="kn">import</span> <span class="nn">socket</span><span class="o">,</span> <span class="nn">os</span>
+
+<span class="c1"># M2Crypto</span>
+<span class="kn">from</span> <span class="nn">M2Crypto</span> <span class="k">import</span> <span class="n">_m2crypto</span> <span class="k">as</span> <span class="n">m2</span>
+
+
+<div class="viewcode-block" id="SSLError"><a class="viewcode-back" href="../../M2Crypto.SSL.html#M2Crypto.SSL.SSLError">[docs]</a><span class="k">class</span> <span class="nc">SSLError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
+ <span class="k">pass</span></div>
+
+
+<div class="viewcode-block" id="SSLTimeoutError"><a class="viewcode-back" href="../../M2Crypto.SSL.html#M2Crypto.SSL.SSLTimeoutError">[docs]</a><span class="k">class</span> <span class="nc">SSLTimeoutError</span><span class="p">(</span><span class="n">SSLError</span><span class="p">,</span> <span class="n">socket</span><span class="o">.</span><span class="n">timeout</span><span class="p">):</span>
+ <span class="k">pass</span></div>
+
+<span class="n">m2</span><span class="o">.</span><span class="n">ssl_init</span><span class="p">(</span><span class="n">SSLError</span><span class="p">,</span> <span class="n">SSLTimeoutError</span><span class="p">)</span>
+
+<span class="c1"># M2Crypto.SSL</span>
+<span class="kn">from</span> <span class="nn">M2Crypto.SSL.Cipher</span> <span class="k">import</span> <span class="n">Cipher</span><span class="p">,</span> <span class="n">Cipher_Stack</span>
+<span class="kn">from</span> <span class="nn">M2Crypto.SSL.Connection</span> <span class="k">import</span> <span class="n">Connection</span>
+<span class="kn">from</span> <span class="nn">M2Crypto.SSL.Context</span> <span class="k">import</span> <span class="n">Context</span>
+<span class="kn">from</span> <span class="nn">M2Crypto.SSL.SSLServer</span> <span class="k">import</span> <span class="n">SSLServer</span><span class="p">,</span> <span class="n">ThreadingSSLServer</span>
+<span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">name</span> <span class="o">!=</span> <span class="s1">&#39;nt&#39;</span><span class="p">:</span>
+ <span class="kn">from</span> <span class="nn">M2Crypto.SSL.SSLServer</span> <span class="k">import</span> <span class="n">ForkingSSLServer</span>
+<span class="kn">from</span> <span class="nn">M2Crypto.SSL.ssl_dispatcher</span> <span class="k">import</span> <span class="n">ssl_dispatcher</span>
+<span class="kn">from</span> <span class="nn">M2Crypto.SSL.timeout</span> <span class="k">import</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">struct_to_timeout</span><span class="p">,</span> <span class="n">struct_size</span>
+
+<span class="n">verify_none</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">SSL_VERIFY_NONE</span> <span class="c1"># type: int</span>
+<span class="n">verify_peer</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">SSL_VERIFY_PEER</span> <span class="c1"># type: int</span>
+<span class="n">verify_fail_if_no_peer_cert</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">SSL_VERIFY_FAIL_IF_NO_PEER_CERT</span> <span class="c1"># type: int</span>
+<span class="n">verify_client_once</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">SSL_VERIFY_CLIENT_ONCE</span> <span class="c1"># type: int</span>
+
+<span class="n">SSL_SENT_SHUTDOWN</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">SSL_SENT_SHUTDOWN</span> <span class="c1"># type: int</span>
+<span class="n">SSL_RECEIVED_SHUTDOWN</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">SSL_RECEIVED_SHUTDOWN</span> <span class="c1"># type: int</span>
+
+<span class="n">op_all</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">SSL_OP_ALL</span> <span class="c1"># type: int</span>
+<span class="n">op_no_sslv2</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">SSL_OP_NO_SSLv2</span> <span class="c1"># type: int</span>
+</pre></div>
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="../../index.html">M2Crypto</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="../../M2Crypto.html">M2Crypto Package</a></li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="../../index.html">Documentation overview</a><ul>
+ <li><a href="../index.html">Module code</a><ul>
+ </ul></li>
+ </ul></li>
+</ul>
+</div>
+<div id="searchbox" style="display: none" role="search">
+ <h3>Quick search</h3>
+ <div class="searchformwrapper">
+ <form class="search" action="../../search.html" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ </div>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer">
+ &copy;2017, Matej Cepl <mcepl@cepl.eu>.
+
+ |
+ Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
+ &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
+
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/_modules/M2Crypto/SSL/Checker.html b/doc/html/_modules/M2Crypto/SSL/Checker.html
new file mode 100644
index 0000000..dc1aea8
--- /dev/null
+++ b/doc/html/_modules/M2Crypto/SSL/Checker.html
@@ -0,0 +1,403 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>M2Crypto.SSL.Checker &#8212; M2Crypto documentation</title>
+ <link rel="stylesheet" href="../../../_static/alabaster.css" type="text/css" />
+ <link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../../../_static/jquery.js"></script>
+ <script type="text/javascript" src="../../../_static/underscore.js"></script>
+ <script type="text/javascript" src="../../../_static/doctools.js"></script>
+ <script type="text/javascript" src="../../../_static/language_data.js"></script>
+ <link rel="index" title="Index" href="../../../genindex.html" />
+ <link rel="search" title="Search" href="../../../search.html" />
+
+ <link rel="stylesheet" href="../../../_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+ <h1>Source code for M2Crypto.SSL.Checker</h1><div class="highlight"><pre>
+<span></span><span class="sd">&quot;&quot;&quot;</span>
+<span class="sd">SSL peer certificate checking routines</span>
+
+<span class="sd">Copyright (c) 2004-2007 Open Source Applications Foundation.</span>
+<span class="sd">All rights reserved.</span>
+
+<span class="sd">Copyright 2008 Heikki Toivonen. All rights reserved.</span>
+<span class="sd">&quot;&quot;&quot;</span>
+
+<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;SSLVerificationError&#39;</span><span class="p">,</span> <span class="s1">&#39;NoCertificate&#39;</span><span class="p">,</span> <span class="s1">&#39;WrongCertificate&#39;</span><span class="p">,</span>
+ <span class="s1">&#39;WrongHost&#39;</span><span class="p">,</span> <span class="s1">&#39;Checker&#39;</span><span class="p">]</span>
+
+<span class="kn">import</span> <span class="nn">re</span>
+<span class="kn">import</span> <span class="nn">socket</span>
+
+<span class="kn">from</span> <span class="nn">M2Crypto</span> <span class="k">import</span> <span class="n">X509</span><span class="p">,</span> <span class="n">m2</span><span class="p">,</span> <span class="n">six</span><span class="p">,</span> <span class="n">util</span> <span class="c1"># noqa</span>
+<span class="k">if</span> <span class="n">util</span><span class="o">.</span><span class="n">py27plus</span><span class="p">:</span>
+ <span class="kn">from</span> <span class="nn">typing</span> <span class="k">import</span> <span class="n">AnyStr</span><span class="p">,</span> <span class="n">Optional</span> <span class="c1"># noqa</span>
+
+
+<div class="viewcode-block" id="SSLVerificationError"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Checker.SSLVerificationError">[docs]</a><span class="k">class</span> <span class="nc">SSLVerificationError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
+ <span class="k">pass</span></div>
+
+
+<div class="viewcode-block" id="NoCertificate"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Checker.NoCertificate">[docs]</a><span class="k">class</span> <span class="nc">NoCertificate</span><span class="p">(</span><span class="n">SSLVerificationError</span><span class="p">):</span>
+ <span class="k">pass</span></div>
+
+
+<div class="viewcode-block" id="WrongCertificate"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Checker.WrongCertificate">[docs]</a><span class="k">class</span> <span class="nc">WrongCertificate</span><span class="p">(</span><span class="n">SSLVerificationError</span><span class="p">):</span>
+ <span class="k">pass</span></div>
+
+
+<div class="viewcode-block" id="WrongHost"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Checker.WrongHost">[docs]</a><span class="k">class</span> <span class="nc">WrongHost</span><span class="p">(</span><span class="n">SSLVerificationError</span><span class="p">):</span>
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">expectedHost</span><span class="p">,</span> <span class="n">actualHost</span><span class="p">,</span> <span class="n">fieldName</span><span class="o">=</span><span class="s1">&#39;commonName&#39;</span><span class="p">):</span>
+ <span class="c1"># type: (str, AnyStr, str) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> This exception will be raised if the certificate returned by the</span>
+<span class="sd"> peer was issued for a different host than we tried to connect to.</span>
+<span class="sd"> This could be due to a server misconfiguration or an active attack.</span>
+
+<span class="sd"> :param expectedHost: The name of the host we expected to find in the</span>
+<span class="sd"> certificate.</span>
+<span class="sd"> :param actualHost: The name of the host we actually found in the</span>
+<span class="sd"> certificate.</span>
+<span class="sd"> :param fieldName: The field name where we noticed the error. This</span>
+<span class="sd"> should be either &#39;commonName&#39; or &#39;subjectAltName&#39;.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">if</span> <span class="n">fieldName</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">&#39;commonName&#39;</span><span class="p">,</span> <span class="s1">&#39;subjectAltName&#39;</span><span class="p">):</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
+ <span class="s1">&#39;Unknown fieldName, should be either commonName &#39;</span> <span class="o">+</span>
+ <span class="s1">&#39;or subjectAltName&#39;</span><span class="p">)</span>
+
+ <span class="n">SSLVerificationError</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">expectedHost</span> <span class="o">=</span> <span class="n">expectedHost</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">actualHost</span> <span class="o">=</span> <span class="n">actualHost</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">fieldName</span> <span class="o">=</span> <span class="n">fieldName</span>
+
+ <span class="k">def</span> <span class="nf">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; str</span>
+ <span class="n">s</span> <span class="o">=</span> <span class="s1">&#39;Peer certificate </span><span class="si">%s</span><span class="s1"> does not match host, expected </span><span class="si">%s</span><span class="s1">, got </span><span class="si">%s</span><span class="s1">&#39;</span> \
+ <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">fieldName</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">expectedHost</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">actualHost</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">six</span><span class="o">.</span><span class="n">ensure_text</span><span class="p">(</span><span class="n">s</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="Checker"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Checker.Checker">[docs]</a><span class="k">class</span> <span class="nc">Checker</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+
+ <span class="n">numericIpMatch</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="s1">&#39;^[0-9]+(\.[0-9]+)*$&#39;</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">host</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">peerCertHash</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">peerCertDigest</span><span class="o">=</span><span class="s1">&#39;sha1&#39;</span><span class="p">):</span>
+ <span class="c1"># type: (Optional[str], Optional[bytes], str) -&gt; None</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">host</span> <span class="o">=</span> <span class="n">host</span>
+ <span class="k">if</span> <span class="n">peerCertHash</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">peerCertHash</span> <span class="o">=</span> <span class="n">six</span><span class="o">.</span><span class="n">ensure_binary</span><span class="p">(</span><span class="n">peerCertHash</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">fingerprint</span> <span class="o">=</span> <span class="n">peerCertHash</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">digest</span> <span class="o">=</span> <span class="n">peerCertDigest</span> <span class="c1"># type: str</span>
+
+ <span class="k">def</span> <span class="nf">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">peerCert</span><span class="p">,</span> <span class="n">host</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="c1"># type: (X509.X509, Optional[str]) -&gt; bool</span>
+ <span class="k">if</span> <span class="n">peerCert</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="n">NoCertificate</span><span class="p">(</span><span class="s1">&#39;peer did not return certificate&#39;</span><span class="p">)</span>
+
+ <span class="k">if</span> <span class="n">host</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">host</span> <span class="o">=</span> <span class="n">host</span> <span class="c1"># type: str</span>
+
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">fingerprint</span><span class="p">:</span>
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">digest</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">&#39;sha1&#39;</span><span class="p">,</span> <span class="s1">&#39;md5&#39;</span><span class="p">):</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">&#39;unsupported digest &quot;</span><span class="si">%s</span><span class="s1">&quot;&#39;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">digest</span><span class="p">)</span>
+
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">digest</span> <span class="o">==</span> <span class="s1">&#39;sha1&#39;</span><span class="p">:</span>
+ <span class="n">expected_len</span> <span class="o">=</span> <span class="mi">40</span>
+ <span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">digest</span> <span class="o">==</span> <span class="s1">&#39;md5&#39;</span><span class="p">:</span>
+ <span class="n">expected_len</span> <span class="o">=</span> <span class="mi">32</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">&#39;Unexpected digest </span><span class="si">{0}</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">digest</span><span class="p">))</span>
+
+ <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">fingerprint</span><span class="p">)</span> <span class="o">!=</span> <span class="n">expected_len</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="n">WrongCertificate</span><span class="p">(</span>
+ <span class="p">(</span><span class="s1">&#39;peer certificate fingerprint length does not match</span><span class="se">\n</span><span class="s1">&#39;</span> <span class="o">+</span>
+ <span class="s1">&#39;fingerprint: </span><span class="si">{0}</span><span class="se">\n</span><span class="s1">expected = </span><span class="si">{1}</span><span class="se">\n</span><span class="s1">&#39;</span> <span class="o">+</span>
+ <span class="s1">&#39;observed = </span><span class="si">{2}</span><span class="s1">&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">fingerprint</span><span class="p">,</span>
+ <span class="n">expected_len</span><span class="p">,</span>
+ <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">fingerprint</span><span class="p">)))</span>
+
+ <span class="n">expected_fingerprint</span> <span class="o">=</span> <span class="n">six</span><span class="o">.</span><span class="n">ensure_text</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">fingerprint</span><span class="p">)</span>
+ <span class="n">observed_fingerprint</span> <span class="o">=</span> <span class="n">peerCert</span><span class="o">.</span><span class="n">get_fingerprint</span><span class="p">(</span><span class="n">md</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">digest</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">observed_fingerprint</span> <span class="o">!=</span> <span class="n">expected_fingerprint</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="n">WrongCertificate</span><span class="p">(</span>
+ <span class="p">(</span><span class="s1">&#39;peer certificate fingerprint does not match</span><span class="se">\n</span><span class="s1">&#39;</span> <span class="o">+</span>
+ <span class="s1">&#39;expected = </span><span class="si">{0}</span><span class="s1">,</span><span class="se">\n</span><span class="s1">&#39;</span> <span class="o">+</span>
+ <span class="s1">&#39;observed = </span><span class="si">{1}</span><span class="s1">&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">expected_fingerprint</span><span class="p">,</span>
+ <span class="n">observed_fingerprint</span><span class="p">))</span>
+
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">host</span><span class="p">:</span>
+ <span class="n">hostValidationPassed</span> <span class="o">=</span> <span class="kc">False</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">useSubjectAltNameOnly</span> <span class="o">=</span> <span class="kc">False</span>
+
+ <span class="c1"># subjectAltName=DNS:somehost[, ...]*</span>
+ <span class="k">try</span><span class="p">:</span>
+ <span class="n">subjectAltName</span> <span class="o">=</span> <span class="n">peerCert</span><span class="o">.</span><span class="n">get_ext</span><span class="p">(</span><span class="s1">&#39;subjectAltName&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">get_value</span><span class="p">()</span>
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_splitSubjectAltName</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">host</span><span class="p">,</span> <span class="n">subjectAltName</span><span class="p">):</span>
+ <span class="n">hostValidationPassed</span> <span class="o">=</span> <span class="kc">True</span>
+ <span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">useSubjectAltNameOnly</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="n">WrongHost</span><span class="p">(</span><span class="n">expectedHost</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">host</span><span class="p">,</span>
+ <span class="n">actualHost</span><span class="o">=</span><span class="n">subjectAltName</span><span class="p">,</span>
+ <span class="n">fieldName</span><span class="o">=</span><span class="s1">&#39;subjectAltName&#39;</span><span class="p">)</span>
+ <span class="k">except</span> <span class="ne">LookupError</span><span class="p">:</span>
+ <span class="k">pass</span>
+
+ <span class="c1"># commonName=somehost[, ...]*</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">hostValidationPassed</span><span class="p">:</span>
+ <span class="n">hasCommonName</span> <span class="o">=</span> <span class="kc">False</span>
+ <span class="n">commonNames</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
+ <span class="k">for</span> <span class="n">entry</span> <span class="ow">in</span> <span class="n">peerCert</span><span class="o">.</span><span class="n">get_subject</span><span class="p">()</span><span class="o">.</span><span class="n">get_entries_by_nid</span><span class="p">(</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">NID_commonName</span><span class="p">):</span>
+ <span class="n">hasCommonName</span> <span class="o">=</span> <span class="kc">True</span>
+ <span class="n">commonName</span> <span class="o">=</span> <span class="n">entry</span><span class="o">.</span><span class="n">get_data</span><span class="p">()</span><span class="o">.</span><span class="n">as_text</span><span class="p">()</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">commonNames</span><span class="p">:</span>
+ <span class="n">commonNames</span> <span class="o">=</span> <span class="n">commonName</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">commonNames</span> <span class="o">+=</span> <span class="s1">&#39;,&#39;</span> <span class="o">+</span> <span class="n">commonName</span>
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_match</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">host</span><span class="p">,</span> <span class="n">commonName</span><span class="p">):</span>
+ <span class="n">hostValidationPassed</span> <span class="o">=</span> <span class="kc">True</span>
+ <span class="k">break</span>
+
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">hasCommonName</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="n">WrongCertificate</span><span class="p">(</span><span class="s1">&#39;no commonName in peer certificate&#39;</span><span class="p">)</span>
+
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">hostValidationPassed</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="n">WrongHost</span><span class="p">(</span><span class="n">expectedHost</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">host</span><span class="p">,</span>
+ <span class="n">actualHost</span><span class="o">=</span><span class="n">commonNames</span><span class="p">,</span>
+ <span class="n">fieldName</span><span class="o">=</span><span class="s1">&#39;commonName&#39;</span><span class="p">)</span>
+
+ <span class="k">return</span> <span class="kc">True</span>
+
+ <span class="k">def</span> <span class="nf">_splitSubjectAltName</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">host</span><span class="p">,</span> <span class="n">subjectAltName</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr, AnyStr) -&gt; bool</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> &gt;&gt;&gt; check = Checker()</span>
+<span class="sd"> &gt;&gt;&gt; check._splitSubjectAltName(host=&#39;my.example.com&#39;,</span>
+<span class="sd"> ... subjectAltName=&#39;DNS:my.example.com&#39;)</span>
+<span class="sd"> True</span>
+<span class="sd"> &gt;&gt;&gt; check._splitSubjectAltName(host=&#39;my.example.com&#39;,</span>
+<span class="sd"> ... subjectAltName=&#39;DNS:*.example.com&#39;)</span>
+<span class="sd"> True</span>
+<span class="sd"> &gt;&gt;&gt; check._splitSubjectAltName(host=&#39;my.example.com&#39;,</span>
+<span class="sd"> ... subjectAltName=&#39;DNS:m*.example.com&#39;)</span>
+<span class="sd"> True</span>
+<span class="sd"> &gt;&gt;&gt; check._splitSubjectAltName(host=&#39;my.example.com&#39;,</span>
+<span class="sd"> ... subjectAltName=&#39;DNS:m*ample.com&#39;)</span>
+<span class="sd"> False</span>
+<span class="sd"> &gt;&gt;&gt; check.useSubjectAltNameOnly</span>
+<span class="sd"> True</span>
+<span class="sd"> &gt;&gt;&gt; check._splitSubjectAltName(host=&#39;my.example.com&#39;,</span>
+<span class="sd"> ... subjectAltName=&#39;DNS:m*ample.com, othername:&lt;unsupported&gt;&#39;)</span>
+<span class="sd"> False</span>
+<span class="sd"> &gt;&gt;&gt; check._splitSubjectAltName(host=&#39;my.example.com&#39;,</span>
+<span class="sd"> ... subjectAltName=&#39;DNS:m*ample.com, DNS:my.example.org&#39;)</span>
+<span class="sd"> False</span>
+<span class="sd"> &gt;&gt;&gt; check._splitSubjectAltName(host=&#39;my.example.com&#39;,</span>
+<span class="sd"> ... subjectAltName=&#39;DNS:m*ample.com, DNS:my.example.com&#39;)</span>
+<span class="sd"> True</span>
+<span class="sd"> &gt;&gt;&gt; check._splitSubjectAltName(host=&#39;my.example.com&#39;,</span>
+<span class="sd"> ... subjectAltName=&#39;DNS:my.example.com, DNS:my.example.org&#39;)</span>
+<span class="sd"> True</span>
+<span class="sd"> &gt;&gt;&gt; check.useSubjectAltNameOnly</span>
+<span class="sd"> True</span>
+<span class="sd"> &gt;&gt;&gt; check._splitSubjectAltName(host=&#39;my.example.com&#39;,</span>
+<span class="sd"> ... subjectAltName=&#39;&#39;)</span>
+<span class="sd"> False</span>
+<span class="sd"> &gt;&gt;&gt; check._splitSubjectAltName(host=&#39;my.example.com&#39;,</span>
+<span class="sd"> ... subjectAltName=&#39;othername:&lt;unsupported&gt;&#39;)</span>
+<span class="sd"> False</span>
+<span class="sd"> &gt;&gt;&gt; check.useSubjectAltNameOnly</span>
+<span class="sd"> False</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">useSubjectAltNameOnly</span> <span class="o">=</span> <span class="kc">False</span>
+ <span class="k">for</span> <span class="n">certHost</span> <span class="ow">in</span> <span class="n">subjectAltName</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;,&#39;</span><span class="p">):</span>
+ <span class="n">certHost</span> <span class="o">=</span> <span class="n">certHost</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
+ <span class="k">if</span> <span class="n">certHost</span><span class="p">[:</span><span class="mi">4</span><span class="p">]</span> <span class="o">==</span> <span class="s1">&#39;dns:&#39;</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">useSubjectAltNameOnly</span> <span class="o">=</span> <span class="kc">True</span>
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_match</span><span class="p">(</span><span class="n">host</span><span class="p">,</span> <span class="n">certHost</span><span class="p">[</span><span class="mi">4</span><span class="p">:]):</span>
+ <span class="k">return</span> <span class="kc">True</span>
+ <span class="k">elif</span> <span class="n">certHost</span><span class="p">[:</span><span class="mi">11</span><span class="p">]</span> <span class="o">==</span> <span class="s1">&#39;ip address:&#39;</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">useSubjectAltNameOnly</span> <span class="o">=</span> <span class="kc">True</span>
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_matchIPAddress</span><span class="p">(</span><span class="n">host</span><span class="p">,</span> <span class="n">certHost</span><span class="p">[</span><span class="mi">11</span><span class="p">:]):</span>
+ <span class="k">return</span> <span class="kc">True</span>
+ <span class="k">return</span> <span class="kc">False</span>
+
+ <span class="k">def</span> <span class="nf">_match</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">host</span><span class="p">,</span> <span class="n">certHost</span><span class="p">):</span>
+ <span class="c1"># type: (str, str) -&gt; bool</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> &gt;&gt;&gt; check = Checker()</span>
+<span class="sd"> &gt;&gt;&gt; check._match(host=&#39;my.example.com&#39;, certHost=&#39;my.example.com&#39;)</span>
+<span class="sd"> True</span>
+<span class="sd"> &gt;&gt;&gt; check._match(host=&#39;my.example.com&#39;, certHost=&#39;*.example.com&#39;)</span>
+<span class="sd"> True</span>
+<span class="sd"> &gt;&gt;&gt; check._match(host=&#39;my.example.com&#39;, certHost=&#39;m*.example.com&#39;)</span>
+<span class="sd"> True</span>
+<span class="sd"> &gt;&gt;&gt; check._match(host=&#39;my.example.com&#39;, certHost=&#39;m*.EXAMPLE.com&#39;)</span>
+<span class="sd"> True</span>
+<span class="sd"> &gt;&gt;&gt; check._match(host=&#39;my.example.com&#39;, certHost=&#39;m*ample.com&#39;)</span>
+<span class="sd"> False</span>
+<span class="sd"> &gt;&gt;&gt; check._match(host=&#39;my.example.com&#39;, certHost=&#39;*.*.com&#39;)</span>
+<span class="sd"> False</span>
+<span class="sd"> &gt;&gt;&gt; check._match(host=&#39;1.2.3.4&#39;, certHost=&#39;1.2.3.4&#39;)</span>
+<span class="sd"> True</span>
+<span class="sd"> &gt;&gt;&gt; check._match(host=&#39;1.2.3.4&#39;, certHost=&#39;*.2.3.4&#39;)</span>
+<span class="sd"> False</span>
+<span class="sd"> &gt;&gt;&gt; check._match(host=&#39;1234&#39;, certHost=&#39;1234&#39;)</span>
+<span class="sd"> True</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="c1"># XXX See RFC 2818 and 3280 for matching rules, this is may not</span>
+ <span class="c1"># XXX yet be complete.</span>
+
+ <span class="n">host</span> <span class="o">=</span> <span class="n">host</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
+ <span class="n">certHost</span> <span class="o">=</span> <span class="n">certHost</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
+
+ <span class="k">if</span> <span class="n">host</span> <span class="o">==</span> <span class="n">certHost</span><span class="p">:</span>
+ <span class="k">return</span> <span class="kc">True</span>
+
+ <span class="k">if</span> <span class="n">certHost</span><span class="o">.</span><span class="n">count</span><span class="p">(</span><span class="s1">&#39;*&#39;</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
+ <span class="c1"># Not sure about this, but being conservative</span>
+ <span class="k">return</span> <span class="kc">False</span>
+
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">numericIpMatch</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">host</span><span class="p">)</span> <span class="ow">or</span> \
+ <span class="bp">self</span><span class="o">.</span><span class="n">numericIpMatch</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">certHost</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;*&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">)):</span>
+ <span class="c1"># Not sure if * allowed in numeric IP, but think not.</span>
+ <span class="k">return</span> <span class="kc">False</span>
+
+ <span class="k">if</span> <span class="n">certHost</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s1">&#39;</span><span class="se">\\</span><span class="s1">&#39;</span><span class="p">)</span> <span class="o">&gt;</span> <span class="o">-</span><span class="mi">1</span><span class="p">:</span>
+ <span class="c1"># Not sure about this, maybe some encoding might have these.</span>
+ <span class="c1"># But being conservative for now, because regex below relies</span>
+ <span class="c1"># on this.</span>
+ <span class="k">return</span> <span class="kc">False</span>
+
+ <span class="c1"># Massage certHost so that it can be used in regex</span>
+ <span class="n">certHost</span> <span class="o">=</span> <span class="n">certHost</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;.&#39;</span><span class="p">,</span> <span class="s1">&#39;\.&#39;</span><span class="p">)</span>
+ <span class="n">certHost</span> <span class="o">=</span> <span class="n">certHost</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;*&#39;</span><span class="p">,</span> <span class="s1">&#39;[^\.]*&#39;</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="s1">&#39;^</span><span class="si">%s</span><span class="s1">$&#39;</span> <span class="o">%</span> <span class="n">certHost</span><span class="p">)</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">host</span><span class="p">):</span>
+ <span class="k">return</span> <span class="kc">True</span>
+
+ <span class="k">return</span> <span class="kc">False</span>
+
+ <span class="k">def</span> <span class="nf">_matchIPAddress</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">host</span><span class="p">,</span> <span class="n">certHost</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr, AnyStr) -&gt; bool</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> &gt;&gt;&gt; check = Checker()</span>
+<span class="sd"> &gt;&gt;&gt; check._matchIPAddress(host=&#39;my.example.com&#39;,</span>
+<span class="sd"> ... certHost=&#39;my.example.com&#39;)</span>
+<span class="sd"> False</span>
+<span class="sd"> &gt;&gt;&gt; check._matchIPAddress(host=&#39;1.2.3.4&#39;, certHost=&#39;1.2.3.4&#39;)</span>
+<span class="sd"> True</span>
+<span class="sd"> &gt;&gt;&gt; check._matchIPAddress(host=&#39;1.2.3.4&#39;, certHost=&#39;*.2.3.4&#39;)</span>
+<span class="sd"> False</span>
+<span class="sd"> &gt;&gt;&gt; check._matchIPAddress(host=&#39;1.2.3.4&#39;, certHost=&#39;1.2.3.40&#39;)</span>
+<span class="sd"> False</span>
+<span class="sd"> &gt;&gt;&gt; check._matchIPAddress(host=&#39;::1&#39;, certHost=&#39;::1&#39;)</span>
+<span class="sd"> True</span>
+<span class="sd"> &gt;&gt;&gt; check._matchIPAddress(host=&#39;::1&#39;, certHost=&#39;0:0:0:0:0:0:0:1&#39;)</span>
+<span class="sd"> True</span>
+<span class="sd"> &gt;&gt;&gt; check._matchIPAddress(host=&#39;::1&#39;, certHost=&#39;::2&#39;)</span>
+<span class="sd"> False</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">try</span><span class="p">:</span>
+ <span class="n">canonical</span> <span class="o">=</span> <span class="n">socket</span><span class="o">.</span><span class="n">getaddrinfo</span><span class="p">(</span><span class="n">host</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">socket</span><span class="o">.</span><span class="n">SOCK_STREAM</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span>
+ <span class="n">socket</span><span class="o">.</span><span class="n">AI_NUMERICHOST</span><span class="p">)</span>
+ <span class="n">certCanonical</span> <span class="o">=</span> <span class="n">socket</span><span class="o">.</span><span class="n">getaddrinfo</span><span class="p">(</span><span class="n">certHost</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span>
+ <span class="n">socket</span><span class="o">.</span><span class="n">SOCK_STREAM</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span>
+ <span class="n">socket</span><span class="o">.</span><span class="n">AI_NUMERICHOST</span><span class="p">)</span>
+ <span class="k">except</span><span class="p">:</span>
+ <span class="k">return</span> <span class="kc">False</span>
+ <span class="k">return</span> <span class="n">canonical</span> <span class="o">==</span> <span class="n">certCanonical</span></div>
+
+
+<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">&#39;__main__&#39;</span><span class="p">:</span>
+ <span class="kn">import</span> <span class="nn">doctest</span>
+ <span class="n">doctest</span><span class="o">.</span><span class="n">testmod</span><span class="p">()</span>
+</pre></div>
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="../../../index.html">M2Crypto</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="../../../M2Crypto.html">M2Crypto Package</a></li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="../../../index.html">Documentation overview</a><ul>
+ <li><a href="../../index.html">Module code</a><ul>
+ <li><a href="../SSL.html">M2Crypto.SSL</a><ul>
+ </ul></li>
+ </ul></li>
+ </ul></li>
+</ul>
+</div>
+<div id="searchbox" style="display: none" role="search">
+ <h3>Quick search</h3>
+ <div class="searchformwrapper">
+ <form class="search" action="../../../search.html" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ </div>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer">
+ &copy;2017, Matej Cepl <mcepl@cepl.eu>.
+
+ |
+ Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
+ &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
+
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/_modules/M2Crypto/SSL/Cipher.html b/doc/html/_modules/M2Crypto/SSL/Cipher.html
new file mode 100644
index 0000000..d9a39b4
--- /dev/null
+++ b/doc/html/_modules/M2Crypto/SSL/Cipher.html
@@ -0,0 +1,166 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>M2Crypto.SSL.Cipher &#8212; M2Crypto documentation</title>
+ <link rel="stylesheet" href="../../../_static/alabaster.css" type="text/css" />
+ <link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../../../_static/jquery.js"></script>
+ <script type="text/javascript" src="../../../_static/underscore.js"></script>
+ <script type="text/javascript" src="../../../_static/doctools.js"></script>
+ <script type="text/javascript" src="../../../_static/language_data.js"></script>
+ <link rel="index" title="Index" href="../../../genindex.html" />
+ <link rel="search" title="Search" href="../../../search.html" />
+
+ <link rel="stylesheet" href="../../../_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+ <h1>Source code for M2Crypto.SSL.Cipher</h1><div class="highlight"><pre>
+<span></span><span class="sd">&quot;&quot;&quot;SSL Ciphers</span>
+
+<span class="sd">Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved.&quot;&quot;&quot;</span>
+
+<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;Cipher&#39;</span><span class="p">,</span> <span class="s1">&#39;Cipher_Stack&#39;</span><span class="p">]</span>
+
+<span class="kn">from</span> <span class="nn">M2Crypto</span> <span class="k">import</span> <span class="n">m2</span><span class="p">,</span> <span class="n">py27plus</span><span class="p">,</span> <span class="n">six</span>
+<span class="k">if</span> <span class="n">py27plus</span><span class="p">:</span>
+ <span class="kn">from</span> <span class="nn">typing</span> <span class="k">import</span> <span class="n">Iterable</span> <span class="c1"># noqa</span>
+
+
+<div class="viewcode-block" id="Cipher"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Cipher.Cipher">[docs]</a><span class="k">class</span> <span class="nc">Cipher</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">cipher</span><span class="p">):</span>
+ <span class="c1"># type: (str) -&gt; None</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">cipher</span> <span class="o">=</span> <span class="n">cipher</span>
+
+ <span class="k">def</span> <span class="nf">__len__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_cipher_get_bits</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">cipher</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; str</span>
+ <span class="k">return</span> <span class="s2">&quot;</span><span class="si">%s</span><span class="s2">-</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">(),</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="p">))</span>
+
+ <span class="k">def</span> <span class="nf">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; str</span>
+ <span class="k">return</span> <span class="s2">&quot;</span><span class="si">%s</span><span class="s2">-</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">(),</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="p">))</span>
+
+<div class="viewcode-block" id="Cipher.version"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Cipher.Cipher.version">[docs]</a> <span class="k">def</span> <span class="nf">version</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_cipher_get_version</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">cipher</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Cipher.name"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Cipher.Cipher.name">[docs]</a> <span class="k">def</span> <span class="nf">name</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; str</span>
+ <span class="k">return</span> <span class="n">six</span><span class="o">.</span><span class="n">ensure_text</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">ssl_cipher_get_name</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">cipher</span><span class="p">))</span></div></div>
+
+
+<div class="viewcode-block" id="Cipher_Stack"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Cipher.Cipher_Stack">[docs]</a><span class="k">class</span> <span class="nc">Cipher_Stack</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">stack</span><span class="p">):</span>
+ <span class="c1"># type: (bytes) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> :param stack: binary of the C-type STACK_OF(SSL_CIPHER)</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">stack</span> <span class="o">=</span> <span class="n">stack</span>
+
+ <span class="k">def</span> <span class="nf">__len__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">sk_ssl_cipher_num</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">stack</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">__getitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">idx</span><span class="p">):</span>
+ <span class="c1"># type: (int) -&gt; Cipher</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="mi">0</span> <span class="o">&lt;=</span> <span class="n">idx</span> <span class="o">&lt;</span> <span class="n">m2</span><span class="o">.</span><span class="n">sk_ssl_cipher_num</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">stack</span><span class="p">):</span>
+ <span class="k">raise</span> <span class="ne">IndexError</span><span class="p">(</span><span class="s1">&#39;index out of range&#39;</span><span class="p">)</span>
+ <span class="n">v</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">sk_ssl_cipher_value</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">stack</span><span class="p">,</span> <span class="n">idx</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">Cipher</span><span class="p">(</span><span class="n">v</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">__iter__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; Iterable</span>
+ <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">six</span><span class="o">.</span><span class="n">moves</span><span class="o">.</span><span class="n">range</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">sk_ssl_cipher_num</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">stack</span><span class="p">)):</span>
+ <span class="k">yield</span> <span class="bp">self</span><span class="p">[</span><span class="n">i</span><span class="p">]</span></div>
+</pre></div>
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="../../../index.html">M2Crypto</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="../../../M2Crypto.html">M2Crypto Package</a></li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="../../../index.html">Documentation overview</a><ul>
+ <li><a href="../../index.html">Module code</a><ul>
+ <li><a href="../SSL.html">M2Crypto.SSL</a><ul>
+ </ul></li>
+ </ul></li>
+ </ul></li>
+</ul>
+</div>
+<div id="searchbox" style="display: none" role="search">
+ <h3>Quick search</h3>
+ <div class="searchformwrapper">
+ <form class="search" action="../../../search.html" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ </div>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer">
+ &copy;2017, Matej Cepl <mcepl@cepl.eu>.
+
+ |
+ Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
+ &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
+
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/_modules/M2Crypto/SSL/Connection.html b/doc/html/_modules/M2Crypto/SSL/Connection.html
new file mode 100644
index 0000000..fcc8c69
--- /dev/null
+++ b/doc/html/_modules/M2Crypto/SSL/Connection.html
@@ -0,0 +1,796 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>M2Crypto.SSL.Connection &#8212; M2Crypto documentation</title>
+ <link rel="stylesheet" href="../../../_static/alabaster.css" type="text/css" />
+ <link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../../../_static/jquery.js"></script>
+ <script type="text/javascript" src="../../../_static/underscore.js"></script>
+ <script type="text/javascript" src="../../../_static/doctools.js"></script>
+ <script type="text/javascript" src="../../../_static/language_data.js"></script>
+ <link rel="index" title="Index" href="../../../genindex.html" />
+ <link rel="search" title="Search" href="../../../search.html" />
+
+ <link rel="stylesheet" href="../../../_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+ <h1>Source code for M2Crypto.SSL.Connection</h1><div class="highlight"><pre>
+<span></span><span class="kn">from</span> <span class="nn">__future__</span> <span class="k">import</span> <span class="n">absolute_import</span>
+
+<span class="sd">&quot;&quot;&quot;SSL Connection aka socket</span>
+
+<span class="sd">Copyright (c) 1999-2004 Ng Pheng Siong. All rights reserved.</span>
+
+<span class="sd">Portions created by Open Source Applications Foundation (OSAF) are</span>
+<span class="sd">Copyright (C) 2004-2007 OSAF. All Rights Reserved.</span>
+
+<span class="sd">Copyright 2008 Heikki Toivonen. All rights reserved.</span>
+<span class="sd">&quot;&quot;&quot;</span>
+
+<span class="kn">import</span> <span class="nn">logging</span>
+<span class="kn">import</span> <span class="nn">socket</span>
+
+<span class="kn">from</span> <span class="nn">M2Crypto</span> <span class="k">import</span> <span class="n">BIO</span><span class="p">,</span> <span class="n">Err</span><span class="p">,</span> <span class="n">X509</span><span class="p">,</span> <span class="n">m2</span><span class="p">,</span> <span class="n">py27plus</span><span class="p">,</span> <span class="n">six</span><span class="p">,</span> <span class="n">util</span> <span class="c1"># noqa</span>
+<span class="kn">from</span> <span class="nn">M2Crypto.SSL</span> <span class="k">import</span> <span class="n">Checker</span><span class="p">,</span> <span class="n">Context</span><span class="p">,</span> <span class="n">timeout</span> <span class="c1"># noqa</span>
+<span class="kn">from</span> <span class="nn">M2Crypto.SSL</span> <span class="k">import</span> <span class="n">SSLError</span>
+<span class="kn">from</span> <span class="nn">M2Crypto.SSL.Cipher</span> <span class="k">import</span> <span class="n">Cipher</span><span class="p">,</span> <span class="n">Cipher_Stack</span>
+<span class="kn">from</span> <span class="nn">M2Crypto.SSL.Session</span> <span class="k">import</span> <span class="n">Session</span>
+<span class="k">if</span> <span class="n">py27plus</span><span class="p">:</span>
+ <span class="kn">from</span> <span class="nn">typing</span> <span class="k">import</span> <span class="n">Any</span><span class="p">,</span> <span class="n">AnyStr</span><span class="p">,</span> <span class="n">Callable</span><span class="p">,</span> <span class="n">Dict</span><span class="p">,</span> <span class="n">List</span><span class="p">,</span> <span class="n">Optional</span><span class="p">,</span> <span class="n">Tuple</span><span class="p">,</span> <span class="n">Union</span> <span class="c1"># noqa</span>
+
+<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;Connection&#39;</span><span class="p">,</span>
+ <span class="s1">&#39;timeout&#39;</span><span class="p">,</span> <span class="c1"># XXX Not really, but for documentation purposes</span>
+ <span class="p">]</span>
+
+<span class="n">log</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="vm">__name__</span><span class="p">)</span>
+
+
+<span class="k">def</span> <span class="nf">_serverPostConnectionCheck</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kw</span><span class="p">):</span>
+ <span class="c1"># type: (*Any, **Any) -&gt; int</span>
+ <span class="k">return</span> <span class="mi">1</span>
+
+
+<div class="viewcode-block" id="Connection"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection">[docs]</a><span class="k">class</span> <span class="nc">Connection</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;An SSL connection.&quot;&quot;&quot;</span>
+
+ <span class="n">clientPostConnectionCheck</span> <span class="o">=</span> <span class="n">Checker</span><span class="o">.</span><span class="n">Checker</span><span class="p">()</span>
+ <span class="n">serverPostConnectionCheck</span> <span class="o">=</span> <span class="n">_serverPostConnectionCheck</span>
+
+ <span class="n">m2_bio_free</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">bio_free</span>
+ <span class="n">m2_ssl_free</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_free</span>
+ <span class="n">m2_bio_noclose</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">bio_noclose</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">ctx</span><span class="p">,</span> <span class="n">sock</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">family</span><span class="o">=</span><span class="n">socket</span><span class="o">.</span><span class="n">AF_INET</span><span class="p">):</span>
+ <span class="c1"># type: (Context, socket.socket, int) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+
+<span class="sd"> :param ctx: SSL.Context</span>
+<span class="sd"> :param sock: socket to be used</span>
+<span class="sd"> :param family: socket family</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">ctx</span> <span class="o">=</span> <span class="n">ctx</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">ssl</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_new</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="o">.</span><span class="n">ctx</span><span class="p">)</span> <span class="c1"># type: bytes</span>
+ <span class="k">if</span> <span class="n">sock</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">socket</span> <span class="o">=</span> <span class="n">sock</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">socket</span> <span class="o">=</span> <span class="n">socket</span><span class="o">.</span><span class="n">socket</span><span class="p">(</span><span class="n">family</span><span class="p">,</span> <span class="n">socket</span><span class="o">.</span><span class="n">SOCK_STREAM</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">socket</span><span class="o">.</span><span class="n">setsockopt</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">SOL_SOCKET</span><span class="p">,</span> <span class="n">socket</span><span class="o">.</span><span class="n">SO_REUSEADDR</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_fileno</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">socket</span><span class="o">.</span><span class="n">fileno</span><span class="p">()</span>
+
+ <span class="bp">self</span><span class="o">.</span><span class="n">_timeout</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">socket</span><span class="o">.</span><span class="n">gettimeout</span><span class="p">()</span>
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_timeout</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_timeout</span> <span class="o">=</span> <span class="o">-</span><span class="mf">1.0</span>
+
+ <span class="bp">self</span><span class="o">.</span><span class="n">ssl_close_flag</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">bio_noclose</span>
+
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="o">.</span><span class="n">post_connection_check</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">set_post_connection_check_callback</span><span class="p">(</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="o">.</span><span class="n">post_connection_check</span><span class="p">)</span>
+
+ <span class="bp">self</span><span class="o">.</span><span class="n">host</span> <span class="o">=</span> <span class="kc">None</span>
+
+ <span class="k">def</span> <span class="nf">__del__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="c1"># Notice that M2Crypto doesn&#39;t automatically shuts down the</span>
+ <span class="c1"># connection here. You have to call self.close() in your</span>
+ <span class="c1"># program, M2Crypto won&#39;t do it automatically for you.</span>
+ <span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;sslbio&#39;</span><span class="p">,</span> <span class="kc">None</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">m2_bio_free</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">sslbio</span><span class="p">)</span>
+ <span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;sockbio&#39;</span><span class="p">,</span> <span class="kc">None</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">m2_bio_free</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">sockbio</span><span class="p">)</span>
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">ssl_close_flag</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">m2_bio_noclose</span> <span class="ow">and</span> \
+ <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;ssl&#39;</span><span class="p">,</span> <span class="kc">None</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">m2_ssl_free</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">socket</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
+
+<div class="viewcode-block" id="Connection.close"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.close">[docs]</a> <span class="k">def</span> <span class="nf">close</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">ssl_shutdown</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Connection.clear"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.clear">[docs]</a> <span class="k">def</span> <span class="nf">clear</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> If there were errors in this connection, call clear() rather</span>
+<span class="sd"> than close() to end it, so that bad sessions will be cleared</span>
+<span class="sd"> from cache.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_clear</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Connection.set_shutdown"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.set_shutdown">[docs]</a> <span class="k">def</span> <span class="nf">set_shutdown</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">mode</span><span class="p">):</span>
+ <span class="c1"># type: (int) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;Sets the shutdown state of the Connection to mode.</span>
+
+<span class="sd"> The shutdown state of an ssl connection is a bitmask of (use</span>
+<span class="sd"> m2.SSL_* constants):</span>
+
+<span class="sd"> 0 No shutdown setting, yet.</span>
+
+<span class="sd"> SSL_SENT_SHUTDOWN</span>
+<span class="sd"> A &quot;close notify&quot; shutdown alert was sent to the peer, the</span>
+<span class="sd"> connection is being considered closed and the session is</span>
+<span class="sd"> closed and correct.</span>
+
+<span class="sd"> SSL_RECEIVED_SHUTDOWN</span>
+<span class="sd"> A shutdown alert was received form the peer, either a normal</span>
+<span class="sd"> &quot;close notify&quot; or a fatal error.</span>
+
+<span class="sd"> SSL_SENT_SHUTDOWN and SSL_RECEIVED_SHUTDOWN can be set at the</span>
+<span class="sd"> same time.</span>
+
+<span class="sd"> :param mode: set the mode bitmask.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">ssl_set_shutdown1</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="p">,</span> <span class="n">mode</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Connection.get_shutdown"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.get_shutdown">[docs]</a> <span class="k">def</span> <span class="nf">get_shutdown</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;Get the current shutdown mode of the Connection.&quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_get_shutdown</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Connection.bind"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.bind">[docs]</a> <span class="k">def</span> <span class="nf">bind</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">addr</span><span class="p">):</span>
+ <span class="c1"># type: (util.AddrType) -&gt; None</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">socket</span><span class="o">.</span><span class="n">bind</span><span class="p">(</span><span class="n">addr</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Connection.listen"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.listen">[docs]</a> <span class="k">def</span> <span class="nf">listen</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">qlen</span><span class="o">=</span><span class="mi">5</span><span class="p">):</span>
+ <span class="c1"># type: (int) -&gt; None</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">socket</span><span class="o">.</span><span class="n">listen</span><span class="p">(</span><span class="n">qlen</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Connection.ssl_get_error"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.ssl_get_error">[docs]</a> <span class="k">def</span> <span class="nf">ssl_get_error</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">ret</span><span class="p">):</span>
+ <span class="c1"># type: (int) -&gt; int</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_get_error</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="p">,</span> <span class="n">ret</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Connection.set_bio"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.set_bio">[docs]</a> <span class="k">def</span> <span class="nf">set_bio</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">readbio</span><span class="p">,</span> <span class="n">writebio</span><span class="p">):</span>
+ <span class="c1"># type: (BIO.BIO, BIO.BIO) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;Explicitly set read and write bios</span>
+
+<span class="sd"> Connects the BIOs for the read and write operations of the</span>
+<span class="sd"> TLS/SSL (encrypted) side of ssl.</span>
+
+<span class="sd"> The SSL engine inherits the behaviour of both BIO objects,</span>
+<span class="sd"> respectively. If a BIO is non-blocking, the Connection will also</span>
+<span class="sd"> have non-blocking behaviour.</span>
+
+<span class="sd"> If there was already a BIO connected to Connection, BIO_free()</span>
+<span class="sd"> will be called (for both the reading and writing side, if</span>
+<span class="sd"> different).</span>
+
+<span class="sd"> :param readbio: BIO for reading</span>
+<span class="sd"> :param writebio: BIO for writing.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">ssl_set_bio</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="p">,</span> <span class="n">readbio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span> <span class="n">writebio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span></div>
+
+<div class="viewcode-block" id="Connection.set_client_CA_list_from_file"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.set_client_CA_list_from_file">[docs]</a> <span class="k">def</span> <span class="nf">set_client_CA_list_from_file</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">cafile</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;Set the acceptable client CA list.</span>
+
+<span class="sd"> If the client returns a certificate, it must have been issued by</span>
+<span class="sd"> one of the CAs listed in cafile.</span>
+
+<span class="sd"> Makes sense only for servers.</span>
+
+<span class="sd"> :param cafile: Filename from which to load the CA list.</span>
+
+<span class="sd"> :return: 0 A failure while manipulating the STACK_OF(X509_NAME)</span>
+<span class="sd"> object occurred or the X509_NAME could not be</span>
+<span class="sd"> extracted from cacert. Check the error stack to find</span>
+<span class="sd"> out the reason.</span>
+
+<span class="sd"> 1 The operation succeeded.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">ssl_set_client_CA_list_from_file</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="p">,</span> <span class="n">cafile</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Connection.set_client_CA_list_from_context"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.set_client_CA_list_from_context">[docs]</a> <span class="k">def</span> <span class="nf">set_client_CA_list_from_context</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Set the acceptable client CA list. If the client</span>
+<span class="sd"> returns a certificate, it must have been issued by</span>
+<span class="sd"> one of the CAs listed in context.</span>
+
+<span class="sd"> Makes sense only for servers.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">ssl_set_client_CA_list_from_context</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="o">.</span><span class="n">ctx</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Connection.setup_addr"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.setup_addr">[docs]</a> <span class="k">def</span> <span class="nf">setup_addr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">addr</span><span class="p">):</span>
+ <span class="c1"># type: (util.AddrType) -&gt; None</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">addr</span> <span class="o">=</span> <span class="n">addr</span></div>
+
+<div class="viewcode-block" id="Connection.set_ssl_close_flag"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.set_ssl_close_flag">[docs]</a> <span class="k">def</span> <span class="nf">set_ssl_close_flag</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">flag</span><span class="p">):</span>
+ <span class="c1"># type: (int) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> By default, SSL struct will be freed in __del__. Call with</span>
+<span class="sd"> m2.bio_close to override this default.</span>
+
+<span class="sd"> :param flag: either m2.bio_close or m2.bio_noclose</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">if</span> <span class="n">flag</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">bio_close</span><span class="p">,</span> <span class="n">m2</span><span class="o">.</span><span class="n">bio_noclose</span><span class="p">):</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;flag must be m2.bio_close or m2.bio_noclose&quot;</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">ssl_close_flag</span> <span class="o">=</span> <span class="n">flag</span></div>
+
+<div class="viewcode-block" id="Connection.setup_ssl"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.setup_ssl">[docs]</a> <span class="k">def</span> <span class="nf">setup_ssl</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="c1"># Make a BIO_s_socket.</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">sockbio</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">bio_new_socket</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">socket</span><span class="o">.</span><span class="n">fileno</span><span class="p">(),</span> <span class="mi">0</span><span class="p">)</span>
+ <span class="c1"># Link SSL struct with the BIO_socket.</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">ssl_set_bio</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">sockbio</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">sockbio</span><span class="p">)</span>
+ <span class="c1"># Make a BIO_f_ssl.</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">sslbio</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">bio_new</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">bio_f_ssl</span><span class="p">())</span>
+ <span class="c1"># Link BIO_f_ssl with the SSL struct.</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">bio_set_ssl</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">sslbio</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="p">,</span> <span class="n">m2</span><span class="o">.</span><span class="n">bio_noclose</span><span class="p">)</span></div>
+
+ <span class="k">def</span> <span class="nf">_setup_ssl</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">addr</span><span class="p">):</span>
+ <span class="c1"># type: (util.AddrType) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;Deprecated&quot;&quot;&quot;</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">setup_addr</span><span class="p">(</span><span class="n">addr</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">setup_ssl</span><span class="p">()</span>
+
+<div class="viewcode-block" id="Connection.set_accept_state"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.set_accept_state">[docs]</a> <span class="k">def</span> <span class="nf">set_accept_state</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;Sets Connection to work in the server mode.&quot;&quot;&quot;</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">ssl_set_accept_state</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Connection.accept_ssl"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.accept_ssl">[docs]</a> <span class="k">def</span> <span class="nf">accept_ssl</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; Optional[int]</span>
+ <span class="sd">&quot;&quot;&quot;Waits for a TLS/SSL client to initiate the TLS/SSL handshake.</span>
+
+<span class="sd"> The communication channel must already have been set and</span>
+<span class="sd"> assigned to the ssl by setting an underlying BIO.</span>
+
+<span class="sd"> :return: 0 The TLS/SSL handshake was not successful but was shut</span>
+<span class="sd"> down controlled and by the specifications of the</span>
+<span class="sd"> TLS/SSL protocol. Call get_error() with the return</span>
+<span class="sd"> value ret to find out the reason.</span>
+
+<span class="sd"> 1 The TLS/SSL handshake was successfully completed,</span>
+<span class="sd"> a TLS/SSL connection has been established.</span>
+
+<span class="sd"> &lt;0 The TLS/SSL handshake was not successful because</span>
+<span class="sd"> a fatal error occurred either at the protocol level</span>
+<span class="sd"> or a connection failure occurred. The shutdown was</span>
+<span class="sd"> not clean. It can also occur of action is need to</span>
+<span class="sd"> continue the operation for non-blocking BIOs. Call</span>
+<span class="sd"> get_error() with the return value ret to find</span>
+<span class="sd"> out the reason.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_accept</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_timeout</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Connection.accept"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.accept">[docs]</a> <span class="k">def</span> <span class="nf">accept</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; Tuple[Connection, util.AddrType]</span>
+ <span class="sd">&quot;&quot;&quot;Accept an SSL connection.</span>
+
+<span class="sd"> The return value is a pair (ssl, addr) where ssl is a new SSL</span>
+<span class="sd"> connection object and addr is the address bound to the other end</span>
+<span class="sd"> of the SSL connection.</span>
+
+<span class="sd"> :return: tuple of Connection and addr. Address can take very</span>
+<span class="sd"> various forms (see socket documentation), for IPv4 it</span>
+<span class="sd"> is tuple(str, int), for IPv6 a tuple of four (host,</span>
+<span class="sd"> port, flowinfo, scopeid), where the last two are</span>
+<span class="sd"> optional ints.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">sock</span><span class="p">,</span> <span class="n">addr</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">socket</span><span class="o">.</span><span class="n">accept</span><span class="p">()</span>
+ <span class="n">ssl</span> <span class="o">=</span> <span class="n">Connection</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">,</span> <span class="n">sock</span><span class="p">)</span>
+ <span class="n">ssl</span><span class="o">.</span><span class="n">addr</span> <span class="o">=</span> <span class="n">addr</span>
+ <span class="n">ssl</span><span class="o">.</span><span class="n">setup_ssl</span><span class="p">()</span>
+ <span class="n">ssl</span><span class="o">.</span><span class="n">set_accept_state</span><span class="p">()</span>
+ <span class="n">ssl</span><span class="o">.</span><span class="n">accept_ssl</span><span class="p">()</span>
+ <span class="n">check</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;postConnectionCheck&#39;</span><span class="p">,</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">serverPostConnectionCheck</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">check</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">check</span><span class="p">(</span><span class="n">ssl</span><span class="o">.</span><span class="n">get_peer_cert</span><span class="p">(),</span> <span class="n">ssl</span><span class="o">.</span><span class="n">addr</span><span class="p">[</span><span class="mi">0</span><span class="p">]):</span>
+ <span class="k">raise</span> <span class="n">Checker</span><span class="o">.</span><span class="n">SSLVerificationError</span><span class="p">(</span>
+ <span class="s1">&#39;post connection check failed&#39;</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">ssl</span><span class="p">,</span> <span class="n">addr</span></div>
+
+<div class="viewcode-block" id="Connection.set_connect_state"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.set_connect_state">[docs]</a> <span class="k">def</span> <span class="nf">set_connect_state</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;Sets Connection to work in the client mode.&quot;&quot;&quot;</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">ssl_set_connect_state</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Connection.connect_ssl"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.connect_ssl">[docs]</a> <span class="k">def</span> <span class="nf">connect_ssl</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; Optional[int]</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_connect</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_timeout</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Connection.connect"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.connect">[docs]</a> <span class="k">def</span> <span class="nf">connect</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">addr</span><span class="p">):</span>
+ <span class="c1"># type: (util.AddrType) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;Overloading socket.connect()</span>
+
+<span class="sd"> :param addr: addresses have various depending on their type</span>
+
+<span class="sd"> :return:status of ssl_connect()</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">socket</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">addr</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">addr</span> <span class="o">=</span> <span class="n">addr</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">setup_ssl</span><span class="p">()</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">set_connect_state</span><span class="p">()</span>
+ <span class="n">ret</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">connect_ssl</span><span class="p">()</span>
+ <span class="n">check</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;postConnectionCheck&#39;</span><span class="p">,</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">clientPostConnectionCheck</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">check</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">get_peer_cert</span><span class="p">(),</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">host</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">host</span> <span class="k">else</span> <span class="bp">self</span><span class="o">.</span><span class="n">addr</span><span class="p">[</span><span class="mi">0</span><span class="p">]):</span>
+ <span class="k">raise</span> <span class="n">Checker</span><span class="o">.</span><span class="n">SSLVerificationError</span><span class="p">(</span>
+ <span class="s1">&#39;post connection check failed&#39;</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">ret</span></div>
+
+<div class="viewcode-block" id="Connection.shutdown"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.shutdown">[docs]</a> <span class="k">def</span> <span class="nf">shutdown</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">how</span><span class="p">):</span>
+ <span class="c1"># type: (int) -&gt; None</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">ssl_set_shutdown</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="p">,</span> <span class="n">how</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Connection.renegotiate"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.renegotiate">[docs]</a> <span class="k">def</span> <span class="nf">renegotiate</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;Renegotiate this connection&#39;s SSL parameters.&quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_renegotiate</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Connection.pending"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.pending">[docs]</a> <span class="k">def</span> <span class="nf">pending</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;Return the numbers of octets that can be read from the connection.&quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_pending</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="p">)</span></div>
+
+ <span class="k">def</span> <span class="nf">_write_bio</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
+ <span class="c1"># type: (bytes) -&gt; int</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_write</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_timeout</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">_write_nbio</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
+ <span class="c1"># type: (bytes) -&gt; int</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_write_nbio</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">_read_bio</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">size</span><span class="o">=</span><span class="mi">1024</span><span class="p">):</span>
+ <span class="c1"># type: (int) -&gt; bytes</span>
+ <span class="k">if</span> <span class="n">size</span> <span class="o">&lt;=</span> <span class="mi">0</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">&#39;size &lt;= 0&#39;</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_read</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="p">,</span> <span class="n">size</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_timeout</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">_read_nbio</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">size</span><span class="o">=</span><span class="mi">1024</span><span class="p">):</span>
+ <span class="c1"># type: (int) -&gt; bytes</span>
+ <span class="k">if</span> <span class="n">size</span> <span class="o">&lt;=</span> <span class="mi">0</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">&#39;size &lt;= 0&#39;</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_read_nbio</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="p">,</span> <span class="n">size</span><span class="p">)</span>
+
+<div class="viewcode-block" id="Connection.write"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.write">[docs]</a> <span class="k">def</span> <span class="nf">write</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
+ <span class="c1"># type: (bytes) -&gt; int</span>
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_timeout</span> <span class="o">!=</span> <span class="mf">0.0</span><span class="p">:</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_write_bio</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_write_nbio</span><span class="p">(</span><span class="n">data</span><span class="p">)</span></div>
+ <span class="n">sendall</span> <span class="o">=</span> <span class="n">send</span> <span class="o">=</span> <span class="n">write</span>
+
+ <span class="k">def</span> <span class="nf">_decref_socketios</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="k">pass</span>
+
+<div class="viewcode-block" id="Connection.recv_into"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.recv_into">[docs]</a> <span class="k">def</span> <span class="nf">recv_into</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">buff</span><span class="p">,</span> <span class="n">nbytes</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
+ <span class="c1"># type: (Union[bytearray, memoryview], int) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> A version of recv() that stores its data into a buffer rather</span>
+<span class="sd"> than creating a new string. Receive up to buffersize bytes from</span>
+<span class="sd"> the socket. If buffersize is not specified (or 0), receive up</span>
+<span class="sd"> to the size available in the given buffer.</span>
+
+<span class="sd"> If buff is bytearray, it will have after return length of the</span>
+<span class="sd"> actually returned number of bytes. If buff is memoryview, then</span>
+<span class="sd"> the size of buff won&#39;t change (it cannot), but all bytes after</span>
+<span class="sd"> the number of returned bytes will be NULL.</span>
+
+<span class="sd"> :param buffer: a buffer for the received bytes</span>
+<span class="sd"> :param nbytes: maximum number of bytes to read</span>
+<span class="sd"> :return: number of bytes read</span>
+
+<span class="sd"> See recv() for documentation about the flags.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">n</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">buff</span><span class="p">)</span> <span class="k">if</span> <span class="n">nbytes</span> <span class="o">==</span> <span class="mi">0</span> <span class="k">else</span> <span class="n">nbytes</span>
+
+ <span class="k">if</span> <span class="n">n</span> <span class="o">&lt;=</span> <span class="mi">0</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">&#39;size &lt;= 0&#39;</span><span class="p">)</span>
+
+ <span class="c1"># buff_bytes are actual bytes returned</span>
+ <span class="n">buff_bytes</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_read</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="p">,</span> <span class="n">n</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_timeout</span><span class="p">)</span>
+ <span class="n">buflen</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">buff_bytes</span><span class="p">)</span>
+
+ <span class="c1"># memoryview type has been added in 2.7</span>
+ <span class="k">if</span> <span class="n">py27plus</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">buff</span><span class="p">,</span> <span class="nb">memoryview</span><span class="p">):</span>
+ <span class="n">buff</span><span class="p">[:</span><span class="n">buflen</span><span class="p">]</span> <span class="o">=</span> <span class="n">buff_bytes</span>
+ <span class="n">buff</span><span class="p">[</span><span class="n">buflen</span><span class="p">:]</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\x00</span><span class="s1">&#39;</span> <span class="o">*</span> <span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">buff</span><span class="p">)</span> <span class="o">-</span> <span class="n">buflen</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">buff</span><span class="p">[:]</span> <span class="o">=</span> <span class="n">buff_bytes</span>
+
+ <span class="k">return</span> <span class="n">buflen</span></div>
+
+<div class="viewcode-block" id="Connection.read"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.read">[docs]</a> <span class="k">def</span> <span class="nf">read</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">size</span><span class="o">=</span><span class="mi">1024</span><span class="p">):</span>
+ <span class="c1"># type: (int) -&gt; bytes</span>
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_timeout</span> <span class="o">!=</span> <span class="mf">0.0</span><span class="p">:</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_read_bio</span><span class="p">(</span><span class="n">size</span><span class="p">)</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_read_nbio</span><span class="p">(</span><span class="n">size</span><span class="p">)</span></div>
+ <span class="n">recv</span> <span class="o">=</span> <span class="n">read</span>
+
+<div class="viewcode-block" id="Connection.setblocking"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.setblocking">[docs]</a> <span class="k">def</span> <span class="nf">setblocking</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">mode</span><span class="p">):</span>
+ <span class="c1"># type: (int) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;Set this connection&#39;s underlying socket to _mode_.</span>
+
+<span class="sd"> Set blocking or non-blocking mode of the socket: if flag is 0,</span>
+<span class="sd"> the socket is set to non-blocking, else to blocking mode.</span>
+<span class="sd"> Initially all sockets are in blocking mode. In non-blocking mode,</span>
+<span class="sd"> if a recv() call doesn&#39;t find any data, or if a send() call can&#39;t</span>
+<span class="sd"> immediately dispose of the data, a error exception is raised;</span>
+<span class="sd"> in blocking mode, the calls block until they can proceed.</span>
+<span class="sd"> s.setblocking(0) is equivalent to s.settimeout(0.0);</span>
+<span class="sd"> s.setblocking(1) is equivalent to s.settimeout(None).</span>
+
+<span class="sd"> :param mode: new mode to be set</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">socket</span><span class="o">.</span><span class="n">setblocking</span><span class="p">(</span><span class="n">mode</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">mode</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_timeout</span> <span class="o">=</span> <span class="o">-</span><span class="mf">1.0</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_timeout</span> <span class="o">=</span> <span class="mf">0.0</span></div>
+
+<div class="viewcode-block" id="Connection.settimeout"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.settimeout">[docs]</a> <span class="k">def</span> <span class="nf">settimeout</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">timeout</span><span class="p">):</span>
+ <span class="c1"># type: (float) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;Set this connection&#39;s underlying socket&#39;s timeout to _timeout_.&quot;&quot;&quot;</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">socket</span><span class="o">.</span><span class="n">settimeout</span><span class="p">(</span><span class="n">timeout</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_timeout</span> <span class="o">=</span> <span class="n">timeout</span>
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_timeout</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_timeout</span> <span class="o">=</span> <span class="o">-</span><span class="mf">1.0</span></div>
+
+<div class="viewcode-block" id="Connection.fileno"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.fileno">[docs]</a> <span class="k">def</span> <span class="nf">fileno</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">socket</span><span class="o">.</span><span class="n">fileno</span><span class="p">()</span></div>
+
+<div class="viewcode-block" id="Connection.getsockopt"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.getsockopt">[docs]</a> <span class="k">def</span> <span class="nf">getsockopt</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">level</span><span class="p">,</span> <span class="n">optname</span><span class="p">,</span> <span class="n">buflen</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="c1"># type: (int, int, Optional[int]) -&gt; Union[int, bytes]</span>
+ <span class="sd">&quot;&quot;&quot;Get the value of the given socket option.</span>
+
+<span class="sd"> :param level: level at which the option resides.</span>
+<span class="sd"> To manipulate options at the sockets API level, level is</span>
+<span class="sd"> specified as socket.SOL_SOCKET. To manipulate options at</span>
+<span class="sd"> any other level the protocol number of the appropriate</span>
+<span class="sd"> protocol controlling the option is supplied. For example,</span>
+<span class="sd"> to indicate that an option is to be interpreted by the</span>
+<span class="sd"> TCP protocol, level should be set to the protocol number</span>
+<span class="sd"> of socket.SOL_TCP; see getprotoent(3).</span>
+
+<span class="sd"> :param optname: The value of the given socket option is</span>
+<span class="sd"> described in the Unix man page getsockopt(2)). The needed</span>
+<span class="sd"> symbolic constants (SO_* etc.) are defined in the socket</span>
+<span class="sd"> module.</span>
+
+<span class="sd"> :param buflen: If it is absent, an integer option is assumed</span>
+<span class="sd"> and its integer value is returned by the function. If</span>
+<span class="sd"> buflen is present, it specifies the maximum length of the</span>
+<span class="sd"> buffer used to receive the option in, and this buffer is</span>
+<span class="sd"> returned as a bytes object.</span>
+
+<span class="sd"> :return: Either integer or bytes value of the option. It is up</span>
+<span class="sd"> to the caller to decode the contents of the buffer (see</span>
+<span class="sd"> the optional built-in module struct for a way to decode</span>
+<span class="sd"> C structures encoded as byte strings).</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">socket</span><span class="o">.</span><span class="n">getsockopt</span><span class="p">(</span><span class="n">level</span><span class="p">,</span> <span class="n">optname</span><span class="p">,</span> <span class="n">buflen</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Connection.setsockopt"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.setsockopt">[docs]</a> <span class="k">def</span> <span class="nf">setsockopt</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">level</span><span class="p">,</span> <span class="n">optname</span><span class="p">,</span> <span class="n">value</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="c1"># type: (int, int, Union[int, bytes, None]) -&gt; Optional[bytes]</span>
+ <span class="sd">&quot;&quot;&quot;Set the value of the given socket option.</span>
+
+<span class="sd"> :param level: same as with getsockopt() above</span>
+
+<span class="sd"> :param optname: same as with getsockopt() above</span>
+
+<span class="sd"> :param value: an integer or a string representing a buffer. In</span>
+<span class="sd"> the latter case it is up to the caller to ensure</span>
+<span class="sd"> that the string contains the proper bits (see the</span>
+<span class="sd"> optional built-in module struct for a way to</span>
+<span class="sd"> encode C structures as strings).</span>
+
+<span class="sd"> :return: None for success or the error handler for failure.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">socket</span><span class="o">.</span><span class="n">setsockopt</span><span class="p">(</span><span class="n">level</span><span class="p">,</span> <span class="n">optname</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Connection.get_context"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.get_context">[docs]</a> <span class="k">def</span> <span class="nf">get_context</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; Context</span>
+ <span class="sd">&quot;&quot;&quot;Return the Context object associated with this connection.&quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_get_ssl_ctx</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Connection.get_state"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.get_state">[docs]</a> <span class="k">def</span> <span class="nf">get_state</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; bytes</span>
+ <span class="sd">&quot;&quot;&quot;Return the SSL state of this connection.</span>
+
+<span class="sd"> During its use, an SSL objects passes several states. The state</span>
+<span class="sd"> is internally maintained. Querying the state information is not</span>
+<span class="sd"> very informative before or when a connection has been</span>
+<span class="sd"> established. It however can be of significant interest during</span>
+<span class="sd"> the handshake.</span>
+
+<span class="sd"> :return: 6 letter string indicating the current state of the SSL</span>
+<span class="sd"> object ssl.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_get_state</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Connection.verify_ok"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.verify_ok">[docs]</a> <span class="k">def</span> <span class="nf">verify_ok</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; bool</span>
+ <span class="k">return</span> <span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">ssl_get_verify_result</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="p">)</span> <span class="o">==</span> <span class="n">m2</span><span class="o">.</span><span class="n">X509_V_OK</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Connection.get_verify_mode"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.get_verify_mode">[docs]</a> <span class="k">def</span> <span class="nf">get_verify_mode</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;Return the peer certificate verification mode.&quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_get_verify_mode</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Connection.get_verify_depth"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.get_verify_depth">[docs]</a> <span class="k">def</span> <span class="nf">get_verify_depth</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;Return the peer certificate verification depth.&quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_get_verify_depth</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Connection.get_verify_result"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.get_verify_result">[docs]</a> <span class="k">def</span> <span class="nf">get_verify_result</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;Return the peer certificate verification result.&quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_get_verify_result</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Connection.get_peer_cert"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.get_peer_cert">[docs]</a> <span class="k">def</span> <span class="nf">get_peer_cert</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; X509.X509</span>
+ <span class="sd">&quot;&quot;&quot;Return the peer certificate.</span>
+
+<span class="sd"> If the peer did not provide a certificate, return None.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">c</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_get_peer_cert</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">c</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">return</span> <span class="kc">None</span>
+ <span class="c1"># Need to free the pointer coz OpenSSL doesn&#39;t.</span>
+ <span class="k">return</span> <span class="n">X509</span><span class="o">.</span><span class="n">X509</span><span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Connection.get_peer_cert_chain"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.get_peer_cert_chain">[docs]</a> <span class="k">def</span> <span class="nf">get_peer_cert_chain</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; Optional[X509.X509_Stack]</span>
+ <span class="sd">&quot;&quot;&quot;Return the peer certificate chain; if the peer did not provide</span>
+<span class="sd"> a certificate chain, return None.</span>
+
+<span class="sd"> :warning: The returned chain will be valid only for as long as the</span>
+<span class="sd"> connection object is alive. Once the connection object</span>
+<span class="sd"> gets freed, the chain will be freed as well.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">c</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_get_peer_cert_chain</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">c</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">return</span> <span class="kc">None</span>
+ <span class="c1"># No need to free the pointer coz OpenSSL does.</span>
+ <span class="k">return</span> <span class="n">X509</span><span class="o">.</span><span class="n">X509_Stack</span><span class="p">(</span><span class="n">c</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Connection.get_cipher"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.get_cipher">[docs]</a> <span class="k">def</span> <span class="nf">get_cipher</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; Optional[Cipher]</span>
+ <span class="sd">&quot;&quot;&quot;Return an M2Crypto.SSL.Cipher object for this connection; if the</span>
+<span class="sd"> connection has not been initialised with a cipher suite, return None.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">c</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_get_current_cipher</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">c</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">return</span> <span class="kc">None</span>
+ <span class="k">return</span> <span class="n">Cipher</span><span class="p">(</span><span class="n">c</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Connection.get_ciphers"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.get_ciphers">[docs]</a> <span class="k">def</span> <span class="nf">get_ciphers</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; Optional[Cipher_Stack]</span>
+ <span class="sd">&quot;&quot;&quot;Return an M2Crypto.SSL.Cipher_Stack object for this</span>
+<span class="sd"> connection; if the connection has not been initialised with</span>
+<span class="sd"> cipher suites, return None.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">c</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_get_ciphers</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">c</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">return</span> <span class="kc">None</span>
+ <span class="k">return</span> <span class="n">Cipher_Stack</span><span class="p">(</span><span class="n">c</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Connection.get_cipher_list"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.get_cipher_list">[docs]</a> <span class="k">def</span> <span class="nf">get_cipher_list</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">idx</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
+ <span class="c1"># type: (int) -&gt; str</span>
+ <span class="sd">&quot;&quot;&quot;Return the cipher suites for this connection as a string object.&quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">six</span><span class="o">.</span><span class="n">ensure_text</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">ssl_get_cipher_list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="p">,</span> <span class="n">idx</span><span class="p">))</span></div>
+
+<div class="viewcode-block" id="Connection.set_cipher_list"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.set_cipher_list">[docs]</a> <span class="k">def</span> <span class="nf">set_cipher_list</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">cipher_list</span><span class="p">):</span>
+ <span class="c1"># type: (str) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;Set the cipher suites for this connection.&quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_set_cipher_list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="p">,</span> <span class="n">cipher_list</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Connection.makefile"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.makefile">[docs]</a> <span class="k">def</span> <span class="nf">makefile</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="s1">&#39;rb&#39;</span><span class="p">,</span> <span class="n">bufsize</span><span class="o">=-</span><span class="mi">1</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr, int) -&gt; socket._fileobject</span>
+ <span class="k">if</span> <span class="n">six</span><span class="o">.</span><span class="n">PY3</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">socket</span><span class="o">.</span><span class="n">SocketIO</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">mode</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">socket</span><span class="o">.</span><span class="n">_fileobject</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">mode</span><span class="p">,</span> <span class="n">bufsize</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Connection.getsockname"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.getsockname">[docs]</a> <span class="k">def</span> <span class="nf">getsockname</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; util.AddrType</span>
+ <span class="sd">&quot;&quot;&quot;Return the socket&#39;s own address.</span>
+
+<span class="sd"> This is useful to find out the port number of an IPv4/v6 socket,</span>
+<span class="sd"> for instance. (The format of the address returned depends</span>
+<span class="sd"> on the address family -- see above.)</span>
+
+<span class="sd"> :return:socket&#39;s address as addr type</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">socket</span><span class="o">.</span><span class="n">getsockname</span><span class="p">()</span></div>
+
+<div class="viewcode-block" id="Connection.getpeername"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.getpeername">[docs]</a> <span class="k">def</span> <span class="nf">getpeername</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; util.AddrType</span>
+ <span class="sd">&quot;&quot;&quot;Return the remote address to which the socket is connected.</span>
+
+<span class="sd"> This is useful to find out the port number of a remote IPv4/v6 socket,</span>
+<span class="sd"> for instance.</span>
+<span class="sd"> On some systems this function is not supported.</span>
+
+<span class="sd"> :return:</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">socket</span><span class="o">.</span><span class="n">getpeername</span><span class="p">()</span></div>
+
+<div class="viewcode-block" id="Connection.set_session_id_ctx"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.set_session_id_ctx">[docs]</a> <span class="k">def</span> <span class="nf">set_session_id_ctx</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">id</span><span class="p">):</span>
+ <span class="c1"># type: (bytes) -&gt; int</span>
+ <span class="n">ret</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_set_session_id_context</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="p">,</span> <span class="nb">id</span><span class="p">)</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">ret</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="n">SSLError</span><span class="p">(</span><span class="n">Err</span><span class="o">.</span><span class="n">get_error_message</span><span class="p">())</span></div>
+
+<div class="viewcode-block" id="Connection.get_session"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.get_session">[docs]</a> <span class="k">def</span> <span class="nf">get_session</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; Session</span>
+ <span class="n">sess</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_get_session</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">Session</span><span class="p">(</span><span class="n">sess</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Connection.set_session"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.set_session">[docs]</a> <span class="k">def</span> <span class="nf">set_session</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">session</span><span class="p">):</span>
+ <span class="c1"># type: (Session) -&gt; None</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">ssl_set_session</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="p">,</span> <span class="n">session</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span></div>
+
+<div class="viewcode-block" id="Connection.get_default_session_timeout"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.get_default_session_timeout">[docs]</a> <span class="k">def</span> <span class="nf">get_default_session_timeout</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_get_default_session_timeout</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Connection.get_socket_read_timeout"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.get_socket_read_timeout">[docs]</a> <span class="k">def</span> <span class="nf">get_socket_read_timeout</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; timeout</span>
+ <span class="k">return</span> <span class="n">timeout</span><span class="o">.</span><span class="n">struct_to_timeout</span><span class="p">(</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">socket</span><span class="o">.</span><span class="n">getsockopt</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">SOL_SOCKET</span><span class="p">,</span> <span class="n">socket</span><span class="o">.</span><span class="n">SO_RCVTIMEO</span><span class="p">,</span>
+ <span class="n">timeout</span><span class="o">.</span><span class="n">struct_size</span><span class="p">()))</span></div>
+
+ <span class="nd">@staticmethod</span>
+ <span class="k">def</span> <span class="nf">_hexdump</span><span class="p">(</span><span class="n">s</span><span class="p">):</span>
+ <span class="k">assert</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">six</span><span class="o">.</span><span class="n">binary_type</span><span class="p">)</span>
+ <span class="k">return</span> <span class="s2">&quot;:&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">{0:02x}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="nb">ord</span><span class="p">(</span><span class="n">c</span><span class="p">)</span> <span class="k">if</span> <span class="n">six</span><span class="o">.</span><span class="n">PY2</span> <span class="k">else</span> <span class="n">c</span><span class="p">)</span> <span class="k">for</span> <span class="n">c</span> <span class="ow">in</span> <span class="n">s</span><span class="p">)</span>
+
+<div class="viewcode-block" id="Connection.get_socket_write_timeout"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.get_socket_write_timeout">[docs]</a> <span class="k">def</span> <span class="nf">get_socket_write_timeout</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; timeout</span>
+ <span class="n">binstr</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">socket</span><span class="o">.</span><span class="n">getsockopt</span><span class="p">(</span>
+ <span class="n">socket</span><span class="o">.</span><span class="n">SOL_SOCKET</span><span class="p">,</span> <span class="n">socket</span><span class="o">.</span><span class="n">SO_SNDTIMEO</span><span class="p">,</span> <span class="n">timeout</span><span class="o">.</span><span class="n">struct_size</span><span class="p">())</span>
+ <span class="n">timeo</span> <span class="o">=</span> <span class="n">timeout</span><span class="o">.</span><span class="n">struct_to_timeout</span><span class="p">(</span><span class="n">binstr</span><span class="p">)</span>
+ <span class="c1">#print(&quot;Debug: get_socket_write_timeout: &quot;</span>
+ <span class="c1"># &quot;get sockopt value: %s -&gt; returned timeout(sec=%r, microsec=%r)&quot; %</span>
+ <span class="c1"># (self._hexdump(binstr), timeo.sec, timeo.microsec))</span>
+ <span class="k">return</span> <span class="n">timeo</span></div>
+
+<div class="viewcode-block" id="Connection.set_socket_read_timeout"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.set_socket_read_timeout">[docs]</a> <span class="k">def</span> <span class="nf">set_socket_read_timeout</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">timeo</span><span class="p">):</span>
+ <span class="c1"># type: (timeout) -&gt; None</span>
+ <span class="k">assert</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">timeo</span><span class="p">,</span> <span class="n">timeout</span><span class="o">.</span><span class="n">timeout</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">socket</span><span class="o">.</span><span class="n">setsockopt</span><span class="p">(</span>
+ <span class="n">socket</span><span class="o">.</span><span class="n">SOL_SOCKET</span><span class="p">,</span> <span class="n">socket</span><span class="o">.</span><span class="n">SO_RCVTIMEO</span><span class="p">,</span> <span class="n">timeo</span><span class="o">.</span><span class="n">pack</span><span class="p">())</span></div>
+
+<div class="viewcode-block" id="Connection.set_socket_write_timeout"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.set_socket_write_timeout">[docs]</a> <span class="k">def</span> <span class="nf">set_socket_write_timeout</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">timeo</span><span class="p">):</span>
+ <span class="c1"># type: (timeout) -&gt; None</span>
+ <span class="k">assert</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">timeo</span><span class="p">,</span> <span class="n">timeout</span><span class="o">.</span><span class="n">timeout</span><span class="p">)</span>
+ <span class="n">binstr</span> <span class="o">=</span> <span class="n">timeo</span><span class="o">.</span><span class="n">pack</span><span class="p">()</span>
+ <span class="c1">#print(&quot;Debug: set_socket_write_timeout: &quot;</span>
+ <span class="c1"># &quot;input timeout(sec=%r, microsec=%r) -&gt; set sockopt value: %s&quot; %</span>
+ <span class="c1"># (timeo.sec, timeo.microsec, self._hexdump(binstr)))</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">socket</span><span class="o">.</span><span class="n">setsockopt</span><span class="p">(</span>
+ <span class="n">socket</span><span class="o">.</span><span class="n">SOL_SOCKET</span><span class="p">,</span> <span class="n">socket</span><span class="o">.</span><span class="n">SO_SNDTIMEO</span><span class="p">,</span> <span class="n">binstr</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Connection.get_version"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.get_version">[docs]</a> <span class="k">def</span> <span class="nf">get_version</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; str</span>
+ <span class="sd">&quot;&quot;&quot;Return the TLS/SSL protocol version for this connection.&quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">six</span><span class="o">.</span><span class="n">ensure_text</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">ssl_get_version</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="p">))</span></div>
+
+<div class="viewcode-block" id="Connection.set_post_connection_check_callback"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.set_post_connection_check_callback">[docs]</a> <span class="k">def</span> <span class="nf">set_post_connection_check_callback</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">postConnectionCheck</span><span class="p">):</span> <span class="c1"># noqa</span>
+ <span class="c1"># type: (Callable) -&gt; None</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">postConnectionCheck</span> <span class="o">=</span> <span class="n">postConnectionCheck</span></div>
+
+<div class="viewcode-block" id="Connection.set_tlsext_host_name"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.set_tlsext_host_name">[docs]</a> <span class="k">def</span> <span class="nf">set_tlsext_host_name</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
+ <span class="c1"># type: (bytes) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;Set the requested hostname for the SNI (Server Name Indication)</span>
+<span class="sd"> extension.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">ssl_set_tlsext_host_name</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Connection.set1_host"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.set1_host">[docs]</a> <span class="k">def</span> <span class="nf">set1_host</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
+ <span class="c1"># type: (bytes) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;Set the requested hostname to check in the server certificate.&quot;&quot;&quot;</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">host</span> <span class="o">=</span> <span class="n">name</span></div></div>
+</pre></div>
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="../../../index.html">M2Crypto</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="../../../M2Crypto.html">M2Crypto Package</a></li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="../../../index.html">Documentation overview</a><ul>
+ <li><a href="../../index.html">Module code</a><ul>
+ <li><a href="../SSL.html">M2Crypto.SSL</a><ul>
+ </ul></li>
+ </ul></li>
+ </ul></li>
+</ul>
+</div>
+<div id="searchbox" style="display: none" role="search">
+ <h3>Quick search</h3>
+ <div class="searchformwrapper">
+ <form class="search" action="../../../search.html" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ </div>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer">
+ &copy;2017, Matej Cepl <mcepl@cepl.eu>.
+
+ |
+ Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
+ &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
+
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/_modules/M2Crypto/SSL/Context.html b/doc/html/_modules/M2Crypto/SSL/Context.html
new file mode 100644
index 0000000..f61a146
--- /dev/null
+++ b/doc/html/_modules/M2Crypto/SSL/Context.html
@@ -0,0 +1,552 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>M2Crypto.SSL.Context &#8212; M2Crypto documentation</title>
+ <link rel="stylesheet" href="../../../_static/alabaster.css" type="text/css" />
+ <link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../../../_static/jquery.js"></script>
+ <script type="text/javascript" src="../../../_static/underscore.js"></script>
+ <script type="text/javascript" src="../../../_static/doctools.js"></script>
+ <script type="text/javascript" src="../../../_static/language_data.js"></script>
+ <link rel="index" title="Index" href="../../../genindex.html" />
+ <link rel="search" title="Search" href="../../../search.html" />
+
+ <link rel="stylesheet" href="../../../_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+ <h1>Source code for M2Crypto.SSL.Context</h1><div class="highlight"><pre>
+<span></span><span class="kn">from</span> <span class="nn">__future__</span> <span class="k">import</span> <span class="n">absolute_import</span>
+
+<span class="sd">&quot;&quot;&quot;SSL Context</span>
+
+<span class="sd">Copyright (c) 1999-2004 Ng Pheng Siong. All rights reserved.&quot;&quot;&quot;</span>
+
+<span class="kn">from</span> <span class="nn">M2Crypto</span> <span class="k">import</span> <span class="n">BIO</span><span class="p">,</span> <span class="n">Err</span><span class="p">,</span> <span class="n">RSA</span><span class="p">,</span> <span class="n">X509</span><span class="p">,</span> <span class="n">m2</span><span class="p">,</span> <span class="n">util</span> <span class="c1"># noqa</span>
+<span class="kn">from</span> <span class="nn">M2Crypto.SSL</span> <span class="k">import</span> <span class="n">cb</span> <span class="c1"># noqa</span>
+<span class="kn">from</span> <span class="nn">M2Crypto.SSL.Session</span> <span class="k">import</span> <span class="n">Session</span> <span class="c1"># noqa</span>
+<span class="kn">from</span> <span class="nn">weakref</span> <span class="k">import</span> <span class="n">WeakValueDictionary</span>
+<span class="k">if</span> <span class="n">util</span><span class="o">.</span><span class="n">py27plus</span><span class="p">:</span>
+ <span class="kn">from</span> <span class="nn">typing</span> <span class="k">import</span> <span class="n">Any</span><span class="p">,</span> <span class="n">AnyStr</span><span class="p">,</span> <span class="n">Callable</span><span class="p">,</span> <span class="n">Optional</span><span class="p">,</span> <span class="n">Union</span> <span class="c1"># noqa</span>
+
+<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;ctxmap&#39;</span><span class="p">,</span> <span class="s1">&#39;Context&#39;</span><span class="p">,</span> <span class="s1">&#39;map&#39;</span><span class="p">]</span>
+
+
+<span class="k">class</span> <span class="nc">_ctxmap</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+ <span class="n">singleton</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1"># type: Optional[_ctxmap]</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;Simple WeakReffed list.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_ctxmap</span> <span class="o">=</span> <span class="n">WeakValueDictionary</span><span class="p">()</span>
+
+ <span class="k">def</span> <span class="nf">__getitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">):</span>
+ <span class="c1"># type: (int) -&gt; Any</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_ctxmap</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
+
+ <span class="k">def</span> <span class="nf">__setitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
+ <span class="c1"># type: (int, Any) -&gt; None</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_ctxmap</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span>
+
+ <span class="k">def</span> <span class="nf">__delitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">):</span>
+ <span class="c1"># type: (int) -&gt; None</span>
+ <span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">_ctxmap</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
+
+
+<div class="viewcode-block" id="ctxmap"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Context.ctxmap">[docs]</a><span class="k">def</span> <span class="nf">ctxmap</span><span class="p">():</span>
+ <span class="c1"># type: () -&gt; _ctxmap</span>
+ <span class="k">if</span> <span class="n">_ctxmap</span><span class="o">.</span><span class="n">singleton</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">_ctxmap</span><span class="o">.</span><span class="n">singleton</span> <span class="o">=</span> <span class="n">_ctxmap</span><span class="p">()</span>
+ <span class="k">return</span> <span class="n">_ctxmap</span><span class="o">.</span><span class="n">singleton</span></div>
+<span class="c1"># deprecated!!!</span>
+<span class="nb">map</span> <span class="o">=</span> <span class="n">ctxmap</span>
+
+
+<div class="viewcode-block" id="Context"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Context.Context">[docs]</a><span class="k">class</span> <span class="nc">Context</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+
+ <span class="sd">&quot;&quot;&quot;&#39;Context&#39; for SSL connections.&quot;&quot;&quot;</span>
+
+ <span class="n">m2_ssl_ctx_free</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_ctx_free</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">protocol</span><span class="o">=</span><span class="s1">&#39;tls&#39;</span><span class="p">,</span> <span class="n">weak_crypto</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
+ <span class="n">post_connection_check</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="c1"># type: (str, Optional[int], Optional[Callable]) -&gt; None</span>
+ <span class="n">proto</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">m2</span><span class="p">,</span> <span class="n">protocol</span> <span class="o">+</span> <span class="s1">&#39;_method&#39;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">proto</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="c1"># default is &#39;sslv23&#39; for older versions of OpenSSL</span>
+ <span class="k">if</span> <span class="n">protocol</span> <span class="o">==</span> <span class="s1">&#39;tls&#39;</span><span class="p">:</span>
+ <span class="n">proto</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">m2</span><span class="p">,</span> <span class="s1">&#39;sslv23_method&#39;</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;no such protocol &#39;</span><span class="si">%s</span><span class="s2">&#39;&quot;</span> <span class="o">%</span> <span class="n">protocol</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">ctx</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_ctx_new</span><span class="p">(</span><span class="n">proto</span><span class="p">())</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">allow_unknown_ca</span> <span class="o">=</span> <span class="mi">0</span> <span class="c1"># type: Union[int, bool]</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">post_connection_check</span> <span class="o">=</span> <span class="n">post_connection_check</span>
+ <span class="n">ctxmap</span><span class="p">()[</span><span class="nb">int</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">)]</span> <span class="o">=</span> <span class="bp">self</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">ssl_ctx_set_cache_size</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">,</span> <span class="mi">128</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">weak_crypto</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">protocol</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">&#39;sslv23&#39;</span><span class="p">,</span> <span class="s1">&#39;tls&#39;</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">set_options</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">SSL_OP_ALL</span> <span class="o">|</span> <span class="n">m2</span><span class="o">.</span><span class="n">SSL_OP_NO_SSLv2</span> <span class="o">|</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">SSL_OP_NO_SSLv3</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">__del__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;ctx&#39;</span><span class="p">,</span> <span class="kc">None</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">m2_ssl_ctx_free</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">)</span>
+
+<div class="viewcode-block" id="Context.close"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.close">[docs]</a> <span class="k">def</span> <span class="nf">close</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="k">del</span> <span class="n">ctxmap</span><span class="p">()[</span><span class="nb">int</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">)]</span></div>
+
+<div class="viewcode-block" id="Context.load_cert"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.load_cert">[docs]</a> <span class="k">def</span> <span class="nf">load_cert</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">certfile</span><span class="p">,</span> <span class="n">keyfile</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
+ <span class="n">callback</span><span class="o">=</span><span class="n">util</span><span class="o">.</span><span class="n">passphrase_callback</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr, Optional[AnyStr], Callable) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;Load certificate and private key into the context.</span>
+
+<span class="sd"> :param certfile: File that contains the PEM-encoded certificate.</span>
+<span class="sd"> :param keyfile: File that contains the PEM-encoded private key.</span>
+<span class="sd"> Default value of None indicates that the private key</span>
+<span class="sd"> is to be found in &#39;certfile&#39;.</span>
+<span class="sd"> :param callback: Callable object to be invoked if the private key is</span>
+<span class="sd"> passphrase-protected. Default callback provides a</span>
+<span class="sd"> simple terminal-style input for the passphrase.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">ssl_ctx_passphrase_callback</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">,</span> <span class="n">callback</span><span class="p">)</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">ssl_ctx_use_cert</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">,</span> <span class="n">certfile</span><span class="p">)</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">keyfile</span><span class="p">:</span>
+ <span class="n">keyfile</span> <span class="o">=</span> <span class="n">certfile</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">ssl_ctx_use_privkey</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">,</span> <span class="n">keyfile</span><span class="p">)</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_ctx_check_privkey</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">):</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">&#39;public/private key mismatch&#39;</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Context.load_cert_chain"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.load_cert_chain">[docs]</a> <span class="k">def</span> <span class="nf">load_cert_chain</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">certchainfile</span><span class="p">,</span> <span class="n">keyfile</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
+ <span class="n">callback</span><span class="o">=</span><span class="n">util</span><span class="o">.</span><span class="n">passphrase_callback</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr, Optional[AnyStr], Callable) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;Load certificate chain and private key into the context.</span>
+
+<span class="sd"> :param certchainfile: File object containing the PEM-encoded</span>
+<span class="sd"> certificate chain.</span>
+<span class="sd"> :param keyfile: File object containing the PEM-encoded private</span>
+<span class="sd"> key. Default value of None indicates that the</span>
+<span class="sd"> private key is to be found in &#39;certchainfile&#39;.</span>
+<span class="sd"> :param callback: Callable object to be invoked if the private key</span>
+<span class="sd"> is passphrase-protected. Default callback</span>
+<span class="sd"> provides a simple terminal-style input for the</span>
+<span class="sd"> passphrase.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">ssl_ctx_passphrase_callback</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">,</span> <span class="n">callback</span><span class="p">)</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">ssl_ctx_use_cert_chain</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">,</span> <span class="n">certchainfile</span><span class="p">)</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">keyfile</span><span class="p">:</span>
+ <span class="n">keyfile</span> <span class="o">=</span> <span class="n">certchainfile</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">ssl_ctx_use_privkey</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">,</span> <span class="n">keyfile</span><span class="p">)</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_ctx_check_privkey</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">):</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">&#39;public/private key mismatch&#39;</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Context.set_client_CA_list_from_file"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.set_client_CA_list_from_file">[docs]</a> <span class="k">def</span> <span class="nf">set_client_CA_list_from_file</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">cafile</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;Load CA certs into the context. These CA certs are sent to the</span>
+<span class="sd"> peer during *SSLv3 certificate request*.</span>
+
+<span class="sd"> :param cafile: File object containing one or more PEM-encoded CA</span>
+<span class="sd"> certificates concatenated together.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">ssl_ctx_set_client_CA_list_from_file</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">,</span> <span class="n">cafile</span><span class="p">)</span></div>
+
+ <span class="c1"># Deprecated.</span>
+ <span class="n">load_client_CA</span> <span class="o">=</span> <span class="n">load_client_ca</span> <span class="o">=</span> <span class="n">set_client_CA_list_from_file</span>
+
+<div class="viewcode-block" id="Context.load_verify_locations"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.load_verify_locations">[docs]</a> <span class="k">def</span> <span class="nf">load_verify_locations</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">cafile</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">capath</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="c1"># type: (Optional[AnyStr], Optional[AnyStr]) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;Load CA certs into the context.</span>
+
+<span class="sd"> These CA certs are used during verification of the peer&#39;s</span>
+<span class="sd"> certificate.</span>
+
+<span class="sd"> :param cafile: File containing one or more PEM-encoded CA</span>
+<span class="sd"> certificates concatenated together.</span>
+
+<span class="sd"> :param capath: Directory containing PEM-encoded CA certificates</span>
+<span class="sd"> (one certificate per file).</span>
+
+<span class="sd"> :return: 0 if the operation failed because CAfile and CApath are NULL</span>
+<span class="sd"> or the processing at one of the locations specified failed.</span>
+<span class="sd"> Check the error stack to find out the reason.</span>
+
+<span class="sd"> 1 The operation succeeded.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">if</span> <span class="n">cafile</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">capath</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;cafile and capath can not both be None.&quot;</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_ctx_load_verify_locations</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">,</span> <span class="n">cafile</span><span class="p">,</span> <span class="n">capath</span><span class="p">)</span></div>
+
+ <span class="c1"># Deprecated.</span>
+ <span class="n">load_verify_info</span> <span class="o">=</span> <span class="n">load_verify_locations</span>
+
+<div class="viewcode-block" id="Context.set_session_id_ctx"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.set_session_id_ctx">[docs]</a> <span class="k">def</span> <span class="nf">set_session_id_ctx</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">id</span><span class="p">):</span>
+ <span class="c1"># type: (bytes) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;Sets the session id for the SSL.Context w/in a session can be reused.</span>
+
+<span class="sd"> :param id: Sessions are generated within a certain context. When</span>
+<span class="sd"> exporting/importing sessions with</span>
+<span class="sd"> i2d_SSL_SESSION/d2i_SSL_SESSION it would be possible,</span>
+<span class="sd"> to re-import a session generated from another context</span>
+<span class="sd"> (e.g. another application), which might lead to</span>
+<span class="sd"> malfunctions. Therefore each application must set its</span>
+<span class="sd"> own session id context sid_ctx which is used to</span>
+<span class="sd"> distinguish the contexts and is stored in exported</span>
+<span class="sd"> sessions. The sid_ctx can be any kind of binary data</span>
+<span class="sd"> with a given length, it is therefore possible to use</span>
+<span class="sd"> e.g. the name of the application and/or the hostname</span>
+<span class="sd"> and/or service name.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">ret</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_ctx_set_session_id_context</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">,</span> <span class="nb">id</span><span class="p">)</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">ret</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="n">Err</span><span class="o">.</span><span class="n">SSLError</span><span class="p">(</span><span class="n">Err</span><span class="o">.</span><span class="n">get_error_code</span><span class="p">(),</span> <span class="s1">&#39;&#39;</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Context.set_default_verify_paths"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.set_default_verify_paths">[docs]</a> <span class="k">def</span> <span class="nf">set_default_verify_paths</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Specifies that the default locations from which CA certs are</span>
+<span class="sd"> loaded should be used.</span>
+
+<span class="sd"> There is one default directory and one default file. The default</span>
+<span class="sd"> CA certificates directory is called &quot;certs&quot; in the default</span>
+<span class="sd"> OpenSSL directory. Alternatively the SSL_CERT_DIR environment</span>
+<span class="sd"> variable can be defined to override this location. The default</span>
+<span class="sd"> CA certificates file is called &quot;cert.pem&quot; in the default OpenSSL</span>
+<span class="sd"> directory. Alternatively the SSL_CERT_FILE environment variable</span>
+<span class="sd"> can be defined to override this location.</span>
+
+<span class="sd"> @return 0 if the operation failed. A missing default location is</span>
+<span class="sd"> still treated as a success. No error code is set.</span>
+
+<span class="sd"> 1 The operation succeeded.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">ret</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_ctx_set_default_verify_paths</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">)</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">ret</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">&#39;Cannot use default SSL certificate store!&#39;</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Context.set_allow_unknown_ca"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.set_allow_unknown_ca">[docs]</a> <span class="k">def</span> <span class="nf">set_allow_unknown_ca</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">ok</span><span class="p">):</span>
+ <span class="c1"># type: (Union[int, bool]) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;Set the context to accept/reject a peer certificate if the</span>
+<span class="sd"> certificate&#39;s CA is unknown.</span>
+
+<span class="sd"> :param ok: True to accept, False to reject.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">allow_unknown_ca</span> <span class="o">=</span> <span class="n">ok</span></div>
+
+<div class="viewcode-block" id="Context.get_allow_unknown_ca"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.get_allow_unknown_ca">[docs]</a> <span class="k">def</span> <span class="nf">get_allow_unknown_ca</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; Union[int, bool]</span>
+ <span class="sd">&quot;&quot;&quot;Get the context&#39;s setting that accepts/rejects a peer</span>
+<span class="sd"> certificate if the certificate&#39;s CA is unknown.</span>
+
+<span class="sd"> FIXME 2Bconverted to bool</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">allow_unknown_ca</span></div>
+
+<div class="viewcode-block" id="Context.set_verify"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.set_verify">[docs]</a> <span class="k">def</span> <span class="nf">set_verify</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">mode</span><span class="p">,</span> <span class="n">depth</span><span class="p">,</span> <span class="n">callback</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="c1"># type: (int, int, Optional[Callable]) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Set verify options. Most applications will need to call this</span>
+<span class="sd"> method with the right options to make a secure SSL connection.</span>
+
+<span class="sd"> :param mode: The verification mode to use. Typically at least</span>
+<span class="sd"> SSL.verify_peer is used. Clients would also typically</span>
+<span class="sd"> add SSL.verify_fail_if_no_peer_cert.</span>
+<span class="sd"> :param depth: The maximum allowed depth of the certificate chain</span>
+<span class="sd"> returned by the peer.</span>
+<span class="sd"> :param callback: Callable that can be used to specify custom</span>
+<span class="sd"> verification checks.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">if</span> <span class="n">callback</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">ssl_ctx_set_verify_default</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">,</span> <span class="n">mode</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">ssl_ctx_set_verify</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">,</span> <span class="n">mode</span><span class="p">,</span> <span class="n">callback</span><span class="p">)</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">ssl_ctx_set_verify_depth</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">,</span> <span class="n">depth</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Context.get_verify_mode"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.get_verify_mode">[docs]</a> <span class="k">def</span> <span class="nf">get_verify_mode</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_ctx_get_verify_mode</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Context.get_verify_depth"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.get_verify_depth">[docs]</a> <span class="k">def</span> <span class="nf">get_verify_depth</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;Returns the verification mode currently set in the SSL Context.&quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_ctx_get_verify_depth</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Context.set_tmp_dh"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.set_tmp_dh">[docs]</a> <span class="k">def</span> <span class="nf">set_tmp_dh</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">dhpfile</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;Load ephemeral DH parameters into the context.</span>
+
+<span class="sd"> :param dhpfile: Filename of the file containing the PEM-encoded</span>
+<span class="sd"> DH parameters.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">f</span> <span class="o">=</span> <span class="n">BIO</span><span class="o">.</span><span class="n">openfile</span><span class="p">(</span><span class="n">dhpfile</span><span class="p">)</span>
+ <span class="n">dhp</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">dh_read_parameters</span><span class="p">(</span><span class="n">f</span><span class="o">.</span><span class="n">bio_ptr</span><span class="p">())</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_ctx_set_tmp_dh</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">,</span> <span class="n">dhp</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Context.set_tmp_dh_callback"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.set_tmp_dh_callback">[docs]</a> <span class="k">def</span> <span class="nf">set_tmp_dh_callback</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">callback</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="c1"># type: (Optional[Callable]) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;Sets the callback function for SSL.Context.</span>
+
+<span class="sd"> :param callback: Callable to be used when a DH parameters are required.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">if</span> <span class="n">callback</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">ssl_ctx_set_tmp_dh_callback</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">,</span> <span class="n">callback</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Context.set_tmp_rsa"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.set_tmp_rsa">[docs]</a> <span class="k">def</span> <span class="nf">set_tmp_rsa</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">rsa</span><span class="p">):</span>
+ <span class="c1"># type: (RSA.RSA) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;Load ephemeral RSA key into the context.</span>
+
+<span class="sd"> :param rsa: RSA.RSA instance.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">rsa</span><span class="p">,</span> <span class="n">RSA</span><span class="o">.</span><span class="n">RSA</span><span class="p">):</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_ctx_set_tmp_rsa</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">,</span> <span class="n">rsa</span><span class="o">.</span><span class="n">rsa</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s2">&quot;Expected an instance of RSA.RSA, got </span><span class="si">%s</span><span class="s2">.&quot;</span> <span class="o">%</span> <span class="n">rsa</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Context.set_tmp_rsa_callback"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.set_tmp_rsa_callback">[docs]</a> <span class="k">def</span> <span class="nf">set_tmp_rsa_callback</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">callback</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="c1"># type: (Optional[Callable]) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;Sets the callback function to be used when</span>
+<span class="sd"> a temporary/ephemeral RSA key is required.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">if</span> <span class="n">callback</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">ssl_ctx_set_tmp_rsa_callback</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">,</span> <span class="n">callback</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Context.set_info_callback"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.set_info_callback">[docs]</a> <span class="k">def</span> <span class="nf">set_info_callback</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">callback</span><span class="o">=</span><span class="n">cb</span><span class="o">.</span><span class="n">ssl_info_callback</span><span class="p">):</span>
+ <span class="c1"># type: (Callable) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;Set a callback function to get state information.</span>
+
+<span class="sd"> It can be used to get state information about the SSL</span>
+<span class="sd"> connections that are created from this context.</span>
+
+<span class="sd"> :param callback: Callback function. The default prints</span>
+<span class="sd"> information to stderr.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">ssl_ctx_set_info_callback</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">,</span> <span class="n">callback</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Context.set_cipher_list"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.set_cipher_list">[docs]</a> <span class="k">def</span> <span class="nf">set_cipher_list</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">cipher_list</span><span class="p">):</span>
+ <span class="c1"># type: (str) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;Sets the list of available ciphers.</span>
+
+<span class="sd"> :param cipher_list: The format of the string is described in</span>
+<span class="sd"> ciphers(1).</span>
+<span class="sd"> :return: 1 if any cipher could be selected and 0 on complete</span>
+<span class="sd"> failure.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_ctx_set_cipher_list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">,</span> <span class="n">cipher_list</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Context.add_session"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.add_session">[docs]</a> <span class="k">def</span> <span class="nf">add_session</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">session</span><span class="p">):</span>
+ <span class="c1"># type: (Session) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;Add the session to the context.</span>
+
+<span class="sd"> :param session: the session to be added.</span>
+
+<span class="sd"> :return: 0 The operation failed. It was tried to add the same</span>
+<span class="sd"> (identical) session twice.</span>
+
+<span class="sd"> 1 The operation succeeded.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_ctx_add_session</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">,</span> <span class="n">session</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span></div>
+
+<div class="viewcode-block" id="Context.remove_session"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.remove_session">[docs]</a> <span class="k">def</span> <span class="nf">remove_session</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">session</span><span class="p">):</span>
+ <span class="c1"># type: (Session) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;Remove the session from the context.</span>
+
+<span class="sd"> :param session: the session to be removed.</span>
+
+<span class="sd"> :return: 0 The operation failed. The session was not found in</span>
+<span class="sd"> the cache.</span>
+
+<span class="sd"> 1 The operation succeeded.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_ctx_remove_session</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">,</span> <span class="n">session</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span></div>
+
+<div class="viewcode-block" id="Context.get_session_timeout"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.get_session_timeout">[docs]</a> <span class="k">def</span> <span class="nf">get_session_timeout</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;Get current session timeout.</span>
+
+<span class="sd"> Whenever a new session is created, it is assigned a maximum</span>
+<span class="sd"> lifetime. This lifetime is specified by storing the creation</span>
+<span class="sd"> time of the session and the timeout value valid at this time. If</span>
+<span class="sd"> the actual time is later than creation time plus timeout, the</span>
+<span class="sd"> session is not reused.</span>
+
+<span class="sd"> Due to this realization, all sessions behave according to the</span>
+<span class="sd"> timeout value valid at the time of the session negotiation.</span>
+<span class="sd"> Changes of the timeout value do not affect already established</span>
+<span class="sd"> sessions.</span>
+
+<span class="sd"> Expired sessions are removed from the internal session cache,</span>
+<span class="sd"> whenever SSL_CTX_flush_sessions(3) is called, either directly by</span>
+<span class="sd"> the application or automatically (see</span>
+<span class="sd"> SSL_CTX_set_session_cache_mode(3))</span>
+
+<span class="sd"> The default value for session timeout is decided on a per</span>
+<span class="sd"> protocol basis, see SSL_get_default_timeout(3). All currently</span>
+<span class="sd"> supported protocols have the same default timeout value of 300</span>
+<span class="sd"> seconds.</span>
+
+<span class="sd"> SSL_CTX_set_timeout() returns the previously set timeout value.</span>
+
+<span class="sd"> :return: the currently set timeout value.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_ctx_get_session_timeout</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Context.set_session_timeout"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.set_session_timeout">[docs]</a> <span class="k">def</span> <span class="nf">set_session_timeout</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">timeout</span><span class="p">):</span>
+ <span class="c1"># type: (int) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;Set new session timeout.</span>
+
+<span class="sd"> See self.get_session_timeout() for explanation of the session</span>
+<span class="sd"> timeouts.</span>
+
+<span class="sd"> :param timeout: new timeout value.</span>
+
+<span class="sd"> :return: the previously set timeout value.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_ctx_set_session_timeout</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">,</span> <span class="n">timeout</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Context.set_session_cache_mode"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.set_session_cache_mode">[docs]</a> <span class="k">def</span> <span class="nf">set_session_cache_mode</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">mode</span><span class="p">):</span>
+ <span class="c1"># type: (int) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;Enables/disables session caching.</span>
+
+<span class="sd"> The mode is set by using m2.SSL_SESS_CACHE_* constants.</span>
+
+<span class="sd"> :param mode: new mode value.</span>
+
+<span class="sd"> :return: the previously set cache mode value.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_ctx_set_session_cache_mode</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">,</span> <span class="n">mode</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Context.get_session_cache_mode"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.get_session_cache_mode">[docs]</a> <span class="k">def</span> <span class="nf">get_session_cache_mode</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;Gets the current session caching.</span>
+
+<span class="sd"> The mode is set to m2.SSL_SESS_CACHE_* constants.</span>
+
+<span class="sd"> :return: the previously set cache mode value.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_ctx_get_session_cache_mode</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Context.set_options"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.set_options">[docs]</a> <span class="k">def</span> <span class="nf">set_options</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">op</span><span class="p">):</span>
+ <span class="c1"># type: (int) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;Adds the options set via bitmask in options to the Context.</span>
+
+<span class="sd"> !!! Options already set before are not cleared!</span>
+
+<span class="sd"> The behaviour of the SSL library can be changed by setting</span>
+<span class="sd"> several options. The options are coded as bitmasks and can be</span>
+<span class="sd"> combined by a logical or operation (|).</span>
+
+<span class="sd"> SSL.Context.set_options() and SSL.set_options() affect the</span>
+<span class="sd"> (external) protocol behaviour of the SSL library. The (internal)</span>
+<span class="sd"> behaviour of the API can be changed by using the similar</span>
+<span class="sd"> SSL.Context.set_mode() and SSL.set_mode() functions.</span>
+
+<span class="sd"> During a handshake, the option settings of the SSL object are</span>
+<span class="sd"> used. When a new SSL object is created from a context using</span>
+<span class="sd"> SSL(), the current option setting is copied. Changes to ctx</span>
+<span class="sd"> do not affect already created SSL objects. SSL.clear() does not</span>
+<span class="sd"> affect the settings.</span>
+
+<span class="sd"> :param op: bitmask of additional options specified in</span>
+<span class="sd"> SSL_CTX_set_options(3) manpage.</span>
+
+<span class="sd"> :return: the new options bitmask after adding options.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_ctx_set_options</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">,</span> <span class="n">op</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Context.get_cert_store"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.get_cert_store">[docs]</a> <span class="k">def</span> <span class="nf">get_cert_store</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; X509.X509</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Get the certificate store associated with this context.</span>
+
+<span class="sd"> :warning: The store is NOT refcounted, and as such can not be relied</span>
+<span class="sd"> to be valid once the context goes away or is changed.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">X509</span><span class="o">.</span><span class="n">X509_Store</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">ssl_ctx_get_cert_store</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">))</span></div></div>
+</pre></div>
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="../../../index.html">M2Crypto</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="../../../M2Crypto.html">M2Crypto Package</a></li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="../../../index.html">Documentation overview</a><ul>
+ <li><a href="../../index.html">Module code</a><ul>
+ <li><a href="../SSL.html">M2Crypto.SSL</a><ul>
+ </ul></li>
+ </ul></li>
+ </ul></li>
+</ul>
+</div>
+<div id="searchbox" style="display: none" role="search">
+ <h3>Quick search</h3>
+ <div class="searchformwrapper">
+ <form class="search" action="../../../search.html" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ </div>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer">
+ &copy;2017, Matej Cepl <mcepl@cepl.eu>.
+
+ |
+ Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
+ &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
+
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/_modules/M2Crypto/SSL/SSLServer.html b/doc/html/_modules/M2Crypto/SSL/SSLServer.html
new file mode 100644
index 0000000..3abb777
--- /dev/null
+++ b/doc/html/_modules/M2Crypto/SSL/SSLServer.html
@@ -0,0 +1,172 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>M2Crypto.SSL.SSLServer &#8212; M2Crypto documentation</title>
+ <link rel="stylesheet" href="../../../_static/alabaster.css" type="text/css" />
+ <link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../../../_static/jquery.js"></script>
+ <script type="text/javascript" src="../../../_static/underscore.js"></script>
+ <script type="text/javascript" src="../../../_static/doctools.js"></script>
+ <script type="text/javascript" src="../../../_static/language_data.js"></script>
+ <link rel="index" title="Index" href="../../../genindex.html" />
+ <link rel="search" title="Search" href="../../../search.html" />
+
+ <link rel="stylesheet" href="../../../_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+ <h1>Source code for M2Crypto.SSL.SSLServer</h1><div class="highlight"><pre>
+<span></span><span class="kn">from</span> <span class="nn">__future__</span> <span class="k">import</span> <span class="n">absolute_import</span><span class="p">,</span> <span class="n">print_function</span>
+
+<span class="sd">&quot;&quot;&quot;SSLServer</span>
+
+<span class="sd">Copyright (c) 1999-2002 Ng Pheng Siong. All rights reserved.&quot;&quot;&quot;</span>
+
+
+<span class="c1"># M2Crypto</span>
+<span class="kn">from</span> <span class="nn">M2Crypto.SSL</span> <span class="k">import</span> <span class="n">SSLError</span>
+<span class="kn">from</span> <span class="nn">M2Crypto.SSL.Connection</span> <span class="k">import</span> <span class="n">Connection</span>
+<span class="kn">from</span> <span class="nn">M2Crypto.SSL.Context</span> <span class="k">import</span> <span class="n">Context</span> <span class="c1"># noqa</span>
+<span class="kn">from</span> <span class="nn">M2Crypto</span> <span class="k">import</span> <span class="n">six</span> <span class="c1"># noqa</span>
+<span class="kn">from</span> <span class="nn">M2Crypto</span> <span class="k">import</span> <span class="n">util</span> <span class="c1"># noqa</span>
+<span class="kn">from</span> <span class="nn">M2Crypto.six.moves.socketserver</span> <span class="k">import</span> <span class="p">(</span><span class="n">BaseServer</span><span class="p">,</span> <span class="n">TCPServer</span><span class="p">,</span>
+ <span class="n">ThreadingMixIn</span><span class="p">)</span>
+<span class="kn">import</span> <span class="nn">os</span>
+<span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">name</span> <span class="o">!=</span> <span class="s1">&#39;nt&#39;</span><span class="p">:</span>
+ <span class="kn">from</span> <span class="nn">M2Crypto.six.moves.socketserver</span> <span class="k">import</span> <span class="n">ForkingMixIn</span>
+<span class="kn">from</span> <span class="nn">socket</span> <span class="k">import</span> <span class="n">socket</span> <span class="c1"># noqa</span>
+<span class="k">if</span> <span class="n">util</span><span class="o">.</span><span class="n">py27plus</span><span class="p">:</span>
+ <span class="kn">from</span> <span class="nn">typing</span> <span class="k">import</span> <span class="n">Union</span> <span class="c1"># noqa</span>
+
+<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;SSLServer&#39;</span><span class="p">,</span> <span class="s1">&#39;ForkingSSLServer&#39;</span><span class="p">,</span> <span class="s1">&#39;ThreadingSSLServer&#39;</span><span class="p">]</span>
+
+
+<div class="viewcode-block" id="SSLServer"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.SSLServer.SSLServer">[docs]</a><span class="k">class</span> <span class="nc">SSLServer</span><span class="p">(</span><span class="n">TCPServer</span><span class="p">):</span>
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">server_address</span><span class="p">,</span> <span class="n">RequestHandlerClass</span><span class="p">,</span> <span class="n">ssl_context</span><span class="p">,</span> <span class="c1"># noqa</span>
+ <span class="n">bind_and_activate</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
+ <span class="c1"># type: (util.AddrType, socketserver.BaseRequestHandler, Context, bool) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Superclass says: Constructor. May be extended, do not override.</span>
+<span class="sd"> This class says: Ho-hum.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">BaseServer</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">server_address</span><span class="p">,</span> <span class="n">RequestHandlerClass</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">ssl_ctx</span> <span class="o">=</span> <span class="n">ssl_context</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">socket</span> <span class="o">=</span> <span class="n">Connection</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl_ctx</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">bind_and_activate</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">server_bind</span><span class="p">()</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">server_activate</span><span class="p">()</span>
+
+<div class="viewcode-block" id="SSLServer.handle_request"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.SSLServer.SSLServer.handle_request">[docs]</a> <span class="k">def</span> <span class="nf">handle_request</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="n">request</span> <span class="o">=</span> <span class="kc">None</span>
+ <span class="n">client_address</span> <span class="o">=</span> <span class="kc">None</span>
+ <span class="k">try</span><span class="p">:</span>
+ <span class="n">request</span><span class="p">,</span> <span class="n">client_address</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_request</span><span class="p">()</span>
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verify_request</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="n">client_address</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">process_request</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="n">client_address</span><span class="p">)</span>
+ <span class="k">except</span> <span class="n">SSLError</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">handle_error</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="n">client_address</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="SSLServer.handle_error"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.SSLServer.SSLServer.handle_error">[docs]</a> <span class="k">def</span> <span class="nf">handle_error</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">,</span> <span class="n">client_address</span><span class="p">):</span>
+ <span class="c1"># type: (Union[socket, Connection], util.AddrType) -&gt; None</span>
+ <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;-&#39;</span> <span class="o">*</span> <span class="mi">40</span><span class="p">)</span>
+ <span class="kn">import</span> <span class="nn">traceback</span>
+ <span class="n">traceback</span><span class="o">.</span><span class="n">print_exc</span><span class="p">()</span>
+ <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;-&#39;</span> <span class="o">*</span> <span class="mi">40</span><span class="p">)</span></div></div>
+
+
+<div class="viewcode-block" id="ThreadingSSLServer"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.SSLServer.ThreadingSSLServer">[docs]</a><span class="k">class</span> <span class="nc">ThreadingSSLServer</span><span class="p">(</span><span class="n">ThreadingMixIn</span><span class="p">,</span> <span class="n">SSLServer</span><span class="p">):</span>
+ <span class="k">pass</span></div>
+
+
+<span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">name</span> <span class="o">!=</span> <span class="s1">&#39;nt&#39;</span><span class="p">:</span>
+<div class="viewcode-block" id="ForkingSSLServer"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.SSLServer.ForkingSSLServer">[docs]</a> <span class="k">class</span> <span class="nc">ForkingSSLServer</span><span class="p">(</span><span class="n">ForkingMixIn</span><span class="p">,</span> <span class="n">SSLServer</span><span class="p">):</span>
+ <span class="k">pass</span></div>
+</pre></div>
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="../../../index.html">M2Crypto</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="../../../M2Crypto.html">M2Crypto Package</a></li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="../../../index.html">Documentation overview</a><ul>
+ <li><a href="../../index.html">Module code</a><ul>
+ <li><a href="../SSL.html">M2Crypto.SSL</a><ul>
+ </ul></li>
+ </ul></li>
+ </ul></li>
+</ul>
+</div>
+<div id="searchbox" style="display: none" role="search">
+ <h3>Quick search</h3>
+ <div class="searchformwrapper">
+ <form class="search" action="../../../search.html" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ </div>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer">
+ &copy;2017, Matej Cepl <mcepl@cepl.eu>.
+
+ |
+ Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
+ &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
+
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/_modules/M2Crypto/SSL/Session.html b/doc/html/_modules/M2Crypto/SSL/Session.html
new file mode 100644
index 0000000..d22a29c
--- /dev/null
+++ b/doc/html/_modules/M2Crypto/SSL/Session.html
@@ -0,0 +1,176 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>M2Crypto.SSL.Session &#8212; M2Crypto documentation</title>
+ <link rel="stylesheet" href="../../../_static/alabaster.css" type="text/css" />
+ <link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../../../_static/jquery.js"></script>
+ <script type="text/javascript" src="../../../_static/underscore.js"></script>
+ <script type="text/javascript" src="../../../_static/doctools.js"></script>
+ <script type="text/javascript" src="../../../_static/language_data.js"></script>
+ <link rel="index" title="Index" href="../../../genindex.html" />
+ <link rel="search" title="Search" href="../../../search.html" />
+
+ <link rel="stylesheet" href="../../../_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+ <h1>Source code for M2Crypto.SSL.Session</h1><div class="highlight"><pre>
+<span></span><span class="sd">&quot;&quot;&quot;SSL Session</span>
+
+<span class="sd">Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved.&quot;&quot;&quot;</span>
+
+<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;Session&#39;</span><span class="p">,</span> <span class="s1">&#39;load_session&#39;</span><span class="p">]</span>
+
+<span class="kn">from</span> <span class="nn">M2Crypto</span> <span class="k">import</span> <span class="n">BIO</span><span class="p">,</span> <span class="n">Err</span><span class="p">,</span> <span class="n">m2</span><span class="p">,</span> <span class="n">util</span>
+<span class="kn">from</span> <span class="nn">M2Crypto.SSL</span> <span class="k">import</span> <span class="n">SSLError</span>
+<span class="k">if</span> <span class="n">util</span><span class="o">.</span><span class="n">py27plus</span><span class="p">:</span>
+ <span class="kn">from</span> <span class="nn">typing</span> <span class="k">import</span> <span class="n">AnyStr</span> <span class="c1"># noqa</span>
+
+
+<div class="viewcode-block" id="Session"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Session.Session">[docs]</a><span class="k">class</span> <span class="nc">Session</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+
+ <span class="n">m2_ssl_session_free</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_session_free</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">session</span><span class="p">,</span> <span class="n">_pyfree</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
+ <span class="c1"># type: (bytes, int) -&gt; None</span>
+ <span class="k">assert</span> <span class="n">session</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">session</span> <span class="o">=</span> <span class="n">session</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_pyfree</span> <span class="o">=</span> <span class="n">_pyfree</span>
+
+ <span class="k">def</span> <span class="nf">__del__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;_pyfree&#39;</span><span class="p">,</span> <span class="mi">0</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">m2_ssl_session_free</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">session</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">_ptr</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; bytes</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">session</span>
+
+<div class="viewcode-block" id="Session.as_text"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Session.Session.as_text">[docs]</a> <span class="k">def</span> <span class="nf">as_text</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; bytes</span>
+ <span class="n">buf</span> <span class="o">=</span> <span class="n">BIO</span><span class="o">.</span><span class="n">MemoryBuffer</span><span class="p">()</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">ssl_session_print</span><span class="p">(</span><span class="n">buf</span><span class="o">.</span><span class="n">bio_ptr</span><span class="p">(),</span> <span class="bp">self</span><span class="o">.</span><span class="n">session</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">buf</span><span class="o">.</span><span class="n">read_all</span><span class="p">()</span></div>
+
+<div class="viewcode-block" id="Session.as_der"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Session.Session.as_der">[docs]</a> <span class="k">def</span> <span class="nf">as_der</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; bytes</span>
+ <span class="n">buf</span> <span class="o">=</span> <span class="n">BIO</span><span class="o">.</span><span class="n">MemoryBuffer</span><span class="p">()</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">i2d_ssl_session</span><span class="p">(</span><span class="n">buf</span><span class="o">.</span><span class="n">bio_ptr</span><span class="p">(),</span> <span class="bp">self</span><span class="o">.</span><span class="n">session</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">buf</span><span class="o">.</span><span class="n">read_all</span><span class="p">()</span></div>
+
+<div class="viewcode-block" id="Session.write_bio"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Session.Session.write_bio">[docs]</a> <span class="k">def</span> <span class="nf">write_bio</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bio</span><span class="p">):</span>
+ <span class="c1"># type: (BIO.BIO) -&gt; int</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_session_write_bio</span><span class="p">(</span><span class="n">bio</span><span class="o">.</span><span class="n">bio_ptr</span><span class="p">(),</span> <span class="bp">self</span><span class="o">.</span><span class="n">session</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Session.get_time"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Session.Session.get_time">[docs]</a> <span class="k">def</span> <span class="nf">get_time</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_session_get_time</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">session</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Session.set_time"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Session.Session.set_time">[docs]</a> <span class="k">def</span> <span class="nf">set_time</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">t</span><span class="p">):</span>
+ <span class="c1"># type: (int) -&gt; int</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_session_set_time</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">session</span><span class="p">,</span> <span class="n">t</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Session.get_timeout"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Session.Session.get_timeout">[docs]</a> <span class="k">def</span> <span class="nf">get_timeout</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_session_get_timeout</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">session</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Session.set_timeout"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Session.Session.set_timeout">[docs]</a> <span class="k">def</span> <span class="nf">set_timeout</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">t</span><span class="p">):</span>
+ <span class="c1"># type: (int) -&gt; int</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_session_set_timeout</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">session</span><span class="p">,</span> <span class="n">t</span><span class="p">)</span></div></div>
+
+
+<div class="viewcode-block" id="load_session"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.Session.load_session">[docs]</a><span class="k">def</span> <span class="nf">load_session</span><span class="p">(</span><span class="n">pemfile</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr) -&gt; Session</span>
+ <span class="k">with</span> <span class="n">BIO</span><span class="o">.</span><span class="n">openfile</span><span class="p">(</span><span class="n">pemfile</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
+ <span class="n">cptr</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_session_read_pem</span><span class="p">(</span><span class="n">f</span><span class="o">.</span><span class="n">bio_ptr</span><span class="p">())</span>
+
+ <span class="k">return</span> <span class="n">Session</span><span class="p">(</span><span class="n">cptr</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span></div>
+</pre></div>
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="../../../index.html">M2Crypto</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="../../../M2Crypto.html">M2Crypto Package</a></li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="../../../index.html">Documentation overview</a><ul>
+ <li><a href="../../index.html">Module code</a><ul>
+ <li><a href="../SSL.html">M2Crypto.SSL</a><ul>
+ </ul></li>
+ </ul></li>
+ </ul></li>
+</ul>
+</div>
+<div id="searchbox" style="display: none" role="search">
+ <h3>Quick search</h3>
+ <div class="searchformwrapper">
+ <form class="search" action="../../../search.html" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ </div>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer">
+ &copy;2017, Matej Cepl <mcepl@cepl.eu>.
+
+ |
+ Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
+ &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
+
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/_modules/M2Crypto/SSL/TwistedProtocolWrapper.html b/doc/html/_modules/M2Crypto/SSL/TwistedProtocolWrapper.html
new file mode 100644
index 0000000..88c32e0
--- /dev/null
+++ b/doc/html/_modules/M2Crypto/SSL/TwistedProtocolWrapper.html
@@ -0,0 +1,597 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>M2Crypto.SSL.TwistedProtocolWrapper &#8212; M2Crypto documentation</title>
+ <link rel="stylesheet" href="../../../_static/alabaster.css" type="text/css" />
+ <link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../../../_static/jquery.js"></script>
+ <script type="text/javascript" src="../../../_static/underscore.js"></script>
+ <script type="text/javascript" src="../../../_static/doctools.js"></script>
+ <script type="text/javascript" src="../../../_static/language_data.js"></script>
+ <link rel="index" title="Index" href="../../../genindex.html" />
+ <link rel="search" title="Search" href="../../../search.html" />
+
+ <link rel="stylesheet" href="../../../_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+ <h1>Source code for M2Crypto.SSL.TwistedProtocolWrapper</h1><div class="highlight"><pre>
+<span></span><span class="sd">&quot;&quot;&quot;</span>
+<span class="sd">Make Twisted use M2Crypto for SSL</span>
+
+<span class="sd">Copyright (c) 2004-2007 Open Source Applications Foundation.</span>
+<span class="sd">All rights reserved.</span>
+
+<span class="sd">FIXME THIS HAS NOT BEEN FINISHED. NEITHER PEP484 NOR PORT PYTHON3 HAS</span>
+<span class="sd">BEEN FINISHED. THE FURTHER WORK WILL BE DONE WHEN THE STATUS OF TWISTED</span>
+<span class="sd">IN THE PYTHON 3 (AND ASYNCIO) WORLD WILL BE CLEAR.</span>
+<span class="sd">&quot;&quot;&quot;</span>
+
+<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;connectSSL&#39;</span><span class="p">,</span> <span class="s1">&#39;connectTCP&#39;</span><span class="p">,</span> <span class="s1">&#39;listenSSL&#39;</span><span class="p">,</span> <span class="s1">&#39;listenTCP&#39;</span><span class="p">,</span>
+ <span class="s1">&#39;TLSProtocolWrapper&#39;</span><span class="p">]</span>
+
+<span class="kn">import</span> <span class="nn">logging</span>
+
+<span class="kn">from</span> <span class="nn">functools</span> <span class="k">import</span> <span class="n">partial</span>
+
+<span class="kn">import</span> <span class="nn">twisted.internet.reactor</span>
+<span class="kn">import</span> <span class="nn">twisted.protocols.policies</span> <span class="k">as</span> <span class="nn">policies</span>
+
+<span class="kn">from</span> <span class="nn">M2Crypto</span> <span class="k">import</span> <span class="n">BIO</span><span class="p">,</span> <span class="n">X509</span><span class="p">,</span> <span class="n">m2</span><span class="p">,</span> <span class="n">util</span>
+<span class="kn">from</span> <span class="nn">M2Crypto.SSL.Checker</span> <span class="k">import</span> <span class="n">Checker</span><span class="p">,</span> <span class="n">SSLVerificationError</span>
+
+<span class="kn">from</span> <span class="nn">twisted.internet.interfaces</span> <span class="k">import</span> <span class="n">ITLSTransport</span>
+<span class="kn">from</span> <span class="nn">twisted.protocols.policies</span> <span class="k">import</span> <span class="n">ProtocolWrapper</span>
+<span class="k">if</span> <span class="n">util</span><span class="o">.</span><span class="n">py27plus</span><span class="p">:</span>
+ <span class="kn">from</span> <span class="nn">typing</span> <span class="k">import</span> <span class="n">AnyStr</span><span class="p">,</span> <span class="n">Callable</span><span class="p">,</span> <span class="n">Iterable</span><span class="p">,</span> <span class="n">Optional</span> <span class="c1"># noqa</span>
+ <span class="kn">from</span> <span class="nn">zope.interface</span> <span class="k">import</span> <span class="n">implementer</span>
+
+<span class="n">log</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="vm">__name__</span><span class="p">)</span>
+
+
+<span class="k">def</span> <span class="nf">_alwaysSucceedsPostConnectionCheck</span><span class="p">(</span><span class="n">peerX509</span><span class="p">,</span> <span class="n">expectedHost</span><span class="p">):</span>
+ <span class="k">return</span> <span class="mi">1</span>
+
+
+<div class="viewcode-block" id="connectSSL"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.TwistedProtocolWrapper.connectSSL">[docs]</a><span class="k">def</span> <span class="nf">connectSSL</span><span class="p">(</span><span class="n">host</span><span class="p">,</span> <span class="n">port</span><span class="p">,</span> <span class="n">factory</span><span class="p">,</span> <span class="n">contextFactory</span><span class="p">,</span> <span class="n">timeout</span><span class="o">=</span><span class="mi">30</span><span class="p">,</span>
+ <span class="n">bindAddress</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
+ <span class="n">reactor</span><span class="o">=</span><span class="n">twisted</span><span class="o">.</span><span class="n">internet</span><span class="o">.</span><span class="n">reactor</span><span class="p">,</span>
+ <span class="n">postConnectionCheck</span><span class="o">=</span><span class="n">Checker</span><span class="p">()):</span>
+ <span class="c1"># type: (str, int, object, object, int, Optional[str], twisted.internet.reactor, Checker) -&gt; reactor.connectTCP</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> A convenience function to start an SSL/TLS connection using Twisted.</span>
+
+<span class="sd"> See IReactorSSL interface in Twisted.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">wrappingFactory</span> <span class="o">=</span> <span class="n">policies</span><span class="o">.</span><span class="n">WrappingFactory</span><span class="p">(</span><span class="n">factory</span><span class="p">)</span>
+ <span class="n">wrappingFactory</span><span class="o">.</span><span class="n">protocol</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">factory</span><span class="p">,</span> <span class="n">wrappedProtocol</span><span class="p">:</span> \
+ <span class="n">TLSProtocolWrapper</span><span class="p">(</span><span class="n">factory</span><span class="p">,</span>
+ <span class="n">wrappedProtocol</span><span class="p">,</span>
+ <span class="n">startPassThrough</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span>
+ <span class="n">client</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span>
+ <span class="n">contextFactory</span><span class="o">=</span><span class="n">contextFactory</span><span class="p">,</span>
+ <span class="n">postConnectionCheck</span><span class="o">=</span><span class="n">postConnectionCheck</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">reactor</span><span class="o">.</span><span class="n">connectTCP</span><span class="p">(</span><span class="n">host</span><span class="p">,</span> <span class="n">port</span><span class="p">,</span> <span class="n">wrappingFactory</span><span class="p">,</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">bindAddress</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="connectTCP"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.TwistedProtocolWrapper.connectTCP">[docs]</a><span class="k">def</span> <span class="nf">connectTCP</span><span class="p">(</span><span class="n">host</span><span class="p">,</span> <span class="n">port</span><span class="p">,</span> <span class="n">factory</span><span class="p">,</span> <span class="n">timeout</span><span class="o">=</span><span class="mi">30</span><span class="p">,</span> <span class="n">bindAddress</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
+ <span class="n">reactor</span><span class="o">=</span><span class="n">twisted</span><span class="o">.</span><span class="n">internet</span><span class="o">.</span><span class="n">reactor</span><span class="p">,</span>
+ <span class="n">postConnectionCheck</span><span class="o">=</span><span class="n">Checker</span><span class="p">()):</span>
+ <span class="c1"># type: (str, int, object, int, Optional[util.AddrType], object, Callable) -&gt; object</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> A convenience function to start a TCP connection using Twisted.</span>
+
+<span class="sd"> NOTE: You must call startTLS(ctx) to go into SSL/TLS mode.</span>
+
+<span class="sd"> See IReactorTCP interface in Twisted.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">wrappingFactory</span> <span class="o">=</span> <span class="n">policies</span><span class="o">.</span><span class="n">WrappingFactory</span><span class="p">(</span><span class="n">factory</span><span class="p">)</span>
+ <span class="n">wrappingFactory</span><span class="o">.</span><span class="n">protocol</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">factory</span><span class="p">,</span> <span class="n">wrappedProtocol</span><span class="p">:</span> \
+ <span class="n">TLSProtocolWrapper</span><span class="p">(</span><span class="n">factory</span><span class="p">,</span>
+ <span class="n">wrappedProtocol</span><span class="p">,</span>
+ <span class="n">startPassThrough</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span>
+ <span class="n">client</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span>
+ <span class="n">contextFactory</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
+ <span class="n">postConnectionCheck</span><span class="o">=</span><span class="n">postConnectionCheck</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">reactor</span><span class="o">.</span><span class="n">connectTCP</span><span class="p">(</span><span class="n">host</span><span class="p">,</span> <span class="n">port</span><span class="p">,</span> <span class="n">wrappingFactory</span><span class="p">,</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">bindAddress</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="listenSSL"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.TwistedProtocolWrapper.listenSSL">[docs]</a><span class="k">def</span> <span class="nf">listenSSL</span><span class="p">(</span><span class="n">port</span><span class="p">,</span> <span class="n">factory</span><span class="p">,</span> <span class="n">contextFactory</span><span class="p">,</span> <span class="n">backlog</span><span class="o">=</span><span class="mi">5</span><span class="p">,</span> <span class="n">interface</span><span class="o">=</span><span class="s1">&#39;&#39;</span><span class="p">,</span>
+ <span class="n">reactor</span><span class="o">=</span><span class="n">twisted</span><span class="o">.</span><span class="n">internet</span><span class="o">.</span><span class="n">reactor</span><span class="p">,</span>
+ <span class="n">postConnectionCheck</span><span class="o">=</span><span class="n">_alwaysSucceedsPostConnectionCheck</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> A convenience function to listen for SSL/TLS connections using Twisted.</span>
+
+<span class="sd"> See IReactorSSL interface in Twisted.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">wrappingFactory</span> <span class="o">=</span> <span class="n">policies</span><span class="o">.</span><span class="n">WrappingFactory</span><span class="p">(</span><span class="n">factory</span><span class="p">)</span>
+ <span class="n">wrappingFactory</span><span class="o">.</span><span class="n">protocol</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">factory</span><span class="p">,</span> <span class="n">wrappedProtocol</span><span class="p">:</span> \
+ <span class="n">TLSProtocolWrapper</span><span class="p">(</span><span class="n">factory</span><span class="p">,</span>
+ <span class="n">wrappedProtocol</span><span class="p">,</span>
+ <span class="n">startPassThrough</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span>
+ <span class="n">client</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span>
+ <span class="n">contextFactory</span><span class="o">=</span><span class="n">contextFactory</span><span class="p">,</span>
+ <span class="n">postConnectionCheck</span><span class="o">=</span><span class="n">postConnectionCheck</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">reactor</span><span class="o">.</span><span class="n">listenTCP</span><span class="p">(</span><span class="n">port</span><span class="p">,</span> <span class="n">wrappingFactory</span><span class="p">,</span> <span class="n">backlog</span><span class="p">,</span> <span class="n">interface</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="listenTCP"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.TwistedProtocolWrapper.listenTCP">[docs]</a><span class="k">def</span> <span class="nf">listenTCP</span><span class="p">(</span><span class="n">port</span><span class="p">,</span> <span class="n">factory</span><span class="p">,</span> <span class="n">backlog</span><span class="o">=</span><span class="mi">5</span><span class="p">,</span> <span class="n">interface</span><span class="o">=</span><span class="s1">&#39;&#39;</span><span class="p">,</span>
+ <span class="n">reactor</span><span class="o">=</span><span class="n">twisted</span><span class="o">.</span><span class="n">internet</span><span class="o">.</span><span class="n">reactor</span><span class="p">,</span>
+ <span class="n">postConnectionCheck</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> A convenience function to listen for TCP connections using Twisted.</span>
+
+<span class="sd"> NOTE: You must call startTLS(ctx) to go into SSL/TLS mode.</span>
+
+<span class="sd"> See IReactorTCP interface in Twisted.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">wrappingFactory</span> <span class="o">=</span> <span class="n">policies</span><span class="o">.</span><span class="n">WrappingFactory</span><span class="p">(</span><span class="n">factory</span><span class="p">)</span>
+ <span class="n">wrappingFactory</span><span class="o">.</span><span class="n">protocol</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">factory</span><span class="p">,</span> <span class="n">wrappedProtocol</span><span class="p">:</span> \
+ <span class="n">TLSProtocolWrapper</span><span class="p">(</span><span class="n">factory</span><span class="p">,</span>
+ <span class="n">wrappedProtocol</span><span class="p">,</span>
+ <span class="n">startPassThrough</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span>
+ <span class="n">client</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span>
+ <span class="n">contextFactory</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
+ <span class="n">postConnectionCheck</span><span class="o">=</span><span class="n">postConnectionCheck</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">reactor</span><span class="o">.</span><span class="n">listenTCP</span><span class="p">(</span><span class="n">port</span><span class="p">,</span> <span class="n">wrappingFactory</span><span class="p">,</span> <span class="n">backlog</span><span class="p">,</span> <span class="n">interface</span><span class="p">)</span></div>
+
+
+<span class="k">class</span> <span class="nc">_BioProxy</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> The purpose of this class is to eliminate the __del__ method from</span>
+<span class="sd"> TLSProtocolWrapper, and thus letting it be garbage collected.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+
+ <span class="n">m2_bio_free_all</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">bio_free_all</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bio</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">bio</span> <span class="o">=</span> <span class="n">bio</span>
+
+ <span class="k">def</span> <span class="nf">_ptr</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">bio</span>
+
+ <span class="k">def</span> <span class="nf">__del__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">bio</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">m2_bio_free_all</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">bio</span><span class="p">)</span>
+
+
+<span class="k">class</span> <span class="nc">_SSLProxy</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> The purpose of this class is to eliminate the __del__ method from</span>
+<span class="sd"> TLSProtocolWrapper, and thus letting it be garbage collected.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+
+ <span class="n">m2_ssl_free</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_free</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">ssl</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">ssl</span> <span class="o">=</span> <span class="n">ssl</span>
+
+ <span class="k">def</span> <span class="nf">_ptr</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">ssl</span>
+
+ <span class="k">def</span> <span class="nf">__del__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">ssl</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">m2_ssl_free</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="p">)</span>
+
+
+<div class="viewcode-block" id="TLSProtocolWrapper"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper">[docs]</a><span class="nd">@implementer</span><span class="p">(</span><span class="n">ITLSTransport</span><span class="p">)</span>
+<span class="k">class</span> <span class="nc">TLSProtocolWrapper</span><span class="p">(</span><span class="n">ProtocolWrapper</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> A SSL/TLS protocol wrapper to be used with Twisted. Typically</span>
+<span class="sd"> you would not use this class directly. Use connectTCP,</span>
+<span class="sd"> connectSSL, listenTCP, listenSSL functions defined above,</span>
+<span class="sd"> which will hook in this class.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">factory</span><span class="p">,</span> <span class="n">wrappedProtocol</span><span class="p">,</span> <span class="n">startPassThrough</span><span class="p">,</span> <span class="n">client</span><span class="p">,</span>
+ <span class="n">contextFactory</span><span class="p">,</span> <span class="n">postConnectionCheck</span><span class="p">):</span>
+ <span class="c1"># type: (policies.WrappingFactory, object, int, int, object, Checker) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> :param factory:</span>
+<span class="sd"> :param wrappedProtocol:</span>
+<span class="sd"> :param startPassThrough: If true we won&#39;t encrypt at all. Need to</span>
+<span class="sd"> call startTLS() later to switch to SSL/TLS.</span>
+<span class="sd"> :param client: True if this should be a client protocol.</span>
+<span class="sd"> :param contextFactory: Factory that creates SSL.Context objects.</span>
+<span class="sd"> The called function is getContext().</span>
+<span class="sd"> :param postConnectionCheck: The post connection check callback that</span>
+<span class="sd"> will be called just after connection has</span>
+<span class="sd"> been established but before any real data</span>
+<span class="sd"> has been exchanged. The first argument to</span>
+<span class="sd"> this function is an X509 object, the second</span>
+<span class="sd"> is the expected host name string.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="c1"># ProtocolWrapper.__init__(self, factory, wrappedProtocol)</span>
+ <span class="c1"># XXX: Twisted 2.0 has a new addition where the wrappingFactory is</span>
+ <span class="c1"># set as the factory of the wrappedProtocol. This is an issue</span>
+ <span class="c1"># as the wrap should be transparent. What we want is</span>
+ <span class="c1"># the factory of the wrappedProtocol to be the wrappedFactory and</span>
+ <span class="c1"># not the outer wrappingFactory. This is how it was implemented in</span>
+ <span class="c1"># Twisted 1.3</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">factory</span> <span class="o">=</span> <span class="n">factory</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">wrappedProtocol</span> <span class="o">=</span> <span class="n">wrappedProtocol</span>
+
+ <span class="c1"># wrappedProtocol == client/server instance</span>
+ <span class="c1"># factory.wrappedFactory == client/server factory</span>
+
+ <span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span> <span class="c1"># Clear text to encrypt and send</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">encrypted</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span> <span class="c1"># Encrypted data we need to decrypt and pass on</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">tlsStarted</span> <span class="o">=</span> <span class="mi">0</span> <span class="c1"># SSL/TLS mode or pass through</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">checked</span> <span class="o">=</span> <span class="mi">0</span> <span class="c1"># Post connection check done or not</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">isClient</span> <span class="o">=</span> <span class="n">client</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">helloDone</span> <span class="o">=</span> <span class="mi">0</span> <span class="c1"># True when hello has been sent</span>
+ <span class="k">if</span> <span class="n">postConnectionCheck</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">postConnectionCheck</span> <span class="o">=</span> <span class="n">_alwaysSucceedsPostConnectionCheck</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">postConnectionCheck</span> <span class="o">=</span> <span class="n">postConnectionCheck</span>
+
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">startPassThrough</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">startTLS</span><span class="p">(</span><span class="n">contextFactory</span><span class="o">.</span><span class="n">getContext</span><span class="p">())</span>
+
+<div class="viewcode-block" id="TLSProtocolWrapper.clear"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper.clear">[docs]</a> <span class="k">def</span> <span class="nf">clear</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Clear this instance, after which it is ready for reuse.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;tlsStarted&#39;</span><span class="p">,</span> <span class="mi">0</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">sslBio</span> <span class="o">=</span> <span class="kc">None</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">ssl</span> <span class="o">=</span> <span class="kc">None</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">internalBio</span> <span class="o">=</span> <span class="kc">None</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">networkBio</span> <span class="o">=</span> <span class="kc">None</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">encrypted</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">tlsStarted</span> <span class="o">=</span> <span class="mi">0</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">checked</span> <span class="o">=</span> <span class="mi">0</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">isClient</span> <span class="o">=</span> <span class="mi">1</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">helloDone</span> <span class="o">=</span> <span class="mi">0</span></div>
+ <span class="c1"># We can reuse self.ctx and it will be deleted automatically</span>
+ <span class="c1"># when this instance dies</span>
+
+<div class="viewcode-block" id="TLSProtocolWrapper.startTLS"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper.startTLS">[docs]</a> <span class="k">def</span> <span class="nf">startTLS</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">ctx</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Start SSL/TLS. If this is not called, this instance just passes data</span>
+<span class="sd"> through untouched.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="c1"># NOTE: This method signature must match the startTLS() method Twisted</span>
+ <span class="c1"># expects transports to have. This will be called automatically</span>
+ <span class="c1"># by Twisted in STARTTLS situations, for example with SMTP.</span>
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">tlsStarted</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s1">&#39;TLS already started&#39;</span><span class="p">)</span>
+
+ <span class="bp">self</span><span class="o">.</span><span class="n">ctx</span> <span class="o">=</span> <span class="n">ctx</span>
+
+ <span class="bp">self</span><span class="o">.</span><span class="n">internalBio</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">bio_new</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">bio_s_bio</span><span class="p">())</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">bio_set_write_buf_size</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">internalBio</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">networkBio</span> <span class="o">=</span> <span class="n">_BioProxy</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">bio_new</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">bio_s_bio</span><span class="p">()))</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">bio_set_write_buf_size</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">networkBio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span> <span class="mi">0</span><span class="p">)</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">bio_make_bio_pair</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">internalBio</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">networkBio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span>
+
+ <span class="bp">self</span><span class="o">.</span><span class="n">sslBio</span> <span class="o">=</span> <span class="n">_BioProxy</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">bio_new</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">bio_f_ssl</span><span class="p">()))</span>
+
+ <span class="bp">self</span><span class="o">.</span><span class="n">ssl</span> <span class="o">=</span> <span class="n">_SSLProxy</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">ssl_new</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="o">.</span><span class="n">ctx</span><span class="p">))</span>
+
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">isClient</span><span class="p">:</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">ssl_set_connect_state</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">ssl_set_accept_state</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span>
+
+ <span class="n">m2</span><span class="o">.</span><span class="n">ssl_set_bio</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span> <span class="bp">self</span><span class="o">.</span><span class="n">internalBio</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">internalBio</span><span class="p">)</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">bio_set_ssl</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">sslBio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span> <span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span> <span class="n">m2</span><span class="o">.</span><span class="n">bio_noclose</span><span class="p">)</span>
+
+ <span class="c1"># Need this for writes that are larger than BIO pair buffers</span>
+ <span class="n">mode</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_get_mode</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">ssl_set_mode</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span>
+ <span class="n">mode</span> <span class="o">|</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">SSL_MODE_ENABLE_PARTIAL_WRITE</span> <span class="o">|</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER</span><span class="p">)</span>
+
+ <span class="bp">self</span><span class="o">.</span><span class="n">tlsStarted</span> <span class="o">=</span> <span class="mi">1</span></div>
+
+<div class="viewcode-block" id="TLSProtocolWrapper.write"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper.write">[docs]</a> <span class="k">def</span> <span class="nf">write</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
+ <span class="c1"># type: (bytes) -&gt; None</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">tlsStarted</span><span class="p">:</span>
+ <span class="n">ProtocolWrapper</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span>
+ <span class="k">return</span>
+
+ <span class="k">try</span><span class="p">:</span>
+ <span class="n">encryptedData</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_encrypt</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
+ <span class="n">ProtocolWrapper</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">encryptedData</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">helloDone</span> <span class="o">=</span> <span class="mi">1</span>
+ <span class="k">except</span> <span class="n">BIO</span><span class="o">.</span><span class="n">BIOError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
+ <span class="c1"># See http://www.openssl.org/docs/apps/verify.html#DIAGNOSTICS</span>
+ <span class="c1"># for the error codes returned by SSL_get_verify_result.</span>
+ <span class="n">e</span><span class="o">.</span><span class="n">args</span> <span class="o">=</span> <span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">ssl_get_verify_result</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="o">.</span><span class="n">_ptr</span><span class="p">()),</span> <span class="n">e</span><span class="o">.</span><span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
+ <span class="k">raise</span> <span class="n">e</span></div>
+
+<div class="viewcode-block" id="TLSProtocolWrapper.writeSequence"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper.writeSequence">[docs]</a> <span class="k">def</span> <span class="nf">writeSequence</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
+ <span class="c1"># type: (Iterable[bytes]) -&gt; None</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">tlsStarted</span><span class="p">:</span>
+ <span class="n">ProtocolWrapper</span><span class="o">.</span><span class="n">writeSequence</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">data</span><span class="p">))</span>
+ <span class="k">return</span>
+
+ <span class="bp">self</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">data</span><span class="p">))</span></div>
+
+<div class="viewcode-block" id="TLSProtocolWrapper.loseConnection"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper.loseConnection">[docs]</a> <span class="k">def</span> <span class="nf">loseConnection</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># XXX Do we need to do m2.ssl_shutdown(self.ssl._ptr())?</span>
+ <span class="n">ProtocolWrapper</span><span class="o">.</span><span class="n">loseConnection</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="TLSProtocolWrapper.connectionMade"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper.connectionMade">[docs]</a> <span class="k">def</span> <span class="nf">connectionMade</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="n">ProtocolWrapper</span><span class="o">.</span><span class="n">connectionMade</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">tlsStarted</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">isClient</span> <span class="ow">and</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">helloDone</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_clientHello</span><span class="p">()</span></div>
+
+<div class="viewcode-block" id="TLSProtocolWrapper.dataReceived"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper.dataReceived">[docs]</a> <span class="k">def</span> <span class="nf">dataReceived</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
+ <span class="c1"># type: (bytes) -&gt; None</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">tlsStarted</span><span class="p">:</span>
+ <span class="n">ProtocolWrapper</span><span class="o">.</span><span class="n">dataReceived</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span>
+ <span class="k">return</span>
+
+ <span class="bp">self</span><span class="o">.</span><span class="n">encrypted</span> <span class="o">+=</span> <span class="n">data</span>
+
+ <span class="k">try</span><span class="p">:</span>
+ <span class="k">while</span> <span class="mi">1</span><span class="p">:</span>
+ <span class="n">decryptedData</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_decrypt</span><span class="p">()</span>
+
+ <span class="bp">self</span><span class="o">.</span><span class="n">_check</span><span class="p">()</span>
+
+ <span class="n">encryptedData</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_encrypt</span><span class="p">()</span>
+ <span class="n">ProtocolWrapper</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">encryptedData</span><span class="p">)</span>
+
+ <span class="n">ProtocolWrapper</span><span class="o">.</span><span class="n">dataReceived</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">decryptedData</span><span class="p">)</span>
+
+ <span class="k">if</span> <span class="n">decryptedData</span> <span class="o">==</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span> <span class="ow">and</span> <span class="n">encryptedData</span> <span class="o">==</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">:</span>
+ <span class="k">break</span>
+ <span class="k">except</span> <span class="n">BIO</span><span class="o">.</span><span class="n">BIOError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
+ <span class="c1"># See http://www.openssl.org/docs/apps/verify.html#DIAGNOSTICS</span>
+ <span class="c1"># for the error codes returned by SSL_get_verify_result.</span>
+ <span class="n">e</span><span class="o">.</span><span class="n">args</span> <span class="o">=</span> <span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">ssl_get_verify_result</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="o">.</span><span class="n">_ptr</span><span class="p">()),</span> <span class="n">e</span><span class="o">.</span><span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
+ <span class="k">raise</span> <span class="n">e</span></div>
+
+<div class="viewcode-block" id="TLSProtocolWrapper.connectionLost"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper.connectionLost">[docs]</a> <span class="k">def</span> <span class="nf">connectionLost</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">reason</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr) -&gt; None</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">clear</span><span class="p">()</span>
+ <span class="n">ProtocolWrapper</span><span class="o">.</span><span class="n">connectionLost</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">reason</span><span class="p">)</span></div>
+
+ <span class="k">def</span> <span class="nf">_check</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">checked</span> <span class="ow">and</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_is_init_finished</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="o">.</span><span class="n">_ptr</span><span class="p">()):</span>
+ <span class="n">x509</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_get_peer_cert</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span>
+ <span class="k">if</span> <span class="n">x509</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">x509</span> <span class="o">=</span> <span class="n">X509</span><span class="o">.</span><span class="n">X509</span><span class="p">(</span><span class="n">x509</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">isClient</span><span class="p">:</span>
+ <span class="n">host</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">transport</span><span class="o">.</span><span class="n">addr</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">host</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">transport</span><span class="o">.</span><span class="n">getPeer</span><span class="p">()</span><span class="o">.</span><span class="n">host</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">postConnectionCheck</span><span class="p">(</span><span class="n">x509</span><span class="p">,</span> <span class="n">host</span><span class="p">):</span>
+ <span class="k">raise</span> <span class="n">SSLVerificationError</span><span class="p">(</span><span class="s1">&#39;post connection check&#39;</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">checked</span> <span class="o">=</span> <span class="mi">1</span>
+
+ <span class="k">def</span> <span class="nf">_clientHello</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="k">try</span><span class="p">:</span>
+ <span class="c1"># We rely on OpenSSL implicitly starting with client hello</span>
+ <span class="c1"># when we haven&#39;t yet established an SSL connection</span>
+ <span class="n">encryptedData</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_encrypt</span><span class="p">(</span><span class="n">clientHello</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
+ <span class="n">ProtocolWrapper</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">encryptedData</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">helloDone</span> <span class="o">=</span> <span class="mi">1</span>
+ <span class="k">except</span> <span class="n">BIO</span><span class="o">.</span><span class="n">BIOError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
+ <span class="c1"># See http://www.openssl.org/docs/apps/verify.html#DIAGNOSTICS</span>
+ <span class="c1"># for the error codes returned by SSL_get_verify_result.</span>
+ <span class="n">e</span><span class="o">.</span><span class="n">args</span> <span class="o">=</span> <span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">ssl_get_verify_result</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl</span><span class="o">.</span><span class="n">_ptr</span><span class="p">()),</span> <span class="n">e</span><span class="o">.</span><span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
+ <span class="k">raise</span> <span class="n">e</span>
+
+ <span class="c1"># Optimizations to reduce attribute accesses</span>
+
+ <span class="nd">@property</span>
+ <span class="k">def</span> <span class="nf">_get_wr_guar_ssl</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; Callable[[], int]</span>
+ <span class="sd">&quot;&quot;&quot;Return max. length of data can be written to the BIO.</span>
+
+<span class="sd"> Writes larger than this value will return a value from</span>
+<span class="sd"> BIO_write() less than the amount requested or if the buffer is</span>
+<span class="sd"> full request a retry.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">partial</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">bio_ctrl_get_write_guarantee</span><span class="p">,</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">sslBio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span>
+
+ <span class="nd">@property</span>
+ <span class="k">def</span> <span class="nf">_get_wr_guar_net</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; Callable[[], int]</span>
+ <span class="k">return</span> <span class="n">partial</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">bio_ctrl_get_write_guarantee</span><span class="p">,</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">networkBio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span>
+
+ <span class="nd">@property</span>
+ <span class="k">def</span> <span class="nf">_shoud_retry_ssl</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; Callable[[], int]</span>
+ <span class="c1"># BIO_should_retry() is true if the call that produced this</span>
+ <span class="c1"># condition should then be retried at a later time.</span>
+ <span class="k">return</span> <span class="n">partial</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">bio_should_retry</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">sslBio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span>
+
+ <span class="nd">@property</span>
+ <span class="k">def</span> <span class="nf">_shoud_retry_net</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; Callable[[], int]</span>
+ <span class="k">return</span> <span class="n">partial</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">bio_should_retry</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">networkBio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span>
+
+ <span class="nd">@property</span>
+ <span class="k">def</span> <span class="nf">_ctrl_pend_ssl</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; Callable[[], int]</span>
+ <span class="c1"># size_t BIO_ctrl_pending(BIO *b);</span>
+ <span class="c1"># BIO_ctrl_pending() return the number of pending characters in</span>
+ <span class="c1"># the BIOs read and write buffers.</span>
+ <span class="k">return</span> <span class="n">partial</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">bio_ctrl_pending</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">sslBio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span>
+
+ <span class="nd">@property</span>
+ <span class="k">def</span> <span class="nf">_ctrl_pend_net</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; Callable[[], int]</span>
+ <span class="k">return</span> <span class="n">partial</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">bio_ctrl_pending</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">networkBio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span>
+
+ <span class="nd">@property</span>
+ <span class="k">def</span> <span class="nf">_write_ssl</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; Callable[[bytes], int]</span>
+ <span class="c1"># All these functions return either the amount of data</span>
+ <span class="c1"># successfully read or written (if the return value is</span>
+ <span class="c1"># positive) or that no data was successfully read or written</span>
+ <span class="c1"># if the result is 0 or -1. If the return value is -2 then</span>
+ <span class="c1"># the operation is not implemented in the specific BIO type.</span>
+ <span class="k">return</span> <span class="n">partial</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">bio_write</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">sslBio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span>
+
+ <span class="nd">@property</span>
+ <span class="k">def</span> <span class="nf">_write_net</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; Callable[[bytes], int]</span>
+ <span class="k">return</span> <span class="n">partial</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">bio_write</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">networkBio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span>
+
+ <span class="nd">@property</span>
+ <span class="k">def</span> <span class="nf">_read_ssl</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; Callable[[int], Optional[bytes]]</span>
+ <span class="k">return</span> <span class="n">partial</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">bio_read</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">sslBio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span>
+
+ <span class="nd">@property</span>
+ <span class="k">def</span> <span class="nf">_read_net</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; Callable[[int], Optional[bytes]]</span>
+ <span class="k">return</span> <span class="n">partial</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">bio_read</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">networkBio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span>
+
+ <span class="k">def</span> <span class="nf">_encrypt</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">clientHello</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
+ <span class="c1"># type: (bytes, int) -&gt; bytes</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> :param data:</span>
+<span class="sd"> :param clientHello:</span>
+<span class="sd"> :return:</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">encryptedData</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">+=</span> <span class="n">data</span>
+
+ <span class="k">while</span> <span class="mi">1</span><span class="p">:</span>
+ <span class="k">if</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_get_wr_guar_ssl</span><span class="p">()</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">!=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">)</span> <span class="ow">or</span> <span class="n">clientHello</span><span class="p">:</span>
+ <span class="n">r</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_write_ssl</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">r</span> <span class="o">&lt;=</span> <span class="mi">0</span><span class="p">:</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_shoud_retry_ssl</span><span class="p">():</span>
+ <span class="k">raise</span> <span class="ne">IOError</span><span class="p">(</span>
+ <span class="p">(</span><span class="s1">&#39;Data left to be written to </span><span class="si">{}</span><span class="s1">, &#39;</span> <span class="o">+</span>
+ <span class="s1">&#39;but cannot retry SSL connection!&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">sslBio</span><span class="p">))</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">checked</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="n">r</span><span class="p">:]</span>
+
+ <span class="n">pending</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_ctrl_pend_net</span><span class="p">()</span>
+ <span class="k">if</span> <span class="n">pending</span><span class="p">:</span>
+ <span class="n">d</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_read_net</span><span class="p">(</span><span class="n">pending</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">d</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> <span class="c1"># This is strange, but d can be None</span>
+ <span class="n">encryptedData</span> <span class="o">+=</span> <span class="n">d</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">assert</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_shoud_retry_net</span><span class="p">())</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">break</span>
+ <span class="k">return</span> <span class="n">encryptedData</span>
+
+ <span class="k">def</span> <span class="nf">_decrypt</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">):</span>
+ <span class="c1"># type: (bytes) -&gt; bytes</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">encrypted</span> <span class="o">+=</span> <span class="n">data</span>
+ <span class="n">decryptedData</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span>
+
+ <span class="k">while</span> <span class="mi">1</span><span class="p">:</span>
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_wr_guar_ssl</span><span class="p">()</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">encrypted</span> <span class="o">!=</span> <span class="sa">b</span><span class="s1">&#39;&#39;</span><span class="p">:</span>
+ <span class="n">r</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_write_net</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">encrypted</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">r</span> <span class="o">&lt;=</span> <span class="mi">0</span><span class="p">:</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_shoud_retry_net</span><span class="p">():</span>
+ <span class="k">raise</span> <span class="ne">IOError</span><span class="p">(</span>
+ <span class="p">(</span><span class="s1">&#39;Data left to be written to </span><span class="si">{}</span><span class="s1">, &#39;</span> <span class="o">+</span>
+ <span class="s1">&#39;but cannot retry SSL connection!&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">networkBio</span><span class="p">))</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">encrypted</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">encrypted</span><span class="p">[</span><span class="n">r</span><span class="p">:]</span>
+
+ <span class="n">pending</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_ctrl_pend_ssl</span><span class="p">()</span>
+ <span class="k">if</span> <span class="n">pending</span><span class="p">:</span>
+ <span class="n">d</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_read_ssl</span><span class="p">(</span><span class="n">pending</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">d</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> <span class="c1"># This is strange, but d can be None</span>
+ <span class="n">decryptedData</span> <span class="o">+=</span> <span class="n">d</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">assert</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_shoud_retry_ssl</span><span class="p">())</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">break</span>
+
+ <span class="k">return</span> <span class="n">decryptedData</span></div>
+</pre></div>
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="../../../index.html">M2Crypto</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="../../../M2Crypto.html">M2Crypto Package</a></li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="../../../index.html">Documentation overview</a><ul>
+ <li><a href="../../index.html">Module code</a><ul>
+ <li><a href="../SSL.html">M2Crypto.SSL</a><ul>
+ </ul></li>
+ </ul></li>
+ </ul></li>
+</ul>
+</div>
+<div id="searchbox" style="display: none" role="search">
+ <h3>Quick search</h3>
+ <div class="searchformwrapper">
+ <form class="search" action="../../../search.html" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ </div>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer">
+ &copy;2017, Matej Cepl <mcepl@cepl.eu>.
+
+ |
+ Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
+ &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
+
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/_modules/M2Crypto/SSL/cb.html b/doc/html/_modules/M2Crypto/SSL/cb.html
new file mode 100644
index 0000000..0e7c20f
--- /dev/null
+++ b/doc/html/_modules/M2Crypto/SSL/cb.html
@@ -0,0 +1,202 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>M2Crypto.SSL.cb &#8212; M2Crypto documentation</title>
+ <link rel="stylesheet" href="../../../_static/alabaster.css" type="text/css" />
+ <link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../../../_static/jquery.js"></script>
+ <script type="text/javascript" src="../../../_static/underscore.js"></script>
+ <script type="text/javascript" src="../../../_static/doctools.js"></script>
+ <script type="text/javascript" src="../../../_static/language_data.js"></script>
+ <link rel="index" title="Index" href="../../../genindex.html" />
+ <link rel="search" title="Search" href="../../../search.html" />
+
+ <link rel="stylesheet" href="../../../_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+ <h1>Source code for M2Crypto.SSL.cb</h1><div class="highlight"><pre>
+<span></span><span class="kn">from</span> <span class="nn">__future__</span> <span class="k">import</span> <span class="n">absolute_import</span>
+
+<span class="sd">&quot;&quot;&quot;SSL callbacks</span>
+
+<span class="sd">Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved.&quot;&quot;&quot;</span>
+
+<span class="kn">import</span> <span class="nn">sys</span>
+
+<span class="kn">from</span> <span class="nn">M2Crypto</span> <span class="k">import</span> <span class="n">m2</span><span class="p">,</span> <span class="n">util</span>
+<span class="k">if</span> <span class="n">util</span><span class="o">.</span><span class="n">py27plus</span><span class="p">:</span>
+ <span class="kn">from</span> <span class="nn">typing</span> <span class="k">import</span> <span class="n">Any</span><span class="p">,</span> <span class="n">List</span> <span class="c1"># noqa</span>
+
+<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;unknown_issuer&#39;</span><span class="p">,</span> <span class="s1">&#39;ssl_verify_callback_stub&#39;</span><span class="p">,</span> <span class="s1">&#39;ssl_verify_callback&#39;</span><span class="p">,</span>
+ <span class="s1">&#39;ssl_verify_callback_allow_unknown_ca&#39;</span><span class="p">,</span> <span class="s1">&#39;ssl_info_callback&#39;</span><span class="p">]</span>
+
+
+<div class="viewcode-block" id="ssl_verify_callback_stub"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.cb.ssl_verify_callback_stub">[docs]</a><span class="k">def</span> <span class="nf">ssl_verify_callback_stub</span><span class="p">(</span><span class="n">ssl_ctx_ptr</span><span class="p">,</span> <span class="n">x509_ptr</span><span class="p">,</span> <span class="n">errnum</span><span class="p">,</span> <span class="n">errdepth</span><span class="p">,</span> <span class="n">ok</span><span class="p">):</span>
+ <span class="c1"># Deprecated</span>
+ <span class="k">return</span> <span class="n">ok</span></div>
+
+<span class="n">unknown_issuer</span> <span class="o">=</span> <span class="p">[</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT</span><span class="p">,</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY</span><span class="p">,</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE</span><span class="p">,</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">X509_V_ERR_CERT_UNTRUSTED</span><span class="p">,</span>
+<span class="p">]</span>
+
+
+<div class="viewcode-block" id="ssl_verify_callback"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.cb.ssl_verify_callback">[docs]</a><span class="k">def</span> <span class="nf">ssl_verify_callback</span><span class="p">(</span><span class="n">ssl_ctx_ptr</span><span class="p">,</span> <span class="n">x509_ptr</span><span class="p">,</span> <span class="n">errnum</span><span class="p">,</span> <span class="n">errdepth</span><span class="p">,</span> <span class="n">ok</span><span class="p">):</span>
+ <span class="c1"># type: (bytes, bytes, int, int, int) -&gt; int</span>
+ <span class="c1"># Deprecated</span>
+
+ <span class="kn">from</span> <span class="nn">M2Crypto.SSL.Context</span> <span class="k">import</span> <span class="n">Context</span>
+ <span class="n">ssl_ctx</span> <span class="o">=</span> <span class="n">Context</span><span class="o">.</span><span class="n">ctxmap</span><span class="p">()[</span><span class="nb">int</span><span class="p">(</span><span class="n">ssl_ctx_ptr</span><span class="p">)]</span>
+ <span class="k">if</span> <span class="n">errnum</span> <span class="ow">in</span> <span class="n">unknown_issuer</span><span class="p">:</span>
+ <span class="k">if</span> <span class="n">ssl_ctx</span><span class="o">.</span><span class="n">get_allow_unknown_ca</span><span class="p">():</span>
+ <span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">&quot;policy: </span><span class="si">%s</span><span class="s2">: permitted...</span><span class="se">\n</span><span class="s2">&quot;</span> <span class="o">%</span>
+ <span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">x509_get_verify_error</span><span class="p">(</span><span class="n">errnum</span><span class="p">)))</span>
+ <span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="o">.</span><span class="n">flush</span><span class="p">()</span>
+ <span class="n">ok</span> <span class="o">=</span> <span class="mi">1</span>
+ <span class="c1"># CRL checking goes here...</span>
+ <span class="k">if</span> <span class="n">ok</span><span class="p">:</span>
+ <span class="k">if</span> <span class="n">ssl_ctx</span><span class="o">.</span><span class="n">get_verify_depth</span><span class="p">()</span> <span class="o">&gt;=</span> <span class="n">errdepth</span><span class="p">:</span>
+ <span class="n">ok</span> <span class="o">=</span> <span class="mi">1</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">ok</span> <span class="o">=</span> <span class="mi">0</span>
+ <span class="k">return</span> <span class="n">ok</span></div>
+
+
+<div class="viewcode-block" id="ssl_verify_callback_allow_unknown_ca"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.cb.ssl_verify_callback_allow_unknown_ca">[docs]</a><span class="k">def</span> <span class="nf">ssl_verify_callback_allow_unknown_ca</span><span class="p">(</span><span class="n">ok</span><span class="p">,</span> <span class="n">store</span><span class="p">):</span>
+ <span class="c1"># type: (int, Any) -&gt; int</span>
+ <span class="n">errnum</span> <span class="o">=</span> <span class="n">store</span><span class="o">.</span><span class="n">get_error</span><span class="p">()</span>
+ <span class="k">if</span> <span class="n">errnum</span> <span class="ow">in</span> <span class="n">unknown_issuer</span><span class="p">:</span>
+ <span class="n">ok</span> <span class="o">=</span> <span class="mi">1</span>
+ <span class="k">return</span> <span class="n">ok</span></div>
+
+
+<span class="c1"># Cribbed from OpenSSL&#39;s apps/s_cb.c.</span>
+<div class="viewcode-block" id="ssl_info_callback"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.cb.ssl_info_callback">[docs]</a><span class="k">def</span> <span class="nf">ssl_info_callback</span><span class="p">(</span><span class="n">where</span><span class="p">,</span> <span class="n">ret</span><span class="p">,</span> <span class="n">ssl_ptr</span><span class="p">):</span>
+ <span class="c1"># type: (int, int, bytes) -&gt; None</span>
+
+ <span class="n">w</span> <span class="o">=</span> <span class="n">where</span> <span class="o">&amp;</span> <span class="o">~</span><span class="n">m2</span><span class="o">.</span><span class="n">SSL_ST_MASK</span>
+ <span class="k">if</span> <span class="n">w</span> <span class="o">&amp;</span> <span class="n">m2</span><span class="o">.</span><span class="n">SSL_ST_CONNECT</span><span class="p">:</span>
+ <span class="n">state</span> <span class="o">=</span> <span class="s2">&quot;SSL connect&quot;</span>
+ <span class="k">elif</span> <span class="n">w</span> <span class="o">&amp;</span> <span class="n">m2</span><span class="o">.</span><span class="n">SSL_ST_ACCEPT</span><span class="p">:</span>
+ <span class="n">state</span> <span class="o">=</span> <span class="s2">&quot;SSL accept&quot;</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">state</span> <span class="o">=</span> <span class="s2">&quot;SSL state unknown&quot;</span>
+
+ <span class="k">if</span> <span class="n">where</span> <span class="o">&amp;</span> <span class="n">m2</span><span class="o">.</span><span class="n">SSL_CB_LOOP</span><span class="p">:</span>
+ <span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">&quot;LOOP: </span><span class="si">%s</span><span class="s2">: </span><span class="si">%s</span><span class="se">\n</span><span class="s2">&quot;</span> <span class="o">%</span>
+ <span class="p">(</span><span class="n">state</span><span class="p">,</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_get_state_v</span><span class="p">(</span><span class="n">ssl_ptr</span><span class="p">)))</span>
+ <span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="o">.</span><span class="n">flush</span><span class="p">()</span>
+ <span class="k">return</span>
+
+ <span class="k">if</span> <span class="n">where</span> <span class="o">&amp;</span> <span class="n">m2</span><span class="o">.</span><span class="n">SSL_CB_EXIT</span><span class="p">:</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">ret</span><span class="p">:</span>
+ <span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">&quot;FAILED: </span><span class="si">%s</span><span class="s2">: </span><span class="si">%s</span><span class="se">\n</span><span class="s2">&quot;</span> <span class="o">%</span>
+ <span class="p">(</span><span class="n">state</span><span class="p">,</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_get_state_v</span><span class="p">(</span><span class="n">ssl_ptr</span><span class="p">)))</span>
+ <span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="o">.</span><span class="n">flush</span><span class="p">()</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">&quot;INFO: </span><span class="si">%s</span><span class="s2">: </span><span class="si">%s</span><span class="se">\n</span><span class="s2">&quot;</span> <span class="o">%</span>
+ <span class="p">(</span><span class="n">state</span><span class="p">,</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_get_state_v</span><span class="p">(</span><span class="n">ssl_ptr</span><span class="p">)))</span>
+ <span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="o">.</span><span class="n">flush</span><span class="p">()</span>
+ <span class="k">return</span>
+
+ <span class="k">if</span> <span class="n">where</span> <span class="o">&amp;</span> <span class="n">m2</span><span class="o">.</span><span class="n">SSL_CB_ALERT</span><span class="p">:</span>
+ <span class="k">if</span> <span class="n">where</span> <span class="o">&amp;</span> <span class="n">m2</span><span class="o">.</span><span class="n">SSL_CB_READ</span><span class="p">:</span>
+ <span class="n">w</span> <span class="o">=</span> <span class="s1">&#39;read&#39;</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">w</span> <span class="o">=</span> <span class="s1">&#39;write&#39;</span>
+ <span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">&quot;ALERT: </span><span class="si">%s</span><span class="s2">: </span><span class="si">%s</span><span class="s2">: </span><span class="si">%s</span><span class="se">\n</span><span class="s2">&quot;</span> <span class="o">%</span>
+ <span class="p">(</span><span class="n">w</span><span class="p">,</span> <span class="n">m2</span><span class="o">.</span><span class="n">ssl_get_alert_type_v</span><span class="p">(</span><span class="n">ret</span><span class="p">),</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">ssl_get_alert_desc_v</span><span class="p">(</span><span class="n">ret</span><span class="p">)))</span>
+ <span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="o">.</span><span class="n">flush</span><span class="p">()</span>
+ <span class="k">return</span></div>
+</pre></div>
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="../../../index.html">M2Crypto</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="../../../M2Crypto.html">M2Crypto Package</a></li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="../../../index.html">Documentation overview</a><ul>
+ <li><a href="../../index.html">Module code</a><ul>
+ <li><a href="../SSL.html">M2Crypto.SSL</a><ul>
+ </ul></li>
+ </ul></li>
+ </ul></li>
+</ul>
+</div>
+<div id="searchbox" style="display: none" role="search">
+ <h3>Quick search</h3>
+ <div class="searchformwrapper">
+ <form class="search" action="../../../search.html" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ </div>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer">
+ &copy;2017, Matej Cepl <mcepl@cepl.eu>.
+
+ |
+ Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
+ &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
+
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/_modules/M2Crypto/SSL/ssl_dispatcher.html b/doc/html/_modules/M2Crypto/SSL/ssl_dispatcher.html
new file mode 100644
index 0000000..a6b964d
--- /dev/null
+++ b/doc/html/_modules/M2Crypto/SSL/ssl_dispatcher.html
@@ -0,0 +1,149 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>M2Crypto.SSL.ssl_dispatcher &#8212; M2Crypto documentation</title>
+ <link rel="stylesheet" href="../../../_static/alabaster.css" type="text/css" />
+ <link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../../../_static/jquery.js"></script>
+ <script type="text/javascript" src="../../../_static/underscore.js"></script>
+ <script type="text/javascript" src="../../../_static/doctools.js"></script>
+ <script type="text/javascript" src="../../../_static/language_data.js"></script>
+ <link rel="index" title="Index" href="../../../genindex.html" />
+ <link rel="search" title="Search" href="../../../search.html" />
+
+ <link rel="stylesheet" href="../../../_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+ <h1>Source code for M2Crypto.SSL.ssl_dispatcher</h1><div class="highlight"><pre>
+<span></span><span class="kn">from</span> <span class="nn">__future__</span> <span class="k">import</span> <span class="n">absolute_import</span>
+
+<span class="sd">&quot;&quot;&quot;SSL dispatcher</span>
+
+<span class="sd">Copyright (c) 1999-2002 Ng Pheng Siong. All rights reserved.&quot;&quot;&quot;</span>
+
+<span class="c1"># Python</span>
+<span class="kn">import</span> <span class="nn">asyncore</span>
+<span class="kn">import</span> <span class="nn">socket</span>
+
+<span class="c1"># M2Crypto</span>
+<span class="kn">from</span> <span class="nn">M2Crypto</span> <span class="k">import</span> <span class="n">util</span> <span class="c1"># noqa</span>
+<span class="kn">from</span> <span class="nn">M2Crypto.SSL.Connection</span> <span class="k">import</span> <span class="n">Connection</span>
+<span class="kn">from</span> <span class="nn">M2Crypto.SSL.Context</span> <span class="k">import</span> <span class="n">Context</span> <span class="c1"># noqa</span>
+
+<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;ssl_dispatcher&#39;</span><span class="p">]</span>
+
+
+<div class="viewcode-block" id="ssl_dispatcher"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.ssl_dispatcher.ssl_dispatcher">[docs]</a><span class="k">class</span> <span class="nc">ssl_dispatcher</span><span class="p">(</span><span class="n">asyncore</span><span class="o">.</span><span class="n">dispatcher</span><span class="p">):</span>
+
+<div class="viewcode-block" id="ssl_dispatcher.create_socket"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.ssl_dispatcher.ssl_dispatcher.create_socket">[docs]</a> <span class="k">def</span> <span class="nf">create_socket</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">ssl_context</span><span class="p">):</span>
+ <span class="c1"># type: (Context) -&gt; None</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">family_and_type</span> <span class="o">=</span> <span class="n">socket</span><span class="o">.</span><span class="n">AF_INET</span><span class="p">,</span> <span class="n">socket</span><span class="o">.</span><span class="n">SOCK_STREAM</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">ssl_ctx</span> <span class="o">=</span> <span class="n">ssl_context</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">socket</span> <span class="o">=</span> <span class="n">Connection</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl_ctx</span><span class="p">)</span>
+ <span class="c1"># self.socket.setblocking(0)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">add_channel</span><span class="p">()</span></div>
+
+<div class="viewcode-block" id="ssl_dispatcher.connect"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.ssl_dispatcher.ssl_dispatcher.connect">[docs]</a> <span class="k">def</span> <span class="nf">connect</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">addr</span><span class="p">):</span>
+ <span class="c1"># type: (util.AddrType) -&gt; None</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">socket</span><span class="o">.</span><span class="n">setblocking</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">socket</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">addr</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">socket</span><span class="o">.</span><span class="n">setblocking</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="ssl_dispatcher.recv"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.ssl_dispatcher.ssl_dispatcher.recv">[docs]</a> <span class="k">def</span> <span class="nf">recv</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">buffer_size</span><span class="o">=</span><span class="mi">4096</span><span class="p">):</span>
+ <span class="c1"># type: (int) -&gt; bytes</span>
+ <span class="sd">&quot;&quot;&quot;Receive data over SSL.&quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">socket</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="n">buffer_size</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="ssl_dispatcher.send"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.ssl_dispatcher.ssl_dispatcher.send">[docs]</a> <span class="k">def</span> <span class="nf">send</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">buffer</span><span class="p">):</span>
+ <span class="c1"># type: (bytes) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;Send data over SSL.&quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">socket</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">buffer</span><span class="p">)</span></div></div>
+</pre></div>
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="../../../index.html">M2Crypto</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="../../../M2Crypto.html">M2Crypto Package</a></li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="../../../index.html">Documentation overview</a><ul>
+ <li><a href="../../index.html">Module code</a><ul>
+ <li><a href="../SSL.html">M2Crypto.SSL</a><ul>
+ </ul></li>
+ </ul></li>
+ </ul></li>
+</ul>
+</div>
+<div id="searchbox" style="display: none" role="search">
+ <h3>Quick search</h3>
+ <div class="searchformwrapper">
+ <form class="search" action="../../../search.html" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ </div>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer">
+ &copy;2017, Matej Cepl <mcepl@cepl.eu>.
+
+ |
+ Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
+ &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
+
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/_modules/M2Crypto/SSL/timeout.html b/doc/html/_modules/M2Crypto/SSL/timeout.html
new file mode 100644
index 0000000..d7fb07f
--- /dev/null
+++ b/doc/html/_modules/M2Crypto/SSL/timeout.html
@@ -0,0 +1,156 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>M2Crypto.SSL.timeout &#8212; M2Crypto documentation</title>
+ <link rel="stylesheet" href="../../../_static/alabaster.css" type="text/css" />
+ <link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../../../_static/jquery.js"></script>
+ <script type="text/javascript" src="../../../_static/underscore.js"></script>
+ <script type="text/javascript" src="../../../_static/doctools.js"></script>
+ <script type="text/javascript" src="../../../_static/language_data.js"></script>
+ <link rel="index" title="Index" href="../../../genindex.html" />
+ <link rel="search" title="Search" href="../../../search.html" />
+
+ <link rel="stylesheet" href="../../../_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+ <h1>Source code for M2Crypto.SSL.timeout</h1><div class="highlight"><pre>
+<span></span><span class="sd">&quot;&quot;&quot;Support for SSL socket timeouts.</span>
+
+<span class="sd">Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved.</span>
+
+<span class="sd">Copyright 2008 Heikki Toivonen. All rights reserved.</span>
+<span class="sd">&quot;&quot;&quot;</span>
+
+<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;DEFAULT_TIMEOUT&#39;</span><span class="p">,</span> <span class="s1">&#39;timeout&#39;</span><span class="p">,</span> <span class="s1">&#39;struct_to_timeout&#39;</span><span class="p">,</span> <span class="s1">&#39;struct_size&#39;</span><span class="p">]</span>
+
+<span class="kn">import</span> <span class="nn">sys</span>
+<span class="kn">import</span> <span class="nn">struct</span>
+
+<span class="n">DEFAULT_TIMEOUT</span> <span class="o">=</span> <span class="mi">600</span> <span class="c1"># type: int</span>
+
+
+<div class="viewcode-block" id="timeout"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.timeout.timeout">[docs]</a><span class="k">class</span> <span class="nc">timeout</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">sec</span><span class="o">=</span><span class="n">DEFAULT_TIMEOUT</span><span class="p">,</span> <span class="n">microsec</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
+ <span class="c1"># type: (int, int) -&gt; None</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">sec</span> <span class="o">=</span> <span class="n">sec</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">microsec</span> <span class="o">=</span> <span class="n">microsec</span>
+
+<div class="viewcode-block" id="timeout.pack"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.timeout.timeout.pack">[docs]</a> <span class="k">def</span> <span class="nf">pack</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="k">if</span> <span class="n">sys</span><span class="o">.</span><span class="n">platform</span> <span class="o">==</span> <span class="s1">&#39;win32&#39;</span><span class="p">:</span>
+ <span class="n">millisec</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">sec</span> <span class="o">*</span> <span class="mi">1000</span> <span class="o">+</span> <span class="nb">round</span><span class="p">(</span><span class="nb">float</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">microsec</span><span class="p">)</span> <span class="o">/</span> <span class="mi">1000</span><span class="p">))</span>
+ <span class="n">binstr</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s1">&#39;l&#39;</span><span class="p">,</span> <span class="n">millisec</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">binstr</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s1">&#39;ll&#39;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">sec</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">microsec</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">binstr</span></div></div>
+
+
+<div class="viewcode-block" id="struct_to_timeout"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.timeout.struct_to_timeout">[docs]</a><span class="k">def</span> <span class="nf">struct_to_timeout</span><span class="p">(</span><span class="n">binstr</span><span class="p">):</span>
+ <span class="c1"># type: (bytes) -&gt; timeout</span>
+ <span class="k">if</span> <span class="n">sys</span><span class="o">.</span><span class="n">platform</span> <span class="o">==</span> <span class="s1">&#39;win32&#39;</span><span class="p">:</span>
+ <span class="n">millisec</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;l&#39;</span><span class="p">,</span> <span class="n">binstr</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
+ <span class="c1"># On py3, int/int performs exact division and returns float. We want</span>
+ <span class="c1"># the whole number portion of the exact division result:</span>
+ <span class="n">sec</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">millisec</span> <span class="o">/</span> <span class="mi">1000</span><span class="p">)</span>
+ <span class="n">microsec</span> <span class="o">=</span> <span class="p">(</span><span class="n">millisec</span> <span class="o">%</span> <span class="mi">1000</span><span class="p">)</span> <span class="o">*</span> <span class="mi">1000</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="p">(</span><span class="n">sec</span><span class="p">,</span> <span class="n">microsec</span><span class="p">)</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;ll&#39;</span><span class="p">,</span> <span class="n">binstr</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">timeout</span><span class="p">(</span><span class="n">sec</span><span class="p">,</span> <span class="n">microsec</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="struct_size"><a class="viewcode-back" href="../../../M2Crypto.SSL.html#M2Crypto.SSL.timeout.struct_size">[docs]</a><span class="k">def</span> <span class="nf">struct_size</span><span class="p">():</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="k">if</span> <span class="n">sys</span><span class="o">.</span><span class="n">platform</span> <span class="o">==</span> <span class="s1">&#39;win32&#39;</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">struct</span><span class="o">.</span><span class="n">calcsize</span><span class="p">(</span><span class="s1">&#39;l&#39;</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">struct</span><span class="o">.</span><span class="n">calcsize</span><span class="p">(</span><span class="s1">&#39;ll&#39;</span><span class="p">)</span></div>
+</pre></div>
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="../../../index.html">M2Crypto</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="../../../M2Crypto.html">M2Crypto Package</a></li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="../../../index.html">Documentation overview</a><ul>
+ <li><a href="../../index.html">Module code</a><ul>
+ <li><a href="../SSL.html">M2Crypto.SSL</a><ul>
+ </ul></li>
+ </ul></li>
+ </ul></li>
+</ul>
+</div>
+<div id="searchbox" style="display: none" role="search">
+ <h3>Quick search</h3>
+ <div class="searchformwrapper">
+ <form class="search" action="../../../search.html" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ </div>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer">
+ &copy;2017, Matej Cepl <mcepl@cepl.eu>.
+
+ |
+ Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
+ &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
+
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/_modules/M2Crypto/X509.html b/doc/html/_modules/M2Crypto/X509.html
new file mode 100644
index 0000000..b546394
--- /dev/null
+++ b/doc/html/_modules/M2Crypto/X509.html
@@ -0,0 +1,1495 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>M2Crypto.X509 &#8212; M2Crypto documentation</title>
+ <link rel="stylesheet" href="../../_static/alabaster.css" type="text/css" />
+ <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../../_static/jquery.js"></script>
+ <script type="text/javascript" src="../../_static/underscore.js"></script>
+ <script type="text/javascript" src="../../_static/doctools.js"></script>
+ <script type="text/javascript" src="../../_static/language_data.js"></script>
+ <link rel="index" title="Index" href="../../genindex.html" />
+ <link rel="search" title="Search" href="../../search.html" />
+
+ <link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+ <h1>Source code for M2Crypto.X509</h1><div class="highlight"><pre>
+<span></span><span class="kn">from</span> <span class="nn">__future__</span> <span class="k">import</span> <span class="n">absolute_import</span>
+
+<span class="sd">&quot;&quot;&quot;M2Crypto wrapper for OpenSSL X509 API.</span>
+
+<span class="sd">Copyright (c) 1999-2004 Ng Pheng Siong. All rights reserved.</span>
+
+<span class="sd">Portions created by Open Source Applications Foundation (OSAF) are</span>
+<span class="sd">Copyright (C) 2004-2007 OSAF. All Rights Reserved.</span>
+<span class="sd">Author: Heikki Toivonen</span>
+<span class="sd">&quot;&quot;&quot;</span>
+
+<span class="kn">import</span> <span class="nn">binascii</span>
+<span class="kn">import</span> <span class="nn">logging</span>
+
+<span class="kn">from</span> <span class="nn">M2Crypto</span> <span class="k">import</span> <span class="n">ASN1</span><span class="p">,</span> <span class="n">BIO</span><span class="p">,</span> <span class="n">EVP</span><span class="p">,</span> <span class="n">m2</span><span class="p">,</span> <span class="n">py27plus</span><span class="p">,</span> <span class="n">six</span> <span class="c1"># noqa</span>
+<span class="k">if</span> <span class="n">py27plus</span><span class="p">:</span>
+ <span class="kn">from</span> <span class="nn">typing</span> <span class="k">import</span> <span class="n">AnyStr</span><span class="p">,</span> <span class="n">Optional</span> <span class="c1"># noqa</span>
+
+<span class="n">FORMAT_DER</span> <span class="o">=</span> <span class="mi">0</span>
+<span class="n">FORMAT_PEM</span> <span class="o">=</span> <span class="mi">1</span>
+
+<span class="n">log</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="vm">__name__</span><span class="p">)</span>
+
+
+<div class="viewcode-block" id="X509Error"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509Error">[docs]</a><span class="k">class</span> <span class="nc">X509Error</span><span class="p">(</span><span class="ne">ValueError</span><span class="p">):</span>
+ <span class="k">pass</span></div>
+
+<span class="n">m2</span><span class="o">.</span><span class="n">x509_init</span><span class="p">(</span><span class="n">X509Error</span><span class="p">)</span>
+
+<span class="n">V_OK</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">X509_V_OK</span> <span class="c1"># type: int</span>
+
+
+<div class="viewcode-block" id="x509_store_default_cb"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.x509_store_default_cb">[docs]</a><span class="k">def</span> <span class="nf">x509_store_default_cb</span><span class="p">(</span><span class="n">ok</span><span class="p">,</span> <span class="n">ctx</span><span class="p">):</span>
+ <span class="c1"># type: (int, X509_Store_Context) -&gt; int</span>
+ <span class="k">return</span> <span class="n">ok</span></div>
+
+
+<div class="viewcode-block" id="new_extension"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.new_extension">[docs]</a><span class="k">def</span> <span class="nf">new_extension</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">value</span><span class="p">,</span> <span class="n">critical</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">_pyfree</span><span class="o">=</span><span class="mi">1</span><span class="p">):</span>
+ <span class="c1"># type: (str, bytes, int, int) -&gt; X509_Extension</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Create new X509_Extension instance.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">if</span> <span class="n">name</span> <span class="o">==</span> <span class="s1">&#39;subjectKeyIdentifier&#39;</span> <span class="ow">and</span> \
+ <span class="n">value</span><span class="o">.</span><span class="n">strip</span><span class="p">(</span><span class="s1">&#39;0123456789abcdefABCDEF:&#39;</span><span class="p">)</span> <span class="ow">is</span> <span class="ow">not</span> <span class="s1">&#39;&#39;</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">&#39;value must be precomputed hash&#39;</span><span class="p">)</span>
+ <span class="n">ctx</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509v3_set_nconf</span><span class="p">()</span>
+ <span class="n">x509_ext_ptr</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509v3_ext_conf</span><span class="p">(</span><span class="kc">None</span><span class="p">,</span> <span class="n">ctx</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">x509_ext_ptr</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="n">X509Error</span><span class="p">(</span>
+ <span class="s2">&quot;Cannot create X509_Extension with name &#39;</span><span class="si">%s</span><span class="s2">&#39; and value &#39;</span><span class="si">%s</span><span class="s2">&#39;&quot;</span> <span class="o">%</span>
+ <span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">value</span><span class="p">))</span>
+ <span class="n">x509_ext</span> <span class="o">=</span> <span class="n">X509_Extension</span><span class="p">(</span><span class="n">x509_ext_ptr</span><span class="p">,</span> <span class="n">_pyfree</span><span class="p">)</span>
+ <span class="n">x509_ext</span><span class="o">.</span><span class="n">set_critical</span><span class="p">(</span><span class="n">critical</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">x509_ext</span></div>
+
+
+<div class="viewcode-block" id="X509_Extension"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509_Extension">[docs]</a><span class="k">class</span> <span class="nc">X509_Extension</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> X509 Extension</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+
+ <span class="n">m2_x509_extension_free</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_extension_free</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x509_ext_ptr</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">_pyfree</span><span class="o">=</span><span class="mi">1</span><span class="p">):</span>
+ <span class="c1"># type: (Optional[bytes], int) -&gt; None</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">x509_ext</span> <span class="o">=</span> <span class="n">x509_ext_ptr</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_pyfree</span> <span class="o">=</span> <span class="n">_pyfree</span>
+
+ <span class="k">def</span> <span class="nf">__del__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;_pyfree&#39;</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">x509_ext</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">m2_x509_extension_free</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509_ext</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">_ptr</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; bytes</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">x509_ext</span>
+
+<div class="viewcode-block" id="X509_Extension.set_critical"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509_Extension.set_critical">[docs]</a> <span class="k">def</span> <span class="nf">set_critical</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">critical</span><span class="o">=</span><span class="mi">1</span><span class="p">):</span>
+ <span class="c1"># type: (int) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Mark this extension critical or noncritical. By default an</span>
+<span class="sd"> extension is not critical.</span>
+
+<span class="sd"> :param critical: Nonzero sets this extension as critical.</span>
+<span class="sd"> Calling this method without arguments will</span>
+<span class="sd"> set this extension to critical.</span>
+<span class="sd"> :return: 1 for success, 0 for failure</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_extension_set_critical</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509_ext</span><span class="p">,</span> <span class="n">critical</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="X509_Extension.get_critical"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509_Extension.get_critical">[docs]</a> <span class="k">def</span> <span class="nf">get_critical</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Return whether or not this is a critical extension.</span>
+
+<span class="sd"> :return: Nonzero if this is a critical extension.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_extension_get_critical</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509_ext</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="X509_Extension.get_name"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509_Extension.get_name">[docs]</a> <span class="k">def</span> <span class="nf">get_name</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; str</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Get the extension name, for example &#39;subjectAltName&#39;.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">six</span><span class="o">.</span><span class="n">ensure_text</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">x509_extension_get_name</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509_ext</span><span class="p">))</span></div>
+
+<div class="viewcode-block" id="X509_Extension.get_value"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509_Extension.get_value">[docs]</a> <span class="k">def</span> <span class="nf">get_value</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">flag</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">indent</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
+ <span class="c1"># type: (int, int) -&gt; str</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Get the extension value, for example &#39;DNS:www.example.com&#39;.</span>
+
+<span class="sd"> :param flag: Flag to control what and how to print.</span>
+<span class="sd"> :param indent: How many spaces to print before actual value.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">buf</span> <span class="o">=</span> <span class="n">BIO</span><span class="o">.</span><span class="n">MemoryBuffer</span><span class="p">()</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">x509_ext_print</span><span class="p">(</span><span class="n">buf</span><span class="o">.</span><span class="n">bio_ptr</span><span class="p">(),</span> <span class="bp">self</span><span class="o">.</span><span class="n">x509_ext</span><span class="p">,</span> <span class="n">flag</span><span class="p">,</span> <span class="n">indent</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">six</span><span class="o">.</span><span class="n">ensure_text</span><span class="p">(</span><span class="n">buf</span><span class="o">.</span><span class="n">read_all</span><span class="p">())</span></div></div>
+
+
+<div class="viewcode-block" id="X509_Extension_Stack"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509_Extension_Stack">[docs]</a><span class="k">class</span> <span class="nc">X509_Extension_Stack</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> X509 Extension Stack</span>
+
+<span class="sd"> :warning: Do not modify the underlying OpenSSL stack</span>
+<span class="sd"> except through this interface, or use any OpenSSL</span>
+<span class="sd"> functions that do so indirectly. Doing so will get the</span>
+<span class="sd"> OpenSSL stack and the internal pystack of this class out</span>
+<span class="sd"> of sync, leading to python memory leaks, exceptions or</span>
+<span class="sd"> even python crashes!</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+
+ <span class="n">m2_sk_x509_extension_free</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">sk_x509_extension_free</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">stack</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">_pyfree</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
+ <span class="c1"># type: (Optional[bytes], int) -&gt; None</span>
+ <span class="k">if</span> <span class="n">stack</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">stack</span> <span class="o">=</span> <span class="n">stack</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_pyfree</span> <span class="o">=</span> <span class="n">_pyfree</span>
+ <span class="n">num</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">sk_x509_extension_num</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">stack</span><span class="p">)</span>
+ <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">num</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">pystack</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">X509_Extension</span><span class="p">(</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">sk_x509_extension_value</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">stack</span><span class="p">,</span> <span class="n">i</span><span class="p">),</span>
+ <span class="n">_pyfree</span><span class="o">=</span><span class="n">_pyfree</span><span class="p">))</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">stack</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">sk_x509_extension_new_null</span><span class="p">()</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_pyfree</span> <span class="o">=</span> <span class="mi">1</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">pystack</span> <span class="o">=</span> <span class="p">[]</span> <span class="c1"># This must be kept in sync with self.stack</span>
+
+ <span class="k">def</span> <span class="nf">__del__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="c1"># see BIO.py - unbalanced __init__ / __del__</span>
+ <span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;_pyfree&#39;</span><span class="p">,</span> <span class="mi">0</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">m2_sk_x509_extension_free</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">stack</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">__len__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">sk_x509_extension_num</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">stack</span><span class="p">)</span> <span class="o">==</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">pystack</span><span class="p">)</span>
+ <span class="k">return</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">pystack</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">__getitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">idx</span><span class="p">):</span>
+ <span class="c1"># type: (int) -&gt; X509_Extension</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">pystack</span><span class="p">[</span><span class="n">idx</span><span class="p">]</span>
+
+ <span class="k">def</span> <span class="nf">__iter__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="k">return</span> <span class="nb">iter</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">pystack</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">_ptr</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; bytes</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">stack</span>
+
+<div class="viewcode-block" id="X509_Extension_Stack.push"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509_Extension_Stack.push">[docs]</a> <span class="k">def</span> <span class="nf">push</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x509_ext</span><span class="p">):</span>
+ <span class="c1"># type: (X509_Extension) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Push X509_Extension object onto the stack.</span>
+
+<span class="sd"> :param x509_ext: X509_Extension object to be pushed onto the stack.</span>
+<span class="sd"> :return: The number of extensions on the stack.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">pystack</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">x509_ext</span><span class="p">)</span>
+ <span class="n">ret</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">sk_x509_extension_push</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">stack</span><span class="p">,</span> <span class="n">x509_ext</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span>
+ <span class="k">assert</span> <span class="n">ret</span> <span class="o">==</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">pystack</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">ret</span></div>
+
+<div class="viewcode-block" id="X509_Extension_Stack.pop"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509_Extension_Stack.pop">[docs]</a> <span class="k">def</span> <span class="nf">pop</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; X509_Extension</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Pop X509_Extension object from the stack.</span>
+
+<span class="sd"> :return: X509_Extension popped</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">x509_ext_ptr</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">sk_x509_extension_pop</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">stack</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">x509_ext_ptr</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">pystack</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span>
+ <span class="k">return</span> <span class="kc">None</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">pystack</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span></div></div>
+
+
+<div class="viewcode-block" id="X509_Name_Entry"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509_Name_Entry">[docs]</a><span class="k">class</span> <span class="nc">X509_Name_Entry</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> X509 Name Entry</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+
+ <span class="n">m2_x509_name_entry_free</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_name_entry_free</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x509_name_entry</span><span class="p">,</span> <span class="n">_pyfree</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
+ <span class="c1"># type: (bytes, int) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> :param x509_name_entry: this should be OpenSSL X509_NAME_ENTRY binary</span>
+<span class="sd"> :param _pyfree:</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">x509_name_entry</span> <span class="o">=</span> <span class="n">x509_name_entry</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_pyfree</span> <span class="o">=</span> <span class="n">_pyfree</span>
+
+ <span class="k">def</span> <span class="nf">__del__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;_pyfree&#39;</span><span class="p">,</span> <span class="mi">0</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">m2_x509_name_entry_free</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509_name_entry</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">_ptr</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; bytes</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">x509_name_entry</span>
+
+<div class="viewcode-block" id="X509_Name_Entry.set_object"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509_Name_Entry.set_object">[docs]</a> <span class="k">def</span> <span class="nf">set_object</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">asn1obj</span><span class="p">):</span>
+ <span class="c1"># type: (ASN1.ASN1_Object) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Sets the field name to asn1obj</span>
+
+<span class="sd"> :param asn1obj:</span>
+<span class="sd"> :return: 0 on failure, 1 on success</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_name_entry_set_object</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509_name_entry</span><span class="p">,</span>
+ <span class="n">asn1obj</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span></div>
+
+<div class="viewcode-block" id="X509_Name_Entry.set_data"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509_Name_Entry.set_data">[docs]</a> <span class="k">def</span> <span class="nf">set_data</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="nb">type</span><span class="o">=</span><span class="n">ASN1</span><span class="o">.</span><span class="n">MBSTRING_ASC</span><span class="p">):</span>
+ <span class="c1"># type: (bytes, int) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Sets the field name to asn1obj</span>
+
+<span class="sd"> :param data: data in a binary form to be set</span>
+<span class="sd"> :return: 0 on failure, 1 on success</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_name_entry_set_data</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509_name_entry</span><span class="p">,</span> <span class="nb">type</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="X509_Name_Entry.get_object"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509_Name_Entry.get_object">[docs]</a> <span class="k">def</span> <span class="nf">get_object</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; ASN1.ASN1_Object</span>
+ <span class="k">return</span> <span class="n">ASN1</span><span class="o">.</span><span class="n">ASN1_Object</span><span class="p">(</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">x509_name_entry_get_object</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509_name_entry</span><span class="p">))</span></div>
+
+<div class="viewcode-block" id="X509_Name_Entry.get_data"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509_Name_Entry.get_data">[docs]</a> <span class="k">def</span> <span class="nf">get_data</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; ASN1.ASN1_String</span>
+ <span class="k">return</span> <span class="n">ASN1</span><span class="o">.</span><span class="n">ASN1_String</span><span class="p">(</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">x509_name_entry_get_data</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509_name_entry</span><span class="p">))</span></div>
+
+<div class="viewcode-block" id="X509_Name_Entry.create_by_txt"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509_Name_Entry.create_by_txt">[docs]</a> <span class="k">def</span> <span class="nf">create_by_txt</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">field</span><span class="p">,</span> <span class="nb">type</span><span class="p">,</span> <span class="n">entry</span><span class="p">,</span> <span class="nb">len</span><span class="p">):</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_name_entry_create_by_txt</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509_name_entry</span><span class="o">.</span><span class="n">_ptr</span><span class="p">(),</span>
+ <span class="n">field</span><span class="p">,</span> <span class="nb">type</span><span class="p">,</span> <span class="n">entry</span><span class="p">,</span> <span class="nb">len</span><span class="p">)</span></div></div>
+
+
+<div class="viewcode-block" id="X509_Name"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509_Name">[docs]</a><span class="k">class</span> <span class="nc">X509_Name</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> X509 Name</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+
+ <span class="n">nid</span> <span class="o">=</span> <span class="p">{</span><span class="s1">&#39;C&#39;</span><span class="p">:</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_countryName</span><span class="p">,</span>
+ <span class="s1">&#39;SP&#39;</span><span class="p">:</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_stateOrProvinceName</span><span class="p">,</span>
+ <span class="s1">&#39;ST&#39;</span><span class="p">:</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_stateOrProvinceName</span><span class="p">,</span>
+ <span class="s1">&#39;stateOrProvinceName&#39;</span><span class="p">:</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_stateOrProvinceName</span><span class="p">,</span>
+ <span class="s1">&#39;L&#39;</span><span class="p">:</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_localityName</span><span class="p">,</span>
+ <span class="s1">&#39;localityName&#39;</span><span class="p">:</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_localityName</span><span class="p">,</span>
+ <span class="s1">&#39;O&#39;</span><span class="p">:</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_organizationName</span><span class="p">,</span>
+ <span class="s1">&#39;organizationName&#39;</span><span class="p">:</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_organizationName</span><span class="p">,</span>
+ <span class="s1">&#39;OU&#39;</span><span class="p">:</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_organizationalUnitName</span><span class="p">,</span>
+ <span class="s1">&#39;organizationUnitName&#39;</span><span class="p">:</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_organizationalUnitName</span><span class="p">,</span>
+ <span class="s1">&#39;CN&#39;</span><span class="p">:</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_commonName</span><span class="p">,</span>
+ <span class="s1">&#39;commonName&#39;</span><span class="p">:</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_commonName</span><span class="p">,</span>
+ <span class="s1">&#39;Email&#39;</span><span class="p">:</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_pkcs9_emailAddress</span><span class="p">,</span>
+ <span class="s1">&#39;emailAddress&#39;</span><span class="p">:</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_pkcs9_emailAddress</span><span class="p">,</span>
+ <span class="s1">&#39;serialNumber&#39;</span><span class="p">:</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_serialNumber</span><span class="p">,</span>
+ <span class="s1">&#39;SN&#39;</span><span class="p">:</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_surname</span><span class="p">,</span>
+ <span class="s1">&#39;surname&#39;</span><span class="p">:</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_surname</span><span class="p">,</span>
+ <span class="s1">&#39;GN&#39;</span><span class="p">:</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_givenName</span><span class="p">,</span>
+ <span class="s1">&#39;givenName&#39;</span><span class="p">:</span> <span class="n">m2</span><span class="o">.</span><span class="n">NID_givenName</span>
+ <span class="p">}</span>
+
+ <span class="n">m2_x509_name_free</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_name_free</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x509_name</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">_pyfree</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
+ <span class="c1"># type: (bytes, int) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> :param x509_name: this should be OpenSSL X509_NAME binary</span>
+<span class="sd"> :param _pyfree:</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">if</span> <span class="n">x509_name</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_name_type_check</span><span class="p">(</span><span class="n">x509_name</span><span class="p">),</span> <span class="s2">&quot;&#39;x509_name&#39; type error&quot;</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">x509_name</span> <span class="o">=</span> <span class="n">x509_name</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_pyfree</span> <span class="o">=</span> <span class="n">_pyfree</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">x509_name</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_name_new</span><span class="p">()</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_pyfree</span> <span class="o">=</span> <span class="mi">1</span>
+
+ <span class="k">def</span> <span class="nf">__del__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;_pyfree&#39;</span><span class="p">,</span> <span class="mi">0</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">m2_x509_name_free</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509_name</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; bytes</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_name_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509_name</span><span class="p">),</span> \
+ <span class="s2">&quot;&#39;x509_name&#39; type error&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_name_oneline</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509_name</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">__getattr__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">attr</span><span class="p">):</span>
+ <span class="c1"># type: (str) -&gt; str</span>
+ <span class="k">if</span> <span class="n">attr</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">nid</span><span class="p">:</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_name_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509_name</span><span class="p">),</span> \
+ <span class="s2">&quot;&#39;x509_name&#39; type error&quot;</span>
+ <span class="k">return</span> <span class="n">six</span><span class="o">.</span><span class="n">ensure_text</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">x509_name_by_nid</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509_name</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">nid</span><span class="p">[</span><span class="n">attr</span><span class="p">]))</span>
+
+ <span class="k">if</span> <span class="n">attr</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__dict__</span><span class="p">:</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__dict__</span><span class="p">[</span><span class="n">attr</span><span class="p">]</span>
+
+ <span class="k">raise</span> <span class="ne">AttributeError</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">attr</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">__setattr__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">attr</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
+ <span class="c1"># type: (str, AnyStr) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> :return: 1 for success of 0 if an error occurred.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">if</span> <span class="n">attr</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">nid</span><span class="p">:</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_name_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509_name</span><span class="p">),</span> \
+ <span class="s2">&quot;&#39;x509_name&#39; type error&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_name_set_by_nid</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509_name</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">nid</span><span class="p">[</span><span class="n">attr</span><span class="p">],</span>
+ <span class="n">six</span><span class="o">.</span><span class="n">ensure_binary</span><span class="p">(</span><span class="n">value</span><span class="p">))</span>
+
+ <span class="bp">self</span><span class="o">.</span><span class="vm">__dict__</span><span class="p">[</span><span class="n">attr</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span>
+
+ <span class="k">def</span> <span class="nf">__len__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_name_entry_count</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509_name</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">__getitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">idx</span><span class="p">):</span>
+ <span class="c1"># type: (int) -&gt; X509_Name_Entry</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="mi">0</span> <span class="o">&lt;=</span> <span class="n">idx</span> <span class="o">&lt;</span> <span class="bp">self</span><span class="o">.</span><span class="n">entry_count</span><span class="p">():</span>
+ <span class="k">raise</span> <span class="ne">IndexError</span><span class="p">(</span><span class="s2">&quot;index out of range&quot;</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">X509_Name_Entry</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">x509_name_get_entry</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509_name</span><span class="p">,</span> <span class="n">idx</span><span class="p">))</span>
+
+ <span class="k">def</span> <span class="nf">__iter__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">entry_count</span><span class="p">()):</span>
+ <span class="k">yield</span> <span class="bp">self</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
+
+ <span class="k">def</span> <span class="nf">_ptr</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_name_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509_name</span><span class="p">),</span> \
+ <span class="s2">&quot;&#39;x509_name&#39; type error&quot;</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">x509_name</span>
+
+<div class="viewcode-block" id="X509_Name.add_entry_by_txt"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509_Name.add_entry_by_txt">[docs]</a> <span class="k">def</span> <span class="nf">add_entry_by_txt</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">field</span><span class="p">,</span> <span class="nb">type</span><span class="p">,</span> <span class="n">entry</span><span class="p">,</span> <span class="nb">len</span><span class="p">,</span> <span class="n">loc</span><span class="p">,</span> <span class="nb">set</span><span class="p">):</span>
+ <span class="c1"># entry_type: (str, int, bytes, int, int, int) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Add X509_Name field whose name is identified by its name.</span>
+
+<span class="sd"> :param field: name of the entry</span>
+<span class="sd"> :param type: use MBSTRING_ASC or MBSTRING_UTF8</span>
+<span class="sd"> (or standard ASN1 type like V_ASN1_IA5STRING)</span>
+<span class="sd"> :param entry: value</span>
+<span class="sd"> :param len: buf_len of the entry</span>
+<span class="sd"> (-1 and the length is computed automagically)</span>
+
+<span class="sd"> The ``loc`` and ``set`` parameters determine where a new entry</span>
+<span class="sd"> should be added.</span>
+<span class="sd"> For almost all applications loc can be set to -1 and set to 0.</span>
+<span class="sd"> This adds a new entry to the end of name as a single valued</span>
+<span class="sd"> RelativeDistinguishedName (RDN).</span>
+
+<span class="sd"> :param loc: determines the index where the new entry is</span>
+<span class="sd"> inserted: if it is -1 it is appended.</span>
+<span class="sd"> :param set: determines how the new type is added. If it is zero</span>
+<span class="sd"> a new RDN is created.</span>
+<span class="sd"> If set is -1 or 1 it is added to the previous or next RDN</span>
+<span class="sd"> structure respectively. This will then be a multivalued</span>
+<span class="sd"> RDN: since multivalues RDNs are very seldom used set is</span>
+<span class="sd"> almost always set to zero.</span>
+
+<span class="sd"> :return: 1 for success of 0 if an error occurred.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_name_add_entry_by_txt</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509_name</span><span class="p">,</span>
+ <span class="n">six</span><span class="o">.</span><span class="n">ensure_str</span><span class="p">(</span><span class="n">field</span><span class="p">),</span> <span class="nb">type</span><span class="p">,</span>
+ <span class="n">six</span><span class="o">.</span><span class="n">ensure_str</span><span class="p">(</span><span class="n">entry</span><span class="p">),</span> <span class="nb">len</span><span class="p">,</span> <span class="n">loc</span><span class="p">,</span> <span class="nb">set</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="X509_Name.entry_count"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509_Name.entry_count">[docs]</a> <span class="k">def</span> <span class="nf">entry_count</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_name_entry_count</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509_name</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="X509_Name.get_entries_by_nid"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509_Name.get_entries_by_nid">[docs]</a> <span class="k">def</span> <span class="nf">get_entries_by_nid</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">nid</span><span class="p">):</span>
+ <span class="c1"># type: (int) -&gt; List[X509_Name_Entry]</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Retrieve the next index matching nid.</span>
+
+<span class="sd"> :param nid: name of the entry (as m2.NID* constants)</span>
+
+<span class="sd"> :return: list of X509_Name_Entry items</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">ret</span> <span class="o">=</span> <span class="p">[]</span>
+ <span class="n">lastpos</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span>
+
+ <span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
+ <span class="n">lastpos</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_name_get_index_by_nid</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509_name</span><span class="p">,</span> <span class="n">nid</span><span class="p">,</span>
+ <span class="n">lastpos</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">lastpos</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="p">:</span>
+ <span class="k">break</span>
+
+ <span class="n">ret</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="bp">self</span><span class="p">[</span><span class="n">lastpos</span><span class="p">])</span>
+
+ <span class="k">return</span> <span class="n">ret</span></div>
+
+<div class="viewcode-block" id="X509_Name.as_text"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509_Name.as_text">[docs]</a> <span class="k">def</span> <span class="nf">as_text</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">indent</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">flags</span><span class="o">=</span><span class="n">m2</span><span class="o">.</span><span class="n">XN_FLAG_COMPAT</span><span class="p">):</span>
+ <span class="c1"># type: (int, int) -&gt; str</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> as_text returns the name as a string.</span>
+
+<span class="sd"> :param indent: Each line in multiline format is indented</span>
+<span class="sd"> by this many spaces.</span>
+<span class="sd"> :param flags: Flags that control how the output should be formatted.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_name_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509_name</span><span class="p">),</span> \
+ <span class="s2">&quot;&#39;x509_name&#39; type error&quot;</span>
+ <span class="n">buf</span> <span class="o">=</span> <span class="n">BIO</span><span class="o">.</span><span class="n">MemoryBuffer</span><span class="p">()</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">x509_name_print_ex</span><span class="p">(</span><span class="n">buf</span><span class="o">.</span><span class="n">bio_ptr</span><span class="p">(),</span> <span class="bp">self</span><span class="o">.</span><span class="n">x509_name</span><span class="p">,</span> <span class="n">indent</span><span class="p">,</span> <span class="n">flags</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">six</span><span class="o">.</span><span class="n">ensure_text</span><span class="p">(</span><span class="n">buf</span><span class="o">.</span><span class="n">read_all</span><span class="p">())</span></div>
+
+<div class="viewcode-block" id="X509_Name.as_der"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509_Name.as_der">[docs]</a> <span class="k">def</span> <span class="nf">as_der</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; bytes</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_name_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509_name</span><span class="p">),</span> \
+ <span class="s2">&quot;&#39;x509_name&#39; type error&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_name_get_der</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509_name</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="X509_Name.as_hash"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509_Name.as_hash">[docs]</a> <span class="k">def</span> <span class="nf">as_hash</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_name_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509_name</span><span class="p">),</span> \
+ <span class="s2">&quot;&#39;x509_name&#39; type error&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_name_hash</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509_name</span><span class="p">)</span></div></div>
+
+
+<div class="viewcode-block" id="X509"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509">[docs]</a><span class="k">class</span> <span class="nc">X509</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> X.509 Certificate</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+
+ <span class="n">m2_x509_free</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_free</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x509</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">_pyfree</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
+ <span class="c1"># type: (Optional[bytes], int) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> :param x509: binary representation of</span>
+<span class="sd"> the underlying OpenSSL X509 object.</span>
+<span class="sd"> :param _pyfree:</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">if</span> <span class="n">x509</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_type_check</span><span class="p">(</span><span class="n">x509</span><span class="p">),</span> <span class="s2">&quot;&#39;x509&#39; type error&quot;</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">x509</span> <span class="o">=</span> <span class="n">x509</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_pyfree</span> <span class="o">=</span> <span class="n">_pyfree</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">x509</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_new</span><span class="p">()</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_pyfree</span> <span class="o">=</span> <span class="mi">1</span>
+
+ <span class="k">def</span> <span class="nf">__del__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;_pyfree&#39;</span><span class="p">,</span> <span class="mi">0</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">m2_x509_free</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">_ptr</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; bytes</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">),</span> <span class="s2">&quot;&#39;x509&#39; type error&quot;</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">x509</span>
+
+<div class="viewcode-block" id="X509.as_text"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509.as_text">[docs]</a> <span class="k">def</span> <span class="nf">as_text</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; str</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">),</span> <span class="s2">&quot;&#39;x509&#39; type error&quot;</span>
+ <span class="n">buf</span> <span class="o">=</span> <span class="n">BIO</span><span class="o">.</span><span class="n">MemoryBuffer</span><span class="p">()</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">x509_print</span><span class="p">(</span><span class="n">buf</span><span class="o">.</span><span class="n">bio_ptr</span><span class="p">(),</span> <span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">six</span><span class="o">.</span><span class="n">ensure_text</span><span class="p">(</span><span class="n">buf</span><span class="o">.</span><span class="n">read_all</span><span class="p">())</span></div>
+
+<div class="viewcode-block" id="X509.as_der"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509.as_der">[docs]</a> <span class="k">def</span> <span class="nf">as_der</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; bytes</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">),</span> <span class="s2">&quot;&#39;x509&#39; type error&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">i2d_x509</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="X509.as_pem"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509.as_pem">[docs]</a> <span class="k">def</span> <span class="nf">as_pem</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; bytes</span>
+ <span class="n">buf</span> <span class="o">=</span> <span class="n">BIO</span><span class="o">.</span><span class="n">MemoryBuffer</span><span class="p">()</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">x509_write_pem</span><span class="p">(</span><span class="n">buf</span><span class="o">.</span><span class="n">bio_ptr</span><span class="p">(),</span> <span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">buf</span><span class="o">.</span><span class="n">read_all</span><span class="p">()</span></div>
+
+<div class="viewcode-block" id="X509.save_pem"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509.save_pem">[docs]</a> <span class="k">def</span> <span class="nf">save_pem</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">filename</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> :param filename: name of the file to be loaded</span>
+<span class="sd"> :return: 1 for success or 0 for failure</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">with</span> <span class="n">BIO</span><span class="o">.</span><span class="n">openfile</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="s1">&#39;wb&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">bio</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_write_pem</span><span class="p">(</span><span class="n">bio</span><span class="o">.</span><span class="n">bio_ptr</span><span class="p">(),</span> <span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="X509.save"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509.save">[docs]</a> <span class="k">def</span> <span class="nf">save</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="nb">format</span><span class="o">=</span><span class="n">FORMAT_PEM</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr, int) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Saves X.509 certificate to a file. Default output</span>
+<span class="sd"> format is PEM.</span>
+
+<span class="sd"> :param filename: Name of the file the cert will be saved to.</span>
+
+<span class="sd"> :param format: Controls what output format is used to save the cert.</span>
+<span class="sd"> Either FORMAT_PEM or FORMAT_DER to save in PEM or</span>
+<span class="sd"> DER format. Raises a ValueError if an unknow</span>
+<span class="sd"> format is used.</span>
+
+<span class="sd"> :return: 1 for success or 0 for failure</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">with</span> <span class="n">BIO</span><span class="o">.</span><span class="n">openfile</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="s1">&#39;wb&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">bio</span><span class="p">:</span>
+ <span class="k">if</span> <span class="nb">format</span> <span class="o">==</span> <span class="n">FORMAT_PEM</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_write_pem</span><span class="p">(</span><span class="n">bio</span><span class="o">.</span><span class="n">bio_ptr</span><span class="p">(),</span> <span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">)</span>
+ <span class="k">elif</span> <span class="nb">format</span> <span class="o">==</span> <span class="n">FORMAT_DER</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">i2d_x509_bio</span><span class="p">(</span><span class="n">bio</span><span class="o">.</span><span class="n">bio_ptr</span><span class="p">(),</span> <span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
+ <span class="s2">&quot;Unknown filetype. Must be either FORMAT_PEM or FORMAT_DER&quot;</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="X509.set_version"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509.set_version">[docs]</a> <span class="k">def</span> <span class="nf">set_version</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">version</span><span class="p">):</span>
+ <span class="c1"># type: (int) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Set version of the certificate.</span>
+
+<span class="sd"> :param version: Version number.</span>
+<span class="sd"> :return: Returns 0 on failure.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">),</span> <span class="s2">&quot;&#39;x509&#39; type error&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_set_version</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">,</span> <span class="n">version</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="X509.set_not_before"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509.set_not_before">[docs]</a> <span class="k">def</span> <span class="nf">set_not_before</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">asn1_time</span><span class="p">):</span>
+ <span class="c1"># type: (ASN1.ASN1_TIME) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> :return: 1 on success, 0 on failure</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">),</span> <span class="s2">&quot;&#39;x509&#39; type error&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_set_not_before</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">,</span> <span class="n">asn1_time</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span></div>
+
+<div class="viewcode-block" id="X509.set_not_after"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509.set_not_after">[docs]</a> <span class="k">def</span> <span class="nf">set_not_after</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">asn1_time</span><span class="p">):</span>
+ <span class="c1"># type: (ASN1.ASN1_TIME) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> :return: 1 on success, 0 on failure</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">),</span> <span class="s2">&quot;&#39;x509&#39; type error&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_set_not_after</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">,</span> <span class="n">asn1_time</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span></div>
+
+<div class="viewcode-block" id="X509.set_subject_name"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509.set_subject_name">[docs]</a> <span class="k">def</span> <span class="nf">set_subject_name</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
+ <span class="c1"># type: (X509_Name) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> :return: 1 on success, 0 on failure</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">),</span> <span class="s2">&quot;&#39;x509&#39; type error&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_set_subject_name</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">,</span> <span class="n">name</span><span class="o">.</span><span class="n">x509_name</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="X509.set_issuer_name"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509.set_issuer_name">[docs]</a> <span class="k">def</span> <span class="nf">set_issuer_name</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
+ <span class="c1"># type: (X509_Name) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> :return: 1 on success, 0 on failure</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">),</span> <span class="s2">&quot;&#39;x509&#39; type error&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_set_issuer_name</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">,</span> <span class="n">name</span><span class="o">.</span><span class="n">x509_name</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="X509.get_version"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509.get_version">[docs]</a> <span class="k">def</span> <span class="nf">get_version</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">),</span> <span class="s2">&quot;&#39;x509&#39; type error&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_get_version</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="X509.get_serial_number"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509.get_serial_number">[docs]</a> <span class="k">def</span> <span class="nf">get_serial_number</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; ASN1.ASN1_Integer</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">),</span> <span class="s2">&quot;&#39;x509&#39; type error&quot;</span>
+ <span class="n">asn1_integer</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_get_serial_number</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">asn1_integer_get</span><span class="p">(</span><span class="n">asn1_integer</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="X509.set_serial_number"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509.set_serial_number">[docs]</a> <span class="k">def</span> <span class="nf">set_serial_number</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">serial</span><span class="p">):</span>
+ <span class="c1"># type: (ASN1.ASN1_Integer) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Set serial number.</span>
+
+<span class="sd"> :param serial: Serial number.</span>
+
+<span class="sd"> :return 1 for success and 0 for failure.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">),</span> <span class="s2">&quot;&#39;x509&#39; type error&quot;</span>
+ <span class="c1"># This &quot;magically&quot; changes serial since asn1_integer</span>
+ <span class="c1"># is C pointer to x509&#39;s internal serial number.</span>
+ <span class="n">asn1_integer</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_get_serial_number</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">asn1_integer_set</span><span class="p">(</span><span class="n">asn1_integer</span><span class="p">,</span> <span class="n">serial</span><span class="p">)</span></div>
+ <span class="c1"># XXX Or should I do this?</span>
+ <span class="c1"># asn1_integer = m2.asn1_integer_new()</span>
+ <span class="c1"># m2.asn1_integer_set(asn1_integer, serial)</span>
+ <span class="c1"># return m2.x509_set_serial_number(self.x509, asn1_integer)</span>
+
+<div class="viewcode-block" id="X509.get_not_before"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509.get_not_before">[docs]</a> <span class="k">def</span> <span class="nf">get_not_before</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; ASN1.ASN1_TIME</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">),</span> <span class="s2">&quot;&#39;x509&#39; type error&quot;</span>
+ <span class="k">return</span> <span class="n">ASN1</span><span class="o">.</span><span class="n">ASN1_TIME</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">x509_get_not_before</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">))</span></div>
+
+<div class="viewcode-block" id="X509.get_not_after"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509.get_not_after">[docs]</a> <span class="k">def</span> <span class="nf">get_not_after</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; ASN1.ASN1_TIME</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">),</span> <span class="s2">&quot;&#39;x509&#39; type error&quot;</span>
+ <span class="n">out</span> <span class="o">=</span> <span class="n">ASN1</span><span class="o">.</span><span class="n">ASN1_TIME</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">x509_get_not_after</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">))</span>
+ <span class="k">if</span> <span class="s1">&#39;Bad time value&#39;</span> <span class="ow">in</span> <span class="nb">str</span><span class="p">(</span><span class="n">out</span><span class="p">):</span>
+ <span class="k">raise</span> <span class="n">X509Error</span><span class="p">(</span>
+ <span class="sd">&#39;&#39;&#39;M2Crypto cannot handle dates after year 2050.</span>
+<span class="sd"> See RFC 5280 4.1.2.5 for more information.</span>
+<span class="sd"> &#39;&#39;&#39;</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">out</span></div>
+
+<div class="viewcode-block" id="X509.get_pubkey"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509.get_pubkey">[docs]</a> <span class="k">def</span> <span class="nf">get_pubkey</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; EVP.PKey</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">),</span> <span class="s2">&quot;&#39;x509&#39; type error&quot;</span>
+ <span class="k">return</span> <span class="n">EVP</span><span class="o">.</span><span class="n">PKey</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">x509_get_pubkey</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">),</span> <span class="n">_pyfree</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="X509.set_pubkey"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509.set_pubkey">[docs]</a> <span class="k">def</span> <span class="nf">set_pubkey</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">pkey</span><span class="p">):</span>
+ <span class="c1"># type: (EVP.PKey) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Set the public key for the certificate</span>
+
+<span class="sd"> :param pkey: Public key</span>
+
+<span class="sd"> :return 1 for success and 0 for failure</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">),</span> <span class="s2">&quot;&#39;x509&#39; type error&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_set_pubkey</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">,</span> <span class="n">pkey</span><span class="o">.</span><span class="n">pkey</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="X509.get_issuer"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509.get_issuer">[docs]</a> <span class="k">def</span> <span class="nf">get_issuer</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; X509_Name</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">),</span> <span class="s2">&quot;&#39;x509&#39; type error&quot;</span>
+ <span class="k">return</span> <span class="n">X509_Name</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">x509_get_issuer_name</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">))</span></div>
+
+<div class="viewcode-block" id="X509.set_issuer"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509.set_issuer">[docs]</a> <span class="k">def</span> <span class="nf">set_issuer</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
+ <span class="c1"># type: (X509_Name) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Set issuer name.</span>
+
+<span class="sd"> :param name: subjectName field.</span>
+
+<span class="sd"> :return 1 for success and 0 for failure</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">),</span> <span class="s2">&quot;&#39;x509&#39; type error&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_set_issuer_name</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">,</span> <span class="n">name</span><span class="o">.</span><span class="n">x509_name</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="X509.get_subject"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509.get_subject">[docs]</a> <span class="k">def</span> <span class="nf">get_subject</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; X509_Name</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">),</span> <span class="s2">&quot;&#39;x509&#39; type error&quot;</span>
+ <span class="k">return</span> <span class="n">X509_Name</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">x509_get_subject_name</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">))</span></div>
+
+<div class="viewcode-block" id="X509.set_subject"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509.set_subject">[docs]</a> <span class="k">def</span> <span class="nf">set_subject</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
+ <span class="c1"># type: (X509_Name) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Set subject name.</span>
+
+<span class="sd"> :param name: subjectName field.</span>
+
+<span class="sd"> :return 1 for success and 0 for failure</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">),</span> <span class="s2">&quot;&#39;x509&#39; type error&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_set_subject_name</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">,</span> <span class="n">name</span><span class="o">.</span><span class="n">x509_name</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="X509.add_ext"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509.add_ext">[docs]</a> <span class="k">def</span> <span class="nf">add_ext</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">ext</span><span class="p">):</span>
+ <span class="c1"># type: (X509_Extension) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Add X509 extension to this certificate.</span>
+
+<span class="sd"> :param ext: Extension</span>
+
+<span class="sd"> :return 1 for success and 0 for failure</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">),</span> <span class="s2">&quot;&#39;x509&#39; type error&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_add_ext</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">,</span> <span class="n">ext</span><span class="o">.</span><span class="n">x509_ext</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="X509.get_ext"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509.get_ext">[docs]</a> <span class="k">def</span> <span class="nf">get_ext</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
+ <span class="c1"># type: (str) -&gt; X509_Extension</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Get X509 extension by name.</span>
+
+<span class="sd"> :param name: Name of the extension</span>
+
+<span class="sd"> :return: X509_Extension</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="c1"># Optimizations to reduce attribute accesses</span>
+ <span class="n">m2x509_get_ext</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_get_ext</span>
+ <span class="n">m2x509_extension_get_name</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_extension_get_name</span>
+ <span class="n">x509</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">x509</span>
+
+ <span class="n">name</span> <span class="o">=</span> <span class="n">six</span><span class="o">.</span><span class="n">ensure_binary</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
+ <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">x509_get_ext_count</span><span class="p">(</span><span class="n">x509</span><span class="p">)):</span>
+ <span class="n">ext_ptr</span> <span class="o">=</span> <span class="n">m2x509_get_ext</span><span class="p">(</span><span class="n">x509</span><span class="p">,</span> <span class="n">i</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">m2x509_extension_get_name</span><span class="p">(</span><span class="n">ext_ptr</span><span class="p">)</span> <span class="o">==</span> <span class="n">name</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">X509_Extension</span><span class="p">(</span><span class="n">ext_ptr</span><span class="p">,</span> <span class="n">_pyfree</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
+
+ <span class="k">raise</span> <span class="ne">LookupError</span></div>
+
+<div class="viewcode-block" id="X509.get_ext_at"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509.get_ext_at">[docs]</a> <span class="k">def</span> <span class="nf">get_ext_at</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">index</span><span class="p">):</span>
+ <span class="c1"># type: (int) -&gt; X509_Extension</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Get X509 extension by index.</span>
+
+<span class="sd"> :param index: Name of the extension</span>
+
+<span class="sd"> :return: X509_Extension</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">if</span> <span class="n">index</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="ow">or</span> <span class="n">index</span> <span class="o">&gt;=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_ext_count</span><span class="p">():</span>
+ <span class="k">raise</span> <span class="ne">IndexError</span>
+
+ <span class="k">return</span> <span class="n">X509_Extension</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">x509_get_ext</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">,</span> <span class="n">index</span><span class="p">),</span>
+ <span class="n">_pyfree</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="X509.get_ext_count"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509.get_ext_count">[docs]</a> <span class="k">def</span> <span class="nf">get_ext_count</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Get X509 extension count.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_get_ext_count</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="X509.sign"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509.sign">[docs]</a> <span class="k">def</span> <span class="nf">sign</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">pkey</span><span class="p">,</span> <span class="n">md</span><span class="p">):</span>
+ <span class="c1"># type: (EVP.PKey, str) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Sign the certificate.</span>
+
+<span class="sd"> :param pkey: Public key</span>
+
+<span class="sd"> :param md: Message digest algorithm to use for signing,</span>
+<span class="sd"> for example &#39;sha1&#39;.</span>
+
+<span class="sd"> :return int</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">),</span> <span class="s2">&quot;&#39;x509&#39; type error&quot;</span>
+ <span class="n">mda</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">m2</span><span class="p">,</span> <span class="n">md</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">mda</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">&#39;unknown message digest&#39;</span><span class="p">,</span> <span class="n">md</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_sign</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">,</span> <span class="n">pkey</span><span class="o">.</span><span class="n">pkey</span><span class="p">,</span> <span class="n">mda</span><span class="p">())</span></div>
+
+<div class="viewcode-block" id="X509.verify"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509.verify">[docs]</a> <span class="k">def</span> <span class="nf">verify</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">pkey</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="c1"># type: (Optional[EVP.PKey]) -&gt; int</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_type_check</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">),</span> <span class="s2">&quot;&#39;x509&#39; type error&quot;</span>
+ <span class="k">if</span> <span class="n">pkey</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_verify</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">,</span> <span class="n">pkey</span><span class="o">.</span><span class="n">pkey</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_verify</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_pubkey</span><span class="p">()</span><span class="o">.</span><span class="n">pkey</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="X509.check_ca"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509.check_ca">[docs]</a> <span class="k">def</span> <span class="nf">check_ca</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Check if the certificate is a Certificate Authority (CA) certificate.</span>
+
+<span class="sd"> :return: 0 if the certificate is not CA, nonzero otherwise.</span>
+
+<span class="sd"> :requires: OpenSSL 0.9.8 or newer</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_check_ca</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="X509.check_purpose"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509.check_purpose">[docs]</a> <span class="k">def</span> <span class="nf">check_purpose</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">id</span><span class="p">,</span> <span class="n">ca</span><span class="p">):</span>
+ <span class="c1"># type: (int, int) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Check if the certificate&#39;s purpose matches the asked purpose.</span>
+
+<span class="sd"> :param id: Purpose id. See X509_PURPOSE_* constants.</span>
+
+<span class="sd"> :param ca: 1 if the certificate should be CA, 0 otherwise.</span>
+
+<span class="sd"> :return: 0 if the certificate purpose does not match, nonzero</span>
+<span class="sd"> otherwise.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_check_purpose</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x509</span><span class="p">,</span> <span class="nb">id</span><span class="p">,</span> <span class="n">ca</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="X509.get_fingerprint"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509.get_fingerprint">[docs]</a> <span class="k">def</span> <span class="nf">get_fingerprint</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">md</span><span class="o">=</span><span class="s1">&#39;md5&#39;</span><span class="p">):</span>
+ <span class="c1"># type: (str) -&gt; str</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Get the fingerprint of the certificate.</span>
+
+<span class="sd"> :param md: Message digest algorithm to use.</span>
+
+<span class="sd"> :return: String containing the fingerprint in hex format.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">der</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">as_der</span><span class="p">()</span>
+ <span class="n">md</span> <span class="o">=</span> <span class="n">EVP</span><span class="o">.</span><span class="n">MessageDigest</span><span class="p">(</span><span class="n">md</span><span class="p">)</span>
+ <span class="n">md</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">der</span><span class="p">)</span>
+ <span class="n">digest</span> <span class="o">=</span> <span class="n">md</span><span class="o">.</span><span class="n">final</span><span class="p">()</span>
+ <span class="k">return</span> <span class="n">six</span><span class="o">.</span><span class="n">ensure_text</span><span class="p">(</span><span class="n">binascii</span><span class="o">.</span><span class="n">hexlify</span><span class="p">(</span><span class="n">digest</span><span class="p">)</span><span class="o">.</span><span class="n">upper</span><span class="p">())</span></div></div>
+
+
+<div class="viewcode-block" id="load_cert"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.load_cert">[docs]</a><span class="k">def</span> <span class="nf">load_cert</span><span class="p">(</span><span class="n">file</span><span class="p">,</span> <span class="nb">format</span><span class="o">=</span><span class="n">FORMAT_PEM</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr, int) -&gt; X509</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Load certificate from file.</span>
+
+<span class="sd"> :param file: Name of file containing certificate in either DER or</span>
+<span class="sd"> PEM format.</span>
+
+<span class="sd"> :param format: Describes the format of the file to be loaded,</span>
+<span class="sd"> either PEM or DER.</span>
+
+<span class="sd"> :return: M2Crypto.X509.X509 object.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">with</span> <span class="n">BIO</span><span class="o">.</span><span class="n">openfile</span><span class="p">(</span><span class="n">file</span><span class="p">)</span> <span class="k">as</span> <span class="n">bio</span><span class="p">:</span>
+ <span class="k">if</span> <span class="nb">format</span> <span class="o">==</span> <span class="n">FORMAT_PEM</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">load_cert_bio</span><span class="p">(</span><span class="n">bio</span><span class="p">)</span>
+ <span class="k">elif</span> <span class="nb">format</span> <span class="o">==</span> <span class="n">FORMAT_DER</span><span class="p">:</span>
+ <span class="n">cptr</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">d2i_x509</span><span class="p">(</span><span class="n">bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span>
+ <span class="k">return</span> <span class="n">X509</span><span class="p">(</span><span class="n">cptr</span><span class="p">,</span> <span class="n">_pyfree</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
+ <span class="s2">&quot;Unknown format. Must be either FORMAT_DER or FORMAT_PEM&quot;</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="load_cert_bio"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.load_cert_bio">[docs]</a><span class="k">def</span> <span class="nf">load_cert_bio</span><span class="p">(</span><span class="n">bio</span><span class="p">,</span> <span class="nb">format</span><span class="o">=</span><span class="n">FORMAT_PEM</span><span class="p">):</span>
+ <span class="c1"># type: (BIO.BIO, int) -&gt; X509</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Load certificate from a bio.</span>
+
+<span class="sd"> :param bio: BIO pointing at a certificate in either DER or PEM format.</span>
+
+<span class="sd"> :param format: Describes the format of the cert to be loaded,</span>
+<span class="sd"> either PEM or DER (via constants FORMAT_PEM</span>
+<span class="sd"> and FORMAT_FORMAT_DER)</span>
+
+<span class="sd"> :return: M2Crypto.X509.X509 object.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">if</span> <span class="nb">format</span> <span class="o">==</span> <span class="n">FORMAT_PEM</span><span class="p">:</span>
+ <span class="n">cptr</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_read_pem</span><span class="p">(</span><span class="n">bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span>
+ <span class="k">elif</span> <span class="nb">format</span> <span class="o">==</span> <span class="n">FORMAT_DER</span><span class="p">:</span>
+ <span class="n">cptr</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">d2i_x509</span><span class="p">(</span><span class="n">bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
+ <span class="s2">&quot;Unknown format. Must be either FORMAT_DER or FORMAT_PEM&quot;</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">X509</span><span class="p">(</span><span class="n">cptr</span><span class="p">,</span> <span class="n">_pyfree</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="load_cert_string"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.load_cert_string">[docs]</a><span class="k">def</span> <span class="nf">load_cert_string</span><span class="p">(</span><span class="n">string</span><span class="p">,</span> <span class="nb">format</span><span class="o">=</span><span class="n">FORMAT_PEM</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr, int) -&gt; X509</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Load certificate from a string.</span>
+
+<span class="sd"> :param string: String containing a certificate in either DER or PEM format.</span>
+
+<span class="sd"> :param format: Describes the format of the cert to be loaded,</span>
+<span class="sd"> either PEM or DER (via constants FORMAT_PEM</span>
+<span class="sd"> and FORMAT_FORMAT_DER)</span>
+
+<span class="sd"> :return: M2Crypto.X509.X509 object.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">string</span> <span class="o">=</span> <span class="n">six</span><span class="o">.</span><span class="n">ensure_binary</span><span class="p">(</span><span class="n">string</span><span class="p">)</span>
+ <span class="n">bio</span> <span class="o">=</span> <span class="n">BIO</span><span class="o">.</span><span class="n">MemoryBuffer</span><span class="p">(</span><span class="n">string</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">load_cert_bio</span><span class="p">(</span><span class="n">bio</span><span class="p">,</span> <span class="nb">format</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="load_cert_der_string"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.load_cert_der_string">[docs]</a><span class="k">def</span> <span class="nf">load_cert_der_string</span><span class="p">(</span><span class="n">string</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr) -&gt; X509</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Load certificate from a string.</span>
+
+<span class="sd"> :param string: String containing a certificate in DER format.</span>
+
+<span class="sd"> :return: M2Crypto.X509.X509 object.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">string</span> <span class="o">=</span> <span class="n">six</span><span class="o">.</span><span class="n">ensure_binary</span><span class="p">(</span><span class="n">string</span><span class="p">)</span>
+ <span class="n">bio</span> <span class="o">=</span> <span class="n">BIO</span><span class="o">.</span><span class="n">MemoryBuffer</span><span class="p">(</span><span class="n">string</span><span class="p">)</span>
+ <span class="n">cptr</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">d2i_x509</span><span class="p">(</span><span class="n">bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span>
+ <span class="k">return</span> <span class="n">X509</span><span class="p">(</span><span class="n">cptr</span><span class="p">,</span> <span class="n">_pyfree</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="X509_Store_Context"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509_Store_Context">[docs]</a><span class="k">class</span> <span class="nc">X509_Store_Context</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> X509 Store Context</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+
+ <span class="n">m2_x509_store_ctx_free</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_store_ctx_free</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x509_store_ctx</span><span class="p">,</span> <span class="n">_pyfree</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
+ <span class="c1"># type: (bytes, int) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+
+<span class="sd"> :param x509_store_ctx: binary data for</span>
+<span class="sd"> OpenSSL X509_STORE_CTX type</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">ctx</span> <span class="o">=</span> <span class="n">x509_store_ctx</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_pyfree</span> <span class="o">=</span> <span class="n">_pyfree</span>
+
+ <span class="k">def</span> <span class="nf">__del__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="c1"># see BIO.py - unbalanced __init__ / __del__</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;_pyfree&#39;</span><span class="p">):</span>
+ <span class="k">pass</span> <span class="c1"># print(&quot;OOPS&quot;)</span>
+ <span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pyfree</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">m2_x509_store_ctx_free</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">_ptr</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">ctx</span>
+
+<div class="viewcode-block" id="X509_Store_Context.get_current_cert"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509_Store_Context.get_current_cert">[docs]</a> <span class="k">def</span> <span class="nf">get_current_cert</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; X509</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Get current X.509 certificate.</span>
+
+<span class="sd"> :warning: The returned certificate is NOT refcounted, so you can not</span>
+<span class="sd"> rely on it being valid once the store context goes</span>
+<span class="sd"> away or is modified.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">X509</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">x509_store_ctx_get_current_cert</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">),</span> <span class="n">_pyfree</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="X509_Store_Context.get_error"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509_Store_Context.get_error">[docs]</a> <span class="k">def</span> <span class="nf">get_error</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Get error code.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_store_ctx_get_error</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="X509_Store_Context.get_error_depth"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509_Store_Context.get_error_depth">[docs]</a> <span class="k">def</span> <span class="nf">get_error_depth</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Get error depth.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_store_ctx_get_error_depth</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="X509_Store_Context.get1_chain"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509_Store_Context.get1_chain">[docs]</a> <span class="k">def</span> <span class="nf">get1_chain</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; X509_Stack</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Get certificate chain.</span>
+
+<span class="sd"> :return: Reference counted (i.e. safe to use even after the store</span>
+<span class="sd"> context goes away) stack of certificates in the chain.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">X509_Stack</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">x509_store_ctx_get1_chain</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">),</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span></div></div>
+
+
+<div class="viewcode-block" id="X509_Store"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509_Store">[docs]</a><span class="k">class</span> <span class="nc">X509_Store</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> X509 Store</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+
+ <span class="n">m2_x509_store_free</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_store_free</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">store</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">_pyfree</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
+ <span class="c1"># type: (Optional[bytes], int) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> :param store: binary data for OpenSSL X509_STORE_CTX type.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">if</span> <span class="n">store</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">store</span> <span class="o">=</span> <span class="n">store</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_pyfree</span> <span class="o">=</span> <span class="n">_pyfree</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">store</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_store_new</span><span class="p">()</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_pyfree</span> <span class="o">=</span> <span class="mi">1</span>
+
+ <span class="k">def</span> <span class="nf">__del__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;_pyfree&#39;</span><span class="p">,</span> <span class="mi">0</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">m2_x509_store_free</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">store</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">_ptr</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">store</span>
+
+<div class="viewcode-block" id="X509_Store.load_info"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509_Store.load_info">[docs]</a> <span class="k">def</span> <span class="nf">load_info</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">file</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> :param file: filename</span>
+
+<span class="sd"> :return: 1 on success, 0 on failure</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">ret</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_store_load_locations</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">store</span><span class="p">,</span> <span class="n">file</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">ret</span></div>
+
+ <span class="n">load_locations</span> <span class="o">=</span> <span class="n">load_info</span>
+
+<div class="viewcode-block" id="X509_Store.add_x509"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509_Store.add_x509">[docs]</a> <span class="k">def</span> <span class="nf">add_x509</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x509</span><span class="p">):</span>
+ <span class="c1"># type: (X509) -&gt; int</span>
+ <span class="k">assert</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">x509</span><span class="p">,</span> <span class="n">X509</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_store_add_cert</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">store</span><span class="p">,</span> <span class="n">x509</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span></div>
+
+<div class="viewcode-block" id="X509_Store.set_verify_cb"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509_Store.set_verify_cb">[docs]</a> <span class="k">def</span> <span class="nf">set_verify_cb</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">callback</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="c1"># type: (Optional[callable]) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Set callback which will be called when the store is verified.</span>
+<span class="sd"> Wrapper over OpenSSL X509_STORE_set_verify_cb().</span>
+
+<span class="sd"> :param callback: Callable to specify verification options.</span>
+<span class="sd"> Type of the callable must be:</span>
+<span class="sd"> (int, X509_Store_Context) -&gt; int.</span>
+<span class="sd"> If None: set the standard options.</span>
+
+<span class="sd"> :note: compile-time or run-time errors in the callback would result</span>
+<span class="sd"> in mysterious errors during verification, which could be hard</span>
+<span class="sd"> to trace.</span>
+
+<span class="sd"> :note: Python exceptions raised in callbacks do not propagate to</span>
+<span class="sd"> verify() call.</span>
+
+<span class="sd"> :return: None</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">if</span> <span class="n">callback</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">set_verify_cb</span><span class="p">(</span><span class="n">x509_store_default_cb</span><span class="p">)</span>
+
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">callable</span><span class="p">(</span><span class="n">callback</span><span class="p">):</span>
+ <span class="k">raise</span> <span class="n">X509Error</span><span class="p">(</span><span class="s2">&quot;set_verify(): callback is not callable&quot;</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_store_set_verify_cb</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">store</span><span class="p">,</span> <span class="n">callback</span><span class="p">)</span></div>
+
+ <span class="n">add_cert</span> <span class="o">=</span> <span class="n">add_x509</span></div>
+
+
+<div class="viewcode-block" id="X509_Stack"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509_Stack">[docs]</a><span class="k">class</span> <span class="nc">X509_Stack</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> X509 Stack</span>
+
+<span class="sd"> :warning: Do not modify the underlying OpenSSL stack</span>
+<span class="sd"> except through this interface, or use any OpenSSL</span>
+<span class="sd"> functions that do so indirectly. Doing so will get the</span>
+<span class="sd"> OpenSSL stack and the internal pystack of this class out</span>
+<span class="sd"> of sync, leading to python memory leaks, exceptions or</span>
+<span class="sd"> even python crashes!</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+
+ <span class="n">m2_sk_x509_free</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">sk_x509_free</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">stack</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">_pyfree</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">_pyfree_x509</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
+ <span class="c1"># type: (bytes, int, int) -&gt; None</span>
+ <span class="k">if</span> <span class="n">stack</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">stack</span> <span class="o">=</span> <span class="n">stack</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_pyfree</span> <span class="o">=</span> <span class="n">_pyfree</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">pystack</span> <span class="o">=</span> <span class="p">[]</span> <span class="c1"># This must be kept in sync with self.stack</span>
+ <span class="n">num</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">sk_x509_num</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">stack</span><span class="p">)</span>
+ <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">num</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">pystack</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">X509</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">sk_x509_value</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">stack</span><span class="p">,</span> <span class="n">i</span><span class="p">),</span>
+ <span class="n">_pyfree</span><span class="o">=</span><span class="n">_pyfree_x509</span><span class="p">))</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">stack</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">sk_x509_new_null</span><span class="p">()</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_pyfree</span> <span class="o">=</span> <span class="mi">1</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">pystack</span> <span class="o">=</span> <span class="p">[]</span> <span class="c1"># This must be kept in sync with self.stack</span>
+
+ <span class="k">def</span> <span class="nf">__del__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;_pyfree&#39;</span><span class="p">,</span> <span class="mi">0</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">m2_sk_x509_free</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">stack</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">__len__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="k">assert</span> <span class="n">m2</span><span class="o">.</span><span class="n">sk_x509_num</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">stack</span><span class="p">)</span> <span class="o">==</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">pystack</span><span class="p">)</span>
+ <span class="k">return</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">pystack</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">__getitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">idx</span><span class="p">):</span>
+ <span class="c1"># type: (int) -&gt; X509</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">pystack</span><span class="p">[</span><span class="n">idx</span><span class="p">]</span>
+
+ <span class="k">def</span> <span class="nf">__iter__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="k">return</span> <span class="nb">iter</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">pystack</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">_ptr</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">stack</span>
+
+<div class="viewcode-block" id="X509_Stack.push"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509_Stack.push">[docs]</a> <span class="k">def</span> <span class="nf">push</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x509</span><span class="p">):</span>
+ <span class="c1"># type: (X509) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> push an X509 certificate onto the stack.</span>
+
+<span class="sd"> :param x509: X509 object.</span>
+
+<span class="sd"> :return: The number of X509 objects currently on the stack.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">assert</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">x509</span><span class="p">,</span> <span class="n">X509</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">pystack</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">x509</span><span class="p">)</span>
+ <span class="n">ret</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">sk_x509_push</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">stack</span><span class="p">,</span> <span class="n">x509</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span>
+ <span class="k">assert</span> <span class="n">ret</span> <span class="o">==</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">pystack</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">ret</span></div>
+
+<div class="viewcode-block" id="X509_Stack.pop"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509_Stack.pop">[docs]</a> <span class="k">def</span> <span class="nf">pop</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; X509</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> pop a certificate from the stack.</span>
+
+<span class="sd"> :return: X509 object that was popped, or None if there is</span>
+<span class="sd"> nothing to pop.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">x509_ptr</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">sk_x509_pop</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">stack</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">x509_ptr</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">pystack</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span>
+ <span class="k">return</span> <span class="kc">None</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">pystack</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span></div>
+
+<div class="viewcode-block" id="X509_Stack.as_der"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.X509_Stack.as_der">[docs]</a> <span class="k">def</span> <span class="nf">as_der</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; bytes</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Return the stack as a DER encoded string</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">get_der_encoding_stack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">stack</span><span class="p">)</span></div></div>
+
+
+<div class="viewcode-block" id="new_stack_from_der"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.new_stack_from_der">[docs]</a><span class="k">def</span> <span class="nf">new_stack_from_der</span><span class="p">(</span><span class="n">der_string</span><span class="p">):</span>
+ <span class="c1"># type: (bytes) -&gt; X509_Stack</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Create a new X509_Stack from DER string.</span>
+
+<span class="sd"> :return: X509_Stack</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">der_string</span> <span class="o">=</span> <span class="n">six</span><span class="o">.</span><span class="n">ensure_binary</span><span class="p">(</span><span class="n">der_string</span><span class="p">)</span>
+ <span class="n">stack_ptr</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">make_stack_from_der_sequence</span><span class="p">(</span><span class="n">der_string</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">X509_Stack</span><span class="p">(</span><span class="n">stack_ptr</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="Request"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.Request">[docs]</a><span class="k">class</span> <span class="nc">Request</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> X509 Certificate Request.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+
+ <span class="n">m2_x509_req_free</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_req_free</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">req</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">_pyfree</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
+ <span class="c1"># type: (Optional[int], int) -&gt; None</span>
+ <span class="k">if</span> <span class="n">req</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">req</span> <span class="o">=</span> <span class="n">req</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_pyfree</span> <span class="o">=</span> <span class="n">_pyfree</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">req</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_req_new</span><span class="p">()</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">x509_req_set_version</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">req</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_pyfree</span> <span class="o">=</span> <span class="mi">1</span>
+
+ <span class="k">def</span> <span class="nf">__del__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;_pyfree&#39;</span><span class="p">,</span> <span class="mi">0</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">m2_x509_req_free</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">req</span><span class="p">)</span>
+
+<div class="viewcode-block" id="Request.as_text"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.Request.as_text">[docs]</a> <span class="k">def</span> <span class="nf">as_text</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; str</span>
+ <span class="n">buf</span> <span class="o">=</span> <span class="n">BIO</span><span class="o">.</span><span class="n">MemoryBuffer</span><span class="p">()</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">x509_req_print</span><span class="p">(</span><span class="n">buf</span><span class="o">.</span><span class="n">bio_ptr</span><span class="p">(),</span> <span class="bp">self</span><span class="o">.</span><span class="n">req</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">six</span><span class="o">.</span><span class="n">ensure_text</span><span class="p">(</span><span class="n">buf</span><span class="o">.</span><span class="n">read_all</span><span class="p">())</span></div>
+
+<div class="viewcode-block" id="Request.as_pem"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.Request.as_pem">[docs]</a> <span class="k">def</span> <span class="nf">as_pem</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; bytes</span>
+ <span class="n">buf</span> <span class="o">=</span> <span class="n">BIO</span><span class="o">.</span><span class="n">MemoryBuffer</span><span class="p">()</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">x509_req_write_pem</span><span class="p">(</span><span class="n">buf</span><span class="o">.</span><span class="n">bio_ptr</span><span class="p">(),</span> <span class="bp">self</span><span class="o">.</span><span class="n">req</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">buf</span><span class="o">.</span><span class="n">read_all</span><span class="p">()</span></div>
+
+<div class="viewcode-block" id="Request.as_der"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.Request.as_der">[docs]</a> <span class="k">def</span> <span class="nf">as_der</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; bytes</span>
+ <span class="n">buf</span> <span class="o">=</span> <span class="n">BIO</span><span class="o">.</span><span class="n">MemoryBuffer</span><span class="p">()</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">i2d_x509_req_bio</span><span class="p">(</span><span class="n">buf</span><span class="o">.</span><span class="n">bio_ptr</span><span class="p">(),</span> <span class="bp">self</span><span class="o">.</span><span class="n">req</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">buf</span><span class="o">.</span><span class="n">read_all</span><span class="p">()</span></div>
+
+<div class="viewcode-block" id="Request.save_pem"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.Request.save_pem">[docs]</a> <span class="k">def</span> <span class="nf">save_pem</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">filename</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr) -&gt; int</span>
+ <span class="k">with</span> <span class="n">BIO</span><span class="o">.</span><span class="n">openfile</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="s1">&#39;wb&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">bio</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_req_write_pem</span><span class="p">(</span><span class="n">bio</span><span class="o">.</span><span class="n">bio_ptr</span><span class="p">(),</span> <span class="bp">self</span><span class="o">.</span><span class="n">req</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Request.save"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.Request.save">[docs]</a> <span class="k">def</span> <span class="nf">save</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="nb">format</span><span class="o">=</span><span class="n">FORMAT_PEM</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr, int) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Saves X.509 certificate request to a file. Default output</span>
+<span class="sd"> format is PEM.</span>
+
+<span class="sd"> :param filename: Name of the file the request will be saved to.</span>
+
+<span class="sd"> :param format: Controls what output format is used to save the</span>
+<span class="sd"> request. Either FORMAT_PEM or FORMAT_DER to save</span>
+<span class="sd"> in PEM or DER format. Raises ValueError if an</span>
+<span class="sd"> unknown format is used.</span>
+
+<span class="sd"> :return: 1 for success, 0 for failure.</span>
+<span class="sd"> The error code can be obtained by ERR_get_error.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">with</span> <span class="n">BIO</span><span class="o">.</span><span class="n">openfile</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="s1">&#39;wb&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">bio</span><span class="p">:</span>
+ <span class="k">if</span> <span class="nb">format</span> <span class="o">==</span> <span class="n">FORMAT_PEM</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_req_write_pem</span><span class="p">(</span><span class="n">bio</span><span class="o">.</span><span class="n">bio_ptr</span><span class="p">(),</span> <span class="bp">self</span><span class="o">.</span><span class="n">req</span><span class="p">)</span>
+ <span class="k">elif</span> <span class="nb">format</span> <span class="o">==</span> <span class="n">FORMAT_DER</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">i2d_x509_req_bio</span><span class="p">(</span><span class="n">bio</span><span class="o">.</span><span class="n">bio_ptr</span><span class="p">(),</span> <span class="bp">self</span><span class="o">.</span><span class="n">req</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
+ <span class="s2">&quot;Unknown filetype. Must be either FORMAT_DER or FORMAT_PEM&quot;</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Request.get_pubkey"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.Request.get_pubkey">[docs]</a> <span class="k">def</span> <span class="nf">get_pubkey</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; EVP.PKey</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Get the public key for the request.</span>
+
+<span class="sd"> :return: Public key from the request.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">EVP</span><span class="o">.</span><span class="n">PKey</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">x509_req_get_pubkey</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">req</span><span class="p">),</span> <span class="n">_pyfree</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Request.set_pubkey"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.Request.set_pubkey">[docs]</a> <span class="k">def</span> <span class="nf">set_pubkey</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">pkey</span><span class="p">):</span>
+ <span class="c1"># type: (EVP.PKey) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Set the public key for the request.</span>
+
+<span class="sd"> :param pkey: Public key</span>
+
+<span class="sd"> :return: Return 1 for success and 0 for failure.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_req_set_pubkey</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">req</span><span class="p">,</span> <span class="n">pkey</span><span class="o">.</span><span class="n">pkey</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Request.get_version"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.Request.get_version">[docs]</a> <span class="k">def</span> <span class="nf">get_version</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Get version.</span>
+
+<span class="sd"> :return: Returns version.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_req_get_version</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">req</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Request.set_version"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.Request.set_version">[docs]</a> <span class="k">def</span> <span class="nf">set_version</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">version</span><span class="p">):</span>
+ <span class="c1"># type: (int) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Set version.</span>
+
+<span class="sd"> :param version: Version number.</span>
+<span class="sd"> :return: Returns 0 on failure.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_req_set_version</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">req</span><span class="p">,</span> <span class="n">version</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Request.get_subject"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.Request.get_subject">[docs]</a> <span class="k">def</span> <span class="nf">get_subject</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; X509_Name</span>
+ <span class="k">return</span> <span class="n">X509_Name</span><span class="p">(</span><span class="n">m2</span><span class="o">.</span><span class="n">x509_req_get_subject_name</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">req</span><span class="p">))</span></div>
+
+<div class="viewcode-block" id="Request.set_subject_name"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.Request.set_subject_name">[docs]</a> <span class="k">def</span> <span class="nf">set_subject_name</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
+ <span class="c1"># type: (X509_Name) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Set subject name.</span>
+
+<span class="sd"> :param name: subjectName field.</span>
+<span class="sd"> :return: 1 for success and 0 for failure</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_req_set_subject_name</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">req</span><span class="p">,</span> <span class="n">name</span><span class="o">.</span><span class="n">x509_name</span><span class="p">)</span></div>
+
+ <span class="n">set_subject</span> <span class="o">=</span> <span class="n">set_subject_name</span>
+
+<div class="viewcode-block" id="Request.add_extensions"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.Request.add_extensions">[docs]</a> <span class="k">def</span> <span class="nf">add_extensions</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">ext_stack</span><span class="p">):</span>
+ <span class="c1"># type: (X509_Extension_Stack) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Add X509 extensions to this request.</span>
+
+<span class="sd"> :param ext_stack: Stack of extensions to add.</span>
+<span class="sd"> :return: 1 for success and 0 for failure</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_req_add_extensions</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">req</span><span class="p">,</span> <span class="n">ext_stack</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span></div>
+
+<div class="viewcode-block" id="Request.verify"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.Request.verify">[docs]</a> <span class="k">def</span> <span class="nf">verify</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">pkey</span><span class="p">):</span>
+ <span class="c1"># type: (EVP.PKey) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+
+<span class="sd"> :param pkey: PKey to be verified</span>
+<span class="sd"> :return: 1 for success and 0 for failure</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_req_verify</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">req</span><span class="p">,</span> <span class="n">pkey</span><span class="o">.</span><span class="n">pkey</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="Request.sign"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.Request.sign">[docs]</a> <span class="k">def</span> <span class="nf">sign</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">pkey</span><span class="p">,</span> <span class="n">md</span><span class="p">):</span>
+ <span class="c1"># type: (EVP.PKey, str) -&gt; int</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+
+<span class="sd"> :param pkey: PKey to be signed</span>
+<span class="sd"> :param md: used algorigthm</span>
+<span class="sd"> :return: 1 for success and 0 for failure</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">mda</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">m2</span><span class="p">,</span> <span class="n">md</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">mda</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">&#39;unknown message digest&#39;</span><span class="p">,</span> <span class="n">md</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_req_sign</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">req</span><span class="p">,</span> <span class="n">pkey</span><span class="o">.</span><span class="n">pkey</span><span class="p">,</span> <span class="n">mda</span><span class="p">())</span></div></div>
+
+
+<div class="viewcode-block" id="load_request"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.load_request">[docs]</a><span class="k">def</span> <span class="nf">load_request</span><span class="p">(</span><span class="n">file</span><span class="p">,</span> <span class="nb">format</span><span class="o">=</span><span class="n">FORMAT_PEM</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr, int) -&gt; Request</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Load certificate request from file.</span>
+
+<span class="sd"> :param file: Name of file containing certificate request in</span>
+<span class="sd"> either PEM or DER format.</span>
+<span class="sd"> :param format: Describes the format of the file to be loaded,</span>
+<span class="sd"> either PEM or DER. (using constants FORMAT_PEM</span>
+<span class="sd"> and FORMAT_DER)</span>
+<span class="sd"> :return: Request object.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">with</span> <span class="n">BIO</span><span class="o">.</span><span class="n">openfile</span><span class="p">(</span><span class="n">file</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
+ <span class="k">if</span> <span class="nb">format</span> <span class="o">==</span> <span class="n">FORMAT_PEM</span><span class="p">:</span>
+ <span class="n">cptr</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_req_read_pem</span><span class="p">(</span><span class="n">f</span><span class="o">.</span><span class="n">bio_ptr</span><span class="p">())</span>
+ <span class="k">elif</span> <span class="nb">format</span> <span class="o">==</span> <span class="n">FORMAT_DER</span><span class="p">:</span>
+ <span class="n">cptr</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">d2i_x509_req</span><span class="p">(</span><span class="n">f</span><span class="o">.</span><span class="n">bio_ptr</span><span class="p">())</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
+ <span class="s2">&quot;Unknown filetype. Must be either FORMAT_PEM or FORMAT_DER&quot;</span><span class="p">)</span>
+
+ <span class="k">return</span> <span class="n">Request</span><span class="p">(</span><span class="n">cptr</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="load_request_bio"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.load_request_bio">[docs]</a><span class="k">def</span> <span class="nf">load_request_bio</span><span class="p">(</span><span class="n">bio</span><span class="p">,</span> <span class="nb">format</span><span class="o">=</span><span class="n">FORMAT_PEM</span><span class="p">):</span>
+ <span class="c1"># type: (BIO.BIO, int) -&gt; Request</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Load certificate request from a bio.</span>
+
+<span class="sd"> :param bio: BIO pointing at a certificate request in</span>
+<span class="sd"> either DER or PEM format.</span>
+<span class="sd"> :param format: Describes the format of the request to be loaded,</span>
+<span class="sd"> either PEM or DER. (using constants FORMAT_PEM</span>
+<span class="sd"> and FORMAT_DER)</span>
+<span class="sd"> :return: M2Crypto.X509.Request object.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">if</span> <span class="nb">format</span> <span class="o">==</span> <span class="n">FORMAT_PEM</span><span class="p">:</span>
+ <span class="n">cptr</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_req_read_pem</span><span class="p">(</span><span class="n">bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span>
+ <span class="k">elif</span> <span class="nb">format</span> <span class="o">==</span> <span class="n">FORMAT_DER</span><span class="p">:</span>
+ <span class="n">cptr</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">d2i_x509_req</span><span class="p">(</span><span class="n">bio</span><span class="o">.</span><span class="n">_ptr</span><span class="p">())</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
+ <span class="s2">&quot;Unknown format. Must be either FORMAT_DER or FORMAT_PEM&quot;</span><span class="p">)</span>
+
+ <span class="k">return</span> <span class="n">Request</span><span class="p">(</span><span class="n">cptr</span><span class="p">,</span> <span class="n">_pyfree</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="load_request_string"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.load_request_string">[docs]</a><span class="k">def</span> <span class="nf">load_request_string</span><span class="p">(</span><span class="n">string</span><span class="p">,</span> <span class="nb">format</span><span class="o">=</span><span class="n">FORMAT_PEM</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr, int) -&gt; Request</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Load certificate request from a string.</span>
+
+<span class="sd"> :param string: String containing a certificate request in</span>
+<span class="sd"> either DER or PEM format.</span>
+<span class="sd"> :param format: Describes the format of the request to be loaded,</span>
+<span class="sd"> either PEM or DER. (using constants FORMAT_PEM</span>
+<span class="sd"> and FORMAT_DER)</span>
+
+<span class="sd"> :return: M2Crypto.X509.Request object.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">string</span> <span class="o">=</span> <span class="n">six</span><span class="o">.</span><span class="n">ensure_binary</span><span class="p">(</span><span class="n">string</span><span class="p">)</span>
+ <span class="n">bio</span> <span class="o">=</span> <span class="n">BIO</span><span class="o">.</span><span class="n">MemoryBuffer</span><span class="p">(</span><span class="n">string</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">load_request_bio</span><span class="p">(</span><span class="n">bio</span><span class="p">,</span> <span class="nb">format</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="load_request_der_string"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.load_request_der_string">[docs]</a><span class="k">def</span> <span class="nf">load_request_der_string</span><span class="p">(</span><span class="n">string</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr) -&gt; Request</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Load certificate request from a string.</span>
+
+<span class="sd"> :param string: String containing a certificate request in DER format.</span>
+<span class="sd"> :return: M2Crypto.X509.Request object.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">string</span> <span class="o">=</span> <span class="n">six</span><span class="o">.</span><span class="n">ensure_binary</span><span class="p">(</span><span class="n">string</span><span class="p">)</span>
+ <span class="n">bio</span> <span class="o">=</span> <span class="n">BIO</span><span class="o">.</span><span class="n">MemoryBuffer</span><span class="p">(</span><span class="n">string</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">load_request_bio</span><span class="p">(</span><span class="n">bio</span><span class="p">,</span> <span class="n">FORMAT_DER</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="CRL"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.CRL">[docs]</a><span class="k">class</span> <span class="nc">CRL</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> X509 Certificate Revocation List</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+
+ <span class="n">m2_x509_crl_free</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_crl_free</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">crl</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">_pyfree</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
+ <span class="c1"># type: (Optional[bytes], int) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+
+<span class="sd"> :param crl: binary representation of</span>
+<span class="sd"> the underlying OpenSSL X509_CRL object.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">if</span> <span class="n">crl</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">crl</span> <span class="o">=</span> <span class="n">crl</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_pyfree</span> <span class="o">=</span> <span class="n">_pyfree</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">crl</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_crl_new</span><span class="p">()</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_pyfree</span> <span class="o">=</span> <span class="mi">1</span>
+
+ <span class="k">def</span> <span class="nf">__del__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;_pyfree&#39;</span><span class="p">,</span> <span class="mi">0</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">m2_x509_crl_free</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">crl</span><span class="p">)</span>
+
+<div class="viewcode-block" id="CRL.as_text"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.CRL.as_text">[docs]</a> <span class="k">def</span> <span class="nf">as_text</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; str</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Return CRL in PEM format in a string.</span>
+
+<span class="sd"> :return: String containing the CRL in PEM format.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">buf</span> <span class="o">=</span> <span class="n">BIO</span><span class="o">.</span><span class="n">MemoryBuffer</span><span class="p">()</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">x509_crl_print</span><span class="p">(</span><span class="n">buf</span><span class="o">.</span><span class="n">bio_ptr</span><span class="p">(),</span> <span class="bp">self</span><span class="o">.</span><span class="n">crl</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">six</span><span class="o">.</span><span class="n">ensure_text</span><span class="p">(</span><span class="n">buf</span><span class="o">.</span><span class="n">read_all</span><span class="p">())</span></div></div>
+
+
+<div class="viewcode-block" id="load_crl"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.X509.load_crl">[docs]</a><span class="k">def</span> <span class="nf">load_crl</span><span class="p">(</span><span class="n">file</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr) -&gt; CRL</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Load CRL from file.</span>
+
+<span class="sd"> :param file: Name of file containing CRL in PEM format.</span>
+
+<span class="sd"> :return: M2Crypto.X509.CRL object.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">with</span> <span class="n">BIO</span><span class="o">.</span><span class="n">openfile</span><span class="p">(</span><span class="n">file</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
+ <span class="n">cptr</span> <span class="o">=</span> <span class="n">m2</span><span class="o">.</span><span class="n">x509_crl_read_pem</span><span class="p">(</span><span class="n">f</span><span class="o">.</span><span class="n">bio_ptr</span><span class="p">())</span>
+
+ <span class="k">return</span> <span class="n">CRL</span><span class="p">(</span><span class="n">cptr</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span></div>
+</pre></div>
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="../../index.html">M2Crypto</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="../../M2Crypto.html">M2Crypto Package</a></li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="../../index.html">Documentation overview</a><ul>
+ <li><a href="../index.html">Module code</a><ul>
+ </ul></li>
+ </ul></li>
+</ul>
+</div>
+<div id="searchbox" style="display: none" role="search">
+ <h3>Quick search</h3>
+ <div class="searchformwrapper">
+ <form class="search" action="../../search.html" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ </div>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer">
+ &copy;2017, Matej Cepl <mcepl@cepl.eu>.
+
+ |
+ Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
+ &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
+
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/_modules/M2Crypto/ftpslib.html b/doc/html/_modules/M2Crypto/ftpslib.html
new file mode 100644
index 0000000..b0db673
--- /dev/null
+++ b/doc/html/_modules/M2Crypto/ftpslib.html
@@ -0,0 +1,195 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>M2Crypto.ftpslib &#8212; M2Crypto documentation</title>
+ <link rel="stylesheet" href="../../_static/alabaster.css" type="text/css" />
+ <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../../_static/jquery.js"></script>
+ <script type="text/javascript" src="../../_static/underscore.js"></script>
+ <script type="text/javascript" src="../../_static/doctools.js"></script>
+ <script type="text/javascript" src="../../_static/language_data.js"></script>
+ <link rel="index" title="Index" href="../../genindex.html" />
+ <link rel="search" title="Search" href="../../search.html" />
+
+ <link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+ <h1>Source code for M2Crypto.ftpslib</h1><div class="highlight"><pre>
+<span></span><span class="kn">from</span> <span class="nn">__future__</span> <span class="k">import</span> <span class="n">absolute_import</span>
+
+<span class="sd">&quot;&quot;&quot;M2Crypto client-side FTP/TLS.</span>
+
+<span class="sd">This implementation complies with draft-murray-auth-ftp-ssl-07.txt.</span>
+
+<span class="sd">Example:</span>
+
+<span class="sd">&gt;&gt;&gt; from M2Crypto import ftpslib</span>
+<span class="sd">&gt;&gt;&gt; f = ftpslib.FTP_TLS()</span>
+<span class="sd">&gt;&gt;&gt; f.connect(&#39;&#39;, 9021)</span>
+<span class="sd">&#39;220 spinnaker.dyndns.org M2Crypto (Medusa) FTP/TLS server v0.07 ready.&#39;</span>
+<span class="sd">&gt;&gt;&gt; f.auth_tls()</span>
+<span class="sd">&gt;&gt;&gt; f.set_pasv(0)</span>
+<span class="sd">&gt;&gt;&gt; f.login(&#39;ftp&#39;, &#39;ngps@&#39;)</span>
+<span class="sd">&#39;230 Ok.&#39;</span>
+<span class="sd">&gt;&gt;&gt; f.retrlines(&#39;LIST&#39;)</span>
+<span class="sd">-rw-rw-r-- 1 0 198 2326 Jul 3 1996 apache_pb.gif</span>
+<span class="sd">drwxrwxr-x 7 0 198 1536 Oct 10 2000 manual</span>
+<span class="sd">drwxrwxr-x 2 0 198 512 Oct 31 2000 modpy</span>
+<span class="sd">drwxrwxr-x 2 0 198 512 Oct 31 2000 bobo</span>
+<span class="sd">drwxr-xr-x 2 0 198 14336 May 28 15:54 postgresql</span>
+<span class="sd">drwxr-xr-x 4 100 198 512 May 16 17:19 home</span>
+<span class="sd">drwxr-xr-x 7 100 100 3584 Sep 23 2000 openacs</span>
+<span class="sd">drwxr-xr-x 10 0 0 512 Aug 5 2000 python1.5</span>
+<span class="sd">-rw-r--r-- 1 100 198 326 Jul 29 03:29 index.html</span>
+<span class="sd">drwxr-xr-x 12 0 0 512 May 31 17:08 python2.1</span>
+<span class="sd">&#39;226 Transfer complete&#39;</span>
+<span class="sd">&gt;&gt;&gt; f.quit()</span>
+<span class="sd">&#39;221 Goodbye.&#39;</span>
+<span class="sd">&gt;&gt;&gt;</span>
+
+
+<span class="sd">Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved.&quot;&quot;&quot;</span>
+
+<span class="c1"># We want to import whole stdlib ftplib objects, because our users want</span>
+<span class="c1"># to use them.</span>
+<span class="kn">from</span> <span class="nn">ftplib</span> <span class="k">import</span> <span class="o">*</span> <span class="c1"># noqa</span>
+
+<span class="c1"># M2Crypto</span>
+<span class="kn">from</span> <span class="nn">M2Crypto</span> <span class="k">import</span> <span class="n">SSL</span>
+
+
+<div class="viewcode-block" id="FTP_TLS"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.ftpslib.FTP_TLS">[docs]</a><span class="k">class</span> <span class="nc">FTP_TLS</span><span class="p">(</span><span class="n">FTP</span><span class="p">):</span>
+
+ <span class="sd">&quot;&quot;&quot;Python OO interface to client-side FTP/TLS.&quot;&quot;&quot;</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">host</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">ssl_ctx</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Initialise the client. If &#39;host&#39; is supplied, connect to it.&quot;&quot;&quot;</span>
+ <span class="k">if</span> <span class="n">ssl_ctx</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">ssl_ctx</span> <span class="o">=</span> <span class="n">ssl_ctx</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">ssl_ctx</span> <span class="o">=</span> <span class="n">SSL</span><span class="o">.</span><span class="n">Context</span><span class="p">()</span>
+ <span class="n">FTP</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">host</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">prot</span> <span class="o">=</span> <span class="mi">0</span>
+
+<div class="viewcode-block" id="FTP_TLS.auth_tls"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.ftpslib.FTP_TLS.auth_tls">[docs]</a> <span class="k">def</span> <span class="nf">auth_tls</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Secure the control connection per AUTH TLS, aka AUTH TLS-C.&quot;&quot;&quot;</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">voidcmd</span><span class="p">(</span><span class="s1">&#39;AUTH TLS&#39;</span><span class="p">)</span>
+ <span class="n">s</span> <span class="o">=</span> <span class="n">SSL</span><span class="o">.</span><span class="n">Connection</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl_ctx</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="p">)</span>
+ <span class="n">s</span><span class="o">.</span><span class="n">setup_ssl</span><span class="p">()</span>
+ <span class="n">s</span><span class="o">.</span><span class="n">set_connect_state</span><span class="p">()</span>
+ <span class="n">s</span><span class="o">.</span><span class="n">connect_ssl</span><span class="p">()</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">sock</span> <span class="o">=</span> <span class="n">s</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">file</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="o">.</span><span class="n">makefile</span><span class="p">()</span></div>
+
+<div class="viewcode-block" id="FTP_TLS.auth_ssl"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.ftpslib.FTP_TLS.auth_ssl">[docs]</a> <span class="k">def</span> <span class="nf">auth_ssl</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Secure the control connection per AUTH SSL, aka AUTH TLS-P.&quot;&quot;&quot;</span>
+ <span class="k">raise</span> <span class="ne">NotImplementedError</span></div>
+
+<div class="viewcode-block" id="FTP_TLS.prot_p"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.ftpslib.FTP_TLS.prot_p">[docs]</a> <span class="k">def</span> <span class="nf">prot_p</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Set up secure data connection.&quot;&quot;&quot;</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">voidcmd</span><span class="p">(</span><span class="s1">&#39;PBSZ 0&#39;</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">voidcmd</span><span class="p">(</span><span class="s1">&#39;PROT P&#39;</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">prot</span> <span class="o">=</span> <span class="mi">1</span></div>
+
+<div class="viewcode-block" id="FTP_TLS.prot_c"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.ftpslib.FTP_TLS.prot_c">[docs]</a> <span class="k">def</span> <span class="nf">prot_c</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Set up data connection in the clear.&quot;&quot;&quot;</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">voidcmd</span><span class="p">(</span><span class="s1">&#39;PROT C&#39;</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">prot</span> <span class="o">=</span> <span class="mi">0</span></div>
+
+<div class="viewcode-block" id="FTP_TLS.ntransfercmd"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.ftpslib.FTP_TLS.ntransfercmd">[docs]</a> <span class="k">def</span> <span class="nf">ntransfercmd</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">cmd</span><span class="p">,</span> <span class="n">rest</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Initiate a data transfer.&quot;&quot;&quot;</span>
+ <span class="n">conn</span><span class="p">,</span> <span class="n">size</span> <span class="o">=</span> <span class="n">FTP</span><span class="o">.</span><span class="n">ntransfercmd</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">cmd</span><span class="p">,</span> <span class="n">rest</span><span class="p">)</span>
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">prot</span><span class="p">:</span>
+ <span class="n">conn</span> <span class="o">=</span> <span class="n">SSL</span><span class="o">.</span><span class="n">Connection</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl_ctx</span><span class="p">,</span> <span class="n">conn</span><span class="p">)</span>
+ <span class="n">conn</span><span class="o">.</span><span class="n">setup_ssl</span><span class="p">()</span>
+ <span class="n">conn</span><span class="o">.</span><span class="n">set_connect_state</span><span class="p">()</span>
+ <span class="n">conn</span><span class="o">.</span><span class="n">set_session</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="o">.</span><span class="n">get_session</span><span class="p">())</span>
+ <span class="n">conn</span><span class="o">.</span><span class="n">connect_ssl</span><span class="p">()</span>
+ <span class="k">return</span> <span class="n">conn</span><span class="p">,</span> <span class="n">size</span></div></div>
+</pre></div>
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="../../index.html">M2Crypto</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="../../M2Crypto.html">M2Crypto Package</a></li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="../../index.html">Documentation overview</a><ul>
+ <li><a href="../index.html">Module code</a><ul>
+ </ul></li>
+ </ul></li>
+</ul>
+</div>
+<div id="searchbox" style="display: none" role="search">
+ <h3>Quick search</h3>
+ <div class="searchformwrapper">
+ <form class="search" action="../../search.html" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ </div>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer">
+ &copy;2017, Matej Cepl <mcepl@cepl.eu>.
+
+ |
+ Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
+ &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
+
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/_modules/M2Crypto/httpslib.html b/doc/html/_modules/M2Crypto/httpslib.html
new file mode 100644
index 0000000..93c1cc5
--- /dev/null
+++ b/doc/html/_modules/M2Crypto/httpslib.html
@@ -0,0 +1,373 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>M2Crypto.httpslib &#8212; M2Crypto documentation</title>
+ <link rel="stylesheet" href="../../_static/alabaster.css" type="text/css" />
+ <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../../_static/jquery.js"></script>
+ <script type="text/javascript" src="../../_static/underscore.js"></script>
+ <script type="text/javascript" src="../../_static/doctools.js"></script>
+ <script type="text/javascript" src="../../_static/language_data.js"></script>
+ <link rel="index" title="Index" href="../../genindex.html" />
+ <link rel="search" title="Search" href="../../search.html" />
+
+ <link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+ <h1>Source code for M2Crypto.httpslib</h1><div class="highlight"><pre>
+<span></span><span class="kn">from</span> <span class="nn">__future__</span> <span class="k">import</span> <span class="n">absolute_import</span>
+
+<span class="kn">import</span> <span class="nn">warnings</span>
+
+<span class="sd">&quot;&quot;&quot;M2Crypto support for Python&#39;s httplib.</span>
+
+<span class="sd">Copyright (c) 1999-2004 Ng Pheng Siong. All rights reserved.&quot;&quot;&quot;</span>
+
+<span class="kn">import</span> <span class="nn">base64</span>
+<span class="kn">import</span> <span class="nn">socket</span>
+
+<span class="kn">from</span> <span class="nn">M2Crypto</span> <span class="k">import</span> <span class="n">SSL</span><span class="p">,</span> <span class="n">py27plus</span><span class="p">,</span> <span class="n">six</span>
+<span class="kn">from</span> <span class="nn">M2Crypto.six.moves.urllib_parse</span> <span class="k">import</span> <span class="n">urlsplit</span><span class="p">,</span> <span class="n">urlunsplit</span>
+<span class="kn">from</span> <span class="nn">M2Crypto.six.moves.http_client</span> <span class="k">import</span> <span class="o">*</span> <span class="c1"># noqa</span>
+<span class="c1"># This is not imported with just &#39;*&#39;</span>
+<span class="kn">from</span> <span class="nn">M2Crypto.six.moves.http_client</span> <span class="k">import</span> <span class="n">HTTPS_PORT</span>
+<span class="k">if</span> <span class="n">py27plus</span><span class="p">:</span>
+ <span class="kn">from</span> <span class="nn">typing</span> <span class="k">import</span> <span class="n">Any</span><span class="p">,</span> <span class="n">AnyStr</span><span class="p">,</span> <span class="n">Callable</span><span class="p">,</span> <span class="n">Dict</span><span class="p">,</span> <span class="n">List</span><span class="p">,</span> <span class="n">Optional</span> <span class="c1"># noqa</span>
+
+
+<div class="viewcode-block" id="HTTPSConnection"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.httpslib.HTTPSConnection">[docs]</a><span class="k">class</span> <span class="nc">HTTPSConnection</span><span class="p">(</span><span class="n">HTTPConnection</span><span class="p">):</span>
+
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> This class allows communication via SSL using M2Crypto.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+
+ <span class="n">default_port</span> <span class="o">=</span> <span class="n">HTTPS_PORT</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">host</span><span class="p">,</span> <span class="n">port</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">strict</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">**</span><span class="n">ssl</span><span class="p">):</span>
+ <span class="c1"># type: (str, Optional[int], Optional[bool], **Any) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Represents one transaction with an HTTP server over the SSL</span>
+<span class="sd"> connection.</span>
+
+<span class="sd"> :param host: host name</span>
+<span class="sd"> :param port: port number</span>
+<span class="sd"> :param strict: if switched on, it raises BadStatusLine to be</span>
+<span class="sd"> raised if the status line can&#39;t be parsed as</span>
+<span class="sd"> a valid HTTP/1.0 or 1.1 status line.</span>
+<span class="sd"> :param ssl: dict with all remaining named real parameters of the</span>
+<span class="sd"> function. Specifically, ``ssl_context`` is expected</span>
+<span class="sd"> to be included with SSL.Context; if it is not</span>
+<span class="sd"> default ``&#39;sslv23&#39;`` is substituted).</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">session</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1"># type: bytes</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">host</span> <span class="o">=</span> <span class="n">host</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">port</span> <span class="o">=</span> <span class="n">port</span>
+ <span class="n">keys</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">ssl</span><span class="o">.</span><span class="n">keys</span><span class="p">())</span> <span class="o">-</span> <span class="nb">set</span><span class="p">((</span><span class="s1">&#39;key_file&#39;</span><span class="p">,</span> <span class="s1">&#39;cert_file&#39;</span><span class="p">,</span> <span class="s1">&#39;ssl_context&#39;</span><span class="p">))</span>
+ <span class="k">if</span> <span class="n">keys</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">&#39;unknown keyword argument: </span><span class="si">%s</span><span class="s1">&#39;</span><span class="p">,</span> <span class="n">keys</span><span class="p">)</span>
+ <span class="k">try</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">ssl_ctx</span> <span class="o">=</span> <span class="n">ssl</span><span class="p">[</span><span class="s1">&#39;ssl_context&#39;</span><span class="p">]</span>
+ <span class="k">assert</span> <span class="nb">isinstance</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl_ctx</span><span class="p">,</span> <span class="n">SSL</span><span class="o">.</span><span class="n">Context</span><span class="p">),</span> <span class="bp">self</span><span class="o">.</span><span class="n">ssl_ctx</span>
+ <span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">ssl_ctx</span> <span class="o">=</span> <span class="n">SSL</span><span class="o">.</span><span class="n">Context</span><span class="p">()</span>
+ <span class="n">HTTPConnection</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">host</span><span class="p">,</span> <span class="n">port</span><span class="p">,</span> <span class="n">strict</span><span class="p">)</span>
+
+<div class="viewcode-block" id="HTTPSConnection.connect"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.httpslib.HTTPSConnection.connect">[docs]</a> <span class="k">def</span> <span class="nf">connect</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="n">error</span> <span class="o">=</span> <span class="kc">None</span>
+ <span class="c1"># We ignore the returned sockaddr because SSL.Connection.connect needs</span>
+ <span class="c1"># a host name.</span>
+ <span class="k">for</span> <span class="p">(</span><span class="n">family</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span><span class="p">)</span> <span class="ow">in</span> \
+ <span class="n">socket</span><span class="o">.</span><span class="n">getaddrinfo</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">host</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">port</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span>
+ <span class="n">socket</span><span class="o">.</span><span class="n">SOCK_STREAM</span><span class="p">):</span>
+ <span class="n">sock</span> <span class="o">=</span> <span class="kc">None</span>
+ <span class="k">try</span><span class="p">:</span>
+ <span class="n">sock</span> <span class="o">=</span> <span class="n">SSL</span><span class="o">.</span><span class="n">Connection</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl_ctx</span><span class="p">,</span> <span class="n">family</span><span class="o">=</span><span class="n">family</span><span class="p">)</span>
+
+ <span class="c1"># set SNI server name since we know it at this point</span>
+ <span class="n">sock</span><span class="o">.</span><span class="n">set_tlsext_host_name</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">host</span><span class="p">)</span>
+
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">session</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">sock</span><span class="o">.</span><span class="n">set_session</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">session</span><span class="p">)</span>
+ <span class="n">sock</span><span class="o">.</span><span class="n">connect</span><span class="p">((</span><span class="bp">self</span><span class="o">.</span><span class="n">host</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">port</span><span class="p">))</span>
+
+ <span class="bp">self</span><span class="o">.</span><span class="n">sock</span> <span class="o">=</span> <span class="n">sock</span>
+ <span class="n">sock</span> <span class="o">=</span> <span class="kc">None</span>
+ <span class="k">return</span>
+ <span class="k">except</span> <span class="n">socket</span><span class="o">.</span><span class="n">error</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
+ <span class="c1"># Other exception are probably SSL-related, in that case we</span>
+ <span class="c1"># abort and the exception is forwarded to the caller.</span>
+ <span class="n">error</span> <span class="o">=</span> <span class="n">e</span>
+ <span class="k">finally</span><span class="p">:</span>
+ <span class="k">if</span> <span class="n">sock</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">sock</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
+
+ <span class="k">if</span> <span class="n">error</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">AssertionError</span><span class="p">(</span><span class="s2">&quot;Empty list returned by getaddrinfo&quot;</span><span class="p">)</span>
+ <span class="k">raise</span> <span class="n">error</span></div>
+
+<div class="viewcode-block" id="HTTPSConnection.close"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.httpslib.HTTPSConnection.close">[docs]</a> <span class="k">def</span> <span class="nf">close</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="c1"># This kludges around line 545 of httplib.py,</span>
+ <span class="c1"># which closes the connection in this object;</span>
+ <span class="c1"># the connection remains open in the response</span>
+ <span class="c1"># object.</span>
+ <span class="c1">#</span>
+ <span class="c1"># M2Crypto doesn&#39;t close-here-keep-open-there,</span>
+ <span class="c1"># so, in effect, we don&#39;t close until the whole</span>
+ <span class="c1"># business is over and gc kicks in.</span>
+ <span class="c1">#</span>
+ <span class="c1"># XXX Long-running callers beware leakage.</span>
+ <span class="c1">#</span>
+ <span class="c1"># XXX 05-Jan-2002: This module works with Python 2.2,</span>
+ <span class="c1"># XXX but I&#39;ve not investigated if the above conditions</span>
+ <span class="c1"># XXX remain.</span>
+ <span class="k">pass</span></div>
+
+<div class="viewcode-block" id="HTTPSConnection.get_session"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.httpslib.HTTPSConnection.get_session">[docs]</a> <span class="k">def</span> <span class="nf">get_session</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; SSL.Session.Session</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="o">.</span><span class="n">get_session</span><span class="p">()</span></div>
+
+<div class="viewcode-block" id="HTTPSConnection.set_session"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.httpslib.HTTPSConnection.set_session">[docs]</a> <span class="k">def</span> <span class="nf">set_session</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">session</span><span class="p">):</span>
+ <span class="c1"># type: (SSL.Session.Session) -&gt; None</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">session</span> <span class="o">=</span> <span class="n">session</span></div></div>
+
+
+<div class="viewcode-block" id="ProxyHTTPSConnection"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.httpslib.ProxyHTTPSConnection">[docs]</a><span class="k">class</span> <span class="nc">ProxyHTTPSConnection</span><span class="p">(</span><span class="n">HTTPSConnection</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> An HTTPS Connection that uses a proxy and the CONNECT request.</span>
+
+<span class="sd"> When the connection is initiated, CONNECT is first sent to the proxy (along</span>
+<span class="sd"> with authorization headers, if supplied). If successful, an SSL connection</span>
+<span class="sd"> will be established over the socket through the proxy and to the target</span>
+<span class="sd"> host.</span>
+
+<span class="sd"> Finally, the actual request is sent over the SSL connection tunneling</span>
+<span class="sd"> through the proxy.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+
+ <span class="n">_ports</span> <span class="o">=</span> <span class="p">{</span><span class="s1">&#39;http&#39;</span><span class="p">:</span> <span class="mi">80</span><span class="p">,</span> <span class="s1">&#39;https&#39;</span><span class="p">:</span> <span class="mi">443</span><span class="p">}</span>
+ <span class="n">_AUTH_HEADER</span> <span class="o">=</span> <span class="s2">&quot;Proxy-Authorization&quot;</span>
+ <span class="n">_UA_HEADER</span> <span class="o">=</span> <span class="s2">&quot;User-Agent&quot;</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">host</span><span class="p">,</span> <span class="n">port</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">strict</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">username</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
+ <span class="n">password</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">**</span><span class="n">ssl</span><span class="p">):</span>
+ <span class="c1"># type: (str, Optional[int], Optional[bool], Optional[AnyStr], Optional[AnyStr], **Any) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Create the ProxyHTTPSConnection object.</span>
+
+<span class="sd"> :param host: host name of the proxy server</span>
+<span class="sd"> :param port: port number of the proxy server</span>
+<span class="sd"> :param strict: if switched on, it raises BadStatusLine to be</span>
+<span class="sd"> raised if the status line can&#39;t be parsed as</span>
+<span class="sd"> a valid HTTP/1.0 or 1.1 status line.</span>
+<span class="sd"> :param username: username on the proxy server, when required</span>
+<span class="sd"> Username can be ``str``, but preferred type</span>
+<span class="sd"> is ``bytes``. M2Crypto does some conversion to</span>
+<span class="sd"> ``bytes`` when necessary, but it&#39;s better when</span>
+<span class="sd"> the user of the library does it on its own.</span>
+<span class="sd"> :param password: password on the proxy server, when required</span>
+<span class="sd"> The same as with ``username``, ``str`` is accepted,</span>
+<span class="sd"> but ``bytes`` are preferred.</span>
+<span class="sd"> :param ssl: dict with all remaining named real parameters of the</span>
+<span class="sd"> function. Specifically, ``ssl_context`` is expected</span>
+<span class="sd"> to be included with SSL.Context; if it is not</span>
+<span class="sd"> default ``&#39;sslv23&#39;`` is substituted).</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">HTTPSConnection</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">host</span><span class="p">,</span> <span class="n">port</span><span class="p">,</span> <span class="n">strict</span><span class="p">,</span> <span class="o">**</span><span class="n">ssl</span><span class="p">)</span>
+
+ <span class="bp">self</span><span class="o">.</span><span class="n">_username</span> <span class="o">=</span> <span class="n">username</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;utf8&#39;</span><span class="p">)</span> \
+ <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">username</span><span class="p">,</span> <span class="n">six</span><span class="o">.</span><span class="n">string_types</span><span class="p">)</span> <span class="k">else</span> <span class="n">username</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_password</span> <span class="o">=</span> <span class="n">password</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;utf8&#39;</span><span class="p">)</span> \
+ <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">password</span><span class="p">,</span> <span class="n">six</span><span class="o">.</span><span class="n">string_types</span><span class="p">)</span> <span class="k">else</span> <span class="n">password</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_proxy_auth</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1"># type: str</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_proxy_UA</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1"># type: str</span>
+
+<div class="viewcode-block" id="ProxyHTTPSConnection.putrequest"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.httpslib.ProxyHTTPSConnection.putrequest">[docs]</a> <span class="k">def</span> <span class="nf">putrequest</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">method</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">skip_host</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">skip_accept_encoding</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr, AnyStr, int, int) -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> putrequest is called before connect, so can interpret url and get</span>
+<span class="sd"> real host/port to be used to make CONNECT request to proxy</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">proto</span><span class="p">,</span> <span class="n">netloc</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">query</span><span class="p">,</span> <span class="n">fragment</span> <span class="o">=</span> <span class="n">urlsplit</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">proto</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;unknown URL type: </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">url</span><span class="p">)</span>
+
+ <span class="c1"># get host &amp; port</span>
+ <span class="k">try</span><span class="p">:</span>
+ <span class="n">username_password</span><span class="p">,</span> <span class="n">host_port</span> <span class="o">=</span> <span class="n">netloc</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;@&#39;</span><span class="p">)</span>
+ <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
+ <span class="n">host_port</span> <span class="o">=</span> <span class="n">netloc</span>
+
+ <span class="k">try</span><span class="p">:</span>
+ <span class="n">host</span><span class="p">,</span> <span class="n">port_s</span> <span class="o">=</span> <span class="n">host_port</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;:&#39;</span><span class="p">)</span>
+ <span class="n">port</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">port_s</span><span class="p">)</span>
+ <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
+ <span class="n">host</span> <span class="o">=</span> <span class="n">host_port</span>
+ <span class="c1"># try to get port from proto</span>
+ <span class="k">try</span><span class="p">:</span>
+ <span class="n">port</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_ports</span><span class="p">[</span><span class="n">proto</span><span class="p">]</span>
+ <span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;unknown protocol for: </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">url</span><span class="p">)</span>
+
+ <span class="bp">self</span><span class="o">.</span><span class="n">_real_host</span> <span class="o">=</span> <span class="n">host</span> <span class="c1"># type: str</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_real_port</span> <span class="o">=</span> <span class="n">port</span> <span class="c1"># type: int</span>
+ <span class="n">rest</span> <span class="o">=</span> <span class="n">urlunsplit</span><span class="p">((</span><span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">query</span><span class="p">,</span> <span class="n">fragment</span><span class="p">))</span>
+ <span class="n">HTTPSConnection</span><span class="o">.</span><span class="n">putrequest</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">method</span><span class="p">,</span> <span class="n">rest</span><span class="p">,</span> <span class="n">skip_host</span><span class="p">,</span>
+ <span class="n">skip_accept_encoding</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="ProxyHTTPSConnection.putheader"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.httpslib.ProxyHTTPSConnection.putheader">[docs]</a> <span class="k">def</span> <span class="nf">putheader</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">header</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr, AnyStr) -&gt; None</span>
+ <span class="c1"># Store the auth header if passed in.</span>
+ <span class="k">if</span> <span class="n">header</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">_UA_HEADER</span><span class="o">.</span><span class="n">lower</span><span class="p">():</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_proxy_UA</span> <span class="o">=</span> <span class="n">value</span>
+ <span class="k">if</span> <span class="n">header</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">_AUTH_HEADER</span><span class="o">.</span><span class="n">lower</span><span class="p">():</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_proxy_auth</span> <span class="o">=</span> <span class="n">value</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">HTTPSConnection</span><span class="o">.</span><span class="n">putheader</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">header</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="ProxyHTTPSConnection.endheaders"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.httpslib.ProxyHTTPSConnection.endheaders">[docs]</a> <span class="k">def</span> <span class="nf">endheaders</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
+ <span class="c1"># type: (*Any, **Any) -&gt; None</span>
+ <span class="c1"># We&#39;ve recieved all of hte headers. Use the supplied username</span>
+ <span class="c1"># and password for authorization, possibly overriding the authstring</span>
+ <span class="c1"># supplied in the headers.</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_proxy_auth</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_proxy_auth</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_encode_auth</span><span class="p">()</span>
+
+ <span class="n">HTTPSConnection</span><span class="o">.</span><span class="n">endheaders</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>
+
+<div class="viewcode-block" id="ProxyHTTPSConnection.connect"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.httpslib.ProxyHTTPSConnection.connect">[docs]</a> <span class="k">def</span> <span class="nf">connect</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="n">HTTPConnection</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
+
+ <span class="c1"># send proxy CONNECT request</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="o">.</span><span class="n">sendall</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_get_connect_msg</span><span class="p">())</span>
+ <span class="n">response</span> <span class="o">=</span> <span class="n">HTTPResponse</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="p">)</span>
+ <span class="n">response</span><span class="o">.</span><span class="n">begin</span><span class="p">()</span>
+
+ <span class="n">code</span> <span class="o">=</span> <span class="n">response</span><span class="o">.</span><span class="n">status</span>
+ <span class="k">if</span> <span class="n">code</span> <span class="o">!=</span> <span class="mi">200</span><span class="p">:</span>
+ <span class="c1"># proxy returned and error, abort connection, and raise exception</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
+ <span class="k">raise</span> <span class="n">socket</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;Proxy connection failed: </span><span class="si">%d</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">code</span><span class="p">)</span>
+
+ <span class="bp">self</span><span class="o">.</span><span class="n">_start_ssl</span><span class="p">()</span></div>
+
+ <span class="k">def</span> <span class="nf">_get_connect_msg</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; bytes</span>
+ <span class="sd">&quot;&quot;&quot; Return an HTTP CONNECT request to send to the proxy. &quot;&quot;&quot;</span>
+ <span class="n">msg</span> <span class="o">=</span> <span class="s2">&quot;CONNECT </span><span class="si">%s</span><span class="s2">:</span><span class="si">%d</span><span class="s2"> HTTP/1.1</span><span class="se">\r\n</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_real_host</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_real_port</span><span class="p">)</span>
+ <span class="n">msg</span> <span class="o">=</span> <span class="n">msg</span> <span class="o">+</span> <span class="s2">&quot;Host: </span><span class="si">%s</span><span class="s2">:</span><span class="si">%d</span><span class="se">\r\n</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_real_host</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_real_port</span><span class="p">)</span>
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_proxy_UA</span><span class="p">:</span>
+ <span class="n">msg</span> <span class="o">=</span> <span class="n">msg</span> <span class="o">+</span> <span class="s2">&quot;</span><span class="si">%s</span><span class="s2">: </span><span class="si">%s</span><span class="se">\r\n</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_UA_HEADER</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_proxy_UA</span><span class="p">)</span>
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_proxy_auth</span><span class="p">:</span>
+ <span class="n">msg</span> <span class="o">=</span> <span class="n">msg</span> <span class="o">+</span> <span class="s2">&quot;</span><span class="si">%s</span><span class="s2">: </span><span class="si">%s</span><span class="se">\r\n</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_AUTH_HEADER</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_proxy_auth</span><span class="p">)</span>
+ <span class="n">msg</span> <span class="o">=</span> <span class="n">msg</span> <span class="o">+</span> <span class="s2">&quot;</span><span class="se">\r\n</span><span class="s2">&quot;</span>
+ <span class="k">return</span> <span class="n">six</span><span class="o">.</span><span class="n">ensure_binary</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">_start_ssl</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot; Make this connection&#39;s socket SSL-aware. &quot;&quot;&quot;</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">sock</span> <span class="o">=</span> <span class="n">SSL</span><span class="o">.</span><span class="n">Connection</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl_ctx</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="o">.</span><span class="n">setup_ssl</span><span class="p">()</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="o">.</span><span class="n">set_connect_state</span><span class="p">()</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="o">.</span><span class="n">connect_ssl</span><span class="p">()</span>
+
+ <span class="k">def</span> <span class="nf">_encode_auth</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># type: () -&gt; Optional[bytes]</span>
+ <span class="sd">&quot;&quot;&quot; Encode the username and password for use in the auth header. &quot;&quot;&quot;</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_username</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">_password</span><span class="p">):</span>
+ <span class="k">return</span> <span class="kc">None</span>
+ <span class="c1"># Authenticated proxy</span>
+ <span class="n">userpass</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="si">%s</span><span class="s2">:</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_username</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_password</span><span class="p">)</span>
+ <span class="k">with</span> <span class="n">warnings</span><span class="o">.</span><span class="n">catch_warnings</span><span class="p">():</span>
+ <span class="n">warnings</span><span class="o">.</span><span class="n">simplefilter</span><span class="p">(</span><span class="s2">&quot;ignore&quot;</span><span class="p">,</span> <span class="ne">DeprecationWarning</span><span class="p">)</span>
+ <span class="n">enc_userpass</span> <span class="o">=</span> <span class="n">base64</span><span class="o">.</span><span class="n">encodestring</span><span class="p">(</span><span class="n">userpass</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">six</span><span class="o">.</span><span class="n">ensure_binary</span><span class="p">(</span><span class="s2">&quot;Basic </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">enc_userpass</span><span class="p">)</span></div>
+</pre></div>
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="../../index.html">M2Crypto</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="../../M2Crypto.html">M2Crypto Package</a></li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="../../index.html">Documentation overview</a><ul>
+ <li><a href="../index.html">Module code</a><ul>
+ </ul></li>
+ </ul></li>
+</ul>
+</div>
+<div id="searchbox" style="display: none" role="search">
+ <h3>Quick search</h3>
+ <div class="searchformwrapper">
+ <form class="search" action="../../search.html" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ </div>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer">
+ &copy;2017, Matej Cepl <mcepl@cepl.eu>.
+
+ |
+ Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
+ &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
+
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/_modules/M2Crypto/m2urllib.html b/doc/html/_modules/M2Crypto/m2urllib.html
new file mode 100644
index 0000000..bb1f8cb
--- /dev/null
+++ b/doc/html/_modules/M2Crypto/m2urllib.html
@@ -0,0 +1,225 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>M2Crypto.m2urllib &#8212; M2Crypto documentation</title>
+ <link rel="stylesheet" href="../../_static/alabaster.css" type="text/css" />
+ <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../../_static/jquery.js"></script>
+ <script type="text/javascript" src="../../_static/underscore.js"></script>
+ <script type="text/javascript" src="../../_static/doctools.js"></script>
+ <script type="text/javascript" src="../../_static/language_data.js"></script>
+ <link rel="index" title="Index" href="../../genindex.html" />
+ <link rel="search" title="Search" href="../../search.html" />
+
+ <link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+ <h1>Source code for M2Crypto.m2urllib</h1><div class="highlight"><pre>
+<span></span><span class="kn">from</span> <span class="nn">__future__</span> <span class="k">import</span> <span class="n">absolute_import</span><span class="p">,</span> <span class="n">print_function</span>
+
+<span class="sd">&quot;&quot;&quot;M2Crypto enhancement to Python&#39;s urllib for handling</span>
+<span class="sd">&#39;https&#39; url&#39;s.</span>
+
+<span class="sd">FIXME: it is questionable whether we need this old-style module at all. urllib</span>
+<span class="sd">(not urllib2) is in Python 3 support just as a legacy API.</span>
+
+<span class="sd">Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved.&quot;&quot;&quot;</span>
+
+<span class="kn">import</span> <span class="nn">base64</span>
+<span class="kn">import</span> <span class="nn">warnings</span>
+
+<span class="kn">from</span> <span class="nn">M2Crypto</span> <span class="k">import</span> <span class="n">SSL</span><span class="p">,</span> <span class="n">httpslib</span><span class="p">,</span> <span class="n">six</span><span class="p">,</span> <span class="n">util</span>
+
+<span class="kn">from</span> <span class="nn">M2Crypto.six.moves.urllib_response</span> <span class="k">import</span> <span class="n">addinfourl</span>
+<span class="k">if</span> <span class="n">util</span><span class="o">.</span><span class="n">py27plus</span><span class="p">:</span>
+ <span class="kn">from</span> <span class="nn">typing</span> <span class="k">import</span> <span class="n">AnyStr</span><span class="p">,</span> <span class="n">Optional</span> <span class="c1"># noqa</span>
+
+<span class="c1"># six.moves doesn&#39;t support star imports</span>
+<span class="k">if</span> <span class="n">six</span><span class="o">.</span><span class="n">PY3</span><span class="p">:</span>
+ <span class="kn">from</span> <span class="nn">urllib.request</span> <span class="k">import</span> <span class="o">*</span> <span class="c1"># noqa for other modules to import</span>
+ <span class="kn">from</span> <span class="nn">urllib.parse</span> <span class="k">import</span> <span class="o">*</span> <span class="c1"># noqa for other modules to import</span>
+ <span class="kn">from</span> <span class="nn">urllib.error</span> <span class="k">import</span> <span class="o">*</span> <span class="c1"># noqa for other modules to import</span>
+<span class="k">else</span><span class="p">:</span>
+ <span class="kn">from</span> <span class="nn">urllib</span> <span class="k">import</span> <span class="o">*</span> <span class="c1"># noqa</span>
+
+
+<div class="viewcode-block" id="open_https"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.m2urllib.open_https">[docs]</a><span class="k">def</span> <span class="nf">open_https</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">ssl_context</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="c1"># type: (URLOpener, AnyStr, Optional[bytes], Optional[SSL.Context]) -&gt; addinfourl</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Open URL over the SSL connection.</span>
+
+<span class="sd"> :param url: URL to be opened</span>
+<span class="sd"> :param data: data for the POST request</span>
+<span class="sd"> :param ssl_context: SSL.Context to be used</span>
+<span class="sd"> :return:</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">if</span> <span class="n">six</span><span class="o">.</span><span class="n">PY3</span><span class="p">:</span>
+ <span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span><span class="s1">&#39;URLOpener has been deprecated in Py3k&#39;</span><span class="p">,</span> <span class="ne">DeprecationWarning</span><span class="p">)</span>
+
+ <span class="k">if</span> <span class="n">ssl_context</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">ssl_context</span><span class="p">,</span> <span class="n">SSL</span><span class="o">.</span><span class="n">Context</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">ctx</span> <span class="o">=</span> <span class="n">ssl_context</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">ctx</span> <span class="o">=</span> <span class="n">SSL</span><span class="o">.</span><span class="n">Context</span><span class="p">()</span>
+ <span class="n">user_passwd</span> <span class="o">=</span> <span class="kc">None</span>
+ <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">six</span><span class="o">.</span><span class="n">string_types</span><span class="p">):</span>
+ <span class="k">try</span><span class="p">:</span> <span class="c1"># python 2</span>
+ <span class="c1"># http://pydoc.org/2.5.1/urllib.html</span>
+ <span class="n">host</span><span class="p">,</span> <span class="n">selector</span> <span class="o">=</span> <span class="n">splithost</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">host</span><span class="p">:</span>
+ <span class="n">user_passwd</span><span class="p">,</span> <span class="n">host</span> <span class="o">=</span> <span class="n">splituser</span><span class="p">(</span><span class="n">host</span><span class="p">)</span>
+ <span class="n">host</span> <span class="o">=</span> <span class="n">unquote</span><span class="p">(</span><span class="n">host</span><span class="p">)</span>
+ <span class="n">realhost</span> <span class="o">=</span> <span class="n">host</span>
+ <span class="k">except</span> <span class="ne">NameError</span><span class="p">:</span> <span class="c1"># python 3 has no splithost</span>
+ <span class="c1"># https://docs.python.org/3/library/urllib.parse.html</span>
+ <span class="n">parsed</span> <span class="o">=</span> <span class="n">urlparse</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
+ <span class="n">host</span> <span class="o">=</span> <span class="n">parsed</span><span class="o">.</span><span class="n">hostname</span>
+ <span class="k">if</span> <span class="n">parsed</span><span class="o">.</span><span class="n">port</span><span class="p">:</span>
+ <span class="n">host</span> <span class="o">+=</span> <span class="s2">&quot;:</span><span class="si">{0}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">parsed</span><span class="o">.</span><span class="n">port</span><span class="p">)</span>
+ <span class="n">user_passwd</span> <span class="o">=</span> <span class="n">parsed</span><span class="o">.</span><span class="n">password</span>
+ <span class="k">if</span> <span class="n">parsed</span><span class="o">.</span><span class="n">password</span><span class="p">:</span>
+ <span class="n">user_passwd</span> <span class="o">+=</span> <span class="s2">&quot;:</span><span class="si">{0}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">parsed</span><span class="o">.</span><span class="n">password</span><span class="p">)</span>
+ <span class="n">selector</span> <span class="o">=</span> <span class="n">parsed</span><span class="o">.</span><span class="n">path</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">host</span><span class="p">,</span> <span class="n">selector</span> <span class="o">=</span> <span class="n">url</span>
+ <span class="n">urltype</span><span class="p">,</span> <span class="n">rest</span> <span class="o">=</span> <span class="n">splittype</span><span class="p">(</span><span class="n">selector</span><span class="p">)</span>
+ <span class="n">url</span> <span class="o">=</span> <span class="n">rest</span>
+ <span class="n">user_passwd</span> <span class="o">=</span> <span class="kc">None</span>
+ <span class="k">if</span> <span class="n">urltype</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="o">!=</span> <span class="s1">&#39;http&#39;</span><span class="p">:</span>
+ <span class="n">realhost</span> <span class="o">=</span> <span class="kc">None</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">try</span><span class="p">:</span> <span class="c1"># python 2</span>
+ <span class="n">realhost</span><span class="p">,</span> <span class="n">rest</span> <span class="o">=</span> <span class="n">splithost</span><span class="p">(</span><span class="n">rest</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">realhost</span><span class="p">:</span>
+ <span class="n">user_passwd</span><span class="p">,</span> <span class="n">realhost</span> <span class="o">=</span> <span class="n">splituser</span><span class="p">(</span><span class="n">realhost</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">user_passwd</span><span class="p">:</span>
+ <span class="n">selector</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="si">%s</span><span class="s2">://</span><span class="si">%s%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">urltype</span><span class="p">,</span> <span class="n">realhost</span><span class="p">,</span> <span class="n">rest</span><span class="p">)</span>
+ <span class="k">except</span> <span class="ne">NameError</span><span class="p">:</span> <span class="c1"># python 3 has no splithost</span>
+ <span class="n">parsed</span> <span class="o">=</span> <span class="n">urlparse</span><span class="p">(</span><span class="n">rest</span><span class="p">)</span>
+ <span class="n">host</span> <span class="o">=</span> <span class="n">parsed</span><span class="o">.</span><span class="n">hostname</span>
+ <span class="k">if</span> <span class="n">parsed</span><span class="o">.</span><span class="n">port</span><span class="p">:</span>
+ <span class="n">host</span> <span class="o">+=</span> <span class="s2">&quot;:</span><span class="si">{0}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">parsed</span><span class="o">.</span><span class="n">port</span><span class="p">)</span>
+ <span class="n">user_passwd</span> <span class="o">=</span> <span class="n">parsed</span><span class="o">.</span><span class="n">username</span>
+ <span class="k">if</span> <span class="n">parsed</span><span class="o">.</span><span class="n">password</span><span class="p">:</span>
+ <span class="n">user_passwd</span> <span class="o">+=</span> <span class="s2">&quot;:</span><span class="si">{0}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">parsed</span><span class="o">.</span><span class="n">password</span><span class="p">)</span>
+ <span class="c1"># print(&quot;proxy via http:&quot;, host, selector)</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">host</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">IOError</span><span class="p">(</span><span class="s1">&#39;http error&#39;</span><span class="p">,</span> <span class="s1">&#39;no host given&#39;</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">user_passwd</span><span class="p">:</span>
+ <span class="k">if</span> <span class="n">six</span><span class="o">.</span><span class="n">PY3</span><span class="p">:</span>
+ <span class="n">auth</span> <span class="o">=</span> <span class="n">base64</span><span class="o">.</span><span class="n">encodebytes</span><span class="p">(</span><span class="n">user_passwd</span><span class="p">)</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">auth</span> <span class="o">=</span> <span class="n">base64</span><span class="o">.</span><span class="n">encodestring</span><span class="p">(</span><span class="n">user_passwd</span><span class="p">)</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">auth</span> <span class="o">=</span> <span class="kc">None</span>
+ <span class="c1"># Start here!</span>
+ <span class="n">h</span> <span class="o">=</span> <span class="n">httpslib</span><span class="o">.</span><span class="n">HTTPSConnection</span><span class="p">(</span><span class="n">host</span><span class="o">=</span><span class="n">host</span><span class="p">,</span> <span class="n">ssl_context</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">)</span>
+ <span class="c1"># h.set_debuglevel(1)</span>
+ <span class="c1"># Stop here!</span>
+ <span class="k">if</span> <span class="n">data</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">h</span><span class="o">.</span><span class="n">putrequest</span><span class="p">(</span><span class="s1">&#39;POST&#39;</span><span class="p">,</span> <span class="n">selector</span><span class="p">)</span>
+ <span class="n">h</span><span class="o">.</span><span class="n">putheader</span><span class="p">(</span><span class="s1">&#39;Content-type&#39;</span><span class="p">,</span> <span class="s1">&#39;application/x-www-form-urlencoded&#39;</span><span class="p">)</span>
+ <span class="n">h</span><span class="o">.</span><span class="n">putheader</span><span class="p">(</span><span class="s1">&#39;Content-length&#39;</span><span class="p">,</span> <span class="s1">&#39;</span><span class="si">%d</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="nb">len</span><span class="p">(</span><span class="n">data</span><span class="p">))</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">h</span><span class="o">.</span><span class="n">putrequest</span><span class="p">(</span><span class="s1">&#39;GET&#39;</span><span class="p">,</span> <span class="n">selector</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">auth</span><span class="p">:</span>
+ <span class="n">h</span><span class="o">.</span><span class="n">putheader</span><span class="p">(</span><span class="s1">&#39;Authorization&#39;</span><span class="p">,</span> <span class="s1">&#39;Basic </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">auth</span><span class="p">)</span>
+ <span class="k">for</span> <span class="n">args</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">addheaders</span><span class="p">:</span>
+ <span class="n">h</span><span class="o">.</span><span class="n">putheader</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">)</span> <span class="c1"># for python3 - used to use apply</span>
+ <span class="n">h</span><span class="o">.</span><span class="n">endheaders</span><span class="p">()</span>
+ <span class="k">if</span> <span class="n">data</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">h</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">data</span> <span class="o">+</span> <span class="s1">&#39;</span><span class="se">\r\n</span><span class="s1">&#39;</span><span class="p">)</span>
+ <span class="c1"># Here again!</span>
+ <span class="n">resp</span> <span class="o">=</span> <span class="n">h</span><span class="o">.</span><span class="n">getresponse</span><span class="p">()</span>
+ <span class="n">fp</span> <span class="o">=</span> <span class="n">resp</span><span class="o">.</span><span class="n">fp</span>
+ <span class="k">return</span> <span class="n">addinfourl</span><span class="p">(</span><span class="n">fp</span><span class="p">,</span> <span class="n">resp</span><span class="o">.</span><span class="n">msg</span><span class="p">,</span> <span class="s2">&quot;https:&quot;</span> <span class="o">+</span> <span class="n">url</span><span class="p">)</span></div>
+ <span class="c1"># Stop again.</span>
+
+<span class="c1"># Minor brain surgery.</span>
+<span class="n">URLopener</span><span class="o">.</span><span class="n">open_https</span> <span class="o">=</span> <span class="n">open_https</span>
+</pre></div>
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="../../index.html">M2Crypto</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="../../M2Crypto.html">M2Crypto Package</a></li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="../../index.html">Documentation overview</a><ul>
+ <li><a href="../index.html">Module code</a><ul>
+ </ul></li>
+ </ul></li>
+</ul>
+</div>
+<div id="searchbox" style="display: none" role="search">
+ <h3>Quick search</h3>
+ <div class="searchformwrapper">
+ <form class="search" action="../../search.html" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ </div>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer">
+ &copy;2017, Matej Cepl <mcepl@cepl.eu>.
+
+ |
+ Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
+ &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
+
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/_modules/M2Crypto/m2urllib2.html b/doc/html/_modules/M2Crypto/m2urllib2.html
new file mode 100644
index 0000000..23bf5f2
--- /dev/null
+++ b/doc/html/_modules/M2Crypto/m2urllib2.html
@@ -0,0 +1,290 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>M2Crypto.m2urllib2 &#8212; M2Crypto documentation</title>
+ <link rel="stylesheet" href="../../_static/alabaster.css" type="text/css" />
+ <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../../_static/jquery.js"></script>
+ <script type="text/javascript" src="../../_static/underscore.js"></script>
+ <script type="text/javascript" src="../../_static/doctools.js"></script>
+ <script type="text/javascript" src="../../_static/language_data.js"></script>
+ <link rel="index" title="Index" href="../../genindex.html" />
+ <link rel="search" title="Search" href="../../search.html" />
+
+ <link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+ <h1>Source code for M2Crypto.m2urllib2</h1><div class="highlight"><pre>
+<span></span><span class="kn">from</span> <span class="nn">__future__</span> <span class="k">import</span> <span class="n">absolute_import</span>
+
+<span class="sd">&quot;&quot;&quot;</span>
+<span class="sd">M2Crypto enhancement to Python&#39;s urllib2 for handling</span>
+<span class="sd">&#39;https&#39; url&#39;s.</span>
+
+<span class="sd">Code from urllib2 is Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007</span>
+<span class="sd">Python Software Foundation; All Rights Reserved</span>
+
+<span class="sd">Summary of changes:</span>
+<span class="sd"> - Use an HTTPSProxyConnection if the request is going through a proxy.</span>
+<span class="sd"> - Add the SSL context to the https connection when performing https_open.</span>
+<span class="sd"> - Add the M2Crypto HTTPSHandler when building a default opener.</span>
+<span class="sd">&quot;&quot;&quot;</span>
+
+<span class="kn">import</span> <span class="nn">socket</span>
+
+<span class="kn">from</span> <span class="nn">M2Crypto</span> <span class="k">import</span> <span class="n">SSL</span><span class="p">,</span> <span class="n">httpslib</span><span class="p">,</span> <span class="n">six</span><span class="p">,</span> <span class="n">util</span>
+
+<span class="kn">from</span> <span class="nn">M2Crypto.six.moves.urllib_parse</span> <span class="k">import</span> <span class="n">urldefrag</span><span class="p">,</span> <span class="n">urlparse</span> <span class="k">as</span> <span class="n">url_parse</span>
+<span class="kn">from</span> <span class="nn">M2Crypto.six.moves.urllib_response</span> <span class="k">import</span> <span class="n">addinfourl</span>
+<span class="k">if</span> <span class="n">util</span><span class="o">.</span><span class="n">py27plus</span><span class="p">:</span>
+ <span class="kn">from</span> <span class="nn">typing</span> <span class="k">import</span> <span class="n">List</span><span class="p">,</span> <span class="n">Optional</span> <span class="c1"># noqa</span>
+
+<span class="c1"># six.moves doesn&#39;t support star imports</span>
+<span class="k">if</span> <span class="n">six</span><span class="o">.</span><span class="n">PY3</span><span class="p">:</span>
+ <span class="kn">from</span> <span class="nn">urllib.request</span> <span class="k">import</span> <span class="o">*</span> <span class="c1"># noqa other modules want to import</span>
+ <span class="kn">from</span> <span class="nn">urllib.error</span> <span class="k">import</span> <span class="o">*</span> <span class="c1"># noqa other modules want to import</span>
+<span class="k">else</span><span class="p">:</span>
+ <span class="kn">from</span> <span class="nn">urllib2</span> <span class="k">import</span> <span class="o">*</span> <span class="c1"># noqa</span>
+
+
+<span class="k">try</span><span class="p">:</span>
+ <span class="n">mother_class</span> <span class="o">=</span> <span class="n">socket</span><span class="o">.</span><span class="n">_fileobject</span>
+<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
+ <span class="n">mother_class</span> <span class="o">=</span> <span class="n">socket</span><span class="o">.</span><span class="n">SocketIO</span>
+
+
+<span class="k">class</span> <span class="nc">_closing_fileobject</span><span class="p">(</span><span class="n">mother_class</span><span class="p">):</span> <span class="c1"># noqa</span>
+ <span class="sd">&quot;&quot;&quot;socket._fileobject that propagates self.close() to the socket.</span>
+
+<span class="sd"> Python 2.5 provides this as socket._fileobject(sock, close=True).</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+
+<span class="c1"># for python 3</span>
+<span class="k">try</span><span class="p">:</span>
+ <span class="n">AbstractHTTPHandler</span>
+<span class="k">except</span> <span class="ne">NameError</span><span class="p">:</span>
+ <span class="c1"># somehow this won&#39;t get imported by the import * above</span>
+ <span class="kn">import</span> <span class="nn">urllib.request</span>
+ <span class="n">AbstractHTTPHandler</span> <span class="o">=</span> <span class="n">urllib</span><span class="o">.</span><span class="n">request</span><span class="o">.</span><span class="n">AbstractHTTPHandler</span>
+
+
+<div class="viewcode-block" id="HTTPSHandler"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.m2urllib2.HTTPSHandler">[docs]</a><span class="k">class</span> <span class="nc">HTTPSHandler</span><span class="p">(</span><span class="n">AbstractHTTPHandler</span><span class="p">):</span>
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">ssl_context</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="c1"># type: (SSL.Context) -&gt; None</span>
+ <span class="n">AbstractHTTPHandler</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
+
+ <span class="k">if</span> <span class="n">ssl_context</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">assert</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">ssl_context</span><span class="p">,</span> <span class="n">SSL</span><span class="o">.</span><span class="n">Context</span><span class="p">),</span> <span class="n">ssl_context</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">ctx</span> <span class="o">=</span> <span class="n">ssl_context</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">ctx</span> <span class="o">=</span> <span class="n">SSL</span><span class="o">.</span><span class="n">Context</span><span class="p">()</span>
+
+ <span class="c1"># Copied from urllib2, so we can set the ssl context.</span>
+<div class="viewcode-block" id="HTTPSHandler.https_open"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.m2urllib2.HTTPSHandler.https_open">[docs]</a> <span class="k">def</span> <span class="nf">https_open</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">req</span><span class="p">):</span>
+ <span class="c1"># type: (Request) -&gt; addinfourl</span>
+ <span class="sd">&quot;&quot;&quot;Return an addinfourl object for the request, using http_class.</span>
+
+<span class="sd"> http_class must implement the HTTPConnection API from httplib.</span>
+<span class="sd"> The addinfourl return value is a file-like object. It also</span>
+<span class="sd"> has methods and attributes including:</span>
+
+<span class="sd"> - info(): return a mimetools.Message object for the headers</span>
+
+<span class="sd"> - geturl(): return the original request URL</span>
+
+<span class="sd"> - code: HTTP status code</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="c1"># https://docs.python.org/3.3/library/urllib.request.html#urllib.request.Request.get_host</span>
+ <span class="k">try</span><span class="p">:</span> <span class="c1"># up to python-3.2</span>
+ <span class="n">host</span> <span class="o">=</span> <span class="n">req</span><span class="o">.</span><span class="n">get_host</span><span class="p">()</span>
+ <span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span> <span class="c1"># from python-3.3</span>
+ <span class="n">host</span> <span class="o">=</span> <span class="n">req</span><span class="o">.</span><span class="n">host</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">host</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="n">URLError</span><span class="p">(</span><span class="s1">&#39;no host given&#39;</span><span class="p">)</span>
+
+ <span class="c1"># Our change: Check to see if we&#39;re using a proxy.</span>
+ <span class="c1"># Then create an appropriate ssl-aware connection.</span>
+ <span class="n">full_url</span> <span class="o">=</span> <span class="n">req</span><span class="o">.</span><span class="n">get_full_url</span><span class="p">()</span>
+ <span class="n">target_host</span> <span class="o">=</span> <span class="n">url_parse</span><span class="p">(</span><span class="n">full_url</span><span class="p">)[</span><span class="mi">1</span><span class="p">]</span>
+
+ <span class="k">if</span> <span class="n">target_host</span> <span class="o">!=</span> <span class="n">host</span><span class="p">:</span>
+ <span class="n">request_uri</span> <span class="o">=</span> <span class="n">urldefrag</span><span class="p">(</span><span class="n">full_url</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
+ <span class="n">h</span> <span class="o">=</span> <span class="n">httpslib</span><span class="o">.</span><span class="n">ProxyHTTPSConnection</span><span class="p">(</span><span class="n">host</span><span class="o">=</span><span class="n">host</span><span class="p">,</span> <span class="n">ssl_context</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">try</span><span class="p">:</span> <span class="c1"># up to python-3.2</span>
+ <span class="n">request_uri</span> <span class="o">=</span> <span class="n">req</span><span class="o">.</span><span class="n">get_selector</span><span class="p">()</span>
+ <span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span> <span class="c1"># from python-3.3</span>
+ <span class="n">request_uri</span> <span class="o">=</span> <span class="n">req</span><span class="o">.</span><span class="n">selector</span>
+ <span class="n">h</span> <span class="o">=</span> <span class="n">httpslib</span><span class="o">.</span><span class="n">HTTPSConnection</span><span class="p">(</span><span class="n">host</span><span class="o">=</span><span class="n">host</span><span class="p">,</span> <span class="n">ssl_context</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">ctx</span><span class="p">)</span>
+ <span class="c1"># End our change</span>
+ <span class="n">h</span><span class="o">.</span><span class="n">set_debuglevel</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_debuglevel</span><span class="p">)</span>
+
+ <span class="n">headers</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span><span class="n">req</span><span class="o">.</span><span class="n">headers</span><span class="p">)</span>
+ <span class="n">headers</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">req</span><span class="o">.</span><span class="n">unredirected_hdrs</span><span class="p">)</span>
+ <span class="c1"># We want to make an HTTP/1.1 request, but the addinfourl</span>
+ <span class="c1"># class isn&#39;t prepared to deal with a persistent connection.</span>
+ <span class="c1"># It will try to read all remaining data from the socket,</span>
+ <span class="c1"># which will block while the server waits for the next request.</span>
+ <span class="c1"># So make sure the connection gets closed after the (only)</span>
+ <span class="c1"># request.</span>
+ <span class="n">headers</span><span class="p">[</span><span class="s2">&quot;Connection&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;close&quot;</span>
+ <span class="k">try</span><span class="p">:</span>
+ <span class="n">h</span><span class="o">.</span><span class="n">request</span><span class="p">(</span><span class="n">req</span><span class="o">.</span><span class="n">get_method</span><span class="p">(),</span> <span class="n">request_uri</span><span class="p">,</span> <span class="n">req</span><span class="o">.</span><span class="n">data</span><span class="p">,</span> <span class="n">headers</span><span class="p">)</span>
+ <span class="n">r</span> <span class="o">=</span> <span class="n">h</span><span class="o">.</span><span class="n">getresponse</span><span class="p">()</span>
+ <span class="k">except</span> <span class="n">socket</span><span class="o">.</span><span class="n">error</span> <span class="k">as</span> <span class="n">err</span><span class="p">:</span> <span class="c1"># XXX what error?</span>
+ <span class="k">raise</span> <span class="n">URLError</span><span class="p">(</span><span class="n">err</span><span class="p">)</span>
+
+ <span class="c1"># Pick apart the HTTPResponse object to get the addinfourl</span>
+ <span class="c1"># object initialized properly.</span>
+
+ <span class="c1"># Wrap the HTTPResponse object in socket&#39;s file object adapter</span>
+ <span class="c1"># for Windows. That adapter calls recv(), so delegate recv()</span>
+ <span class="c1"># to read(). This weird wrapping allows the returned object to</span>
+ <span class="c1"># have readline() and readlines() methods.</span>
+ <span class="n">r</span><span class="o">.</span><span class="n">recv</span> <span class="o">=</span> <span class="n">r</span><span class="o">.</span><span class="n">read</span>
+ <span class="k">if</span> <span class="n">six</span><span class="o">.</span><span class="n">PY2</span><span class="p">:</span>
+ <span class="n">fp</span> <span class="o">=</span> <span class="n">socket</span><span class="o">.</span><span class="n">_fileobject</span><span class="p">(</span><span class="n">r</span><span class="p">,</span> <span class="n">close</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">r</span><span class="o">.</span><span class="n">_decref_socketios</span> <span class="o">=</span> <span class="k">lambda</span><span class="p">:</span> <span class="kc">None</span>
+ <span class="n">r</span><span class="o">.</span><span class="n">ssl</span> <span class="o">=</span> <span class="n">h</span><span class="o">.</span><span class="n">sock</span><span class="o">.</span><span class="n">ssl</span>
+ <span class="n">r</span><span class="o">.</span><span class="n">_timeout</span> <span class="o">=</span> <span class="o">-</span><span class="mf">1.0</span>
+ <span class="n">r</span><span class="o">.</span><span class="n">recv_into</span> <span class="o">=</span> <span class="n">r</span><span class="o">.</span><span class="n">readinto</span>
+ <span class="n">fp</span> <span class="o">=</span> <span class="n">socket</span><span class="o">.</span><span class="n">SocketIO</span><span class="p">(</span><span class="n">r</span><span class="p">,</span> <span class="s1">&#39;rb&#39;</span><span class="p">)</span>
+
+ <span class="n">resp</span> <span class="o">=</span> <span class="n">addinfourl</span><span class="p">(</span><span class="n">fp</span><span class="p">,</span> <span class="n">r</span><span class="o">.</span><span class="n">msg</span><span class="p">,</span> <span class="n">req</span><span class="o">.</span><span class="n">get_full_url</span><span class="p">())</span>
+ <span class="n">resp</span><span class="o">.</span><span class="n">code</span> <span class="o">=</span> <span class="n">r</span><span class="o">.</span><span class="n">status</span>
+ <span class="n">resp</span><span class="o">.</span><span class="n">msg</span> <span class="o">=</span> <span class="n">r</span><span class="o">.</span><span class="n">reason</span>
+ <span class="k">return</span> <span class="n">resp</span></div>
+
+ <span class="n">https_request</span> <span class="o">=</span> <span class="n">AbstractHTTPHandler</span><span class="o">.</span><span class="n">do_request_</span></div>
+
+
+<span class="c1"># Copied from urllib2 with modifications for ssl</span>
+<div class="viewcode-block" id="build_opener"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.m2urllib2.build_opener">[docs]</a><span class="k">def</span> <span class="nf">build_opener</span><span class="p">(</span><span class="n">ssl_context</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">*</span><span class="n">handlers</span><span class="p">):</span>
+ <span class="c1"># type: (Optional[SSL.Context], *object) -&gt; OpenerDirector</span>
+ <span class="sd">&quot;&quot;&quot;Create an opener object from a list of handlers.</span>
+
+<span class="sd"> The opener will use several default handlers, including support</span>
+<span class="sd"> for HTTP and FTP.</span>
+
+<span class="sd"> If any of the handlers passed as arguments are subclasses of the</span>
+<span class="sd"> default handlers, the default handlers will not be used.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+
+ <span class="k">def</span> <span class="nf">isclass</span><span class="p">(</span><span class="n">obj</span><span class="p">):</span>
+ <span class="k">return</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="nb">type</span><span class="p">)</span> <span class="ow">or</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s2">&quot;__bases__&quot;</span><span class="p">)</span>
+
+ <span class="n">opener</span> <span class="o">=</span> <span class="n">OpenerDirector</span><span class="p">()</span>
+ <span class="n">default_classes</span> <span class="o">=</span> <span class="p">[</span><span class="n">ProxyHandler</span><span class="p">,</span> <span class="n">UnknownHandler</span><span class="p">,</span> <span class="n">HTTPHandler</span><span class="p">,</span>
+ <span class="n">HTTPDefaultErrorHandler</span><span class="p">,</span> <span class="n">HTTPRedirectHandler</span><span class="p">,</span>
+ <span class="n">FTPHandler</span><span class="p">,</span> <span class="n">FileHandler</span><span class="p">,</span> <span class="n">HTTPErrorProcessor</span><span class="p">]</span>
+ <span class="n">skip</span> <span class="o">=</span> <span class="p">[]</span>
+ <span class="k">for</span> <span class="n">klass</span> <span class="ow">in</span> <span class="n">default_classes</span><span class="p">:</span>
+ <span class="k">for</span> <span class="n">check</span> <span class="ow">in</span> <span class="n">handlers</span><span class="p">:</span>
+ <span class="k">if</span> <span class="n">isclass</span><span class="p">(</span><span class="n">check</span><span class="p">):</span>
+ <span class="k">if</span> <span class="nb">issubclass</span><span class="p">(</span><span class="n">check</span><span class="p">,</span> <span class="n">klass</span><span class="p">):</span>
+ <span class="n">skip</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">klass</span><span class="p">)</span>
+ <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">check</span><span class="p">,</span> <span class="n">klass</span><span class="p">):</span>
+ <span class="n">skip</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">klass</span><span class="p">)</span>
+ <span class="k">for</span> <span class="n">klass</span> <span class="ow">in</span> <span class="n">skip</span><span class="p">:</span>
+ <span class="n">default_classes</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">klass</span><span class="p">)</span>
+
+ <span class="k">for</span> <span class="n">klass</span> <span class="ow">in</span> <span class="n">default_classes</span><span class="p">:</span>
+ <span class="n">opener</span><span class="o">.</span><span class="n">add_handler</span><span class="p">(</span><span class="n">klass</span><span class="p">())</span>
+
+ <span class="c1"># Add the HTTPS handler with ssl_context</span>
+ <span class="k">if</span> <span class="n">HTTPSHandler</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">skip</span><span class="p">:</span>
+ <span class="n">opener</span><span class="o">.</span><span class="n">add_handler</span><span class="p">(</span><span class="n">HTTPSHandler</span><span class="p">(</span><span class="n">ssl_context</span><span class="p">))</span>
+
+ <span class="k">for</span> <span class="n">h</span> <span class="ow">in</span> <span class="n">handlers</span><span class="p">:</span>
+ <span class="k">if</span> <span class="n">isclass</span><span class="p">(</span><span class="n">h</span><span class="p">):</span>
+ <span class="n">h</span> <span class="o">=</span> <span class="n">h</span><span class="p">()</span>
+ <span class="n">opener</span><span class="o">.</span><span class="n">add_handler</span><span class="p">(</span><span class="n">h</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">opener</span></div>
+</pre></div>
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="../../index.html">M2Crypto</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="../../M2Crypto.html">M2Crypto Package</a></li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="../../index.html">Documentation overview</a><ul>
+ <li><a href="../index.html">Module code</a><ul>
+ </ul></li>
+ </ul></li>
+</ul>
+</div>
+<div id="searchbox" style="display: none" role="search">
+ <h3>Quick search</h3>
+ <div class="searchformwrapper">
+ <form class="search" action="../../search.html" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ </div>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer">
+ &copy;2017, Matej Cepl <mcepl@cepl.eu>.
+
+ |
+ Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
+ &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
+
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/_modules/M2Crypto/m2xmlrpclib.html b/doc/html/_modules/M2Crypto/m2xmlrpclib.html
new file mode 100644
index 0000000..fb3834f
--- /dev/null
+++ b/doc/html/_modules/M2Crypto/m2xmlrpclib.html
@@ -0,0 +1,183 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>M2Crypto.m2xmlrpclib &#8212; M2Crypto documentation</title>
+ <link rel="stylesheet" href="../../_static/alabaster.css" type="text/css" />
+ <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../../_static/jquery.js"></script>
+ <script type="text/javascript" src="../../_static/underscore.js"></script>
+ <script type="text/javascript" src="../../_static/doctools.js"></script>
+ <script type="text/javascript" src="../../_static/language_data.js"></script>
+ <link rel="index" title="Index" href="../../genindex.html" />
+ <link rel="search" title="Search" href="../../search.html" />
+
+ <link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+ <h1>Source code for M2Crypto.m2xmlrpclib</h1><div class="highlight"><pre>
+<span></span><span class="kn">from</span> <span class="nn">__future__</span> <span class="k">import</span> <span class="n">absolute_import</span>
+
+<span class="sd">&quot;&quot;&quot;M2Crypto enhancement to xmlrpclib.</span>
+
+<span class="sd">Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved.&quot;&quot;&quot;</span>
+
+<span class="kn">import</span> <span class="nn">base64</span>
+
+<span class="kn">import</span> <span class="nn">M2Crypto</span>
+
+<span class="kn">from</span> <span class="nn">M2Crypto</span> <span class="k">import</span> <span class="n">SSL</span><span class="p">,</span> <span class="n">httpslib</span><span class="p">,</span> <span class="n">m2urllib</span><span class="p">,</span> <span class="n">six</span><span class="p">,</span> <span class="n">util</span>
+<span class="k">if</span> <span class="n">util</span><span class="o">.</span><span class="n">py27plus</span><span class="p">:</span>
+ <span class="kn">from</span> <span class="nn">typing</span> <span class="k">import</span> <span class="n">Any</span><span class="p">,</span> <span class="n">AnyStr</span><span class="p">,</span> <span class="n">Callable</span><span class="p">,</span> <span class="n">Optional</span> <span class="c1"># noqa</span>
+
+<span class="kn">from</span> <span class="nn">M2Crypto.six.moves.xmlrpc_client</span> <span class="k">import</span> <span class="n">ProtocolError</span><span class="p">,</span> <span class="n">Transport</span>
+<span class="c1"># six.moves doesn&#39;t support star imports</span>
+<span class="k">if</span> <span class="n">six</span><span class="o">.</span><span class="n">PY3</span><span class="p">:</span>
+ <span class="kn">from</span> <span class="nn">xmlrpc.client</span> <span class="k">import</span> <span class="o">*</span> <span class="c1"># noqa</span>
+<span class="k">else</span><span class="p">:</span>
+ <span class="kn">from</span> <span class="nn">xmlrpclib</span> <span class="k">import</span> <span class="o">*</span> <span class="c1"># noqa</span>
+
+<span class="n">__version__</span> <span class="o">=</span> <span class="n">M2Crypto</span><span class="o">.</span><span class="n">__version__</span>
+
+
+<div class="viewcode-block" id="SSL_Transport"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.m2xmlrpclib.SSL_Transport">[docs]</a><span class="k">class</span> <span class="nc">SSL_Transport</span><span class="p">(</span><span class="n">Transport</span><span class="p">):</span>
+
+ <span class="n">user_agent</span> <span class="o">=</span> <span class="s2">&quot;M2Crypto_XMLRPC/</span><span class="si">%s</span><span class="s2"> - </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">__version__</span><span class="p">,</span>
+ <span class="n">Transport</span><span class="o">.</span><span class="n">user_agent</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">ssl_context</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kw</span><span class="p">):</span>
+ <span class="c1"># type: (Optional[SSL.Context], *Any, **Any) -&gt; None</span>
+ <span class="n">Transport</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kw</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">ssl_context</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">ssl_ctx</span> <span class="o">=</span> <span class="n">SSL</span><span class="o">.</span><span class="n">Context</span><span class="p">()</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">ssl_ctx</span> <span class="o">=</span> <span class="n">ssl_context</span>
+
+<div class="viewcode-block" id="SSL_Transport.request"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.m2xmlrpclib.SSL_Transport.request">[docs]</a> <span class="k">def</span> <span class="nf">request</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">host</span><span class="p">,</span> <span class="n">handler</span><span class="p">,</span> <span class="n">request_body</span><span class="p">,</span> <span class="n">verbose</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
+ <span class="c1"># type: (AnyStr, Callable, bytes, int) -&gt; object</span>
+ <span class="c1"># Handle username and password.</span>
+ <span class="n">user_passwd</span><span class="p">,</span> <span class="n">host_port</span> <span class="o">=</span> <span class="n">m2urllib</span><span class="o">.</span><span class="n">splituser</span><span class="p">(</span><span class="n">host</span><span class="p">)</span>
+ <span class="n">_host</span><span class="p">,</span> <span class="n">_port</span> <span class="o">=</span> <span class="n">m2urllib</span><span class="o">.</span><span class="n">splitport</span><span class="p">(</span><span class="n">host_port</span><span class="p">)</span>
+ <span class="n">h</span> <span class="o">=</span> <span class="n">httpslib</span><span class="o">.</span><span class="n">HTTPSConnection</span><span class="p">(</span><span class="n">_host</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">_port</span><span class="p">),</span>
+ <span class="n">ssl_context</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">ssl_ctx</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">verbose</span><span class="p">:</span>
+ <span class="n">h</span><span class="o">.</span><span class="n">set_debuglevel</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
+
+ <span class="c1"># What follows is as in xmlrpclib.Transport. (Except the authz bit.)</span>
+ <span class="n">h</span><span class="o">.</span><span class="n">putrequest</span><span class="p">(</span><span class="s2">&quot;POST&quot;</span><span class="p">,</span> <span class="n">handler</span><span class="p">)</span>
+
+ <span class="c1"># required by HTTP/1.1</span>
+ <span class="n">h</span><span class="o">.</span><span class="n">putheader</span><span class="p">(</span><span class="s2">&quot;Host&quot;</span><span class="p">,</span> <span class="n">_host</span><span class="p">)</span>
+
+ <span class="c1"># required by XML-RPC</span>
+ <span class="n">h</span><span class="o">.</span><span class="n">putheader</span><span class="p">(</span><span class="s2">&quot;User-Agent&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">user_agent</span><span class="p">)</span>
+ <span class="n">h</span><span class="o">.</span><span class="n">putheader</span><span class="p">(</span><span class="s2">&quot;Content-Type&quot;</span><span class="p">,</span> <span class="s2">&quot;text/xml&quot;</span><span class="p">)</span>
+ <span class="n">h</span><span class="o">.</span><span class="n">putheader</span><span class="p">(</span><span class="s2">&quot;Content-Length&quot;</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">request_body</span><span class="p">)))</span>
+
+ <span class="c1"># Authorisation.</span>
+ <span class="k">if</span> <span class="n">user_passwd</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">auth</span> <span class="o">=</span> <span class="n">base64</span><span class="o">.</span><span class="n">encodestring</span><span class="p">(</span><span class="n">user_passwd</span><span class="p">)</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
+ <span class="n">h</span><span class="o">.</span><span class="n">putheader</span><span class="p">(</span><span class="s1">&#39;Authorization&#39;</span><span class="p">,</span> <span class="s1">&#39;Basic </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">auth</span><span class="p">)</span>
+
+ <span class="n">h</span><span class="o">.</span><span class="n">endheaders</span><span class="p">()</span>
+
+ <span class="k">if</span> <span class="n">request_body</span><span class="p">:</span>
+ <span class="n">h</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">request_body</span><span class="p">)</span>
+
+ <span class="n">errcode</span><span class="p">,</span> <span class="n">errmsg</span><span class="p">,</span> <span class="n">headers</span> <span class="o">=</span> <span class="n">h</span><span class="o">.</span><span class="n">getreply</span><span class="p">()</span>
+
+ <span class="k">if</span> <span class="n">errcode</span> <span class="o">!=</span> <span class="mi">200</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="n">ProtocolError</span><span class="p">(</span>
+ <span class="n">host</span> <span class="o">+</span> <span class="n">handler</span><span class="p">,</span>
+ <span class="n">errcode</span><span class="p">,</span> <span class="n">errmsg</span><span class="p">,</span>
+ <span class="n">headers</span>
+ <span class="p">)</span>
+
+ <span class="bp">self</span><span class="o">.</span><span class="n">verbose</span> <span class="o">=</span> <span class="n">verbose</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">parse_response</span><span class="p">(</span><span class="n">h</span><span class="o">.</span><span class="n">getfile</span><span class="p">())</span></div></div>
+</pre></div>
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="../../index.html">M2Crypto</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="../../M2Crypto.html">M2Crypto Package</a></li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="../../index.html">Documentation overview</a><ul>
+ <li><a href="../index.html">Module code</a><ul>
+ </ul></li>
+ </ul></li>
+</ul>
+</div>
+<div id="searchbox" style="display: none" role="search">
+ <h3>Quick search</h3>
+ <div class="searchformwrapper">
+ <form class="search" action="../../search.html" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ </div>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer">
+ &copy;2017, Matej Cepl <mcepl@cepl.eu>.
+
+ |
+ Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
+ &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
+
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/_modules/M2Crypto/threading.html b/doc/html/_modules/M2Crypto/threading.html
new file mode 100644
index 0000000..7074d6c
--- /dev/null
+++ b/doc/html/_modules/M2Crypto/threading.html
@@ -0,0 +1,129 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>M2Crypto.threading &#8212; M2Crypto documentation</title>
+ <link rel="stylesheet" href="../../_static/alabaster.css" type="text/css" />
+ <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../../_static/jquery.js"></script>
+ <script type="text/javascript" src="../../_static/underscore.js"></script>
+ <script type="text/javascript" src="../../_static/doctools.js"></script>
+ <script type="text/javascript" src="../../_static/language_data.js"></script>
+ <link rel="index" title="Index" href="../../genindex.html" />
+ <link rel="search" title="Search" href="../../search.html" />
+
+ <link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+ <h1>Source code for M2Crypto.threading</h1><div class="highlight"><pre>
+<span></span><span class="kn">from</span> <span class="nn">__future__</span> <span class="k">import</span> <span class="n">absolute_import</span>
+
+<span class="sd">&quot;&quot;&quot;</span>
+<span class="sd">M2Crypto threading support, required for multithreaded applications.</span>
+
+<span class="sd">Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved.&quot;&quot;&quot;</span>
+
+<span class="c1"># M2Crypto</span>
+<span class="kn">from</span> <span class="nn">M2Crypto</span> <span class="k">import</span> <span class="n">m2</span>
+
+
+<div class="viewcode-block" id="init"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.threading.init">[docs]</a><span class="k">def</span> <span class="nf">init</span><span class="p">():</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Initialize threading support.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">threading_init</span><span class="p">()</span></div>
+
+
+<div class="viewcode-block" id="cleanup"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.threading.cleanup">[docs]</a><span class="k">def</span> <span class="nf">cleanup</span><span class="p">():</span>
+ <span class="c1"># type: () -&gt; None</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> End and cleanup threading support.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">m2</span><span class="o">.</span><span class="n">threading_cleanup</span><span class="p">()</span></div>
+</pre></div>
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="../../index.html">M2Crypto</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="../../M2Crypto.html">M2Crypto Package</a></li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="../../index.html">Documentation overview</a><ul>
+ <li><a href="../index.html">Module code</a><ul>
+ </ul></li>
+ </ul></li>
+</ul>
+</div>
+<div id="searchbox" style="display: none" role="search">
+ <h3>Quick search</h3>
+ <div class="searchformwrapper">
+ <form class="search" action="../../search.html" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ </div>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer">
+ &copy;2017, Matej Cepl <mcepl@cepl.eu>.
+
+ |
+ Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
+ &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
+
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/_modules/M2Crypto/util.html b/doc/html/_modules/M2Crypto/util.html
new file mode 100644
index 0000000..3cd7461
--- /dev/null
+++ b/doc/html/_modules/M2Crypto/util.html
@@ -0,0 +1,193 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>M2Crypto.util &#8212; M2Crypto documentation</title>
+ <link rel="stylesheet" href="../../_static/alabaster.css" type="text/css" />
+ <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../../_static/jquery.js"></script>
+ <script type="text/javascript" src="../../_static/underscore.js"></script>
+ <script type="text/javascript" src="../../_static/doctools.js"></script>
+ <script type="text/javascript" src="../../_static/language_data.js"></script>
+ <link rel="index" title="Index" href="../../genindex.html" />
+ <link rel="search" title="Search" href="../../search.html" />
+
+ <link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+ <h1>Source code for M2Crypto.util</h1><div class="highlight"><pre>
+<span></span><span class="kn">from</span> <span class="nn">__future__</span> <span class="k">import</span> <span class="n">absolute_import</span>
+<span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> M2Crypto utility routines.</span>
+
+<span class="sd"> NOTHING IN THIS MODULE IS GUARANTEED TO BE STABLE, USED ONLY FOR</span>
+<span class="sd"> INTERNAL PURPOSES OF M2CRYPTO.</span>
+
+<span class="sd"> Copyright (c) 1999-2004 Ng Pheng Siong. All rights reserved.</span>
+
+<span class="sd"> Portions created by Open Source Applications Foundation (OSAF) are</span>
+<span class="sd"> Copyright (C) 2004 OSAF. All Rights Reserved.</span>
+<span class="sd">&quot;&quot;&quot;</span>
+
+<span class="kn">import</span> <span class="nn">binascii</span>
+<span class="kn">import</span> <span class="nn">logging</span>
+<span class="kn">import</span> <span class="nn">sys</span>
+
+<span class="kn">from</span> <span class="nn">M2Crypto</span> <span class="k">import</span> <span class="n">m2</span><span class="p">,</span> <span class="n">py27plus</span><span class="p">,</span> <span class="n">six</span>
+<span class="k">if</span> <span class="n">py27plus</span><span class="p">:</span>
+ <span class="kn">from</span> <span class="nn">typing</span> <span class="k">import</span> <span class="n">Any</span><span class="p">,</span> <span class="n">AnyStr</span><span class="p">,</span> <span class="n">Optional</span><span class="p">,</span> <span class="n">Tuple</span><span class="p">,</span> <span class="n">Union</span> <span class="c1"># noqa</span>
+ <span class="c1"># see https://github.com/python/typeshed/issues/222</span>
+ <span class="n">AddrType</span> <span class="o">=</span> <span class="n">Union</span><span class="p">[</span><span class="n">Tuple</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">int</span><span class="p">],</span> <span class="nb">str</span><span class="p">]</span>
+
+<span class="n">log</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s1">&#39;util&#39;</span><span class="p">)</span>
+
+
+<div class="viewcode-block" id="UtilError"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.util.UtilError">[docs]</a><span class="k">class</span> <span class="nc">UtilError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
+ <span class="k">pass</span></div>
+
+<span class="n">m2</span><span class="o">.</span><span class="n">util_init</span><span class="p">(</span><span class="n">UtilError</span><span class="p">)</span>
+
+
+<div class="viewcode-block" id="pkcs5_pad"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.util.pkcs5_pad">[docs]</a><span class="k">def</span> <span class="nf">pkcs5_pad</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">blklen</span><span class="o">=</span><span class="mi">8</span><span class="p">):</span>
+ <span class="c1"># type: (str, int) -&gt; str</span>
+ <span class="n">pad</span> <span class="o">=</span> <span class="p">(</span><span class="mi">8</span> <span class="o">-</span> <span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> <span class="o">%</span> <span class="mi">8</span><span class="p">))</span>
+ <span class="k">return</span> <span class="n">data</span> <span class="o">+</span> <span class="nb">chr</span><span class="p">(</span><span class="n">pad</span><span class="p">)</span> <span class="o">*</span> <span class="n">pad</span></div>
+
+
+<div class="viewcode-block" id="pkcs7_pad"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.util.pkcs7_pad">[docs]</a><span class="k">def</span> <span class="nf">pkcs7_pad</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">blklen</span><span class="p">):</span>
+ <span class="c1"># type: (str, int) -&gt; str</span>
+ <span class="k">if</span> <span class="n">blklen</span> <span class="o">&gt;</span> <span class="mi">255</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">&#39;illegal block size&#39;</span><span class="p">)</span>
+ <span class="n">pad</span> <span class="o">=</span> <span class="p">(</span><span class="n">blklen</span> <span class="o">-</span> <span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> <span class="o">%</span> <span class="n">blklen</span><span class="p">))</span>
+ <span class="k">return</span> <span class="n">data</span> <span class="o">+</span> <span class="nb">chr</span><span class="p">(</span><span class="n">pad</span><span class="p">)</span> <span class="o">*</span> <span class="n">pad</span></div>
+
+
+<div class="viewcode-block" id="bin_to_hex"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.util.bin_to_hex">[docs]</a><span class="k">def</span> <span class="nf">bin_to_hex</span><span class="p">(</span><span class="n">b</span><span class="p">):</span>
+ <span class="c1"># type: (bytes) -&gt; str</span>
+ <span class="k">return</span> <span class="n">six</span><span class="o">.</span><span class="n">ensure_text</span><span class="p">(</span><span class="n">binascii</span><span class="o">.</span><span class="n">b2a_base64</span><span class="p">(</span><span class="n">b</span><span class="p">)[:</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span></div>
+
+
+<div class="viewcode-block" id="octx_to_num"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.util.octx_to_num">[docs]</a><span class="k">def</span> <span class="nf">octx_to_num</span><span class="p">(</span><span class="n">x</span><span class="p">):</span>
+ <span class="c1"># type: (bytes) -&gt; int</span>
+ <span class="k">return</span> <span class="nb">int</span><span class="p">(</span><span class="n">binascii</span><span class="o">.</span><span class="n">hexlify</span><span class="p">(</span><span class="n">x</span><span class="p">),</span> <span class="mi">16</span><span class="p">)</span></div>
+
+
+<div class="viewcode-block" id="genparam_callback"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.util.genparam_callback">[docs]</a><span class="k">def</span> <span class="nf">genparam_callback</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">n</span><span class="p">,</span> <span class="n">out</span><span class="o">=</span><span class="n">sys</span><span class="o">.</span><span class="n">stdout</span><span class="p">):</span>
+ <span class="c1"># type: (int, Any, file) -&gt; None</span>
+ <span class="n">ch</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;.&#39;</span><span class="p">,</span> <span class="s1">&#39;+&#39;</span><span class="p">,</span> <span class="s1">&#39;*&#39;</span><span class="p">,</span> <span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">]</span>
+ <span class="n">out</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">ch</span><span class="p">[</span><span class="n">p</span><span class="p">])</span>
+ <span class="n">out</span><span class="o">.</span><span class="n">flush</span><span class="p">()</span></div>
+
+
+<div class="viewcode-block" id="quiet_genparam_callback"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.util.quiet_genparam_callback">[docs]</a><span class="k">def</span> <span class="nf">quiet_genparam_callback</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">n</span><span class="p">,</span> <span class="n">out</span><span class="p">):</span>
+ <span class="c1"># type: (Any, Any, Any) -&gt; None</span>
+ <span class="k">pass</span></div>
+
+
+<div class="viewcode-block" id="passphrase_callback"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.util.passphrase_callback">[docs]</a><span class="k">def</span> <span class="nf">passphrase_callback</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="n">prompt1</span><span class="o">=</span><span class="s1">&#39;Enter passphrase:&#39;</span><span class="p">,</span>
+ <span class="n">prompt2</span><span class="o">=</span><span class="s1">&#39;Verify passphrase:&#39;</span><span class="p">):</span>
+ <span class="c1"># type: (bool, str, str) -&gt; Optional[str]</span>
+ <span class="kn">from</span> <span class="nn">getpass</span> <span class="k">import</span> <span class="n">getpass</span>
+ <span class="k">while</span> <span class="mi">1</span><span class="p">:</span>
+ <span class="k">try</span><span class="p">:</span>
+ <span class="n">p1</span> <span class="o">=</span> <span class="n">getpass</span><span class="p">(</span><span class="n">prompt1</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">v</span><span class="p">:</span>
+ <span class="n">p2</span> <span class="o">=</span> <span class="n">getpass</span><span class="p">(</span><span class="n">prompt2</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">p1</span> <span class="o">==</span> <span class="n">p2</span><span class="p">:</span>
+ <span class="k">break</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">break</span>
+ <span class="k">except</span> <span class="ne">KeyboardInterrupt</span><span class="p">:</span>
+ <span class="k">return</span> <span class="kc">None</span>
+ <span class="k">return</span> <span class="n">p1</span></div>
+
+
+<div class="viewcode-block" id="no_passphrase_callback"><a class="viewcode-back" href="../../M2Crypto.html#M2Crypto.util.no_passphrase_callback">[docs]</a><span class="k">def</span> <span class="nf">no_passphrase_callback</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">):</span>
+ <span class="c1"># type: (*Any) -&gt; str</span>
+ <span class="k">return</span> <span class="s1">&#39;&#39;</span></div>
+</pre></div>
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="../../index.html">M2Crypto</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="../../M2Crypto.html">M2Crypto Package</a></li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="../../index.html">Documentation overview</a><ul>
+ <li><a href="../index.html">Module code</a><ul>
+ </ul></li>
+ </ul></li>
+</ul>
+</div>
+<div id="searchbox" style="display: none" role="search">
+ <h3>Quick search</h3>
+ <div class="searchformwrapper">
+ <form class="search" action="../../search.html" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ </div>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer">
+ &copy;2017, Matej Cepl <mcepl@cepl.eu>.
+
+ |
+ Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
+ &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
+
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/_modules/index.html b/doc/html/_modules/index.html
new file mode 100644
index 0000000..56bc7ef
--- /dev/null
+++ b/doc/html/_modules/index.html
@@ -0,0 +1,137 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>Overview: module code &#8212; M2Crypto documentation</title>
+ <link rel="stylesheet" href="../_static/alabaster.css" type="text/css" />
+ <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../_static/jquery.js"></script>
+ <script type="text/javascript" src="../_static/underscore.js"></script>
+ <script type="text/javascript" src="../_static/doctools.js"></script>
+ <script type="text/javascript" src="../_static/language_data.js"></script>
+ <link rel="index" title="Index" href="../genindex.html" />
+ <link rel="search" title="Search" href="../search.html" />
+
+ <link rel="stylesheet" href="../_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+ <h1>All modules for which code is available</h1>
+<ul><li><a href="M2Crypto/ASN1.html">M2Crypto.ASN1</a></li>
+<li><a href="M2Crypto/AuthCookie.html">M2Crypto.AuthCookie</a></li>
+<li><a href="M2Crypto/BIO.html">M2Crypto.BIO</a></li>
+<li><a href="M2Crypto/BN.html">M2Crypto.BN</a></li>
+<li><a href="M2Crypto/DH.html">M2Crypto.DH</a></li>
+<li><a href="M2Crypto/DSA.html">M2Crypto.DSA</a></li>
+<li><a href="M2Crypto/EC.html">M2Crypto.EC</a></li>
+<li><a href="M2Crypto/EVP.html">M2Crypto.EVP</a></li>
+<li><a href="M2Crypto/Engine.html">M2Crypto.Engine</a></li>
+<li><a href="M2Crypto/Err.html">M2Crypto.Err</a></li>
+<li><a href="M2Crypto/RC4.html">M2Crypto.RC4</a></li>
+<li><a href="M2Crypto/RSA.html">M2Crypto.RSA</a></li>
+<li><a href="M2Crypto/Rand.html">M2Crypto.Rand</a></li>
+<li><a href="M2Crypto/SMIME.html">M2Crypto.SMIME</a></li>
+<li><a href="M2Crypto/SSL.html">M2Crypto.SSL</a></li>
+<ul><li><a href="M2Crypto/SSL/Checker.html">M2Crypto.SSL.Checker</a></li>
+<li><a href="M2Crypto/SSL/Cipher.html">M2Crypto.SSL.Cipher</a></li>
+<li><a href="M2Crypto/SSL/Connection.html">M2Crypto.SSL.Connection</a></li>
+<li><a href="M2Crypto/SSL/Context.html">M2Crypto.SSL.Context</a></li>
+<li><a href="M2Crypto/SSL/SSLServer.html">M2Crypto.SSL.SSLServer</a></li>
+<li><a href="M2Crypto/SSL/Session.html">M2Crypto.SSL.Session</a></li>
+<li><a href="M2Crypto/SSL/TwistedProtocolWrapper.html">M2Crypto.SSL.TwistedProtocolWrapper</a></li>
+<li><a href="M2Crypto/SSL/cb.html">M2Crypto.SSL.cb</a></li>
+<li><a href="M2Crypto/SSL/ssl_dispatcher.html">M2Crypto.SSL.ssl_dispatcher</a></li>
+<li><a href="M2Crypto/SSL/timeout.html">M2Crypto.SSL.timeout</a></li>
+</ul><li><a href="M2Crypto/X509.html">M2Crypto.X509</a></li>
+<li><a href="M2Crypto/_m2crypto.html">M2Crypto._m2crypto</a></li>
+<li><a href="M2Crypto/ftpslib.html">M2Crypto.ftpslib</a></li>
+<li><a href="M2Crypto/httpslib.html">M2Crypto.httpslib</a></li>
+<li><a href="M2Crypto/m2urllib.html">M2Crypto.m2urllib</a></li>
+<li><a href="M2Crypto/m2urllib2.html">M2Crypto.m2urllib2</a></li>
+<li><a href="M2Crypto/m2xmlrpclib.html">M2Crypto.m2xmlrpclib</a></li>
+<li><a href="M2Crypto/threading.html">M2Crypto.threading</a></li>
+<li><a href="M2Crypto/util.html">M2Crypto.util</a></li>
+<li><a href="urllib/request.html">urllib.request</a></li>
+</ul>
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="../index.html">M2Crypto</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="../M2Crypto.html">M2Crypto Package</a></li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="../index.html">Documentation overview</a><ul>
+ </ul></li>
+</ul>
+</div>
+<div id="searchbox" style="display: none" role="search">
+ <h3>Quick search</h3>
+ <div class="searchformwrapper">
+ <form class="search" action="../search.html" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ </div>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer">
+ &copy;2017, Matej Cepl <mcepl@cepl.eu>.
+
+ |
+ Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
+ &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
+
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/_modules/urllib/request.html b/doc/html/_modules/urllib/request.html
new file mode 100644
index 0000000..ee22b9d
--- /dev/null
+++ b/doc/html/_modules/urllib/request.html
@@ -0,0 +1,2841 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>urllib.request &#8212; M2Crypto documentation</title>
+ <link rel="stylesheet" href="../../_static/alabaster.css" type="text/css" />
+ <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../../_static/jquery.js"></script>
+ <script type="text/javascript" src="../../_static/underscore.js"></script>
+ <script type="text/javascript" src="../../_static/doctools.js"></script>
+ <script type="text/javascript" src="../../_static/language_data.js"></script>
+ <link rel="index" title="Index" href="../../genindex.html" />
+ <link rel="search" title="Search" href="../../search.html" />
+
+ <link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+ <h1>Source code for urllib.request</h1><div class="highlight"><pre>
+<span></span><span class="sd">&quot;&quot;&quot;An extensible library for opening URLs using a variety of protocols</span>
+
+<span class="sd">The simplest way to use this module is to call the urlopen function,</span>
+<span class="sd">which accepts a string containing a URL or a Request object (described</span>
+<span class="sd">below). It opens the URL and returns the results as file-like</span>
+<span class="sd">object; the returned object has some extra methods described below.</span>
+
+<span class="sd">The OpenerDirector manages a collection of Handler objects that do</span>
+<span class="sd">all the actual work. Each Handler implements a particular protocol or</span>
+<span class="sd">option. The OpenerDirector is a composite object that invokes the</span>
+<span class="sd">Handlers needed to open the requested URL. For example, the</span>
+<span class="sd">HTTPHandler performs HTTP GET and POST requests and deals with</span>
+<span class="sd">non-error returns. The HTTPRedirectHandler automatically deals with</span>
+<span class="sd">HTTP 301, 302, 303 and 307 redirect errors, and the HTTPDigestAuthHandler</span>
+<span class="sd">deals with digest authentication.</span>
+
+<span class="sd">urlopen(url, data=None) -- Basic usage is the same as original</span>
+<span class="sd">urllib. pass the url and optionally data to post to an HTTP URL, and</span>
+<span class="sd">get a file-like object back. One difference is that you can also pass</span>
+<span class="sd">a Request instance instead of URL. Raises a URLError (subclass of</span>
+<span class="sd">OSError); for HTTP errors, raises an HTTPError, which can also be</span>
+<span class="sd">treated as a valid response.</span>
+
+<span class="sd">build_opener -- Function that creates a new OpenerDirector instance.</span>
+<span class="sd">Will install the default handlers. Accepts one or more Handlers as</span>
+<span class="sd">arguments, either instances or Handler classes that it will</span>
+<span class="sd">instantiate. If one of the argument is a subclass of the default</span>
+<span class="sd">handler, the argument will be installed instead of the default.</span>
+
+<span class="sd">install_opener -- Installs a new opener as the default opener.</span>
+
+<span class="sd">objects of interest:</span>
+
+<span class="sd">OpenerDirector -- Sets up the User Agent as the Python-urllib client and manages</span>
+<span class="sd">the Handler classes, while dealing with requests and responses.</span>
+
+<span class="sd">Request -- An object that encapsulates the state of a request. The</span>
+<span class="sd">state can be as simple as the URL. It can also include extra HTTP</span>
+<span class="sd">headers, e.g. a User-Agent.</span>
+
+<span class="sd">BaseHandler --</span>
+
+<span class="sd">internals:</span>
+<span class="sd">BaseHandler and parent</span>
+<span class="sd">_call_chain conventions</span>
+
+<span class="sd">Example usage:</span>
+
+<span class="sd">import urllib.request</span>
+
+<span class="sd"># set up authentication info</span>
+<span class="sd">authinfo = urllib.request.HTTPBasicAuthHandler()</span>
+<span class="sd">authinfo.add_password(realm=&#39;PDQ Application&#39;,</span>
+<span class="sd"> uri=&#39;https://mahler:8092/site-updates.py&#39;,</span>
+<span class="sd"> user=&#39;klem&#39;,</span>
+<span class="sd"> passwd=&#39;geheim$parole&#39;)</span>
+
+<span class="sd">proxy_support = urllib.request.ProxyHandler({&quot;http&quot; : &quot;http://ahad-haam:3128&quot;})</span>
+
+<span class="sd"># build a new opener that adds authentication and caching FTP handlers</span>
+<span class="sd">opener = urllib.request.build_opener(proxy_support, authinfo,</span>
+<span class="sd"> urllib.request.CacheFTPHandler)</span>
+
+<span class="sd"># install it</span>
+<span class="sd">urllib.request.install_opener(opener)</span>
+
+<span class="sd">f = urllib.request.urlopen(&#39;http://www.python.org/&#39;)</span>
+<span class="sd">&quot;&quot;&quot;</span>
+
+<span class="c1"># XXX issues:</span>
+<span class="c1"># If an authentication error handler that tries to perform</span>
+<span class="c1"># authentication for some reason but fails, how should the error be</span>
+<span class="c1"># signalled? The client needs to know the HTTP error code. But if</span>
+<span class="c1"># the handler knows that the problem was, e.g., that it didn&#39;t know</span>
+<span class="c1"># that hash algo that requested in the challenge, it would be good to</span>
+<span class="c1"># pass that information along to the client, too.</span>
+<span class="c1"># ftp errors aren&#39;t handled cleanly</span>
+<span class="c1"># check digest against correct (i.e. non-apache) implementation</span>
+
+<span class="c1"># Possible extensions:</span>
+<span class="c1"># complex proxies XXX not sure what exactly was meant by this</span>
+<span class="c1"># abstract factory for opener</span>
+
+<span class="kn">import</span> <span class="nn">base64</span>
+<span class="kn">import</span> <span class="nn">bisect</span>
+<span class="kn">import</span> <span class="nn">email</span>
+<span class="kn">import</span> <span class="nn">hashlib</span>
+<span class="kn">import</span> <span class="nn">http.client</span>
+<span class="kn">import</span> <span class="nn">io</span>
+<span class="kn">import</span> <span class="nn">os</span>
+<span class="kn">import</span> <span class="nn">posixpath</span>
+<span class="kn">import</span> <span class="nn">re</span>
+<span class="kn">import</span> <span class="nn">socket</span>
+<span class="kn">import</span> <span class="nn">string</span>
+<span class="kn">import</span> <span class="nn">sys</span>
+<span class="kn">import</span> <span class="nn">time</span>
+<span class="kn">import</span> <span class="nn">tempfile</span>
+<span class="kn">import</span> <span class="nn">contextlib</span>
+<span class="kn">import</span> <span class="nn">warnings</span>
+
+
+<span class="kn">from</span> <span class="nn">urllib.error</span> <span class="k">import</span> <span class="n">URLError</span><span class="p">,</span> <span class="n">HTTPError</span><span class="p">,</span> <span class="n">ContentTooShortError</span>
+<span class="kn">from</span> <span class="nn">urllib.parse</span> <span class="k">import</span> <span class="p">(</span>
+ <span class="n">urlparse</span><span class="p">,</span> <span class="n">urlsplit</span><span class="p">,</span> <span class="n">urljoin</span><span class="p">,</span> <span class="n">unwrap</span><span class="p">,</span> <span class="n">quote</span><span class="p">,</span> <span class="n">unquote</span><span class="p">,</span>
+ <span class="n">splittype</span><span class="p">,</span> <span class="n">splithost</span><span class="p">,</span> <span class="n">splitport</span><span class="p">,</span> <span class="n">splituser</span><span class="p">,</span> <span class="n">splitpasswd</span><span class="p">,</span>
+ <span class="n">splitattr</span><span class="p">,</span> <span class="n">splitquery</span><span class="p">,</span> <span class="n">splitvalue</span><span class="p">,</span> <span class="n">splittag</span><span class="p">,</span> <span class="n">to_bytes</span><span class="p">,</span>
+ <span class="n">unquote_to_bytes</span><span class="p">,</span> <span class="n">urlunparse</span><span class="p">)</span>
+<span class="kn">from</span> <span class="nn">urllib.response</span> <span class="k">import</span> <span class="n">addinfourl</span><span class="p">,</span> <span class="n">addclosehook</span>
+
+<span class="c1"># check for SSL</span>
+<span class="k">try</span><span class="p">:</span>
+ <span class="kn">import</span> <span class="nn">ssl</span>
+<span class="k">except</span> <span class="ne">ImportError</span><span class="p">:</span>
+ <span class="n">_have_ssl</span> <span class="o">=</span> <span class="kc">False</span>
+<span class="k">else</span><span class="p">:</span>
+ <span class="n">_have_ssl</span> <span class="o">=</span> <span class="kc">True</span>
+
+<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span>
+ <span class="c1"># Classes</span>
+ <span class="s1">&#39;Request&#39;</span><span class="p">,</span> <span class="s1">&#39;OpenerDirector&#39;</span><span class="p">,</span> <span class="s1">&#39;BaseHandler&#39;</span><span class="p">,</span> <span class="s1">&#39;HTTPDefaultErrorHandler&#39;</span><span class="p">,</span>
+ <span class="s1">&#39;HTTPRedirectHandler&#39;</span><span class="p">,</span> <span class="s1">&#39;HTTPCookieProcessor&#39;</span><span class="p">,</span> <span class="s1">&#39;ProxyHandler&#39;</span><span class="p">,</span>
+ <span class="s1">&#39;HTTPPasswordMgr&#39;</span><span class="p">,</span> <span class="s1">&#39;HTTPPasswordMgrWithDefaultRealm&#39;</span><span class="p">,</span>
+ <span class="s1">&#39;HTTPPasswordMgrWithPriorAuth&#39;</span><span class="p">,</span> <span class="s1">&#39;AbstractBasicAuthHandler&#39;</span><span class="p">,</span>
+ <span class="s1">&#39;HTTPBasicAuthHandler&#39;</span><span class="p">,</span> <span class="s1">&#39;ProxyBasicAuthHandler&#39;</span><span class="p">,</span> <span class="s1">&#39;AbstractDigestAuthHandler&#39;</span><span class="p">,</span>
+ <span class="s1">&#39;HTTPDigestAuthHandler&#39;</span><span class="p">,</span> <span class="s1">&#39;ProxyDigestAuthHandler&#39;</span><span class="p">,</span> <span class="s1">&#39;HTTPHandler&#39;</span><span class="p">,</span>
+ <span class="s1">&#39;FileHandler&#39;</span><span class="p">,</span> <span class="s1">&#39;FTPHandler&#39;</span><span class="p">,</span> <span class="s1">&#39;CacheFTPHandler&#39;</span><span class="p">,</span> <span class="s1">&#39;DataHandler&#39;</span><span class="p">,</span>
+ <span class="s1">&#39;UnknownHandler&#39;</span><span class="p">,</span> <span class="s1">&#39;HTTPErrorProcessor&#39;</span><span class="p">,</span>
+ <span class="c1"># Functions</span>
+ <span class="s1">&#39;urlopen&#39;</span><span class="p">,</span> <span class="s1">&#39;install_opener&#39;</span><span class="p">,</span> <span class="s1">&#39;build_opener&#39;</span><span class="p">,</span>
+ <span class="s1">&#39;pathname2url&#39;</span><span class="p">,</span> <span class="s1">&#39;url2pathname&#39;</span><span class="p">,</span> <span class="s1">&#39;getproxies&#39;</span><span class="p">,</span>
+ <span class="c1"># Legacy interface</span>
+ <span class="s1">&#39;urlretrieve&#39;</span><span class="p">,</span> <span class="s1">&#39;urlcleanup&#39;</span><span class="p">,</span> <span class="s1">&#39;URLopener&#39;</span><span class="p">,</span> <span class="s1">&#39;FancyURLopener&#39;</span><span class="p">,</span>
+<span class="p">]</span>
+
+<span class="c1"># used in User-Agent header sent</span>
+<span class="n">__version__</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="si">%d</span><span class="s1">.</span><span class="si">%d</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">sys</span><span class="o">.</span><span class="n">version_info</span><span class="p">[:</span><span class="mi">2</span><span class="p">]</span>
+
+<span class="n">_opener</span> <span class="o">=</span> <span class="kc">None</span>
+<span class="k">def</span> <span class="nf">urlopen</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">timeout</span><span class="o">=</span><span class="n">socket</span><span class="o">.</span><span class="n">_GLOBAL_DEFAULT_TIMEOUT</span><span class="p">,</span>
+ <span class="o">*</span><span class="p">,</span> <span class="n">cafile</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">capath</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">cadefault</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">context</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="sd">&#39;&#39;&#39;Open the URL url, which can be either a string or a Request object.</span>
+
+<span class="sd"> *data* must be an object specifying additional data to be sent to</span>
+<span class="sd"> the server, or None if no such data is needed. See Request for</span>
+<span class="sd"> details.</span>
+
+<span class="sd"> urllib.request module uses HTTP/1.1 and includes a &quot;Connection:close&quot;</span>
+<span class="sd"> header in its HTTP requests.</span>
+
+<span class="sd"> The optional *timeout* parameter specifies a timeout in seconds for</span>
+<span class="sd"> blocking operations like the connection attempt (if not specified, the</span>
+<span class="sd"> global default timeout setting will be used). This only works for HTTP,</span>
+<span class="sd"> HTTPS and FTP connections.</span>
+
+<span class="sd"> If *context* is specified, it must be a ssl.SSLContext instance describing</span>
+<span class="sd"> the various SSL options. See HTTPSConnection for more details.</span>
+
+<span class="sd"> The optional *cafile* and *capath* parameters specify a set of trusted CA</span>
+<span class="sd"> certificates for HTTPS requests. cafile should point to a single file</span>
+<span class="sd"> containing a bundle of CA certificates, whereas capath should point to a</span>
+<span class="sd"> directory of hashed certificate files. More information can be found in</span>
+<span class="sd"> ssl.SSLContext.load_verify_locations().</span>
+
+<span class="sd"> The *cadefault* parameter is ignored.</span>
+
+<span class="sd"> This function always returns an object which can work as a context</span>
+<span class="sd"> manager and has methods such as</span>
+
+<span class="sd"> * geturl() - return the URL of the resource retrieved, commonly used to</span>
+<span class="sd"> determine if a redirect was followed</span>
+
+<span class="sd"> * info() - return the meta-information of the page, such as headers, in the</span>
+<span class="sd"> form of an email.message_from_string() instance (see Quick Reference to</span>
+<span class="sd"> HTTP Headers)</span>
+
+<span class="sd"> * getcode() - return the HTTP status code of the response. Raises URLError</span>
+<span class="sd"> on errors.</span>
+
+<span class="sd"> For HTTP and HTTPS URLs, this function returns a http.client.HTTPResponse</span>
+<span class="sd"> object slightly modified. In addition to the three new methods above, the</span>
+<span class="sd"> msg attribute contains the same information as the reason attribute ---</span>
+<span class="sd"> the reason phrase returned by the server --- instead of the response</span>
+<span class="sd"> headers as it is specified in the documentation for HTTPResponse.</span>
+
+<span class="sd"> For FTP, file, and data URLs and requests explicitly handled by legacy</span>
+<span class="sd"> URLopener and FancyURLopener classes, this function returns a</span>
+<span class="sd"> urllib.response.addinfourl object.</span>
+
+<span class="sd"> Note that None may be returned if no handler handles the request (though</span>
+<span class="sd"> the default installed global OpenerDirector uses UnknownHandler to ensure</span>
+<span class="sd"> this never happens).</span>
+
+<span class="sd"> In addition, if proxy settings are detected (for example, when a *_proxy</span>
+<span class="sd"> environment variable like http_proxy is set), ProxyHandler is default</span>
+<span class="sd"> installed and makes sure the requests are handled through the proxy.</span>
+
+<span class="sd"> &#39;&#39;&#39;</span>
+ <span class="k">global</span> <span class="n">_opener</span>
+ <span class="k">if</span> <span class="n">cafile</span> <span class="ow">or</span> <span class="n">capath</span> <span class="ow">or</span> <span class="n">cadefault</span><span class="p">:</span>
+ <span class="kn">import</span> <span class="nn">warnings</span>
+ <span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span><span class="s2">&quot;cafile, capath and cadefault are deprecated, use a &quot;</span>
+ <span class="s2">&quot;custom context instead.&quot;</span><span class="p">,</span> <span class="ne">DeprecationWarning</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">context</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
+ <span class="s2">&quot;You can&#39;t pass both context and any of cafile, capath, and &quot;</span>
+ <span class="s2">&quot;cadefault&quot;</span>
+ <span class="p">)</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">_have_ssl</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">&#39;SSL support not available&#39;</span><span class="p">)</span>
+ <span class="n">context</span> <span class="o">=</span> <span class="n">ssl</span><span class="o">.</span><span class="n">create_default_context</span><span class="p">(</span><span class="n">ssl</span><span class="o">.</span><span class="n">Purpose</span><span class="o">.</span><span class="n">SERVER_AUTH</span><span class="p">,</span>
+ <span class="n">cafile</span><span class="o">=</span><span class="n">cafile</span><span class="p">,</span>
+ <span class="n">capath</span><span class="o">=</span><span class="n">capath</span><span class="p">)</span>
+ <span class="n">https_handler</span> <span class="o">=</span> <span class="n">HTTPSHandler</span><span class="p">(</span><span class="n">context</span><span class="o">=</span><span class="n">context</span><span class="p">)</span>
+ <span class="n">opener</span> <span class="o">=</span> <span class="n">build_opener</span><span class="p">(</span><span class="n">https_handler</span><span class="p">)</span>
+ <span class="k">elif</span> <span class="n">context</span><span class="p">:</span>
+ <span class="n">https_handler</span> <span class="o">=</span> <span class="n">HTTPSHandler</span><span class="p">(</span><span class="n">context</span><span class="o">=</span><span class="n">context</span><span class="p">)</span>
+ <span class="n">opener</span> <span class="o">=</span> <span class="n">build_opener</span><span class="p">(</span><span class="n">https_handler</span><span class="p">)</span>
+ <span class="k">elif</span> <span class="n">_opener</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">_opener</span> <span class="o">=</span> <span class="n">opener</span> <span class="o">=</span> <span class="n">build_opener</span><span class="p">()</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">opener</span> <span class="o">=</span> <span class="n">_opener</span>
+ <span class="k">return</span> <span class="n">opener</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">timeout</span><span class="p">)</span>
+
+<span class="k">def</span> <span class="nf">install_opener</span><span class="p">(</span><span class="n">opener</span><span class="p">):</span>
+ <span class="k">global</span> <span class="n">_opener</span>
+ <span class="n">_opener</span> <span class="o">=</span> <span class="n">opener</span>
+
+<span class="n">_url_tempfiles</span> <span class="o">=</span> <span class="p">[]</span>
+<span class="k">def</span> <span class="nf">urlretrieve</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">filename</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">reporthook</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Retrieve a URL into a temporary location on disk.</span>
+
+<span class="sd"> Requires a URL argument. If a filename is passed, it is used as</span>
+<span class="sd"> the temporary file location. The reporthook argument should be</span>
+<span class="sd"> a callable that accepts a block number, a read size, and the</span>
+<span class="sd"> total file size of the URL target. The data argument should be</span>
+<span class="sd"> valid URL encoded data.</span>
+
+<span class="sd"> If a filename is passed and the URL points to a local resource,</span>
+<span class="sd"> the result is a copy from local file to new file.</span>
+
+<span class="sd"> Returns a tuple containing the path to the newly created</span>
+<span class="sd"> data file as well as the resulting HTTPMessage object.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">url_type</span><span class="p">,</span> <span class="n">path</span> <span class="o">=</span> <span class="n">splittype</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
+
+ <span class="k">with</span> <span class="n">contextlib</span><span class="o">.</span><span class="n">closing</span><span class="p">(</span><span class="n">urlopen</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">data</span><span class="p">))</span> <span class="k">as</span> <span class="n">fp</span><span class="p">:</span>
+ <span class="n">headers</span> <span class="o">=</span> <span class="n">fp</span><span class="o">.</span><span class="n">info</span><span class="p">()</span>
+
+ <span class="c1"># Just return the local path and the &quot;headers&quot; for file://</span>
+ <span class="c1"># URLs. No sense in performing a copy unless requested.</span>
+ <span class="k">if</span> <span class="n">url_type</span> <span class="o">==</span> <span class="s2">&quot;file&quot;</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">filename</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">normpath</span><span class="p">(</span><span class="n">path</span><span class="p">),</span> <span class="n">headers</span>
+
+ <span class="c1"># Handle temporary file setup.</span>
+ <span class="k">if</span> <span class="n">filename</span><span class="p">:</span>
+ <span class="n">tfp</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="s1">&#39;wb&#39;</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">tfp</span> <span class="o">=</span> <span class="n">tempfile</span><span class="o">.</span><span class="n">NamedTemporaryFile</span><span class="p">(</span><span class="n">delete</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
+ <span class="n">filename</span> <span class="o">=</span> <span class="n">tfp</span><span class="o">.</span><span class="n">name</span>
+ <span class="n">_url_tempfiles</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span>
+
+ <span class="k">with</span> <span class="n">tfp</span><span class="p">:</span>
+ <span class="n">result</span> <span class="o">=</span> <span class="n">filename</span><span class="p">,</span> <span class="n">headers</span>
+ <span class="n">bs</span> <span class="o">=</span> <span class="mi">1024</span><span class="o">*</span><span class="mi">8</span>
+ <span class="n">size</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span>
+ <span class="n">read</span> <span class="o">=</span> <span class="mi">0</span>
+ <span class="n">blocknum</span> <span class="o">=</span> <span class="mi">0</span>
+ <span class="k">if</span> <span class="s2">&quot;content-length&quot;</span> <span class="ow">in</span> <span class="n">headers</span><span class="p">:</span>
+ <span class="n">size</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">headers</span><span class="p">[</span><span class="s2">&quot;Content-Length&quot;</span><span class="p">])</span>
+
+ <span class="k">if</span> <span class="n">reporthook</span><span class="p">:</span>
+ <span class="n">reporthook</span><span class="p">(</span><span class="n">blocknum</span><span class="p">,</span> <span class="n">bs</span><span class="p">,</span> <span class="n">size</span><span class="p">)</span>
+
+ <span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
+ <span class="n">block</span> <span class="o">=</span> <span class="n">fp</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="n">bs</span><span class="p">)</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">block</span><span class="p">:</span>
+ <span class="k">break</span>
+ <span class="n">read</span> <span class="o">+=</span> <span class="nb">len</span><span class="p">(</span><span class="n">block</span><span class="p">)</span>
+ <span class="n">tfp</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">block</span><span class="p">)</span>
+ <span class="n">blocknum</span> <span class="o">+=</span> <span class="mi">1</span>
+ <span class="k">if</span> <span class="n">reporthook</span><span class="p">:</span>
+ <span class="n">reporthook</span><span class="p">(</span><span class="n">blocknum</span><span class="p">,</span> <span class="n">bs</span><span class="p">,</span> <span class="n">size</span><span class="p">)</span>
+
+ <span class="k">if</span> <span class="n">size</span> <span class="o">&gt;=</span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">read</span> <span class="o">&lt;</span> <span class="n">size</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="n">ContentTooShortError</span><span class="p">(</span>
+ <span class="s2">&quot;retrieval incomplete: got only </span><span class="si">%i</span><span class="s2"> out of </span><span class="si">%i</span><span class="s2"> bytes&quot;</span>
+ <span class="o">%</span> <span class="p">(</span><span class="n">read</span><span class="p">,</span> <span class="n">size</span><span class="p">),</span> <span class="n">result</span><span class="p">)</span>
+
+ <span class="k">return</span> <span class="n">result</span>
+
+<span class="k">def</span> <span class="nf">urlcleanup</span><span class="p">():</span>
+ <span class="sd">&quot;&quot;&quot;Clean up temporary files from urlretrieve calls.&quot;&quot;&quot;</span>
+ <span class="k">for</span> <span class="n">temp_file</span> <span class="ow">in</span> <span class="n">_url_tempfiles</span><span class="p">:</span>
+ <span class="k">try</span><span class="p">:</span>
+ <span class="n">os</span><span class="o">.</span><span class="n">unlink</span><span class="p">(</span><span class="n">temp_file</span><span class="p">)</span>
+ <span class="k">except</span> <span class="ne">OSError</span><span class="p">:</span>
+ <span class="k">pass</span>
+
+ <span class="k">del</span> <span class="n">_url_tempfiles</span><span class="p">[:]</span>
+ <span class="k">global</span> <span class="n">_opener</span>
+ <span class="k">if</span> <span class="n">_opener</span><span class="p">:</span>
+ <span class="n">_opener</span> <span class="o">=</span> <span class="kc">None</span>
+
+<span class="c1"># copied from cookielib.py</span>
+<span class="n">_cut_port_re</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="sa">r</span><span class="s2">&quot;:\d+$&quot;</span><span class="p">,</span> <span class="n">re</span><span class="o">.</span><span class="n">ASCII</span><span class="p">)</span>
+<span class="k">def</span> <span class="nf">request_host</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Return request-host, as defined by RFC 2965.</span>
+
+<span class="sd"> Variation from RFC: returned value is lowercased, for convenient</span>
+<span class="sd"> comparison.</span>
+
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">url</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">full_url</span>
+ <span class="n">host</span> <span class="o">=</span> <span class="n">urlparse</span><span class="p">(</span><span class="n">url</span><span class="p">)[</span><span class="mi">1</span><span class="p">]</span>
+ <span class="k">if</span> <span class="n">host</span> <span class="o">==</span> <span class="s2">&quot;&quot;</span><span class="p">:</span>
+ <span class="n">host</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">get_header</span><span class="p">(</span><span class="s2">&quot;Host&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">)</span>
+
+ <span class="c1"># remove port, if present</span>
+ <span class="n">host</span> <span class="o">=</span> <span class="n">_cut_port_re</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="n">host</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">host</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
+
+<span class="k">class</span> <span class="nc">Request</span><span class="p">:</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="p">{},</span>
+ <span class="n">origin_req_host</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">unverifiable</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
+ <span class="n">method</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">full_url</span> <span class="o">=</span> <span class="n">url</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">headers</span> <span class="o">=</span> <span class="p">{}</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">unredirected_hdrs</span> <span class="o">=</span> <span class="p">{}</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_data</span> <span class="o">=</span> <span class="kc">None</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">data</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_tunnel_host</span> <span class="o">=</span> <span class="kc">None</span>
+ <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">headers</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">add_header</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">origin_req_host</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">origin_req_host</span> <span class="o">=</span> <span class="n">request_host</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">origin_req_host</span> <span class="o">=</span> <span class="n">origin_req_host</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">unverifiable</span> <span class="o">=</span> <span class="n">unverifiable</span>
+ <span class="k">if</span> <span class="n">method</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">method</span> <span class="o">=</span> <span class="n">method</span>
+
+ <span class="nd">@property</span>
+ <span class="k">def</span> <span class="nf">full_url</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">fragment</span><span class="p">:</span>
+ <span class="k">return</span> <span class="s1">&#39;</span><span class="si">{}</span><span class="s1">#</span><span class="si">{}</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_full_url</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">fragment</span><span class="p">)</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_full_url</span>
+
+ <span class="nd">@full_url</span><span class="o">.</span><span class="n">setter</span>
+ <span class="k">def</span> <span class="nf">full_url</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">url</span><span class="p">):</span>
+ <span class="c1"># unwrap(&#39;&lt;URL:type://host/path&gt;&#39;) --&gt; &#39;type://host/path&#39;</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_full_url</span> <span class="o">=</span> <span class="n">unwrap</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_full_url</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">fragment</span> <span class="o">=</span> <span class="n">splittag</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_full_url</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_parse</span><span class="p">()</span>
+
+ <span class="nd">@full_url</span><span class="o">.</span><span class="n">deleter</span>
+ <span class="k">def</span> <span class="nf">full_url</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_full_url</span> <span class="o">=</span> <span class="kc">None</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">fragment</span> <span class="o">=</span> <span class="kc">None</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">selector</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
+
+ <span class="nd">@property</span>
+ <span class="k">def</span> <span class="nf">data</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_data</span>
+
+ <span class="nd">@data</span><span class="o">.</span><span class="n">setter</span>
+ <span class="k">def</span> <span class="nf">data</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
+ <span class="k">if</span> <span class="n">data</span> <span class="o">!=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_data</span> <span class="o">=</span> <span class="n">data</span>
+ <span class="c1"># issue 16464</span>
+ <span class="c1"># if we change data we need to remove content-length header</span>
+ <span class="c1"># (cause it&#39;s most probably calculated for previous value)</span>
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">has_header</span><span class="p">(</span><span class="s2">&quot;Content-length&quot;</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">remove_header</span><span class="p">(</span><span class="s2">&quot;Content-length&quot;</span><span class="p">)</span>
+
+ <span class="nd">@data</span><span class="o">.</span><span class="n">deleter</span>
+ <span class="k">def</span> <span class="nf">data</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="kc">None</span>
+
+ <span class="k">def</span> <span class="nf">_parse</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">type</span><span class="p">,</span> <span class="n">rest</span> <span class="o">=</span> <span class="n">splittype</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_full_url</span><span class="p">)</span>
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">type</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;unknown url type: </span><span class="si">%r</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">full_url</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">host</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">selector</span> <span class="o">=</span> <span class="n">splithost</span><span class="p">(</span><span class="n">rest</span><span class="p">)</span>
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">host</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">host</span> <span class="o">=</span> <span class="n">unquote</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">host</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">get_method</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Return a string indicating the HTTP request method.&quot;&quot;&quot;</span>
+ <span class="n">default_method</span> <span class="o">=</span> <span class="s2">&quot;POST&quot;</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="k">else</span> <span class="s2">&quot;GET&quot;</span>
+ <span class="k">return</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;method&#39;</span><span class="p">,</span> <span class="n">default_method</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">get_full_url</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">full_url</span>
+
+ <span class="k">def</span> <span class="nf">set_proxy</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">host</span><span class="p">,</span> <span class="nb">type</span><span class="p">):</span>
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">type</span> <span class="o">==</span> <span class="s1">&#39;https&#39;</span> <span class="ow">and</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_tunnel_host</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_tunnel_host</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">host</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">type</span><span class="o">=</span> <span class="nb">type</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">selector</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">full_url</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">host</span> <span class="o">=</span> <span class="n">host</span>
+
+ <span class="k">def</span> <span class="nf">has_proxy</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">selector</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">full_url</span>
+
+ <span class="k">def</span> <span class="nf">add_header</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">val</span><span class="p">):</span>
+ <span class="c1"># useful for something like authentication</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">headers</span><span class="p">[</span><span class="n">key</span><span class="o">.</span><span class="n">capitalize</span><span class="p">()]</span> <span class="o">=</span> <span class="n">val</span>
+
+ <span class="k">def</span> <span class="nf">add_unredirected_header</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">val</span><span class="p">):</span>
+ <span class="c1"># will not be added to a redirected request</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">unredirected_hdrs</span><span class="p">[</span><span class="n">key</span><span class="o">.</span><span class="n">capitalize</span><span class="p">()]</span> <span class="o">=</span> <span class="n">val</span>
+
+ <span class="k">def</span> <span class="nf">has_header</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">header_name</span><span class="p">):</span>
+ <span class="k">return</span> <span class="p">(</span><span class="n">header_name</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">headers</span> <span class="ow">or</span>
+ <span class="n">header_name</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">unredirected_hdrs</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">get_header</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">header_name</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">headers</span><span class="o">.</span><span class="n">get</span><span class="p">(</span>
+ <span class="n">header_name</span><span class="p">,</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">unredirected_hdrs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">header_name</span><span class="p">,</span> <span class="n">default</span><span class="p">))</span>
+
+ <span class="k">def</span> <span class="nf">remove_header</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">header_name</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">headers</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="n">header_name</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">unredirected_hdrs</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="n">header_name</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">header_items</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="n">hdrs</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">unredirected_hdrs</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
+ <span class="n">hdrs</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">headers</span><span class="p">)</span>
+ <span class="k">return</span> <span class="nb">list</span><span class="p">(</span><span class="n">hdrs</span><span class="o">.</span><span class="n">items</span><span class="p">())</span>
+
+<span class="k">class</span> <span class="nc">OpenerDirector</span><span class="p">:</span>
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="n">client_version</span> <span class="o">=</span> <span class="s2">&quot;Python-urllib/</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">__version__</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">addheaders</span> <span class="o">=</span> <span class="p">[(</span><span class="s1">&#39;User-agent&#39;</span><span class="p">,</span> <span class="n">client_version</span><span class="p">)]</span>
+ <span class="c1"># self.handlers is retained only for backward compatibility</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">handlers</span> <span class="o">=</span> <span class="p">[]</span>
+ <span class="c1"># manage the individual handlers</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">handle_open</span> <span class="o">=</span> <span class="p">{}</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">handle_error</span> <span class="o">=</span> <span class="p">{}</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">process_response</span> <span class="o">=</span> <span class="p">{}</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">process_request</span> <span class="o">=</span> <span class="p">{}</span>
+
+ <span class="k">def</span> <span class="nf">add_handler</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">handler</span><span class="p">):</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">handler</span><span class="p">,</span> <span class="s2">&quot;add_parent&quot;</span><span class="p">):</span>
+ <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s2">&quot;expected BaseHandler instance, got </span><span class="si">%r</span><span class="s2">&quot;</span> <span class="o">%</span>
+ <span class="nb">type</span><span class="p">(</span><span class="n">handler</span><span class="p">))</span>
+
+ <span class="n">added</span> <span class="o">=</span> <span class="kc">False</span>
+ <span class="k">for</span> <span class="n">meth</span> <span class="ow">in</span> <span class="nb">dir</span><span class="p">(</span><span class="n">handler</span><span class="p">):</span>
+ <span class="k">if</span> <span class="n">meth</span> <span class="ow">in</span> <span class="p">[</span><span class="s2">&quot;redirect_request&quot;</span><span class="p">,</span> <span class="s2">&quot;do_open&quot;</span><span class="p">,</span> <span class="s2">&quot;proxy_open&quot;</span><span class="p">]:</span>
+ <span class="c1"># oops, coincidental match</span>
+ <span class="k">continue</span>
+
+ <span class="n">i</span> <span class="o">=</span> <span class="n">meth</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s2">&quot;_&quot;</span><span class="p">)</span>
+ <span class="n">protocol</span> <span class="o">=</span> <span class="n">meth</span><span class="p">[:</span><span class="n">i</span><span class="p">]</span>
+ <span class="n">condition</span> <span class="o">=</span> <span class="n">meth</span><span class="p">[</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">:]</span>
+
+ <span class="k">if</span> <span class="n">condition</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">&quot;error&quot;</span><span class="p">):</span>
+ <span class="n">j</span> <span class="o">=</span> <span class="n">condition</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s2">&quot;_&quot;</span><span class="p">)</span> <span class="o">+</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">1</span>
+ <span class="n">kind</span> <span class="o">=</span> <span class="n">meth</span><span class="p">[</span><span class="n">j</span><span class="o">+</span><span class="mi">1</span><span class="p">:]</span>
+ <span class="k">try</span><span class="p">:</span>
+ <span class="n">kind</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">kind</span><span class="p">)</span>
+ <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
+ <span class="k">pass</span>
+ <span class="n">lookup</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">handle_error</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">protocol</span><span class="p">,</span> <span class="p">{})</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">handle_error</span><span class="p">[</span><span class="n">protocol</span><span class="p">]</span> <span class="o">=</span> <span class="n">lookup</span>
+ <span class="k">elif</span> <span class="n">condition</span> <span class="o">==</span> <span class="s2">&quot;open&quot;</span><span class="p">:</span>
+ <span class="n">kind</span> <span class="o">=</span> <span class="n">protocol</span>
+ <span class="n">lookup</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">handle_open</span>
+ <span class="k">elif</span> <span class="n">condition</span> <span class="o">==</span> <span class="s2">&quot;response&quot;</span><span class="p">:</span>
+ <span class="n">kind</span> <span class="o">=</span> <span class="n">protocol</span>
+ <span class="n">lookup</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">process_response</span>
+ <span class="k">elif</span> <span class="n">condition</span> <span class="o">==</span> <span class="s2">&quot;request&quot;</span><span class="p">:</span>
+ <span class="n">kind</span> <span class="o">=</span> <span class="n">protocol</span>
+ <span class="n">lookup</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">process_request</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">continue</span>
+
+ <span class="n">handlers</span> <span class="o">=</span> <span class="n">lookup</span><span class="o">.</span><span class="n">setdefault</span><span class="p">(</span><span class="n">kind</span><span class="p">,</span> <span class="p">[])</span>
+ <span class="k">if</span> <span class="n">handlers</span><span class="p">:</span>
+ <span class="n">bisect</span><span class="o">.</span><span class="n">insort</span><span class="p">(</span><span class="n">handlers</span><span class="p">,</span> <span class="n">handler</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">handlers</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">handler</span><span class="p">)</span>
+ <span class="n">added</span> <span class="o">=</span> <span class="kc">True</span>
+
+ <span class="k">if</span> <span class="n">added</span><span class="p">:</span>
+ <span class="n">bisect</span><span class="o">.</span><span class="n">insort</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">handlers</span><span class="p">,</span> <span class="n">handler</span><span class="p">)</span>
+ <span class="n">handler</span><span class="o">.</span><span class="n">add_parent</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">close</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># Only exists for backwards compatibility.</span>
+ <span class="k">pass</span>
+
+ <span class="k">def</span> <span class="nf">_call_chain</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">chain</span><span class="p">,</span> <span class="n">kind</span><span class="p">,</span> <span class="n">meth_name</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">):</span>
+ <span class="c1"># Handlers raise an exception if no one else should try to handle</span>
+ <span class="c1"># the request, or return None if they can&#39;t but another handler</span>
+ <span class="c1"># could. Otherwise, they return the response.</span>
+ <span class="n">handlers</span> <span class="o">=</span> <span class="n">chain</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">kind</span><span class="p">,</span> <span class="p">())</span>
+ <span class="k">for</span> <span class="n">handler</span> <span class="ow">in</span> <span class="n">handlers</span><span class="p">:</span>
+ <span class="n">func</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">handler</span><span class="p">,</span> <span class="n">meth_name</span><span class="p">)</span>
+ <span class="n">result</span> <span class="o">=</span> <span class="n">func</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">result</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">result</span>
+
+ <span class="k">def</span> <span class="nf">open</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">fullurl</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">timeout</span><span class="o">=</span><span class="n">socket</span><span class="o">.</span><span class="n">_GLOBAL_DEFAULT_TIMEOUT</span><span class="p">):</span>
+ <span class="c1"># accept a URL or a Request object</span>
+ <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">fullurl</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
+ <span class="n">req</span> <span class="o">=</span> <span class="n">Request</span><span class="p">(</span><span class="n">fullurl</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">req</span> <span class="o">=</span> <span class="n">fullurl</span>
+ <span class="k">if</span> <span class="n">data</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">req</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">data</span>
+
+ <span class="n">req</span><span class="o">.</span><span class="n">timeout</span> <span class="o">=</span> <span class="n">timeout</span>
+ <span class="n">protocol</span> <span class="o">=</span> <span class="n">req</span><span class="o">.</span><span class="n">type</span>
+
+ <span class="c1"># pre-process request</span>
+ <span class="n">meth_name</span> <span class="o">=</span> <span class="n">protocol</span><span class="o">+</span><span class="s2">&quot;_request&quot;</span>
+ <span class="k">for</span> <span class="n">processor</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">process_request</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">protocol</span><span class="p">,</span> <span class="p">[]):</span>
+ <span class="n">meth</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">processor</span><span class="p">,</span> <span class="n">meth_name</span><span class="p">)</span>
+ <span class="n">req</span> <span class="o">=</span> <span class="n">meth</span><span class="p">(</span><span class="n">req</span><span class="p">)</span>
+
+ <span class="n">response</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_open</span><span class="p">(</span><span class="n">req</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span>
+
+ <span class="c1"># post-process response</span>
+ <span class="n">meth_name</span> <span class="o">=</span> <span class="n">protocol</span><span class="o">+</span><span class="s2">&quot;_response&quot;</span>
+ <span class="k">for</span> <span class="n">processor</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">process_response</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">protocol</span><span class="p">,</span> <span class="p">[]):</span>
+ <span class="n">meth</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">processor</span><span class="p">,</span> <span class="n">meth_name</span><span class="p">)</span>
+ <span class="n">response</span> <span class="o">=</span> <span class="n">meth</span><span class="p">(</span><span class="n">req</span><span class="p">,</span> <span class="n">response</span><span class="p">)</span>
+
+ <span class="k">return</span> <span class="n">response</span>
+
+ <span class="k">def</span> <span class="nf">_open</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">req</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="n">result</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_call_chain</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">handle_open</span><span class="p">,</span> <span class="s1">&#39;default&#39;</span><span class="p">,</span>
+ <span class="s1">&#39;default_open&#39;</span><span class="p">,</span> <span class="n">req</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">result</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">result</span>
+
+ <span class="n">protocol</span> <span class="o">=</span> <span class="n">req</span><span class="o">.</span><span class="n">type</span>
+ <span class="n">result</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_call_chain</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">handle_open</span><span class="p">,</span> <span class="n">protocol</span><span class="p">,</span> <span class="n">protocol</span> <span class="o">+</span>
+ <span class="s1">&#39;_open&#39;</span><span class="p">,</span> <span class="n">req</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">result</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">result</span>
+
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_call_chain</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">handle_open</span><span class="p">,</span> <span class="s1">&#39;unknown&#39;</span><span class="p">,</span>
+ <span class="s1">&#39;unknown_open&#39;</span><span class="p">,</span> <span class="n">req</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">error</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">proto</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">):</span>
+ <span class="k">if</span> <span class="n">proto</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">&#39;http&#39;</span><span class="p">,</span> <span class="s1">&#39;https&#39;</span><span class="p">):</span>
+ <span class="c1"># XXX http[s] protocols are special-cased</span>
+ <span class="nb">dict</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">handle_error</span><span class="p">[</span><span class="s1">&#39;http&#39;</span><span class="p">]</span> <span class="c1"># https is not different than http</span>
+ <span class="n">proto</span> <span class="o">=</span> <span class="n">args</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="c1"># YUCK!</span>
+ <span class="n">meth_name</span> <span class="o">=</span> <span class="s1">&#39;http_error_</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">proto</span>
+ <span class="n">http_err</span> <span class="o">=</span> <span class="mi">1</span>
+ <span class="n">orig_args</span> <span class="o">=</span> <span class="n">args</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="nb">dict</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">handle_error</span>
+ <span class="n">meth_name</span> <span class="o">=</span> <span class="n">proto</span> <span class="o">+</span> <span class="s1">&#39;_error&#39;</span>
+ <span class="n">http_err</span> <span class="o">=</span> <span class="mi">0</span>
+ <span class="n">args</span> <span class="o">=</span> <span class="p">(</span><span class="nb">dict</span><span class="p">,</span> <span class="n">proto</span><span class="p">,</span> <span class="n">meth_name</span><span class="p">)</span> <span class="o">+</span> <span class="n">args</span>
+ <span class="n">result</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_call_chain</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">result</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">result</span>
+
+ <span class="k">if</span> <span class="n">http_err</span><span class="p">:</span>
+ <span class="n">args</span> <span class="o">=</span> <span class="p">(</span><span class="nb">dict</span><span class="p">,</span> <span class="s1">&#39;default&#39;</span><span class="p">,</span> <span class="s1">&#39;http_error_default&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="n">orig_args</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_call_chain</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">)</span>
+
+<span class="c1"># XXX probably also want an abstract factory that knows when it makes</span>
+<span class="c1"># sense to skip a superclass in favor of a subclass and when it might</span>
+<span class="c1"># make sense to include both</span>
+
+<span class="k">def</span> <span class="nf">build_opener</span><span class="p">(</span><span class="o">*</span><span class="n">handlers</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Create an opener object from a list of handlers.</span>
+
+<span class="sd"> The opener will use several default handlers, including support</span>
+<span class="sd"> for HTTP, FTP and when applicable HTTPS.</span>
+
+<span class="sd"> If any of the handlers passed as arguments are subclasses of the</span>
+<span class="sd"> default handlers, the default handlers will not be used.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">opener</span> <span class="o">=</span> <span class="n">OpenerDirector</span><span class="p">()</span>
+ <span class="n">default_classes</span> <span class="o">=</span> <span class="p">[</span><span class="n">ProxyHandler</span><span class="p">,</span> <span class="n">UnknownHandler</span><span class="p">,</span> <span class="n">HTTPHandler</span><span class="p">,</span>
+ <span class="n">HTTPDefaultErrorHandler</span><span class="p">,</span> <span class="n">HTTPRedirectHandler</span><span class="p">,</span>
+ <span class="n">FTPHandler</span><span class="p">,</span> <span class="n">FileHandler</span><span class="p">,</span> <span class="n">HTTPErrorProcessor</span><span class="p">,</span>
+ <span class="n">DataHandler</span><span class="p">]</span>
+ <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">http</span><span class="o">.</span><span class="n">client</span><span class="p">,</span> <span class="s2">&quot;HTTPSConnection&quot;</span><span class="p">):</span>
+ <span class="n">default_classes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">HTTPSHandler</span><span class="p">)</span>
+ <span class="n">skip</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
+ <span class="k">for</span> <span class="n">klass</span> <span class="ow">in</span> <span class="n">default_classes</span><span class="p">:</span>
+ <span class="k">for</span> <span class="n">check</span> <span class="ow">in</span> <span class="n">handlers</span><span class="p">:</span>
+ <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">check</span><span class="p">,</span> <span class="nb">type</span><span class="p">):</span>
+ <span class="k">if</span> <span class="nb">issubclass</span><span class="p">(</span><span class="n">check</span><span class="p">,</span> <span class="n">klass</span><span class="p">):</span>
+ <span class="n">skip</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">klass</span><span class="p">)</span>
+ <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">check</span><span class="p">,</span> <span class="n">klass</span><span class="p">):</span>
+ <span class="n">skip</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">klass</span><span class="p">)</span>
+ <span class="k">for</span> <span class="n">klass</span> <span class="ow">in</span> <span class="n">skip</span><span class="p">:</span>
+ <span class="n">default_classes</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">klass</span><span class="p">)</span>
+
+ <span class="k">for</span> <span class="n">klass</span> <span class="ow">in</span> <span class="n">default_classes</span><span class="p">:</span>
+ <span class="n">opener</span><span class="o">.</span><span class="n">add_handler</span><span class="p">(</span><span class="n">klass</span><span class="p">())</span>
+
+ <span class="k">for</span> <span class="n">h</span> <span class="ow">in</span> <span class="n">handlers</span><span class="p">:</span>
+ <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">h</span><span class="p">,</span> <span class="nb">type</span><span class="p">):</span>
+ <span class="n">h</span> <span class="o">=</span> <span class="n">h</span><span class="p">()</span>
+ <span class="n">opener</span><span class="o">.</span><span class="n">add_handler</span><span class="p">(</span><span class="n">h</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">opener</span>
+
+<span class="k">class</span> <span class="nc">BaseHandler</span><span class="p">:</span>
+ <span class="n">handler_order</span> <span class="o">=</span> <span class="mi">500</span>
+
+ <span class="k">def</span> <span class="nf">add_parent</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">parent</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">parent</span> <span class="o">=</span> <span class="n">parent</span>
+
+ <span class="k">def</span> <span class="nf">close</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># Only exists for backwards compatibility</span>
+ <span class="k">pass</span>
+
+ <span class="k">def</span> <span class="nf">__lt__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="s2">&quot;handler_order&quot;</span><span class="p">):</span>
+ <span class="c1"># Try to preserve the old behavior of having custom classes</span>
+ <span class="c1"># inserted after default ones (works only for custom user</span>
+ <span class="c1"># classes which are not aware of handler_order).</span>
+ <span class="k">return</span> <span class="kc">True</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">handler_order</span> <span class="o">&lt;</span> <span class="n">other</span><span class="o">.</span><span class="n">handler_order</span>
+
+
+<span class="k">class</span> <span class="nc">HTTPErrorProcessor</span><span class="p">(</span><span class="n">BaseHandler</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Process HTTP error responses.&quot;&quot;&quot;</span>
+ <span class="n">handler_order</span> <span class="o">=</span> <span class="mi">1000</span> <span class="c1"># after all other processing</span>
+
+ <span class="k">def</span> <span class="nf">http_response</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">,</span> <span class="n">response</span><span class="p">):</span>
+ <span class="n">code</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="n">hdrs</span> <span class="o">=</span> <span class="n">response</span><span class="o">.</span><span class="n">code</span><span class="p">,</span> <span class="n">response</span><span class="o">.</span><span class="n">msg</span><span class="p">,</span> <span class="n">response</span><span class="o">.</span><span class="n">info</span><span class="p">()</span>
+
+ <span class="c1"># According to RFC 2616, &quot;2xx&quot; code indicates that the client&#39;s</span>
+ <span class="c1"># request was successfully received, understood, and accepted.</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="p">(</span><span class="mi">200</span> <span class="o">&lt;=</span> <span class="n">code</span> <span class="o">&lt;</span> <span class="mi">300</span><span class="p">):</span>
+ <span class="n">response</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">parent</span><span class="o">.</span><span class="n">error</span><span class="p">(</span>
+ <span class="s1">&#39;http&#39;</span><span class="p">,</span> <span class="n">request</span><span class="p">,</span> <span class="n">response</span><span class="p">,</span> <span class="n">code</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="n">hdrs</span><span class="p">)</span>
+
+ <span class="k">return</span> <span class="n">response</span>
+
+ <span class="n">https_response</span> <span class="o">=</span> <span class="n">http_response</span>
+
+<span class="k">class</span> <span class="nc">HTTPDefaultErrorHandler</span><span class="p">(</span><span class="n">BaseHandler</span><span class="p">):</span>
+ <span class="k">def</span> <span class="nf">http_error_default</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">req</span><span class="p">,</span> <span class="n">fp</span><span class="p">,</span> <span class="n">code</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="n">hdrs</span><span class="p">):</span>
+ <span class="k">raise</span> <span class="n">HTTPError</span><span class="p">(</span><span class="n">req</span><span class="o">.</span><span class="n">full_url</span><span class="p">,</span> <span class="n">code</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="n">hdrs</span><span class="p">,</span> <span class="n">fp</span><span class="p">)</span>
+
+<span class="k">class</span> <span class="nc">HTTPRedirectHandler</span><span class="p">(</span><span class="n">BaseHandler</span><span class="p">):</span>
+ <span class="c1"># maximum number of redirections to any single URL</span>
+ <span class="c1"># this is needed because of the state that cookies introduce</span>
+ <span class="n">max_repeats</span> <span class="o">=</span> <span class="mi">4</span>
+ <span class="c1"># maximum total number of redirections (regardless of URL) before</span>
+ <span class="c1"># assuming we&#39;re in a loop</span>
+ <span class="n">max_redirections</span> <span class="o">=</span> <span class="mi">10</span>
+
+ <span class="k">def</span> <span class="nf">redirect_request</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">req</span><span class="p">,</span> <span class="n">fp</span><span class="p">,</span> <span class="n">code</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="n">headers</span><span class="p">,</span> <span class="n">newurl</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Return a Request or None in response to a redirect.</span>
+
+<span class="sd"> This is called by the http_error_30x methods when a</span>
+<span class="sd"> redirection response is received. If a redirection should</span>
+<span class="sd"> take place, return a new Request to allow http_error_30x to</span>
+<span class="sd"> perform the redirect. Otherwise, raise HTTPError if no-one</span>
+<span class="sd"> else should try to handle this url. Return None if you can&#39;t</span>
+<span class="sd"> but another Handler might.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">m</span> <span class="o">=</span> <span class="n">req</span><span class="o">.</span><span class="n">get_method</span><span class="p">()</span>
+ <span class="k">if</span> <span class="p">(</span><span class="ow">not</span> <span class="p">(</span><span class="n">code</span> <span class="ow">in</span> <span class="p">(</span><span class="mi">301</span><span class="p">,</span> <span class="mi">302</span><span class="p">,</span> <span class="mi">303</span><span class="p">,</span> <span class="mi">307</span><span class="p">)</span> <span class="ow">and</span> <span class="n">m</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">&quot;GET&quot;</span><span class="p">,</span> <span class="s2">&quot;HEAD&quot;</span><span class="p">)</span>
+ <span class="ow">or</span> <span class="n">code</span> <span class="ow">in</span> <span class="p">(</span><span class="mi">301</span><span class="p">,</span> <span class="mi">302</span><span class="p">,</span> <span class="mi">303</span><span class="p">)</span> <span class="ow">and</span> <span class="n">m</span> <span class="o">==</span> <span class="s2">&quot;POST&quot;</span><span class="p">)):</span>
+ <span class="k">raise</span> <span class="n">HTTPError</span><span class="p">(</span><span class="n">req</span><span class="o">.</span><span class="n">full_url</span><span class="p">,</span> <span class="n">code</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="n">headers</span><span class="p">,</span> <span class="n">fp</span><span class="p">)</span>
+
+ <span class="c1"># Strictly (according to RFC 2616), 301 or 302 in response to</span>
+ <span class="c1"># a POST MUST NOT cause a redirection without confirmation</span>
+ <span class="c1"># from the user (of urllib.request, in this case). In practice,</span>
+ <span class="c1"># essentially all clients do redirect in this case, so we do</span>
+ <span class="c1"># the same.</span>
+
+ <span class="c1"># Be conciliant with URIs containing a space. This is mainly</span>
+ <span class="c1"># redundant with the more complete encoding done in http_error_302(),</span>
+ <span class="c1"># but it is kept for compatibility with other callers.</span>
+ <span class="n">newurl</span> <span class="o">=</span> <span class="n">newurl</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="s1">&#39;%20&#39;</span><span class="p">)</span>
+
+ <span class="n">CONTENT_HEADERS</span> <span class="o">=</span> <span class="p">(</span><span class="s2">&quot;content-length&quot;</span><span class="p">,</span> <span class="s2">&quot;content-type&quot;</span><span class="p">)</span>
+ <span class="n">newheaders</span> <span class="o">=</span> <span class="p">{</span><span class="n">k</span><span class="p">:</span> <span class="n">v</span> <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">req</span><span class="o">.</span><span class="n">headers</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
+ <span class="k">if</span> <span class="n">k</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">CONTENT_HEADERS</span><span class="p">}</span>
+ <span class="k">return</span> <span class="n">Request</span><span class="p">(</span><span class="n">newurl</span><span class="p">,</span>
+ <span class="n">headers</span><span class="o">=</span><span class="n">newheaders</span><span class="p">,</span>
+ <span class="n">origin_req_host</span><span class="o">=</span><span class="n">req</span><span class="o">.</span><span class="n">origin_req_host</span><span class="p">,</span>
+ <span class="n">unverifiable</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
+
+ <span class="c1"># Implementation note: To avoid the server sending us into an</span>
+ <span class="c1"># infinite loop, the request object needs to track what URLs we</span>
+ <span class="c1"># have already seen. Do this by adding a handler-specific</span>
+ <span class="c1"># attribute to the Request object.</span>
+ <span class="k">def</span> <span class="nf">http_error_302</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">req</span><span class="p">,</span> <span class="n">fp</span><span class="p">,</span> <span class="n">code</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="n">headers</span><span class="p">):</span>
+ <span class="c1"># Some servers (incorrectly) return multiple Location headers</span>
+ <span class="c1"># (so probably same goes for URI). Use first header.</span>
+ <span class="k">if</span> <span class="s2">&quot;location&quot;</span> <span class="ow">in</span> <span class="n">headers</span><span class="p">:</span>
+ <span class="n">newurl</span> <span class="o">=</span> <span class="n">headers</span><span class="p">[</span><span class="s2">&quot;location&quot;</span><span class="p">]</span>
+ <span class="k">elif</span> <span class="s2">&quot;uri&quot;</span> <span class="ow">in</span> <span class="n">headers</span><span class="p">:</span>
+ <span class="n">newurl</span> <span class="o">=</span> <span class="n">headers</span><span class="p">[</span><span class="s2">&quot;uri&quot;</span><span class="p">]</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">return</span>
+
+ <span class="c1"># fix a possible malformed URL</span>
+ <span class="n">urlparts</span> <span class="o">=</span> <span class="n">urlparse</span><span class="p">(</span><span class="n">newurl</span><span class="p">)</span>
+
+ <span class="c1"># For security reasons we don&#39;t allow redirection to anything other</span>
+ <span class="c1"># than http, https or ftp.</span>
+
+ <span class="k">if</span> <span class="n">urlparts</span><span class="o">.</span><span class="n">scheme</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">&#39;http&#39;</span><span class="p">,</span> <span class="s1">&#39;https&#39;</span><span class="p">,</span> <span class="s1">&#39;ftp&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">):</span>
+ <span class="k">raise</span> <span class="n">HTTPError</span><span class="p">(</span>
+ <span class="n">newurl</span><span class="p">,</span> <span class="n">code</span><span class="p">,</span>
+ <span class="s2">&quot;</span><span class="si">%s</span><span class="s2"> - Redirection to url &#39;</span><span class="si">%s</span><span class="s2">&#39; is not allowed&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="n">newurl</span><span class="p">),</span>
+ <span class="n">headers</span><span class="p">,</span> <span class="n">fp</span><span class="p">)</span>
+
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">urlparts</span><span class="o">.</span><span class="n">path</span> <span class="ow">and</span> <span class="n">urlparts</span><span class="o">.</span><span class="n">netloc</span><span class="p">:</span>
+ <span class="n">urlparts</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">urlparts</span><span class="p">)</span>
+ <span class="n">urlparts</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;/&quot;</span>
+ <span class="n">newurl</span> <span class="o">=</span> <span class="n">urlunparse</span><span class="p">(</span><span class="n">urlparts</span><span class="p">)</span>
+
+ <span class="c1"># http.client.parse_headers() decodes as ISO-8859-1. Recover the</span>
+ <span class="c1"># original bytes and percent-encode non-ASCII bytes, and any special</span>
+ <span class="c1"># characters such as the space.</span>
+ <span class="n">newurl</span> <span class="o">=</span> <span class="n">quote</span><span class="p">(</span>
+ <span class="n">newurl</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s2">&quot;iso-8859-1&quot;</span><span class="p">,</span> <span class="n">safe</span><span class="o">=</span><span class="n">string</span><span class="o">.</span><span class="n">punctuation</span><span class="p">)</span>
+ <span class="n">newurl</span> <span class="o">=</span> <span class="n">urljoin</span><span class="p">(</span><span class="n">req</span><span class="o">.</span><span class="n">full_url</span><span class="p">,</span> <span class="n">newurl</span><span class="p">)</span>
+
+ <span class="c1"># XXX Probably want to forget about the state of the current</span>
+ <span class="c1"># request, although that might interact poorly with other</span>
+ <span class="c1"># handlers that also use handler-specific request attributes</span>
+ <span class="n">new</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">redirect_request</span><span class="p">(</span><span class="n">req</span><span class="p">,</span> <span class="n">fp</span><span class="p">,</span> <span class="n">code</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="n">headers</span><span class="p">,</span> <span class="n">newurl</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">new</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">return</span>
+
+ <span class="c1"># loop detection</span>
+ <span class="c1"># .redirect_dict has a key url if url was previously visited.</span>
+ <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">req</span><span class="p">,</span> <span class="s1">&#39;redirect_dict&#39;</span><span class="p">):</span>
+ <span class="n">visited</span> <span class="o">=</span> <span class="n">new</span><span class="o">.</span><span class="n">redirect_dict</span> <span class="o">=</span> <span class="n">req</span><span class="o">.</span><span class="n">redirect_dict</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">visited</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">newurl</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="bp">self</span><span class="o">.</span><span class="n">max_repeats</span> <span class="ow">or</span>
+ <span class="nb">len</span><span class="p">(</span><span class="n">visited</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="bp">self</span><span class="o">.</span><span class="n">max_redirections</span><span class="p">):</span>
+ <span class="k">raise</span> <span class="n">HTTPError</span><span class="p">(</span><span class="n">req</span><span class="o">.</span><span class="n">full_url</span><span class="p">,</span> <span class="n">code</span><span class="p">,</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">inf_msg</span> <span class="o">+</span> <span class="n">msg</span><span class="p">,</span> <span class="n">headers</span><span class="p">,</span> <span class="n">fp</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">visited</span> <span class="o">=</span> <span class="n">new</span><span class="o">.</span><span class="n">redirect_dict</span> <span class="o">=</span> <span class="n">req</span><span class="o">.</span><span class="n">redirect_dict</span> <span class="o">=</span> <span class="p">{}</span>
+ <span class="n">visited</span><span class="p">[</span><span class="n">newurl</span><span class="p">]</span> <span class="o">=</span> <span class="n">visited</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">newurl</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span>
+
+ <span class="c1"># Don&#39;t close the fp until we are sure that we won&#39;t use it</span>
+ <span class="c1"># with HTTPError.</span>
+ <span class="n">fp</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
+ <span class="n">fp</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
+
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">parent</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">new</span><span class="p">,</span> <span class="n">timeout</span><span class="o">=</span><span class="n">req</span><span class="o">.</span><span class="n">timeout</span><span class="p">)</span>
+
+ <span class="n">http_error_301</span> <span class="o">=</span> <span class="n">http_error_303</span> <span class="o">=</span> <span class="n">http_error_307</span> <span class="o">=</span> <span class="n">http_error_302</span>
+
+ <span class="n">inf_msg</span> <span class="o">=</span> <span class="s2">&quot;The HTTP server returned a redirect error that would &quot;</span> \
+ <span class="s2">&quot;lead to an infinite loop.</span><span class="se">\n</span><span class="s2">&quot;</span> \
+ <span class="s2">&quot;The last 30x error message was:</span><span class="se">\n</span><span class="s2">&quot;</span>
+
+
+<span class="k">def</span> <span class="nf">_parse_proxy</span><span class="p">(</span><span class="n">proxy</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Return (scheme, user, password, host/port) given a URL or an authority.</span>
+
+<span class="sd"> If a URL is supplied, it must have an authority (host:port) component.</span>
+<span class="sd"> According to RFC 3986, having an authority component means the URL must</span>
+<span class="sd"> have two slashes after the scheme.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">scheme</span><span class="p">,</span> <span class="n">r_scheme</span> <span class="o">=</span> <span class="n">splittype</span><span class="p">(</span><span class="n">proxy</span><span class="p">)</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">r_scheme</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">&quot;/&quot;</span><span class="p">):</span>
+ <span class="c1"># authority</span>
+ <span class="n">scheme</span> <span class="o">=</span> <span class="kc">None</span>
+ <span class="n">authority</span> <span class="o">=</span> <span class="n">proxy</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="c1"># URL</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">r_scheme</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">&quot;//&quot;</span><span class="p">):</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;proxy URL with no authority: </span><span class="si">%r</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">proxy</span><span class="p">)</span>
+ <span class="c1"># We have an authority, so for RFC 3986-compliant URLs (by ss 3.</span>
+ <span class="c1"># and 3.3.), path is empty or starts with &#39;/&#39;</span>
+ <span class="n">end</span> <span class="o">=</span> <span class="n">r_scheme</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s2">&quot;/&quot;</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">end</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="p">:</span>
+ <span class="n">end</span> <span class="o">=</span> <span class="kc">None</span>
+ <span class="n">authority</span> <span class="o">=</span> <span class="n">r_scheme</span><span class="p">[</span><span class="mi">2</span><span class="p">:</span><span class="n">end</span><span class="p">]</span>
+ <span class="n">userinfo</span><span class="p">,</span> <span class="n">hostport</span> <span class="o">=</span> <span class="n">splituser</span><span class="p">(</span><span class="n">authority</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">userinfo</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">user</span><span class="p">,</span> <span class="n">password</span> <span class="o">=</span> <span class="n">splitpasswd</span><span class="p">(</span><span class="n">userinfo</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">user</span> <span class="o">=</span> <span class="n">password</span> <span class="o">=</span> <span class="kc">None</span>
+ <span class="k">return</span> <span class="n">scheme</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="n">password</span><span class="p">,</span> <span class="n">hostport</span>
+
+<span class="k">class</span> <span class="nc">ProxyHandler</span><span class="p">(</span><span class="n">BaseHandler</span><span class="p">):</span>
+ <span class="c1"># Proxies must be in front</span>
+ <span class="n">handler_order</span> <span class="o">=</span> <span class="mi">100</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">proxies</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="k">if</span> <span class="n">proxies</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">proxies</span> <span class="o">=</span> <span class="n">getproxies</span><span class="p">()</span>
+ <span class="k">assert</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">proxies</span><span class="p">,</span> <span class="s1">&#39;keys&#39;</span><span class="p">),</span> <span class="s2">&quot;proxies must be a mapping&quot;</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">proxies</span> <span class="o">=</span> <span class="n">proxies</span>
+ <span class="k">for</span> <span class="nb">type</span><span class="p">,</span> <span class="n">url</span> <span class="ow">in</span> <span class="n">proxies</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
+ <span class="nb">setattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;</span><span class="si">%s</span><span class="s1">_open&#39;</span> <span class="o">%</span> <span class="nb">type</span><span class="p">,</span>
+ <span class="k">lambda</span> <span class="n">r</span><span class="p">,</span> <span class="n">proxy</span><span class="o">=</span><span class="n">url</span><span class="p">,</span> <span class="nb">type</span><span class="o">=</span><span class="nb">type</span><span class="p">,</span> <span class="n">meth</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">proxy_open</span><span class="p">:</span>
+ <span class="n">meth</span><span class="p">(</span><span class="n">r</span><span class="p">,</span> <span class="n">proxy</span><span class="p">,</span> <span class="nb">type</span><span class="p">))</span>
+
+ <span class="k">def</span> <span class="nf">proxy_open</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">req</span><span class="p">,</span> <span class="n">proxy</span><span class="p">,</span> <span class="nb">type</span><span class="p">):</span>
+ <span class="n">orig_type</span> <span class="o">=</span> <span class="n">req</span><span class="o">.</span><span class="n">type</span>
+ <span class="n">proxy_type</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="n">password</span><span class="p">,</span> <span class="n">hostport</span> <span class="o">=</span> <span class="n">_parse_proxy</span><span class="p">(</span><span class="n">proxy</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">proxy_type</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">proxy_type</span> <span class="o">=</span> <span class="n">orig_type</span>
+
+ <span class="k">if</span> <span class="n">req</span><span class="o">.</span><span class="n">host</span> <span class="ow">and</span> <span class="n">proxy_bypass</span><span class="p">(</span><span class="n">req</span><span class="o">.</span><span class="n">host</span><span class="p">):</span>
+ <span class="k">return</span> <span class="kc">None</span>
+
+ <span class="k">if</span> <span class="n">user</span> <span class="ow">and</span> <span class="n">password</span><span class="p">:</span>
+ <span class="n">user_pass</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="si">%s</span><span class="s1">:</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">unquote</span><span class="p">(</span><span class="n">user</span><span class="p">),</span>
+ <span class="n">unquote</span><span class="p">(</span><span class="n">password</span><span class="p">))</span>
+ <span class="n">creds</span> <span class="o">=</span> <span class="n">base64</span><span class="o">.</span><span class="n">b64encode</span><span class="p">(</span><span class="n">user_pass</span><span class="o">.</span><span class="n">encode</span><span class="p">())</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">&quot;ascii&quot;</span><span class="p">)</span>
+ <span class="n">req</span><span class="o">.</span><span class="n">add_header</span><span class="p">(</span><span class="s1">&#39;Proxy-authorization&#39;</span><span class="p">,</span> <span class="s1">&#39;Basic &#39;</span> <span class="o">+</span> <span class="n">creds</span><span class="p">)</span>
+ <span class="n">hostport</span> <span class="o">=</span> <span class="n">unquote</span><span class="p">(</span><span class="n">hostport</span><span class="p">)</span>
+ <span class="n">req</span><span class="o">.</span><span class="n">set_proxy</span><span class="p">(</span><span class="n">hostport</span><span class="p">,</span> <span class="n">proxy_type</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">orig_type</span> <span class="o">==</span> <span class="n">proxy_type</span> <span class="ow">or</span> <span class="n">orig_type</span> <span class="o">==</span> <span class="s1">&#39;https&#39;</span><span class="p">:</span>
+ <span class="c1"># let other handlers take care of it</span>
+ <span class="k">return</span> <span class="kc">None</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="c1"># need to start over, because the other handlers don&#39;t</span>
+ <span class="c1"># grok the proxy&#39;s URL type</span>
+ <span class="c1"># e.g. if we have a constructor arg proxies like so:</span>
+ <span class="c1"># {&#39;http&#39;: &#39;ftp://proxy.example.com&#39;}, we may end up turning</span>
+ <span class="c1"># a request for http://acme.example.com/a into one for</span>
+ <span class="c1"># ftp://proxy.example.com/a</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">parent</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">req</span><span class="p">,</span> <span class="n">timeout</span><span class="o">=</span><span class="n">req</span><span class="o">.</span><span class="n">timeout</span><span class="p">)</span>
+
+<span class="k">class</span> <span class="nc">HTTPPasswordMgr</span><span class="p">:</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">passwd</span> <span class="o">=</span> <span class="p">{}</span>
+
+ <span class="k">def</span> <span class="nf">add_password</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">realm</span><span class="p">,</span> <span class="n">uri</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="n">passwd</span><span class="p">):</span>
+ <span class="c1"># uri could be a single URI or a sequence</span>
+ <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">uri</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
+ <span class="n">uri</span> <span class="o">=</span> <span class="p">[</span><span class="n">uri</span><span class="p">]</span>
+ <span class="k">if</span> <span class="n">realm</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">passwd</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">passwd</span><span class="p">[</span><span class="n">realm</span><span class="p">]</span> <span class="o">=</span> <span class="p">{}</span>
+ <span class="k">for</span> <span class="n">default_port</span> <span class="ow">in</span> <span class="kc">True</span><span class="p">,</span> <span class="kc">False</span><span class="p">:</span>
+ <span class="n">reduced_uri</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">reduce_uri</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">default_port</span><span class="p">)</span> <span class="k">for</span> <span class="n">u</span> <span class="ow">in</span> <span class="n">uri</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">passwd</span><span class="p">[</span><span class="n">realm</span><span class="p">][</span><span class="n">reduced_uri</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="n">user</span><span class="p">,</span> <span class="n">passwd</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">find_user_password</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">realm</span><span class="p">,</span> <span class="n">authuri</span><span class="p">):</span>
+ <span class="n">domains</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">passwd</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">realm</span><span class="p">,</span> <span class="p">{})</span>
+ <span class="k">for</span> <span class="n">default_port</span> <span class="ow">in</span> <span class="kc">True</span><span class="p">,</span> <span class="kc">False</span><span class="p">:</span>
+ <span class="n">reduced_authuri</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">reduce_uri</span><span class="p">(</span><span class="n">authuri</span><span class="p">,</span> <span class="n">default_port</span><span class="p">)</span>
+ <span class="k">for</span> <span class="n">uris</span><span class="p">,</span> <span class="n">authinfo</span> <span class="ow">in</span> <span class="n">domains</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
+ <span class="k">for</span> <span class="n">uri</span> <span class="ow">in</span> <span class="n">uris</span><span class="p">:</span>
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_suburi</span><span class="p">(</span><span class="n">uri</span><span class="p">,</span> <span class="n">reduced_authuri</span><span class="p">):</span>
+ <span class="k">return</span> <span class="n">authinfo</span>
+ <span class="k">return</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span>
+
+ <span class="k">def</span> <span class="nf">reduce_uri</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">uri</span><span class="p">,</span> <span class="n">default_port</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Accept authority or URI and extract only the authority and path.&quot;&quot;&quot;</span>
+ <span class="c1"># note HTTP URLs do not have a userinfo component</span>
+ <span class="n">parts</span> <span class="o">=</span> <span class="n">urlsplit</span><span class="p">(</span><span class="n">uri</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">parts</span><span class="p">[</span><span class="mi">1</span><span class="p">]:</span>
+ <span class="c1"># URI</span>
+ <span class="n">scheme</span> <span class="o">=</span> <span class="n">parts</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
+ <span class="n">authority</span> <span class="o">=</span> <span class="n">parts</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
+ <span class="n">path</span> <span class="o">=</span> <span class="n">parts</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="ow">or</span> <span class="s1">&#39;/&#39;</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="c1"># host or host:port</span>
+ <span class="n">scheme</span> <span class="o">=</span> <span class="kc">None</span>
+ <span class="n">authority</span> <span class="o">=</span> <span class="n">uri</span>
+ <span class="n">path</span> <span class="o">=</span> <span class="s1">&#39;/&#39;</span>
+ <span class="n">host</span><span class="p">,</span> <span class="n">port</span> <span class="o">=</span> <span class="n">splitport</span><span class="p">(</span><span class="n">authority</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">default_port</span> <span class="ow">and</span> <span class="n">port</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">scheme</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">dport</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;http&quot;</span><span class="p">:</span> <span class="mi">80</span><span class="p">,</span>
+ <span class="s2">&quot;https&quot;</span><span class="p">:</span> <span class="mi">443</span><span class="p">,</span>
+ <span class="p">}</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">scheme</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">dport</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">authority</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="si">%s</span><span class="s2">:</span><span class="si">%d</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">host</span><span class="p">,</span> <span class="n">dport</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">authority</span><span class="p">,</span> <span class="n">path</span>
+
+ <span class="k">def</span> <span class="nf">is_suburi</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">base</span><span class="p">,</span> <span class="n">test</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Check if test is below base in a URI tree</span>
+
+<span class="sd"> Both args must be URIs in reduced form.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">if</span> <span class="n">base</span> <span class="o">==</span> <span class="n">test</span><span class="p">:</span>
+ <span class="k">return</span> <span class="kc">True</span>
+ <span class="k">if</span> <span class="n">base</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">!=</span> <span class="n">test</span><span class="p">[</span><span class="mi">0</span><span class="p">]:</span>
+ <span class="k">return</span> <span class="kc">False</span>
+ <span class="n">common</span> <span class="o">=</span> <span class="n">posixpath</span><span class="o">.</span><span class="n">commonprefix</span><span class="p">((</span><span class="n">base</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">test</span><span class="p">[</span><span class="mi">1</span><span class="p">]))</span>
+ <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">common</span><span class="p">)</span> <span class="o">==</span> <span class="nb">len</span><span class="p">(</span><span class="n">base</span><span class="p">[</span><span class="mi">1</span><span class="p">]):</span>
+ <span class="k">return</span> <span class="kc">True</span>
+ <span class="k">return</span> <span class="kc">False</span>
+
+
+<span class="k">class</span> <span class="nc">HTTPPasswordMgrWithDefaultRealm</span><span class="p">(</span><span class="n">HTTPPasswordMgr</span><span class="p">):</span>
+
+ <span class="k">def</span> <span class="nf">find_user_password</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">realm</span><span class="p">,</span> <span class="n">authuri</span><span class="p">):</span>
+ <span class="n">user</span><span class="p">,</span> <span class="n">password</span> <span class="o">=</span> <span class="n">HTTPPasswordMgr</span><span class="o">.</span><span class="n">find_user_password</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">realm</span><span class="p">,</span>
+ <span class="n">authuri</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">user</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">user</span><span class="p">,</span> <span class="n">password</span>
+ <span class="k">return</span> <span class="n">HTTPPasswordMgr</span><span class="o">.</span><span class="n">find_user_password</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="n">authuri</span><span class="p">)</span>
+
+
+<span class="k">class</span> <span class="nc">HTTPPasswordMgrWithPriorAuth</span><span class="p">(</span><span class="n">HTTPPasswordMgrWithDefaultRealm</span><span class="p">):</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">authenticated</span> <span class="o">=</span> <span class="p">{}</span>
+ <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">add_password</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">realm</span><span class="p">,</span> <span class="n">uri</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="n">passwd</span><span class="p">,</span> <span class="n">is_authenticated</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">update_authenticated</span><span class="p">(</span><span class="n">uri</span><span class="p">,</span> <span class="n">is_authenticated</span><span class="p">)</span>
+ <span class="c1"># Add a default for prior auth requests</span>
+ <span class="k">if</span> <span class="n">realm</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">add_password</span><span class="p">(</span><span class="kc">None</span><span class="p">,</span> <span class="n">uri</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="n">passwd</span><span class="p">)</span>
+ <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">add_password</span><span class="p">(</span><span class="n">realm</span><span class="p">,</span> <span class="n">uri</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="n">passwd</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">update_authenticated</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">uri</span><span class="p">,</span> <span class="n">is_authenticated</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
+ <span class="c1"># uri could be a single URI or a sequence</span>
+ <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">uri</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
+ <span class="n">uri</span> <span class="o">=</span> <span class="p">[</span><span class="n">uri</span><span class="p">]</span>
+
+ <span class="k">for</span> <span class="n">default_port</span> <span class="ow">in</span> <span class="kc">True</span><span class="p">,</span> <span class="kc">False</span><span class="p">:</span>
+ <span class="k">for</span> <span class="n">u</span> <span class="ow">in</span> <span class="n">uri</span><span class="p">:</span>
+ <span class="n">reduced_uri</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">reduce_uri</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">default_port</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">authenticated</span><span class="p">[</span><span class="n">reduced_uri</span><span class="p">]</span> <span class="o">=</span> <span class="n">is_authenticated</span>
+
+ <span class="k">def</span> <span class="nf">is_authenticated</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">authuri</span><span class="p">):</span>
+ <span class="k">for</span> <span class="n">default_port</span> <span class="ow">in</span> <span class="kc">True</span><span class="p">,</span> <span class="kc">False</span><span class="p">:</span>
+ <span class="n">reduced_authuri</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">reduce_uri</span><span class="p">(</span><span class="n">authuri</span><span class="p">,</span> <span class="n">default_port</span><span class="p">)</span>
+ <span class="k">for</span> <span class="n">uri</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">authenticated</span><span class="p">:</span>
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_suburi</span><span class="p">(</span><span class="n">uri</span><span class="p">,</span> <span class="n">reduced_authuri</span><span class="p">):</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">authenticated</span><span class="p">[</span><span class="n">uri</span><span class="p">]</span>
+
+
+<span class="k">class</span> <span class="nc">AbstractBasicAuthHandler</span><span class="p">:</span>
+
+ <span class="c1"># XXX this allows for multiple auth-schemes, but will stupidly pick</span>
+ <span class="c1"># the last one with a realm specified.</span>
+
+ <span class="c1"># allow for double- and single-quoted realm values</span>
+ <span class="c1"># (single quotes are a violation of the RFC, but appear in the wild)</span>
+ <span class="n">rx</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="s1">&#39;(?:.*,)*[ </span><span class="se">\t</span><span class="s1">]*([^ </span><span class="se">\t</span><span class="s1">]+)[ </span><span class="se">\t</span><span class="s1">]+&#39;</span>
+ <span class="s1">&#39;realm=([&quot;</span><span class="se">\&#39;</span><span class="s1">]?)([^&quot;</span><span class="se">\&#39;</span><span class="s1">]*)</span><span class="se">\\</span><span class="s1">2&#39;</span><span class="p">,</span> <span class="n">re</span><span class="o">.</span><span class="n">I</span><span class="p">)</span>
+
+ <span class="c1"># XXX could pre-emptively send auth info already accepted (RFC 2617,</span>
+ <span class="c1"># end of section 2, and section 1.2 immediately after &quot;credentials&quot;</span>
+ <span class="c1"># production).</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">password_mgr</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="k">if</span> <span class="n">password_mgr</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">password_mgr</span> <span class="o">=</span> <span class="n">HTTPPasswordMgr</span><span class="p">()</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">passwd</span> <span class="o">=</span> <span class="n">password_mgr</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">add_password</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">passwd</span><span class="o">.</span><span class="n">add_password</span>
+
+ <span class="k">def</span> <span class="nf">http_error_auth_reqed</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">authreq</span><span class="p">,</span> <span class="n">host</span><span class="p">,</span> <span class="n">req</span><span class="p">,</span> <span class="n">headers</span><span class="p">):</span>
+ <span class="c1"># host may be an authority (without userinfo) or a URL with an</span>
+ <span class="c1"># authority</span>
+ <span class="c1"># XXX could be multiple headers</span>
+ <span class="n">authreq</span> <span class="o">=</span> <span class="n">headers</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">authreq</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
+
+ <span class="k">if</span> <span class="n">authreq</span><span class="p">:</span>
+ <span class="n">scheme</span> <span class="o">=</span> <span class="n">authreq</span><span class="o">.</span><span class="n">split</span><span class="p">()[</span><span class="mi">0</span><span class="p">]</span>
+ <span class="k">if</span> <span class="n">scheme</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="o">!=</span> <span class="s1">&#39;basic&#39;</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;AbstractBasicAuthHandler does not&quot;</span>
+ <span class="s2">&quot; support the following scheme: &#39;</span><span class="si">%s</span><span class="s2">&#39;&quot;</span> <span class="o">%</span>
+ <span class="n">scheme</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">mo</span> <span class="o">=</span> <span class="n">AbstractBasicAuthHandler</span><span class="o">.</span><span class="n">rx</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="n">authreq</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">mo</span><span class="p">:</span>
+ <span class="n">scheme</span><span class="p">,</span> <span class="n">quote</span><span class="p">,</span> <span class="n">realm</span> <span class="o">=</span> <span class="n">mo</span><span class="o">.</span><span class="n">groups</span><span class="p">()</span>
+ <span class="k">if</span> <span class="n">quote</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">[</span><span class="s1">&#39;&quot;&#39;</span><span class="p">,</span><span class="s2">&quot;&#39;&quot;</span><span class="p">]:</span>
+ <span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span><span class="s2">&quot;Basic Auth Realm was unquoted&quot;</span><span class="p">,</span>
+ <span class="ne">UserWarning</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">scheme</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="o">==</span> <span class="s1">&#39;basic&#39;</span><span class="p">:</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">retry_http_basic_auth</span><span class="p">(</span><span class="n">host</span><span class="p">,</span> <span class="n">req</span><span class="p">,</span> <span class="n">realm</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">retry_http_basic_auth</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">host</span><span class="p">,</span> <span class="n">req</span><span class="p">,</span> <span class="n">realm</span><span class="p">):</span>
+ <span class="n">user</span><span class="p">,</span> <span class="n">pw</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">passwd</span><span class="o">.</span><span class="n">find_user_password</span><span class="p">(</span><span class="n">realm</span><span class="p">,</span> <span class="n">host</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">pw</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">raw</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="si">%s</span><span class="s2">:</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">user</span><span class="p">,</span> <span class="n">pw</span><span class="p">)</span>
+ <span class="n">auth</span> <span class="o">=</span> <span class="s2">&quot;Basic &quot;</span> <span class="o">+</span> <span class="n">base64</span><span class="o">.</span><span class="n">b64encode</span><span class="p">(</span><span class="n">raw</span><span class="o">.</span><span class="n">encode</span><span class="p">())</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">&quot;ascii&quot;</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">req</span><span class="o">.</span><span class="n">get_header</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">auth_header</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> <span class="o">==</span> <span class="n">auth</span><span class="p">:</span>
+ <span class="k">return</span> <span class="kc">None</span>
+ <span class="n">req</span><span class="o">.</span><span class="n">add_unredirected_header</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">auth_header</span><span class="p">,</span> <span class="n">auth</span><span class="p">)</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">parent</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">req</span><span class="p">,</span> <span class="n">timeout</span><span class="o">=</span><span class="n">req</span><span class="o">.</span><span class="n">timeout</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">return</span> <span class="kc">None</span>
+
+ <span class="k">def</span> <span class="nf">http_request</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">req</span><span class="p">):</span>
+ <span class="k">if</span> <span class="p">(</span><span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">passwd</span><span class="p">,</span> <span class="s1">&#39;is_authenticated&#39;</span><span class="p">)</span> <span class="ow">or</span>
+ <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">passwd</span><span class="o">.</span><span class="n">is_authenticated</span><span class="p">(</span><span class="n">req</span><span class="o">.</span><span class="n">full_url</span><span class="p">)):</span>
+ <span class="k">return</span> <span class="n">req</span>
+
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">req</span><span class="o">.</span><span class="n">has_header</span><span class="p">(</span><span class="s1">&#39;Authorization&#39;</span><span class="p">):</span>
+ <span class="n">user</span><span class="p">,</span> <span class="n">passwd</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">passwd</span><span class="o">.</span><span class="n">find_user_password</span><span class="p">(</span><span class="kc">None</span><span class="p">,</span> <span class="n">req</span><span class="o">.</span><span class="n">full_url</span><span class="p">)</span>
+ <span class="n">credentials</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="si">{0}</span><span class="s1">:</span><span class="si">{1}</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">user</span><span class="p">,</span> <span class="n">passwd</span><span class="p">)</span><span class="o">.</span><span class="n">encode</span><span class="p">()</span>
+ <span class="n">auth_str</span> <span class="o">=</span> <span class="n">base64</span><span class="o">.</span><span class="n">standard_b64encode</span><span class="p">(</span><span class="n">credentials</span><span class="p">)</span><span class="o">.</span><span class="n">decode</span><span class="p">()</span>
+ <span class="n">req</span><span class="o">.</span><span class="n">add_unredirected_header</span><span class="p">(</span><span class="s1">&#39;Authorization&#39;</span><span class="p">,</span>
+ <span class="s1">&#39;Basic </span><span class="si">{}</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">auth_str</span><span class="o">.</span><span class="n">strip</span><span class="p">()))</span>
+ <span class="k">return</span> <span class="n">req</span>
+
+ <span class="k">def</span> <span class="nf">http_response</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">req</span><span class="p">,</span> <span class="n">response</span><span class="p">):</span>
+ <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">passwd</span><span class="p">,</span> <span class="s1">&#39;is_authenticated&#39;</span><span class="p">):</span>
+ <span class="k">if</span> <span class="mi">200</span> <span class="o">&lt;=</span> <span class="n">response</span><span class="o">.</span><span class="n">code</span> <span class="o">&lt;</span> <span class="mi">300</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">passwd</span><span class="o">.</span><span class="n">update_authenticated</span><span class="p">(</span><span class="n">req</span><span class="o">.</span><span class="n">full_url</span><span class="p">,</span> <span class="kc">True</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">passwd</span><span class="o">.</span><span class="n">update_authenticated</span><span class="p">(</span><span class="n">req</span><span class="o">.</span><span class="n">full_url</span><span class="p">,</span> <span class="kc">False</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">response</span>
+
+ <span class="n">https_request</span> <span class="o">=</span> <span class="n">http_request</span>
+ <span class="n">https_response</span> <span class="o">=</span> <span class="n">http_response</span>
+
+
+
+<span class="k">class</span> <span class="nc">HTTPBasicAuthHandler</span><span class="p">(</span><span class="n">AbstractBasicAuthHandler</span><span class="p">,</span> <span class="n">BaseHandler</span><span class="p">):</span>
+
+ <span class="n">auth_header</span> <span class="o">=</span> <span class="s1">&#39;Authorization&#39;</span>
+
+ <span class="k">def</span> <span class="nf">http_error_401</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">req</span><span class="p">,</span> <span class="n">fp</span><span class="p">,</span> <span class="n">code</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="n">headers</span><span class="p">):</span>
+ <span class="n">url</span> <span class="o">=</span> <span class="n">req</span><span class="o">.</span><span class="n">full_url</span>
+ <span class="n">response</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">http_error_auth_reqed</span><span class="p">(</span><span class="s1">&#39;www-authenticate&#39;</span><span class="p">,</span>
+ <span class="n">url</span><span class="p">,</span> <span class="n">req</span><span class="p">,</span> <span class="n">headers</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">response</span>
+
+
+<span class="k">class</span> <span class="nc">ProxyBasicAuthHandler</span><span class="p">(</span><span class="n">AbstractBasicAuthHandler</span><span class="p">,</span> <span class="n">BaseHandler</span><span class="p">):</span>
+
+ <span class="n">auth_header</span> <span class="o">=</span> <span class="s1">&#39;Proxy-authorization&#39;</span>
+
+ <span class="k">def</span> <span class="nf">http_error_407</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">req</span><span class="p">,</span> <span class="n">fp</span><span class="p">,</span> <span class="n">code</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="n">headers</span><span class="p">):</span>
+ <span class="c1"># http_error_auth_reqed requires that there is no userinfo component in</span>
+ <span class="c1"># authority. Assume there isn&#39;t one, since urllib.request does not (and</span>
+ <span class="c1"># should not, RFC 3986 s. 3.2.1) support requests for URLs containing</span>
+ <span class="c1"># userinfo.</span>
+ <span class="n">authority</span> <span class="o">=</span> <span class="n">req</span><span class="o">.</span><span class="n">host</span>
+ <span class="n">response</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">http_error_auth_reqed</span><span class="p">(</span><span class="s1">&#39;proxy-authenticate&#39;</span><span class="p">,</span>
+ <span class="n">authority</span><span class="p">,</span> <span class="n">req</span><span class="p">,</span> <span class="n">headers</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">response</span>
+
+
+<span class="c1"># Return n random bytes.</span>
+<span class="n">_randombytes</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">urandom</span>
+
+
+<span class="k">class</span> <span class="nc">AbstractDigestAuthHandler</span><span class="p">:</span>
+ <span class="c1"># Digest authentication is specified in RFC 2617.</span>
+
+ <span class="c1"># XXX The client does not inspect the Authentication-Info header</span>
+ <span class="c1"># in a successful response.</span>
+
+ <span class="c1"># XXX It should be possible to test this implementation against</span>
+ <span class="c1"># a mock server that just generates a static set of challenges.</span>
+
+ <span class="c1"># XXX qop=&quot;auth-int&quot; supports is shaky</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">passwd</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="k">if</span> <span class="n">passwd</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">passwd</span> <span class="o">=</span> <span class="n">HTTPPasswordMgr</span><span class="p">()</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">passwd</span> <span class="o">=</span> <span class="n">passwd</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">add_password</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">passwd</span><span class="o">.</span><span class="n">add_password</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">retried</span> <span class="o">=</span> <span class="mi">0</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">nonce_count</span> <span class="o">=</span> <span class="mi">0</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">last_nonce</span> <span class="o">=</span> <span class="kc">None</span>
+
+ <span class="k">def</span> <span class="nf">reset_retry_count</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">retried</span> <span class="o">=</span> <span class="mi">0</span>
+
+ <span class="k">def</span> <span class="nf">http_error_auth_reqed</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">auth_header</span><span class="p">,</span> <span class="n">host</span><span class="p">,</span> <span class="n">req</span><span class="p">,</span> <span class="n">headers</span><span class="p">):</span>
+ <span class="n">authreq</span> <span class="o">=</span> <span class="n">headers</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">auth_header</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">retried</span> <span class="o">&gt;</span> <span class="mi">5</span><span class="p">:</span>
+ <span class="c1"># Don&#39;t fail endlessly - if we failed once, we&#39;ll probably</span>
+ <span class="c1"># fail a second time. Hm. Unless the Password Manager is</span>
+ <span class="c1"># prompting for the information. Crap. This isn&#39;t great</span>
+ <span class="c1"># but it&#39;s better than the current &#39;repeat until recursion</span>
+ <span class="c1"># depth exceeded&#39; approach &lt;wink&gt;</span>
+ <span class="k">raise</span> <span class="n">HTTPError</span><span class="p">(</span><span class="n">req</span><span class="o">.</span><span class="n">full_url</span><span class="p">,</span> <span class="mi">401</span><span class="p">,</span> <span class="s2">&quot;digest auth failed&quot;</span><span class="p">,</span>
+ <span class="n">headers</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">retried</span> <span class="o">+=</span> <span class="mi">1</span>
+ <span class="k">if</span> <span class="n">authreq</span><span class="p">:</span>
+ <span class="n">scheme</span> <span class="o">=</span> <span class="n">authreq</span><span class="o">.</span><span class="n">split</span><span class="p">()[</span><span class="mi">0</span><span class="p">]</span>
+ <span class="k">if</span> <span class="n">scheme</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="o">==</span> <span class="s1">&#39;digest&#39;</span><span class="p">:</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">retry_http_digest_auth</span><span class="p">(</span><span class="n">req</span><span class="p">,</span> <span class="n">authreq</span><span class="p">)</span>
+ <span class="k">elif</span> <span class="n">scheme</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="o">!=</span> <span class="s1">&#39;basic&#39;</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;AbstractDigestAuthHandler does not support&quot;</span>
+ <span class="s2">&quot; the following scheme: &#39;</span><span class="si">%s</span><span class="s2">&#39;&quot;</span> <span class="o">%</span> <span class="n">scheme</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">retry_http_digest_auth</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">req</span><span class="p">,</span> <span class="n">auth</span><span class="p">):</span>
+ <span class="n">token</span><span class="p">,</span> <span class="n">challenge</span> <span class="o">=</span> <span class="n">auth</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
+ <span class="n">chal</span> <span class="o">=</span> <span class="n">parse_keqv_list</span><span class="p">(</span><span class="nb">filter</span><span class="p">(</span><span class="kc">None</span><span class="p">,</span> <span class="n">parse_http_list</span><span class="p">(</span><span class="n">challenge</span><span class="p">)))</span>
+ <span class="n">auth</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_authorization</span><span class="p">(</span><span class="n">req</span><span class="p">,</span> <span class="n">chal</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">auth</span><span class="p">:</span>
+ <span class="n">auth_val</span> <span class="o">=</span> <span class="s1">&#39;Digest </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">auth</span>
+ <span class="k">if</span> <span class="n">req</span><span class="o">.</span><span class="n">headers</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">auth_header</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> <span class="o">==</span> <span class="n">auth_val</span><span class="p">:</span>
+ <span class="k">return</span> <span class="kc">None</span>
+ <span class="n">req</span><span class="o">.</span><span class="n">add_unredirected_header</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">auth_header</span><span class="p">,</span> <span class="n">auth_val</span><span class="p">)</span>
+ <span class="n">resp</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">parent</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">req</span><span class="p">,</span> <span class="n">timeout</span><span class="o">=</span><span class="n">req</span><span class="o">.</span><span class="n">timeout</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">resp</span>
+
+ <span class="k">def</span> <span class="nf">get_cnonce</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">nonce</span><span class="p">):</span>
+ <span class="c1"># The cnonce-value is an opaque</span>
+ <span class="c1"># quoted string value provided by the client and used by both client</span>
+ <span class="c1"># and server to avoid chosen plaintext attacks, to provide mutual</span>
+ <span class="c1"># authentication, and to provide some message integrity protection.</span>
+ <span class="c1"># This isn&#39;t a fabulous effort, but it&#39;s probably Good Enough.</span>
+ <span class="n">s</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="si">%s</span><span class="s2">:</span><span class="si">%s</span><span class="s2">:</span><span class="si">%s</span><span class="s2">:&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">nonce_count</span><span class="p">,</span> <span class="n">nonce</span><span class="p">,</span> <span class="n">time</span><span class="o">.</span><span class="n">ctime</span><span class="p">())</span>
+ <span class="n">b</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s2">&quot;ascii&quot;</span><span class="p">)</span> <span class="o">+</span> <span class="n">_randombytes</span><span class="p">(</span><span class="mi">8</span><span class="p">)</span>
+ <span class="n">dig</span> <span class="o">=</span> <span class="n">hashlib</span><span class="o">.</span><span class="n">sha1</span><span class="p">(</span><span class="n">b</span><span class="p">)</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span>
+ <span class="k">return</span> <span class="n">dig</span><span class="p">[:</span><span class="mi">16</span><span class="p">]</span>
+
+ <span class="k">def</span> <span class="nf">get_authorization</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">req</span><span class="p">,</span> <span class="n">chal</span><span class="p">):</span>
+ <span class="k">try</span><span class="p">:</span>
+ <span class="n">realm</span> <span class="o">=</span> <span class="n">chal</span><span class="p">[</span><span class="s1">&#39;realm&#39;</span><span class="p">]</span>
+ <span class="n">nonce</span> <span class="o">=</span> <span class="n">chal</span><span class="p">[</span><span class="s1">&#39;nonce&#39;</span><span class="p">]</span>
+ <span class="n">qop</span> <span class="o">=</span> <span class="n">chal</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;qop&#39;</span><span class="p">)</span>
+ <span class="n">algorithm</span> <span class="o">=</span> <span class="n">chal</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;algorithm&#39;</span><span class="p">,</span> <span class="s1">&#39;MD5&#39;</span><span class="p">)</span>
+ <span class="c1"># mod_digest doesn&#39;t send an opaque, even though it isn&#39;t</span>
+ <span class="c1"># supposed to be optional</span>
+ <span class="n">opaque</span> <span class="o">=</span> <span class="n">chal</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;opaque&#39;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
+ <span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
+ <span class="k">return</span> <span class="kc">None</span>
+
+ <span class="n">H</span><span class="p">,</span> <span class="n">KD</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_algorithm_impls</span><span class="p">(</span><span class="n">algorithm</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">H</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">return</span> <span class="kc">None</span>
+
+ <span class="n">user</span><span class="p">,</span> <span class="n">pw</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">passwd</span><span class="o">.</span><span class="n">find_user_password</span><span class="p">(</span><span class="n">realm</span><span class="p">,</span> <span class="n">req</span><span class="o">.</span><span class="n">full_url</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">user</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">return</span> <span class="kc">None</span>
+
+ <span class="c1"># XXX not implemented yet</span>
+ <span class="k">if</span> <span class="n">req</span><span class="o">.</span><span class="n">data</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">entdig</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_entity_digest</span><span class="p">(</span><span class="n">req</span><span class="o">.</span><span class="n">data</span><span class="p">,</span> <span class="n">chal</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">entdig</span> <span class="o">=</span> <span class="kc">None</span>
+
+ <span class="n">A1</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="si">%s</span><span class="s2">:</span><span class="si">%s</span><span class="s2">:</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">user</span><span class="p">,</span> <span class="n">realm</span><span class="p">,</span> <span class="n">pw</span><span class="p">)</span>
+ <span class="n">A2</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="si">%s</span><span class="s2">:</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">req</span><span class="o">.</span><span class="n">get_method</span><span class="p">(),</span>
+ <span class="c1"># XXX selector: what about proxies and full urls</span>
+ <span class="n">req</span><span class="o">.</span><span class="n">selector</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">qop</span> <span class="o">==</span> <span class="s1">&#39;auth&#39;</span><span class="p">:</span>
+ <span class="k">if</span> <span class="n">nonce</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">last_nonce</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">nonce_count</span> <span class="o">+=</span> <span class="mi">1</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">nonce_count</span> <span class="o">=</span> <span class="mi">1</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">last_nonce</span> <span class="o">=</span> <span class="n">nonce</span>
+ <span class="n">ncvalue</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="si">%08x</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">nonce_count</span>
+ <span class="n">cnonce</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_cnonce</span><span class="p">(</span><span class="n">nonce</span><span class="p">)</span>
+ <span class="n">noncebit</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="si">%s</span><span class="s2">:</span><span class="si">%s</span><span class="s2">:</span><span class="si">%s</span><span class="s2">:</span><span class="si">%s</span><span class="s2">:</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">nonce</span><span class="p">,</span> <span class="n">ncvalue</span><span class="p">,</span> <span class="n">cnonce</span><span class="p">,</span> <span class="n">qop</span><span class="p">,</span> <span class="n">H</span><span class="p">(</span><span class="n">A2</span><span class="p">))</span>
+ <span class="n">respdig</span> <span class="o">=</span> <span class="n">KD</span><span class="p">(</span><span class="n">H</span><span class="p">(</span><span class="n">A1</span><span class="p">),</span> <span class="n">noncebit</span><span class="p">)</span>
+ <span class="k">elif</span> <span class="n">qop</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">respdig</span> <span class="o">=</span> <span class="n">KD</span><span class="p">(</span><span class="n">H</span><span class="p">(</span><span class="n">A1</span><span class="p">),</span> <span class="s2">&quot;</span><span class="si">%s</span><span class="s2">:</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">nonce</span><span class="p">,</span> <span class="n">H</span><span class="p">(</span><span class="n">A2</span><span class="p">)))</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="c1"># XXX handle auth-int.</span>
+ <span class="k">raise</span> <span class="n">URLError</span><span class="p">(</span><span class="s2">&quot;qop &#39;</span><span class="si">%s</span><span class="s2">&#39; is not supported.&quot;</span> <span class="o">%</span> <span class="n">qop</span><span class="p">)</span>
+
+ <span class="c1"># XXX should the partial digests be encoded too?</span>
+
+ <span class="n">base</span> <span class="o">=</span> <span class="s1">&#39;username=&quot;</span><span class="si">%s</span><span class="s1">&quot;, realm=&quot;</span><span class="si">%s</span><span class="s1">&quot;, nonce=&quot;</span><span class="si">%s</span><span class="s1">&quot;, uri=&quot;</span><span class="si">%s</span><span class="s1">&quot;, &#39;</span> \
+ <span class="s1">&#39;response=&quot;</span><span class="si">%s</span><span class="s1">&quot;&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">user</span><span class="p">,</span> <span class="n">realm</span><span class="p">,</span> <span class="n">nonce</span><span class="p">,</span> <span class="n">req</span><span class="o">.</span><span class="n">selector</span><span class="p">,</span>
+ <span class="n">respdig</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">opaque</span><span class="p">:</span>
+ <span class="n">base</span> <span class="o">+=</span> <span class="s1">&#39;, opaque=&quot;</span><span class="si">%s</span><span class="s1">&quot;&#39;</span> <span class="o">%</span> <span class="n">opaque</span>
+ <span class="k">if</span> <span class="n">entdig</span><span class="p">:</span>
+ <span class="n">base</span> <span class="o">+=</span> <span class="s1">&#39;, digest=&quot;</span><span class="si">%s</span><span class="s1">&quot;&#39;</span> <span class="o">%</span> <span class="n">entdig</span>
+ <span class="n">base</span> <span class="o">+=</span> <span class="s1">&#39;, algorithm=&quot;</span><span class="si">%s</span><span class="s1">&quot;&#39;</span> <span class="o">%</span> <span class="n">algorithm</span>
+ <span class="k">if</span> <span class="n">qop</span><span class="p">:</span>
+ <span class="n">base</span> <span class="o">+=</span> <span class="s1">&#39;, qop=auth, nc=</span><span class="si">%s</span><span class="s1">, cnonce=&quot;</span><span class="si">%s</span><span class="s1">&quot;&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">ncvalue</span><span class="p">,</span> <span class="n">cnonce</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">base</span>
+
+ <span class="k">def</span> <span class="nf">get_algorithm_impls</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">algorithm</span><span class="p">):</span>
+ <span class="c1"># lambdas assume digest modules are imported at the top level</span>
+ <span class="k">if</span> <span class="n">algorithm</span> <span class="o">==</span> <span class="s1">&#39;MD5&#39;</span><span class="p">:</span>
+ <span class="n">H</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="n">hashlib</span><span class="o">.</span><span class="n">md5</span><span class="p">(</span><span class="n">x</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s2">&quot;ascii&quot;</span><span class="p">))</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span>
+ <span class="k">elif</span> <span class="n">algorithm</span> <span class="o">==</span> <span class="s1">&#39;SHA&#39;</span><span class="p">:</span>
+ <span class="n">H</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="n">hashlib</span><span class="o">.</span><span class="n">sha1</span><span class="p">(</span><span class="n">x</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s2">&quot;ascii&quot;</span><span class="p">))</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span>
+ <span class="c1"># XXX MD5-sess</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;Unsupported digest authentication &quot;</span>
+ <span class="s2">&quot;algorithm </span><span class="si">%r</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">algorithm</span><span class="p">)</span>
+ <span class="n">KD</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">s</span><span class="p">,</span> <span class="n">d</span><span class="p">:</span> <span class="n">H</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">%s</span><span class="s2">:</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">d</span><span class="p">))</span>
+ <span class="k">return</span> <span class="n">H</span><span class="p">,</span> <span class="n">KD</span>
+
+ <span class="k">def</span> <span class="nf">get_entity_digest</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">chal</span><span class="p">):</span>
+ <span class="c1"># XXX not implemented yet</span>
+ <span class="k">return</span> <span class="kc">None</span>
+
+
+<span class="k">class</span> <span class="nc">HTTPDigestAuthHandler</span><span class="p">(</span><span class="n">BaseHandler</span><span class="p">,</span> <span class="n">AbstractDigestAuthHandler</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;An authentication protocol defined by RFC 2069</span>
+
+<span class="sd"> Digest authentication improves on basic authentication because it</span>
+<span class="sd"> does not transmit passwords in the clear.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+
+ <span class="n">auth_header</span> <span class="o">=</span> <span class="s1">&#39;Authorization&#39;</span>
+ <span class="n">handler_order</span> <span class="o">=</span> <span class="mi">490</span> <span class="c1"># before Basic auth</span>
+
+ <span class="k">def</span> <span class="nf">http_error_401</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">req</span><span class="p">,</span> <span class="n">fp</span><span class="p">,</span> <span class="n">code</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="n">headers</span><span class="p">):</span>
+ <span class="n">host</span> <span class="o">=</span> <span class="n">urlparse</span><span class="p">(</span><span class="n">req</span><span class="o">.</span><span class="n">full_url</span><span class="p">)[</span><span class="mi">1</span><span class="p">]</span>
+ <span class="n">retry</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">http_error_auth_reqed</span><span class="p">(</span><span class="s1">&#39;www-authenticate&#39;</span><span class="p">,</span>
+ <span class="n">host</span><span class="p">,</span> <span class="n">req</span><span class="p">,</span> <span class="n">headers</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">reset_retry_count</span><span class="p">()</span>
+ <span class="k">return</span> <span class="n">retry</span>
+
+
+<span class="k">class</span> <span class="nc">ProxyDigestAuthHandler</span><span class="p">(</span><span class="n">BaseHandler</span><span class="p">,</span> <span class="n">AbstractDigestAuthHandler</span><span class="p">):</span>
+
+ <span class="n">auth_header</span> <span class="o">=</span> <span class="s1">&#39;Proxy-Authorization&#39;</span>
+ <span class="n">handler_order</span> <span class="o">=</span> <span class="mi">490</span> <span class="c1"># before Basic auth</span>
+
+ <span class="k">def</span> <span class="nf">http_error_407</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">req</span><span class="p">,</span> <span class="n">fp</span><span class="p">,</span> <span class="n">code</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="n">headers</span><span class="p">):</span>
+ <span class="n">host</span> <span class="o">=</span> <span class="n">req</span><span class="o">.</span><span class="n">host</span>
+ <span class="n">retry</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">http_error_auth_reqed</span><span class="p">(</span><span class="s1">&#39;proxy-authenticate&#39;</span><span class="p">,</span>
+ <span class="n">host</span><span class="p">,</span> <span class="n">req</span><span class="p">,</span> <span class="n">headers</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">reset_retry_count</span><span class="p">()</span>
+ <span class="k">return</span> <span class="n">retry</span>
+
+<span class="k">class</span> <span class="nc">AbstractHTTPHandler</span><span class="p">(</span><span class="n">BaseHandler</span><span class="p">):</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">debuglevel</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_debuglevel</span> <span class="o">=</span> <span class="n">debuglevel</span>
+
+ <span class="k">def</span> <span class="nf">set_http_debuglevel</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">level</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_debuglevel</span> <span class="o">=</span> <span class="n">level</span>
+
+ <span class="k">def</span> <span class="nf">_get_content_length</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">):</span>
+ <span class="k">return</span> <span class="n">http</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">HTTPConnection</span><span class="o">.</span><span class="n">_get_content_length</span><span class="p">(</span>
+ <span class="n">request</span><span class="o">.</span><span class="n">data</span><span class="p">,</span>
+ <span class="n">request</span><span class="o">.</span><span class="n">get_method</span><span class="p">())</span>
+
+ <span class="k">def</span> <span class="nf">do_request_</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">):</span>
+ <span class="n">host</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">host</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">host</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="n">URLError</span><span class="p">(</span><span class="s1">&#39;no host given&#39;</span><span class="p">)</span>
+
+ <span class="k">if</span> <span class="n">request</span><span class="o">.</span><span class="n">data</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> <span class="c1"># POST</span>
+ <span class="n">data</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">data</span>
+ <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
+ <span class="n">msg</span> <span class="o">=</span> <span class="s2">&quot;POST data should be bytes, an iterable of bytes, &quot;</span> \
+ <span class="s2">&quot;or a file object. It cannot be of type str.&quot;</span>
+ <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">request</span><span class="o">.</span><span class="n">has_header</span><span class="p">(</span><span class="s1">&#39;Content-type&#39;</span><span class="p">):</span>
+ <span class="n">request</span><span class="o">.</span><span class="n">add_unredirected_header</span><span class="p">(</span>
+ <span class="s1">&#39;Content-type&#39;</span><span class="p">,</span>
+ <span class="s1">&#39;application/x-www-form-urlencoded&#39;</span><span class="p">)</span>
+ <span class="k">if</span> <span class="p">(</span><span class="ow">not</span> <span class="n">request</span><span class="o">.</span><span class="n">has_header</span><span class="p">(</span><span class="s1">&#39;Content-length&#39;</span><span class="p">)</span>
+ <span class="ow">and</span> <span class="ow">not</span> <span class="n">request</span><span class="o">.</span><span class="n">has_header</span><span class="p">(</span><span class="s1">&#39;Transfer-encoding&#39;</span><span class="p">)):</span>
+ <span class="n">content_length</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_content_length</span><span class="p">(</span><span class="n">request</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">content_length</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">request</span><span class="o">.</span><span class="n">add_unredirected_header</span><span class="p">(</span>
+ <span class="s1">&#39;Content-length&#39;</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">content_length</span><span class="p">))</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">request</span><span class="o">.</span><span class="n">add_unredirected_header</span><span class="p">(</span>
+ <span class="s1">&#39;Transfer-encoding&#39;</span><span class="p">,</span> <span class="s1">&#39;chunked&#39;</span><span class="p">)</span>
+
+ <span class="n">sel_host</span> <span class="o">=</span> <span class="n">host</span>
+ <span class="k">if</span> <span class="n">request</span><span class="o">.</span><span class="n">has_proxy</span><span class="p">():</span>
+ <span class="n">scheme</span><span class="p">,</span> <span class="n">sel</span> <span class="o">=</span> <span class="n">splittype</span><span class="p">(</span><span class="n">request</span><span class="o">.</span><span class="n">selector</span><span class="p">)</span>
+ <span class="n">sel_host</span><span class="p">,</span> <span class="n">sel_path</span> <span class="o">=</span> <span class="n">splithost</span><span class="p">(</span><span class="n">sel</span><span class="p">)</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">request</span><span class="o">.</span><span class="n">has_header</span><span class="p">(</span><span class="s1">&#39;Host&#39;</span><span class="p">):</span>
+ <span class="n">request</span><span class="o">.</span><span class="n">add_unredirected_header</span><span class="p">(</span><span class="s1">&#39;Host&#39;</span><span class="p">,</span> <span class="n">sel_host</span><span class="p">)</span>
+ <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">parent</span><span class="o">.</span><span class="n">addheaders</span><span class="p">:</span>
+ <span class="n">name</span> <span class="o">=</span> <span class="n">name</span><span class="o">.</span><span class="n">capitalize</span><span class="p">()</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">request</span><span class="o">.</span><span class="n">has_header</span><span class="p">(</span><span class="n">name</span><span class="p">):</span>
+ <span class="n">request</span><span class="o">.</span><span class="n">add_unredirected_header</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
+
+ <span class="k">return</span> <span class="n">request</span>
+
+ <span class="k">def</span> <span class="nf">do_open</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">http_class</span><span class="p">,</span> <span class="n">req</span><span class="p">,</span> <span class="o">**</span><span class="n">http_conn_args</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Return an HTTPResponse object for the request, using http_class.</span>
+
+<span class="sd"> http_class must implement the HTTPConnection API from http.client.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">host</span> <span class="o">=</span> <span class="n">req</span><span class="o">.</span><span class="n">host</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">host</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="n">URLError</span><span class="p">(</span><span class="s1">&#39;no host given&#39;</span><span class="p">)</span>
+
+ <span class="c1"># will parse host:port</span>
+ <span class="n">h</span> <span class="o">=</span> <span class="n">http_class</span><span class="p">(</span><span class="n">host</span><span class="p">,</span> <span class="n">timeout</span><span class="o">=</span><span class="n">req</span><span class="o">.</span><span class="n">timeout</span><span class="p">,</span> <span class="o">**</span><span class="n">http_conn_args</span><span class="p">)</span>
+ <span class="n">h</span><span class="o">.</span><span class="n">set_debuglevel</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_debuglevel</span><span class="p">)</span>
+
+ <span class="n">headers</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span><span class="n">req</span><span class="o">.</span><span class="n">unredirected_hdrs</span><span class="p">)</span>
+ <span class="n">headers</span><span class="o">.</span><span class="n">update</span><span class="p">({</span><span class="n">k</span><span class="p">:</span> <span class="n">v</span> <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">req</span><span class="o">.</span><span class="n">headers</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
+ <span class="k">if</span> <span class="n">k</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">headers</span><span class="p">})</span>
+
+ <span class="c1"># TODO(jhylton): Should this be redesigned to handle</span>
+ <span class="c1"># persistent connections?</span>
+
+ <span class="c1"># We want to make an HTTP/1.1 request, but the addinfourl</span>
+ <span class="c1"># class isn&#39;t prepared to deal with a persistent connection.</span>
+ <span class="c1"># It will try to read all remaining data from the socket,</span>
+ <span class="c1"># which will block while the server waits for the next request.</span>
+ <span class="c1"># So make sure the connection gets closed after the (only)</span>
+ <span class="c1"># request.</span>
+ <span class="n">headers</span><span class="p">[</span><span class="s2">&quot;Connection&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;close&quot;</span>
+ <span class="n">headers</span> <span class="o">=</span> <span class="p">{</span><span class="n">name</span><span class="o">.</span><span class="n">title</span><span class="p">():</span> <span class="n">val</span> <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">val</span> <span class="ow">in</span> <span class="n">headers</span><span class="o">.</span><span class="n">items</span><span class="p">()}</span>
+
+ <span class="k">if</span> <span class="n">req</span><span class="o">.</span><span class="n">_tunnel_host</span><span class="p">:</span>
+ <span class="n">tunnel_headers</span> <span class="o">=</span> <span class="p">{}</span>
+ <span class="n">proxy_auth_hdr</span> <span class="o">=</span> <span class="s2">&quot;Proxy-Authorization&quot;</span>
+ <span class="k">if</span> <span class="n">proxy_auth_hdr</span> <span class="ow">in</span> <span class="n">headers</span><span class="p">:</span>
+ <span class="n">tunnel_headers</span><span class="p">[</span><span class="n">proxy_auth_hdr</span><span class="p">]</span> <span class="o">=</span> <span class="n">headers</span><span class="p">[</span><span class="n">proxy_auth_hdr</span><span class="p">]</span>
+ <span class="c1"># Proxy-Authorization should not be sent to origin</span>
+ <span class="c1"># server.</span>
+ <span class="k">del</span> <span class="n">headers</span><span class="p">[</span><span class="n">proxy_auth_hdr</span><span class="p">]</span>
+ <span class="n">h</span><span class="o">.</span><span class="n">set_tunnel</span><span class="p">(</span><span class="n">req</span><span class="o">.</span><span class="n">_tunnel_host</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="n">tunnel_headers</span><span class="p">)</span>
+
+ <span class="k">try</span><span class="p">:</span>
+ <span class="k">try</span><span class="p">:</span>
+ <span class="n">h</span><span class="o">.</span><span class="n">request</span><span class="p">(</span><span class="n">req</span><span class="o">.</span><span class="n">get_method</span><span class="p">(),</span> <span class="n">req</span><span class="o">.</span><span class="n">selector</span><span class="p">,</span> <span class="n">req</span><span class="o">.</span><span class="n">data</span><span class="p">,</span> <span class="n">headers</span><span class="p">,</span>
+ <span class="n">encode_chunked</span><span class="o">=</span><span class="n">req</span><span class="o">.</span><span class="n">has_header</span><span class="p">(</span><span class="s1">&#39;Transfer-encoding&#39;</span><span class="p">))</span>
+ <span class="k">except</span> <span class="ne">OSError</span> <span class="k">as</span> <span class="n">err</span><span class="p">:</span> <span class="c1"># timeout error</span>
+ <span class="k">raise</span> <span class="n">URLError</span><span class="p">(</span><span class="n">err</span><span class="p">)</span>
+ <span class="n">r</span> <span class="o">=</span> <span class="n">h</span><span class="o">.</span><span class="n">getresponse</span><span class="p">()</span>
+ <span class="k">except</span><span class="p">:</span>
+ <span class="n">h</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
+ <span class="k">raise</span>
+
+ <span class="c1"># If the server does not send us a &#39;Connection: close&#39; header,</span>
+ <span class="c1"># HTTPConnection assumes the socket should be left open. Manually</span>
+ <span class="c1"># mark the socket to be closed when this response object goes away.</span>
+ <span class="k">if</span> <span class="n">h</span><span class="o">.</span><span class="n">sock</span><span class="p">:</span>
+ <span class="n">h</span><span class="o">.</span><span class="n">sock</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
+ <span class="n">h</span><span class="o">.</span><span class="n">sock</span> <span class="o">=</span> <span class="kc">None</span>
+
+ <span class="n">r</span><span class="o">.</span><span class="n">url</span> <span class="o">=</span> <span class="n">req</span><span class="o">.</span><span class="n">get_full_url</span><span class="p">()</span>
+ <span class="c1"># This line replaces the .msg attribute of the HTTPResponse</span>
+ <span class="c1"># with .headers, because urllib clients expect the response to</span>
+ <span class="c1"># have the reason in .msg. It would be good to mark this</span>
+ <span class="c1"># attribute is deprecated and get then to use info() or</span>
+ <span class="c1"># .headers.</span>
+ <span class="n">r</span><span class="o">.</span><span class="n">msg</span> <span class="o">=</span> <span class="n">r</span><span class="o">.</span><span class="n">reason</span>
+ <span class="k">return</span> <span class="n">r</span>
+
+
+<span class="k">class</span> <span class="nc">HTTPHandler</span><span class="p">(</span><span class="n">AbstractHTTPHandler</span><span class="p">):</span>
+
+ <span class="k">def</span> <span class="nf">http_open</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">req</span><span class="p">):</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">do_open</span><span class="p">(</span><span class="n">http</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">HTTPConnection</span><span class="p">,</span> <span class="n">req</span><span class="p">)</span>
+
+ <span class="n">http_request</span> <span class="o">=</span> <span class="n">AbstractHTTPHandler</span><span class="o">.</span><span class="n">do_request_</span>
+
+<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">http</span><span class="o">.</span><span class="n">client</span><span class="p">,</span> <span class="s1">&#39;HTTPSConnection&#39;</span><span class="p">):</span>
+
+ <span class="k">class</span> <span class="nc">HTTPSHandler</span><span class="p">(</span><span class="n">AbstractHTTPHandler</span><span class="p">):</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">debuglevel</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">context</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">check_hostname</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="n">AbstractHTTPHandler</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">debuglevel</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_context</span> <span class="o">=</span> <span class="n">context</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">_check_hostname</span> <span class="o">=</span> <span class="n">check_hostname</span>
+
+ <span class="k">def</span> <span class="nf">https_open</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">req</span><span class="p">):</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">do_open</span><span class="p">(</span><span class="n">http</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">HTTPSConnection</span><span class="p">,</span> <span class="n">req</span><span class="p">,</span>
+ <span class="n">context</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_context</span><span class="p">,</span> <span class="n">check_hostname</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_check_hostname</span><span class="p">)</span>
+
+ <span class="n">https_request</span> <span class="o">=</span> <span class="n">AbstractHTTPHandler</span><span class="o">.</span><span class="n">do_request_</span>
+
+ <span class="n">__all__</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">&#39;HTTPSHandler&#39;</span><span class="p">)</span>
+
+<span class="k">class</span> <span class="nc">HTTPCookieProcessor</span><span class="p">(</span><span class="n">BaseHandler</span><span class="p">):</span>
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">cookiejar</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="kn">import</span> <span class="nn">http.cookiejar</span>
+ <span class="k">if</span> <span class="n">cookiejar</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">cookiejar</span> <span class="o">=</span> <span class="n">http</span><span class="o">.</span><span class="n">cookiejar</span><span class="o">.</span><span class="n">CookieJar</span><span class="p">()</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">cookiejar</span> <span class="o">=</span> <span class="n">cookiejar</span>
+
+ <span class="k">def</span> <span class="nf">http_request</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">cookiejar</span><span class="o">.</span><span class="n">add_cookie_header</span><span class="p">(</span><span class="n">request</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">request</span>
+
+ <span class="k">def</span> <span class="nf">http_response</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">,</span> <span class="n">response</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">cookiejar</span><span class="o">.</span><span class="n">extract_cookies</span><span class="p">(</span><span class="n">response</span><span class="p">,</span> <span class="n">request</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">response</span>
+
+ <span class="n">https_request</span> <span class="o">=</span> <span class="n">http_request</span>
+ <span class="n">https_response</span> <span class="o">=</span> <span class="n">http_response</span>
+
+<span class="k">class</span> <span class="nc">UnknownHandler</span><span class="p">(</span><span class="n">BaseHandler</span><span class="p">):</span>
+ <span class="k">def</span> <span class="nf">unknown_open</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">req</span><span class="p">):</span>
+ <span class="nb">type</span> <span class="o">=</span> <span class="n">req</span><span class="o">.</span><span class="n">type</span>
+ <span class="k">raise</span> <span class="n">URLError</span><span class="p">(</span><span class="s1">&#39;unknown url type: </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="nb">type</span><span class="p">)</span>
+
+<span class="k">def</span> <span class="nf">parse_keqv_list</span><span class="p">(</span><span class="n">l</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Parse list of key=value strings where keys are not duplicated.&quot;&quot;&quot;</span>
+ <span class="n">parsed</span> <span class="o">=</span> <span class="p">{}</span>
+ <span class="k">for</span> <span class="n">elt</span> <span class="ow">in</span> <span class="n">l</span><span class="p">:</span>
+ <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="o">=</span> <span class="n">elt</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;=&#39;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">v</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="s1">&#39;&quot;&#39;</span> <span class="ow">and</span> <span class="n">v</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="s1">&#39;&quot;&#39;</span><span class="p">:</span>
+ <span class="n">v</span> <span class="o">=</span> <span class="n">v</span><span class="p">[</span><span class="mi">1</span><span class="p">:</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
+ <span class="n">parsed</span><span class="p">[</span><span class="n">k</span><span class="p">]</span> <span class="o">=</span> <span class="n">v</span>
+ <span class="k">return</span> <span class="n">parsed</span>
+
+<span class="k">def</span> <span class="nf">parse_http_list</span><span class="p">(</span><span class="n">s</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Parse lists as described by RFC 2068 Section 2.</span>
+
+<span class="sd"> In particular, parse comma-separated lists where the elements of</span>
+<span class="sd"> the list may include quoted-strings. A quoted-string could</span>
+<span class="sd"> contain a comma. A non-quoted string could have quotes in the</span>
+<span class="sd"> middle. Neither commas nor quotes count if they are escaped.</span>
+<span class="sd"> Only double-quotes count, not single-quotes.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">res</span> <span class="o">=</span> <span class="p">[]</span>
+ <span class="n">part</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
+
+ <span class="n">escape</span> <span class="o">=</span> <span class="n">quote</span> <span class="o">=</span> <span class="kc">False</span>
+ <span class="k">for</span> <span class="n">cur</span> <span class="ow">in</span> <span class="n">s</span><span class="p">:</span>
+ <span class="k">if</span> <span class="n">escape</span><span class="p">:</span>
+ <span class="n">part</span> <span class="o">+=</span> <span class="n">cur</span>
+ <span class="n">escape</span> <span class="o">=</span> <span class="kc">False</span>
+ <span class="k">continue</span>
+ <span class="k">if</span> <span class="n">quote</span><span class="p">:</span>
+ <span class="k">if</span> <span class="n">cur</span> <span class="o">==</span> <span class="s1">&#39;</span><span class="se">\\</span><span class="s1">&#39;</span><span class="p">:</span>
+ <span class="n">escape</span> <span class="o">=</span> <span class="kc">True</span>
+ <span class="k">continue</span>
+ <span class="k">elif</span> <span class="n">cur</span> <span class="o">==</span> <span class="s1">&#39;&quot;&#39;</span><span class="p">:</span>
+ <span class="n">quote</span> <span class="o">=</span> <span class="kc">False</span>
+ <span class="n">part</span> <span class="o">+=</span> <span class="n">cur</span>
+ <span class="k">continue</span>
+
+ <span class="k">if</span> <span class="n">cur</span> <span class="o">==</span> <span class="s1">&#39;,&#39;</span><span class="p">:</span>
+ <span class="n">res</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">part</span><span class="p">)</span>
+ <span class="n">part</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
+ <span class="k">continue</span>
+
+ <span class="k">if</span> <span class="n">cur</span> <span class="o">==</span> <span class="s1">&#39;&quot;&#39;</span><span class="p">:</span>
+ <span class="n">quote</span> <span class="o">=</span> <span class="kc">True</span>
+
+ <span class="n">part</span> <span class="o">+=</span> <span class="n">cur</span>
+
+ <span class="c1"># append last part</span>
+ <span class="k">if</span> <span class="n">part</span><span class="p">:</span>
+ <span class="n">res</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">part</span><span class="p">)</span>
+
+ <span class="k">return</span> <span class="p">[</span><span class="n">part</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="k">for</span> <span class="n">part</span> <span class="ow">in</span> <span class="n">res</span><span class="p">]</span>
+
+<span class="k">class</span> <span class="nc">FileHandler</span><span class="p">(</span><span class="n">BaseHandler</span><span class="p">):</span>
+ <span class="c1"># Use local file or FTP depending on form of URL</span>
+ <span class="k">def</span> <span class="nf">file_open</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">req</span><span class="p">):</span>
+ <span class="n">url</span> <span class="o">=</span> <span class="n">req</span><span class="o">.</span><span class="n">selector</span>
+ <span class="k">if</span> <span class="n">url</span><span class="p">[:</span><span class="mi">2</span><span class="p">]</span> <span class="o">==</span> <span class="s1">&#39;//&#39;</span> <span class="ow">and</span> <span class="n">url</span><span class="p">[</span><span class="mi">2</span><span class="p">:</span><span class="mi">3</span><span class="p">]</span> <span class="o">!=</span> <span class="s1">&#39;/&#39;</span> <span class="ow">and</span> <span class="p">(</span><span class="n">req</span><span class="o">.</span><span class="n">host</span> <span class="ow">and</span>
+ <span class="n">req</span><span class="o">.</span><span class="n">host</span> <span class="o">!=</span> <span class="s1">&#39;localhost&#39;</span><span class="p">):</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">req</span><span class="o">.</span><span class="n">host</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_names</span><span class="p">():</span>
+ <span class="k">raise</span> <span class="n">URLError</span><span class="p">(</span><span class="s2">&quot;file:// scheme is supported only on localhost&quot;</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">open_local_file</span><span class="p">(</span><span class="n">req</span><span class="p">)</span>
+
+ <span class="c1"># names for the localhost</span>
+ <span class="n">names</span> <span class="o">=</span> <span class="kc">None</span>
+ <span class="k">def</span> <span class="nf">get_names</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="k">if</span> <span class="n">FileHandler</span><span class="o">.</span><span class="n">names</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">try</span><span class="p">:</span>
+ <span class="n">FileHandler</span><span class="o">.</span><span class="n">names</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span>
+ <span class="n">socket</span><span class="o">.</span><span class="n">gethostbyname_ex</span><span class="p">(</span><span class="s1">&#39;localhost&#39;</span><span class="p">)[</span><span class="mi">2</span><span class="p">]</span> <span class="o">+</span>
+ <span class="n">socket</span><span class="o">.</span><span class="n">gethostbyname_ex</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">gethostname</span><span class="p">())[</span><span class="mi">2</span><span class="p">])</span>
+ <span class="k">except</span> <span class="n">socket</span><span class="o">.</span><span class="n">gaierror</span><span class="p">:</span>
+ <span class="n">FileHandler</span><span class="o">.</span><span class="n">names</span> <span class="o">=</span> <span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">gethostbyname</span><span class="p">(</span><span class="s1">&#39;localhost&#39;</span><span class="p">),)</span>
+ <span class="k">return</span> <span class="n">FileHandler</span><span class="o">.</span><span class="n">names</span>
+
+ <span class="c1"># not entirely sure what the rules are here</span>
+ <span class="k">def</span> <span class="nf">open_local_file</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">req</span><span class="p">):</span>
+ <span class="kn">import</span> <span class="nn">email.utils</span>
+ <span class="kn">import</span> <span class="nn">mimetypes</span>
+ <span class="n">host</span> <span class="o">=</span> <span class="n">req</span><span class="o">.</span><span class="n">host</span>
+ <span class="n">filename</span> <span class="o">=</span> <span class="n">req</span><span class="o">.</span><span class="n">selector</span>
+ <span class="n">localfile</span> <span class="o">=</span> <span class="n">url2pathname</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span>
+ <span class="k">try</span><span class="p">:</span>
+ <span class="n">stats</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">stat</span><span class="p">(</span><span class="n">localfile</span><span class="p">)</span>
+ <span class="n">size</span> <span class="o">=</span> <span class="n">stats</span><span class="o">.</span><span class="n">st_size</span>
+ <span class="n">modified</span> <span class="o">=</span> <span class="n">email</span><span class="o">.</span><span class="n">utils</span><span class="o">.</span><span class="n">formatdate</span><span class="p">(</span><span class="n">stats</span><span class="o">.</span><span class="n">st_mtime</span><span class="p">,</span> <span class="n">usegmt</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
+ <span class="n">mtype</span> <span class="o">=</span> <span class="n">mimetypes</span><span class="o">.</span><span class="n">guess_type</span><span class="p">(</span><span class="n">filename</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
+ <span class="n">headers</span> <span class="o">=</span> <span class="n">email</span><span class="o">.</span><span class="n">message_from_string</span><span class="p">(</span>
+ <span class="s1">&#39;Content-type: </span><span class="si">%s</span><span class="se">\n</span><span class="s1">Content-length: </span><span class="si">%d</span><span class="se">\n</span><span class="s1">Last-modified: </span><span class="si">%s</span><span class="se">\n</span><span class="s1">&#39;</span> <span class="o">%</span>
+ <span class="p">(</span><span class="n">mtype</span> <span class="ow">or</span> <span class="s1">&#39;text/plain&#39;</span><span class="p">,</span> <span class="n">size</span><span class="p">,</span> <span class="n">modified</span><span class="p">))</span>
+ <span class="k">if</span> <span class="n">host</span><span class="p">:</span>
+ <span class="n">host</span><span class="p">,</span> <span class="n">port</span> <span class="o">=</span> <span class="n">splitport</span><span class="p">(</span><span class="n">host</span><span class="p">)</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">host</span> <span class="ow">or</span> \
+ <span class="p">(</span><span class="ow">not</span> <span class="n">port</span> <span class="ow">and</span> <span class="n">_safe_gethostbyname</span><span class="p">(</span><span class="n">host</span><span class="p">)</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_names</span><span class="p">()):</span>
+ <span class="k">if</span> <span class="n">host</span><span class="p">:</span>
+ <span class="n">origurl</span> <span class="o">=</span> <span class="s1">&#39;file://&#39;</span> <span class="o">+</span> <span class="n">host</span> <span class="o">+</span> <span class="n">filename</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">origurl</span> <span class="o">=</span> <span class="s1">&#39;file://&#39;</span> <span class="o">+</span> <span class="n">filename</span>
+ <span class="k">return</span> <span class="n">addinfourl</span><span class="p">(</span><span class="nb">open</span><span class="p">(</span><span class="n">localfile</span><span class="p">,</span> <span class="s1">&#39;rb&#39;</span><span class="p">),</span> <span class="n">headers</span><span class="p">,</span> <span class="n">origurl</span><span class="p">)</span>
+ <span class="k">except</span> <span class="ne">OSError</span> <span class="k">as</span> <span class="n">exp</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="n">URLError</span><span class="p">(</span><span class="n">exp</span><span class="p">)</span>
+ <span class="k">raise</span> <span class="n">URLError</span><span class="p">(</span><span class="s1">&#39;file not on local host&#39;</span><span class="p">)</span>
+
+<span class="k">def</span> <span class="nf">_safe_gethostbyname</span><span class="p">(</span><span class="n">host</span><span class="p">):</span>
+ <span class="k">try</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">socket</span><span class="o">.</span><span class="n">gethostbyname</span><span class="p">(</span><span class="n">host</span><span class="p">)</span>
+ <span class="k">except</span> <span class="n">socket</span><span class="o">.</span><span class="n">gaierror</span><span class="p">:</span>
+ <span class="k">return</span> <span class="kc">None</span>
+
+<span class="k">class</span> <span class="nc">FTPHandler</span><span class="p">(</span><span class="n">BaseHandler</span><span class="p">):</span>
+ <span class="k">def</span> <span class="nf">ftp_open</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">req</span><span class="p">):</span>
+ <span class="kn">import</span> <span class="nn">ftplib</span>
+ <span class="kn">import</span> <span class="nn">mimetypes</span>
+ <span class="n">host</span> <span class="o">=</span> <span class="n">req</span><span class="o">.</span><span class="n">host</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">host</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="n">URLError</span><span class="p">(</span><span class="s1">&#39;ftp error: no host given&#39;</span><span class="p">)</span>
+ <span class="n">host</span><span class="p">,</span> <span class="n">port</span> <span class="o">=</span> <span class="n">splitport</span><span class="p">(</span><span class="n">host</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">port</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">port</span> <span class="o">=</span> <span class="n">ftplib</span><span class="o">.</span><span class="n">FTP_PORT</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">port</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">port</span><span class="p">)</span>
+
+ <span class="c1"># username/password handling</span>
+ <span class="n">user</span><span class="p">,</span> <span class="n">host</span> <span class="o">=</span> <span class="n">splituser</span><span class="p">(</span><span class="n">host</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">user</span><span class="p">:</span>
+ <span class="n">user</span><span class="p">,</span> <span class="n">passwd</span> <span class="o">=</span> <span class="n">splitpasswd</span><span class="p">(</span><span class="n">user</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">passwd</span> <span class="o">=</span> <span class="kc">None</span>
+ <span class="n">host</span> <span class="o">=</span> <span class="n">unquote</span><span class="p">(</span><span class="n">host</span><span class="p">)</span>
+ <span class="n">user</span> <span class="o">=</span> <span class="n">user</span> <span class="ow">or</span> <span class="s1">&#39;&#39;</span>
+ <span class="n">passwd</span> <span class="o">=</span> <span class="n">passwd</span> <span class="ow">or</span> <span class="s1">&#39;&#39;</span>
+
+ <span class="k">try</span><span class="p">:</span>
+ <span class="n">host</span> <span class="o">=</span> <span class="n">socket</span><span class="o">.</span><span class="n">gethostbyname</span><span class="p">(</span><span class="n">host</span><span class="p">)</span>
+ <span class="k">except</span> <span class="ne">OSError</span> <span class="k">as</span> <span class="n">msg</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="n">URLError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
+ <span class="n">path</span><span class="p">,</span> <span class="n">attrs</span> <span class="o">=</span> <span class="n">splitattr</span><span class="p">(</span><span class="n">req</span><span class="o">.</span><span class="n">selector</span><span class="p">)</span>
+ <span class="n">dirs</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;/&#39;</span><span class="p">)</span>
+ <span class="n">dirs</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="n">unquote</span><span class="p">,</span> <span class="n">dirs</span><span class="p">))</span>
+ <span class="n">dirs</span><span class="p">,</span> <span class="n">file</span> <span class="o">=</span> <span class="n">dirs</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span> <span class="n">dirs</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
+ <span class="k">if</span> <span class="n">dirs</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">dirs</span><span class="p">[</span><span class="mi">0</span><span class="p">]:</span>
+ <span class="n">dirs</span> <span class="o">=</span> <span class="n">dirs</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span>
+ <span class="k">try</span><span class="p">:</span>
+ <span class="n">fw</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">connect_ftp</span><span class="p">(</span><span class="n">user</span><span class="p">,</span> <span class="n">passwd</span><span class="p">,</span> <span class="n">host</span><span class="p">,</span> <span class="n">port</span><span class="p">,</span> <span class="n">dirs</span><span class="p">,</span> <span class="n">req</span><span class="o">.</span><span class="n">timeout</span><span class="p">)</span>
+ <span class="nb">type</span> <span class="o">=</span> <span class="n">file</span> <span class="ow">and</span> <span class="s1">&#39;I&#39;</span> <span class="ow">or</span> <span class="s1">&#39;D&#39;</span>
+ <span class="k">for</span> <span class="n">attr</span> <span class="ow">in</span> <span class="n">attrs</span><span class="p">:</span>
+ <span class="n">attr</span><span class="p">,</span> <span class="n">value</span> <span class="o">=</span> <span class="n">splitvalue</span><span class="p">(</span><span class="n">attr</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">attr</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="o">==</span> <span class="s1">&#39;type&#39;</span> <span class="ow">and</span> \
+ <span class="n">value</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">&#39;a&#39;</span><span class="p">,</span> <span class="s1">&#39;A&#39;</span><span class="p">,</span> <span class="s1">&#39;i&#39;</span><span class="p">,</span> <span class="s1">&#39;I&#39;</span><span class="p">,</span> <span class="s1">&#39;d&#39;</span><span class="p">,</span> <span class="s1">&#39;D&#39;</span><span class="p">):</span>
+ <span class="nb">type</span> <span class="o">=</span> <span class="n">value</span><span class="o">.</span><span class="n">upper</span><span class="p">()</span>
+ <span class="n">fp</span><span class="p">,</span> <span class="n">retrlen</span> <span class="o">=</span> <span class="n">fw</span><span class="o">.</span><span class="n">retrfile</span><span class="p">(</span><span class="n">file</span><span class="p">,</span> <span class="nb">type</span><span class="p">)</span>
+ <span class="n">headers</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
+ <span class="n">mtype</span> <span class="o">=</span> <span class="n">mimetypes</span><span class="o">.</span><span class="n">guess_type</span><span class="p">(</span><span class="n">req</span><span class="o">.</span><span class="n">full_url</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
+ <span class="k">if</span> <span class="n">mtype</span><span class="p">:</span>
+ <span class="n">headers</span> <span class="o">+=</span> <span class="s2">&quot;Content-type: </span><span class="si">%s</span><span class="se">\n</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">mtype</span>
+ <span class="k">if</span> <span class="n">retrlen</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">retrlen</span> <span class="o">&gt;=</span> <span class="mi">0</span><span class="p">:</span>
+ <span class="n">headers</span> <span class="o">+=</span> <span class="s2">&quot;Content-length: </span><span class="si">%d</span><span class="se">\n</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">retrlen</span>
+ <span class="n">headers</span> <span class="o">=</span> <span class="n">email</span><span class="o">.</span><span class="n">message_from_string</span><span class="p">(</span><span class="n">headers</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">addinfourl</span><span class="p">(</span><span class="n">fp</span><span class="p">,</span> <span class="n">headers</span><span class="p">,</span> <span class="n">req</span><span class="o">.</span><span class="n">full_url</span><span class="p">)</span>
+ <span class="k">except</span> <span class="n">ftplib</span><span class="o">.</span><span class="n">all_errors</span> <span class="k">as</span> <span class="n">exp</span><span class="p">:</span>
+ <span class="n">exc</span> <span class="o">=</span> <span class="n">URLError</span><span class="p">(</span><span class="s1">&#39;ftp error: </span><span class="si">%r</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">exp</span><span class="p">)</span>
+ <span class="k">raise</span> <span class="n">exc</span><span class="o">.</span><span class="n">with_traceback</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">()[</span><span class="mi">2</span><span class="p">])</span>
+
+ <span class="k">def</span> <span class="nf">connect_ftp</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="n">passwd</span><span class="p">,</span> <span class="n">host</span><span class="p">,</span> <span class="n">port</span><span class="p">,</span> <span class="n">dirs</span><span class="p">,</span> <span class="n">timeout</span><span class="p">):</span>
+ <span class="k">return</span> <span class="n">ftpwrapper</span><span class="p">(</span><span class="n">user</span><span class="p">,</span> <span class="n">passwd</span><span class="p">,</span> <span class="n">host</span><span class="p">,</span> <span class="n">port</span><span class="p">,</span> <span class="n">dirs</span><span class="p">,</span> <span class="n">timeout</span><span class="p">,</span>
+ <span class="n">persistent</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
+
+<span class="k">class</span> <span class="nc">CacheFTPHandler</span><span class="p">(</span><span class="n">FTPHandler</span><span class="p">):</span>
+ <span class="c1"># XXX would be nice to have pluggable cache strategies</span>
+ <span class="c1"># XXX this stuff is definitely not thread safe</span>
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">cache</span> <span class="o">=</span> <span class="p">{}</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">timeout</span> <span class="o">=</span> <span class="p">{}</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">soonest</span> <span class="o">=</span> <span class="mi">0</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">delay</span> <span class="o">=</span> <span class="mi">60</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">max_conns</span> <span class="o">=</span> <span class="mi">16</span>
+
+ <span class="k">def</span> <span class="nf">setTimeout</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">t</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">delay</span> <span class="o">=</span> <span class="n">t</span>
+
+ <span class="k">def</span> <span class="nf">setMaxConns</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">m</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">max_conns</span> <span class="o">=</span> <span class="n">m</span>
+
+ <span class="k">def</span> <span class="nf">connect_ftp</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="n">passwd</span><span class="p">,</span> <span class="n">host</span><span class="p">,</span> <span class="n">port</span><span class="p">,</span> <span class="n">dirs</span><span class="p">,</span> <span class="n">timeout</span><span class="p">):</span>
+ <span class="n">key</span> <span class="o">=</span> <span class="n">user</span><span class="p">,</span> <span class="n">host</span><span class="p">,</span> <span class="n">port</span><span class="p">,</span> <span class="s1">&#39;/&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">dirs</span><span class="p">),</span> <span class="n">timeout</span>
+ <span class="k">if</span> <span class="n">key</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">cache</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">timeout</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">delay</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">cache</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">ftpwrapper</span><span class="p">(</span><span class="n">user</span><span class="p">,</span> <span class="n">passwd</span><span class="p">,</span> <span class="n">host</span><span class="p">,</span> <span class="n">port</span><span class="p">,</span>
+ <span class="n">dirs</span><span class="p">,</span> <span class="n">timeout</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">timeout</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">delay</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">check_cache</span><span class="p">()</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">cache</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
+
+ <span class="k">def</span> <span class="nf">check_cache</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># first check for old ones</span>
+ <span class="n">t</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span>
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">soonest</span> <span class="o">&lt;=</span> <span class="n">t</span><span class="p">:</span>
+ <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="nb">list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">timeout</span><span class="o">.</span><span class="n">items</span><span class="p">()):</span>
+ <span class="k">if</span> <span class="n">v</span> <span class="o">&lt;</span> <span class="n">t</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">cache</span><span class="p">[</span><span class="n">k</span><span class="p">]</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
+ <span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">cache</span><span class="p">[</span><span class="n">k</span><span class="p">]</span>
+ <span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">timeout</span><span class="p">[</span><span class="n">k</span><span class="p">]</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">soonest</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="nb">list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">timeout</span><span class="o">.</span><span class="n">values</span><span class="p">()))</span>
+
+ <span class="c1"># then check the size</span>
+ <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">cache</span><span class="p">)</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">max_conns</span><span class="p">:</span>
+ <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="nb">list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">timeout</span><span class="o">.</span><span class="n">items</span><span class="p">()):</span>
+ <span class="k">if</span> <span class="n">v</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">soonest</span><span class="p">:</span>
+ <span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">cache</span><span class="p">[</span><span class="n">k</span><span class="p">]</span>
+ <span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">timeout</span><span class="p">[</span><span class="n">k</span><span class="p">]</span>
+ <span class="k">break</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">soonest</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="nb">list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">timeout</span><span class="o">.</span><span class="n">values</span><span class="p">()))</span>
+
+ <span class="k">def</span> <span class="nf">clear_cache</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="k">for</span> <span class="n">conn</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">cache</span><span class="o">.</span><span class="n">values</span><span class="p">():</span>
+ <span class="n">conn</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">cache</span><span class="o">.</span><span class="n">clear</span><span class="p">()</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">timeout</span><span class="o">.</span><span class="n">clear</span><span class="p">()</span>
+
+<span class="k">class</span> <span class="nc">DataHandler</span><span class="p">(</span><span class="n">BaseHandler</span><span class="p">):</span>
+ <span class="k">def</span> <span class="nf">data_open</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">req</span><span class="p">):</span>
+ <span class="c1"># data URLs as specified in RFC 2397.</span>
+ <span class="c1">#</span>
+ <span class="c1"># ignores POSTed data</span>
+ <span class="c1">#</span>
+ <span class="c1"># syntax:</span>
+ <span class="c1"># dataurl := &quot;data:&quot; [ mediatype ] [ &quot;;base64&quot; ] &quot;,&quot; data</span>
+ <span class="c1"># mediatype := [ type &quot;/&quot; subtype ] *( &quot;;&quot; parameter )</span>
+ <span class="c1"># data := *urlchar</span>
+ <span class="c1"># parameter := attribute &quot;=&quot; value</span>
+ <span class="n">url</span> <span class="o">=</span> <span class="n">req</span><span class="o">.</span><span class="n">full_url</span>
+
+ <span class="n">scheme</span><span class="p">,</span> <span class="n">data</span> <span class="o">=</span> <span class="n">url</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot;:&quot;</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span>
+ <span class="n">mediatype</span><span class="p">,</span> <span class="n">data</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot;,&quot;</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span>
+
+ <span class="c1"># even base64 encoded data URLs might be quoted so unquote in any case:</span>
+ <span class="n">data</span> <span class="o">=</span> <span class="n">unquote_to_bytes</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">mediatype</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="s2">&quot;;base64&quot;</span><span class="p">):</span>
+ <span class="n">data</span> <span class="o">=</span> <span class="n">base64</span><span class="o">.</span><span class="n">decodebytes</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
+ <span class="n">mediatype</span> <span class="o">=</span> <span class="n">mediatype</span><span class="p">[:</span><span class="o">-</span><span class="mi">7</span><span class="p">]</span>
+
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">mediatype</span><span class="p">:</span>
+ <span class="n">mediatype</span> <span class="o">=</span> <span class="s2">&quot;text/plain;charset=US-ASCII&quot;</span>
+
+ <span class="n">headers</span> <span class="o">=</span> <span class="n">email</span><span class="o">.</span><span class="n">message_from_string</span><span class="p">(</span><span class="s2">&quot;Content-type: </span><span class="si">%s</span><span class="se">\n</span><span class="s2">Content-length: </span><span class="si">%d</span><span class="se">\n</span><span class="s2">&quot;</span> <span class="o">%</span>
+ <span class="p">(</span><span class="n">mediatype</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">data</span><span class="p">)))</span>
+
+ <span class="k">return</span> <span class="n">addinfourl</span><span class="p">(</span><span class="n">io</span><span class="o">.</span><span class="n">BytesIO</span><span class="p">(</span><span class="n">data</span><span class="p">),</span> <span class="n">headers</span><span class="p">,</span> <span class="n">url</span><span class="p">)</span>
+
+
+<span class="c1"># Code move from the old urllib module</span>
+
+<span class="n">MAXFTPCACHE</span> <span class="o">=</span> <span class="mi">10</span> <span class="c1"># Trim the ftp cache beyond this size</span>
+
+<span class="c1"># Helper for non-unix systems</span>
+<span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">name</span> <span class="o">==</span> <span class="s1">&#39;nt&#39;</span><span class="p">:</span>
+ <span class="kn">from</span> <span class="nn">nturl2path</span> <span class="k">import</span> <span class="n">url2pathname</span><span class="p">,</span> <span class="n">pathname2url</span>
+<span class="k">else</span><span class="p">:</span>
+ <span class="k">def</span> <span class="nf">url2pathname</span><span class="p">(</span><span class="n">pathname</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;OS-specific conversion from a relative URL of the &#39;file&#39; scheme</span>
+<span class="sd"> to a file system path; not recommended for general use.&quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">unquote</span><span class="p">(</span><span class="n">pathname</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">pathname2url</span><span class="p">(</span><span class="n">pathname</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;OS-specific conversion from a file system path to a relative URL</span>
+<span class="sd"> of the &#39;file&#39; scheme; not recommended for general use.&quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">quote</span><span class="p">(</span><span class="n">pathname</span><span class="p">)</span>
+
+
+<span class="n">ftpcache</span> <span class="o">=</span> <span class="p">{}</span>
+
+
+<span class="k">class</span> <span class="nc">URLopener</span><span class="p">:</span>
+ <span class="sd">&quot;&quot;&quot;Class to open URLs.</span>
+<span class="sd"> This is a class rather than just a subroutine because we may need</span>
+<span class="sd"> more than one set of global protocol-specific options.</span>
+<span class="sd"> Note -- this is a base class for those who don&#39;t want the</span>
+<span class="sd"> automatic handling of errors type 302 (relocated) and 401</span>
+<span class="sd"> (authorization needed).&quot;&quot;&quot;</span>
+
+ <span class="n">__tempfiles</span> <span class="o">=</span> <span class="kc">None</span>
+
+ <span class="n">version</span> <span class="o">=</span> <span class="s2">&quot;Python-urllib/</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">__version__</span>
+
+ <span class="c1"># Constructor</span>
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">proxies</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">**</span><span class="n">x509</span><span class="p">):</span>
+ <span class="n">msg</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="si">%(class)s</span><span class="s2"> style of invoking requests is deprecated. &quot;</span> \
+ <span class="s2">&quot;Use newer urlopen functions/methods&quot;</span> <span class="o">%</span> <span class="p">{</span><span class="s1">&#39;class&#39;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span><span class="p">}</span>
+ <span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="ne">DeprecationWarning</span><span class="p">,</span> <span class="n">stacklevel</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">proxies</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">proxies</span> <span class="o">=</span> <span class="n">getproxies</span><span class="p">()</span>
+ <span class="k">assert</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">proxies</span><span class="p">,</span> <span class="s1">&#39;keys&#39;</span><span class="p">),</span> <span class="s2">&quot;proxies must be a mapping&quot;</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">proxies</span> <span class="o">=</span> <span class="n">proxies</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">key_file</span> <span class="o">=</span> <span class="n">x509</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;key_file&#39;</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">cert_file</span> <span class="o">=</span> <span class="n">x509</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;cert_file&#39;</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">addheaders</span> <span class="o">=</span> <span class="p">[(</span><span class="s1">&#39;User-Agent&#39;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">version</span><span class="p">),</span> <span class="p">(</span><span class="s1">&#39;Accept&#39;</span><span class="p">,</span> <span class="s1">&#39;*/*&#39;</span><span class="p">)]</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">__tempfiles</span> <span class="o">=</span> <span class="p">[]</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">__unlink</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">unlink</span> <span class="c1"># See cleanup()</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">tempcache</span> <span class="o">=</span> <span class="kc">None</span>
+ <span class="c1"># Undocumented feature: if you assign {} to tempcache,</span>
+ <span class="c1"># it is used to cache files retrieved with</span>
+ <span class="c1"># self.retrieve(). This is not enabled by default</span>
+ <span class="c1"># since it does not work for changing documents (and I</span>
+ <span class="c1"># haven&#39;t got the logic to check expiration headers</span>
+ <span class="c1"># yet).</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">ftpcache</span> <span class="o">=</span> <span class="n">ftpcache</span>
+ <span class="c1"># Undocumented feature: you can use a different</span>
+ <span class="c1"># ftp cache by assigning to the .ftpcache member;</span>
+ <span class="c1"># in case you want logically independent URL openers</span>
+ <span class="c1"># XXX This is not threadsafe. Bah.</span>
+
+ <span class="k">def</span> <span class="nf">__del__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
+
+ <span class="k">def</span> <span class="nf">close</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">cleanup</span><span class="p">()</span>
+
+ <span class="k">def</span> <span class="nf">cleanup</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="c1"># This code sometimes runs when the rest of this module</span>
+ <span class="c1"># has already been deleted, so it can&#39;t use any globals</span>
+ <span class="c1"># or import anything.</span>
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">__tempfiles</span><span class="p">:</span>
+ <span class="k">for</span> <span class="n">file</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">__tempfiles</span><span class="p">:</span>
+ <span class="k">try</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">__unlink</span><span class="p">(</span><span class="n">file</span><span class="p">)</span>
+ <span class="k">except</span> <span class="ne">OSError</span><span class="p">:</span>
+ <span class="k">pass</span>
+ <span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">__tempfiles</span><span class="p">[:]</span>
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">tempcache</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">tempcache</span><span class="o">.</span><span class="n">clear</span><span class="p">()</span>
+
+ <span class="k">def</span> <span class="nf">addheader</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Add a header to be used by the HTTP interface only</span>
+<span class="sd"> e.g. u.addheader(&#39;Accept&#39;, &#39;sound/basic&#39;)&quot;&quot;&quot;</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">addheaders</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">args</span><span class="p">)</span>
+
+ <span class="c1"># External interface</span>
+ <span class="k">def</span> <span class="nf">open</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">fullurl</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Use URLopener().open(file) instead of open(file, &#39;r&#39;).&quot;&quot;&quot;</span>
+ <span class="n">fullurl</span> <span class="o">=</span> <span class="n">unwrap</span><span class="p">(</span><span class="n">to_bytes</span><span class="p">(</span><span class="n">fullurl</span><span class="p">))</span>
+ <span class="n">fullurl</span> <span class="o">=</span> <span class="n">quote</span><span class="p">(</span><span class="n">fullurl</span><span class="p">,</span> <span class="n">safe</span><span class="o">=</span><span class="s2">&quot;%/:=&amp;?~#+!$,;&#39;@()*[]|&quot;</span><span class="p">)</span>
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">tempcache</span> <span class="ow">and</span> <span class="n">fullurl</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">tempcache</span><span class="p">:</span>
+ <span class="n">filename</span><span class="p">,</span> <span class="n">headers</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">tempcache</span><span class="p">[</span><span class="n">fullurl</span><span class="p">]</span>
+ <span class="n">fp</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="s1">&#39;rb&#39;</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">addinfourl</span><span class="p">(</span><span class="n">fp</span><span class="p">,</span> <span class="n">headers</span><span class="p">,</span> <span class="n">fullurl</span><span class="p">)</span>
+ <span class="n">urltype</span><span class="p">,</span> <span class="n">url</span> <span class="o">=</span> <span class="n">splittype</span><span class="p">(</span><span class="n">fullurl</span><span class="p">)</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">urltype</span><span class="p">:</span>
+ <span class="n">urltype</span> <span class="o">=</span> <span class="s1">&#39;file&#39;</span>
+ <span class="k">if</span> <span class="n">urltype</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">proxies</span><span class="p">:</span>
+ <span class="n">proxy</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">proxies</span><span class="p">[</span><span class="n">urltype</span><span class="p">]</span>
+ <span class="n">urltype</span><span class="p">,</span> <span class="n">proxyhost</span> <span class="o">=</span> <span class="n">splittype</span><span class="p">(</span><span class="n">proxy</span><span class="p">)</span>
+ <span class="n">host</span><span class="p">,</span> <span class="n">selector</span> <span class="o">=</span> <span class="n">splithost</span><span class="p">(</span><span class="n">proxyhost</span><span class="p">)</span>
+ <span class="n">url</span> <span class="o">=</span> <span class="p">(</span><span class="n">host</span><span class="p">,</span> <span class="n">fullurl</span><span class="p">)</span> <span class="c1"># Signal special case to open_*()</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">proxy</span> <span class="o">=</span> <span class="kc">None</span>
+ <span class="n">name</span> <span class="o">=</span> <span class="s1">&#39;open_&#39;</span> <span class="o">+</span> <span class="n">urltype</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">type</span> <span class="o">=</span> <span class="n">urltype</span>
+ <span class="n">name</span> <span class="o">=</span> <span class="n">name</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;-&#39;</span><span class="p">,</span> <span class="s1">&#39;_&#39;</span><span class="p">)</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
+ <span class="k">if</span> <span class="n">proxy</span><span class="p">:</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">open_unknown_proxy</span><span class="p">(</span><span class="n">proxy</span><span class="p">,</span> <span class="n">fullurl</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">open_unknown</span><span class="p">(</span><span class="n">fullurl</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span>
+ <span class="k">try</span><span class="p">:</span>
+ <span class="k">if</span> <span class="n">data</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">return</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">)(</span><span class="n">url</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">return</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">)(</span><span class="n">url</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span>
+ <span class="k">except</span> <span class="p">(</span><span class="n">HTTPError</span><span class="p">,</span> <span class="n">URLError</span><span class="p">):</span>
+ <span class="k">raise</span>
+ <span class="k">except</span> <span class="ne">OSError</span> <span class="k">as</span> <span class="n">msg</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">OSError</span><span class="p">(</span><span class="s1">&#39;socket error&#39;</span><span class="p">,</span> <span class="n">msg</span><span class="p">)</span><span class="o">.</span><span class="n">with_traceback</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">()[</span><span class="mi">2</span><span class="p">])</span>
+
+ <span class="k">def</span> <span class="nf">open_unknown</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">fullurl</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Overridable interface to open unknown URL type.&quot;&quot;&quot;</span>
+ <span class="nb">type</span><span class="p">,</span> <span class="n">url</span> <span class="o">=</span> <span class="n">splittype</span><span class="p">(</span><span class="n">fullurl</span><span class="p">)</span>
+ <span class="k">raise</span> <span class="ne">OSError</span><span class="p">(</span><span class="s1">&#39;url error&#39;</span><span class="p">,</span> <span class="s1">&#39;unknown url type&#39;</span><span class="p">,</span> <span class="nb">type</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">open_unknown_proxy</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">proxy</span><span class="p">,</span> <span class="n">fullurl</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Overridable interface to open unknown URL type.&quot;&quot;&quot;</span>
+ <span class="nb">type</span><span class="p">,</span> <span class="n">url</span> <span class="o">=</span> <span class="n">splittype</span><span class="p">(</span><span class="n">fullurl</span><span class="p">)</span>
+ <span class="k">raise</span> <span class="ne">OSError</span><span class="p">(</span><span class="s1">&#39;url error&#39;</span><span class="p">,</span> <span class="s1">&#39;invalid proxy for </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="nb">type</span><span class="p">,</span> <span class="n">proxy</span><span class="p">)</span>
+
+ <span class="c1"># External interface</span>
+ <span class="k">def</span> <span class="nf">retrieve</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">filename</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">reporthook</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;retrieve(url) returns (filename, headers) for a local object</span>
+<span class="sd"> or (tempfilename, headers) for a remote object.&quot;&quot;&quot;</span>
+ <span class="n">url</span> <span class="o">=</span> <span class="n">unwrap</span><span class="p">(</span><span class="n">to_bytes</span><span class="p">(</span><span class="n">url</span><span class="p">))</span>
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">tempcache</span> <span class="ow">and</span> <span class="n">url</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">tempcache</span><span class="p">:</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">tempcache</span><span class="p">[</span><span class="n">url</span><span class="p">]</span>
+ <span class="nb">type</span><span class="p">,</span> <span class="n">url1</span> <span class="o">=</span> <span class="n">splittype</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">filename</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">and</span> <span class="p">(</span><span class="ow">not</span> <span class="nb">type</span> <span class="ow">or</span> <span class="nb">type</span> <span class="o">==</span> <span class="s1">&#39;file&#39;</span><span class="p">):</span>
+ <span class="k">try</span><span class="p">:</span>
+ <span class="n">fp</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">open_local_file</span><span class="p">(</span><span class="n">url1</span><span class="p">)</span>
+ <span class="n">hdrs</span> <span class="o">=</span> <span class="n">fp</span><span class="o">.</span><span class="n">info</span><span class="p">()</span>
+ <span class="n">fp</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
+ <span class="k">return</span> <span class="n">url2pathname</span><span class="p">(</span><span class="n">splithost</span><span class="p">(</span><span class="n">url1</span><span class="p">)[</span><span class="mi">1</span><span class="p">]),</span> <span class="n">hdrs</span>
+ <span class="k">except</span> <span class="ne">OSError</span> <span class="k">as</span> <span class="n">msg</span><span class="p">:</span>
+ <span class="k">pass</span>
+ <span class="n">fp</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span>
+ <span class="k">try</span><span class="p">:</span>
+ <span class="n">headers</span> <span class="o">=</span> <span class="n">fp</span><span class="o">.</span><span class="n">info</span><span class="p">()</span>
+ <span class="k">if</span> <span class="n">filename</span><span class="p">:</span>
+ <span class="n">tfp</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="s1">&#39;wb&#39;</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">garbage</span><span class="p">,</span> <span class="n">path</span> <span class="o">=</span> <span class="n">splittype</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
+ <span class="n">garbage</span><span class="p">,</span> <span class="n">path</span> <span class="o">=</span> <span class="n">splithost</span><span class="p">(</span><span class="n">path</span> <span class="ow">or</span> <span class="s2">&quot;&quot;</span><span class="p">)</span>
+ <span class="n">path</span><span class="p">,</span> <span class="n">garbage</span> <span class="o">=</span> <span class="n">splitquery</span><span class="p">(</span><span class="n">path</span> <span class="ow">or</span> <span class="s2">&quot;&quot;</span><span class="p">)</span>
+ <span class="n">path</span><span class="p">,</span> <span class="n">garbage</span> <span class="o">=</span> <span class="n">splitattr</span><span class="p">(</span><span class="n">path</span> <span class="ow">or</span> <span class="s2">&quot;&quot;</span><span class="p">)</span>
+ <span class="n">suffix</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">splitext</span><span class="p">(</span><span class="n">path</span><span class="p">)[</span><span class="mi">1</span><span class="p">]</span>
+ <span class="p">(</span><span class="n">fd</span><span class="p">,</span> <span class="n">filename</span><span class="p">)</span> <span class="o">=</span> <span class="n">tempfile</span><span class="o">.</span><span class="n">mkstemp</span><span class="p">(</span><span class="n">suffix</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">__tempfiles</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span>
+ <span class="n">tfp</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">fdopen</span><span class="p">(</span><span class="n">fd</span><span class="p">,</span> <span class="s1">&#39;wb&#39;</span><span class="p">)</span>
+ <span class="k">try</span><span class="p">:</span>
+ <span class="n">result</span> <span class="o">=</span> <span class="n">filename</span><span class="p">,</span> <span class="n">headers</span>
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">tempcache</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">tempcache</span><span class="p">[</span><span class="n">url</span><span class="p">]</span> <span class="o">=</span> <span class="n">result</span>
+ <span class="n">bs</span> <span class="o">=</span> <span class="mi">1024</span><span class="o">*</span><span class="mi">8</span>
+ <span class="n">size</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span>
+ <span class="n">read</span> <span class="o">=</span> <span class="mi">0</span>
+ <span class="n">blocknum</span> <span class="o">=</span> <span class="mi">0</span>
+ <span class="k">if</span> <span class="s2">&quot;content-length&quot;</span> <span class="ow">in</span> <span class="n">headers</span><span class="p">:</span>
+ <span class="n">size</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">headers</span><span class="p">[</span><span class="s2">&quot;Content-Length&quot;</span><span class="p">])</span>
+ <span class="k">if</span> <span class="n">reporthook</span><span class="p">:</span>
+ <span class="n">reporthook</span><span class="p">(</span><span class="n">blocknum</span><span class="p">,</span> <span class="n">bs</span><span class="p">,</span> <span class="n">size</span><span class="p">)</span>
+ <span class="k">while</span> <span class="mi">1</span><span class="p">:</span>
+ <span class="n">block</span> <span class="o">=</span> <span class="n">fp</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="n">bs</span><span class="p">)</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">block</span><span class="p">:</span>
+ <span class="k">break</span>
+ <span class="n">read</span> <span class="o">+=</span> <span class="nb">len</span><span class="p">(</span><span class="n">block</span><span class="p">)</span>
+ <span class="n">tfp</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">block</span><span class="p">)</span>
+ <span class="n">blocknum</span> <span class="o">+=</span> <span class="mi">1</span>
+ <span class="k">if</span> <span class="n">reporthook</span><span class="p">:</span>
+ <span class="n">reporthook</span><span class="p">(</span><span class="n">blocknum</span><span class="p">,</span> <span class="n">bs</span><span class="p">,</span> <span class="n">size</span><span class="p">)</span>
+ <span class="k">finally</span><span class="p">:</span>
+ <span class="n">tfp</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
+ <span class="k">finally</span><span class="p">:</span>
+ <span class="n">fp</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
+
+ <span class="c1"># raise exception if actual size does not match content-length header</span>
+ <span class="k">if</span> <span class="n">size</span> <span class="o">&gt;=</span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">read</span> <span class="o">&lt;</span> <span class="n">size</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="n">ContentTooShortError</span><span class="p">(</span>
+ <span class="s2">&quot;retrieval incomplete: got only </span><span class="si">%i</span><span class="s2"> out of </span><span class="si">%i</span><span class="s2"> bytes&quot;</span>
+ <span class="o">%</span> <span class="p">(</span><span class="n">read</span><span class="p">,</span> <span class="n">size</span><span class="p">),</span> <span class="n">result</span><span class="p">)</span>
+
+ <span class="k">return</span> <span class="n">result</span>
+
+ <span class="c1"># Each method named open_&lt;type&gt; knows how to open that type of URL</span>
+
+ <span class="k">def</span> <span class="nf">_open_generic_http</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">connection_factory</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Make an HTTP connection using connection_class.</span>
+
+<span class="sd"> This is an internal method that should be called from</span>
+<span class="sd"> open_http() or open_https().</span>
+
+<span class="sd"> Arguments:</span>
+<span class="sd"> - connection_factory should take a host name and return an</span>
+<span class="sd"> HTTPConnection instance.</span>
+<span class="sd"> - url is the url to retrieval or a host, relative-path pair.</span>
+<span class="sd"> - data is payload for a POST request or None.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+
+ <span class="n">user_passwd</span> <span class="o">=</span> <span class="kc">None</span>
+ <span class="n">proxy_passwd</span><span class="o">=</span> <span class="kc">None</span>
+ <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
+ <span class="n">host</span><span class="p">,</span> <span class="n">selector</span> <span class="o">=</span> <span class="n">splithost</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">host</span><span class="p">:</span>
+ <span class="n">user_passwd</span><span class="p">,</span> <span class="n">host</span> <span class="o">=</span> <span class="n">splituser</span><span class="p">(</span><span class="n">host</span><span class="p">)</span>
+ <span class="n">host</span> <span class="o">=</span> <span class="n">unquote</span><span class="p">(</span><span class="n">host</span><span class="p">)</span>
+ <span class="n">realhost</span> <span class="o">=</span> <span class="n">host</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">host</span><span class="p">,</span> <span class="n">selector</span> <span class="o">=</span> <span class="n">url</span>
+ <span class="c1"># check whether the proxy contains authorization information</span>
+ <span class="n">proxy_passwd</span><span class="p">,</span> <span class="n">host</span> <span class="o">=</span> <span class="n">splituser</span><span class="p">(</span><span class="n">host</span><span class="p">)</span>
+ <span class="c1"># now we proceed with the url we want to obtain</span>
+ <span class="n">urltype</span><span class="p">,</span> <span class="n">rest</span> <span class="o">=</span> <span class="n">splittype</span><span class="p">(</span><span class="n">selector</span><span class="p">)</span>
+ <span class="n">url</span> <span class="o">=</span> <span class="n">rest</span>
+ <span class="n">user_passwd</span> <span class="o">=</span> <span class="kc">None</span>
+ <span class="k">if</span> <span class="n">urltype</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="o">!=</span> <span class="s1">&#39;http&#39;</span><span class="p">:</span>
+ <span class="n">realhost</span> <span class="o">=</span> <span class="kc">None</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">realhost</span><span class="p">,</span> <span class="n">rest</span> <span class="o">=</span> <span class="n">splithost</span><span class="p">(</span><span class="n">rest</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">realhost</span><span class="p">:</span>
+ <span class="n">user_passwd</span><span class="p">,</span> <span class="n">realhost</span> <span class="o">=</span> <span class="n">splituser</span><span class="p">(</span><span class="n">realhost</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">user_passwd</span><span class="p">:</span>
+ <span class="n">selector</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="si">%s</span><span class="s2">://</span><span class="si">%s%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">urltype</span><span class="p">,</span> <span class="n">realhost</span><span class="p">,</span> <span class="n">rest</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">proxy_bypass</span><span class="p">(</span><span class="n">realhost</span><span class="p">):</span>
+ <span class="n">host</span> <span class="o">=</span> <span class="n">realhost</span>
+
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">host</span><span class="p">:</span> <span class="k">raise</span> <span class="ne">OSError</span><span class="p">(</span><span class="s1">&#39;http error&#39;</span><span class="p">,</span> <span class="s1">&#39;no host given&#39;</span><span class="p">)</span>
+
+ <span class="k">if</span> <span class="n">proxy_passwd</span><span class="p">:</span>
+ <span class="n">proxy_passwd</span> <span class="o">=</span> <span class="n">unquote</span><span class="p">(</span><span class="n">proxy_passwd</span><span class="p">)</span>
+ <span class="n">proxy_auth</span> <span class="o">=</span> <span class="n">base64</span><span class="o">.</span><span class="n">b64encode</span><span class="p">(</span><span class="n">proxy_passwd</span><span class="o">.</span><span class="n">encode</span><span class="p">())</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s1">&#39;ascii&#39;</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">proxy_auth</span> <span class="o">=</span> <span class="kc">None</span>
+
+ <span class="k">if</span> <span class="n">user_passwd</span><span class="p">:</span>
+ <span class="n">user_passwd</span> <span class="o">=</span> <span class="n">unquote</span><span class="p">(</span><span class="n">user_passwd</span><span class="p">)</span>
+ <span class="n">auth</span> <span class="o">=</span> <span class="n">base64</span><span class="o">.</span><span class="n">b64encode</span><span class="p">(</span><span class="n">user_passwd</span><span class="o">.</span><span class="n">encode</span><span class="p">())</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s1">&#39;ascii&#39;</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">auth</span> <span class="o">=</span> <span class="kc">None</span>
+ <span class="n">http_conn</span> <span class="o">=</span> <span class="n">connection_factory</span><span class="p">(</span><span class="n">host</span><span class="p">)</span>
+ <span class="n">headers</span> <span class="o">=</span> <span class="p">{}</span>
+ <span class="k">if</span> <span class="n">proxy_auth</span><span class="p">:</span>
+ <span class="n">headers</span><span class="p">[</span><span class="s2">&quot;Proxy-Authorization&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;Basic </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">proxy_auth</span>
+ <span class="k">if</span> <span class="n">auth</span><span class="p">:</span>
+ <span class="n">headers</span><span class="p">[</span><span class="s2">&quot;Authorization&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;Basic </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">auth</span>
+ <span class="k">if</span> <span class="n">realhost</span><span class="p">:</span>
+ <span class="n">headers</span><span class="p">[</span><span class="s2">&quot;Host&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">realhost</span>
+
+ <span class="c1"># Add Connection:close as we don&#39;t support persistent connections yet.</span>
+ <span class="c1"># This helps in closing the socket and avoiding ResourceWarning</span>
+
+ <span class="n">headers</span><span class="p">[</span><span class="s2">&quot;Connection&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;close&quot;</span>
+
+ <span class="k">for</span> <span class="n">header</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">addheaders</span><span class="p">:</span>
+ <span class="n">headers</span><span class="p">[</span><span class="n">header</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span>
+
+ <span class="k">if</span> <span class="n">data</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">headers</span><span class="p">[</span><span class="s2">&quot;Content-Type&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;application/x-www-form-urlencoded&quot;</span>
+ <span class="n">http_conn</span><span class="o">.</span><span class="n">request</span><span class="p">(</span><span class="s2">&quot;POST&quot;</span><span class="p">,</span> <span class="n">selector</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">headers</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">http_conn</span><span class="o">.</span><span class="n">request</span><span class="p">(</span><span class="s2">&quot;GET&quot;</span><span class="p">,</span> <span class="n">selector</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">)</span>
+
+ <span class="k">try</span><span class="p">:</span>
+ <span class="n">response</span> <span class="o">=</span> <span class="n">http_conn</span><span class="o">.</span><span class="n">getresponse</span><span class="p">()</span>
+ <span class="k">except</span> <span class="n">http</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">BadStatusLine</span><span class="p">:</span>
+ <span class="c1"># something went wrong with the HTTP status line</span>
+ <span class="k">raise</span> <span class="n">URLError</span><span class="p">(</span><span class="s2">&quot;http protocol error: bad status line&quot;</span><span class="p">)</span>
+
+ <span class="c1"># According to RFC 2616, &quot;2xx&quot; code indicates that the client&#39;s</span>
+ <span class="c1"># request was successfully received, understood, and accepted.</span>
+ <span class="k">if</span> <span class="mi">200</span> <span class="o">&lt;=</span> <span class="n">response</span><span class="o">.</span><span class="n">status</span> <span class="o">&lt;</span> <span class="mi">300</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">addinfourl</span><span class="p">(</span><span class="n">response</span><span class="p">,</span> <span class="n">response</span><span class="o">.</span><span class="n">msg</span><span class="p">,</span> <span class="s2">&quot;http:&quot;</span> <span class="o">+</span> <span class="n">url</span><span class="p">,</span>
+ <span class="n">response</span><span class="o">.</span><span class="n">status</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">http_error</span><span class="p">(</span>
+ <span class="n">url</span><span class="p">,</span> <span class="n">response</span><span class="o">.</span><span class="n">fp</span><span class="p">,</span>
+ <span class="n">response</span><span class="o">.</span><span class="n">status</span><span class="p">,</span> <span class="n">response</span><span class="o">.</span><span class="n">reason</span><span class="p">,</span> <span class="n">response</span><span class="o">.</span><span class="n">msg</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">open_http</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Use HTTP protocol.&quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_open_generic_http</span><span class="p">(</span><span class="n">http</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">HTTPConnection</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">http_error</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">fp</span><span class="p">,</span> <span class="n">errcode</span><span class="p">,</span> <span class="n">errmsg</span><span class="p">,</span> <span class="n">headers</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Handle http errors.</span>
+
+<span class="sd"> Derived class can override this, or provide specific handlers</span>
+<span class="sd"> named http_error_DDD where DDD is the 3-digit error code.&quot;&quot;&quot;</span>
+ <span class="c1"># First check if there&#39;s a specific handler for this error</span>
+ <span class="n">name</span> <span class="o">=</span> <span class="s1">&#39;http_error_</span><span class="si">%d</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">errcode</span>
+ <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
+ <span class="n">method</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">data</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">result</span> <span class="o">=</span> <span class="n">method</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">fp</span><span class="p">,</span> <span class="n">errcode</span><span class="p">,</span> <span class="n">errmsg</span><span class="p">,</span> <span class="n">headers</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">result</span> <span class="o">=</span> <span class="n">method</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">fp</span><span class="p">,</span> <span class="n">errcode</span><span class="p">,</span> <span class="n">errmsg</span><span class="p">,</span> <span class="n">headers</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">result</span><span class="p">:</span> <span class="k">return</span> <span class="n">result</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">http_error_default</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">fp</span><span class="p">,</span> <span class="n">errcode</span><span class="p">,</span> <span class="n">errmsg</span><span class="p">,</span> <span class="n">headers</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">http_error_default</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">fp</span><span class="p">,</span> <span class="n">errcode</span><span class="p">,</span> <span class="n">errmsg</span><span class="p">,</span> <span class="n">headers</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Default error handler: close the connection and raise OSError.&quot;&quot;&quot;</span>
+ <span class="n">fp</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
+ <span class="k">raise</span> <span class="n">HTTPError</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">errcode</span><span class="p">,</span> <span class="n">errmsg</span><span class="p">,</span> <span class="n">headers</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
+
+ <span class="k">if</span> <span class="n">_have_ssl</span><span class="p">:</span>
+ <span class="k">def</span> <span class="nf">_https_connection</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">host</span><span class="p">):</span>
+ <span class="k">return</span> <span class="n">http</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">HTTPSConnection</span><span class="p">(</span><span class="n">host</span><span class="p">,</span>
+ <span class="n">key_file</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">key_file</span><span class="p">,</span>
+ <span class="n">cert_file</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">cert_file</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">open_https</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Use HTTPS protocol.&quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_open_generic_http</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_https_connection</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">open_file</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">url</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Use local file or FTP depending on form of URL.&quot;&quot;&quot;</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
+ <span class="k">raise</span> <span class="n">URLError</span><span class="p">(</span><span class="s1">&#39;file error: proxy support for file protocol currently not implemented&#39;</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">url</span><span class="p">[:</span><span class="mi">2</span><span class="p">]</span> <span class="o">==</span> <span class="s1">&#39;//&#39;</span> <span class="ow">and</span> <span class="n">url</span><span class="p">[</span><span class="mi">2</span><span class="p">:</span><span class="mi">3</span><span class="p">]</span> <span class="o">!=</span> <span class="s1">&#39;/&#39;</span> <span class="ow">and</span> <span class="n">url</span><span class="p">[</span><span class="mi">2</span><span class="p">:</span><span class="mi">12</span><span class="p">]</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="o">!=</span> <span class="s1">&#39;localhost/&#39;</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;file:// scheme is supported only on localhost&quot;</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">open_local_file</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">open_local_file</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">url</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Use local file.&quot;&quot;&quot;</span>
+ <span class="kn">import</span> <span class="nn">email.utils</span>
+ <span class="kn">import</span> <span class="nn">mimetypes</span>
+ <span class="n">host</span><span class="p">,</span> <span class="n">file</span> <span class="o">=</span> <span class="n">splithost</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
+ <span class="n">localname</span> <span class="o">=</span> <span class="n">url2pathname</span><span class="p">(</span><span class="n">file</span><span class="p">)</span>
+ <span class="k">try</span><span class="p">:</span>
+ <span class="n">stats</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">stat</span><span class="p">(</span><span class="n">localname</span><span class="p">)</span>
+ <span class="k">except</span> <span class="ne">OSError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="n">URLError</span><span class="p">(</span><span class="n">e</span><span class="o">.</span><span class="n">strerror</span><span class="p">,</span> <span class="n">e</span><span class="o">.</span><span class="n">filename</span><span class="p">)</span>
+ <span class="n">size</span> <span class="o">=</span> <span class="n">stats</span><span class="o">.</span><span class="n">st_size</span>
+ <span class="n">modified</span> <span class="o">=</span> <span class="n">email</span><span class="o">.</span><span class="n">utils</span><span class="o">.</span><span class="n">formatdate</span><span class="p">(</span><span class="n">stats</span><span class="o">.</span><span class="n">st_mtime</span><span class="p">,</span> <span class="n">usegmt</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
+ <span class="n">mtype</span> <span class="o">=</span> <span class="n">mimetypes</span><span class="o">.</span><span class="n">guess_type</span><span class="p">(</span><span class="n">url</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
+ <span class="n">headers</span> <span class="o">=</span> <span class="n">email</span><span class="o">.</span><span class="n">message_from_string</span><span class="p">(</span>
+ <span class="s1">&#39;Content-Type: </span><span class="si">%s</span><span class="se">\n</span><span class="s1">Content-Length: </span><span class="si">%d</span><span class="se">\n</span><span class="s1">Last-modified: </span><span class="si">%s</span><span class="se">\n</span><span class="s1">&#39;</span> <span class="o">%</span>
+ <span class="p">(</span><span class="n">mtype</span> <span class="ow">or</span> <span class="s1">&#39;text/plain&#39;</span><span class="p">,</span> <span class="n">size</span><span class="p">,</span> <span class="n">modified</span><span class="p">))</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">host</span><span class="p">:</span>
+ <span class="n">urlfile</span> <span class="o">=</span> <span class="n">file</span>
+ <span class="k">if</span> <span class="n">file</span><span class="p">[:</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="s1">&#39;/&#39;</span><span class="p">:</span>
+ <span class="n">urlfile</span> <span class="o">=</span> <span class="s1">&#39;file://&#39;</span> <span class="o">+</span> <span class="n">file</span>
+ <span class="k">return</span> <span class="n">addinfourl</span><span class="p">(</span><span class="nb">open</span><span class="p">(</span><span class="n">localname</span><span class="p">,</span> <span class="s1">&#39;rb&#39;</span><span class="p">),</span> <span class="n">headers</span><span class="p">,</span> <span class="n">urlfile</span><span class="p">)</span>
+ <span class="n">host</span><span class="p">,</span> <span class="n">port</span> <span class="o">=</span> <span class="n">splitport</span><span class="p">(</span><span class="n">host</span><span class="p">)</span>
+ <span class="k">if</span> <span class="p">(</span><span class="ow">not</span> <span class="n">port</span>
+ <span class="ow">and</span> <span class="n">socket</span><span class="o">.</span><span class="n">gethostbyname</span><span class="p">(</span><span class="n">host</span><span class="p">)</span> <span class="ow">in</span> <span class="p">((</span><span class="n">localhost</span><span class="p">(),)</span> <span class="o">+</span> <span class="n">thishost</span><span class="p">())):</span>
+ <span class="n">urlfile</span> <span class="o">=</span> <span class="n">file</span>
+ <span class="k">if</span> <span class="n">file</span><span class="p">[:</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="s1">&#39;/&#39;</span><span class="p">:</span>
+ <span class="n">urlfile</span> <span class="o">=</span> <span class="s1">&#39;file://&#39;</span> <span class="o">+</span> <span class="n">file</span>
+ <span class="k">elif</span> <span class="n">file</span><span class="p">[:</span><span class="mi">2</span><span class="p">]</span> <span class="o">==</span> <span class="s1">&#39;./&#39;</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;local file url may start with / or file:. Unknown url of type: </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">url</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">addinfourl</span><span class="p">(</span><span class="nb">open</span><span class="p">(</span><span class="n">localname</span><span class="p">,</span> <span class="s1">&#39;rb&#39;</span><span class="p">),</span> <span class="n">headers</span><span class="p">,</span> <span class="n">urlfile</span><span class="p">)</span>
+ <span class="k">raise</span> <span class="n">URLError</span><span class="p">(</span><span class="s1">&#39;local file error: not on local host&#39;</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">open_ftp</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">url</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Use FTP protocol.&quot;&quot;&quot;</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
+ <span class="k">raise</span> <span class="n">URLError</span><span class="p">(</span><span class="s1">&#39;ftp error: proxy support for ftp protocol currently not implemented&#39;</span><span class="p">)</span>
+ <span class="kn">import</span> <span class="nn">mimetypes</span>
+ <span class="n">host</span><span class="p">,</span> <span class="n">path</span> <span class="o">=</span> <span class="n">splithost</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">host</span><span class="p">:</span> <span class="k">raise</span> <span class="n">URLError</span><span class="p">(</span><span class="s1">&#39;ftp error: no host given&#39;</span><span class="p">)</span>
+ <span class="n">host</span><span class="p">,</span> <span class="n">port</span> <span class="o">=</span> <span class="n">splitport</span><span class="p">(</span><span class="n">host</span><span class="p">)</span>
+ <span class="n">user</span><span class="p">,</span> <span class="n">host</span> <span class="o">=</span> <span class="n">splituser</span><span class="p">(</span><span class="n">host</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">user</span><span class="p">:</span> <span class="n">user</span><span class="p">,</span> <span class="n">passwd</span> <span class="o">=</span> <span class="n">splitpasswd</span><span class="p">(</span><span class="n">user</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span> <span class="n">passwd</span> <span class="o">=</span> <span class="kc">None</span>
+ <span class="n">host</span> <span class="o">=</span> <span class="n">unquote</span><span class="p">(</span><span class="n">host</span><span class="p">)</span>
+ <span class="n">user</span> <span class="o">=</span> <span class="n">unquote</span><span class="p">(</span><span class="n">user</span> <span class="ow">or</span> <span class="s1">&#39;&#39;</span><span class="p">)</span>
+ <span class="n">passwd</span> <span class="o">=</span> <span class="n">unquote</span><span class="p">(</span><span class="n">passwd</span> <span class="ow">or</span> <span class="s1">&#39;&#39;</span><span class="p">)</span>
+ <span class="n">host</span> <span class="o">=</span> <span class="n">socket</span><span class="o">.</span><span class="n">gethostbyname</span><span class="p">(</span><span class="n">host</span><span class="p">)</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">port</span><span class="p">:</span>
+ <span class="kn">import</span> <span class="nn">ftplib</span>
+ <span class="n">port</span> <span class="o">=</span> <span class="n">ftplib</span><span class="o">.</span><span class="n">FTP_PORT</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">port</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">port</span><span class="p">)</span>
+ <span class="n">path</span><span class="p">,</span> <span class="n">attrs</span> <span class="o">=</span> <span class="n">splitattr</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
+ <span class="n">path</span> <span class="o">=</span> <span class="n">unquote</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
+ <span class="n">dirs</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;/&#39;</span><span class="p">)</span>
+ <span class="n">dirs</span><span class="p">,</span> <span class="n">file</span> <span class="o">=</span> <span class="n">dirs</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span> <span class="n">dirs</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
+ <span class="k">if</span> <span class="n">dirs</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">dirs</span><span class="p">[</span><span class="mi">0</span><span class="p">]:</span> <span class="n">dirs</span> <span class="o">=</span> <span class="n">dirs</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span>
+ <span class="k">if</span> <span class="n">dirs</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">dirs</span><span class="p">[</span><span class="mi">0</span><span class="p">]:</span> <span class="n">dirs</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;/&#39;</span>
+ <span class="n">key</span> <span class="o">=</span> <span class="n">user</span><span class="p">,</span> <span class="n">host</span><span class="p">,</span> <span class="n">port</span><span class="p">,</span> <span class="s1">&#39;/&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">dirs</span><span class="p">)</span>
+ <span class="c1"># XXX thread unsafe!</span>
+ <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ftpcache</span><span class="p">)</span> <span class="o">&gt;</span> <span class="n">MAXFTPCACHE</span><span class="p">:</span>
+ <span class="c1"># Prune the cache, rather arbitrarily</span>
+ <span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="nb">list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ftpcache</span><span class="p">):</span>
+ <span class="k">if</span> <span class="n">k</span> <span class="o">!=</span> <span class="n">key</span><span class="p">:</span>
+ <span class="n">v</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">ftpcache</span><span class="p">[</span><span class="n">k</span><span class="p">]</span>
+ <span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">ftpcache</span><span class="p">[</span><span class="n">k</span><span class="p">]</span>
+ <span class="n">v</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
+ <span class="k">try</span><span class="p">:</span>
+ <span class="k">if</span> <span class="n">key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">ftpcache</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">ftpcache</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> \
+ <span class="n">ftpwrapper</span><span class="p">(</span><span class="n">user</span><span class="p">,</span> <span class="n">passwd</span><span class="p">,</span> <span class="n">host</span><span class="p">,</span> <span class="n">port</span><span class="p">,</span> <span class="n">dirs</span><span class="p">)</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">file</span><span class="p">:</span> <span class="nb">type</span> <span class="o">=</span> <span class="s1">&#39;D&#39;</span>
+ <span class="k">else</span><span class="p">:</span> <span class="nb">type</span> <span class="o">=</span> <span class="s1">&#39;I&#39;</span>
+ <span class="k">for</span> <span class="n">attr</span> <span class="ow">in</span> <span class="n">attrs</span><span class="p">:</span>
+ <span class="n">attr</span><span class="p">,</span> <span class="n">value</span> <span class="o">=</span> <span class="n">splitvalue</span><span class="p">(</span><span class="n">attr</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">attr</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="o">==</span> <span class="s1">&#39;type&#39;</span> <span class="ow">and</span> \
+ <span class="n">value</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">&#39;a&#39;</span><span class="p">,</span> <span class="s1">&#39;A&#39;</span><span class="p">,</span> <span class="s1">&#39;i&#39;</span><span class="p">,</span> <span class="s1">&#39;I&#39;</span><span class="p">,</span> <span class="s1">&#39;d&#39;</span><span class="p">,</span> <span class="s1">&#39;D&#39;</span><span class="p">):</span>
+ <span class="nb">type</span> <span class="o">=</span> <span class="n">value</span><span class="o">.</span><span class="n">upper</span><span class="p">()</span>
+ <span class="p">(</span><span class="n">fp</span><span class="p">,</span> <span class="n">retrlen</span><span class="p">)</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">ftpcache</span><span class="p">[</span><span class="n">key</span><span class="p">]</span><span class="o">.</span><span class="n">retrfile</span><span class="p">(</span><span class="n">file</span><span class="p">,</span> <span class="nb">type</span><span class="p">)</span>
+ <span class="n">mtype</span> <span class="o">=</span> <span class="n">mimetypes</span><span class="o">.</span><span class="n">guess_type</span><span class="p">(</span><span class="s2">&quot;ftp:&quot;</span> <span class="o">+</span> <span class="n">url</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
+ <span class="n">headers</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
+ <span class="k">if</span> <span class="n">mtype</span><span class="p">:</span>
+ <span class="n">headers</span> <span class="o">+=</span> <span class="s2">&quot;Content-Type: </span><span class="si">%s</span><span class="se">\n</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">mtype</span>
+ <span class="k">if</span> <span class="n">retrlen</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">retrlen</span> <span class="o">&gt;=</span> <span class="mi">0</span><span class="p">:</span>
+ <span class="n">headers</span> <span class="o">+=</span> <span class="s2">&quot;Content-Length: </span><span class="si">%d</span><span class="se">\n</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">retrlen</span>
+ <span class="n">headers</span> <span class="o">=</span> <span class="n">email</span><span class="o">.</span><span class="n">message_from_string</span><span class="p">(</span><span class="n">headers</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">addinfourl</span><span class="p">(</span><span class="n">fp</span><span class="p">,</span> <span class="n">headers</span><span class="p">,</span> <span class="s2">&quot;ftp:&quot;</span> <span class="o">+</span> <span class="n">url</span><span class="p">)</span>
+ <span class="k">except</span> <span class="n">ftperrors</span><span class="p">()</span> <span class="k">as</span> <span class="n">exp</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="n">URLError</span><span class="p">(</span><span class="s1">&#39;ftp error </span><span class="si">%r</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">exp</span><span class="p">)</span><span class="o">.</span><span class="n">with_traceback</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">()[</span><span class="mi">2</span><span class="p">])</span>
+
+ <span class="k">def</span> <span class="nf">open_data</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Use &quot;data&quot; URL.&quot;&quot;&quot;</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
+ <span class="k">raise</span> <span class="n">URLError</span><span class="p">(</span><span class="s1">&#39;data error: proxy support for data protocol currently not implemented&#39;</span><span class="p">)</span>
+ <span class="c1"># ignore POSTed data</span>
+ <span class="c1">#</span>
+ <span class="c1"># syntax of data URLs:</span>
+ <span class="c1"># dataurl := &quot;data:&quot; [ mediatype ] [ &quot;;base64&quot; ] &quot;,&quot; data</span>
+ <span class="c1"># mediatype := [ type &quot;/&quot; subtype ] *( &quot;;&quot; parameter )</span>
+ <span class="c1"># data := *urlchar</span>
+ <span class="c1"># parameter := attribute &quot;=&quot; value</span>
+ <span class="k">try</span><span class="p">:</span>
+ <span class="p">[</span><span class="nb">type</span><span class="p">,</span> <span class="n">data</span><span class="p">]</span> <span class="o">=</span> <span class="n">url</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;,&#39;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
+ <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="ne">OSError</span><span class="p">(</span><span class="s1">&#39;data error&#39;</span><span class="p">,</span> <span class="s1">&#39;bad data URL&#39;</span><span class="p">)</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="nb">type</span><span class="p">:</span>
+ <span class="nb">type</span> <span class="o">=</span> <span class="s1">&#39;text/plain;charset=US-ASCII&#39;</span>
+ <span class="n">semi</span> <span class="o">=</span> <span class="nb">type</span><span class="o">.</span><span class="n">rfind</span><span class="p">(</span><span class="s1">&#39;;&#39;</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">semi</span> <span class="o">&gt;=</span> <span class="mi">0</span> <span class="ow">and</span> <span class="s1">&#39;=&#39;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="nb">type</span><span class="p">[</span><span class="n">semi</span><span class="p">:]:</span>
+ <span class="n">encoding</span> <span class="o">=</span> <span class="nb">type</span><span class="p">[</span><span class="n">semi</span><span class="o">+</span><span class="mi">1</span><span class="p">:]</span>
+ <span class="nb">type</span> <span class="o">=</span> <span class="nb">type</span><span class="p">[:</span><span class="n">semi</span><span class="p">]</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">encoding</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
+ <span class="n">msg</span> <span class="o">=</span> <span class="p">[]</span>
+ <span class="n">msg</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">&#39;Date: </span><span class="si">%s</span><span class="s1">&#39;</span><span class="o">%</span><span class="n">time</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="s1">&#39;</span><span class="si">%a</span><span class="s1">, </span><span class="si">%d</span><span class="s1"> %b %Y %H:%M:%S GMT&#39;</span><span class="p">,</span>
+ <span class="n">time</span><span class="o">.</span><span class="n">gmtime</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())))</span>
+ <span class="n">msg</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">&#39;Content-type: </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="nb">type</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">encoding</span> <span class="o">==</span> <span class="s1">&#39;base64&#39;</span><span class="p">:</span>
+ <span class="c1"># XXX is this encoding/decoding ok?</span>
+ <span class="n">data</span> <span class="o">=</span> <span class="n">base64</span><span class="o">.</span><span class="n">decodebytes</span><span class="p">(</span><span class="n">data</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;ascii&#39;</span><span class="p">))</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s1">&#39;latin-1&#39;</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">data</span> <span class="o">=</span> <span class="n">unquote</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
+ <span class="n">msg</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">&#39;Content-Length: </span><span class="si">%d</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="nb">len</span><span class="p">(</span><span class="n">data</span><span class="p">))</span>
+ <span class="n">msg</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">&#39;&#39;</span><span class="p">)</span>
+ <span class="n">msg</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
+ <span class="n">msg</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
+ <span class="n">headers</span> <span class="o">=</span> <span class="n">email</span><span class="o">.</span><span class="n">message_from_string</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
+ <span class="n">f</span> <span class="o">=</span> <span class="n">io</span><span class="o">.</span><span class="n">StringIO</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
+ <span class="c1">#f.fileno = None # needed for addinfourl</span>
+ <span class="k">return</span> <span class="n">addinfourl</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">headers</span><span class="p">,</span> <span class="n">url</span><span class="p">)</span>
+
+
+<span class="k">class</span> <span class="nc">FancyURLopener</span><span class="p">(</span><span class="n">URLopener</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Derived class with handlers for errors we can handle (perhaps).&quot;&quot;&quot;</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
+ <span class="n">URLopener</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">auth_cache</span> <span class="o">=</span> <span class="p">{}</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">tries</span> <span class="o">=</span> <span class="mi">0</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">maxtries</span> <span class="o">=</span> <span class="mi">10</span>
+
+ <span class="k">def</span> <span class="nf">http_error_default</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">fp</span><span class="p">,</span> <span class="n">errcode</span><span class="p">,</span> <span class="n">errmsg</span><span class="p">,</span> <span class="n">headers</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Default error handling -- don&#39;t raise an exception.&quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">addinfourl</span><span class="p">(</span><span class="n">fp</span><span class="p">,</span> <span class="n">headers</span><span class="p">,</span> <span class="s2">&quot;http:&quot;</span> <span class="o">+</span> <span class="n">url</span><span class="p">,</span> <span class="n">errcode</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">http_error_302</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">fp</span><span class="p">,</span> <span class="n">errcode</span><span class="p">,</span> <span class="n">errmsg</span><span class="p">,</span> <span class="n">headers</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Error 302 -- relocated (temporarily).&quot;&quot;&quot;</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">tries</span> <span class="o">+=</span> <span class="mi">1</span>
+ <span class="k">try</span><span class="p">:</span>
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">maxtries</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">tries</span> <span class="o">&gt;=</span> <span class="bp">self</span><span class="o">.</span><span class="n">maxtries</span><span class="p">:</span>
+ <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s2">&quot;http_error_500&quot;</span><span class="p">):</span>
+ <span class="n">meth</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">http_error_500</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">meth</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">http_error_default</span>
+ <span class="k">return</span> <span class="n">meth</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">fp</span><span class="p">,</span> <span class="mi">500</span><span class="p">,</span>
+ <span class="s2">&quot;Internal Server Error: Redirect Recursion&quot;</span><span class="p">,</span>
+ <span class="n">headers</span><span class="p">)</span>
+ <span class="n">result</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">redirect_internal</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">fp</span><span class="p">,</span> <span class="n">errcode</span><span class="p">,</span> <span class="n">errmsg</span><span class="p">,</span>
+ <span class="n">headers</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">result</span>
+ <span class="k">finally</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">tries</span> <span class="o">=</span> <span class="mi">0</span>
+
+ <span class="k">def</span> <span class="nf">redirect_internal</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">fp</span><span class="p">,</span> <span class="n">errcode</span><span class="p">,</span> <span class="n">errmsg</span><span class="p">,</span> <span class="n">headers</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
+ <span class="k">if</span> <span class="s1">&#39;location&#39;</span> <span class="ow">in</span> <span class="n">headers</span><span class="p">:</span>
+ <span class="n">newurl</span> <span class="o">=</span> <span class="n">headers</span><span class="p">[</span><span class="s1">&#39;location&#39;</span><span class="p">]</span>
+ <span class="k">elif</span> <span class="s1">&#39;uri&#39;</span> <span class="ow">in</span> <span class="n">headers</span><span class="p">:</span>
+ <span class="n">newurl</span> <span class="o">=</span> <span class="n">headers</span><span class="p">[</span><span class="s1">&#39;uri&#39;</span><span class="p">]</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">return</span>
+ <span class="n">fp</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
+
+ <span class="c1"># In case the server sent a relative URL, join with original:</span>
+ <span class="n">newurl</span> <span class="o">=</span> <span class="n">urljoin</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">type</span> <span class="o">+</span> <span class="s2">&quot;:&quot;</span> <span class="o">+</span> <span class="n">url</span><span class="p">,</span> <span class="n">newurl</span><span class="p">)</span>
+
+ <span class="n">urlparts</span> <span class="o">=</span> <span class="n">urlparse</span><span class="p">(</span><span class="n">newurl</span><span class="p">)</span>
+
+ <span class="c1"># For security reasons, we don&#39;t allow redirection to anything other</span>
+ <span class="c1"># than http, https and ftp.</span>
+
+ <span class="c1"># We are using newer HTTPError with older redirect_internal method</span>
+ <span class="c1"># This older method will get deprecated in 3.3</span>
+
+ <span class="k">if</span> <span class="n">urlparts</span><span class="o">.</span><span class="n">scheme</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">&#39;http&#39;</span><span class="p">,</span> <span class="s1">&#39;https&#39;</span><span class="p">,</span> <span class="s1">&#39;ftp&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">):</span>
+ <span class="k">raise</span> <span class="n">HTTPError</span><span class="p">(</span><span class="n">newurl</span><span class="p">,</span> <span class="n">errcode</span><span class="p">,</span>
+ <span class="n">errmsg</span> <span class="o">+</span>
+ <span class="s2">&quot; Redirection to url &#39;</span><span class="si">%s</span><span class="s2">&#39; is not allowed.&quot;</span> <span class="o">%</span> <span class="n">newurl</span><span class="p">,</span>
+ <span class="n">headers</span><span class="p">,</span> <span class="n">fp</span><span class="p">)</span>
+
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">newurl</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">http_error_301</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">fp</span><span class="p">,</span> <span class="n">errcode</span><span class="p">,</span> <span class="n">errmsg</span><span class="p">,</span> <span class="n">headers</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Error 301 -- also relocated (permanently).&quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">http_error_302</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">fp</span><span class="p">,</span> <span class="n">errcode</span><span class="p">,</span> <span class="n">errmsg</span><span class="p">,</span> <span class="n">headers</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">http_error_303</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">fp</span><span class="p">,</span> <span class="n">errcode</span><span class="p">,</span> <span class="n">errmsg</span><span class="p">,</span> <span class="n">headers</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Error 303 -- also relocated (essentially identical to 302).&quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">http_error_302</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">fp</span><span class="p">,</span> <span class="n">errcode</span><span class="p">,</span> <span class="n">errmsg</span><span class="p">,</span> <span class="n">headers</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">http_error_307</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">fp</span><span class="p">,</span> <span class="n">errcode</span><span class="p">,</span> <span class="n">errmsg</span><span class="p">,</span> <span class="n">headers</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Error 307 -- relocated, but turn POST into error.&quot;&quot;&quot;</span>
+ <span class="k">if</span> <span class="n">data</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">http_error_302</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">fp</span><span class="p">,</span> <span class="n">errcode</span><span class="p">,</span> <span class="n">errmsg</span><span class="p">,</span> <span class="n">headers</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">http_error_default</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">fp</span><span class="p">,</span> <span class="n">errcode</span><span class="p">,</span> <span class="n">errmsg</span><span class="p">,</span> <span class="n">headers</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">http_error_401</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">fp</span><span class="p">,</span> <span class="n">errcode</span><span class="p">,</span> <span class="n">errmsg</span><span class="p">,</span> <span class="n">headers</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
+ <span class="n">retry</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Error 401 -- authentication required.</span>
+<span class="sd"> This function supports Basic authentication only.&quot;&quot;&quot;</span>
+ <span class="k">if</span> <span class="s1">&#39;www-authenticate&#39;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">headers</span><span class="p">:</span>
+ <span class="n">URLopener</span><span class="o">.</span><span class="n">http_error_default</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">fp</span><span class="p">,</span>
+ <span class="n">errcode</span><span class="p">,</span> <span class="n">errmsg</span><span class="p">,</span> <span class="n">headers</span><span class="p">)</span>
+ <span class="n">stuff</span> <span class="o">=</span> <span class="n">headers</span><span class="p">[</span><span class="s1">&#39;www-authenticate&#39;</span><span class="p">]</span>
+ <span class="n">match</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="s1">&#39;[ </span><span class="se">\t</span><span class="s1">]*([^ </span><span class="se">\t</span><span class="s1">]+)[ </span><span class="se">\t</span><span class="s1">]+realm=&quot;([^&quot;]*)&quot;&#39;</span><span class="p">,</span> <span class="n">stuff</span><span class="p">)</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">match</span><span class="p">:</span>
+ <span class="n">URLopener</span><span class="o">.</span><span class="n">http_error_default</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">fp</span><span class="p">,</span>
+ <span class="n">errcode</span><span class="p">,</span> <span class="n">errmsg</span><span class="p">,</span> <span class="n">headers</span><span class="p">)</span>
+ <span class="n">scheme</span><span class="p">,</span> <span class="n">realm</span> <span class="o">=</span> <span class="n">match</span><span class="o">.</span><span class="n">groups</span><span class="p">()</span>
+ <span class="k">if</span> <span class="n">scheme</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="o">!=</span> <span class="s1">&#39;basic&#39;</span><span class="p">:</span>
+ <span class="n">URLopener</span><span class="o">.</span><span class="n">http_error_default</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">fp</span><span class="p">,</span>
+ <span class="n">errcode</span><span class="p">,</span> <span class="n">errmsg</span><span class="p">,</span> <span class="n">headers</span><span class="p">)</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">retry</span><span class="p">:</span>
+ <span class="n">URLopener</span><span class="o">.</span><span class="n">http_error_default</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">fp</span><span class="p">,</span> <span class="n">errcode</span><span class="p">,</span> <span class="n">errmsg</span><span class="p">,</span>
+ <span class="n">headers</span><span class="p">)</span>
+ <span class="n">name</span> <span class="o">=</span> <span class="s1">&#39;retry_&#39;</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">type</span> <span class="o">+</span> <span class="s1">&#39;_basic_auth&#39;</span>
+ <span class="k">if</span> <span class="n">data</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">return</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">name</span><span class="p">)(</span><span class="n">url</span><span class="p">,</span> <span class="n">realm</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">return</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">name</span><span class="p">)(</span><span class="n">url</span><span class="p">,</span> <span class="n">realm</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">http_error_407</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">fp</span><span class="p">,</span> <span class="n">errcode</span><span class="p">,</span> <span class="n">errmsg</span><span class="p">,</span> <span class="n">headers</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
+ <span class="n">retry</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Error 407 -- proxy authentication required.</span>
+<span class="sd"> This function supports Basic authentication only.&quot;&quot;&quot;</span>
+ <span class="k">if</span> <span class="s1">&#39;proxy-authenticate&#39;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">headers</span><span class="p">:</span>
+ <span class="n">URLopener</span><span class="o">.</span><span class="n">http_error_default</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">fp</span><span class="p">,</span>
+ <span class="n">errcode</span><span class="p">,</span> <span class="n">errmsg</span><span class="p">,</span> <span class="n">headers</span><span class="p">)</span>
+ <span class="n">stuff</span> <span class="o">=</span> <span class="n">headers</span><span class="p">[</span><span class="s1">&#39;proxy-authenticate&#39;</span><span class="p">]</span>
+ <span class="n">match</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="s1">&#39;[ </span><span class="se">\t</span><span class="s1">]*([^ </span><span class="se">\t</span><span class="s1">]+)[ </span><span class="se">\t</span><span class="s1">]+realm=&quot;([^&quot;]*)&quot;&#39;</span><span class="p">,</span> <span class="n">stuff</span><span class="p">)</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">match</span><span class="p">:</span>
+ <span class="n">URLopener</span><span class="o">.</span><span class="n">http_error_default</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">fp</span><span class="p">,</span>
+ <span class="n">errcode</span><span class="p">,</span> <span class="n">errmsg</span><span class="p">,</span> <span class="n">headers</span><span class="p">)</span>
+ <span class="n">scheme</span><span class="p">,</span> <span class="n">realm</span> <span class="o">=</span> <span class="n">match</span><span class="o">.</span><span class="n">groups</span><span class="p">()</span>
+ <span class="k">if</span> <span class="n">scheme</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="o">!=</span> <span class="s1">&#39;basic&#39;</span><span class="p">:</span>
+ <span class="n">URLopener</span><span class="o">.</span><span class="n">http_error_default</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">fp</span><span class="p">,</span>
+ <span class="n">errcode</span><span class="p">,</span> <span class="n">errmsg</span><span class="p">,</span> <span class="n">headers</span><span class="p">)</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">retry</span><span class="p">:</span>
+ <span class="n">URLopener</span><span class="o">.</span><span class="n">http_error_default</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">fp</span><span class="p">,</span> <span class="n">errcode</span><span class="p">,</span> <span class="n">errmsg</span><span class="p">,</span>
+ <span class="n">headers</span><span class="p">)</span>
+ <span class="n">name</span> <span class="o">=</span> <span class="s1">&#39;retry_proxy_&#39;</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">type</span> <span class="o">+</span> <span class="s1">&#39;_basic_auth&#39;</span>
+ <span class="k">if</span> <span class="n">data</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">return</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">name</span><span class="p">)(</span><span class="n">url</span><span class="p">,</span> <span class="n">realm</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">return</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">name</span><span class="p">)(</span><span class="n">url</span><span class="p">,</span> <span class="n">realm</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">retry_proxy_http_basic_auth</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">realm</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="n">host</span><span class="p">,</span> <span class="n">selector</span> <span class="o">=</span> <span class="n">splithost</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
+ <span class="n">newurl</span> <span class="o">=</span> <span class="s1">&#39;http://&#39;</span> <span class="o">+</span> <span class="n">host</span> <span class="o">+</span> <span class="n">selector</span>
+ <span class="n">proxy</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">proxies</span><span class="p">[</span><span class="s1">&#39;http&#39;</span><span class="p">]</span>
+ <span class="n">urltype</span><span class="p">,</span> <span class="n">proxyhost</span> <span class="o">=</span> <span class="n">splittype</span><span class="p">(</span><span class="n">proxy</span><span class="p">)</span>
+ <span class="n">proxyhost</span><span class="p">,</span> <span class="n">proxyselector</span> <span class="o">=</span> <span class="n">splithost</span><span class="p">(</span><span class="n">proxyhost</span><span class="p">)</span>
+ <span class="n">i</span> <span class="o">=</span> <span class="n">proxyhost</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s1">&#39;@&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span>
+ <span class="n">proxyhost</span> <span class="o">=</span> <span class="n">proxyhost</span><span class="p">[</span><span class="n">i</span><span class="p">:]</span>
+ <span class="n">user</span><span class="p">,</span> <span class="n">passwd</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_user_passwd</span><span class="p">(</span><span class="n">proxyhost</span><span class="p">,</span> <span class="n">realm</span><span class="p">,</span> <span class="n">i</span><span class="p">)</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="p">(</span><span class="n">user</span> <span class="ow">or</span> <span class="n">passwd</span><span class="p">):</span> <span class="k">return</span> <span class="kc">None</span>
+ <span class="n">proxyhost</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="si">%s</span><span class="s2">:</span><span class="si">%s</span><span class="s2">@</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">quote</span><span class="p">(</span><span class="n">user</span><span class="p">,</span> <span class="n">safe</span><span class="o">=</span><span class="s1">&#39;&#39;</span><span class="p">),</span>
+ <span class="n">quote</span><span class="p">(</span><span class="n">passwd</span><span class="p">,</span> <span class="n">safe</span><span class="o">=</span><span class="s1">&#39;&#39;</span><span class="p">),</span> <span class="n">proxyhost</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">proxies</span><span class="p">[</span><span class="s1">&#39;http&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;http://&#39;</span> <span class="o">+</span> <span class="n">proxyhost</span> <span class="o">+</span> <span class="n">proxyselector</span>
+ <span class="k">if</span> <span class="n">data</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">newurl</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">newurl</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">retry_proxy_https_basic_auth</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">realm</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="n">host</span><span class="p">,</span> <span class="n">selector</span> <span class="o">=</span> <span class="n">splithost</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
+ <span class="n">newurl</span> <span class="o">=</span> <span class="s1">&#39;https://&#39;</span> <span class="o">+</span> <span class="n">host</span> <span class="o">+</span> <span class="n">selector</span>
+ <span class="n">proxy</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">proxies</span><span class="p">[</span><span class="s1">&#39;https&#39;</span><span class="p">]</span>
+ <span class="n">urltype</span><span class="p">,</span> <span class="n">proxyhost</span> <span class="o">=</span> <span class="n">splittype</span><span class="p">(</span><span class="n">proxy</span><span class="p">)</span>
+ <span class="n">proxyhost</span><span class="p">,</span> <span class="n">proxyselector</span> <span class="o">=</span> <span class="n">splithost</span><span class="p">(</span><span class="n">proxyhost</span><span class="p">)</span>
+ <span class="n">i</span> <span class="o">=</span> <span class="n">proxyhost</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s1">&#39;@&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span>
+ <span class="n">proxyhost</span> <span class="o">=</span> <span class="n">proxyhost</span><span class="p">[</span><span class="n">i</span><span class="p">:]</span>
+ <span class="n">user</span><span class="p">,</span> <span class="n">passwd</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_user_passwd</span><span class="p">(</span><span class="n">proxyhost</span><span class="p">,</span> <span class="n">realm</span><span class="p">,</span> <span class="n">i</span><span class="p">)</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="p">(</span><span class="n">user</span> <span class="ow">or</span> <span class="n">passwd</span><span class="p">):</span> <span class="k">return</span> <span class="kc">None</span>
+ <span class="n">proxyhost</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="si">%s</span><span class="s2">:</span><span class="si">%s</span><span class="s2">@</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">quote</span><span class="p">(</span><span class="n">user</span><span class="p">,</span> <span class="n">safe</span><span class="o">=</span><span class="s1">&#39;&#39;</span><span class="p">),</span>
+ <span class="n">quote</span><span class="p">(</span><span class="n">passwd</span><span class="p">,</span> <span class="n">safe</span><span class="o">=</span><span class="s1">&#39;&#39;</span><span class="p">),</span> <span class="n">proxyhost</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">proxies</span><span class="p">[</span><span class="s1">&#39;https&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;https://&#39;</span> <span class="o">+</span> <span class="n">proxyhost</span> <span class="o">+</span> <span class="n">proxyselector</span>
+ <span class="k">if</span> <span class="n">data</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">newurl</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">newurl</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">retry_http_basic_auth</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">realm</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="n">host</span><span class="p">,</span> <span class="n">selector</span> <span class="o">=</span> <span class="n">splithost</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
+ <span class="n">i</span> <span class="o">=</span> <span class="n">host</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s1">&#39;@&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span>
+ <span class="n">host</span> <span class="o">=</span> <span class="n">host</span><span class="p">[</span><span class="n">i</span><span class="p">:]</span>
+ <span class="n">user</span><span class="p">,</span> <span class="n">passwd</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_user_passwd</span><span class="p">(</span><span class="n">host</span><span class="p">,</span> <span class="n">realm</span><span class="p">,</span> <span class="n">i</span><span class="p">)</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="p">(</span><span class="n">user</span> <span class="ow">or</span> <span class="n">passwd</span><span class="p">):</span> <span class="k">return</span> <span class="kc">None</span>
+ <span class="n">host</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="si">%s</span><span class="s2">:</span><span class="si">%s</span><span class="s2">@</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">quote</span><span class="p">(</span><span class="n">user</span><span class="p">,</span> <span class="n">safe</span><span class="o">=</span><span class="s1">&#39;&#39;</span><span class="p">),</span>
+ <span class="n">quote</span><span class="p">(</span><span class="n">passwd</span><span class="p">,</span> <span class="n">safe</span><span class="o">=</span><span class="s1">&#39;&#39;</span><span class="p">),</span> <span class="n">host</span><span class="p">)</span>
+ <span class="n">newurl</span> <span class="o">=</span> <span class="s1">&#39;http://&#39;</span> <span class="o">+</span> <span class="n">host</span> <span class="o">+</span> <span class="n">selector</span>
+ <span class="k">if</span> <span class="n">data</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">newurl</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">newurl</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">retry_https_basic_auth</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">realm</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="n">host</span><span class="p">,</span> <span class="n">selector</span> <span class="o">=</span> <span class="n">splithost</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
+ <span class="n">i</span> <span class="o">=</span> <span class="n">host</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s1">&#39;@&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span>
+ <span class="n">host</span> <span class="o">=</span> <span class="n">host</span><span class="p">[</span><span class="n">i</span><span class="p">:]</span>
+ <span class="n">user</span><span class="p">,</span> <span class="n">passwd</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_user_passwd</span><span class="p">(</span><span class="n">host</span><span class="p">,</span> <span class="n">realm</span><span class="p">,</span> <span class="n">i</span><span class="p">)</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="p">(</span><span class="n">user</span> <span class="ow">or</span> <span class="n">passwd</span><span class="p">):</span> <span class="k">return</span> <span class="kc">None</span>
+ <span class="n">host</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="si">%s</span><span class="s2">:</span><span class="si">%s</span><span class="s2">@</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">quote</span><span class="p">(</span><span class="n">user</span><span class="p">,</span> <span class="n">safe</span><span class="o">=</span><span class="s1">&#39;&#39;</span><span class="p">),</span>
+ <span class="n">quote</span><span class="p">(</span><span class="n">passwd</span><span class="p">,</span> <span class="n">safe</span><span class="o">=</span><span class="s1">&#39;&#39;</span><span class="p">),</span> <span class="n">host</span><span class="p">)</span>
+ <span class="n">newurl</span> <span class="o">=</span> <span class="s1">&#39;https://&#39;</span> <span class="o">+</span> <span class="n">host</span> <span class="o">+</span> <span class="n">selector</span>
+ <span class="k">if</span> <span class="n">data</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">newurl</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">newurl</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">get_user_passwd</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">host</span><span class="p">,</span> <span class="n">realm</span><span class="p">,</span> <span class="n">clear_cache</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
+ <span class="n">key</span> <span class="o">=</span> <span class="n">realm</span> <span class="o">+</span> <span class="s1">&#39;@&#39;</span> <span class="o">+</span> <span class="n">host</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
+ <span class="k">if</span> <span class="n">key</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">auth_cache</span><span class="p">:</span>
+ <span class="k">if</span> <span class="n">clear_cache</span><span class="p">:</span>
+ <span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">auth_cache</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">auth_cache</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
+ <span class="n">user</span><span class="p">,</span> <span class="n">passwd</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">prompt_user_passwd</span><span class="p">(</span><span class="n">host</span><span class="p">,</span> <span class="n">realm</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">user</span> <span class="ow">or</span> <span class="n">passwd</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">auth_cache</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="n">user</span><span class="p">,</span> <span class="n">passwd</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">user</span><span class="p">,</span> <span class="n">passwd</span>
+
+ <span class="k">def</span> <span class="nf">prompt_user_passwd</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">host</span><span class="p">,</span> <span class="n">realm</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Override this in a GUI environment!&quot;&quot;&quot;</span>
+ <span class="kn">import</span> <span class="nn">getpass</span>
+ <span class="k">try</span><span class="p">:</span>
+ <span class="n">user</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s2">&quot;Enter username for </span><span class="si">%s</span><span class="s2"> at </span><span class="si">%s</span><span class="s2">: &quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">realm</span><span class="p">,</span> <span class="n">host</span><span class="p">))</span>
+ <span class="n">passwd</span> <span class="o">=</span> <span class="n">getpass</span><span class="o">.</span><span class="n">getpass</span><span class="p">(</span><span class="s2">&quot;Enter password for </span><span class="si">%s</span><span class="s2"> in </span><span class="si">%s</span><span class="s2"> at </span><span class="si">%s</span><span class="s2">: &quot;</span> <span class="o">%</span>
+ <span class="p">(</span><span class="n">user</span><span class="p">,</span> <span class="n">realm</span><span class="p">,</span> <span class="n">host</span><span class="p">))</span>
+ <span class="k">return</span> <span class="n">user</span><span class="p">,</span> <span class="n">passwd</span>
+ <span class="k">except</span> <span class="ne">KeyboardInterrupt</span><span class="p">:</span>
+ <span class="nb">print</span><span class="p">()</span>
+ <span class="k">return</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span>
+
+
+<span class="c1"># Utility functions</span>
+
+<span class="n">_localhost</span> <span class="o">=</span> <span class="kc">None</span>
+<span class="k">def</span> <span class="nf">localhost</span><span class="p">():</span>
+ <span class="sd">&quot;&quot;&quot;Return the IP address of the magic hostname &#39;localhost&#39;.&quot;&quot;&quot;</span>
+ <span class="k">global</span> <span class="n">_localhost</span>
+ <span class="k">if</span> <span class="n">_localhost</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">_localhost</span> <span class="o">=</span> <span class="n">socket</span><span class="o">.</span><span class="n">gethostbyname</span><span class="p">(</span><span class="s1">&#39;localhost&#39;</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">_localhost</span>
+
+<span class="n">_thishost</span> <span class="o">=</span> <span class="kc">None</span>
+<span class="k">def</span> <span class="nf">thishost</span><span class="p">():</span>
+ <span class="sd">&quot;&quot;&quot;Return the IP addresses of the current host.&quot;&quot;&quot;</span>
+ <span class="k">global</span> <span class="n">_thishost</span>
+ <span class="k">if</span> <span class="n">_thishost</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">try</span><span class="p">:</span>
+ <span class="n">_thishost</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">gethostbyname_ex</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">gethostname</span><span class="p">())[</span><span class="mi">2</span><span class="p">])</span>
+ <span class="k">except</span> <span class="n">socket</span><span class="o">.</span><span class="n">gaierror</span><span class="p">:</span>
+ <span class="n">_thishost</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">gethostbyname_ex</span><span class="p">(</span><span class="s1">&#39;localhost&#39;</span><span class="p">)[</span><span class="mi">2</span><span class="p">])</span>
+ <span class="k">return</span> <span class="n">_thishost</span>
+
+<span class="n">_ftperrors</span> <span class="o">=</span> <span class="kc">None</span>
+<span class="k">def</span> <span class="nf">ftperrors</span><span class="p">():</span>
+ <span class="sd">&quot;&quot;&quot;Return the set of errors raised by the FTP class.&quot;&quot;&quot;</span>
+ <span class="k">global</span> <span class="n">_ftperrors</span>
+ <span class="k">if</span> <span class="n">_ftperrors</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="kn">import</span> <span class="nn">ftplib</span>
+ <span class="n">_ftperrors</span> <span class="o">=</span> <span class="n">ftplib</span><span class="o">.</span><span class="n">all_errors</span>
+ <span class="k">return</span> <span class="n">_ftperrors</span>
+
+<span class="n">_noheaders</span> <span class="o">=</span> <span class="kc">None</span>
+<span class="k">def</span> <span class="nf">noheaders</span><span class="p">():</span>
+ <span class="sd">&quot;&quot;&quot;Return an empty email Message object.&quot;&quot;&quot;</span>
+ <span class="k">global</span> <span class="n">_noheaders</span>
+ <span class="k">if</span> <span class="n">_noheaders</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">_noheaders</span> <span class="o">=</span> <span class="n">email</span><span class="o">.</span><span class="n">message_from_string</span><span class="p">(</span><span class="s2">&quot;&quot;</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">_noheaders</span>
+
+
+<span class="c1"># Utility classes</span>
+
+<span class="k">class</span> <span class="nc">ftpwrapper</span><span class="p">:</span>
+ <span class="sd">&quot;&quot;&quot;Class used by open_ftp() for cache of open FTP connections.&quot;&quot;&quot;</span>
+
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="n">passwd</span><span class="p">,</span> <span class="n">host</span><span class="p">,</span> <span class="n">port</span><span class="p">,</span> <span class="n">dirs</span><span class="p">,</span> <span class="n">timeout</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
+ <span class="n">persistent</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">user</span> <span class="o">=</span> <span class="n">user</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">passwd</span> <span class="o">=</span> <span class="n">passwd</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">host</span> <span class="o">=</span> <span class="n">host</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">port</span> <span class="o">=</span> <span class="n">port</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">dirs</span> <span class="o">=</span> <span class="n">dirs</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">timeout</span> <span class="o">=</span> <span class="n">timeout</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">refcount</span> <span class="o">=</span> <span class="mi">0</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">keepalive</span> <span class="o">=</span> <span class="n">persistent</span>
+ <span class="k">try</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">init</span><span class="p">()</span>
+ <span class="k">except</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
+ <span class="k">raise</span>
+
+ <span class="k">def</span> <span class="nf">init</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="kn">import</span> <span class="nn">ftplib</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">busy</span> <span class="o">=</span> <span class="mi">0</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">ftp</span> <span class="o">=</span> <span class="n">ftplib</span><span class="o">.</span><span class="n">FTP</span><span class="p">()</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">ftp</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">host</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">port</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">timeout</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">ftp</span><span class="o">.</span><span class="n">login</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">user</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">passwd</span><span class="p">)</span>
+ <span class="n">_target</span> <span class="o">=</span> <span class="s1">&#39;/&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dirs</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">ftp</span><span class="o">.</span><span class="n">cwd</span><span class="p">(</span><span class="n">_target</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">retrfile</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">file</span><span class="p">,</span> <span class="nb">type</span><span class="p">):</span>
+ <span class="kn">import</span> <span class="nn">ftplib</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">endtransfer</span><span class="p">()</span>
+ <span class="k">if</span> <span class="nb">type</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">&#39;d&#39;</span><span class="p">,</span> <span class="s1">&#39;D&#39;</span><span class="p">):</span> <span class="n">cmd</span> <span class="o">=</span> <span class="s1">&#39;TYPE A&#39;</span><span class="p">;</span> <span class="n">isdir</span> <span class="o">=</span> <span class="mi">1</span>
+ <span class="k">else</span><span class="p">:</span> <span class="n">cmd</span> <span class="o">=</span> <span class="s1">&#39;TYPE &#39;</span> <span class="o">+</span> <span class="nb">type</span><span class="p">;</span> <span class="n">isdir</span> <span class="o">=</span> <span class="mi">0</span>
+ <span class="k">try</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">ftp</span><span class="o">.</span><span class="n">voidcmd</span><span class="p">(</span><span class="n">cmd</span><span class="p">)</span>
+ <span class="k">except</span> <span class="n">ftplib</span><span class="o">.</span><span class="n">all_errors</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">init</span><span class="p">()</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">ftp</span><span class="o">.</span><span class="n">voidcmd</span><span class="p">(</span><span class="n">cmd</span><span class="p">)</span>
+ <span class="n">conn</span> <span class="o">=</span> <span class="kc">None</span>
+ <span class="k">if</span> <span class="n">file</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">isdir</span><span class="p">:</span>
+ <span class="c1"># Try to retrieve as a file</span>
+ <span class="k">try</span><span class="p">:</span>
+ <span class="n">cmd</span> <span class="o">=</span> <span class="s1">&#39;RETR &#39;</span> <span class="o">+</span> <span class="n">file</span>
+ <span class="n">conn</span><span class="p">,</span> <span class="n">retrlen</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">ftp</span><span class="o">.</span><span class="n">ntransfercmd</span><span class="p">(</span><span class="n">cmd</span><span class="p">)</span>
+ <span class="k">except</span> <span class="n">ftplib</span><span class="o">.</span><span class="n">error_perm</span> <span class="k">as</span> <span class="n">reason</span><span class="p">:</span>
+ <span class="k">if</span> <span class="nb">str</span><span class="p">(</span><span class="n">reason</span><span class="p">)[:</span><span class="mi">3</span><span class="p">]</span> <span class="o">!=</span> <span class="s1">&#39;550&#39;</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="n">URLError</span><span class="p">(</span><span class="s1">&#39;ftp error: </span><span class="si">%r</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">reason</span><span class="p">)</span><span class="o">.</span><span class="n">with_traceback</span><span class="p">(</span>
+ <span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">()[</span><span class="mi">2</span><span class="p">])</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">conn</span><span class="p">:</span>
+ <span class="c1"># Set transfer mode to ASCII!</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">ftp</span><span class="o">.</span><span class="n">voidcmd</span><span class="p">(</span><span class="s1">&#39;TYPE A&#39;</span><span class="p">)</span>
+ <span class="c1"># Try a directory listing. Verify that directory exists.</span>
+ <span class="k">if</span> <span class="n">file</span><span class="p">:</span>
+ <span class="n">pwd</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">ftp</span><span class="o">.</span><span class="n">pwd</span><span class="p">()</span>
+ <span class="k">try</span><span class="p">:</span>
+ <span class="k">try</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">ftp</span><span class="o">.</span><span class="n">cwd</span><span class="p">(</span><span class="n">file</span><span class="p">)</span>
+ <span class="k">except</span> <span class="n">ftplib</span><span class="o">.</span><span class="n">error_perm</span> <span class="k">as</span> <span class="n">reason</span><span class="p">:</span>
+ <span class="k">raise</span> <span class="n">URLError</span><span class="p">(</span><span class="s1">&#39;ftp error: </span><span class="si">%r</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">reason</span><span class="p">)</span> <span class="kn">from</span> <span class="nn">reason</span>
+ <span class="k">finally</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">ftp</span><span class="o">.</span><span class="n">cwd</span><span class="p">(</span><span class="n">pwd</span><span class="p">)</span>
+ <span class="n">cmd</span> <span class="o">=</span> <span class="s1">&#39;LIST &#39;</span> <span class="o">+</span> <span class="n">file</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">cmd</span> <span class="o">=</span> <span class="s1">&#39;LIST&#39;</span>
+ <span class="n">conn</span><span class="p">,</span> <span class="n">retrlen</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">ftp</span><span class="o">.</span><span class="n">ntransfercmd</span><span class="p">(</span><span class="n">cmd</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">busy</span> <span class="o">=</span> <span class="mi">1</span>
+
+ <span class="n">ftpobj</span> <span class="o">=</span> <span class="n">addclosehook</span><span class="p">(</span><span class="n">conn</span><span class="o">.</span><span class="n">makefile</span><span class="p">(</span><span class="s1">&#39;rb&#39;</span><span class="p">),</span> <span class="bp">self</span><span class="o">.</span><span class="n">file_close</span><span class="p">)</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">refcount</span> <span class="o">+=</span> <span class="mi">1</span>
+ <span class="n">conn</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
+ <span class="c1"># Pass back both a suitably decorated object and a retrieval length</span>
+ <span class="k">return</span> <span class="p">(</span><span class="n">ftpobj</span><span class="p">,</span> <span class="n">retrlen</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">endtransfer</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">busy</span> <span class="o">=</span> <span class="mi">0</span>
+
+ <span class="k">def</span> <span class="nf">close</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">keepalive</span> <span class="o">=</span> <span class="kc">False</span>
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">refcount</span> <span class="o">&lt;=</span> <span class="mi">0</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">real_close</span><span class="p">()</span>
+
+ <span class="k">def</span> <span class="nf">file_close</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">endtransfer</span><span class="p">()</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">refcount</span> <span class="o">-=</span> <span class="mi">1</span>
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">refcount</span> <span class="o">&lt;=</span> <span class="mi">0</span> <span class="ow">and</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">keepalive</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">real_close</span><span class="p">()</span>
+
+ <span class="k">def</span> <span class="nf">real_close</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">endtransfer</span><span class="p">()</span>
+ <span class="k">try</span><span class="p">:</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">ftp</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
+ <span class="k">except</span> <span class="n">ftperrors</span><span class="p">():</span>
+ <span class="k">pass</span>
+
+<span class="c1"># Proxy handling</span>
+<span class="k">def</span> <span class="nf">getproxies_environment</span><span class="p">():</span>
+ <span class="sd">&quot;&quot;&quot;Return a dictionary of scheme -&gt; proxy server URL mappings.</span>
+
+<span class="sd"> Scan the environment for variables named &lt;scheme&gt;_proxy;</span>
+<span class="sd"> this seems to be the standard convention. If you need a</span>
+<span class="sd"> different way, you can pass a proxies dictionary to the</span>
+<span class="sd"> [Fancy]URLopener constructor.</span>
+
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">proxies</span> <span class="o">=</span> <span class="p">{}</span>
+ <span class="c1"># in order to prefer lowercase variables, process environment in</span>
+ <span class="c1"># two passes: first matches any, second pass matches lowercase only</span>
+ <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
+ <span class="n">name</span> <span class="o">=</span> <span class="n">name</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
+ <span class="k">if</span> <span class="n">value</span> <span class="ow">and</span> <span class="n">name</span><span class="p">[</span><span class="o">-</span><span class="mi">6</span><span class="p">:]</span> <span class="o">==</span> <span class="s1">&#39;_proxy&#39;</span><span class="p">:</span>
+ <span class="n">proxies</span><span class="p">[</span><span class="n">name</span><span class="p">[:</span><span class="o">-</span><span class="mi">6</span><span class="p">]]</span> <span class="o">=</span> <span class="n">value</span>
+ <span class="c1"># CVE-2016-1000110 - If we are running as CGI script, forget HTTP_PROXY</span>
+ <span class="c1"># (non-all-lowercase) as it may be set from the web server by a &quot;Proxy:&quot;</span>
+ <span class="c1"># header from the client</span>
+ <span class="c1"># If &quot;proxy&quot; is lowercase, it will still be used thanks to the next block</span>
+ <span class="k">if</span> <span class="s1">&#39;REQUEST_METHOD&#39;</span> <span class="ow">in</span> <span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">:</span>
+ <span class="n">proxies</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s1">&#39;http&#39;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
+ <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
+ <span class="k">if</span> <span class="n">name</span><span class="p">[</span><span class="o">-</span><span class="mi">6</span><span class="p">:]</span> <span class="o">==</span> <span class="s1">&#39;_proxy&#39;</span><span class="p">:</span>
+ <span class="n">name</span> <span class="o">=</span> <span class="n">name</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
+ <span class="k">if</span> <span class="n">value</span><span class="p">:</span>
+ <span class="n">proxies</span><span class="p">[</span><span class="n">name</span><span class="p">[:</span><span class="o">-</span><span class="mi">6</span><span class="p">]]</span> <span class="o">=</span> <span class="n">value</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">proxies</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="n">name</span><span class="p">[:</span><span class="o">-</span><span class="mi">6</span><span class="p">],</span> <span class="kc">None</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">proxies</span>
+
+<span class="k">def</span> <span class="nf">proxy_bypass_environment</span><span class="p">(</span><span class="n">host</span><span class="p">,</span> <span class="n">proxies</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Test if proxies should not be used for a particular host.</span>
+
+<span class="sd"> Checks the proxy dict for the value of no_proxy, which should</span>
+<span class="sd"> be a list of comma separated DNS suffixes, or &#39;*&#39; for all hosts.</span>
+
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">if</span> <span class="n">proxies</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">proxies</span> <span class="o">=</span> <span class="n">getproxies_environment</span><span class="p">()</span>
+ <span class="c1"># don&#39;t bypass, if no_proxy isn&#39;t specified</span>
+ <span class="k">try</span><span class="p">:</span>
+ <span class="n">no_proxy</span> <span class="o">=</span> <span class="n">proxies</span><span class="p">[</span><span class="s1">&#39;no&#39;</span><span class="p">]</span>
+ <span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
+ <span class="k">return</span> <span class="mi">0</span>
+ <span class="c1"># &#39;*&#39; is special case for always bypass</span>
+ <span class="k">if</span> <span class="n">no_proxy</span> <span class="o">==</span> <span class="s1">&#39;*&#39;</span><span class="p">:</span>
+ <span class="k">return</span> <span class="mi">1</span>
+ <span class="c1"># strip port off host</span>
+ <span class="n">hostonly</span><span class="p">,</span> <span class="n">port</span> <span class="o">=</span> <span class="n">splitport</span><span class="p">(</span><span class="n">host</span><span class="p">)</span>
+ <span class="c1"># check if the host ends with any of the DNS suffixes</span>
+ <span class="n">no_proxy_list</span> <span class="o">=</span> <span class="p">[</span><span class="n">proxy</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="k">for</span> <span class="n">proxy</span> <span class="ow">in</span> <span class="n">no_proxy</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;,&#39;</span><span class="p">)]</span>
+ <span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">no_proxy_list</span><span class="p">:</span>
+ <span class="k">if</span> <span class="n">name</span><span class="p">:</span>
+ <span class="n">name</span> <span class="o">=</span> <span class="n">name</span><span class="o">.</span><span class="n">lstrip</span><span class="p">(</span><span class="s1">&#39;.&#39;</span><span class="p">)</span> <span class="c1"># ignore leading dots</span>
+ <span class="n">name</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">escape</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
+ <span class="n">pattern</span> <span class="o">=</span> <span class="sa">r</span><span class="s1">&#39;(.+\.)?</span><span class="si">%s</span><span class="s1">$&#39;</span> <span class="o">%</span> <span class="n">name</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">re</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">pattern</span><span class="p">,</span> <span class="n">hostonly</span><span class="p">,</span> <span class="n">re</span><span class="o">.</span><span class="n">I</span><span class="p">)</span>
+ <span class="ow">or</span> <span class="n">re</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">pattern</span><span class="p">,</span> <span class="n">host</span><span class="p">,</span> <span class="n">re</span><span class="o">.</span><span class="n">I</span><span class="p">)):</span>
+ <span class="k">return</span> <span class="mi">1</span>
+ <span class="c1"># otherwise, don&#39;t bypass</span>
+ <span class="k">return</span> <span class="mi">0</span>
+
+
+<span class="c1"># This code tests an OSX specific data structure but is testable on all</span>
+<span class="c1"># platforms</span>
+<span class="k">def</span> <span class="nf">_proxy_bypass_macosx_sysconf</span><span class="p">(</span><span class="n">host</span><span class="p">,</span> <span class="n">proxy_settings</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd"> Return True iff this host shouldn&#39;t be accessed using a proxy</span>
+
+<span class="sd"> This function uses the MacOSX framework SystemConfiguration</span>
+<span class="sd"> to fetch the proxy information.</span>
+
+<span class="sd"> proxy_settings come from _scproxy._get_proxy_settings or get mocked ie:</span>
+<span class="sd"> { &#39;exclude_simple&#39;: bool,</span>
+<span class="sd"> &#39;exceptions&#39;: [&#39;foo.bar&#39;, &#39;*.bar.com&#39;, &#39;127.0.0.1&#39;, &#39;10.1&#39;, &#39;10.0/16&#39;]</span>
+<span class="sd"> }</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="kn">from</span> <span class="nn">fnmatch</span> <span class="k">import</span> <span class="n">fnmatch</span>
+
+ <span class="n">hostonly</span><span class="p">,</span> <span class="n">port</span> <span class="o">=</span> <span class="n">splitport</span><span class="p">(</span><span class="n">host</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">ip2num</span><span class="p">(</span><span class="n">ipAddr</span><span class="p">):</span>
+ <span class="n">parts</span> <span class="o">=</span> <span class="n">ipAddr</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;.&#39;</span><span class="p">)</span>
+ <span class="n">parts</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="nb">int</span><span class="p">,</span> <span class="n">parts</span><span class="p">))</span>
+ <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">parts</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">4</span><span class="p">:</span>
+ <span class="n">parts</span> <span class="o">=</span> <span class="p">(</span><span class="n">parts</span> <span class="o">+</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">])[:</span><span class="mi">4</span><span class="p">]</span>
+ <span class="k">return</span> <span class="p">(</span><span class="n">parts</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">&lt;&lt;</span> <span class="mi">24</span><span class="p">)</span> <span class="o">|</span> <span class="p">(</span><span class="n">parts</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">&lt;&lt;</span> <span class="mi">16</span><span class="p">)</span> <span class="o">|</span> <span class="p">(</span><span class="n">parts</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">&lt;&lt;</span> <span class="mi">8</span><span class="p">)</span> <span class="o">|</span> <span class="n">parts</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span>
+
+ <span class="c1"># Check for simple host names:</span>
+ <span class="k">if</span> <span class="s1">&#39;.&#39;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">host</span><span class="p">:</span>
+ <span class="k">if</span> <span class="n">proxy_settings</span><span class="p">[</span><span class="s1">&#39;exclude_simple&#39;</span><span class="p">]:</span>
+ <span class="k">return</span> <span class="kc">True</span>
+
+ <span class="n">hostIP</span> <span class="o">=</span> <span class="kc">None</span>
+
+ <span class="k">for</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">proxy_settings</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;exceptions&#39;</span><span class="p">,</span> <span class="p">()):</span>
+ <span class="c1"># Items in the list are strings like these: *.local, 169.254/16</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">value</span><span class="p">:</span> <span class="k">continue</span>
+
+ <span class="n">m</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="sa">r</span><span class="s2">&quot;(\d+(?:\.\d+)*)(/\d+)?&quot;</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">m</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">if</span> <span class="n">hostIP</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="k">try</span><span class="p">:</span>
+ <span class="n">hostIP</span> <span class="o">=</span> <span class="n">socket</span><span class="o">.</span><span class="n">gethostbyname</span><span class="p">(</span><span class="n">hostonly</span><span class="p">)</span>
+ <span class="n">hostIP</span> <span class="o">=</span> <span class="n">ip2num</span><span class="p">(</span><span class="n">hostIP</span><span class="p">)</span>
+ <span class="k">except</span> <span class="ne">OSError</span><span class="p">:</span>
+ <span class="k">continue</span>
+
+ <span class="n">base</span> <span class="o">=</span> <span class="n">ip2num</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="mi">1</span><span class="p">))</span>
+ <span class="n">mask</span> <span class="o">=</span> <span class="n">m</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">mask</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
+ <span class="n">mask</span> <span class="o">=</span> <span class="mi">8</span> <span class="o">*</span> <span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span><span class="o">.</span><span class="n">count</span><span class="p">(</span><span class="s1">&#39;.&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">mask</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">mask</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span>
+ <span class="n">mask</span> <span class="o">=</span> <span class="mi">32</span> <span class="o">-</span> <span class="n">mask</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">hostIP</span> <span class="o">&gt;&gt;</span> <span class="n">mask</span><span class="p">)</span> <span class="o">==</span> <span class="p">(</span><span class="n">base</span> <span class="o">&gt;&gt;</span> <span class="n">mask</span><span class="p">):</span>
+ <span class="k">return</span> <span class="kc">True</span>
+
+ <span class="k">elif</span> <span class="n">fnmatch</span><span class="p">(</span><span class="n">host</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
+ <span class="k">return</span> <span class="kc">True</span>
+
+ <span class="k">return</span> <span class="kc">False</span>
+
+
+<span class="k">if</span> <span class="n">sys</span><span class="o">.</span><span class="n">platform</span> <span class="o">==</span> <span class="s1">&#39;darwin&#39;</span><span class="p">:</span>
+ <span class="kn">from</span> <span class="nn">_scproxy</span> <span class="k">import</span> <span class="n">_get_proxy_settings</span><span class="p">,</span> <span class="n">_get_proxies</span>
+
+ <span class="k">def</span> <span class="nf">proxy_bypass_macosx_sysconf</span><span class="p">(</span><span class="n">host</span><span class="p">):</span>
+ <span class="n">proxy_settings</span> <span class="o">=</span> <span class="n">_get_proxy_settings</span><span class="p">()</span>
+ <span class="k">return</span> <span class="n">_proxy_bypass_macosx_sysconf</span><span class="p">(</span><span class="n">host</span><span class="p">,</span> <span class="n">proxy_settings</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">getproxies_macosx_sysconf</span><span class="p">():</span>
+ <span class="sd">&quot;&quot;&quot;Return a dictionary of scheme -&gt; proxy server URL mappings.</span>
+
+<span class="sd"> This function uses the MacOSX framework SystemConfiguration</span>
+<span class="sd"> to fetch the proxy information.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">_get_proxies</span><span class="p">()</span>
+
+
+
+ <span class="k">def</span> <span class="nf">proxy_bypass</span><span class="p">(</span><span class="n">host</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Return True, if host should be bypassed.</span>
+
+<span class="sd"> Checks proxy settings gathered from the environment, if specified,</span>
+<span class="sd"> or from the MacOSX framework SystemConfiguration.</span>
+
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">proxies</span> <span class="o">=</span> <span class="n">getproxies_environment</span><span class="p">()</span>
+ <span class="k">if</span> <span class="n">proxies</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">proxy_bypass_environment</span><span class="p">(</span><span class="n">host</span><span class="p">,</span> <span class="n">proxies</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">proxy_bypass_macosx_sysconf</span><span class="p">(</span><span class="n">host</span><span class="p">)</span>
+
+ <span class="k">def</span> <span class="nf">getproxies</span><span class="p">():</span>
+ <span class="k">return</span> <span class="n">getproxies_environment</span><span class="p">()</span> <span class="ow">or</span> <span class="n">getproxies_macosx_sysconf</span><span class="p">()</span>
+
+
+<span class="k">elif</span> <span class="n">os</span><span class="o">.</span><span class="n">name</span> <span class="o">==</span> <span class="s1">&#39;nt&#39;</span><span class="p">:</span>
+ <span class="k">def</span> <span class="nf">getproxies_registry</span><span class="p">():</span>
+ <span class="sd">&quot;&quot;&quot;Return a dictionary of scheme -&gt; proxy server URL mappings.</span>
+
+<span class="sd"> Win32 uses the registry to store proxies.</span>
+
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">proxies</span> <span class="o">=</span> <span class="p">{}</span>
+ <span class="k">try</span><span class="p">:</span>
+ <span class="kn">import</span> <span class="nn">winreg</span>
+ <span class="k">except</span> <span class="ne">ImportError</span><span class="p">:</span>
+ <span class="c1"># Std module, so should be around - but you never know!</span>
+ <span class="k">return</span> <span class="n">proxies</span>
+ <span class="k">try</span><span class="p">:</span>
+ <span class="n">internetSettings</span> <span class="o">=</span> <span class="n">winreg</span><span class="o">.</span><span class="n">OpenKey</span><span class="p">(</span><span class="n">winreg</span><span class="o">.</span><span class="n">HKEY_CURRENT_USER</span><span class="p">,</span>
+ <span class="sa">r</span><span class="s1">&#39;Software\Microsoft\Windows\CurrentVersion\Internet Settings&#39;</span><span class="p">)</span>
+ <span class="n">proxyEnable</span> <span class="o">=</span> <span class="n">winreg</span><span class="o">.</span><span class="n">QueryValueEx</span><span class="p">(</span><span class="n">internetSettings</span><span class="p">,</span>
+ <span class="s1">&#39;ProxyEnable&#39;</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
+ <span class="k">if</span> <span class="n">proxyEnable</span><span class="p">:</span>
+ <span class="c1"># Returned as Unicode but problems if not converted to ASCII</span>
+ <span class="n">proxyServer</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">winreg</span><span class="o">.</span><span class="n">QueryValueEx</span><span class="p">(</span><span class="n">internetSettings</span><span class="p">,</span>
+ <span class="s1">&#39;ProxyServer&#39;</span><span class="p">)[</span><span class="mi">0</span><span class="p">])</span>
+ <span class="k">if</span> <span class="s1">&#39;=&#39;</span> <span class="ow">in</span> <span class="n">proxyServer</span><span class="p">:</span>
+ <span class="c1"># Per-protocol settings</span>
+ <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">proxyServer</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;;&#39;</span><span class="p">):</span>
+ <span class="n">protocol</span><span class="p">,</span> <span class="n">address</span> <span class="o">=</span> <span class="n">p</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;=&#39;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
+ <span class="c1"># See if address has a type:// prefix</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">re</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="s1">&#39;^([^/:]+)://&#39;</span><span class="p">,</span> <span class="n">address</span><span class="p">):</span>
+ <span class="n">address</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="si">%s</span><span class="s1">://</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">protocol</span><span class="p">,</span> <span class="n">address</span><span class="p">)</span>
+ <span class="n">proxies</span><span class="p">[</span><span class="n">protocol</span><span class="p">]</span> <span class="o">=</span> <span class="n">address</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="c1"># Use one setting for all protocols</span>
+ <span class="k">if</span> <span class="n">proxyServer</span><span class="p">[:</span><span class="mi">5</span><span class="p">]</span> <span class="o">==</span> <span class="s1">&#39;http:&#39;</span><span class="p">:</span>
+ <span class="n">proxies</span><span class="p">[</span><span class="s1">&#39;http&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">proxyServer</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">proxies</span><span class="p">[</span><span class="s1">&#39;http&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;http://</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">proxyServer</span>
+ <span class="n">proxies</span><span class="p">[</span><span class="s1">&#39;https&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;https://</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">proxyServer</span>
+ <span class="n">proxies</span><span class="p">[</span><span class="s1">&#39;ftp&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;ftp://</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">proxyServer</span>
+ <span class="n">internetSettings</span><span class="o">.</span><span class="n">Close</span><span class="p">()</span>
+ <span class="k">except</span> <span class="p">(</span><span class="ne">OSError</span><span class="p">,</span> <span class="ne">ValueError</span><span class="p">,</span> <span class="ne">TypeError</span><span class="p">):</span>
+ <span class="c1"># Either registry key not found etc, or the value in an</span>
+ <span class="c1"># unexpected format.</span>
+ <span class="c1"># proxies already set up to be empty so nothing to do</span>
+ <span class="k">pass</span>
+ <span class="k">return</span> <span class="n">proxies</span>
+
+ <span class="k">def</span> <span class="nf">getproxies</span><span class="p">():</span>
+ <span class="sd">&quot;&quot;&quot;Return a dictionary of scheme -&gt; proxy server URL mappings.</span>
+
+<span class="sd"> Returns settings gathered from the environment, if specified,</span>
+<span class="sd"> or the registry.</span>
+
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">return</span> <span class="n">getproxies_environment</span><span class="p">()</span> <span class="ow">or</span> <span class="n">getproxies_registry</span><span class="p">()</span>
+
+ <span class="k">def</span> <span class="nf">proxy_bypass_registry</span><span class="p">(</span><span class="n">host</span><span class="p">):</span>
+ <span class="k">try</span><span class="p">:</span>
+ <span class="kn">import</span> <span class="nn">winreg</span>
+ <span class="k">except</span> <span class="ne">ImportError</span><span class="p">:</span>
+ <span class="c1"># Std modules, so should be around - but you never know!</span>
+ <span class="k">return</span> <span class="mi">0</span>
+ <span class="k">try</span><span class="p">:</span>
+ <span class="n">internetSettings</span> <span class="o">=</span> <span class="n">winreg</span><span class="o">.</span><span class="n">OpenKey</span><span class="p">(</span><span class="n">winreg</span><span class="o">.</span><span class="n">HKEY_CURRENT_USER</span><span class="p">,</span>
+ <span class="sa">r</span><span class="s1">&#39;Software\Microsoft\Windows\CurrentVersion\Internet Settings&#39;</span><span class="p">)</span>
+ <span class="n">proxyEnable</span> <span class="o">=</span> <span class="n">winreg</span><span class="o">.</span><span class="n">QueryValueEx</span><span class="p">(</span><span class="n">internetSettings</span><span class="p">,</span>
+ <span class="s1">&#39;ProxyEnable&#39;</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
+ <span class="n">proxyOverride</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">winreg</span><span class="o">.</span><span class="n">QueryValueEx</span><span class="p">(</span><span class="n">internetSettings</span><span class="p">,</span>
+ <span class="s1">&#39;ProxyOverride&#39;</span><span class="p">)[</span><span class="mi">0</span><span class="p">])</span>
+ <span class="c1"># ^^^^ Returned as Unicode but problems if not converted to ASCII</span>
+ <span class="k">except</span> <span class="ne">OSError</span><span class="p">:</span>
+ <span class="k">return</span> <span class="mi">0</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">proxyEnable</span> <span class="ow">or</span> <span class="ow">not</span> <span class="n">proxyOverride</span><span class="p">:</span>
+ <span class="k">return</span> <span class="mi">0</span>
+ <span class="c1"># try to make a host list from name and IP address.</span>
+ <span class="n">rawHost</span><span class="p">,</span> <span class="n">port</span> <span class="o">=</span> <span class="n">splitport</span><span class="p">(</span><span class="n">host</span><span class="p">)</span>
+ <span class="n">host</span> <span class="o">=</span> <span class="p">[</span><span class="n">rawHost</span><span class="p">]</span>
+ <span class="k">try</span><span class="p">:</span>
+ <span class="n">addr</span> <span class="o">=</span> <span class="n">socket</span><span class="o">.</span><span class="n">gethostbyname</span><span class="p">(</span><span class="n">rawHost</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">addr</span> <span class="o">!=</span> <span class="n">rawHost</span><span class="p">:</span>
+ <span class="n">host</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">addr</span><span class="p">)</span>
+ <span class="k">except</span> <span class="ne">OSError</span><span class="p">:</span>
+ <span class="k">pass</span>
+ <span class="k">try</span><span class="p">:</span>
+ <span class="n">fqdn</span> <span class="o">=</span> <span class="n">socket</span><span class="o">.</span><span class="n">getfqdn</span><span class="p">(</span><span class="n">rawHost</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">fqdn</span> <span class="o">!=</span> <span class="n">rawHost</span><span class="p">:</span>
+ <span class="n">host</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">fqdn</span><span class="p">)</span>
+ <span class="k">except</span> <span class="ne">OSError</span><span class="p">:</span>
+ <span class="k">pass</span>
+ <span class="c1"># make a check value list from the registry entry: replace the</span>
+ <span class="c1"># &#39;&lt;local&gt;&#39; string by the localhost entry and the corresponding</span>
+ <span class="c1"># canonical entry.</span>
+ <span class="n">proxyOverride</span> <span class="o">=</span> <span class="n">proxyOverride</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;;&#39;</span><span class="p">)</span>
+ <span class="c1"># now check if we match one of the registry values.</span>
+ <span class="k">for</span> <span class="n">test</span> <span class="ow">in</span> <span class="n">proxyOverride</span><span class="p">:</span>
+ <span class="k">if</span> <span class="n">test</span> <span class="o">==</span> <span class="s1">&#39;&lt;local&gt;&#39;</span><span class="p">:</span>
+ <span class="k">if</span> <span class="s1">&#39;.&#39;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">rawHost</span><span class="p">:</span>
+ <span class="k">return</span> <span class="mi">1</span>
+ <span class="n">test</span> <span class="o">=</span> <span class="n">test</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s2">&quot;.&quot;</span><span class="p">,</span> <span class="sa">r</span><span class="s2">&quot;\.&quot;</span><span class="p">)</span> <span class="c1"># mask dots</span>
+ <span class="n">test</span> <span class="o">=</span> <span class="n">test</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s2">&quot;*&quot;</span><span class="p">,</span> <span class="sa">r</span><span class="s2">&quot;.*&quot;</span><span class="p">)</span> <span class="c1"># change glob sequence</span>
+ <span class="n">test</span> <span class="o">=</span> <span class="n">test</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s2">&quot;?&quot;</span><span class="p">,</span> <span class="sa">r</span><span class="s2">&quot;.&quot;</span><span class="p">)</span> <span class="c1"># change glob char</span>
+ <span class="k">for</span> <span class="n">val</span> <span class="ow">in</span> <span class="n">host</span><span class="p">:</span>
+ <span class="k">if</span> <span class="n">re</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">test</span><span class="p">,</span> <span class="n">val</span><span class="p">,</span> <span class="n">re</span><span class="o">.</span><span class="n">I</span><span class="p">):</span>
+ <span class="k">return</span> <span class="mi">1</span>
+ <span class="k">return</span> <span class="mi">0</span>
+
+ <span class="k">def</span> <span class="nf">proxy_bypass</span><span class="p">(</span><span class="n">host</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Return True, if host should be bypassed.</span>
+
+<span class="sd"> Checks proxy settings gathered from the environment, if specified,</span>
+<span class="sd"> or the registry.</span>
+
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="n">proxies</span> <span class="o">=</span> <span class="n">getproxies_environment</span><span class="p">()</span>
+ <span class="k">if</span> <span class="n">proxies</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">proxy_bypass_environment</span><span class="p">(</span><span class="n">host</span><span class="p">,</span> <span class="n">proxies</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">proxy_bypass_registry</span><span class="p">(</span><span class="n">host</span><span class="p">)</span>
+
+<span class="k">else</span><span class="p">:</span>
+ <span class="c1"># By default use environment variables</span>
+ <span class="n">getproxies</span> <span class="o">=</span> <span class="n">getproxies_environment</span>
+ <span class="n">proxy_bypass</span> <span class="o">=</span> <span class="n">proxy_bypass_environment</span>
+</pre></div>
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="../../index.html">M2Crypto</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="../../M2Crypto.html">M2Crypto Package</a></li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="../../index.html">Documentation overview</a><ul>
+ <li><a href="../index.html">Module code</a><ul>
+ </ul></li>
+ </ul></li>
+</ul>
+</div>
+<div id="searchbox" style="display: none" role="search">
+ <h3>Quick search</h3>
+ <div class="searchformwrapper">
+ <form class="search" action="../../search.html" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ </div>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer">
+ &copy;2017, Matej Cepl <mcepl@cepl.eu>.
+
+ |
+ Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
+ &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
+
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/_sources/M2Crypto.SSL.rst.txt b/doc/html/_sources/M2Crypto.SSL.rst.txt
new file mode 100644
index 0000000..233c1eb
--- /dev/null
+++ b/doc/html/_sources/M2Crypto.SSL.rst.txt
@@ -0,0 +1,91 @@
+SSL Package
+===========
+
+:mod:`SSL` Package
+------------------
+
+.. automodule:: M2Crypto.SSL
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`Checker` Module
+---------------------
+
+.. automodule:: M2Crypto.SSL.Checker
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`Cipher` Module
+--------------------
+
+.. automodule:: M2Crypto.SSL.Cipher
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`Connection` Module
+------------------------
+
+.. automodule:: M2Crypto.SSL.Connection
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`Context` Module
+---------------------
+
+.. automodule:: M2Crypto.SSL.Context
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`SSLServer` Module
+-----------------------
+
+.. automodule:: M2Crypto.SSL.SSLServer
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`Session` Module
+---------------------
+
+.. automodule:: M2Crypto.SSL.Session
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`TwistedProtocolWrapper` Module
+------------------------------------
+
+.. automodule:: M2Crypto.SSL.TwistedProtocolWrapper
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`cb` Module
+----------------
+
+.. automodule:: M2Crypto.SSL.cb
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`ssl_dispatcher` Module
+----------------------------
+
+.. automodule:: M2Crypto.SSL.ssl_dispatcher
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`timeout` Module
+---------------------
+
+.. automodule:: M2Crypto.SSL.timeout
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
diff --git a/doc/html/_sources/M2Crypto.rst.txt b/doc/html/_sources/M2Crypto.rst.txt
new file mode 100644
index 0000000..dc6c706
--- /dev/null
+++ b/doc/html/_sources/M2Crypto.rst.txt
@@ -0,0 +1,218 @@
+M2Crypto Package
+================
+
+:mod:`M2Crypto` Package
+-----------------------
+
+.. automodule:: M2Crypto.__init__
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`ASN1` Module
+------------------
+
+.. automodule:: M2Crypto.ASN1
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`AuthCookie` Module
+------------------------
+
+.. automodule:: M2Crypto.AuthCookie
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`BIO` Module
+-----------------
+
+.. automodule:: M2Crypto.BIO
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`BN` Module
+----------------
+
+.. automodule:: M2Crypto.BN
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`DH` Module
+----------------
+
+.. automodule:: M2Crypto.DH
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`DSA` Module
+-----------------
+
+.. automodule:: M2Crypto.DSA
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`EC` Module
+----------------
+
+.. automodule:: M2Crypto.EC
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`EVP` Module
+-----------------
+
+.. automodule:: M2Crypto.EVP
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`Engine` Module
+--------------------
+
+.. automodule:: M2Crypto.Engine
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`Err` Module
+-----------------
+
+.. automodule:: M2Crypto.Err
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`RC4` Module
+-----------------
+
+.. automodule:: M2Crypto.RC4
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`RSA` Module
+-----------------
+
+.. automodule:: M2Crypto.RSA
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`Rand` Module
+------------------
+
+.. automodule:: M2Crypto.Rand
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`SMIME` Module
+-------------------
+
+.. automodule:: M2Crypto.SMIME
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`X509` Module
+------------------
+
+.. automodule:: M2Crypto.X509
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`callback` Module
+----------------------
+
+.. automodule:: M2Crypto.callback
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`ftpslib` Module
+---------------------
+
+.. automodule:: M2Crypto.ftpslib
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`httpslib` Module
+----------------------
+
+.. automodule:: M2Crypto.httpslib
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`m2` Module
+----------------
+
+.. automodule:: M2Crypto.m2
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`m2crypto` Module
+----------------------
+
+.. automodule:: M2Crypto.m2crypto
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`m2urllib` Module
+----------------------
+
+.. automodule:: M2Crypto.m2urllib
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`m2urllib2` Module
+-----------------------
+
+.. automodule:: M2Crypto.m2urllib2
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`m2xmlrpclib` Module
+-------------------------
+
+.. automodule:: M2Crypto.m2xmlrpclib
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`threading` Module
+-----------------------
+
+.. automodule:: M2Crypto.threading
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+:mod:`util` Module
+------------------
+
+.. automodule:: M2Crypto.util
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+Subpackages
+-----------
+
+.. toctree::
+
+ M2Crypto.SSL
+
diff --git a/doc/html/_sources/ZServerSSL-HOWTO.rst.txt b/doc/html/_sources/ZServerSSL-HOWTO.rst.txt
new file mode 100644
index 0000000..91ef5af
--- /dev/null
+++ b/doc/html/_sources/ZServerSSL-HOWTO.rst.txt
@@ -0,0 +1,239 @@
+:orphan:
+
+.. _zserverssl-howto:
+
+ZServerSSL-HOWTO
+################
+
+:author: Pheng Siong Ng <ngps@post1.com>
+:copyright: © 2000, 2001 by Ng Pheng Siong.
+:date: 2003-06-22
+
+.. contents::
+ :backlinks: entry
+
+.. sectnum::
+ :suffix: .
+
+Introduction
+============
+
+ZServerSSL adds to Zope's ZServer the following:
+
+- HTTPS server
+- WebDAV-source-over-HTTPS server
+
+With the HTTPS server, ZServerSSL also provides WebDAV-over-HTTPS and
+XMLRPC-over-HTTPS access to Zope.
+
+These instructions apply to both Un\*x and Windows installations of Zope
+2.6.1. To avoid cluttering the presentation, Windows pathnames are shown
+in Un\*x fashion.
+
+Preparation
+===========
+
+#. Download M2Crypto 0.11, contained in the file ``m2crypto-0.11.zip``.
+#. Unpack ``m2crypto-0.11.zip``. This will create a directory
+ ``m2crypto-0.11``. Henceforth, we refer to this directory as ``$M2``.
+#. Install M2Crypto per the instructions in ``$M2/INSTALL``.
+
+The ZServerSSL distribution is in ``$M2/demo/Zope``. We shall refer to
+this directory as ``$ZSSL``.
+
+Installation
+============
+
+Below, we refer to your Zope top-level directory as ``$ZOPE``.
+
+#. Copy ``$ZSSL/z2s.py`` into ``$ZOPE``.
+
+#. Depending on your operating system, modify ``$ZOPE/start`` or
+ ``$ZOPE/start.bat`` to invoke ``$ZOPE/z2s.py``, instead of
+ ``$ZOPE/z2.py``. The files ``$ZSSL/starts`` and ``$ZSSL/starts.bat``
+ serve as examples.
+
+#. Copy ``$ZSSL/dh1024.pem`` into ``$ZOPE``. This file contains
+ Diffie-Hellman parameters for use by the SSL protocol.
+
+#. Copy ``$ZSSL/randpool.dat`` into ``$ZOPE``. This file contains seed
+ material for the OpenSSL PRNG. Alternatively, create
+ ``$ZOPE/randpool.dat`` thusly::
+
+ $ dd if=/dev/urandom of=randpool.dat bs=1024 count=1
+
+#. Copy ``$ZSSL/ca.pem`` to ``$ZOPE``. This file contains an
+ example Certification Authority (CA) certificate. For
+ information on operating your own CA, see :ref:`howto-ca` or
+ one of numerous similar documents available on the web.
+
+#. Copy ``$ZSSL/server.pem`` to ``$ZOPE``. This file contains an RSA key
+ pair and its X.509v3 certificate issued by the above CA. You may also
+ create your own key/certificate bundle.
+
+#. Copy ``$ZSSL/ZServer/HTTPS_Server.py`` to ``$ZOPE/ZServer``.
+
+#. Copy ``$ZSSL/ZServer/__init__.py`` to ``$ZOPE/ZServer``. This
+ overwrites the existing ``$ZOPE/ZServer/__init__.py``. Alternatively,
+ apply the following patch to ``$ZOPE/ZServer/__init__.py``::
+
+ --- __init__.py.org Sat Jun 21 23:20:41 2003
+ +++ __init__.py Tue Jan 7 23:30:53 2003
+ @@ -84,6 +84,7 @@
+ import asyncore
+ from medusa import resolver, logger
+ from HTTPServer import zhttp_server, zhttp_handler
+ +from HTTPS_Server import zhttps_server, zhttps_handler
+ from PCGIServer import PCGIServer
+ from FCGIServer import FCGIServer
+ from FTPServer import FTPServer
+
+#. Copy ``$ZSSL/ZServer/medusa/https_server.py`` to
+ ``$ZOPE/ZServer/medusa``.
+
+#. Stop Zope, if it is running.
+
+#. Start Zope with ZServerSSL thusly::
+
+ ./starts -X -f 9021 -w 9080 -W 9081 -y 9443 -Y 9444
+
+ This starts the following:
+
+ - an FTP server on port 9021
+ - a HTTP server on port 9080
+ - a WebDAV-source server on port 9081
+ - a HTTPS server on port 9443
+ - a WebDAV-source-over-HTTPS server on port 9444
+
+Testing
+=======
+
+Below, we assume your Zope server is running on ``localhost``.
+
+HTTPS
+=====
+
+This testing is done with Mozilla 1.1 on FreeBSD.
+
+#. With a browser, connect to https://localhost:9443/. Browse around.
+ Check out your browser's HTTPS informational screens.
+#. Connect to https://localhost:9443/manage. Verify that you can access
+ Zope's management functionality.
+
+WebDAV-over-HTTPS
+=================
+
+This testing is done with Cadaver 0.21.0 on FreeBSD.::
+
+ $ cadaver https://localhost:9443/
+ WARNING: Untrusted server certificate presented:
+ Issued to: M2Crypto, SG
+ Issued by: M2Crypto, SG
+ Do you wish to accept the certificate? (y/n) y
+ dav:/> ls
+ Listing collection `/': succeeded.
+ Coll: Channels 0 Jun 19 00:04
+ Coll: Control_Panel 0 Jun 6 00:13
+ Coll: Examples 0 Jun 6 00:12
+ Coll: catalog 0 Jun 12 11:53
+ Coll: ngps 0 Jun 16 15:34
+ Coll: portal 0 Jun 21 15:21
+ Coll: skunk 0 Jun 18 21:18
+ Coll: temp_folder 0 Jun 22 17:57
+ Coll: zope 0 Jun 20 15:27
+ acl_users 0 Dec 30 1998
+ browser_id_manager 0 Jun 6 00:12
+ default.css 3037 Jun 21 16:38
+ error_log 0 Jun 6 00:12
+ index_html 313 Jun 12 13:36
+ portal0 0 Jun 21 15:21
+ session_data_manager 0 Jun 6 00:12
+ standard_error_message 1365 Jan 21 2001
+ standard_html_footer 50 Jun 12 12:30
+ standard_html_header 80 Jan 21 2001
+ standard_template.pt 282 Jun 6 00:12
+ zsyncer 0 Jun 17 15:28
+ dav:/> quit
+ Connection to `localhost' closed.
+ $
+
+
+WebDAV-Source-over-HTTPS
+========================
+
+This testing is done with Mozilla 1.1 on FreeBSD.
+
+#. Open the Mozilla Composer window.
+#. Click "File", "Open Web Location". A dialog box appears.
+#. Enter ``https://localhost:9444/index_html`` for the URL.
+#. Select "Open in new Composer window."
+#. Click "Open". A new Composer window will open with ``index_html``
+ loaded.
+
+Python with M2Crypto
+====================
+
+This testing is done with M2Crypto 0.11 and Python 2.2.2 on FreeBSD.
+
+HTTPS
+=====
+
+::
+
+ >>> from M2Crypto import Rand, SSL, m2urllib
+ >>> url = m2urllib.FancyURLopener()
+ >>> url.addheader('Connection', 'close')
+ >>> u = url.open('https://127.0.0.1:9443/')
+ send: 'GET / HTTP/1.1\r\nHost: 127.0.0.1:9443\r\nAccept-Encoding: identity\r\nUser-agent: Python-urllib/1.15\r\nConnection: close\r\n\r\n'
+ reply: 'HTTP/1.1 200 OK\r\n'
+ header: Server: ZServerSSL/0.11
+ header: Date: Sun, 22 Jun 2003 13:42:34 GMT
+ header: Connection: close
+ header: Content-Type: text/html
+ header: Etag:
+ header: Content-Length: 535
+ >>> while 1:
+ ... data = u.read()
+ ... if not data: break
+ ... print(data)
+ ...
+
+::
+
+ <html><head>
+ <base href="https://127.0.0.1:9443/" />
+ <title>Zope</title></head><body bgcolor="#FFFFFF">
+
+ <h1>NgPS Desktop Portal</h1>
+
+ &nbsp;&nbsp;So many hacks.<br>
+ &nbsp;&nbsp;So little time.<br>
+
+ <h2>Link Farm</h2>
+ <ul>
+ <li><a href="http://localhost:8080/portal">Portal</a></li>
+ <li><a href="http://localhost/">Local Apache Home Page</a></li>
+ </ul>
+
+ <hr><a href="http://www.zope.org/Credits" target="_top"><img src="https://127.0.0.1:9443/p_/ZopeButton" width="115" height="50" border="0" alt="Powered by Zope" /></a></body></html>
+
+::
+
+ >>> u.close()
+ >>>
+
+XMLRPC-over-HTTPS
+=================
+
+::
+
+ >>> from M2Crypto.m2xmlrpclib import Server, SSL_Transport
+ >>> zs = Server('https://127.0.0.1:9443/', SSL_Transport())
+ >>> print(zs.propertyMap())
+ [{'type': 'string', 'id': 'title', 'mode': 'w'}]
+ >>>
+
+Conclusion
+==========
+
+Well, it works! ;-)
diff --git a/doc/html/_sources/howto.ca.rst.txt b/doc/html/_sources/howto.ca.rst.txt
new file mode 100644
index 0000000..e950b59
--- /dev/null
+++ b/doc/html/_sources/howto.ca.rst.txt
@@ -0,0 +1,370 @@
+:orphan:
+
+.. _howto-ca:
+
+HOWTO: Creating your own CA with OpenSSL
+########################################
+
+:author: Pheng Siong Ng <ngps@post1.com>
+:copyright: © 2000, 2001 by Ng Pheng Siong.
+
+Introduction
+============
+
+This is a HOWTO on creating your own *certification authority* (*CA*)
+with OpenSSL.
+
+I last created a CA about a year ago, when I began work on
+`M2Crypto <https://gitlab.com/m2crypto/m2crypto/>`__ and needed
+certificates for the SSL bits. I accepted the tools' default
+settings then, e.g., certificate validity of 365 days; this meant
+that my certificates, including my CA's certificate, have now
+expired.
+
+Since I am using these certificates for M2Crypto's demonstration
+programs (and I have forgotten the passphrase to the CA's private
+key), I decided to discard the old CA and start afresh. I also
+decided to document the process, hence this HOWTO.
+
+The Procedure
+=============
+
+I use ``CA.pl``, a Perl program written by Steve Hanson and bundled with
+OpenSSL.
+
+The following are the steps to create a CA:
+
+1. Choose a directory to do your CA work. All commands are executed
+ within this directory. Let's call the directory ``demo``.
+
+2. Copy ``CA.pl`` and ``openssl.cnf`` into ``demo``.
+
+3. Apply the following patch to ``CA.pl``, which allows it to generate a
+ CA certificate with a validity period of 1095 days, i.e.,
+ 3 years::
+
+ --- CA.pl.org Sat Mar 31 12:40:13 2001
+ +++ CA.pl Sat Mar 31 12:41:15 2001
+ @@ -97,7 +97,7 @@
+ } else {
+ print "Making CA certificate ...\n";
+ system ("$REQ -new -x509 -keyout " .
+ - "${CATOP}/private/$CAKEY -out ${CATOP}/$CACERT $DAYS");
+ + "${CATOP}/private/$CAKEY -out ${CATOP}/$CACERT -days 1095");
+ $RET=$?;
+ }
+ }
+
+
+4. Create a new CA like this::
+
+ ./CA.pl -newca
+
+ A certificate filename (or enter to create) <enter>
+
+ Making CA certificate ...
+ Using configuration from openssl.cnf
+ Generating a 1024 bit RSA private key
+ ............++++++
+ ......................++++++
+ writing new private key to './demoCA/private/cakey.pem'
+ Enter PEM pass phrase: <secret passphrase here>
+ Verifying password - Enter PEM pass phrase: <secret passphrase again>
+ -----
+ You are about to be asked to enter information that will be incorporated
+ into your certificate request.
+ What you are about to enter is what is called a Distinguished Name or a DN.
+ There are quite a few fields but you can leave some blank
+ For some fields there will be a default value,
+ If you enter '.', the field will be left blank.
+ -----
+ Country Name (2 letter code) [AU]:SG
+ State or Province Name (full name) [Some-State]:.
+ Locality Name (eg, city) []:..
+ Organization Name (eg, company) [Internet Widgits Pty Ltd]:DemoCA
+ Organizational Unit Name (eg, section) []:.
+ Common Name (eg, YOUR name) []:DemoCA Certificate Master
+ Email Address []:certmaster@democa.dom
+
+ This creates a new CA in the directory ``demoCA``. The CA's
+ self-signed certificate is in ``demoCA/cacert.pem`` and its RSA key
+ pair is in ``demoCA/private/cakey.pem``.
+
+ ``demoCA/private/cakey.pem`` looks like this::
+
+ cat demoCA/private/cakey.pem
+
+ -----BEGIN RSA PRIVATE KEY-----
+ Proc-Type: 4,ENCRYPTED
+ DEK-Info: DES-EDE3-CBC,19973A9DBBB601BA
+
+ eOq9WFScNiI4/UWEUaSnGTKpJv2JYuMD3HwQox2Q3Cd4zGqVjJ6gF3exa5126cKf
+ X/bMVnwbPpuFZPiAIvaLyCjT6pYeXTBbSzs7/GQnvEOv+nYnDUFWi0Qm92qLk0uy
+ pFi/M1aWheN3vir2ZlAw+DW0bOOZhj8tC7Co7lMYb0YE271b6/YRPZCwQ3GXAHUJ
+ +aMYxlUDrK45aCUa/1CZDzTgk7h9cDgx2QJSIvYMYytCfI3zsuZMJS8/4OXLL0bI
+ lKmAc1dwB3DqGJt5XK4WJesiNfdxeCNEgAcYtEAgYZTPIApU+kTgTCIxJl2nMW7j
+ ax+Q1z7g+4MpgG20WD633D4z4dTlDdz+dnLi0rvuvxiwt+dUhrqiML1tyi+Z6EBH
+ jU4/cLBWev3rYfrlp4x8J9mDte0YKOk3t0wQOHqRetTsIfdtjnFp/Hu3qDmTCWjD
+ z/g7PPoO/bg/B877J9WBPbL/1hXXFYo88M+2aGlPOgDcFdiOqbLb2DCscohMbbVr
+ A4mgiy2kwWfIE73qiyV7yyG8FlRvr1iib+jbT3LTGf743utYAAs7HNGuOUObhoyt
+ jYvBD7ACn35P5YX7KTqvqErwdijxYCaNBCnvmRtmYSaNw9Kv1UJTxc5Vx7YLwIPk
+ E9KyBgKI7vPOjWBZ27+zOvNycmv1ciNtpALAw4bWtXnhCDVTHaVDy34OkheMzNCg
+ 2cjcBFzOkMIjcI03KbTQXOFIQGlsTWXGzkNf/zBQ+KksT1MCj+zBXSCvlDASMckg
+ kef21pGgUqPF14gKGfWX3sV4bjc1vbrRwq6zlG3nMuYqR5MtJJY9eQ==
+ -----END RSA PRIVATE KEY-----
+
+
+5. Next, generate a certificate request::
+
+ ./CA.pl -newreq
+
+ Using configuration from openssl.cnf
+ Generating a 1024 bit RSA private key
+ ..........++++++
+ ..............++++++
+ writing new private key to 'newreq.pem'
+ Enter PEM pass phrase: <another secret passphrase here>
+ Verifying password - Enter PEM pass phrase: <another secret passphrase again>
+ -----
+ You are about to be asked to enter information that will be incorporated
+ into your certificate request.
+ What you are about to enter is what is called a Distinguished Name or a DN.
+ There are quite a few fields but you can leave some blank
+ For some fields there will be a default value,
+ If you enter '.', the field will be left blank.
+ -----
+ Country Name (2 letter code) [AU]:SG
+ State or Province Name (full name) [Some-State]:..
+ Locality Name (eg, city) []:.
+ Organization Name (eg, company) [Internet Widgits Pty Ltd]:M2Crypto
+ Organizational Unit Name (eg, section) []:.
+ Common Name (eg, YOUR name) []:localhost
+ Email Address []:admin@server.example.dom
+
+ Please enter the following 'extra' attributes
+ to be sent with your certificate request
+ A challenge password []:<enter>
+ An optional company name []:<enter>
+ Request (and private key) is in newreq.pem
+
+\
+
+ The certificate request and private key in ``newreq.pem`` looks like
+ this::
+
+ cat newreq.pem
+
+ -----BEGIN RSA PRIVATE KEY-----
+ Proc-Type: 4,ENCRYPTED
+ DEK-Info: DES-EDE3-CBC,41B2874DF3D02DD4
+
+ mg611EoVkLEooSTv+qTM0Ddmm/M1jE/Jy5RD/sc3LSMhuGu9xc26OgsTJmkQuIAh
+ J/B4lAw8G59VTG6DykeEtrG0rUBx4bggc7PKbFuiN423YjJODWcHvVgnPOzXMQt+
+ lY4tPl5+217MRHyx2NsWGrpkQNdu3GeSPOVMl3jeQiaXupONbwQ7rj42+X/VtAJP
+ W4D1NNwu8aGCPyShsEXHc/fI1WDpphYWke97pOjIZVQESFZOPty5HjIYZux4U+td
+ W81xODtq2ecJXc8fn2Wpa9y5VD1LT7oJksOuL1+Z04OVaeUe4x0swM17HlBm2kVt
+ fe/C/L6kN27MwZhE331VjtTjSGl4/gknqQDbLOtqT06f3OISsDJETm2itllyhgzv
+ C6Fi3N03rGFmKectijC+tws5k+P+HRG6sai33usk8xPokJqA+HYSWPz1XVlpRmv4
+ kdjQOdST7ovU62mOTgf3ARcduPPwuzTfxOlYONe5NioO1APVHBrInQwcpLkpOTQR
+ vI4roIN+b75/nihUWGUJn/nbbBa2Yl0N5Gs1Tyiy9Z+CcRT2TfWKBBFlEUIFl7Mb
+ J9fTV3DI+k+akbR4il1NkQ8EcSmCr3WpA0I9n0EHI7ZVpVaHxc0sqaPFl8YGdFHq
+ 1Qk53C/w6+qPpDzT3yKFmG2LZytAAM1czvb6RbNRJJP2ZrpBwn/h99sUTo/yPfxY
+ nueYmFJDm0uVNtG0icXGNUfSfnjKNTtHPAgyKGetRIC3kgJz/bo2w7EI6iEjBAzK
+ l5TRm4x6ZJxwuXXMiJCehMMd8TC8ybwWO4AO19B3ebFFeTVsUgxSGA==
+ -----END RSA PRIVATE KEY-----
+ -----BEGIN CERTIFICATE REQUEST-----
+ MIIBnTCCAQYCAQAwXTELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRIw
+ EAYDVQQDEwlsb2NhbGhvc3QxJzAlBgkqhkiG9w0BCQEWGGFkbWluQHNlcnZlci5l
+ eGFtcGxlLmRvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAr1nYY1Qrll1r
+ uB/FqlCRrr5nvupdIN+3wF7q915tvEQoc74bnu6b8IbbGRMhzdzmvQ4SzFfVEAuM
+ MuTHeybPq5th7YDrTNizKKxOBnqE2KYuX9X22A1Kh49soJJFg6kPb9MUgiZBiMlv
+ tb7K3CHfgw5WagWnLl8Lb+ccvKZZl+8CAwEAAaAAMA0GCSqGSIb3DQEBBAUAA4GB
+ AHpoRp5YS55CZpy+wdigQEwjL/wSluvo+WjtpvP0YoBMJu4VMKeZi405R7o8oEwi
+ PdlrrliKNknFmHKIaCKTLRcU59ScA6ADEIWUzqmUzP5Cs6jrSRo3NKfg1bd09D1K
+ 9rsQkRc9Urv9mRBIsredGnYECNeRaK5R1yzpOowninXC
+ -----END CERTIFICATE REQUEST-----
+
+\
+
+ Decoding the certificate request gives the following::
+
+ openssl req -text -noout < newreq.pem
+
+ Using configuration from /usr/local/pkg/openssl/openssl.cnf
+ Certificate Request:
+ Data:
+ Version: 0 (0x0)
+ Subject: C=SG, O=M2Crypto, CN=localhost/Email=admin@server.example.dom
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public Key: (1024 bit)
+ Modulus (1024 bit):
+ 00:af:59:d8:63:54:2b:96:5d:6b:b8:1f:c5:aa:50:
+ 91:ae:be:67:be:ea:5d:20:df:b7:c0:5e:ea:f7:5e:
+ 6d:bc:44:28:73:be:1b:9e:ee:9b:f0:86:db:19:13:
+ 21:cd:dc:e6:bd:0e:12:cc:57:d5:10:0b:8c:32:e4:
+ c7:7b:26:cf:ab:9b:61:ed:80:eb:4c:d8:b3:28:ac:
+ 4e:06:7a:84:d8:a6:2e:5f:d5:f6:d8:0d:4a:87:8f:
+ 6c:a0:92:45:83:a9:0f:6f:d3:14:82:26:41:88:c9:
+ 6f:b5:be:ca:dc:21:df:83:0e:56:6a:05:a7:2e:5f:
+ 0b:6f:e7:1c:bc:a6:59:97:ef
+ Exponent: 65537 (0x10001)
+ Attributes:
+ a0:00
+ Signature Algorithm: md5WithRSAEncryption
+ 7a:68:46:9e:58:4b:9e:42:66:9c:be:c1:d8:a0:40:4c:23:2f:
+ fc:12:96:eb:e8:f9:68:ed:a6:f3:f4:62:80:4c:26:ee:15:30:
+ a7:99:8b:8d:39:47:ba:3c:a0:4c:22:3d:d9:6b:ae:58:8a:36:
+ 49:c5:98:72:88:68:22:93:2d:17:14:e7:d4:9c:03:a0:03:10:
+ 85:94:ce:a9:94:cc:fe:42:b3:a8:eb:49:1a:37:34:a7:e0:d5:
+ b7:74:f4:3d:4a:f6:bb:10:91:17:3d:52:bb:fd:99:10:48:b2:
+ b7:9d:1a:76:04:08:d7:91:68:ae:51:d7:2c:e9:3a:8c:27:8a:
+ 75:c2
+
+6. Now, sign the certificate request::
+
+ ./CA.pl -sign
+
+ Using configuration from openssl.cnf
+ Enter PEM pass phrase: <CA's passphrase>
+ Check that the request matches the signature
+ Signature ok
+ The Subjects Distinguished Name is as follows
+ countryName :PRINTABLE:'SG'
+ organizationName :PRINTABLE:'M2Crypto'
+ commonName :PRINTABLE:'localhost'
+ emailAddress :IA5STRING:'admin@server.example.dom'
+ Certificate is to be certified until Mar 31 02:57:30 2002 GMT (365 days)
+ Sign the certificate? [y/n]:y
+
+
+ 1 out of 1 certificate requests certified, commit? [y/n]y
+ Write out database with 1 new entries
+ Data Base Updated
+ Signed certificate is in newcert.pem
+
+\
+
+ ``newcert.pem`` looks like this::
+
+ cat newcert.pem
+
+ Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: md5WithRSAEncryption
+ Issuer: C=SG, O=DemoCA, CN=DemoCA Certificate Master/Email=certmaster@democa.dom
+ Validity
+ Not Before: Mar 31 02:57:30 2001 GMT
+ Not After : Mar 31 02:57:30 2002 GMT
+ Subject: C=SG, O=M2Crypto, CN=localhost/Email=admin@server.example.dom
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public Key: (1024 bit)
+ Modulus (1024 bit):
+ 00:af:59:d8:63:54:2b:96:5d:6b:b8:1f:c5:aa:50:
+ 91:ae:be:67:be:ea:5d:20:df:b7:c0:5e:ea:f7:5e:
+ 6d:bc:44:28:73:be:1b:9e:ee:9b:f0:86:db:19:13:
+ 21:cd:dc:e6:bd:0e:12:cc:57:d5:10:0b:8c:32:e4:
+ c7:7b:26:cf:ab:9b:61:ed:80:eb:4c:d8:b3:28:ac:
+ 4e:06:7a:84:d8:a6:2e:5f:d5:f6:d8:0d:4a:87:8f:
+ 6c:a0:92:45:83:a9:0f:6f:d3:14:82:26:41:88:c9:
+ 6f:b5:be:ca:dc:21:df:83:0e:56:6a:05:a7:2e:5f:
+ 0b:6f:e7:1c:bc:a6:59:97:ef
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints:
+ Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: md5WithRSAEncryption
+ Issuer: C=SG, O=DemoCA, CN=DemoCA Certificate Master/Email=certmaster@democa.dom
+ Validity
+ Not Before: Mar 31 02:57:30 2001 GMT
+ Not After : Mar 31 02:57:30 2002 GMT
+ Subject: C=SG, O=M2Crypto, CN=localhost/Email=admin@server.example.dom
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public Key: (1024 bit)
+ Modulus (1024 bit):
+ 00:af:59:d8:63:54:2b:96:5d:6b:b8:1f:c5:aa:50:
+ 91:ae:be:67:be:ea:5d:20:df:b7:c0:5e:ea:f7:5e:
+ 6d:bc:44:28:73:be:1b:9e:ee:9b:f0:86:db:19:13:
+ 21:cd:dc:e6:bd:0e:12:cc:57:d5:10:0b:8c:32:e4:
+ c7:7b:26:cf:ab:9b:61:ed:80:eb:4c:d8:b3:28:ac:
+ 4e:06:7a:84:d8:a6:2e:5f:d5:f6:d8:0d:4a:87:8f:
+ 6c:a0:92:45:83:a9:0f:6f:d3:14:82:26:41:88:c9:
+ 6f:b5:be:ca:dc:21:df:83:0e:56:6a:05:a7:2e:5f:
+ 0b:6f:e7:1c:bc:a6:59:97:ef
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints:
+ CA:FALSE
+ Netscape Comment:
+ OpenSSL Generated Certificate
+ X509v3 Subject Key Identifier:
+ B3:D6:89:88:2F:B1:15:40:EC:0A:C0:30:35:3A:B7:DA:72:73:1B:4D
+ X509v3 Authority Key Identifier:
+ keyid:F9:6A:A6:34:97:6B:BC:BB:5A:17:0D:19:FC:62:21:0B:00:B5:0E:29
+ DirName:/C=SG/O=DemoCA/CN=DemoCA Certificate Master/Email=certmaster@democa.dom
+ serial:00
+
+ Signature Algorithm: md5WithRSAEncryption
+
+7. In certain situations, e.g., where your certificate and private key
+ are to be used in an unattended SSL server, you may wish to not
+ encrypt the private key, i.e., leave the key in the clear. This
+ decision should be governed by your site's security policy and threat
+ model, of course::
+
+ openssl rsa < newkey.pem > newkey2.pem
+
+ read RSA key
+ Enter PEM pass phrase:<secret passphrase here>
+ writing RSA key
+
+ ``newkey2.pem`` looks like this::
+
+ cat newkey2.pem
+
+ -----BEGIN RSA PRIVATE KEY-----
+ MIICXgIBAAKBgQCvWdhjVCuWXWu4H8WqUJGuvme+6l0g37fAXur3Xm28RChzvhue
+ 7pvwhtsZEyHN3Oa9DhLMV9UQC4wy5Md7Js+rm2HtgOtM2LMorE4GeoTYpi5f1fbY
+ DUqHj2ygkkWDqQ9v0xSCJkGIyW+1vsrcId+DDlZqBacuXwtv5xy8plmX7wIDAQAB
+ AoGAbAkU8w3W1Qu15Hle1bJSL7GMReoreqeblOBmMAZz4by0l6sXZXJpjWXo86f/
+ +dASMYTMPC4ZTYtv06N07AFbjL+kDfqDMTfzQkYMHp1LAq1Ihbq1rHWSBH5n3ekq
+ KiY8JKpv8DR5Po1iKaXJFuDByGDENJwYbSRSpSK3P+vkWWECQQDkEUE/ZPqqqZkQ
+ 2iWRPAsCbEID8SAraQl3DdCLYs/GgARfmmj4yUHEwkys9Jo1H8k4BdxugmaUwNi5
+ YQ/CVzrXAkEAxNO80ArbGxPUmr11GHG/bGBYj1DUBkHZSc7dgxZdtUCLGNxQnNsg
+ Iwq3n6j1sUzS3UW6abQ8bivYNOUcMKJAqQJBANQxFaLU4b/NQaODQ3aoBZpAfP9L
+ 5eFdvbet+7zjt2r5CpikgkwOfAmDuXEltx/8LevY0CllW+nErx9zJgVrwUsCQQCu
+ 76H5JiznPBDSF2FjgHWqVVdgyW4owY3mU739LHvNBLicN/RN9VPy0Suy8/CqzKT9
+ lWPBXzf2k3FuUdNkRlFBAkEAmpXoybuiFR2S5Bma/ax96lVs0/VihhfC1zZP/X/F
+ Br77+h9dIul+2DnyOl50zu0Sdzst1/7ay4JSDHyiBCMGSQ==
+ -----END RSA PRIVATE KEY-----
+
+
+That's it! The certificate, ``newcert.pem``, and the private key -
+``newkey.pem`` (encrypted) or ``newkey2.pem`` (unencrypted) - are now
+ready to be used. You may wish to rename the files to more intuitive
+names.
+
+You should also keep the CA's certificate ``demo/cacert.pem`` handy
+for use when developing and deploying SSL or S/MIME applications.
+
+Conclusion
+==========
+
+We've walked through the basic steps in the creation of a CA and
+certificates using the tools that come with OpenSSL. We did not cover
+more advanced topics such as constraining a certificate to be SSL-only
+or S/MIME-only.
+
+There exist several HOWTOs similar to this one on the net. This one is
+written specifically to facilitate discussions in my other HOWTOs on
+developing SSL and S/MIME applications in
+`Python <http://www.python.org>`__ using
+`M2Crypto <https://gitlab.com/m2crypto/m2crypto/>`__.
+
diff --git a/doc/html/_sources/howto.smime.rst.txt b/doc/html/_sources/howto.smime.rst.txt
new file mode 100644
index 0000000..715e7c4
--- /dev/null
+++ b/doc/html/_sources/howto.smime.rst.txt
@@ -0,0 +1,778 @@
+:orphan:
+
+.. _howto-smime:
+
+HOWTO: Programming S/MIME in Python with M2Crypto
+=================================================
+
+:author: Pheng Siong Ng <ngps@post1.com>
+:copyright: © 2000, 2001 by Ng Pheng Siong.
+
+Introduction
+============
+
+`M2Crypto <https://gitlab.com/m2crypto/m2crypto/>`__ is a
+`Python <http://www.python.org>`__ interface to
+`OpenSSL <http://www.openssl.org>`__. It makes available to the Python
+programmer SSL functionality to implement clients and servers, S/MIME
+v2, RSA, DSA, DH, symmetric ciphers, message digests and HMACs.
+
+This document demonstrates programming S/MIME with M2Crypto.
+
+S/MIME
+======
+
+S/MIME - Secure Multipurpose Internet Mail Extensions [RFC 2311, RFC
+2312] - provides a consistent way to send and receive secure MIME data.
+Based on the popular Internet MIME standard, S/MIME provides the
+following cryptographic security services for electronic messaging
+applications - *authentication*, *message integrity* and
+*non-repudiation of origin* (using *digital signatures*), and *privacy*
+and *data security* (using *encryption*).
+
+Keys and Certificates
+=====================
+
+To create an S/MIME-signed message, you need an RSA key pair (this
+consists of a public key and a private key) and an X.509 certificate of
+said public key.
+
+To create an S/MIME-encrypted message, you need an X.509 certificate for
+each recipient.
+
+To create an S/MIME-signed *and* -encrypted message, first create a
+signed message, then encrypt the signed message with the recipients'
+certificates.
+
+You may generate key pairs and obtain certificates by using a commercial
+*certification authority* service.
+
+You can also do so using freely-available software. For many purposes,
+e.g., automated S/MIME messaging by system administration processes,
+this approach is cheap and effective.
+
+We now work through using OpenSSL to generate key pairs and
+certificates. This assumes you have OpenSSL installed properly on your
+system.
+
+First, we generate an X.509 certificate to be used for signing::
+
+ openssl req -newkey rsa:1024 -nodes -x509 -days 365 -out signer.pem
+
+ Using configuration from /usr/local/pkg/openssl/openssl.cnf
+ Generating a 1024 bit RSA private key
+ ..++++++
+ ....................++++++
+ writing new private key to 'privkey.pem'
+ -----
+ You are about to be asked to enter information that will be incorporated
+ into your certificate request.
+ What you are about to enter is what is called a Distinguished Name or a DN.
+ There are quite a few fields but you can leave some blank
+ For some fields there will be a default value,
+ If you enter '.', the field will be left blank.
+ -----
+ Country Name (2 letter code) [AU]:SG
+ State or Province Name (full name) [Some-State]:.
+ Locality Name (eg, city) []:.
+ Organization Name (eg, company) [Internet Widgits Pty Ltd]:M2Crypto
+ Organizational Unit Name (eg, section) []:.
+ Common Name (eg, YOUR name) []:S/MIME Sender
+ Email Address []:sender@example.dom
+
+
+This generates a 1024-bit RSA key pair, unencrypted, into
+``privkey.pem``; it also generates a self-signed X.509 certificate for
+the public key into ``signer.pem``. The certificate is valid for 365
+days, i.e., a year.
+
+Let's rename ``privkey.pem`` so that we know it is a companion of
+``signer.pem``'s::
+
+ mv privkey.pem signer_key.pem
+
+To verify the content of ``signer.pem``, execute the following::
+
+ openssl x509 -noout -text -in signer.pem
+
+ Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 0 (0x0)
+ Signature Algorithm: md5WithRSAEncryption
+ Issuer: C=SG, O=M2Crypto, CN=S/MIME Sender/Email=sender@example.dom
+ Validity
+ Not Before: Mar 24 12:56:16 2001 GMT
+ Not After : Mar 24 12:56:16 2002 GMT
+ Subject: C=SG, O=M2Crypto, CN=S/MIME Sender/Email=sender@example.dom
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public Key: (1024 bit)
+ Modulus (1024 bit):
+ 00:a9:d6:e2:b5:11:3b:ae:3c:e2:17:31:70:e1:6e:
+ 01:f4:19:6d:bd:2a:42:36:2b:37:34:e2:83:1d:0d:
+ 11:2e:b4:99:44:db:10:67:be:97:5f:5b:1a:26:33:
+ 46:23:2f:95:04:7a:35:da:9d:f9:26:88:39:9e:17:
+ cd:3e:eb:a8:19:8d:a8:2a:f1:43:da:55:a9:2e:2c:
+ 65:ed:04:71:42:ce:73:53:b8:ea:7e:c7:f0:23:c6:
+ 63:c5:5e:68:96:64:a7:b4:2a:94:26:76:eb:79:ea:
+ e3:4e:aa:82:09:4f:44:87:4a:12:62:b5:d7:1f:ca:
+ f2:ce:d5:ba:7e:1f:48:fd:b9
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 29:FB:38:B6:BF:E2:40:BB:FF:D5:71:D7:D5:C4:F0:83:1A:2B:C7:99
+ X509v3 Authority Key Identifier:
+ keyid:29:FB:38:B6:BF:E2:40:BB:FF:D5:71:D7:D5:C4:F0:83:1A:2B:C7:99
+ DirName:/C=SG/O=M2Crypto/CN=S/MIME Sender/Email=sender@example.dom
+ serial:00
+
+ X509v3 Basic Constraints:
+ CA:TRUE
+ Signature Algorithm: md5WithRSAEncryption
+ 68:c8:6b:1b:fa:7c:9a:39:35:76:18:15:c9:fd:89:97:62:db:
+ 7a:b0:2d:13:dd:97:e8:1b:7a:9f:22:27:83:24:9d:2e:56:ec:
+ 97:89:3c:ef:16:55:80:5a:18:7c:22:d0:f6:bb:e3:a4:e8:59:
+ 30:ff:99:5a:93:3e:ea:bc:ee:7f:8d:d6:7d:37:8c:ac:3d:74:
+ 80:ce:7a:99:ba:27:b9:2a:a3:71:fa:a5:25:ba:47:17:df:07:
+ 56:96:36:fd:60:b9:6c:96:06:e8:e3:7b:9f:4b:6a:95:71:a8:
+ 34:fc:fc:b5:88:8b:c4:3f:1e:24:f6:52:47:b2:7d:44:67:d9:
+ 83:e8
+
+Next, we generate a self-signed X.509 certificate for the recipient.
+Note that ``privkey.pem`` will be recreated::
+
+ openssl req -newkey rsa:1024 -nodes -x509 -days 365 -out recipient.pem
+
+ Using configuration from /usr/local/pkg/openssl/openssl.cnf
+ Generating a 1024 bit RSA private key
+ .....................................++++++
+ .................++++++
+ writing new private key to 'privkey.pem'
+ -----
+ You are about to be asked to enter information that will be incorporated
+ into your certificate request.
+ What you are about to enter is what is called a Distinguished Name or a DN.
+ There are quite a few fields but you can leave some blank
+ For some fields there will be a default value,
+ If you enter '.', the field will be left blank.
+ -----
+ Country Name (2 letter code) [AU]:SG
+ State or Province Name (full name) [Some-State]:.
+ Locality Name (eg, city) []:.
+ Organization Name (eg, company) [Internet Widgits Pty Ltd]:M2Crypto
+ Organizational Unit Name (eg, section) []:.
+ Common Name (eg, YOUR name) []:S/MIME Recipient
+ Email Address []:recipient@example.dom
+
+Again, rename ``privkey.pem``::
+
+ mv privkey.pem recipient_key.pem
+
+
+In the examples to follow, S/MIME Sender, ``<sender@example.dom>``,
+shall be the sender of S/MIME messages, while S/MIME Recipient,
+``<recipient@example.dom>``, shall be the recipient of S/MIME messages.
+
+Armed with the key pairs and certificates, we are now ready to begin
+programming S/MIME in Python.
+
+ **Note:** The private keys generated above are *not
+ passphrase-protected*, i.e., they are *in the clear*. Anyone who has
+ access to such a key can generate S/MIME-signed messages with it,
+ and decrypt S/MIME messages encrypted to it's corresponding public
+ key.
+
+ We may passphrase-protect the keys, if we so choose. M2Crypto will
+ prompt the user for the passphrase when such a key is being loaded.
+
+M2Crypto.SMIME
+==============
+
+The Python programmer accesses M2Crypto's S/MIME functionality through
+class ``SMIME`` in the module ``M2Crypto.SMIME``. Typically, an
+``SMIME`` object is instantiated; the object is then set up for the
+intended operation: sign, encrypt, decrypt or verify; finally, the
+operation is invoked on the object.
+
+``M2Crypto.SMIME`` makes extensive use of ``M2Crypto.BIO``:
+``M2Crypto.BIO`` is a Python abstraction of the ``BIO`` abstraction in
+OpenSSL. A commonly used ``BIO`` abstraction in M2Crypto is
+``M2Crypto.BIO.MemoryBuffer``, which implements a memory-based file-like
+object, similar to Python's own ``StringIO``.
+
+Sign
+====
+
+The following code demonstrates how to generate an S/MIME-signed
+message. ``randpool.dat`` contains random data which is used to seed
+OpenSSL's pseudo-random number generator via M2Crypto::
+
+ from M2Crypto import BIO, Rand, SMIME
+
+ def makebuf(text):
+ return BIO.MemoryBuffer(text)
+
+ # Make a MemoryBuffer of the message.
+ buf = makebuf('a sign of our times')
+
+ # Seed the PRNG.
+ Rand.load_file('randpool.dat', -1)
+
+ # Instantiate an SMIME object; set it up; sign the buffer.
+ s = SMIME.SMIME()
+ s.load_key('signer_key.pem', 'signer.pem')
+ p7 = s.sign(buf, SMIME.PKCS7_DETACHED)
+
+
+``p7`` now contains a *PKCS #7 signature blob* wrapped in an
+``M2Crypto.SMIME.PKCS7`` object. Note that ``buf`` has been consumed by
+``sign()`` and has to be recreated if it is to be used again.
+
+We may now send the signed message via SMTP. In these examples, we shall
+not do so; instead, we'll render the S/MIME output in mail-friendly
+format, and pretend that our messages are sent and received
+correctly::
+
+ # Recreate buf.
+ buf = makebuf('a sign of our times')
+
+ # Output p7 in mail-friendly format.
+ out = BIO.MemoryBuffer()
+ out.write('From: sender@example.dom\n')
+ out.write('To: recipient@example.dom\n')
+ out.write('Subject: M2Crypto S/MIME testing\n')
+ s.write(out, p7, buf)
+
+ print(out.read())
+
+ # Save the PRNG's state.
+ Rand.save_file('randpool.dat')
+
+Here's the output::
+
+ From: sender@example.dom
+ To: recipient@example.dom
+ Subject: M2Crypto S/MIME testing
+ MIME-Version: 1.0
+ Content-Type: multipart/signed ; protocol="application/x-pkcs7-signature" ; micalg=sha1 ; boundary="----3C93156FC7B4EBF49FE9C7DB7F503087"
+
+ This is an S/MIME signed message
+
+ ------3C93156FC7B4EBF49FE9C7DB7F503087
+ a sign of our times
+ ------3C93156FC7B4EBF49FE9C7DB7F503087
+ Content-Type: application/x-pkcs7-signature; name="smime.p7s"
+ Content-Transfer-Encoding: base64
+ Content-Disposition: attachment; filename="smime.p7s"
+
+ MIIE8AYJKoZIhvcNAQcCoIIE4TCCBN0CAQExCzAJBgUrDgMCGgUAMCIGCSqGSIb3
+ DQEHAaAVBBNhIHNpZ24gb2Ygb3VyIHRpbWVzoIIC5zCCAuMwggJMoAMCAQICAQAw
+ DQYJKoZIhvcNAQEEBQAwWzELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRv
+ MRYwFAYDVQQDEw1TL01JTUUgU2VuZGVyMSEwHwYJKoZIhvcNAQkBFhJzZW5kZXJA
+ ZXhhbXBsZS5kb20wHhcNMDEwMzMxMTE0MDMzWhcNMDIwMzMxMTE0MDMzWjBbMQsw
+ CQYDVQQGEwJTRzERMA8GA1UEChMITTJDcnlwdG8xFjAUBgNVBAMTDVMvTUlNRSBT
+ ZW5kZXIxITAfBgkqhkiG9w0BCQEWEnNlbmRlckBleGFtcGxlLmRvbTCBnzANBgkq
+ hkiG9w0BAQEFAAOBjQAwgYkCgYEA5c5Tj1CHTSOxa1q2q0FYiwMWYHptJpJcvtZm
+ UwrgU5sHrA8OnCM0cDXEj0KPf3cfNjHffB8HWMzI4UEgNmFXQNsxoGZ+iqwxLlNj
+ y9Mh7eFW/Bjq5hNXbouSlQ0rWBRkoxV64y+t6lQehb32WfYXQbKFxFJSXzSxOx3R
+ 8YhSPd0CAwEAAaOBtjCBszAdBgNVHQ4EFgQUXOyolL1t4jaBwZFRM7MS8nBLzUow
+ gYMGA1UdIwR8MHqAFFzsqJS9beI2gcGRUTOzEvJwS81KoV+kXTBbMQswCQYDVQQG
+ EwJTRzERMA8GA1UEChMITTJDcnlwdG8xFjAUBgNVBAMTDVMvTUlNRSBTZW5kZXIx
+ ITAfBgkqhkiG9w0BCQEWEnNlbmRlckBleGFtcGxlLmRvbYIBADAMBgNVHRMEBTAD
+ AQH/MA0GCSqGSIb3DQEBBAUAA4GBAHo3DrCHR86fSTVAvfiXdSswWqKtCEhUHRdC
+ TLFGl4hDk2GyZxaFuqZwiURz/H7nMicymI2wkz8H/wyHFg8G3BIehURpj2v/ZWXY
+ eovbgS7EZALVVkDj4hNl/IIHWd6Gtv1UODf7URbxtl3hQ9/eTWITrefT1heuPnar
+ 8czydsOLMYIBujCCAbYCAQEwYDBbMQswCQYDVQQGEwJTRzERMA8GA1UEChMITTJD
+ cnlwdG8xFjAUBgNVBAMTDVMvTUlNRSBTZW5kZXIxITAfBgkqhkiG9w0BCQEWEnNl
+ bmRlckBleGFtcGxlLmRvbQIBADAJBgUrDgMCGgUAoIGxMBgGCSqGSIb3DQEJAzEL
+ BgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTAxMDMzMTExNDUwMlowIwYJKoZI
+ hvcNAQkEMRYEFOoeRUd8ExIYXfQq8BTFuKWrSP3iMFIGCSqGSIb3DQEJDzFFMEMw
+ CgYIKoZIhvcNAwcwDgYIKoZIhvcNAwICAgCAMA0GCCqGSIb3DQMCAgFAMAcGBSsO
+ AwIHMA0GCCqGSIb3DQMCAgEoMA0GCSqGSIb3DQEBAQUABIGAQpU8hFUtLCF6hO2t
+ ec9EYJ/Imqqiiw+BxWxkUUVT81Vbjwdn9JST6+sztM5JRP2ZW+b4txEjZriYC8f3
+ kv95YMTGbIsuWkJ93GrbvqoJ/CxO23r9WWRnZEm/1EZN9ZmlrYqzBTxnNRmP3Dhj
+ cW8kzZwH+2/2zz2G7x1HxRWH95A=
+
+ ------3C93156FC7B4EBF49FE9C7DB7F503087--
+
+
+Verify
+======
+
+Assume the above output has been saved into ``sign.p7``. Let's now
+verify the signature::
+
+ from M2Crypto import SMIME, X509
+
+ # Instantiate an SMIME object.
+ s = SMIME.SMIME()
+
+ # Load the signer's cert.
+ x509 = X509.load_cert('signer.pem')
+ sk = X509.X509_Stack()
+ sk.push(x509)
+ s.set_x509_stack(sk)
+
+ # Load the signer's CA cert. In this case, because the signer's
+ # cert is self-signed, it is the signer's cert itself.
+ st = X509.X509_Store()
+ st.load_info('signer.pem')
+ s.set_x509_store(st)
+
+ # Load the data, verify it.
+ p7, data = SMIME.smime_load_pkcs7('sign.p7')
+ v = s.verify(p7, data)
+ print(v)
+ print(data)
+ print(data.read())
+
+Here's the output of the above program::
+
+ a sign of our times
+ <M2Crypto.BIO.BIO instance at 0x822012c>
+ a sign of our times
+
+Suppose, instead of loading ``signer.pem`` above, we load
+``recipient.pem``. That is, we do a global substitution of
+``recipient.pem`` for ``signer.pem`` in the above program. Here's the
+modified program's output::
+
+ Traceback (most recent call last):
+ File "./verify.py", line 22, in ?
+ v = s.verify(p7)
+ File "/usr/local/home/ngps/prog/m2/M2Crypto/SMIME.py", line 205, in verify
+ raise SMIME_Error, Err.get_error()
+ M2Crypto.SMIME.SMIME_Error: 312:error:21075075:PKCS7 routines:PKCS7_verify:certificate verify error:pk7_smime.c:213:Verify error:self signed certificate
+
+
+As displayed, the error is generated by line 213 of OpenSSL's
+``pk7_smime.c`` (as of OpenSSL 0.9.6); if you are a C programmer, you
+may wish to look up the C source to explore OpenSSL's S/MIME
+implementation and understand why the error message is worded thus.
+
+Encrypt
+=======
+
+We now demonstrate how to generate an S/MIME-encrypted message::
+
+ from M2Crypto import BIO, Rand, SMIME, X509
+
+ def makebuf(text):
+ return BIO.MemoryBuffer(text)
+
+ # Make a MemoryBuffer of the message.
+ buf = makebuf('a sign of our times')
+
+ # Seed the PRNG.
+ Rand.load_file('randpool.dat', -1)
+
+ # Instantiate an SMIME object.
+ s = SMIME.SMIME()
+
+ # Load target cert to encrypt to.
+ x509 = X509.load_cert('recipient.pem')
+ sk = X509.X509_Stack()
+ sk.push(x509)
+ s.set_x509_stack(sk)
+
+ # Set cipher: 3-key triple-DES in CBC mode.
+ s.set_cipher(SMIME.Cipher('des_ede3_cbc'))
+
+ # Encrypt the buffer.
+ p7 = s.encrypt(buf)
+
+ # Output p7 in mail-friendly format.
+ out = BIO.MemoryBuffer()
+ out.write('From: sender@example.dom\n')
+ out.write('To: recipient@example.dom\n')
+ out.write('Subject: M2Crypto S/MIME testing\n')
+ s.write(out, p7)
+
+ print(out.read())
+
+ # Save the PRNG's state.
+ Rand.save_file('randpool.dat')
+
+Here's the output of the above program::
+
+ From: sender@example.dom
+ To: recipient@example.dom
+ Subject: M2Crypto S/MIME testing
+ MIME-Version: 1.0
+ Content-Disposition: attachment; filename="smime.p7m"
+ Content-Type: application/x-pkcs7-mime; name="smime.p7m"
+ Content-Transfer-Encoding: base64
+
+ MIIBVwYJKoZIhvcNAQcDoIIBSDCCAUQCAQAxggEAMIH9AgEAMGYwYTELMAkGA1UE
+ BhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRkwFwYDVQQDExBTL01JTUUgUmVjaXBp
+ ZW50MSQwIgYJKoZIhvcNAQkBFhVyZWNpcGllbnRAZXhhbXBsZS5kb20CAQAwDQYJ
+ KoZIhvcNAQEBBQAEgYCBaXZ+qjpBEZwdP7gjfzfAtQitESyMwo3i+LBOw6sSDir6
+ FlNDPCnkrTvqDX3Rt6X6vBtTCYOm+qiN7ujPkOU61cN7h8dvHR8YW9+0IPY80/W0
+ lZ/HihSRgwTNd7LnxUUcPx8YV1id0dlmP0Hz+Lg+mHf6rqaR//JcYhX9vW4XvjA7
+ BgkqhkiG9w0BBwEwFAYIKoZIhvcNAwcECMN+qya6ADywgBgHr9Jkhwn5Gsdu7BwX
+ nIQfYTYcdL9I5Sk=
+
+
+Decrypt
+=======
+
+Assume the above output has been saved into ``encrypt.p7``. Decrypt the
+message thusly::
+
+ from M2Crypto import BIO, SMIME, X509
+
+ # Instantiate an SMIME object.
+ s = SMIME.SMIME()
+
+ # Load private key and cert.
+ s.load_key('recipient_key.pem', 'recipient.pem')
+
+ # Load the encrypted data.
+ p7, data = SMIME.smime_load_pkcs7('encrypt.p7')
+
+ # Decrypt p7.
+ out = s.decrypt(p7)
+
+ print(out)
+
+Here's the output::
+
+ a sign of our times
+
+
+Sign and Encrypt
+================
+
+Here's how to generate an S/MIME-signed/encrypted message::
+
+ from M2Crypto import BIO, Rand, SMIME, X509
+
+ def makebuf(text):
+ return BIO.MemoryBuffer(text)
+
+ # Make a MemoryBuffer of the message.
+ buf = makebuf('a sign of our times')
+
+ # Seed the PRNG.
+ Rand.load_file('randpool.dat', -1)
+
+ # Instantiate an SMIME object.
+ s = SMIME.SMIME()
+
+ # Load signer's key and cert. Sign the buffer.
+ s.load_key('signer_key.pem', 'signer.pem')
+ p7 = s.sign(buf)
+
+ # Load target cert to encrypt the signed message to.
+ x509 = X509.load_cert('recipient.pem')
+ sk = X509.X509_Stack()
+ sk.push(x509)
+ s.set_x509_stack(sk)
+
+ # Set cipher: 3-key triple-DES in CBC mode.
+ s.set_cipher(SMIME.Cipher('des_ede3_cbc'))
+
+ # Create a temporary buffer.
+ tmp = BIO.MemoryBuffer()
+
+ # Write the signed message into the temporary buffer.
+ s.write(tmp, p7)
+
+ # Encrypt the temporary buffer.
+ p7 = s.encrypt(tmp)
+
+ # Output p7 in mail-friendly format.
+ out = BIO.MemoryBuffer()
+ out.write('From: sender@example.dom\n')
+ out.write('To: recipient@example.dom\n')
+ out.write('Subject: M2Crypto S/MIME testing\n')
+ s.write(out, p7)
+
+ print(out.read())
+
+ # Save the PRNG's state.
+ Rand.save_file('randpool.dat')
+
+Here's the output of the above program::
+
+ From: sender@example.dom
+ To: recipient@example.dom
+ Subject: M2Crypto S/MIME testing
+ MIME-Version: 1.0
+ Content-Disposition: attachment; filename="smime.p7m"
+ Content-Type: application/x-pkcs7-mime; name="smime.p7m"
+ Content-Transfer-Encoding: base64
+
+ MIIIwwYJKoZIhvcNAQcDoIIItDCCCLACAQAxggEAMIH9AgEAMGYwYTELMAkGA1UE
+ BhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRkwFwYDVQQDExBTL01JTUUgUmVjaXBp
+ ZW50MSQwIgYJKoZIhvcNAQkBFhVyZWNpcGllbnRAZXhhbXBsZS5kb20CAQAwDQYJ
+ KoZIhvcNAQEBBQAEgYBlZlGupFphwhsGtIAPvDExN61qisz3oem88xoXkUW0SzoR
+ B9zJFFAuQTWzdNJgrKKYikhWjDojaAc/PFl1K5dYxRgtZLB36ULJD/v/yWmxnjz8
+ TvtK+Wbal2P/MH2pZ4LVERXa/snTElhCawUlwtiFz/JvY5CiF/dcwd+AwFQq4jCC
+ B6UGCSqGSIb3DQEHATAUBggqhkiG9w0DBwQIRF525UfwszaAggeA85RmX6AXQMxb
+ eBDz/LJeCgc3RqU1UwIsbKMquIs1S46Ebbm5nP75izPnujOkJ2hv+LNzqOWADmOl
+ +CnGEq1qxTyduIgUDA2nBgCL/gVyVy+/XC9dtImUUTxtxLgYtB0ujkBNsOaENOlM
+ fv4SGM3jkR+K/xlYG6HHzZGbfYyNGj2Y7yMZ1rL1m8SnRNmkCysKGTrudeNf6wT9
+ J6wO9DzLTioz3ZnVr3LjsSKIb4tIp4ugqNJaLuW7m3FtZ3MAgxN68hBbJs8TZ8tL
+ V/0jwUqS+grcgZEb9ymfcedxahtDUfHjRkpDpsxZzVVGkSBNcbQu92oByQVnRQ8m
+ wrYLp3/eawM5AvuV7HNpTT5ZR+1t8luishHN9899IMP2Vyg0Ub67FqFypYmM2cm2
+ sjAI4KpfvT00XFNvgLuYwYEKs9syGTO7hiHNQKcF44F5LYv6nTFwmFQB11dAtY9V
+ ull4D2CLDx9OvyNyKwdEZB5dyV0r/uKIdkhST60V2Q9KegpzgFpoZtSKM/HPYSVH
+ 1Bc9f3Q/GqZCvNZZCMx8UvRjQR8dRWDSmPJ0VXG1+wJ+fCmSPP3AuQ1/VsgPRqx2
+ 56VrpGPpGut40hV8xQFbWIZ2whwWLKPFAHj8B79ZtFUzUrU6Z2rNpvv8inHc/+S/
+ b6GR5s8/gucRblvd7n3OFNX5UJmPmcw9zWbu/1Dr9DY8l0nAQh21y5FGSS8B1wdE
+ oD2M3Lp7JbwjQbRtnDhImqul2S4yu+m+wDD1aR2K4k3GAI7KKgOBWT0+BDClcn8A
+ 4Ju6/YUbj33YlMPJgnGijLnolFy0hNW7TmWqR+8tSI3wO5eNKg4qwBnarqc3vgCV
+ quVxINAXyGQCO9lzdw6hudk8/+BlweGdqhONaIWbK5z1L/SfQo6LC9MTsj7FJydq
+ bc+kEbfZS8aSq7uc9axW6Ti0eAPJ8EVHtwhSBgZQRweKFBXs6HbbhMIdc4N0M7Oq
+ UiFXaF6s4n2uihVP6TqXtHEjTpZoC7pC+HCYiuKXUJtaqtXBOh+y3KLvHk09YL6D
+ XmTDg+UTiFsh4jKKm/BhdelbR5JbpJcj5AId76Mfr8+F/1g9ePOvsWHpQr/oIQTo
+ xEkaxCmzEgP0b6caMWfMUQrbVGxBBNcqKc/ir9fGGOPHATzzq/xLcQYvK1tZhd/D
+ ah/gpMPndsyvVCEuFPluWyDiM0VkwHgC2/3pJIYFHaxK64IutmPsy393rHMEB4kN
+ AHau6kWK+yL9qEVH1pP2zvswQ12P7gjt3T/G3bGsmvlXkEfztfjkXo6XnjcBNf5y
+ G+974AKLcjnk1gzIgarz+lAMY57Gkw4oNDMrTqVQ2OJQlvOSbllPXzH+aAiavB8W
+ ZPECLLwHxD4B1AuaiAArgKl935u/TOB+yQOR8JgGsUzROyJqHJ/SC51HkebgCkL1
+ aggtjgPlIBEXLZAlhpWLZ9lAQyrQpvCVJYwaOvfMmvRav4NAFNoZ2/Q7S4Tn1z+U
+ XX+f+GD58P4MPMhU5IKnz4yH4nlHnAiTEvcs85TZUAXze9g/uBOwZITeGtyLi52S
+ aETIr4v7SgXMepX7ThQ1Pv/jddsK/u4j2F34u0XktwCP+UrbfkE2mocdXvdzxbmd
+ tZSznK2qwgVSsPOs9MhUaepbnjmNBFFBrULhrUtSglM/VX/rWNiyh0aw4XYyHhIt
+ 9ZNlfEjKjJ67VEMBxBJ/ieUCouRGCxPYD1j65VT7oB3ZiyPu2F2nlUIcYNqPg1Sd
+ QBCrdaOXdJ0uLwyTAUeVE+wMbgscLvWsfZcCCJHAvw9NHFMUcnrdWxAYMVETNUOn
+ uryVAK7VfOldaz6z3NOSOi6nonNeHpR/sipBa4ik5xCRLT9e0S2QJgRvO9GyfAqz
+ 3DIzHtxIGePFzTiUYUTxS3i2gnMX2PEe3ChTLlYWD3jNeAKz0iOzpDphIF2xHLLQ
+ 1tCAqBmq/vUzALyDFFdFuTIqQZys4z/u4Dmyq9uXs421eN3v2hkVHvDy8uT2Ot29
+ lg4Q5YezR1EjaW//9guL1BXbcKrTEdtxeNqtem7SpZOMTSwD2lhB8z65GrX90Cyt
+ EMmaRSGYEdf5h1afL1SmKOMskbqxe1D2jG/vsXC7XX7xO/ioy0BdiJcYN1JiMOHJ
+ EOzFol5I20YkiV6j+cenfQFwc/NkaSxEkR8AUHJSbvUmRQRl6r0nnsFpZdR1w7pv
+ wkaT+eOpZynO4mY/ZtF6MpXJsixi6L4ZYXEbS6yHf+XGFfB0okILylmwv2bf6+Mq
+ nqXlmGj3Jwq7X9/+2BDqvfpFFX5lSmItKZAobLdssjFR6roJxOqRsGia2aZ+0+U5
+ VhgdITtnElgtHBaeZU5rHDswgdeLVBP+rGWnKxpJ+pLtNNi25sPYRcWFL6Erd25u
+ eXiY8GEIr+u7rqBWpc9HR34sAPRs3ubbCUleT748keCbx247ImBtiDctZxcc1O86
+ +0QjHP6HUT7FSo/FmT7a120S3Gd2jixGh06l/9ij5Z6mJa7Rm7TTbSjup/XISnOT
+ MKWcbI1nfVOhCv3xDq2eLae+s0oVoc041ceRazqFM2TL/Z6UXRME
+
+
+Decrypt and Verify
+==================
+
+Suppose the above output has been saved into ``se.p7``. The following
+demonstrates how to decrypt and verify it::
+
+ from M2Crypto import BIO, SMIME, X509
+
+ # Instantiate an SMIME object.
+ s = SMIME.SMIME()
+
+ # Load private key and cert.
+ s.load_key('recipient_key.pem', 'recipient.pem')
+
+ # Load the signed/encrypted data.
+ p7, data = SMIME.smime_load_pkcs7('se.p7')
+
+ # After the above step, 'data' == None.
+ # Decrypt p7. 'out' now contains a PKCS #7 signed blob.
+ out = s.decrypt(p7)
+
+ # Load the signer's cert.
+ x509 = X509.load_cert('signer.pem')
+ sk = X509.X509_Stack()
+ sk.push(x509)
+ s.set_x509_stack(sk)
+
+ # Load the signer's CA cert. In this case, because the signer's
+ # cert is self-signed, it is the signer's cert itself.
+ st = X509.X509_Store()
+ st.load_info('signer.pem')
+ s.set_x509_store(st)
+
+ # Recall 'out' contains a PKCS #7 blob.
+ # Transform 'out'; verify the resulting PKCS #7 blob.
+ p7_bio = BIO.MemoryBuffer(out)
+ p7, data = SMIME.smime_load_pkcs7_bio(p7_bio)
+ v = s.verify(p7)
+
+ print(v)
+
+
+The output is as follows::
+
+ a sign of our times
+
+
+Sending S/MIME messages via SMTP
+================================
+
+In the above examples, we've assumed that our S/MIME messages are sent
+and received automagically. The following is a Python function that
+generates S/MIME-signed/encrypted messages and sends them via
+SMTP::
+
+ from M2Crypto import BIO, SMIME, X509
+ import smtplib, string, sys
+
+ def sendsmime(from_addr, to_addrs, subject, msg, from_key, from_cert=None, to_certs=None, smtpd='localhost'):
+
+ msg_bio = BIO.MemoryBuffer(msg)
+ sign = from_key
+ encrypt = to_certs
+
+ s = SMIME.SMIME()
+ if sign:
+ s.load_key(from_key, from_cert)
+ if encrypt:
+ p7 = s.sign(msg_bio, flags=SMIME.PKCS7_TEXT)
+ else:
+ p7 = s.sign(msg_bio, flags=SMIME.PKCS7_TEXT|SMIME.PKCS7_DETACHED)
+ msg_bio = BIO.MemoryBuffer(msg) # Recreate coz sign() has consumed it.
+
+ if encrypt:
+ sk = X509.X509_Stack()
+ for x in to_certs:
+ sk.push(X509.load_cert(x))
+ s.set_x509_stack(sk)
+ s.set_cipher(SMIME.Cipher('des_ede3_cbc'))
+ tmp_bio = BIO.MemoryBuffer()
+ if sign:
+ s.write(tmp_bio, p7)
+ else:
+ tmp_bio.write(msg)
+ p7 = s.encrypt(tmp_bio)
+
+ out = BIO.MemoryBuffer()
+ out.write('From: %s\r\n' % from_addr)
+ out.write('To: %s\r\n' % string.join(to_addrs, ", "))
+ out.write('Subject: %s\r\n' % subject)
+ if encrypt:
+ s.write(out, p7)
+ else:
+ if sign:
+ s.write(out, p7, msg_bio, SMIME.PKCS7_TEXT)
+ else:
+ out.write('\r\n')
+ out.write(msg)
+ out.close()
+
+ smtp = smtplib.SMTP()
+ smtp.connect(smtpd)
+ smtp.sendmail(from_addr, to_addrs, out.read())
+ smtp.quit()
+
+
+This function sends plain, S/MIME-signed, S/MIME-encrypted, and
+S/MIME-signed/encrypted messages, depending on the parameters
+``from_key`` and ``to_certs``. The function's output interoperates with
+Netscape Messenger.
+
+Verifying origin of S/MIME messages
+===================================
+
+In our examples above that decrypt or verify messages, we skipped a
+step: verifying that the ``from`` address of the message matches the
+``email address`` attribute in the sender's certificate.
+
+The premise of current X.509 certification practice is that the CA is
+supposed to verify your identity, and to issue a certificate with
+``email address`` that matches your actual mail address. (Verisign's
+March 2001 failure in identity verification resulting in Microsoft
+certificates being issued to spoofers notwithstanding.)
+
+If you run your own CA, your certification practice is up to you, of
+course, and it would probably be part of your security policy.
+
+Whether your S/MIME messaging application needs to verify the ``from``
+addresses of S/MIME messages depends on your security policy and your
+system's threat model, as always.
+
+Interoperating with Netscape Messenger
+======================================
+
+Suppose S/MIME Recipient uses Netscape Messenger. To enable Messenger to
+handle S/MIME messages from S/MIME Sender, S/MIME Recipient needs to
+configure Messenger with his private key and certificate, as well as
+S/MIME Sender's certificate.
+
+ **Note:** Configuring Messenger's POP or IMAP settings so that it
+ retrieves mail correctly is beyond the scope of this HOWTO.
+
+The following steps demonstrate how to import S/MIME Recipient's private
+key and certificate for Messenger:
+
+1. Transform S/MIME Recipient's private key and certificate into *PKCS
+ #12* format::
+
+ openssl pkcs12 -export -in recipient.pem -inkey recipient_key.pem \
+ -name "S/MIME Recipient" -out recipient.p12
+
+ Enter Export Password:<enter>
+ Verifying password - Enter Export Password:<enter>
+
+2. Start Messenger.
+
+3. Click on the (open) "lock" icon at the bottom left corner of
+ Messenger's window. This brings up the "Security Info" dialog box.
+
+4. Click on "Yours" under "Certificates".
+
+5. Select "Import a certificate", then pick ``recipient.p12`` from the
+ ensuing file selection dialog box.
+
+Next, you need to import ``signer.pem`` as a CA certificate, so that
+Messenger will mark messages signed by S/MIME Sender as "trusted":
+
+1. Create a DER encoding of ``signer.pem``::
+
+ openssl x509 -inform pem -outform der -in signer.pem -out signer.der
+
+2. Install ``signer.der`` into Messenger as MIME type
+ ``application/x-x509-ca-cert``. You do this by downloading
+ ``signer.der`` via Navigator from a HTTP or HTTPS server, with the
+ correct MIME type mapping. (You may use ``demo/ssl/https_srv.py``,
+ bundled with M2Crypto, for this purpose.) Follow the series of dialog
+ boxes to accept ``signer.der`` as a CA for certifying email users.
+
+S/MIME Recipient is now able to decrypt and read S/MIME Sender's
+messages with Messenger. Messenger will indicate that S/MIME Sender's
+messages are signed, encrypted, or encrypted *and* signed, as the case
+may be, via the "stamp" icon on the message window's top right corner.
+
+Clicking on the "stamp" icon brings you to the Security Info dialog box.
+Messenger informs you that the message is, say, encrypted with 168-bit
+DES-EDE3-CBC and that it is digitally signed by the private key
+corresponding to the public key contained in the certificate
+``signer.pem``.
+
+Interoperating with Microsoft Outlook
+=====================================
+
+I do not know how to do this, as I do not use Outlook. (Nor do I use
+Netscape Messenger, actually. I use Mutt, top dog of MUAs. ;-)
+Information on how to configure Outlook with keys and certificates so
+that it handles S/MIME mail is gratefully accepted.
+
+ZSmime
+======
+
+ZSmime is a `Zope <http://www.zope.org>`__ *product* that enables Zope
+to generate S/MIME-signed/encrypted messages. ZSmime demonstrates how to
+invoke M2Crypto in a web application server extension.
+
+ZSmime has its own
+`HOWTO <http://sandbox.rulemaker.net/ngps/zope/zsmime/howto.html>`__
+explaining its usage. (That HOWTO has some overlap in content with this
+document.)
+
+Resources
+=========
+
+- IETF S/MIME Working Group - http://www.imc.org/ietf-smime
+
+- S/MIME and OpenPGP - http://www.imc.org/smime-pgpmime.html
+
+- S/MIME Freeware Library -
+ http://www.getronicsgov.com/hot/sfl_home.htm
+
+- Mozilla Network Security Services -
+ http://www.mozilla.org/projects/security/pkg/nss
+
+- S/MIME Cracking Screen Saver - http://www.counterpane.com/smime.html
diff --git a/doc/html/_sources/howto.ssl.rst.txt b/doc/html/_sources/howto.ssl.rst.txt
new file mode 100644
index 0000000..7f3278c
--- /dev/null
+++ b/doc/html/_sources/howto.ssl.rst.txt
@@ -0,0 +1,131 @@
+:orphan:
+
+.. _howto-ssl:
+
+HOWTO: Programming SSL in Python with M2Crypto
+==============================================
+
+:author: Pheng Siong Ng <ngps@netmemetic.com> and Heikki Toivonen (heikki@osafoundation.org)
+:copyright: © 2000, 2001 by Ng Pheng Siong,
+ portions © 2006 by Open Source Applications Foundation
+
+Introduction
+============
+
+`M2Crypto <https://gitlab.com/m2crypto/m2crypto/>`__ is a
+`Python <http://www.python.org>`__ interface to
+`OpenSSL <http://www.openssl.org>`__. It makes available to the Python
+programmer SSL functionality to implement clients and servers, S/MIME
+v2, RSA, DSA, DH, symmetric ciphers, message digests and HMACs.
+
+This document demonstrates programming HTTPS with M2Crypto.
+
+A bit of history
+================
+
+M2Crypto was created during the time of Python 1.5, which features a
+module httplib providing client-side HTTP functionality. M2Crypto sports
+a httpslib based on httplib.
+
+Beginning with version 2.0, Python's socket module provided
+(rudimentary) SSL support. Also in the same version, httplib was
+enhanced with class HTTPConnection, which is more sophisticated than the
+old class HTTP, and HTTPSConnection, which does HTTPS.
+
+Subsequently, M2Crypto.httpslib grew a compatible (but not identical)
+class HTTPSConnection.
+
+The primary interface difference between the two HTTPSConnection classes
+is that M2Crypto's version accepts an M2Crypto.SSL.Context instance as a
+parameter, whereas Python 2.x's SSL support does not permit Pythonic
+control of the SSL context.
+
+Within the implementations, Python's ``HTTPSConnection`` employs a
+``FakeSocket`` object, which collects all input from the SSL connection
+before returning it to the application as a ``StringIO`` buffer, whereas
+M2Crypto's ``HTTPSConnection`` uses a buffering
+``M2Crypto.BIO.IOBuffer`` object that works over the underlying
+M2Crypto.SSL.Connection directly.
+
+Since then M2Crypto has gained a Twisted wrapper that allows securing
+Twisted SSL connections with M2Crypto.
+
+Secure SSL
+==========
+
+It is recommended that you read the book Network Security with OpenSSL
+by John Viega, Matt Messier and Pravir Chandra, ISBN 059600270X.
+
+Using M2Crypto does not automatically make an SSL connection secure.
+There are various steps that need to be made before we can make that
+claim. Let's see how a simple client can establish a secure
+connection::
+
+ ctx = SSL.Context()
+ ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, depth=9)
+ if ctx.load_verify_locations('ca.pem') != 1: raise Exception('No CA certs')
+ s = SSL.Connection(ctx)
+ s.connect(server_address)
+ # Normal protocol (for example HTTP) commands follow
+
+The first line creates an SSL context. The defaults allow any SSL
+version (except SSL version 2 which has known weaknesses) and sets the
+allowed ciphers to secure ones.
+
+The second line tells M2Crypto to perform certificate validation. The
+flags shown above are typical for clients, and requires the server to
+send a certificate. The depth parameter tells how long certificate
+chains are allowed - 9 is pretty common default, although probably too
+long in practice.
+
+The third line loads the allowed root (certificate authority or CA)
+certificates. Most Linux distributions come with CA certificates in
+suitable format. You could also download the
+`certdata.txt <http://mxr.mozilla.org/seamonkey/source//security/nss/lib/ckfw/builtins/certdata.txt?raw=1>`__
+file from the
+`NSS <http://www.mozilla.org/projects/security/pki/nss/>`__ project and
+convert it with the little M2Crypto utility script
+`demo/x509/certdata2pem.py <http://svn.osafoundation.org/m2crypto/trunk/demo/x509/certdata2pem.py>`__.
+
+The fourth line creates an SSL connection object with the secure
+context.
+
+The fifth line connects to the server. During this time we perform the
+last security step: just after connection, but before exchanging any
+data, we compare the commonName (or subjectAltName DNS field) field in
+the certificate the server returned to the server address we tried to
+connect to. This happens automatically with SSL.Connection and the
+Twisted wrapper class, and anything that uses those. In all other cases
+you must do the check manually. It is recommended you call the
+SSL.Checker to do the actual check.
+
+SSL servers are different in that they typically do not require the
+client to send a certificate, so there is usually no certificate
+checking. Also, it is typically useless to perform host name checking.
+
+Code Samples
+============
+
+The best samples of how to use the various SSL objects are in the tests
+directory, and the test\_ssl.py file specifically. There are additional
+samples in the demo directory, but they are not quaranteed to be up to
+date.
+
+NOTE: The tests and demos may not be secure as is. Use the information
+above on how to make them secure.
+
+ssldump
+=======
+
+ssldump "is an SSLv3/TLS network protocol analyser. It identifies TCP
+connections on the chosen network interface and attempts to interpret
+them as SSLv3/TLS traffic. When it identifies SSLv3/TLS traffic, it
+decodes the records and displays them in a textual form to stdout. If
+provided with the appropriate keying material, it will also decrypt the
+connections and display the application data traffic.
+
+If linked with OpenSSL, ssldump can display certificates in decoded form
+and decrypt traffic (provided that it has the appropriate keying
+material)."
+
+ssldump is written by Eric Rescorla.
diff --git a/doc/html/_sources/index.rst.txt b/doc/html/_sources/index.rst.txt
new file mode 100644
index 0000000..a472668
--- /dev/null
+++ b/doc/html/_sources/index.rst.txt
@@ -0,0 +1,30 @@
+Welcome to M2Crypto's documentation!
+====================================
+
+Contents:
+
+.. toctree::
+ :maxdepth: 4
+
+ M2Crypto
+
+
+HOWTOs
+======
+
+* :ref:`howto-ca`
+
+* :ref:`howto-ssl`
+
+* :ref:`howto-smime`
+
+* :ref:`zserverssl-howto`
+
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
+
diff --git a/doc/html/_static/ajax-loader.gif b/doc/html/_static/ajax-loader.gif
new file mode 100644
index 0000000..61faf8c
--- /dev/null
+++ b/doc/html/_static/ajax-loader.gif
Binary files differ
diff --git a/doc/html/_static/alabaster.css b/doc/html/_static/alabaster.css
new file mode 100644
index 0000000..0eddaeb
--- /dev/null
+++ b/doc/html/_static/alabaster.css
@@ -0,0 +1,701 @@
+@import url("basic.css");
+
+/* -- page layout ----------------------------------------------------------- */
+
+body {
+ font-family: Georgia, serif;
+ font-size: 17px;
+ background-color: #fff;
+ color: #000;
+ margin: 0;
+ padding: 0;
+}
+
+
+div.document {
+ width: 940px;
+ margin: 30px auto 0 auto;
+}
+
+div.documentwrapper {
+ float: left;
+ width: 100%;
+}
+
+div.bodywrapper {
+ margin: 0 0 0 220px;
+}
+
+div.sphinxsidebar {
+ width: 220px;
+ font-size: 14px;
+ line-height: 1.5;
+}
+
+hr {
+ border: 1px solid #B1B4B6;
+}
+
+div.body {
+ background-color: #fff;
+ color: #3E4349;
+ padding: 0 30px 0 30px;
+}
+
+div.body > .section {
+ text-align: left;
+}
+
+div.footer {
+ width: 940px;
+ margin: 20px auto 30px auto;
+ font-size: 14px;
+ color: #888;
+ text-align: right;
+}
+
+div.footer a {
+ color: #888;
+}
+
+p.caption {
+ font-family: inherit;
+ font-size: inherit;
+}
+
+
+div.relations {
+ display: none;
+}
+
+
+div.sphinxsidebar a {
+ color: #444;
+ text-decoration: none;
+ border-bottom: 1px dotted #999;
+}
+
+div.sphinxsidebar a:hover {
+ border-bottom: 1px solid #999;
+}
+
+div.sphinxsidebarwrapper {
+ padding: 18px 10px;
+}
+
+div.sphinxsidebarwrapper p.logo {
+ padding: 0;
+ margin: -10px 0 0 0px;
+ text-align: center;
+}
+
+div.sphinxsidebarwrapper h1.logo {
+ margin-top: -10px;
+ text-align: center;
+ margin-bottom: 5px;
+ text-align: left;
+}
+
+div.sphinxsidebarwrapper h1.logo-name {
+ margin-top: 0px;
+}
+
+div.sphinxsidebarwrapper p.blurb {
+ margin-top: 0;
+ font-style: normal;
+}
+
+div.sphinxsidebar h3,
+div.sphinxsidebar h4 {
+ font-family: Georgia, serif;
+ color: #444;
+ font-size: 24px;
+ font-weight: normal;
+ margin: 0 0 5px 0;
+ padding: 0;
+}
+
+div.sphinxsidebar h4 {
+ font-size: 20px;
+}
+
+div.sphinxsidebar h3 a {
+ color: #444;
+}
+
+div.sphinxsidebar p.logo a,
+div.sphinxsidebar h3 a,
+div.sphinxsidebar p.logo a:hover,
+div.sphinxsidebar h3 a:hover {
+ border: none;
+}
+
+div.sphinxsidebar p {
+ color: #555;
+ margin: 10px 0;
+}
+
+div.sphinxsidebar ul {
+ margin: 10px 0;
+ padding: 0;
+ color: #000;
+}
+
+div.sphinxsidebar ul li.toctree-l1 > a {
+ font-size: 120%;
+}
+
+div.sphinxsidebar ul li.toctree-l2 > a {
+ font-size: 110%;
+}
+
+div.sphinxsidebar input {
+ border: 1px solid #CCC;
+ font-family: Georgia, serif;
+ font-size: 1em;
+}
+
+div.sphinxsidebar hr {
+ border: none;
+ height: 1px;
+ color: #AAA;
+ background: #AAA;
+
+ text-align: left;
+ margin-left: 0;
+ width: 50%;
+}
+
+div.sphinxsidebar .badge {
+ border-bottom: none;
+}
+
+div.sphinxsidebar .badge:hover {
+ border-bottom: none;
+}
+
+/* To address an issue with donation coming after search */
+div.sphinxsidebar h3.donation {
+ margin-top: 10px;
+}
+
+/* -- body styles ----------------------------------------------------------- */
+
+a {
+ color: #004B6B;
+ text-decoration: underline;
+}
+
+a:hover {
+ color: #6D4100;
+ text-decoration: underline;
+}
+
+div.body h1,
+div.body h2,
+div.body h3,
+div.body h4,
+div.body h5,
+div.body h6 {
+ font-family: Georgia, serif;
+ font-weight: normal;
+ margin: 30px 0px 10px 0px;
+ padding: 0;
+}
+
+div.body h1 { margin-top: 0; padding-top: 0; font-size: 240%; }
+div.body h2 { font-size: 180%; }
+div.body h3 { font-size: 150%; }
+div.body h4 { font-size: 130%; }
+div.body h5 { font-size: 100%; }
+div.body h6 { font-size: 100%; }
+
+a.headerlink {
+ color: #DDD;
+ padding: 0 4px;
+ text-decoration: none;
+}
+
+a.headerlink:hover {
+ color: #444;
+ background: #EAEAEA;
+}
+
+div.body p, div.body dd, div.body li {
+ line-height: 1.4em;
+}
+
+div.admonition {
+ margin: 20px 0px;
+ padding: 10px 30px;
+ background-color: #EEE;
+ border: 1px solid #CCC;
+}
+
+div.admonition tt.xref, div.admonition code.xref, div.admonition a tt {
+ background-color: #FBFBFB;
+ border-bottom: 1px solid #fafafa;
+}
+
+div.admonition p.admonition-title {
+ font-family: Georgia, serif;
+ font-weight: normal;
+ font-size: 24px;
+ margin: 0 0 10px 0;
+ padding: 0;
+ line-height: 1;
+}
+
+div.admonition p.last {
+ margin-bottom: 0;
+}
+
+div.highlight {
+ background-color: #fff;
+}
+
+dt:target, .highlight {
+ background: #FAF3E8;
+}
+
+div.warning {
+ background-color: #FCC;
+ border: 1px solid #FAA;
+}
+
+div.danger {
+ background-color: #FCC;
+ border: 1px solid #FAA;
+ -moz-box-shadow: 2px 2px 4px #D52C2C;
+ -webkit-box-shadow: 2px 2px 4px #D52C2C;
+ box-shadow: 2px 2px 4px #D52C2C;
+}
+
+div.error {
+ background-color: #FCC;
+ border: 1px solid #FAA;
+ -moz-box-shadow: 2px 2px 4px #D52C2C;
+ -webkit-box-shadow: 2px 2px 4px #D52C2C;
+ box-shadow: 2px 2px 4px #D52C2C;
+}
+
+div.caution {
+ background-color: #FCC;
+ border: 1px solid #FAA;
+}
+
+div.attention {
+ background-color: #FCC;
+ border: 1px solid #FAA;
+}
+
+div.important {
+ background-color: #EEE;
+ border: 1px solid #CCC;
+}
+
+div.note {
+ background-color: #EEE;
+ border: 1px solid #CCC;
+}
+
+div.tip {
+ background-color: #EEE;
+ border: 1px solid #CCC;
+}
+
+div.hint {
+ background-color: #EEE;
+ border: 1px solid #CCC;
+}
+
+div.seealso {
+ background-color: #EEE;
+ border: 1px solid #CCC;
+}
+
+div.topic {
+ background-color: #EEE;
+}
+
+p.admonition-title {
+ display: inline;
+}
+
+p.admonition-title:after {
+ content: ":";
+}
+
+pre, tt, code {
+ font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
+ font-size: 0.9em;
+}
+
+.hll {
+ background-color: #FFC;
+ margin: 0 -12px;
+ padding: 0 12px;
+ display: block;
+}
+
+img.screenshot {
+}
+
+tt.descname, tt.descclassname, code.descname, code.descclassname {
+ font-size: 0.95em;
+}
+
+tt.descname, code.descname {
+ padding-right: 0.08em;
+}
+
+img.screenshot {
+ -moz-box-shadow: 2px 2px 4px #EEE;
+ -webkit-box-shadow: 2px 2px 4px #EEE;
+ box-shadow: 2px 2px 4px #EEE;
+}
+
+table.docutils {
+ border: 1px solid #888;
+ -moz-box-shadow: 2px 2px 4px #EEE;
+ -webkit-box-shadow: 2px 2px 4px #EEE;
+ box-shadow: 2px 2px 4px #EEE;
+}
+
+table.docutils td, table.docutils th {
+ border: 1px solid #888;
+ padding: 0.25em 0.7em;
+}
+
+table.field-list, table.footnote {
+ border: none;
+ -moz-box-shadow: none;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+
+table.footnote {
+ margin: 15px 0;
+ width: 100%;
+ border: 1px solid #EEE;
+ background: #FDFDFD;
+ font-size: 0.9em;
+}
+
+table.footnote + table.footnote {
+ margin-top: -15px;
+ border-top: none;
+}
+
+table.field-list th {
+ padding: 0 0.8em 0 0;
+}
+
+table.field-list td {
+ padding: 0;
+}
+
+table.field-list p {
+ margin-bottom: 0.8em;
+}
+
+/* Cloned from
+ * https://github.com/sphinx-doc/sphinx/commit/ef60dbfce09286b20b7385333d63a60321784e68
+ */
+.field-name {
+ -moz-hyphens: manual;
+ -ms-hyphens: manual;
+ -webkit-hyphens: manual;
+ hyphens: manual;
+}
+
+table.footnote td.label {
+ width: .1px;
+ padding: 0.3em 0 0.3em 0.5em;
+}
+
+table.footnote td {
+ padding: 0.3em 0.5em;
+}
+
+dl {
+ margin: 0;
+ padding: 0;
+}
+
+dl dd {
+ margin-left: 30px;
+}
+
+blockquote {
+ margin: 0 0 0 30px;
+ padding: 0;
+}
+
+ul, ol {
+ /* Matches the 30px from the narrow-screen "li > ul" selector below */
+ margin: 10px 0 10px 30px;
+ padding: 0;
+}
+
+pre {
+ background: #EEE;
+ padding: 7px 30px;
+ margin: 15px 0px;
+ line-height: 1.3em;
+}
+
+div.viewcode-block:target {
+ background: #ffd;
+}
+
+dl pre, blockquote pre, li pre {
+ margin-left: 0;
+ padding-left: 30px;
+}
+
+tt, code {
+ background-color: #ecf0f3;
+ color: #222;
+ /* padding: 1px 2px; */
+}
+
+tt.xref, code.xref, a tt {
+ background-color: #FBFBFB;
+ border-bottom: 1px solid #fff;
+}
+
+a.reference {
+ text-decoration: none;
+ border-bottom: 1px dotted #004B6B;
+}
+
+/* Don't put an underline on images */
+a.image-reference, a.image-reference:hover {
+ border-bottom: none;
+}
+
+a.reference:hover {
+ border-bottom: 1px solid #6D4100;
+}
+
+a.footnote-reference {
+ text-decoration: none;
+ font-size: 0.7em;
+ vertical-align: top;
+ border-bottom: 1px dotted #004B6B;
+}
+
+a.footnote-reference:hover {
+ border-bottom: 1px solid #6D4100;
+}
+
+a:hover tt, a:hover code {
+ background: #EEE;
+}
+
+
+@media screen and (max-width: 870px) {
+
+ div.sphinxsidebar {
+ display: none;
+ }
+
+ div.document {
+ width: 100%;
+
+ }
+
+ div.documentwrapper {
+ margin-left: 0;
+ margin-top: 0;
+ margin-right: 0;
+ margin-bottom: 0;
+ }
+
+ div.bodywrapper {
+ margin-top: 0;
+ margin-right: 0;
+ margin-bottom: 0;
+ margin-left: 0;
+ }
+
+ ul {
+ margin-left: 0;
+ }
+
+ li > ul {
+ /* Matches the 30px from the "ul, ol" selector above */
+ margin-left: 30px;
+ }
+
+ .document {
+ width: auto;
+ }
+
+ .footer {
+ width: auto;
+ }
+
+ .bodywrapper {
+ margin: 0;
+ }
+
+ .footer {
+ width: auto;
+ }
+
+ .github {
+ display: none;
+ }
+
+
+
+}
+
+
+
+@media screen and (max-width: 875px) {
+
+ body {
+ margin: 0;
+ padding: 20px 30px;
+ }
+
+ div.documentwrapper {
+ float: none;
+ background: #fff;
+ }
+
+ div.sphinxsidebar {
+ display: block;
+ float: none;
+ width: 102.5%;
+ margin: 50px -30px -20px -30px;
+ padding: 10px 20px;
+ background: #333;
+ color: #FFF;
+ }
+
+ div.sphinxsidebar h3, div.sphinxsidebar h4, div.sphinxsidebar p,
+ div.sphinxsidebar h3 a {
+ color: #fff;
+ }
+
+ div.sphinxsidebar a {
+ color: #AAA;
+ }
+
+ div.sphinxsidebar p.logo {
+ display: none;
+ }
+
+ div.document {
+ width: 100%;
+ margin: 0;
+ }
+
+ div.footer {
+ display: none;
+ }
+
+ div.bodywrapper {
+ margin: 0;
+ }
+
+ div.body {
+ min-height: 0;
+ padding: 0;
+ }
+
+ .rtd_doc_footer {
+ display: none;
+ }
+
+ .document {
+ width: auto;
+ }
+
+ .footer {
+ width: auto;
+ }
+
+ .footer {
+ width: auto;
+ }
+
+ .github {
+ display: none;
+ }
+}
+
+
+/* misc. */
+
+.revsys-inline {
+ display: none!important;
+}
+
+/* Make nested-list/multi-paragraph items look better in Releases changelog
+ * pages. Without this, docutils' magical list fuckery causes inconsistent
+ * formatting between different release sub-lists.
+ */
+div#changelog > div.section > ul > li > p:only-child {
+ margin-bottom: 0;
+}
+
+/* Hide fugly table cell borders in ..bibliography:: directive output */
+table.docutils.citation, table.docutils.citation td, table.docutils.citation th {
+ border: none;
+ /* Below needed in some edge cases; if not applied, bottom shadows appear */
+ -moz-box-shadow: none;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+
+
+/* relbar */
+
+.related {
+ line-height: 30px;
+ width: 100%;
+ font-size: 0.9rem;
+}
+
+.related.top {
+ border-bottom: 1px solid #EEE;
+ margin-bottom: 20px;
+}
+
+.related.bottom {
+ border-top: 1px solid #EEE;
+}
+
+.related ul {
+ padding: 0;
+ margin: 0;
+ list-style: none;
+}
+
+.related li {
+ display: inline;
+}
+
+nav#rellinks {
+ float: right;
+}
+
+nav#rellinks li+li:before {
+ content: "|";
+}
+
+nav#breadcrumbs li+li:before {
+ content: "\00BB";
+}
+
+/* Hide certain items when printing */
+@media print {
+ div.related {
+ display: none;
+ }
+} \ No newline at end of file
diff --git a/doc/html/_static/basic.css b/doc/html/_static/basic.css
new file mode 100644
index 0000000..0807176
--- /dev/null
+++ b/doc/html/_static/basic.css
@@ -0,0 +1,676 @@
+/*
+ * basic.css
+ * ~~~~~~~~~
+ *
+ * Sphinx stylesheet -- basic theme.
+ *
+ * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+/* -- main layout ----------------------------------------------------------- */
+
+div.clearer {
+ clear: both;
+}
+
+/* -- relbar ---------------------------------------------------------------- */
+
+div.related {
+ width: 100%;
+ font-size: 90%;
+}
+
+div.related h3 {
+ display: none;
+}
+
+div.related ul {
+ margin: 0;
+ padding: 0 0 0 10px;
+ list-style: none;
+}
+
+div.related li {
+ display: inline;
+}
+
+div.related li.right {
+ float: right;
+ margin-right: 5px;
+}
+
+/* -- sidebar --------------------------------------------------------------- */
+
+div.sphinxsidebarwrapper {
+ padding: 10px 5px 0 10px;
+}
+
+div.sphinxsidebar {
+ float: left;
+ width: 230px;
+ margin-left: -100%;
+ font-size: 90%;
+ word-wrap: break-word;
+ overflow-wrap : break-word;
+}
+
+div.sphinxsidebar ul {
+ list-style: none;
+}
+
+div.sphinxsidebar ul ul,
+div.sphinxsidebar ul.want-points {
+ margin-left: 20px;
+ list-style: square;
+}
+
+div.sphinxsidebar ul ul {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+div.sphinxsidebar form {
+ margin-top: 10px;
+}
+
+div.sphinxsidebar input {
+ border: 1px solid #98dbcc;
+ font-family: sans-serif;
+ font-size: 1em;
+}
+
+div.sphinxsidebar #searchbox form.search {
+ overflow: hidden;
+}
+
+div.sphinxsidebar #searchbox input[type="text"] {
+ float: left;
+ width: 80%;
+ padding: 0.25em;
+ box-sizing: border-box;
+}
+
+div.sphinxsidebar #searchbox input[type="submit"] {
+ float: left;
+ width: 20%;
+ border-left: none;
+ padding: 0.25em;
+ box-sizing: border-box;
+}
+
+
+img {
+ border: 0;
+ max-width: 100%;
+}
+
+/* -- search page ----------------------------------------------------------- */
+
+ul.search {
+ margin: 10px 0 0 20px;
+ padding: 0;
+}
+
+ul.search li {
+ padding: 5px 0 5px 20px;
+ background-image: url(file.png);
+ background-repeat: no-repeat;
+ background-position: 0 7px;
+}
+
+ul.search li a {
+ font-weight: bold;
+}
+
+ul.search li div.context {
+ color: #888;
+ margin: 2px 0 0 30px;
+ text-align: left;
+}
+
+ul.keywordmatches li.goodmatch a {
+ font-weight: bold;
+}
+
+/* -- index page ------------------------------------------------------------ */
+
+table.contentstable {
+ width: 90%;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+table.contentstable p.biglink {
+ line-height: 150%;
+}
+
+a.biglink {
+ font-size: 1.3em;
+}
+
+span.linkdescr {
+ font-style: italic;
+ padding-top: 5px;
+ font-size: 90%;
+}
+
+/* -- general index --------------------------------------------------------- */
+
+table.indextable {
+ width: 100%;
+}
+
+table.indextable td {
+ text-align: left;
+ vertical-align: top;
+}
+
+table.indextable ul {
+ margin-top: 0;
+ margin-bottom: 0;
+ list-style-type: none;
+}
+
+table.indextable > tbody > tr > td > ul {
+ padding-left: 0em;
+}
+
+table.indextable tr.pcap {
+ height: 10px;
+}
+
+table.indextable tr.cap {
+ margin-top: 10px;
+ background-color: #f2f2f2;
+}
+
+img.toggler {
+ margin-right: 3px;
+ margin-top: 3px;
+ cursor: pointer;
+}
+
+div.modindex-jumpbox {
+ border-top: 1px solid #ddd;
+ border-bottom: 1px solid #ddd;
+ margin: 1em 0 1em 0;
+ padding: 0.4em;
+}
+
+div.genindex-jumpbox {
+ border-top: 1px solid #ddd;
+ border-bottom: 1px solid #ddd;
+ margin: 1em 0 1em 0;
+ padding: 0.4em;
+}
+
+/* -- domain module index --------------------------------------------------- */
+
+table.modindextable td {
+ padding: 2px;
+ border-collapse: collapse;
+}
+
+/* -- general body styles --------------------------------------------------- */
+
+div.body {
+ min-width: 450px;
+ max-width: 800px;
+}
+
+div.body p, div.body dd, div.body li, div.body blockquote {
+ -moz-hyphens: auto;
+ -ms-hyphens: auto;
+ -webkit-hyphens: auto;
+ hyphens: auto;
+}
+
+a.headerlink {
+ visibility: hidden;
+}
+
+h1:hover > a.headerlink,
+h2:hover > a.headerlink,
+h3:hover > a.headerlink,
+h4:hover > a.headerlink,
+h5:hover > a.headerlink,
+h6:hover > a.headerlink,
+dt:hover > a.headerlink,
+caption:hover > a.headerlink,
+p.caption:hover > a.headerlink,
+div.code-block-caption:hover > a.headerlink {
+ visibility: visible;
+}
+
+div.body p.caption {
+ text-align: inherit;
+}
+
+div.body td {
+ text-align: left;
+}
+
+.first {
+ margin-top: 0 !important;
+}
+
+p.rubric {
+ margin-top: 30px;
+ font-weight: bold;
+}
+
+img.align-left, .figure.align-left, object.align-left {
+ clear: left;
+ float: left;
+ margin-right: 1em;
+}
+
+img.align-right, .figure.align-right, object.align-right {
+ clear: right;
+ float: right;
+ margin-left: 1em;
+}
+
+img.align-center, .figure.align-center, object.align-center {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+.align-left {
+ text-align: left;
+}
+
+.align-center {
+ text-align: center;
+}
+
+.align-right {
+ text-align: right;
+}
+
+/* -- sidebars -------------------------------------------------------------- */
+
+div.sidebar {
+ margin: 0 0 0.5em 1em;
+ border: 1px solid #ddb;
+ padding: 7px 7px 0 7px;
+ background-color: #ffe;
+ width: 40%;
+ float: right;
+}
+
+p.sidebar-title {
+ font-weight: bold;
+}
+
+/* -- topics ---------------------------------------------------------------- */
+
+div.topic {
+ border: 1px solid #ccc;
+ padding: 7px 7px 0 7px;
+ margin: 10px 0 10px 0;
+}
+
+p.topic-title {
+ font-size: 1.1em;
+ font-weight: bold;
+ margin-top: 10px;
+}
+
+/* -- admonitions ----------------------------------------------------------- */
+
+div.admonition {
+ margin-top: 10px;
+ margin-bottom: 10px;
+ padding: 7px;
+}
+
+div.admonition dt {
+ font-weight: bold;
+}
+
+div.admonition dl {
+ margin-bottom: 0;
+}
+
+p.admonition-title {
+ margin: 0px 10px 5px 0px;
+ font-weight: bold;
+}
+
+div.body p.centered {
+ text-align: center;
+ margin-top: 25px;
+}
+
+/* -- tables ---------------------------------------------------------------- */
+
+table.docutils {
+ border: 0;
+ border-collapse: collapse;
+}
+
+table.align-center {
+ margin-left: auto;
+ margin-right: auto;
+}
+
+table caption span.caption-number {
+ font-style: italic;
+}
+
+table caption span.caption-text {
+}
+
+table.docutils td, table.docutils th {
+ padding: 1px 8px 1px 5px;
+ border-top: 0;
+ border-left: 0;
+ border-right: 0;
+ border-bottom: 1px solid #aaa;
+}
+
+table.footnote td, table.footnote th {
+ border: 0 !important;
+}
+
+th {
+ text-align: left;
+ padding-right: 5px;
+}
+
+table.citation {
+ border-left: solid 1px gray;
+ margin-left: 1px;
+}
+
+table.citation td {
+ border-bottom: none;
+}
+
+/* -- figures --------------------------------------------------------------- */
+
+div.figure {
+ margin: 0.5em;
+ padding: 0.5em;
+}
+
+div.figure p.caption {
+ padding: 0.3em;
+}
+
+div.figure p.caption span.caption-number {
+ font-style: italic;
+}
+
+div.figure p.caption span.caption-text {
+}
+
+/* -- field list styles ----------------------------------------------------- */
+
+table.field-list td, table.field-list th {
+ border: 0 !important;
+}
+
+.field-list ul {
+ margin: 0;
+ padding-left: 1em;
+}
+
+.field-list p {
+ margin: 0;
+}
+
+.field-name {
+ -moz-hyphens: manual;
+ -ms-hyphens: manual;
+ -webkit-hyphens: manual;
+ hyphens: manual;
+}
+
+/* -- hlist styles ---------------------------------------------------------- */
+
+table.hlist td {
+ vertical-align: top;
+}
+
+
+/* -- other body styles ----------------------------------------------------- */
+
+ol.arabic {
+ list-style: decimal;
+}
+
+ol.loweralpha {
+ list-style: lower-alpha;
+}
+
+ol.upperalpha {
+ list-style: upper-alpha;
+}
+
+ol.lowerroman {
+ list-style: lower-roman;
+}
+
+ol.upperroman {
+ list-style: upper-roman;
+}
+
+dl {
+ margin-bottom: 15px;
+}
+
+dd p {
+ margin-top: 0px;
+}
+
+dd ul, dd table {
+ margin-bottom: 10px;
+}
+
+dd {
+ margin-top: 3px;
+ margin-bottom: 10px;
+ margin-left: 30px;
+}
+
+dt:target, span.highlighted {
+ background-color: #fbe54e;
+}
+
+rect.highlighted {
+ fill: #fbe54e;
+}
+
+dl.glossary dt {
+ font-weight: bold;
+ font-size: 1.1em;
+}
+
+.optional {
+ font-size: 1.3em;
+}
+
+.sig-paren {
+ font-size: larger;
+}
+
+.versionmodified {
+ font-style: italic;
+}
+
+.system-message {
+ background-color: #fda;
+ padding: 5px;
+ border: 3px solid red;
+}
+
+.footnote:target {
+ background-color: #ffa;
+}
+
+.line-block {
+ display: block;
+ margin-top: 1em;
+ margin-bottom: 1em;
+}
+
+.line-block .line-block {
+ margin-top: 0;
+ margin-bottom: 0;
+ margin-left: 1.5em;
+}
+
+.guilabel, .menuselection {
+ font-family: sans-serif;
+}
+
+.accelerator {
+ text-decoration: underline;
+}
+
+.classifier {
+ font-style: oblique;
+}
+
+abbr, acronym {
+ border-bottom: dotted 1px;
+ cursor: help;
+}
+
+/* -- code displays --------------------------------------------------------- */
+
+pre {
+ overflow: auto;
+ overflow-y: hidden; /* fixes display issues on Chrome browsers */
+}
+
+span.pre {
+ -moz-hyphens: none;
+ -ms-hyphens: none;
+ -webkit-hyphens: none;
+ hyphens: none;
+}
+
+td.linenos pre {
+ padding: 5px 0px;
+ border: 0;
+ background-color: transparent;
+ color: #aaa;
+}
+
+table.highlighttable {
+ margin-left: 0.5em;
+}
+
+table.highlighttable td {
+ padding: 0 0.5em 0 0.5em;
+}
+
+div.code-block-caption {
+ padding: 2px 5px;
+ font-size: small;
+}
+
+div.code-block-caption code {
+ background-color: transparent;
+}
+
+div.code-block-caption + div > div.highlight > pre {
+ margin-top: 0;
+}
+
+div.code-block-caption span.caption-number {
+ padding: 0.1em 0.3em;
+ font-style: italic;
+}
+
+div.code-block-caption span.caption-text {
+}
+
+div.literal-block-wrapper {
+ padding: 1em 1em 0;
+}
+
+div.literal-block-wrapper div.highlight {
+ margin: 0;
+}
+
+code.descname {
+ background-color: transparent;
+ font-weight: bold;
+ font-size: 1.2em;
+}
+
+code.descclassname {
+ background-color: transparent;
+}
+
+code.xref, a code {
+ background-color: transparent;
+ font-weight: bold;
+}
+
+h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {
+ background-color: transparent;
+}
+
+.viewcode-link {
+ float: right;
+}
+
+.viewcode-back {
+ float: right;
+ font-family: sans-serif;
+}
+
+div.viewcode-block:target {
+ margin: -1px -10px;
+ padding: 0 10px;
+}
+
+/* -- math display ---------------------------------------------------------- */
+
+img.math {
+ vertical-align: middle;
+}
+
+div.body div.math p {
+ text-align: center;
+}
+
+span.eqno {
+ float: right;
+}
+
+span.eqno a.headerlink {
+ position: relative;
+ left: 0px;
+ z-index: 1;
+}
+
+div.math:hover a.headerlink {
+ visibility: visible;
+}
+
+/* -- printout stylesheet --------------------------------------------------- */
+
+@media print {
+ div.document,
+ div.documentwrapper,
+ div.bodywrapper {
+ margin: 0 !important;
+ width: 100%;
+ }
+
+ div.sphinxsidebar,
+ div.related,
+ div.footer,
+ #top-link {
+ display: none;
+ }
+} \ No newline at end of file
diff --git a/doc/html/_static/comment-bright.png b/doc/html/_static/comment-bright.png
new file mode 100644
index 0000000..15e27ed
--- /dev/null
+++ b/doc/html/_static/comment-bright.png
Binary files differ
diff --git a/doc/html/_static/comment-close.png b/doc/html/_static/comment-close.png
new file mode 100644
index 0000000..4d91bcf
--- /dev/null
+++ b/doc/html/_static/comment-close.png
Binary files differ
diff --git a/doc/html/_static/comment.png b/doc/html/_static/comment.png
new file mode 100644
index 0000000..dfbc0cb
--- /dev/null
+++ b/doc/html/_static/comment.png
Binary files differ
diff --git a/doc/html/_static/custom.css b/doc/html/_static/custom.css
new file mode 100644
index 0000000..2a924f1
--- /dev/null
+++ b/doc/html/_static/custom.css
@@ -0,0 +1 @@
+/* This file intentionally left blank. */
diff --git a/doc/html/_static/doctools.js b/doc/html/_static/doctools.js
new file mode 100644
index 0000000..344db17
--- /dev/null
+++ b/doc/html/_static/doctools.js
@@ -0,0 +1,315 @@
+/*
+ * doctools.js
+ * ~~~~~~~~~~~
+ *
+ * Sphinx JavaScript utilities for all documentation.
+ *
+ * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+/**
+ * select a different prefix for underscore
+ */
+$u = _.noConflict();
+
+/**
+ * make the code below compatible with browsers without
+ * an installed firebug like debugger
+if (!window.console || !console.firebug) {
+ var names = ["log", "debug", "info", "warn", "error", "assert", "dir",
+ "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace",
+ "profile", "profileEnd"];
+ window.console = {};
+ for (var i = 0; i < names.length; ++i)
+ window.console[names[i]] = function() {};
+}
+ */
+
+/**
+ * small helper function to urldecode strings
+ */
+jQuery.urldecode = function(x) {
+ return decodeURIComponent(x).replace(/\+/g, ' ');
+};
+
+/**
+ * small helper function to urlencode strings
+ */
+jQuery.urlencode = encodeURIComponent;
+
+/**
+ * This function returns the parsed url parameters of the
+ * current request. Multiple values per key are supported,
+ * it will always return arrays of strings for the value parts.
+ */
+jQuery.getQueryParameters = function(s) {
+ if (typeof s === 'undefined')
+ s = document.location.search;
+ var parts = s.substr(s.indexOf('?') + 1).split('&');
+ var result = {};
+ for (var i = 0; i < parts.length; i++) {
+ var tmp = parts[i].split('=', 2);
+ var key = jQuery.urldecode(tmp[0]);
+ var value = jQuery.urldecode(tmp[1]);
+ if (key in result)
+ result[key].push(value);
+ else
+ result[key] = [value];
+ }
+ return result;
+};
+
+/**
+ * highlight a given string on a jquery object by wrapping it in
+ * span elements with the given class name.
+ */
+jQuery.fn.highlightText = function(text, className) {
+ function highlight(node, addItems) {
+ if (node.nodeType === 3) {
+ var val = node.nodeValue;
+ var pos = val.toLowerCase().indexOf(text);
+ if (pos >= 0 &&
+ !jQuery(node.parentNode).hasClass(className) &&
+ !jQuery(node.parentNode).hasClass("nohighlight")) {
+ var span;
+ var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg");
+ if (isInSVG) {
+ span = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
+ } else {
+ span = document.createElement("span");
+ span.className = className;
+ }
+ span.appendChild(document.createTextNode(val.substr(pos, text.length)));
+ node.parentNode.insertBefore(span, node.parentNode.insertBefore(
+ document.createTextNode(val.substr(pos + text.length)),
+ node.nextSibling));
+ node.nodeValue = val.substr(0, pos);
+ if (isInSVG) {
+ var bbox = span.getBBox();
+ var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
+ rect.x.baseVal.value = bbox.x;
+ rect.y.baseVal.value = bbox.y;
+ rect.width.baseVal.value = bbox.width;
+ rect.height.baseVal.value = bbox.height;
+ rect.setAttribute('class', className);
+ var parentOfText = node.parentNode.parentNode;
+ addItems.push({
+ "parent": node.parentNode,
+ "target": rect});
+ }
+ }
+ }
+ else if (!jQuery(node).is("button, select, textarea")) {
+ jQuery.each(node.childNodes, function() {
+ highlight(this, addItems);
+ });
+ }
+ }
+ var addItems = [];
+ var result = this.each(function() {
+ highlight(this, addItems);
+ });
+ for (var i = 0; i < addItems.length; ++i) {
+ jQuery(addItems[i].parent).before(addItems[i].target);
+ }
+ return result;
+};
+
+/*
+ * backward compatibility for jQuery.browser
+ * This will be supported until firefox bug is fixed.
+ */
+if (!jQuery.browser) {
+ jQuery.uaMatch = function(ua) {
+ ua = ua.toLowerCase();
+
+ var match = /(chrome)[ \/]([\w.]+)/.exec(ua) ||
+ /(webkit)[ \/]([\w.]+)/.exec(ua) ||
+ /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) ||
+ /(msie) ([\w.]+)/.exec(ua) ||
+ ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) ||
+ [];
+
+ return {
+ browser: match[ 1 ] || "",
+ version: match[ 2 ] || "0"
+ };
+ };
+ jQuery.browser = {};
+ jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true;
+}
+
+/**
+ * Small JavaScript module for the documentation.
+ */
+var Documentation = {
+
+ init : function() {
+ this.fixFirefoxAnchorBug();
+ this.highlightSearchWords();
+ this.initIndexTable();
+ if (DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) {
+ this.initOnKeyListeners();
+ }
+ },
+
+ /**
+ * i18n support
+ */
+ TRANSLATIONS : {},
+ PLURAL_EXPR : function(n) { return n === 1 ? 0 : 1; },
+ LOCALE : 'unknown',
+
+ // gettext and ngettext don't access this so that the functions
+ // can safely bound to a different name (_ = Documentation.gettext)
+ gettext : function(string) {
+ var translated = Documentation.TRANSLATIONS[string];
+ if (typeof translated === 'undefined')
+ return string;
+ return (typeof translated === 'string') ? translated : translated[0];
+ },
+
+ ngettext : function(singular, plural, n) {
+ var translated = Documentation.TRANSLATIONS[singular];
+ if (typeof translated === 'undefined')
+ return (n == 1) ? singular : plural;
+ return translated[Documentation.PLURALEXPR(n)];
+ },
+
+ addTranslations : function(catalog) {
+ for (var key in catalog.messages)
+ this.TRANSLATIONS[key] = catalog.messages[key];
+ this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')');
+ this.LOCALE = catalog.locale;
+ },
+
+ /**
+ * add context elements like header anchor links
+ */
+ addContextElements : function() {
+ $('div[id] > :header:first').each(function() {
+ $('<a class="headerlink">\u00B6</a>').
+ attr('href', '#' + this.id).
+ attr('title', _('Permalink to this headline')).
+ appendTo(this);
+ });
+ $('dt[id]').each(function() {
+ $('<a class="headerlink">\u00B6</a>').
+ attr('href', '#' + this.id).
+ attr('title', _('Permalink to this definition')).
+ appendTo(this);
+ });
+ },
+
+ /**
+ * workaround a firefox stupidity
+ * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075
+ */
+ fixFirefoxAnchorBug : function() {
+ if (document.location.hash && $.browser.mozilla)
+ window.setTimeout(function() {
+ document.location.href += '';
+ }, 10);
+ },
+
+ /**
+ * highlight the search words provided in the url in the text
+ */
+ highlightSearchWords : function() {
+ var params = $.getQueryParameters();
+ var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : [];
+ if (terms.length) {
+ var body = $('div.body');
+ if (!body.length) {
+ body = $('body');
+ }
+ window.setTimeout(function() {
+ $.each(terms, function() {
+ body.highlightText(this.toLowerCase(), 'highlighted');
+ });
+ }, 10);
+ $('<p class="highlight-link"><a href="javascript:Documentation.' +
+ 'hideSearchWords()">' + _('Hide Search Matches') + '</a></p>')
+ .appendTo($('#searchbox'));
+ }
+ },
+
+ /**
+ * init the domain index toggle buttons
+ */
+ initIndexTable : function() {
+ var togglers = $('img.toggler').click(function() {
+ var src = $(this).attr('src');
+ var idnum = $(this).attr('id').substr(7);
+ $('tr.cg-' + idnum).toggle();
+ if (src.substr(-9) === 'minus.png')
+ $(this).attr('src', src.substr(0, src.length-9) + 'plus.png');
+ else
+ $(this).attr('src', src.substr(0, src.length-8) + 'minus.png');
+ }).css('display', '');
+ if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) {
+ togglers.click();
+ }
+ },
+
+ /**
+ * helper function to hide the search marks again
+ */
+ hideSearchWords : function() {
+ $('#searchbox .highlight-link').fadeOut(300);
+ $('span.highlighted').removeClass('highlighted');
+ },
+
+ /**
+ * make the url absolute
+ */
+ makeURL : function(relativeURL) {
+ return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL;
+ },
+
+ /**
+ * get the current relative url
+ */
+ getCurrentURL : function() {
+ var path = document.location.pathname;
+ var parts = path.split(/\//);
+ $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() {
+ if (this === '..')
+ parts.pop();
+ });
+ var url = parts.join('/');
+ return path.substring(url.lastIndexOf('/') + 1, path.length - 1);
+ },
+
+ initOnKeyListeners: function() {
+ $(document).keyup(function(event) {
+ var activeElementType = document.activeElement.tagName;
+ // don't navigate when in search box or textarea
+ if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT') {
+ switch (event.keyCode) {
+ case 37: // left
+ var prevHref = $('link[rel="prev"]').prop('href');
+ if (prevHref) {
+ window.location.href = prevHref;
+ return false;
+ }
+ case 39: // right
+ var nextHref = $('link[rel="next"]').prop('href');
+ if (nextHref) {
+ window.location.href = nextHref;
+ return false;
+ }
+ }
+ }
+ });
+ }
+};
+
+// quick alias for translations
+_ = Documentation.gettext;
+
+$(document).ready(function() {
+ Documentation.init();
+});
diff --git a/doc/html/_static/documentation_options.js b/doc/html/_static/documentation_options.js
new file mode 100644
index 0000000..d28647e
--- /dev/null
+++ b/doc/html/_static/documentation_options.js
@@ -0,0 +1,10 @@
+var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
+ VERSION: '',
+ LANGUAGE: 'None',
+ COLLAPSE_INDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true,
+ SOURCELINK_SUFFIX: '.txt',
+ NAVIGATION_WITH_KEYS: false,
+}; \ No newline at end of file
diff --git a/doc/html/_static/down-pressed.png b/doc/html/_static/down-pressed.png
new file mode 100644
index 0000000..5756c8c
--- /dev/null
+++ b/doc/html/_static/down-pressed.png
Binary files differ
diff --git a/doc/html/_static/down.png b/doc/html/_static/down.png
new file mode 100644
index 0000000..1b3bdad
--- /dev/null
+++ b/doc/html/_static/down.png
Binary files differ
diff --git a/doc/html/_static/file.png b/doc/html/_static/file.png
new file mode 100644
index 0000000..a858a41
--- /dev/null
+++ b/doc/html/_static/file.png
Binary files differ
diff --git a/doc/html/_static/jquery-3.2.1.js b/doc/html/_static/jquery-3.2.1.js
new file mode 100644
index 0000000..d2d8ca4
--- /dev/null
+++ b/doc/html/_static/jquery-3.2.1.js
@@ -0,0 +1,10253 @@
+/*!
+ * jQuery JavaScript Library v3.2.1
+ * https://jquery.com/
+ *
+ * Includes Sizzle.js
+ * https://sizzlejs.com/
+ *
+ * Copyright JS Foundation and other contributors
+ * Released under the MIT license
+ * https://jquery.org/license
+ *
+ * Date: 2017-03-20T18:59Z
+ */
+( function( global, factory ) {
+
+ "use strict";
+
+ if ( typeof module === "object" && typeof module.exports === "object" ) {
+
+ // For CommonJS and CommonJS-like environments where a proper `window`
+ // is present, execute the factory and get jQuery.
+ // For environments that do not have a `window` with a `document`
+ // (such as Node.js), expose a factory as module.exports.
+ // This accentuates the need for the creation of a real `window`.
+ // e.g. var jQuery = require("jquery")(window);
+ // See ticket #14549 for more info.
+ module.exports = global.document ?
+ factory( global, true ) :
+ function( w ) {
+ if ( !w.document ) {
+ throw new Error( "jQuery requires a window with a document" );
+ }
+ return factory( w );
+ };
+ } else {
+ factory( global );
+ }
+
+// Pass this if window is not defined yet
+} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
+
+// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
+// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode
+// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common
+// enough that all such attempts are guarded in a try block.
+"use strict";
+
+var arr = [];
+
+var document = window.document;
+
+var getProto = Object.getPrototypeOf;
+
+var slice = arr.slice;
+
+var concat = arr.concat;
+
+var push = arr.push;
+
+var indexOf = arr.indexOf;
+
+var class2type = {};
+
+var toString = class2type.toString;
+
+var hasOwn = class2type.hasOwnProperty;
+
+var fnToString = hasOwn.toString;
+
+var ObjectFunctionString = fnToString.call( Object );
+
+var support = {};
+
+
+
+ function DOMEval( code, doc ) {
+ doc = doc || document;
+
+ var script = doc.createElement( "script" );
+
+ script.text = code;
+ doc.head.appendChild( script ).parentNode.removeChild( script );
+ }
+/* global Symbol */
+// Defining this global in .eslintrc.json would create a danger of using the global
+// unguarded in another place, it seems safer to define global only for this module
+
+
+
+var
+ version = "3.2.1",
+
+ // Define a local copy of jQuery
+ jQuery = function( selector, context ) {
+
+ // The jQuery object is actually just the init constructor 'enhanced'
+ // Need init if jQuery is called (just allow error to be thrown if not included)
+ return new jQuery.fn.init( selector, context );
+ },
+
+ // Support: Android <=4.0 only
+ // Make sure we trim BOM and NBSP
+ rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
+
+ // Matches dashed string for camelizing
+ rmsPrefix = /^-ms-/,
+ rdashAlpha = /-([a-z])/g,
+
+ // Used by jQuery.camelCase as callback to replace()
+ fcamelCase = function( all, letter ) {
+ return letter.toUpperCase();
+ };
+
+jQuery.fn = jQuery.prototype = {
+
+ // The current version of jQuery being used
+ jquery: version,
+
+ constructor: jQuery,
+
+ // The default length of a jQuery object is 0
+ length: 0,
+
+ toArray: function() {
+ return slice.call( this );
+ },
+
+ // Get the Nth element in the matched element set OR
+ // Get the whole matched element set as a clean array
+ get: function( num ) {
+
+ // Return all the elements in a clean array
+ if ( num == null ) {
+ return slice.call( this );
+ }
+
+ // Return just the one element from the set
+ return num < 0 ? this[ num + this.length ] : this[ num ];
+ },
+
+ // Take an array of elements and push it onto the stack
+ // (returning the new matched element set)
+ pushStack: function( elems ) {
+
+ // Build a new jQuery matched element set
+ var ret = jQuery.merge( this.constructor(), elems );
+
+ // Add the old object onto the stack (as a reference)
+ ret.prevObject = this;
+
+ // Return the newly-formed element set
+ return ret;
+ },
+
+ // Execute a callback for every element in the matched set.
+ each: function( callback ) {
+ return jQuery.each( this, callback );
+ },
+
+ map: function( callback ) {
+ return this.pushStack( jQuery.map( this, function( elem, i ) {
+ return callback.call( elem, i, elem );
+ } ) );
+ },
+
+ slice: function() {
+ return this.pushStack( slice.apply( this, arguments ) );
+ },
+
+ first: function() {
+ return this.eq( 0 );
+ },
+
+ last: function() {
+ return this.eq( -1 );
+ },
+
+ eq: function( i ) {
+ var len = this.length,
+ j = +i + ( i < 0 ? len : 0 );
+ return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
+ },
+
+ end: function() {
+ return this.prevObject || this.constructor();
+ },
+
+ // For internal use only.
+ // Behaves like an Array's method, not like a jQuery method.
+ push: push,
+ sort: arr.sort,
+ splice: arr.splice
+};
+
+jQuery.extend = jQuery.fn.extend = function() {
+ var options, name, src, copy, copyIsArray, clone,
+ target = arguments[ 0 ] || {},
+ i = 1,
+ length = arguments.length,
+ deep = false;
+
+ // Handle a deep copy situation
+ if ( typeof target === "boolean" ) {
+ deep = target;
+
+ // Skip the boolean and the target
+ target = arguments[ i ] || {};
+ i++;
+ }
+
+ // Handle case when target is a string or something (possible in deep copy)
+ if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
+ target = {};
+ }
+
+ // Extend jQuery itself if only one argument is passed
+ if ( i === length ) {
+ target = this;
+ i--;
+ }
+
+ for ( ; i < length; i++ ) {
+
+ // Only deal with non-null/undefined values
+ if ( ( options = arguments[ i ] ) != null ) {
+
+ // Extend the base object
+ for ( name in options ) {
+ src = target[ name ];
+ copy = options[ name ];
+
+ // Prevent never-ending loop
+ if ( target === copy ) {
+ continue;
+ }
+
+ // Recurse if we're merging plain objects or arrays
+ if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
+ ( copyIsArray = Array.isArray( copy ) ) ) ) {
+
+ if ( copyIsArray ) {
+ copyIsArray = false;
+ clone = src && Array.isArray( src ) ? src : [];
+
+ } else {
+ clone = src && jQuery.isPlainObject( src ) ? src : {};
+ }
+
+ // Never move original objects, clone them
+ target[ name ] = jQuery.extend( deep, clone, copy );
+
+ // Don't bring in undefined values
+ } else if ( copy !== undefined ) {
+ target[ name ] = copy;
+ }
+ }
+ }
+ }
+
+ // Return the modified object
+ return target;
+};
+
+jQuery.extend( {
+
+ // Unique for each copy of jQuery on the page
+ expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
+
+ // Assume jQuery is ready without the ready module
+ isReady: true,
+
+ error: function( msg ) {
+ throw new Error( msg );
+ },
+
+ noop: function() {},
+
+ isFunction: function( obj ) {
+ return jQuery.type( obj ) === "function";
+ },
+
+ isWindow: function( obj ) {
+ return obj != null && obj === obj.window;
+ },
+
+ isNumeric: function( obj ) {
+
+ // As of jQuery 3.0, isNumeric is limited to
+ // strings and numbers (primitives or objects)
+ // that can be coerced to finite numbers (gh-2662)
+ var type = jQuery.type( obj );
+ return ( type === "number" || type === "string" ) &&
+
+ // parseFloat NaNs numeric-cast false positives ("")
+ // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
+ // subtraction forces infinities to NaN
+ !isNaN( obj - parseFloat( obj ) );
+ },
+
+ isPlainObject: function( obj ) {
+ var proto, Ctor;
+
+ // Detect obvious negatives
+ // Use toString instead of jQuery.type to catch host objects
+ if ( !obj || toString.call( obj ) !== "[object Object]" ) {
+ return false;
+ }
+
+ proto = getProto( obj );
+
+ // Objects with no prototype (e.g., `Object.create( null )`) are plain
+ if ( !proto ) {
+ return true;
+ }
+
+ // Objects with prototype are plain iff they were constructed by a global Object function
+ Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor;
+ return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString;
+ },
+
+ isEmptyObject: function( obj ) {
+
+ /* eslint-disable no-unused-vars */
+ // See https://github.com/eslint/eslint/issues/6125
+ var name;
+
+ for ( name in obj ) {
+ return false;
+ }
+ return true;
+ },
+
+ type: function( obj ) {
+ if ( obj == null ) {
+ return obj + "";
+ }
+
+ // Support: Android <=2.3 only (functionish RegExp)
+ return typeof obj === "object" || typeof obj === "function" ?
+ class2type[ toString.call( obj ) ] || "object" :
+ typeof obj;
+ },
+
+ // Evaluates a script in a global context
+ globalEval: function( code ) {
+ DOMEval( code );
+ },
+
+ // Convert dashed to camelCase; used by the css and data modules
+ // Support: IE <=9 - 11, Edge 12 - 13
+ // Microsoft forgot to hump their vendor prefix (#9572)
+ camelCase: function( string ) {
+ return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
+ },
+
+ each: function( obj, callback ) {
+ var length, i = 0;
+
+ if ( isArrayLike( obj ) ) {
+ length = obj.length;
+ for ( ; i < length; i++ ) {
+ if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
+ break;
+ }
+ }
+ } else {
+ for ( i in obj ) {
+ if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
+ break;
+ }
+ }
+ }
+
+ return obj;
+ },
+
+ // Support: Android <=4.0 only
+ trim: function( text ) {
+ return text == null ?
+ "" :
+ ( text + "" ).replace( rtrim, "" );
+ },
+
+ // results is for internal usage only
+ makeArray: function( arr, results ) {
+ var ret = results || [];
+
+ if ( arr != null ) {
+ if ( isArrayLike( Object( arr ) ) ) {
+ jQuery.merge( ret,
+ typeof arr === "string" ?
+ [ arr ] : arr
+ );
+ } else {
+ push.call( ret, arr );
+ }
+ }
+
+ return ret;
+ },
+
+ inArray: function( elem, arr, i ) {
+ return arr == null ? -1 : indexOf.call( arr, elem, i );
+ },
+
+ // Support: Android <=4.0 only, PhantomJS 1 only
+ // push.apply(_, arraylike) throws on ancient WebKit
+ merge: function( first, second ) {
+ var len = +second.length,
+ j = 0,
+ i = first.length;
+
+ for ( ; j < len; j++ ) {
+ first[ i++ ] = second[ j ];
+ }
+
+ first.length = i;
+
+ return first;
+ },
+
+ grep: function( elems, callback, invert ) {
+ var callbackInverse,
+ matches = [],
+ i = 0,
+ length = elems.length,
+ callbackExpect = !invert;
+
+ // Go through the array, only saving the items
+ // that pass the validator function
+ for ( ; i < length; i++ ) {
+ callbackInverse = !callback( elems[ i ], i );
+ if ( callbackInverse !== callbackExpect ) {
+ matches.push( elems[ i ] );
+ }
+ }
+
+ return matches;
+ },
+
+ // arg is for internal usage only
+ map: function( elems, callback, arg ) {
+ var length, value,
+ i = 0,
+ ret = [];
+
+ // Go through the array, translating each of the items to their new values
+ if ( isArrayLike( elems ) ) {
+ length = elems.length;
+ for ( ; i < length; i++ ) {
+ value = callback( elems[ i ], i, arg );
+
+ if ( value != null ) {
+ ret.push( value );
+ }
+ }
+
+ // Go through every key on the object,
+ } else {
+ for ( i in elems ) {
+ value = callback( elems[ i ], i, arg );
+
+ if ( value != null ) {
+ ret.push( value );
+ }
+ }
+ }
+
+ // Flatten any nested arrays
+ return concat.apply( [], ret );
+ },
+
+ // A global GUID counter for objects
+ guid: 1,
+
+ // Bind a function to a context, optionally partially applying any
+ // arguments.
+ proxy: function( fn, context ) {
+ var tmp, args, proxy;
+
+ if ( typeof context === "string" ) {
+ tmp = fn[ context ];
+ context = fn;
+ fn = tmp;
+ }
+
+ // Quick check to determine if target is callable, in the spec
+ // this throws a TypeError, but we will just return undefined.
+ if ( !jQuery.isFunction( fn ) ) {
+ return undefined;
+ }
+
+ // Simulated bind
+ args = slice.call( arguments, 2 );
+ proxy = function() {
+ return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
+ };
+
+ // Set the guid of unique handler to the same of original handler, so it can be removed
+ proxy.guid = fn.guid = fn.guid || jQuery.guid++;
+
+ return proxy;
+ },
+
+ now: Date.now,
+
+ // jQuery.support is not used in Core but other projects attach their
+ // properties to it so it needs to exist.
+ support: support
+} );
+
+if ( typeof Symbol === "function" ) {
+ jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
+}
+
+// Populate the class2type map
+jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
+function( i, name ) {
+ class2type[ "[object " + name + "]" ] = name.toLowerCase();
+} );
+
+function isArrayLike( obj ) {
+
+ // Support: real iOS 8.2 only (not reproducible in simulator)
+ // `in` check used to prevent JIT error (gh-2145)
+ // hasOwn isn't used here due to false negatives
+ // regarding Nodelist length in IE
+ var length = !!obj && "length" in obj && obj.length,
+ type = jQuery.type( obj );
+
+ if ( type === "function" || jQuery.isWindow( obj ) ) {
+ return false;
+ }
+
+ return type === "array" || length === 0 ||
+ typeof length === "number" && length > 0 && ( length - 1 ) in obj;
+}
+var Sizzle =
+/*!
+ * Sizzle CSS Selector Engine v2.3.3
+ * https://sizzlejs.com/
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license
+ * http://jquery.org/license
+ *
+ * Date: 2016-08-08
+ */
+(function( window ) {
+
+var i,
+ support,
+ Expr,
+ getText,
+ isXML,
+ tokenize,
+ compile,
+ select,
+ outermostContext,
+ sortInput,
+ hasDuplicate,
+
+ // Local document vars
+ setDocument,
+ document,
+ docElem,
+ documentIsHTML,
+ rbuggyQSA,
+ rbuggyMatches,
+ matches,
+ contains,
+
+ // Instance-specific data
+ expando = "sizzle" + 1 * new Date(),
+ preferredDoc = window.document,
+ dirruns = 0,
+ done = 0,
+ classCache = createCache(),
+ tokenCache = createCache(),
+ compilerCache = createCache(),
+ sortOrder = function( a, b ) {
+ if ( a === b ) {
+ hasDuplicate = true;
+ }
+ return 0;
+ },
+
+ // Instance methods
+ hasOwn = ({}).hasOwnProperty,
+ arr = [],
+ pop = arr.pop,
+ push_native = arr.push,
+ push = arr.push,
+ slice = arr.slice,
+ // Use a stripped-down indexOf as it's faster than native
+ // https://jsperf.com/thor-indexof-vs-for/5
+ indexOf = function( list, elem ) {
+ var i = 0,
+ len = list.length;
+ for ( ; i < len; i++ ) {
+ if ( list[i] === elem ) {
+ return i;
+ }
+ }
+ return -1;
+ },
+
+ booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
+
+ // Regular expressions
+
+ // http://www.w3.org/TR/css3-selectors/#whitespace
+ whitespace = "[\\x20\\t\\r\\n\\f]",
+
+ // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
+ identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+",
+
+ // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
+ attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
+ // Operator (capture 2)
+ "*([*^$|!~]?=)" + whitespace +
+ // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
+ "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
+ "*\\]",
+
+ pseudos = ":(" + identifier + ")(?:\\((" +
+ // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
+ // 1. quoted (capture 3; capture 4 or capture 5)
+ "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
+ // 2. simple (capture 6)
+ "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
+ // 3. anything else (capture 2)
+ ".*" +
+ ")\\)|)",
+
+ // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
+ rwhitespace = new RegExp( whitespace + "+", "g" ),
+ rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
+
+ rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
+ rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
+
+ rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
+
+ rpseudo = new RegExp( pseudos ),
+ ridentifier = new RegExp( "^" + identifier + "$" ),
+
+ matchExpr = {
+ "ID": new RegExp( "^#(" + identifier + ")" ),
+ "CLASS": new RegExp( "^\\.(" + identifier + ")" ),
+ "TAG": new RegExp( "^(" + identifier + "|[*])" ),
+ "ATTR": new RegExp( "^" + attributes ),
+ "PSEUDO": new RegExp( "^" + pseudos ),
+ "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
+ "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
+ "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
+ "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
+ // For use in libraries implementing .is()
+ // We use this for POS matching in `select`
+ "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
+ whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
+ },
+
+ rinputs = /^(?:input|select|textarea|button)$/i,
+ rheader = /^h\d$/i,
+
+ rnative = /^[^{]+\{\s*\[native \w/,
+
+ // Easily-parseable/retrievable ID or TAG or CLASS selectors
+ rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
+
+ rsibling = /[+~]/,
+
+ // CSS escapes
+ // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
+ runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
+ funescape = function( _, escaped, escapedWhitespace ) {
+ var high = "0x" + escaped - 0x10000;
+ // NaN means non-codepoint
+ // Support: Firefox<24
+ // Workaround erroneous numeric interpretation of +"0x"
+ return high !== high || escapedWhitespace ?
+ escaped :
+ high < 0 ?
+ // BMP codepoint
+ String.fromCharCode( high + 0x10000 ) :
+ // Supplemental Plane codepoint (surrogate pair)
+ String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
+ },
+
+ // CSS string/identifier serialization
+ // https://drafts.csswg.org/cssom/#common-serializing-idioms
+ rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,
+ fcssescape = function( ch, asCodePoint ) {
+ if ( asCodePoint ) {
+
+ // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
+ if ( ch === "\0" ) {
+ return "\uFFFD";
+ }
+
+ // Control characters and (dependent upon position) numbers get escaped as code points
+ return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
+ }
+
+ // Other potentially-special ASCII characters get backslash-escaped
+ return "\\" + ch;
+ },
+
+ // Used for iframes
+ // See setDocument()
+ // Removing the function wrapper causes a "Permission Denied"
+ // error in IE
+ unloadHandler = function() {
+ setDocument();
+ },
+
+ disabledAncestor = addCombinator(
+ function( elem ) {
+ return elem.disabled === true && ("form" in elem || "label" in elem);
+ },
+ { dir: "parentNode", next: "legend" }
+ );
+
+// Optimize for push.apply( _, NodeList )
+try {
+ push.apply(
+ (arr = slice.call( preferredDoc.childNodes )),
+ preferredDoc.childNodes
+ );
+ // Support: Android<4.0
+ // Detect silently failing push.apply
+ arr[ preferredDoc.childNodes.length ].nodeType;
+} catch ( e ) {
+ push = { apply: arr.length ?
+
+ // Leverage slice if possible
+ function( target, els ) {
+ push_native.apply( target, slice.call(els) );
+ } :
+
+ // Support: IE<9
+ // Otherwise append directly
+ function( target, els ) {
+ var j = target.length,
+ i = 0;
+ // Can't trust NodeList.length
+ while ( (target[j++] = els[i++]) ) {}
+ target.length = j - 1;
+ }
+ };
+}
+
+function Sizzle( selector, context, results, seed ) {
+ var m, i, elem, nid, match, groups, newSelector,
+ newContext = context && context.ownerDocument,
+
+ // nodeType defaults to 9, since context defaults to document
+ nodeType = context ? context.nodeType : 9;
+
+ results = results || [];
+
+ // Return early from calls with invalid selector or context
+ if ( typeof selector !== "string" || !selector ||
+ nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
+
+ return results;
+ }
+
+ // Try to shortcut find operations (as opposed to filters) in HTML documents
+ if ( !seed ) {
+
+ if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
+ setDocument( context );
+ }
+ context = context || document;
+
+ if ( documentIsHTML ) {
+
+ // If the selector is sufficiently simple, try using a "get*By*" DOM method
+ // (excepting DocumentFragment context, where the methods don't exist)
+ if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
+
+ // ID selector
+ if ( (m = match[1]) ) {
+
+ // Document context
+ if ( nodeType === 9 ) {
+ if ( (elem = context.getElementById( m )) ) {
+
+ // Support: IE, Opera, Webkit
+ // TODO: identify versions
+ // getElementById can match elements by name instead of ID
+ if ( elem.id === m ) {
+ results.push( elem );
+ return results;
+ }
+ } else {
+ return results;
+ }
+
+ // Element context
+ } else {
+
+ // Support: IE, Opera, Webkit
+ // TODO: identify versions
+ // getElementById can match elements by name instead of ID
+ if ( newContext && (elem = newContext.getElementById( m )) &&
+ contains( context, elem ) &&
+ elem.id === m ) {
+
+ results.push( elem );
+ return results;
+ }
+ }
+
+ // Type selector
+ } else if ( match[2] ) {
+ push.apply( results, context.getElementsByTagName( selector ) );
+ return results;
+
+ // Class selector
+ } else if ( (m = match[3]) && support.getElementsByClassName &&
+ context.getElementsByClassName ) {
+
+ push.apply( results, context.getElementsByClassName( m ) );
+ return results;
+ }
+ }
+
+ // Take advantage of querySelectorAll
+ if ( support.qsa &&
+ !compilerCache[ selector + " " ] &&
+ (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
+
+ if ( nodeType !== 1 ) {
+ newContext = context;
+ newSelector = selector;
+
+ // qSA looks outside Element context, which is not what we want
+ // Thanks to Andrew Dupont for this workaround technique
+ // Support: IE <=8
+ // Exclude object elements
+ } else if ( context.nodeName.toLowerCase() !== "object" ) {
+
+ // Capture the context ID, setting it first if necessary
+ if ( (nid = context.getAttribute( "id" )) ) {
+ nid = nid.replace( rcssescape, fcssescape );
+ } else {
+ context.setAttribute( "id", (nid = expando) );
+ }
+
+ // Prefix every selector in the list
+ groups = tokenize( selector );
+ i = groups.length;
+ while ( i-- ) {
+ groups[i] = "#" + nid + " " + toSelector( groups[i] );
+ }
+ newSelector = groups.join( "," );
+
+ // Expand context for sibling selectors
+ newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
+ context;
+ }
+
+ if ( newSelector ) {
+ try {
+ push.apply( results,
+ newContext.querySelectorAll( newSelector )
+ );
+ return results;
+ } catch ( qsaError ) {
+ } finally {
+ if ( nid === expando ) {
+ context.removeAttribute( "id" );
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // All others
+ return select( selector.replace( rtrim, "$1" ), context, results, seed );
+}
+
+/**
+ * Create key-value caches of limited size
+ * @returns {function(string, object)} Returns the Object data after storing it on itself with
+ * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
+ * deleting the oldest entry
+ */
+function createCache() {
+ var keys = [];
+
+ function cache( key, value ) {
+ // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
+ if ( keys.push( key + " " ) > Expr.cacheLength ) {
+ // Only keep the most recent entries
+ delete cache[ keys.shift() ];
+ }
+ return (cache[ key + " " ] = value);
+ }
+ return cache;
+}
+
+/**
+ * Mark a function for special use by Sizzle
+ * @param {Function} fn The function to mark
+ */
+function markFunction( fn ) {
+ fn[ expando ] = true;
+ return fn;
+}
+
+/**
+ * Support testing using an element
+ * @param {Function} fn Passed the created element and returns a boolean result
+ */
+function assert( fn ) {
+ var el = document.createElement("fieldset");
+
+ try {
+ return !!fn( el );
+ } catch (e) {
+ return false;
+ } finally {
+ // Remove from its parent by default
+ if ( el.parentNode ) {
+ el.parentNode.removeChild( el );
+ }
+ // release memory in IE
+ el = null;
+ }
+}
+
+/**
+ * Adds the same handler for all of the specified attrs
+ * @param {String} attrs Pipe-separated list of attributes
+ * @param {Function} handler The method that will be applied
+ */
+function addHandle( attrs, handler ) {
+ var arr = attrs.split("|"),
+ i = arr.length;
+
+ while ( i-- ) {
+ Expr.attrHandle[ arr[i] ] = handler;
+ }
+}
+
+/**
+ * Checks document order of two siblings
+ * @param {Element} a
+ * @param {Element} b
+ * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
+ */
+function siblingCheck( a, b ) {
+ var cur = b && a,
+ diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
+ a.sourceIndex - b.sourceIndex;
+
+ // Use IE sourceIndex if available on both nodes
+ if ( diff ) {
+ return diff;
+ }
+
+ // Check if b follows a
+ if ( cur ) {
+ while ( (cur = cur.nextSibling) ) {
+ if ( cur === b ) {
+ return -1;
+ }
+ }
+ }
+
+ return a ? 1 : -1;
+}
+
+/**
+ * Returns a function to use in pseudos for input types
+ * @param {String} type
+ */
+function createInputPseudo( type ) {
+ return function( elem ) {
+ var name = elem.nodeName.toLowerCase();
+ return name === "input" && elem.type === type;
+ };
+}
+
+/**
+ * Returns a function to use in pseudos for buttons
+ * @param {String} type
+ */
+function createButtonPseudo( type ) {
+ return function( elem ) {
+ var name = elem.nodeName.toLowerCase();
+ return (name === "input" || name === "button") && elem.type === type;
+ };
+}
+
+/**
+ * Returns a function to use in pseudos for :enabled/:disabled
+ * @param {Boolean} disabled true for :disabled; false for :enabled
+ */
+function createDisabledPseudo( disabled ) {
+
+ // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
+ return function( elem ) {
+
+ // Only certain elements can match :enabled or :disabled
+ // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
+ // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
+ if ( "form" in elem ) {
+
+ // Check for inherited disabledness on relevant non-disabled elements:
+ // * listed form-associated elements in a disabled fieldset
+ // https://html.spec.whatwg.org/multipage/forms.html#category-listed
+ // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
+ // * option elements in a disabled optgroup
+ // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
+ // All such elements have a "form" property.
+ if ( elem.parentNode && elem.disabled === false ) {
+
+ // Option elements defer to a parent optgroup if present
+ if ( "label" in elem ) {
+ if ( "label" in elem.parentNode ) {
+ return elem.parentNode.disabled === disabled;
+ } else {
+ return elem.disabled === disabled;
+ }
+ }
+
+ // Support: IE 6 - 11
+ // Use the isDisabled shortcut property to check for disabled fieldset ancestors
+ return elem.isDisabled === disabled ||
+
+ // Where there is no isDisabled, check manually
+ /* jshint -W018 */
+ elem.isDisabled !== !disabled &&
+ disabledAncestor( elem ) === disabled;
+ }
+
+ return elem.disabled === disabled;
+
+ // Try to winnow out elements that can't be disabled before trusting the disabled property.
+ // Some victims get caught in our net (label, legend, menu, track), but it shouldn't
+ // even exist on them, let alone have a boolean value.
+ } else if ( "label" in elem ) {
+ return elem.disabled === disabled;
+ }
+
+ // Remaining elements are neither :enabled nor :disabled
+ return false;
+ };
+}
+
+/**
+ * Returns a function to use in pseudos for positionals
+ * @param {Function} fn
+ */
+function createPositionalPseudo( fn ) {
+ return markFunction(function( argument ) {
+ argument = +argument;
+ return markFunction(function( seed, matches ) {
+ var j,
+ matchIndexes = fn( [], seed.length, argument ),
+ i = matchIndexes.length;
+
+ // Match elements found at the specified indexes
+ while ( i-- ) {
+ if ( seed[ (j = matchIndexes[i]) ] ) {
+ seed[j] = !(matches[j] = seed[j]);
+ }
+ }
+ });
+ });
+}
+
+/**
+ * Checks a node for validity as a Sizzle context
+ * @param {Element|Object=} context
+ * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
+ */
+function testContext( context ) {
+ return context && typeof context.getElementsByTagName !== "undefined" && context;
+}
+
+// Expose support vars for convenience
+support = Sizzle.support = {};
+
+/**
+ * Detects XML nodes
+ * @param {Element|Object} elem An element or a document
+ * @returns {Boolean} True iff elem is a non-HTML XML node
+ */
+isXML = Sizzle.isXML = function( elem ) {
+ // documentElement is verified for cases where it doesn't yet exist
+ // (such as loading iframes in IE - #4833)
+ var documentElement = elem && (elem.ownerDocument || elem).documentElement;
+ return documentElement ? documentElement.nodeName !== "HTML" : false;
+};
+
+/**
+ * Sets document-related variables once based on the current document
+ * @param {Element|Object} [doc] An element or document object to use to set the document
+ * @returns {Object} Returns the current document
+ */
+setDocument = Sizzle.setDocument = function( node ) {
+ var hasCompare, subWindow,
+ doc = node ? node.ownerDocument || node : preferredDoc;
+
+ // Return early if doc is invalid or already selected
+ if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
+ return document;
+ }
+
+ // Update global variables
+ document = doc;
+ docElem = document.documentElement;
+ documentIsHTML = !isXML( document );
+
+ // Support: IE 9-11, Edge
+ // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
+ if ( preferredDoc !== document &&
+ (subWindow = document.defaultView) && subWindow.top !== subWindow ) {
+
+ // Support: IE 11, Edge
+ if ( subWindow.addEventListener ) {
+ subWindow.addEventListener( "unload", unloadHandler, false );
+
+ // Support: IE 9 - 10 only
+ } else if ( subWindow.attachEvent ) {
+ subWindow.attachEvent( "onunload", unloadHandler );
+ }
+ }
+
+ /* Attributes
+ ---------------------------------------------------------------------- */
+
+ // Support: IE<8
+ // Verify that getAttribute really returns attributes and not properties
+ // (excepting IE8 booleans)
+ support.attributes = assert(function( el ) {
+ el.className = "i";
+ return !el.getAttribute("className");
+ });
+
+ /* getElement(s)By*
+ ---------------------------------------------------------------------- */
+
+ // Check if getElementsByTagName("*") returns only elements
+ support.getElementsByTagName = assert(function( el ) {
+ el.appendChild( document.createComment("") );
+ return !el.getElementsByTagName("*").length;
+ });
+
+ // Support: IE<9
+ support.getElementsByClassName = rnative.test( document.getElementsByClassName );
+
+ // Support: IE<10
+ // Check if getElementById returns elements by name
+ // The broken getElementById methods don't pick up programmatically-set names,
+ // so use a roundabout getElementsByName test
+ support.getById = assert(function( el ) {
+ docElem.appendChild( el ).id = expando;
+ return !document.getElementsByName || !document.getElementsByName( expando ).length;
+ });
+
+ // ID filter and find
+ if ( support.getById ) {
+ Expr.filter["ID"] = function( id ) {
+ var attrId = id.replace( runescape, funescape );
+ return function( elem ) {
+ return elem.getAttribute("id") === attrId;
+ };
+ };
+ Expr.find["ID"] = function( id, context ) {
+ if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
+ var elem = context.getElementById( id );
+ return elem ? [ elem ] : [];
+ }
+ };
+ } else {
+ Expr.filter["ID"] = function( id ) {
+ var attrId = id.replace( runescape, funescape );
+ return function( elem ) {
+ var node = typeof elem.getAttributeNode !== "undefined" &&
+ elem.getAttributeNode("id");
+ return node && node.value === attrId;
+ };
+ };
+
+ // Support: IE 6 - 7 only
+ // getElementById is not reliable as a find shortcut
+ Expr.find["ID"] = function( id, context ) {
+ if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
+ var node, i, elems,
+ elem = context.getElementById( id );
+
+ if ( elem ) {
+
+ // Verify the id attribute
+ node = elem.getAttributeNode("id");
+ if ( node && node.value === id ) {
+ return [ elem ];
+ }
+
+ // Fall back on getElementsByName
+ elems = context.getElementsByName( id );
+ i = 0;
+ while ( (elem = elems[i++]) ) {
+ node = elem.getAttributeNode("id");
+ if ( node && node.value === id ) {
+ return [ elem ];
+ }
+ }
+ }
+
+ return [];
+ }
+ };
+ }
+
+ // Tag
+ Expr.find["TAG"] = support.getElementsByTagName ?
+ function( tag, context ) {
+ if ( typeof context.getElementsByTagName !== "undefined" ) {
+ return context.getElementsByTagName( tag );
+
+ // DocumentFragment nodes don't have gEBTN
+ } else if ( support.qsa ) {
+ return context.querySelectorAll( tag );
+ }
+ } :
+
+ function( tag, context ) {
+ var elem,
+ tmp = [],
+ i = 0,
+ // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
+ results = context.getElementsByTagName( tag );
+
+ // Filter out possible comments
+ if ( tag === "*" ) {
+ while ( (elem = results[i++]) ) {
+ if ( elem.nodeType === 1 ) {
+ tmp.push( elem );
+ }
+ }
+
+ return tmp;
+ }
+ return results;
+ };
+
+ // Class
+ Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
+ if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
+ return context.getElementsByClassName( className );
+ }
+ };
+
+ /* QSA/matchesSelector
+ ---------------------------------------------------------------------- */
+
+ // QSA and matchesSelector support
+
+ // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
+ rbuggyMatches = [];
+
+ // qSa(:focus) reports false when true (Chrome 21)
+ // We allow this because of a bug in IE8/9 that throws an error
+ // whenever `document.activeElement` is accessed on an iframe
+ // So, we allow :focus to pass through QSA all the time to avoid the IE error
+ // See https://bugs.jquery.com/ticket/13378
+ rbuggyQSA = [];
+
+ if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
+ // Build QSA regex
+ // Regex strategy adopted from Diego Perini
+ assert(function( el ) {
+ // Select is set to empty string on purpose
+ // This is to test IE's treatment of not explicitly
+ // setting a boolean content attribute,
+ // since its presence should be enough
+ // https://bugs.jquery.com/ticket/12359
+ docElem.appendChild( el ).innerHTML = "<a id='" + expando + "'></a>" +
+ "<select id='" + expando + "-\r\\' msallowcapture=''>" +
+ "<option selected=''></option></select>";
+
+ // Support: IE8, Opera 11-12.16
+ // Nothing should be selected when empty strings follow ^= or $= or *=
+ // The test attribute must be unknown in Opera but "safe" for WinRT
+ // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
+ if ( el.querySelectorAll("[msallowcapture^='']").length ) {
+ rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
+ }
+
+ // Support: IE8
+ // Boolean attributes and "value" are not treated correctly
+ if ( !el.querySelectorAll("[selected]").length ) {
+ rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
+ }
+
+ // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
+ if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
+ rbuggyQSA.push("~=");
+ }
+
+ // Webkit/Opera - :checked should return selected option elements
+ // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+ // IE8 throws error here and will not see later tests
+ if ( !el.querySelectorAll(":checked").length ) {
+ rbuggyQSA.push(":checked");
+ }
+
+ // Support: Safari 8+, iOS 8+
+ // https://bugs.webkit.org/show_bug.cgi?id=136851
+ // In-page `selector#id sibling-combinator selector` fails
+ if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) {
+ rbuggyQSA.push(".#.+[+~]");
+ }
+ });
+
+ assert(function( el ) {
+ el.innerHTML = "<a href='' disabled='disabled'></a>" +
+ "<select disabled='disabled'><option/></select>";
+
+ // Support: Windows 8 Native Apps
+ // The type and name attributes are restricted during .innerHTML assignment
+ var input = document.createElement("input");
+ input.setAttribute( "type", "hidden" );
+ el.appendChild( input ).setAttribute( "name", "D" );
+
+ // Support: IE8
+ // Enforce case-sensitivity of name attribute
+ if ( el.querySelectorAll("[name=d]").length ) {
+ rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
+ }
+
+ // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
+ // IE8 throws error here and will not see later tests
+ if ( el.querySelectorAll(":enabled").length !== 2 ) {
+ rbuggyQSA.push( ":enabled", ":disabled" );
+ }
+
+ // Support: IE9-11+
+ // IE's :disabled selector does not pick up the children of disabled fieldsets
+ docElem.appendChild( el ).disabled = true;
+ if ( el.querySelectorAll(":disabled").length !== 2 ) {
+ rbuggyQSA.push( ":enabled", ":disabled" );
+ }
+
+ // Opera 10-11 does not throw on post-comma invalid pseudos
+ el.querySelectorAll("*,:x");
+ rbuggyQSA.push(",.*:");
+ });
+ }
+
+ if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
+ docElem.webkitMatchesSelector ||
+ docElem.mozMatchesSelector ||
+ docElem.oMatchesSelector ||
+ docElem.msMatchesSelector) )) ) {
+
+ assert(function( el ) {
+ // Check to see if it's possible to do matchesSelector
+ // on a disconnected node (IE 9)
+ support.disconnectedMatch = matches.call( el, "*" );
+
+ // This should fail with an exception
+ // Gecko does not error, returns false instead
+ matches.call( el, "[s!='']:x" );
+ rbuggyMatches.push( "!=", pseudos );
+ });
+ }
+
+ rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
+ rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
+
+ /* Contains
+ ---------------------------------------------------------------------- */
+ hasCompare = rnative.test( docElem.compareDocumentPosition );
+
+ // Element contains another
+ // Purposefully self-exclusive
+ // As in, an element does not contain itself
+ contains = hasCompare || rnative.test( docElem.contains ) ?
+ function( a, b ) {
+ var adown = a.nodeType === 9 ? a.documentElement : a,
+ bup = b && b.parentNode;
+ return a === bup || !!( bup && bup.nodeType === 1 && (
+ adown.contains ?
+ adown.contains( bup ) :
+ a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
+ ));
+ } :
+ function( a, b ) {
+ if ( b ) {
+ while ( (b = b.parentNode) ) {
+ if ( b === a ) {
+ return true;
+ }
+ }
+ }
+ return false;
+ };
+
+ /* Sorting
+ ---------------------------------------------------------------------- */
+
+ // Document order sorting
+ sortOrder = hasCompare ?
+ function( a, b ) {
+
+ // Flag for duplicate removal
+ if ( a === b ) {
+ hasDuplicate = true;
+ return 0;
+ }
+
+ // Sort on method existence if only one input has compareDocumentPosition
+ var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
+ if ( compare ) {
+ return compare;
+ }
+
+ // Calculate position if both inputs belong to the same document
+ compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
+ a.compareDocumentPosition( b ) :
+
+ // Otherwise we know they are disconnected
+ 1;
+
+ // Disconnected nodes
+ if ( compare & 1 ||
+ (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
+
+ // Choose the first element that is related to our preferred document
+ if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
+ return -1;
+ }
+ if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
+ return 1;
+ }
+
+ // Maintain original order
+ return sortInput ?
+ ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
+ 0;
+ }
+
+ return compare & 4 ? -1 : 1;
+ } :
+ function( a, b ) {
+ // Exit early if the nodes are identical
+ if ( a === b ) {
+ hasDuplicate = true;
+ return 0;
+ }
+
+ var cur,
+ i = 0,
+ aup = a.parentNode,
+ bup = b.parentNode,
+ ap = [ a ],
+ bp = [ b ];
+
+ // Parentless nodes are either documents or disconnected
+ if ( !aup || !bup ) {
+ return a === document ? -1 :
+ b === document ? 1 :
+ aup ? -1 :
+ bup ? 1 :
+ sortInput ?
+ ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
+ 0;
+
+ // If the nodes are siblings, we can do a quick check
+ } else if ( aup === bup ) {
+ return siblingCheck( a, b );
+ }
+
+ // Otherwise we need full lists of their ancestors for comparison
+ cur = a;
+ while ( (cur = cur.parentNode) ) {
+ ap.unshift( cur );
+ }
+ cur = b;
+ while ( (cur = cur.parentNode) ) {
+ bp.unshift( cur );
+ }
+
+ // Walk down the tree looking for a discrepancy
+ while ( ap[i] === bp[i] ) {
+ i++;
+ }
+
+ return i ?
+ // Do a sibling check if the nodes have a common ancestor
+ siblingCheck( ap[i], bp[i] ) :
+
+ // Otherwise nodes in our document sort first
+ ap[i] === preferredDoc ? -1 :
+ bp[i] === preferredDoc ? 1 :
+ 0;
+ };
+
+ return document;
+};
+
+Sizzle.matches = function( expr, elements ) {
+ return Sizzle( expr, null, null, elements );
+};
+
+Sizzle.matchesSelector = function( elem, expr ) {
+ // Set document vars if needed
+ if ( ( elem.ownerDocument || elem ) !== document ) {
+ setDocument( elem );
+ }
+
+ // Make sure that attribute selectors are quoted
+ expr = expr.replace( rattributeQuotes, "='$1']" );
+
+ if ( support.matchesSelector && documentIsHTML &&
+ !compilerCache[ expr + " " ] &&
+ ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
+ ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
+
+ try {
+ var ret = matches.call( elem, expr );
+
+ // IE 9's matchesSelector returns false on disconnected nodes
+ if ( ret || support.disconnectedMatch ||
+ // As well, disconnected nodes are said to be in a document
+ // fragment in IE 9
+ elem.document && elem.document.nodeType !== 11 ) {
+ return ret;
+ }
+ } catch (e) {}
+ }
+
+ return Sizzle( expr, document, null, [ elem ] ).length > 0;
+};
+
+Sizzle.contains = function( context, elem ) {
+ // Set document vars if needed
+ if ( ( context.ownerDocument || context ) !== document ) {
+ setDocument( context );
+ }
+ return contains( context, elem );
+};
+
+Sizzle.attr = function( elem, name ) {
+ // Set document vars if needed
+ if ( ( elem.ownerDocument || elem ) !== document ) {
+ setDocument( elem );
+ }
+
+ var fn = Expr.attrHandle[ name.toLowerCase() ],
+ // Don't get fooled by Object.prototype properties (jQuery #13807)
+ val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
+ fn( elem, name, !documentIsHTML ) :
+ undefined;
+
+ return val !== undefined ?
+ val :
+ support.attributes || !documentIsHTML ?
+ elem.getAttribute( name ) :
+ (val = elem.getAttributeNode(name)) && val.specified ?
+ val.value :
+ null;
+};
+
+Sizzle.escape = function( sel ) {
+ return (sel + "").replace( rcssescape, fcssescape );
+};
+
+Sizzle.error = function( msg ) {
+ throw new Error( "Syntax error, unrecognized expression: " + msg );
+};
+
+/**
+ * Document sorting and removing duplicates
+ * @param {ArrayLike} results
+ */
+Sizzle.uniqueSort = function( results ) {
+ var elem,
+ duplicates = [],
+ j = 0,
+ i = 0;
+
+ // Unless we *know* we can detect duplicates, assume their presence
+ hasDuplicate = !support.detectDuplicates;
+ sortInput = !support.sortStable && results.slice( 0 );
+ results.sort( sortOrder );
+
+ if ( hasDuplicate ) {
+ while ( (elem = results[i++]) ) {
+ if ( elem === results[ i ] ) {
+ j = duplicates.push( i );
+ }
+ }
+ while ( j-- ) {
+ results.splice( duplicates[ j ], 1 );
+ }
+ }
+
+ // Clear input after sorting to release objects
+ // See https://github.com/jquery/sizzle/pull/225
+ sortInput = null;
+
+ return results;
+};
+
+/**
+ * Utility function for retrieving the text value of an array of DOM nodes
+ * @param {Array|Element} elem
+ */
+getText = Sizzle.getText = function( elem ) {
+ var node,
+ ret = "",
+ i = 0,
+ nodeType = elem.nodeType;
+
+ if ( !nodeType ) {
+ // If no nodeType, this is expected to be an array
+ while ( (node = elem[i++]) ) {
+ // Do not traverse comment nodes
+ ret += getText( node );
+ }
+ } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
+ // Use textContent for elements
+ // innerText usage removed for consistency of new lines (jQuery #11153)
+ if ( typeof elem.textContent === "string" ) {
+ return elem.textContent;
+ } else {
+ // Traverse its children
+ for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
+ ret += getText( elem );
+ }
+ }
+ } else if ( nodeType === 3 || nodeType === 4 ) {
+ return elem.nodeValue;
+ }
+ // Do not include comment or processing instruction nodes
+
+ return ret;
+};
+
+Expr = Sizzle.selectors = {
+
+ // Can be adjusted by the user
+ cacheLength: 50,
+
+ createPseudo: markFunction,
+
+ match: matchExpr,
+
+ attrHandle: {},
+
+ find: {},
+
+ relative: {
+ ">": { dir: "parentNode", first: true },
+ " ": { dir: "parentNode" },
+ "+": { dir: "previousSibling", first: true },
+ "~": { dir: "previousSibling" }
+ },
+
+ preFilter: {
+ "ATTR": function( match ) {
+ match[1] = match[1].replace( runescape, funescape );
+
+ // Move the given value to match[3] whether quoted or unquoted
+ match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
+
+ if ( match[2] === "~=" ) {
+ match[3] = " " + match[3] + " ";
+ }
+
+ return match.slice( 0, 4 );
+ },
+
+ "CHILD": function( match ) {
+ /* matches from matchExpr["CHILD"]
+ 1 type (only|nth|...)
+ 2 what (child|of-type)
+ 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
+ 4 xn-component of xn+y argument ([+-]?\d*n|)
+ 5 sign of xn-component
+ 6 x of xn-component
+ 7 sign of y-component
+ 8 y of y-component
+ */
+ match[1] = match[1].toLowerCase();
+
+ if ( match[1].slice( 0, 3 ) === "nth" ) {
+ // nth-* requires argument
+ if ( !match[3] ) {
+ Sizzle.error( match[0] );
+ }
+
+ // numeric x and y parameters for Expr.filter.CHILD
+ // remember that false/true cast respectively to 0/1
+ match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
+ match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
+
+ // other types prohibit arguments
+ } else if ( match[3] ) {
+ Sizzle.error( match[0] );
+ }
+
+ return match;
+ },
+
+ "PSEUDO": function( match ) {
+ var excess,
+ unquoted = !match[6] && match[2];
+
+ if ( matchExpr["CHILD"].test( match[0] ) ) {
+ return null;
+ }
+
+ // Accept quoted arguments as-is
+ if ( match[3] ) {
+ match[2] = match[4] || match[5] || "";
+
+ // Strip excess characters from unquoted arguments
+ } else if ( unquoted && rpseudo.test( unquoted ) &&
+ // Get excess from tokenize (recursively)
+ (excess = tokenize( unquoted, true )) &&
+ // advance to the next closing parenthesis
+ (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
+
+ // excess is a negative index
+ match[0] = match[0].slice( 0, excess );
+ match[2] = unquoted.slice( 0, excess );
+ }
+
+ // Return only captures needed by the pseudo filter method (type and argument)
+ return match.slice( 0, 3 );
+ }
+ },
+
+ filter: {
+
+ "TAG": function( nodeNameSelector ) {
+ var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
+ return nodeNameSelector === "*" ?
+ function() { return true; } :
+ function( elem ) {
+ return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
+ };
+ },
+
+ "CLASS": function( className ) {
+ var pattern = classCache[ className + " " ];
+
+ return pattern ||
+ (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
+ classCache( className, function( elem ) {
+ return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
+ });
+ },
+
+ "ATTR": function( name, operator, check ) {
+ return function( elem ) {
+ var result = Sizzle.attr( elem, name );
+
+ if ( result == null ) {
+ return operator === "!=";
+ }
+ if ( !operator ) {
+ return true;
+ }
+
+ result += "";
+
+ return operator === "=" ? result === check :
+ operator === "!=" ? result !== check :
+ operator === "^=" ? check && result.indexOf( check ) === 0 :
+ operator === "*=" ? check && result.indexOf( check ) > -1 :
+ operator === "$=" ? check && result.slice( -check.length ) === check :
+ operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
+ operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
+ false;
+ };
+ },
+
+ "CHILD": function( type, what, argument, first, last ) {
+ var simple = type.slice( 0, 3 ) !== "nth",
+ forward = type.slice( -4 ) !== "last",
+ ofType = what === "of-type";
+
+ return first === 1 && last === 0 ?
+
+ // Shortcut for :nth-*(n)
+ function( elem ) {
+ return !!elem.parentNode;
+ } :
+
+ function( elem, context, xml ) {
+ var cache, uniqueCache, outerCache, node, nodeIndex, start,
+ dir = simple !== forward ? "nextSibling" : "previousSibling",
+ parent = elem.parentNode,
+ name = ofType && elem.nodeName.toLowerCase(),
+ useCache = !xml && !ofType,
+ diff = false;
+
+ if ( parent ) {
+
+ // :(first|last|only)-(child|of-type)
+ if ( simple ) {
+ while ( dir ) {
+ node = elem;
+ while ( (node = node[ dir ]) ) {
+ if ( ofType ?
+ node.nodeName.toLowerCase() === name :
+ node.nodeType === 1 ) {
+
+ return false;
+ }
+ }
+ // Reverse direction for :only-* (if we haven't yet done so)
+ start = dir = type === "only" && !start && "nextSibling";
+ }
+ return true;
+ }
+
+ start = [ forward ? parent.firstChild : parent.lastChild ];
+
+ // non-xml :nth-child(...) stores cache data on `parent`
+ if ( forward && useCache ) {
+
+ // Seek `elem` from a previously-cached index
+
+ // ...in a gzip-friendly way
+ node = parent;
+ outerCache = node[ expando ] || (node[ expando ] = {});
+
+ // Support: IE <9 only
+ // Defend against cloned attroperties (jQuery gh-1709)
+ uniqueCache = outerCache[ node.uniqueID ] ||
+ (outerCache[ node.uniqueID ] = {});
+
+ cache = uniqueCache[ type ] || [];
+ nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
+ diff = nodeIndex && cache[ 2 ];
+ node = nodeIndex && parent.childNodes[ nodeIndex ];
+
+ while ( (node = ++nodeIndex && node && node[ dir ] ||
+
+ // Fallback to seeking `elem` from the start
+ (diff = nodeIndex = 0) || start.pop()) ) {
+
+ // When found, cache indexes on `parent` and break
+ if ( node.nodeType === 1 && ++diff && node === elem ) {
+ uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
+ break;
+ }
+ }
+
+ } else {
+ // Use previously-cached element index if available
+ if ( useCache ) {
+ // ...in a gzip-friendly way
+ node = elem;
+ outerCache = node[ expando ] || (node[ expando ] = {});
+
+ // Support: IE <9 only
+ // Defend against cloned attroperties (jQuery gh-1709)
+ uniqueCache = outerCache[ node.uniqueID ] ||
+ (outerCache[ node.uniqueID ] = {});
+
+ cache = uniqueCache[ type ] || [];
+ nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
+ diff = nodeIndex;
+ }
+
+ // xml :nth-child(...)
+ // or :nth-last-child(...) or :nth(-last)?-of-type(...)
+ if ( diff === false ) {
+ // Use the same loop as above to seek `elem` from the start
+ while ( (node = ++nodeIndex && node && node[ dir ] ||
+ (diff = nodeIndex = 0) || start.pop()) ) {
+
+ if ( ( ofType ?
+ node.nodeName.toLowerCase() === name :
+ node.nodeType === 1 ) &&
+ ++diff ) {
+
+ // Cache the index of each encountered element
+ if ( useCache ) {
+ outerCache = node[ expando ] || (node[ expando ] = {});
+
+ // Support: IE <9 only
+ // Defend against cloned attroperties (jQuery gh-1709)
+ uniqueCache = outerCache[ node.uniqueID ] ||
+ (outerCache[ node.uniqueID ] = {});
+
+ uniqueCache[ type ] = [ dirruns, diff ];
+ }
+
+ if ( node === elem ) {
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ // Incorporate the offset, then check against cycle size
+ diff -= last;
+ return diff === first || ( diff % first === 0 && diff / first >= 0 );
+ }
+ };
+ },
+
+ "PSEUDO": function( pseudo, argument ) {
+ // pseudo-class names are case-insensitive
+ // http://www.w3.org/TR/selectors/#pseudo-classes
+ // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
+ // Remember that setFilters inherits from pseudos
+ var args,
+ fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
+ Sizzle.error( "unsupported pseudo: " + pseudo );
+
+ // The user may use createPseudo to indicate that
+ // arguments are needed to create the filter function
+ // just as Sizzle does
+ if ( fn[ expando ] ) {
+ return fn( argument );
+ }
+
+ // But maintain support for old signatures
+ if ( fn.length > 1 ) {
+ args = [ pseudo, pseudo, "", argument ];
+ return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
+ markFunction(function( seed, matches ) {
+ var idx,
+ matched = fn( seed, argument ),
+ i = matched.length;
+ while ( i-- ) {
+ idx = indexOf( seed, matched[i] );
+ seed[ idx ] = !( matches[ idx ] = matched[i] );
+ }
+ }) :
+ function( elem ) {
+ return fn( elem, 0, args );
+ };
+ }
+
+ return fn;
+ }
+ },
+
+ pseudos: {
+ // Potentially complex pseudos
+ "not": markFunction(function( selector ) {
+ // Trim the selector passed to compile
+ // to avoid treating leading and trailing
+ // spaces as combinators
+ var input = [],
+ results = [],
+ matcher = compile( selector.replace( rtrim, "$1" ) );
+
+ return matcher[ expando ] ?
+ markFunction(function( seed, matches, context, xml ) {
+ var elem,
+ unmatched = matcher( seed, null, xml, [] ),
+ i = seed.length;
+
+ // Match elements unmatched by `matcher`
+ while ( i-- ) {
+ if ( (elem = unmatched[i]) ) {
+ seed[i] = !(matches[i] = elem);
+ }
+ }
+ }) :
+ function( elem, context, xml ) {
+ input[0] = elem;
+ matcher( input, null, xml, results );
+ // Don't keep the element (issue #299)
+ input[0] = null;
+ return !results.pop();
+ };
+ }),
+
+ "has": markFunction(function( selector ) {
+ return function( elem ) {
+ return Sizzle( selector, elem ).length > 0;
+ };
+ }),
+
+ "contains": markFunction(function( text ) {
+ text = text.replace( runescape, funescape );
+ return function( elem ) {
+ return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
+ };
+ }),
+
+ // "Whether an element is represented by a :lang() selector
+ // is based solely on the element's language value
+ // being equal to the identifier C,
+ // or beginning with the identifier C immediately followed by "-".
+ // The matching of C against the element's language value is performed case-insensitively.
+ // The identifier C does not have to be a valid language name."
+ // http://www.w3.org/TR/selectors/#lang-pseudo
+ "lang": markFunction( function( lang ) {
+ // lang value must be a valid identifier
+ if ( !ridentifier.test(lang || "") ) {
+ Sizzle.error( "unsupported lang: " + lang );
+ }
+ lang = lang.replace( runescape, funescape ).toLowerCase();
+ return function( elem ) {
+ var elemLang;
+ do {
+ if ( (elemLang = documentIsHTML ?
+ elem.lang :
+ elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
+
+ elemLang = elemLang.toLowerCase();
+ return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
+ }
+ } while ( (elem = elem.parentNode) && elem.nodeType === 1 );
+ return false;
+ };
+ }),
+
+ // Miscellaneous
+ "target": function( elem ) {
+ var hash = window.location && window.location.hash;
+ return hash && hash.slice( 1 ) === elem.id;
+ },
+
+ "root": function( elem ) {
+ return elem === docElem;
+ },
+
+ "focus": function( elem ) {
+ return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
+ },
+
+ // Boolean properties
+ "enabled": createDisabledPseudo( false ),
+ "disabled": createDisabledPseudo( true ),
+
+ "checked": function( elem ) {
+ // In CSS3, :checked should return both checked and selected elements
+ // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+ var nodeName = elem.nodeName.toLowerCase();
+ return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
+ },
+
+ "selected": function( elem ) {
+ // Accessing this property makes selected-by-default
+ // options in Safari work properly
+ if ( elem.parentNode ) {
+ elem.parentNode.selectedIndex;
+ }
+
+ return elem.selected === true;
+ },
+
+ // Contents
+ "empty": function( elem ) {
+ // http://www.w3.org/TR/selectors/#empty-pseudo
+ // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
+ // but not by others (comment: 8; processing instruction: 7; etc.)
+ // nodeType < 6 works because attributes (2) do not appear as children
+ for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
+ if ( elem.nodeType < 6 ) {
+ return false;
+ }
+ }
+ return true;
+ },
+
+ "parent": function( elem ) {
+ return !Expr.pseudos["empty"]( elem );
+ },
+
+ // Element/input types
+ "header": function( elem ) {
+ return rheader.test( elem.nodeName );
+ },
+
+ "input": function( elem ) {
+ return rinputs.test( elem.nodeName );
+ },
+
+ "button": function( elem ) {
+ var name = elem.nodeName.toLowerCase();
+ return name === "input" && elem.type === "button" || name === "button";
+ },
+
+ "text": function( elem ) {
+ var attr;
+ return elem.nodeName.toLowerCase() === "input" &&
+ elem.type === "text" &&
+
+ // Support: IE<8
+ // New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
+ ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
+ },
+
+ // Position-in-collection
+ "first": createPositionalPseudo(function() {
+ return [ 0 ];
+ }),
+
+ "last": createPositionalPseudo(function( matchIndexes, length ) {
+ return [ length - 1 ];
+ }),
+
+ "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
+ return [ argument < 0 ? argument + length : argument ];
+ }),
+
+ "even": createPositionalPseudo(function( matchIndexes, length ) {
+ var i = 0;
+ for ( ; i < length; i += 2 ) {
+ matchIndexes.push( i );
+ }
+ return matchIndexes;
+ }),
+
+ "odd": createPositionalPseudo(function( matchIndexes, length ) {
+ var i = 1;
+ for ( ; i < length; i += 2 ) {
+ matchIndexes.push( i );
+ }
+ return matchIndexes;
+ }),
+
+ "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
+ var i = argument < 0 ? argument + length : argument;
+ for ( ; --i >= 0; ) {
+ matchIndexes.push( i );
+ }
+ return matchIndexes;
+ }),
+
+ "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
+ var i = argument < 0 ? argument + length : argument;
+ for ( ; ++i < length; ) {
+ matchIndexes.push( i );
+ }
+ return matchIndexes;
+ })
+ }
+};
+
+Expr.pseudos["nth"] = Expr.pseudos["eq"];
+
+// Add button/input type pseudos
+for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
+ Expr.pseudos[ i ] = createInputPseudo( i );
+}
+for ( i in { submit: true, reset: true } ) {
+ Expr.pseudos[ i ] = createButtonPseudo( i );
+}
+
+// Easy API for creating new setFilters
+function setFilters() {}
+setFilters.prototype = Expr.filters = Expr.pseudos;
+Expr.setFilters = new setFilters();
+
+tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
+ var matched, match, tokens, type,
+ soFar, groups, preFilters,
+ cached = tokenCache[ selector + " " ];
+
+ if ( cached ) {
+ return parseOnly ? 0 : cached.slice( 0 );
+ }
+
+ soFar = selector;
+ groups = [];
+ preFilters = Expr.preFilter;
+
+ while ( soFar ) {
+
+ // Comma and first run
+ if ( !matched || (match = rcomma.exec( soFar )) ) {
+ if ( match ) {
+ // Don't consume trailing commas as valid
+ soFar = soFar.slice( match[0].length ) || soFar;
+ }
+ groups.push( (tokens = []) );
+ }
+
+ matched = false;
+
+ // Combinators
+ if ( (match = rcombinators.exec( soFar )) ) {
+ matched = match.shift();
+ tokens.push({
+ value: matched,
+ // Cast descendant combinators to space
+ type: match[0].replace( rtrim, " " )
+ });
+ soFar = soFar.slice( matched.length );
+ }
+
+ // Filters
+ for ( type in Expr.filter ) {
+ if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
+ (match = preFilters[ type ]( match ))) ) {
+ matched = match.shift();
+ tokens.push({
+ value: matched,
+ type: type,
+ matches: match
+ });
+ soFar = soFar.slice( matched.length );
+ }
+ }
+
+ if ( !matched ) {
+ break;
+ }
+ }
+
+ // Return the length of the invalid excess
+ // if we're just parsing
+ // Otherwise, throw an error or return tokens
+ return parseOnly ?
+ soFar.length :
+ soFar ?
+ Sizzle.error( selector ) :
+ // Cache the tokens
+ tokenCache( selector, groups ).slice( 0 );
+};
+
+function toSelector( tokens ) {
+ var i = 0,
+ len = tokens.length,
+ selector = "";
+ for ( ; i < len; i++ ) {
+ selector += tokens[i].value;
+ }
+ return selector;
+}
+
+function addCombinator( matcher, combinator, base ) {
+ var dir = combinator.dir,
+ skip = combinator.next,
+ key = skip || dir,
+ checkNonElements = base && key === "parentNode",
+ doneName = done++;
+
+ return combinator.first ?
+ // Check against closest ancestor/preceding element
+ function( elem, context, xml ) {
+ while ( (elem = elem[ dir ]) ) {
+ if ( elem.nodeType === 1 || checkNonElements ) {
+ return matcher( elem, context, xml );
+ }
+ }
+ return false;
+ } :
+
+ // Check against all ancestor/preceding elements
+ function( elem, context, xml ) {
+ var oldCache, uniqueCache, outerCache,
+ newCache = [ dirruns, doneName ];
+
+ // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
+ if ( xml ) {
+ while ( (elem = elem[ dir ]) ) {
+ if ( elem.nodeType === 1 || checkNonElements ) {
+ if ( matcher( elem, context, xml ) ) {
+ return true;
+ }
+ }
+ }
+ } else {
+ while ( (elem = elem[ dir ]) ) {
+ if ( elem.nodeType === 1 || checkNonElements ) {
+ outerCache = elem[ expando ] || (elem[ expando ] = {});
+
+ // Support: IE <9 only
+ // Defend against cloned attroperties (jQuery gh-1709)
+ uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});
+
+ if ( skip && skip === elem.nodeName.toLowerCase() ) {
+ elem = elem[ dir ] || elem;
+ } else if ( (oldCache = uniqueCache[ key ]) &&
+ oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
+
+ // Assign to newCache so results back-propagate to previous elements
+ return (newCache[ 2 ] = oldCache[ 2 ]);
+ } else {
+ // Reuse newcache so results back-propagate to previous elements
+ uniqueCache[ key ] = newCache;
+
+ // A match means we're done; a fail means we have to keep checking
+ if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+ };
+}
+
+function elementMatcher( matchers ) {
+ return matchers.length > 1 ?
+ function( elem, context, xml ) {
+ var i = matchers.length;
+ while ( i-- ) {
+ if ( !matchers[i]( elem, context, xml ) ) {
+ return false;
+ }
+ }
+ return true;
+ } :
+ matchers[0];
+}
+
+function multipleContexts( selector, contexts, results ) {
+ var i = 0,
+ len = contexts.length;
+ for ( ; i < len; i++ ) {
+ Sizzle( selector, contexts[i], results );
+ }
+ return results;
+}
+
+function condense( unmatched, map, filter, context, xml ) {
+ var elem,
+ newUnmatched = [],
+ i = 0,
+ len = unmatched.length,
+ mapped = map != null;
+
+ for ( ; i < len; i++ ) {
+ if ( (elem = unmatched[i]) ) {
+ if ( !filter || filter( elem, context, xml ) ) {
+ newUnmatched.push( elem );
+ if ( mapped ) {
+ map.push( i );
+ }
+ }
+ }
+ }
+
+ return newUnmatched;
+}
+
+function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
+ if ( postFilter && !postFilter[ expando ] ) {
+ postFilter = setMatcher( postFilter );
+ }
+ if ( postFinder && !postFinder[ expando ] ) {
+ postFinder = setMatcher( postFinder, postSelector );
+ }
+ return markFunction(function( seed, results, context, xml ) {
+ var temp, i, elem,
+ preMap = [],
+ postMap = [],
+ preexisting = results.length,
+
+ // Get initial elements from seed or context
+ elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
+
+ // Prefilter to get matcher input, preserving a map for seed-results synchronization
+ matcherIn = preFilter && ( seed || !selector ) ?
+ condense( elems, preMap, preFilter, context, xml ) :
+ elems,
+
+ matcherOut = matcher ?
+ // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
+ postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
+
+ // ...intermediate processing is necessary
+ [] :
+
+ // ...otherwise use results directly
+ results :
+ matcherIn;
+
+ // Find primary matches
+ if ( matcher ) {
+ matcher( matcherIn, matcherOut, context, xml );
+ }
+
+ // Apply postFilter
+ if ( postFilter ) {
+ temp = condense( matcherOut, postMap );
+ postFilter( temp, [], context, xml );
+
+ // Un-match failing elements by moving them back to matcherIn
+ i = temp.length;
+ while ( i-- ) {
+ if ( (elem = temp[i]) ) {
+ matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
+ }
+ }
+ }
+
+ if ( seed ) {
+ if ( postFinder || preFilter ) {
+ if ( postFinder ) {
+ // Get the final matcherOut by condensing this intermediate into postFinder contexts
+ temp = [];
+ i = matcherOut.length;
+ while ( i-- ) {
+ if ( (elem = matcherOut[i]) ) {
+ // Restore matcherIn since elem is not yet a final match
+ temp.push( (matcherIn[i] = elem) );
+ }
+ }
+ postFinder( null, (matcherOut = []), temp, xml );
+ }
+
+ // Move matched elements from seed to results to keep them synchronized
+ i = matcherOut.length;
+ while ( i-- ) {
+ if ( (elem = matcherOut[i]) &&
+ (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
+
+ seed[temp] = !(results[temp] = elem);
+ }
+ }
+ }
+
+ // Add elements to results, through postFinder if defined
+ } else {
+ matcherOut = condense(
+ matcherOut === results ?
+ matcherOut.splice( preexisting, matcherOut.length ) :
+ matcherOut
+ );
+ if ( postFinder ) {
+ postFinder( null, results, matcherOut, xml );
+ } else {
+ push.apply( results, matcherOut );
+ }
+ }
+ });
+}
+
+function matcherFromTokens( tokens ) {
+ var checkContext, matcher, j,
+ len = tokens.length,
+ leadingRelative = Expr.relative[ tokens[0].type ],
+ implicitRelative = leadingRelative || Expr.relative[" "],
+ i = leadingRelative ? 1 : 0,
+
+ // The foundational matcher ensures that elements are reachable from top-level context(s)
+ matchContext = addCombinator( function( elem ) {
+ return elem === checkContext;
+ }, implicitRelative, true ),
+ matchAnyContext = addCombinator( function( elem ) {
+ return indexOf( checkContext, elem ) > -1;
+ }, implicitRelative, true ),
+ matchers = [ function( elem, context, xml ) {
+ var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
+ (checkContext = context).nodeType ?
+ matchContext( elem, context, xml ) :
+ matchAnyContext( elem, context, xml ) );
+ // Avoid hanging onto element (issue #299)
+ checkContext = null;
+ return ret;
+ } ];
+
+ for ( ; i < len; i++ ) {
+ if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
+ matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
+ } else {
+ matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
+
+ // Return special upon seeing a positional matcher
+ if ( matcher[ expando ] ) {
+ // Find the next relative operator (if any) for proper handling
+ j = ++i;
+ for ( ; j < len; j++ ) {
+ if ( Expr.relative[ tokens[j].type ] ) {
+ break;
+ }
+ }
+ return setMatcher(
+ i > 1 && elementMatcher( matchers ),
+ i > 1 && toSelector(
+ // If the preceding token was a descendant combinator, insert an implicit any-element `*`
+ tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
+ ).replace( rtrim, "$1" ),
+ matcher,
+ i < j && matcherFromTokens( tokens.slice( i, j ) ),
+ j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
+ j < len && toSelector( tokens )
+ );
+ }
+ matchers.push( matcher );
+ }
+ }
+
+ return elementMatcher( matchers );
+}
+
+function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
+ var bySet = setMatchers.length > 0,
+ byElement = elementMatchers.length > 0,
+ superMatcher = function( seed, context, xml, results, outermost ) {
+ var elem, j, matcher,
+ matchedCount = 0,
+ i = "0",
+ unmatched = seed && [],
+ setMatched = [],
+ contextBackup = outermostContext,
+ // We must always have either seed elements or outermost context
+ elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
+ // Use integer dirruns iff this is the outermost matcher
+ dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
+ len = elems.length;
+
+ if ( outermost ) {
+ outermostContext = context === document || context || outermost;
+ }
+
+ // Add elements passing elementMatchers directly to results
+ // Support: IE<9, Safari
+ // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
+ for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
+ if ( byElement && elem ) {
+ j = 0;
+ if ( !context && elem.ownerDocument !== document ) {
+ setDocument( elem );
+ xml = !documentIsHTML;
+ }
+ while ( (matcher = elementMatchers[j++]) ) {
+ if ( matcher( elem, context || document, xml) ) {
+ results.push( elem );
+ break;
+ }
+ }
+ if ( outermost ) {
+ dirruns = dirrunsUnique;
+ }
+ }
+
+ // Track unmatched elements for set filters
+ if ( bySet ) {
+ // They will have gone through all possible matchers
+ if ( (elem = !matcher && elem) ) {
+ matchedCount--;
+ }
+
+ // Lengthen the array for every element, matched or not
+ if ( seed ) {
+ unmatched.push( elem );
+ }
+ }
+ }
+
+ // `i` is now the count of elements visited above, and adding it to `matchedCount`
+ // makes the latter nonnegative.
+ matchedCount += i;
+
+ // Apply set filters to unmatched elements
+ // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
+ // equals `i`), unless we didn't visit _any_ elements in the above loop because we have
+ // no element matchers and no seed.
+ // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
+ // case, which will result in a "00" `matchedCount` that differs from `i` but is also
+ // numerically zero.
+ if ( bySet && i !== matchedCount ) {
+ j = 0;
+ while ( (matcher = setMatchers[j++]) ) {
+ matcher( unmatched, setMatched, context, xml );
+ }
+
+ if ( seed ) {
+ // Reintegrate element matches to eliminate the need for sorting
+ if ( matchedCount > 0 ) {
+ while ( i-- ) {
+ if ( !(unmatched[i] || setMatched[i]) ) {
+ setMatched[i] = pop.call( results );
+ }
+ }
+ }
+
+ // Discard index placeholder values to get only actual matches
+ setMatched = condense( setMatched );
+ }
+
+ // Add matches to results
+ push.apply( results, setMatched );
+
+ // Seedless set matches succeeding multiple successful matchers stipulate sorting
+ if ( outermost && !seed && setMatched.length > 0 &&
+ ( matchedCount + setMatchers.length ) > 1 ) {
+
+ Sizzle.uniqueSort( results );
+ }
+ }
+
+ // Override manipulation of globals by nested matchers
+ if ( outermost ) {
+ dirruns = dirrunsUnique;
+ outermostContext = contextBackup;
+ }
+
+ return unmatched;
+ };
+
+ return bySet ?
+ markFunction( superMatcher ) :
+ superMatcher;
+}
+
+compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
+ var i,
+ setMatchers = [],
+ elementMatchers = [],
+ cached = compilerCache[ selector + " " ];
+
+ if ( !cached ) {
+ // Generate a function of recursive functions that can be used to check each element
+ if ( !match ) {
+ match = tokenize( selector );
+ }
+ i = match.length;
+ while ( i-- ) {
+ cached = matcherFromTokens( match[i] );
+ if ( cached[ expando ] ) {
+ setMatchers.push( cached );
+ } else {
+ elementMatchers.push( cached );
+ }
+ }
+
+ // Cache the compiled function
+ cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
+
+ // Save selector and tokenization
+ cached.selector = selector;
+ }
+ return cached;
+};
+
+/**
+ * A low-level selection function that works with Sizzle's compiled
+ * selector functions
+ * @param {String|Function} selector A selector or a pre-compiled
+ * selector function built with Sizzle.compile
+ * @param {Element} context
+ * @param {Array} [results]
+ * @param {Array} [seed] A set of elements to match against
+ */
+select = Sizzle.select = function( selector, context, results, seed ) {
+ var i, tokens, token, type, find,
+ compiled = typeof selector === "function" && selector,
+ match = !seed && tokenize( (selector = compiled.selector || selector) );
+
+ results = results || [];
+
+ // Try to minimize operations if there is only one selector in the list and no seed
+ // (the latter of which guarantees us context)
+ if ( match.length === 1 ) {
+
+ // Reduce context if the leading compound selector is an ID
+ tokens = match[0] = match[0].slice( 0 );
+ if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
+ context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) {
+
+ context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
+ if ( !context ) {
+ return results;
+
+ // Precompiled matchers will still verify ancestry, so step up a level
+ } else if ( compiled ) {
+ context = context.parentNode;
+ }
+
+ selector = selector.slice( tokens.shift().value.length );
+ }
+
+ // Fetch a seed set for right-to-left matching
+ i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
+ while ( i-- ) {
+ token = tokens[i];
+
+ // Abort if we hit a combinator
+ if ( Expr.relative[ (type = token.type) ] ) {
+ break;
+ }
+ if ( (find = Expr.find[ type ]) ) {
+ // Search, expanding context for leading sibling combinators
+ if ( (seed = find(
+ token.matches[0].replace( runescape, funescape ),
+ rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
+ )) ) {
+
+ // If seed is empty or no tokens remain, we can return early
+ tokens.splice( i, 1 );
+ selector = seed.length && toSelector( tokens );
+ if ( !selector ) {
+ push.apply( results, seed );
+ return results;
+ }
+
+ break;
+ }
+ }
+ }
+ }
+
+ // Compile and execute a filtering function if one is not provided
+ // Provide `match` to avoid retokenization if we modified the selector above
+ ( compiled || compile( selector, match ) )(
+ seed,
+ context,
+ !documentIsHTML,
+ results,
+ !context || rsibling.test( selector ) && testContext( context.parentNode ) || context
+ );
+ return results;
+};
+
+// One-time assignments
+
+// Sort stability
+support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
+
+// Support: Chrome 14-35+
+// Always assume duplicates if they aren't passed to the comparison function
+support.detectDuplicates = !!hasDuplicate;
+
+// Initialize against the default document
+setDocument();
+
+// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
+// Detached nodes confoundingly follow *each other*
+support.sortDetached = assert(function( el ) {
+ // Should return 1, but returns 4 (following)
+ return el.compareDocumentPosition( document.createElement("fieldset") ) & 1;
+});
+
+// Support: IE<8
+// Prevent attribute/property "interpolation"
+// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
+if ( !assert(function( el ) {
+ el.innerHTML = "<a href='#'></a>";
+ return el.firstChild.getAttribute("href") === "#" ;
+}) ) {
+ addHandle( "type|href|height|width", function( elem, name, isXML ) {
+ if ( !isXML ) {
+ return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
+ }
+ });
+}
+
+// Support: IE<9
+// Use defaultValue in place of getAttribute("value")
+if ( !support.attributes || !assert(function( el ) {
+ el.innerHTML = "<input/>";
+ el.firstChild.setAttribute( "value", "" );
+ return el.firstChild.getAttribute( "value" ) === "";
+}) ) {
+ addHandle( "value", function( elem, name, isXML ) {
+ if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
+ return elem.defaultValue;
+ }
+ });
+}
+
+// Support: IE<9
+// Use getAttributeNode to fetch booleans when getAttribute lies
+if ( !assert(function( el ) {
+ return el.getAttribute("disabled") == null;
+}) ) {
+ addHandle( booleans, function( elem, name, isXML ) {
+ var val;
+ if ( !isXML ) {
+ return elem[ name ] === true ? name.toLowerCase() :
+ (val = elem.getAttributeNode( name )) && val.specified ?
+ val.value :
+ null;
+ }
+ });
+}
+
+return Sizzle;
+
+})( window );
+
+
+
+jQuery.find = Sizzle;
+jQuery.expr = Sizzle.selectors;
+
+// Deprecated
+jQuery.expr[ ":" ] = jQuery.expr.pseudos;
+jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
+jQuery.text = Sizzle.getText;
+jQuery.isXMLDoc = Sizzle.isXML;
+jQuery.contains = Sizzle.contains;
+jQuery.escapeSelector = Sizzle.escape;
+
+
+
+
+var dir = function( elem, dir, until ) {
+ var matched = [],
+ truncate = until !== undefined;
+
+ while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
+ if ( elem.nodeType === 1 ) {
+ if ( truncate && jQuery( elem ).is( until ) ) {
+ break;
+ }
+ matched.push( elem );
+ }
+ }
+ return matched;
+};
+
+
+var siblings = function( n, elem ) {
+ var matched = [];
+
+ for ( ; n; n = n.nextSibling ) {
+ if ( n.nodeType === 1 && n !== elem ) {
+ matched.push( n );
+ }
+ }
+
+ return matched;
+};
+
+
+var rneedsContext = jQuery.expr.match.needsContext;
+
+
+
+function nodeName( elem, name ) {
+
+ return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
+
+};
+var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i );
+
+
+
+var risSimple = /^.[^:#\[\.,]*$/;
+
+// Implement the identical functionality for filter and not
+function winnow( elements, qualifier, not ) {
+ if ( jQuery.isFunction( qualifier ) ) {
+ return jQuery.grep( elements, function( elem, i ) {
+ return !!qualifier.call( elem, i, elem ) !== not;
+ } );
+ }
+
+ // Single element
+ if ( qualifier.nodeType ) {
+ return jQuery.grep( elements, function( elem ) {
+ return ( elem === qualifier ) !== not;
+ } );
+ }
+
+ // Arraylike of elements (jQuery, arguments, Array)
+ if ( typeof qualifier !== "string" ) {
+ return jQuery.grep( elements, function( elem ) {
+ return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
+ } );
+ }
+
+ // Simple selector that can be filtered directly, removing non-Elements
+ if ( risSimple.test( qualifier ) ) {
+ return jQuery.filter( qualifier, elements, not );
+ }
+
+ // Complex selector, compare the two sets, removing non-Elements
+ qualifier = jQuery.filter( qualifier, elements );
+ return jQuery.grep( elements, function( elem ) {
+ return ( indexOf.call( qualifier, elem ) > -1 ) !== not && elem.nodeType === 1;
+ } );
+}
+
+jQuery.filter = function( expr, elems, not ) {
+ var elem = elems[ 0 ];
+
+ if ( not ) {
+ expr = ":not(" + expr + ")";
+ }
+
+ if ( elems.length === 1 && elem.nodeType === 1 ) {
+ return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];
+ }
+
+ return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
+ return elem.nodeType === 1;
+ } ) );
+};
+
+jQuery.fn.extend( {
+ find: function( selector ) {
+ var i, ret,
+ len = this.length,
+ self = this;
+
+ if ( typeof selector !== "string" ) {
+ return this.pushStack( jQuery( selector ).filter( function() {
+ for ( i = 0; i < len; i++ ) {
+ if ( jQuery.contains( self[ i ], this ) ) {
+ return true;
+ }
+ }
+ } ) );
+ }
+
+ ret = this.pushStack( [] );
+
+ for ( i = 0; i < len; i++ ) {
+ jQuery.find( selector, self[ i ], ret );
+ }
+
+ return len > 1 ? jQuery.uniqueSort( ret ) : ret;
+ },
+ filter: function( selector ) {
+ return this.pushStack( winnow( this, selector || [], false ) );
+ },
+ not: function( selector ) {
+ return this.pushStack( winnow( this, selector || [], true ) );
+ },
+ is: function( selector ) {
+ return !!winnow(
+ this,
+
+ // If this is a positional/relative selector, check membership in the returned set
+ // so $("p:first").is("p:last") won't return true for a doc with two "p".
+ typeof selector === "string" && rneedsContext.test( selector ) ?
+ jQuery( selector ) :
+ selector || [],
+ false
+ ).length;
+ }
+} );
+
+
+// Initialize a jQuery object
+
+
+// A central reference to the root jQuery(document)
+var rootjQuery,
+
+ // A simple way to check for HTML strings
+ // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
+ // Strict HTML recognition (#11290: must start with <)
+ // Shortcut simple #id case for speed
+ rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,
+
+ init = jQuery.fn.init = function( selector, context, root ) {
+ var match, elem;
+
+ // HANDLE: $(""), $(null), $(undefined), $(false)
+ if ( !selector ) {
+ return this;
+ }
+
+ // Method init() accepts an alternate rootjQuery
+ // so migrate can support jQuery.sub (gh-2101)
+ root = root || rootjQuery;
+
+ // Handle HTML strings
+ if ( typeof selector === "string" ) {
+ if ( selector[ 0 ] === "<" &&
+ selector[ selector.length - 1 ] === ">" &&
+ selector.length >= 3 ) {
+
+ // Assume that strings that start and end with <> are HTML and skip the regex check
+ match = [ null, selector, null ];
+
+ } else {
+ match = rquickExpr.exec( selector );
+ }
+
+ // Match html or make sure no context is specified for #id
+ if ( match && ( match[ 1 ] || !context ) ) {
+
+ // HANDLE: $(html) -> $(array)
+ if ( match[ 1 ] ) {
+ context = context instanceof jQuery ? context[ 0 ] : context;
+
+ // Option to run scripts is true for back-compat
+ // Intentionally let the error be thrown if parseHTML is not present
+ jQuery.merge( this, jQuery.parseHTML(
+ match[ 1 ],
+ context && context.nodeType ? context.ownerDocument || context : document,
+ true
+ ) );
+
+ // HANDLE: $(html, props)
+ if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
+ for ( match in context ) {
+
+ // Properties of context are called as methods if possible
+ if ( jQuery.isFunction( this[ match ] ) ) {
+ this[ match ]( context[ match ] );
+
+ // ...and otherwise set as attributes
+ } else {
+ this.attr( match, context[ match ] );
+ }
+ }
+ }
+
+ return this;
+
+ // HANDLE: $(#id)
+ } else {
+ elem = document.getElementById( match[ 2 ] );
+
+ if ( elem ) {
+
+ // Inject the element directly into the jQuery object
+ this[ 0 ] = elem;
+ this.length = 1;
+ }
+ return this;
+ }
+
+ // HANDLE: $(expr, $(...))
+ } else if ( !context || context.jquery ) {
+ return ( context || root ).find( selector );
+
+ // HANDLE: $(expr, context)
+ // (which is just equivalent to: $(context).find(expr)
+ } else {
+ return this.constructor( context ).find( selector );
+ }
+
+ // HANDLE: $(DOMElement)
+ } else if ( selector.nodeType ) {
+ this[ 0 ] = selector;
+ this.length = 1;
+ return this;
+
+ // HANDLE: $(function)
+ // Shortcut for document ready
+ } else if ( jQuery.isFunction( selector ) ) {
+ return root.ready !== undefined ?
+ root.ready( selector ) :
+
+ // Execute immediately if ready is not present
+ selector( jQuery );
+ }
+
+ return jQuery.makeArray( selector, this );
+ };
+
+// Give the init function the jQuery prototype for later instantiation
+init.prototype = jQuery.fn;
+
+// Initialize central reference
+rootjQuery = jQuery( document );
+
+
+var rparentsprev = /^(?:parents|prev(?:Until|All))/,
+
+ // Methods guaranteed to produce a unique set when starting from a unique set
+ guaranteedUnique = {
+ children: true,
+ contents: true,
+ next: true,
+ prev: true
+ };
+
+jQuery.fn.extend( {
+ has: function( target ) {
+ var targets = jQuery( target, this ),
+ l = targets.length;
+
+ return this.filter( function() {
+ var i = 0;
+ for ( ; i < l; i++ ) {
+ if ( jQuery.contains( this, targets[ i ] ) ) {
+ return true;
+ }
+ }
+ } );
+ },
+
+ closest: function( selectors, context ) {
+ var cur,
+ i = 0,
+ l = this.length,
+ matched = [],
+ targets = typeof selectors !== "string" && jQuery( selectors );
+
+ // Positional selectors never match, since there's no _selection_ context
+ if ( !rneedsContext.test( selectors ) ) {
+ for ( ; i < l; i++ ) {
+ for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
+
+ // Always skip document fragments
+ if ( cur.nodeType < 11 && ( targets ?
+ targets.index( cur ) > -1 :
+
+ // Don't pass non-elements to Sizzle
+ cur.nodeType === 1 &&
+ jQuery.find.matchesSelector( cur, selectors ) ) ) {
+
+ matched.push( cur );
+ break;
+ }
+ }
+ }
+ }
+
+ return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
+ },
+
+ // Determine the position of an element within the set
+ index: function( elem ) {
+
+ // No argument, return index in parent
+ if ( !elem ) {
+ return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
+ }
+
+ // Index in selector
+ if ( typeof elem === "string" ) {
+ return indexOf.call( jQuery( elem ), this[ 0 ] );
+ }
+
+ // Locate the position of the desired element
+ return indexOf.call( this,
+
+ // If it receives a jQuery object, the first element is used
+ elem.jquery ? elem[ 0 ] : elem
+ );
+ },
+
+ add: function( selector, context ) {
+ return this.pushStack(
+ jQuery.uniqueSort(
+ jQuery.merge( this.get(), jQuery( selector, context ) )
+ )
+ );
+ },
+
+ addBack: function( selector ) {
+ return this.add( selector == null ?
+ this.prevObject : this.prevObject.filter( selector )
+ );
+ }
+} );
+
+function sibling( cur, dir ) {
+ while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
+ return cur;
+}
+
+jQuery.each( {
+ parent: function( elem ) {
+ var parent = elem.parentNode;
+ return parent && parent.nodeType !== 11 ? parent : null;
+ },
+ parents: function( elem ) {
+ return dir( elem, "parentNode" );
+ },
+ parentsUntil: function( elem, i, until ) {
+ return dir( elem, "parentNode", until );
+ },
+ next: function( elem ) {
+ return sibling( elem, "nextSibling" );
+ },
+ prev: function( elem ) {
+ return sibling( elem, "previousSibling" );
+ },
+ nextAll: function( elem ) {
+ return dir( elem, "nextSibling" );
+ },
+ prevAll: function( elem ) {
+ return dir( elem, "previousSibling" );
+ },
+ nextUntil: function( elem, i, until ) {
+ return dir( elem, "nextSibling", until );
+ },
+ prevUntil: function( elem, i, until ) {
+ return dir( elem, "previousSibling", until );
+ },
+ siblings: function( elem ) {
+ return siblings( ( elem.parentNode || {} ).firstChild, elem );
+ },
+ children: function( elem ) {
+ return siblings( elem.firstChild );
+ },
+ contents: function( elem ) {
+ if ( nodeName( elem, "iframe" ) ) {
+ return elem.contentDocument;
+ }
+
+ // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only
+ // Treat the template element as a regular one in browsers that
+ // don't support it.
+ if ( nodeName( elem, "template" ) ) {
+ elem = elem.content || elem;
+ }
+
+ return jQuery.merge( [], elem.childNodes );
+ }
+}, function( name, fn ) {
+ jQuery.fn[ name ] = function( until, selector ) {
+ var matched = jQuery.map( this, fn, until );
+
+ if ( name.slice( -5 ) !== "Until" ) {
+ selector = until;
+ }
+
+ if ( selector && typeof selector === "string" ) {
+ matched = jQuery.filter( selector, matched );
+ }
+
+ if ( this.length > 1 ) {
+
+ // Remove duplicates
+ if ( !guaranteedUnique[ name ] ) {
+ jQuery.uniqueSort( matched );
+ }
+
+ // Reverse order for parents* and prev-derivatives
+ if ( rparentsprev.test( name ) ) {
+ matched.reverse();
+ }
+ }
+
+ return this.pushStack( matched );
+ };
+} );
+var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g );
+
+
+
+// Convert String-formatted options into Object-formatted ones
+function createOptions( options ) {
+ var object = {};
+ jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {
+ object[ flag ] = true;
+ } );
+ return object;
+}
+
+/*
+ * Create a callback list using the following parameters:
+ *
+ * options: an optional list of space-separated options that will change how
+ * the callback list behaves or a more traditional option object
+ *
+ * By default a callback list will act like an event callback list and can be
+ * "fired" multiple times.
+ *
+ * Possible options:
+ *
+ * once: will ensure the callback list can only be fired once (like a Deferred)
+ *
+ * memory: will keep track of previous values and will call any callback added
+ * after the list has been fired right away with the latest "memorized"
+ * values (like a Deferred)
+ *
+ * unique: will ensure a callback can only be added once (no duplicate in the list)
+ *
+ * stopOnFalse: interrupt callings when a callback returns false
+ *
+ */
+jQuery.Callbacks = function( options ) {
+
+ // Convert options from String-formatted to Object-formatted if needed
+ // (we check in cache first)
+ options = typeof options === "string" ?
+ createOptions( options ) :
+ jQuery.extend( {}, options );
+
+ var // Flag to know if list is currently firing
+ firing,
+
+ // Last fire value for non-forgettable lists
+ memory,
+
+ // Flag to know if list was already fired
+ fired,
+
+ // Flag to prevent firing
+ locked,
+
+ // Actual callback list
+ list = [],
+
+ // Queue of execution data for repeatable lists
+ queue = [],
+
+ // Index of currently firing callback (modified by add/remove as needed)
+ firingIndex = -1,
+
+ // Fire callbacks
+ fire = function() {
+
+ // Enforce single-firing
+ locked = locked || options.once;
+
+ // Execute callbacks for all pending executions,
+ // respecting firingIndex overrides and runtime changes
+ fired = firing = true;
+ for ( ; queue.length; firingIndex = -1 ) {
+ memory = queue.shift();
+ while ( ++firingIndex < list.length ) {
+
+ // Run callback and check for early termination
+ if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
+ options.stopOnFalse ) {
+
+ // Jump to end and forget the data so .add doesn't re-fire
+ firingIndex = list.length;
+ memory = false;
+ }
+ }
+ }
+
+ // Forget the data if we're done with it
+ if ( !options.memory ) {
+ memory = false;
+ }
+
+ firing = false;
+
+ // Clean up if we're done firing for good
+ if ( locked ) {
+
+ // Keep an empty list if we have data for future add calls
+ if ( memory ) {
+ list = [];
+
+ // Otherwise, this object is spent
+ } else {
+ list = "";
+ }
+ }
+ },
+
+ // Actual Callbacks object
+ self = {
+
+ // Add a callback or a collection of callbacks to the list
+ add: function() {
+ if ( list ) {
+
+ // If we have memory from a past run, we should fire after adding
+ if ( memory && !firing ) {
+ firingIndex = list.length - 1;
+ queue.push( memory );
+ }
+
+ ( function add( args ) {
+ jQuery.each( args, function( _, arg ) {
+ if ( jQuery.isFunction( arg ) ) {
+ if ( !options.unique || !self.has( arg ) ) {
+ list.push( arg );
+ }
+ } else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) {
+
+ // Inspect recursively
+ add( arg );
+ }
+ } );
+ } )( arguments );
+
+ if ( memory && !firing ) {
+ fire();
+ }
+ }
+ return this;
+ },
+
+ // Remove a callback from the list
+ remove: function() {
+ jQuery.each( arguments, function( _, arg ) {
+ var index;
+ while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
+ list.splice( index, 1 );
+
+ // Handle firing indexes
+ if ( index <= firingIndex ) {
+ firingIndex--;
+ }
+ }
+ } );
+ return this;
+ },
+
+ // Check if a given callback is in the list.
+ // If no argument is given, return whether or not list has callbacks attached.
+ has: function( fn ) {
+ return fn ?
+ jQuery.inArray( fn, list ) > -1 :
+ list.length > 0;
+ },
+
+ // Remove all callbacks from the list
+ empty: function() {
+ if ( list ) {
+ list = [];
+ }
+ return this;
+ },
+
+ // Disable .fire and .add
+ // Abort any current/pending executions
+ // Clear all callbacks and values
+ disable: function() {
+ locked = queue = [];
+ list = memory = "";
+ return this;
+ },
+ disabled: function() {
+ return !list;
+ },
+
+ // Disable .fire
+ // Also disable .add unless we have memory (since it would have no effect)
+ // Abort any pending executions
+ lock: function() {
+ locked = queue = [];
+ if ( !memory && !firing ) {
+ list = memory = "";
+ }
+ return this;
+ },
+ locked: function() {
+ return !!locked;
+ },
+
+ // Call all callbacks with the given context and arguments
+ fireWith: function( context, args ) {
+ if ( !locked ) {
+ args = args || [];
+ args = [ context, args.slice ? args.slice() : args ];
+ queue.push( args );
+ if ( !firing ) {
+ fire();
+ }
+ }
+ return this;
+ },
+
+ // Call all the callbacks with the given arguments
+ fire: function() {
+ self.fireWith( this, arguments );
+ return this;
+ },
+
+ // To know if the callbacks have already been called at least once
+ fired: function() {
+ return !!fired;
+ }
+ };
+
+ return self;
+};
+
+
+function Identity( v ) {
+ return v;
+}
+function Thrower( ex ) {
+ throw ex;
+}
+
+function adoptValue( value, resolve, reject, noValue ) {
+ var method;
+
+ try {
+
+ // Check for promise aspect first to privilege synchronous behavior
+ if ( value && jQuery.isFunction( ( method = value.promise ) ) ) {
+ method.call( value ).done( resolve ).fail( reject );
+
+ // Other thenables
+ } else if ( value && jQuery.isFunction( ( method = value.then ) ) ) {
+ method.call( value, resolve, reject );
+
+ // Other non-thenables
+ } else {
+
+ // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:
+ // * false: [ value ].slice( 0 ) => resolve( value )
+ // * true: [ value ].slice( 1 ) => resolve()
+ resolve.apply( undefined, [ value ].slice( noValue ) );
+ }
+
+ // For Promises/A+, convert exceptions into rejections
+ // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in
+ // Deferred#then to conditionally suppress rejection.
+ } catch ( value ) {
+
+ // Support: Android 4.0 only
+ // Strict mode functions invoked without .call/.apply get global-object context
+ reject.apply( undefined, [ value ] );
+ }
+}
+
+jQuery.extend( {
+
+ Deferred: function( func ) {
+ var tuples = [
+
+ // action, add listener, callbacks,
+ // ... .then handlers, argument index, [final state]
+ [ "notify", "progress", jQuery.Callbacks( "memory" ),
+ jQuery.Callbacks( "memory" ), 2 ],
+ [ "resolve", "done", jQuery.Callbacks( "once memory" ),
+ jQuery.Callbacks( "once memory" ), 0, "resolved" ],
+ [ "reject", "fail", jQuery.Callbacks( "once memory" ),
+ jQuery.Callbacks( "once memory" ), 1, "rejected" ]
+ ],
+ state = "pending",
+ promise = {
+ state: function() {
+ return state;
+ },
+ always: function() {
+ deferred.done( arguments ).fail( arguments );
+ return this;
+ },
+ "catch": function( fn ) {
+ return promise.then( null, fn );
+ },
+
+ // Keep pipe for back-compat
+ pipe: function( /* fnDone, fnFail, fnProgress */ ) {
+ var fns = arguments;
+
+ return jQuery.Deferred( function( newDefer ) {
+ jQuery.each( tuples, function( i, tuple ) {
+
+ // Map tuples (progress, done, fail) to arguments (done, fail, progress)
+ var fn = jQuery.isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];
+
+ // deferred.progress(function() { bind to newDefer or newDefer.notify })
+ // deferred.done(function() { bind to newDefer or newDefer.resolve })
+ // deferred.fail(function() { bind to newDefer or newDefer.reject })
+ deferred[ tuple[ 1 ] ]( function() {
+ var returned = fn && fn.apply( this, arguments );
+ if ( returned && jQuery.isFunction( returned.promise ) ) {
+ returned.promise()
+ .progress( newDefer.notify )
+ .done( newDefer.resolve )
+ .fail( newDefer.reject );
+ } else {
+ newDefer[ tuple[ 0 ] + "With" ](
+ this,
+ fn ? [ returned ] : arguments
+ );
+ }
+ } );
+ } );
+ fns = null;
+ } ).promise();
+ },
+ then: function( onFulfilled, onRejected, onProgress ) {
+ var maxDepth = 0;
+ function resolve( depth, deferred, handler, special ) {
+ return function() {
+ var that = this,
+ args = arguments,
+ mightThrow = function() {
+ var returned, then;
+
+ // Support: Promises/A+ section 2.3.3.3.3
+ // https://promisesaplus.com/#point-59
+ // Ignore double-resolution attempts
+ if ( depth < maxDepth ) {
+ return;
+ }
+
+ returned = handler.apply( that, args );
+
+ // Support: Promises/A+ section 2.3.1
+ // https://promisesaplus.com/#point-48
+ if ( returned === deferred.promise() ) {
+ throw new TypeError( "Thenable self-resolution" );
+ }
+
+ // Support: Promises/A+ sections 2.3.3.1, 3.5
+ // https://promisesaplus.com/#point-54
+ // https://promisesaplus.com/#point-75
+ // Retrieve `then` only once
+ then = returned &&
+
+ // Support: Promises/A+ section 2.3.4
+ // https://promisesaplus.com/#point-64
+ // Only check objects and functions for thenability
+ ( typeof returned === "object" ||
+ typeof returned === "function" ) &&
+ returned.then;
+
+ // Handle a returned thenable
+ if ( jQuery.isFunction( then ) ) {
+
+ // Special processors (notify) just wait for resolution
+ if ( special ) {
+ then.call(
+ returned,
+ resolve( maxDepth, deferred, Identity, special ),
+ resolve( maxDepth, deferred, Thrower, special )
+ );
+
+ // Normal processors (resolve) also hook into progress
+ } else {
+
+ // ...and disregard older resolution values
+ maxDepth++;
+
+ then.call(
+ returned,
+ resolve( maxDepth, deferred, Identity, special ),
+ resolve( maxDepth, deferred, Thrower, special ),
+ resolve( maxDepth, deferred, Identity,
+ deferred.notifyWith )
+ );
+ }
+
+ // Handle all other returned values
+ } else {
+
+ // Only substitute handlers pass on context
+ // and multiple values (non-spec behavior)
+ if ( handler !== Identity ) {
+ that = undefined;
+ args = [ returned ];
+ }
+
+ // Process the value(s)
+ // Default process is resolve
+ ( special || deferred.resolveWith )( that, args );
+ }
+ },
+
+ // Only normal processors (resolve) catch and reject exceptions
+ process = special ?
+ mightThrow :
+ function() {
+ try {
+ mightThrow();
+ } catch ( e ) {
+
+ if ( jQuery.Deferred.exceptionHook ) {
+ jQuery.Deferred.exceptionHook( e,
+ process.stackTrace );
+ }
+
+ // Support: Promises/A+ section 2.3.3.3.4.1
+ // https://promisesaplus.com/#point-61
+ // Ignore post-resolution exceptions
+ if ( depth + 1 >= maxDepth ) {
+
+ // Only substitute handlers pass on context
+ // and multiple values (non-spec behavior)
+ if ( handler !== Thrower ) {
+ that = undefined;
+ args = [ e ];
+ }
+
+ deferred.rejectWith( that, args );
+ }
+ }
+ };
+
+ // Support: Promises/A+ section 2.3.3.3.1
+ // https://promisesaplus.com/#point-57
+ // Re-resolve promises immediately to dodge false rejection from
+ // subsequent errors
+ if ( depth ) {
+ process();
+ } else {
+
+ // Call an optional hook to record the stack, in case of exception
+ // since it's otherwise lost when execution goes async
+ if ( jQuery.Deferred.getStackHook ) {
+ process.stackTrace = jQuery.Deferred.getStackHook();
+ }
+ window.setTimeout( process );
+ }
+ };
+ }
+
+ return jQuery.Deferred( function( newDefer ) {
+
+ // progress_handlers.add( ... )
+ tuples[ 0 ][ 3 ].add(
+ resolve(
+ 0,
+ newDefer,
+ jQuery.isFunction( onProgress ) ?
+ onProgress :
+ Identity,
+ newDefer.notifyWith
+ )
+ );
+
+ // fulfilled_handlers.add( ... )
+ tuples[ 1 ][ 3 ].add(
+ resolve(
+ 0,
+ newDefer,
+ jQuery.isFunction( onFulfilled ) ?
+ onFulfilled :
+ Identity
+ )
+ );
+
+ // rejected_handlers.add( ... )
+ tuples[ 2 ][ 3 ].add(
+ resolve(
+ 0,
+ newDefer,
+ jQuery.isFunction( onRejected ) ?
+ onRejected :
+ Thrower
+ )
+ );
+ } ).promise();
+ },
+
+ // Get a promise for this deferred
+ // If obj is provided, the promise aspect is added to the object
+ promise: function( obj ) {
+ return obj != null ? jQuery.extend( obj, promise ) : promise;
+ }
+ },
+ deferred = {};
+
+ // Add list-specific methods
+ jQuery.each( tuples, function( i, tuple ) {
+ var list = tuple[ 2 ],
+ stateString = tuple[ 5 ];
+
+ // promise.progress = list.add
+ // promise.done = list.add
+ // promise.fail = list.add
+ promise[ tuple[ 1 ] ] = list.add;
+
+ // Handle state
+ if ( stateString ) {
+ list.add(
+ function() {
+
+ // state = "resolved" (i.e., fulfilled)
+ // state = "rejected"
+ state = stateString;
+ },
+
+ // rejected_callbacks.disable
+ // fulfilled_callbacks.disable
+ tuples[ 3 - i ][ 2 ].disable,
+
+ // progress_callbacks.lock
+ tuples[ 0 ][ 2 ].lock
+ );
+ }
+
+ // progress_handlers.fire
+ // fulfilled_handlers.fire
+ // rejected_handlers.fire
+ list.add( tuple[ 3 ].fire );
+
+ // deferred.notify = function() { deferred.notifyWith(...) }
+ // deferred.resolve = function() { deferred.resolveWith(...) }
+ // deferred.reject = function() { deferred.rejectWith(...) }
+ deferred[ tuple[ 0 ] ] = function() {
+ deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments );
+ return this;
+ };
+
+ // deferred.notifyWith = list.fireWith
+ // deferred.resolveWith = list.fireWith
+ // deferred.rejectWith = list.fireWith
+ deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
+ } );
+
+ // Make the deferred a promise
+ promise.promise( deferred );
+
+ // Call given func if any
+ if ( func ) {
+ func.call( deferred, deferred );
+ }
+
+ // All done!
+ return deferred;
+ },
+
+ // Deferred helper
+ when: function( singleValue ) {
+ var
+
+ // count of uncompleted subordinates
+ remaining = arguments.length,
+
+ // count of unprocessed arguments
+ i = remaining,
+
+ // subordinate fulfillment data
+ resolveContexts = Array( i ),
+ resolveValues = slice.call( arguments ),
+
+ // the master Deferred
+ master = jQuery.Deferred(),
+
+ // subordinate callback factory
+ updateFunc = function( i ) {
+ return function( value ) {
+ resolveContexts[ i ] = this;
+ resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
+ if ( !( --remaining ) ) {
+ master.resolveWith( resolveContexts, resolveValues );
+ }
+ };
+ };
+
+ // Single- and empty arguments are adopted like Promise.resolve
+ if ( remaining <= 1 ) {
+ adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject,
+ !remaining );
+
+ // Use .then() to unwrap secondary thenables (cf. gh-3000)
+ if ( master.state() === "pending" ||
+ jQuery.isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {
+
+ return master.then();
+ }
+ }
+
+ // Multiple arguments are aggregated like Promise.all array elements
+ while ( i-- ) {
+ adoptValue( resolveValues[ i ], updateFunc( i ), master.reject );
+ }
+
+ return master.promise();
+ }
+} );
+
+
+// These usually indicate a programmer mistake during development,
+// warn about them ASAP rather than swallowing them by default.
+var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;
+
+jQuery.Deferred.exceptionHook = function( error, stack ) {
+
+ // Support: IE 8 - 9 only
+ // Console exists when dev tools are open, which can happen at any time
+ if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {
+ window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack );
+ }
+};
+
+
+
+
+jQuery.readyException = function( error ) {
+ window.setTimeout( function() {
+ throw error;
+ } );
+};
+
+
+
+
+// The deferred used on DOM ready
+var readyList = jQuery.Deferred();
+
+jQuery.fn.ready = function( fn ) {
+
+ readyList
+ .then( fn )
+
+ // Wrap jQuery.readyException in a function so that the lookup
+ // happens at the time of error handling instead of callback
+ // registration.
+ .catch( function( error ) {
+ jQuery.readyException( error );
+ } );
+
+ return this;
+};
+
+jQuery.extend( {
+
+ // Is the DOM ready to be used? Set to true once it occurs.
+ isReady: false,
+
+ // A counter to track how many items to wait for before
+ // the ready event fires. See #6781
+ readyWait: 1,
+
+ // Handle when the DOM is ready
+ ready: function( wait ) {
+
+ // Abort if there are pending holds or we're already ready
+ if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
+ return;
+ }
+
+ // Remember that the DOM is ready
+ jQuery.isReady = true;
+
+ // If a normal DOM Ready event fired, decrement, and wait if need be
+ if ( wait !== true && --jQuery.readyWait > 0 ) {
+ return;
+ }
+
+ // If there are functions bound, to execute
+ readyList.resolveWith( document, [ jQuery ] );
+ }
+} );
+
+jQuery.ready.then = readyList.then;
+
+// The ready event handler and self cleanup method
+function completed() {
+ document.removeEventListener( "DOMContentLoaded", completed );
+ window.removeEventListener( "load", completed );
+ jQuery.ready();
+}
+
+// Catch cases where $(document).ready() is called
+// after the browser event has already occurred.
+// Support: IE <=9 - 10 only
+// Older IE sometimes signals "interactive" too soon
+if ( document.readyState === "complete" ||
+ ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
+
+ // Handle it asynchronously to allow scripts the opportunity to delay ready
+ window.setTimeout( jQuery.ready );
+
+} else {
+
+ // Use the handy event callback
+ document.addEventListener( "DOMContentLoaded", completed );
+
+ // A fallback to window.onload, that will always work
+ window.addEventListener( "load", completed );
+}
+
+
+
+
+// Multifunctional method to get and set values of a collection
+// The value/s can optionally be executed if it's a function
+var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
+ var i = 0,
+ len = elems.length,
+ bulk = key == null;
+
+ // Sets many values
+ if ( jQuery.type( key ) === "object" ) {
+ chainable = true;
+ for ( i in key ) {
+ access( elems, fn, i, key[ i ], true, emptyGet, raw );
+ }
+
+ // Sets one value
+ } else if ( value !== undefined ) {
+ chainable = true;
+
+ if ( !jQuery.isFunction( value ) ) {
+ raw = true;
+ }
+
+ if ( bulk ) {
+
+ // Bulk operations run against the entire set
+ if ( raw ) {
+ fn.call( elems, value );
+ fn = null;
+
+ // ...except when executing function values
+ } else {
+ bulk = fn;
+ fn = function( elem, key, value ) {
+ return bulk.call( jQuery( elem ), value );
+ };
+ }
+ }
+
+ if ( fn ) {
+ for ( ; i < len; i++ ) {
+ fn(
+ elems[ i ], key, raw ?
+ value :
+ value.call( elems[ i ], i, fn( elems[ i ], key ) )
+ );
+ }
+ }
+ }
+
+ if ( chainable ) {
+ return elems;
+ }
+
+ // Gets
+ if ( bulk ) {
+ return fn.call( elems );
+ }
+
+ return len ? fn( elems[ 0 ], key ) : emptyGet;
+};
+var acceptData = function( owner ) {
+
+ // Accepts only:
+ // - Node
+ // - Node.ELEMENT_NODE
+ // - Node.DOCUMENT_NODE
+ // - Object
+ // - Any
+ return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
+};
+
+
+
+
+function Data() {
+ this.expando = jQuery.expando + Data.uid++;
+}
+
+Data.uid = 1;
+
+Data.prototype = {
+
+ cache: function( owner ) {
+
+ // Check if the owner object already has a cache
+ var value = owner[ this.expando ];
+
+ // If not, create one
+ if ( !value ) {
+ value = {};
+
+ // We can accept data for non-element nodes in modern browsers,
+ // but we should not, see #8335.
+ // Always return an empty object.
+ if ( acceptData( owner ) ) {
+
+ // If it is a node unlikely to be stringify-ed or looped over
+ // use plain assignment
+ if ( owner.nodeType ) {
+ owner[ this.expando ] = value;
+
+ // Otherwise secure it in a non-enumerable property
+ // configurable must be true to allow the property to be
+ // deleted when data is removed
+ } else {
+ Object.defineProperty( owner, this.expando, {
+ value: value,
+ configurable: true
+ } );
+ }
+ }
+ }
+
+ return value;
+ },
+ set: function( owner, data, value ) {
+ var prop,
+ cache = this.cache( owner );
+
+ // Handle: [ owner, key, value ] args
+ // Always use camelCase key (gh-2257)
+ if ( typeof data === "string" ) {
+ cache[ jQuery.camelCase( data ) ] = value;
+
+ // Handle: [ owner, { properties } ] args
+ } else {
+
+ // Copy the properties one-by-one to the cache object
+ for ( prop in data ) {
+ cache[ jQuery.camelCase( prop ) ] = data[ prop ];
+ }
+ }
+ return cache;
+ },
+ get: function( owner, key ) {
+ return key === undefined ?
+ this.cache( owner ) :
+
+ // Always use camelCase key (gh-2257)
+ owner[ this.expando ] && owner[ this.expando ][ jQuery.camelCase( key ) ];
+ },
+ access: function( owner, key, value ) {
+
+ // In cases where either:
+ //
+ // 1. No key was specified
+ // 2. A string key was specified, but no value provided
+ //
+ // Take the "read" path and allow the get method to determine
+ // which value to return, respectively either:
+ //
+ // 1. The entire cache object
+ // 2. The data stored at the key
+ //
+ if ( key === undefined ||
+ ( ( key && typeof key === "string" ) && value === undefined ) ) {
+
+ return this.get( owner, key );
+ }
+
+ // When the key is not a string, or both a key and value
+ // are specified, set or extend (existing objects) with either:
+ //
+ // 1. An object of properties
+ // 2. A key and value
+ //
+ this.set( owner, key, value );
+
+ // Since the "set" path can have two possible entry points
+ // return the expected data based on which path was taken[*]
+ return value !== undefined ? value : key;
+ },
+ remove: function( owner, key ) {
+ var i,
+ cache = owner[ this.expando ];
+
+ if ( cache === undefined ) {
+ return;
+ }
+
+ if ( key !== undefined ) {
+
+ // Support array or space separated string of keys
+ if ( Array.isArray( key ) ) {
+
+ // If key is an array of keys...
+ // We always set camelCase keys, so remove that.
+ key = key.map( jQuery.camelCase );
+ } else {
+ key = jQuery.camelCase( key );
+
+ // If a key with the spaces exists, use it.
+ // Otherwise, create an array by matching non-whitespace
+ key = key in cache ?
+ [ key ] :
+ ( key.match( rnothtmlwhite ) || [] );
+ }
+
+ i = key.length;
+
+ while ( i-- ) {
+ delete cache[ key[ i ] ];
+ }
+ }
+
+ // Remove the expando if there's no more data
+ if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
+
+ // Support: Chrome <=35 - 45
+ // Webkit & Blink performance suffers when deleting properties
+ // from DOM nodes, so set to undefined instead
+ // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
+ if ( owner.nodeType ) {
+ owner[ this.expando ] = undefined;
+ } else {
+ delete owner[ this.expando ];
+ }
+ }
+ },
+ hasData: function( owner ) {
+ var cache = owner[ this.expando ];
+ return cache !== undefined && !jQuery.isEmptyObject( cache );
+ }
+};
+var dataPriv = new Data();
+
+var dataUser = new Data();
+
+
+
+// Implementation Summary
+//
+// 1. Enforce API surface and semantic compatibility with 1.9.x branch
+// 2. Improve the module's maintainability by reducing the storage
+// paths to a single mechanism.
+// 3. Use the same single mechanism to support "private" and "user" data.
+// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
+// 5. Avoid exposing implementation details on user objects (eg. expando properties)
+// 6. Provide a clear path for implementation upgrade to WeakMap in 2014
+
+var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
+ rmultiDash = /[A-Z]/g;
+
+function getData( data ) {
+ if ( data === "true" ) {
+ return true;
+ }
+
+ if ( data === "false" ) {
+ return false;
+ }
+
+ if ( data === "null" ) {
+ return null;
+ }
+
+ // Only convert to a number if it doesn't change the string
+ if ( data === +data + "" ) {
+ return +data;
+ }
+
+ if ( rbrace.test( data ) ) {
+ return JSON.parse( data );
+ }
+
+ return data;
+}
+
+function dataAttr( elem, key, data ) {
+ var name;
+
+ // If nothing was found internally, try to fetch any
+ // data from the HTML5 data-* attribute
+ if ( data === undefined && elem.nodeType === 1 ) {
+ name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
+ data = elem.getAttribute( name );
+
+ if ( typeof data === "string" ) {
+ try {
+ data = getData( data );
+ } catch ( e ) {}
+
+ // Make sure we set the data so it isn't changed later
+ dataUser.set( elem, key, data );
+ } else {
+ data = undefined;
+ }
+ }
+ return data;
+}
+
+jQuery.extend( {
+ hasData: function( elem ) {
+ return dataUser.hasData( elem ) || dataPriv.hasData( elem );
+ },
+
+ data: function( elem, name, data ) {
+ return dataUser.access( elem, name, data );
+ },
+
+ removeData: function( elem, name ) {
+ dataUser.remove( elem, name );
+ },
+
+ // TODO: Now that all calls to _data and _removeData have been replaced
+ // with direct calls to dataPriv methods, these can be deprecated.
+ _data: function( elem, name, data ) {
+ return dataPriv.access( elem, name, data );
+ },
+
+ _removeData: function( elem, name ) {
+ dataPriv.remove( elem, name );
+ }
+} );
+
+jQuery.fn.extend( {
+ data: function( key, value ) {
+ var i, name, data,
+ elem = this[ 0 ],
+ attrs = elem && elem.attributes;
+
+ // Gets all values
+ if ( key === undefined ) {
+ if ( this.length ) {
+ data = dataUser.get( elem );
+
+ if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
+ i = attrs.length;
+ while ( i-- ) {
+
+ // Support: IE 11 only
+ // The attrs elements can be null (#14894)
+ if ( attrs[ i ] ) {
+ name = attrs[ i ].name;
+ if ( name.indexOf( "data-" ) === 0 ) {
+ name = jQuery.camelCase( name.slice( 5 ) );
+ dataAttr( elem, name, data[ name ] );
+ }
+ }
+ }
+ dataPriv.set( elem, "hasDataAttrs", true );
+ }
+ }
+
+ return data;
+ }
+
+ // Sets multiple values
+ if ( typeof key === "object" ) {
+ return this.each( function() {
+ dataUser.set( this, key );
+ } );
+ }
+
+ return access( this, function( value ) {
+ var data;
+
+ // The calling jQuery object (element matches) is not empty
+ // (and therefore has an element appears at this[ 0 ]) and the
+ // `value` parameter was not undefined. An empty jQuery object
+ // will result in `undefined` for elem = this[ 0 ] which will
+ // throw an exception if an attempt to read a data cache is made.
+ if ( elem && value === undefined ) {
+
+ // Attempt to get data from the cache
+ // The key will always be camelCased in Data
+ data = dataUser.get( elem, key );
+ if ( data !== undefined ) {
+ return data;
+ }
+
+ // Attempt to "discover" the data in
+ // HTML5 custom data-* attrs
+ data = dataAttr( elem, key );
+ if ( data !== undefined ) {
+ return data;
+ }
+
+ // We tried really hard, but the data doesn't exist.
+ return;
+ }
+
+ // Set the data...
+ this.each( function() {
+
+ // We always store the camelCased key
+ dataUser.set( this, key, value );
+ } );
+ }, null, value, arguments.length > 1, null, true );
+ },
+
+ removeData: function( key ) {
+ return this.each( function() {
+ dataUser.remove( this, key );
+ } );
+ }
+} );
+
+
+jQuery.extend( {
+ queue: function( elem, type, data ) {
+ var queue;
+
+ if ( elem ) {
+ type = ( type || "fx" ) + "queue";
+ queue = dataPriv.get( elem, type );
+
+ // Speed up dequeue by getting out quickly if this is just a lookup
+ if ( data ) {
+ if ( !queue || Array.isArray( data ) ) {
+ queue = dataPriv.access( elem, type, jQuery.makeArray( data ) );
+ } else {
+ queue.push( data );
+ }
+ }
+ return queue || [];
+ }
+ },
+
+ dequeue: function( elem, type ) {
+ type = type || "fx";
+
+ var queue = jQuery.queue( elem, type ),
+ startLength = queue.length,
+ fn = queue.shift(),
+ hooks = jQuery._queueHooks( elem, type ),
+ next = function() {
+ jQuery.dequeue( elem, type );
+ };
+
+ // If the fx queue is dequeued, always remove the progress sentinel
+ if ( fn === "inprogress" ) {
+ fn = queue.shift();
+ startLength--;
+ }
+
+ if ( fn ) {
+
+ // Add a progress sentinel to prevent the fx queue from being
+ // automatically dequeued
+ if ( type === "fx" ) {
+ queue.unshift( "inprogress" );
+ }
+
+ // Clear up the last queue stop function
+ delete hooks.stop;
+ fn.call( elem, next, hooks );
+ }
+
+ if ( !startLength && hooks ) {
+ hooks.empty.fire();
+ }
+ },
+
+ // Not public - generate a queueHooks object, or return the current one
+ _queueHooks: function( elem, type ) {
+ var key = type + "queueHooks";
+ return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {
+ empty: jQuery.Callbacks( "once memory" ).add( function() {
+ dataPriv.remove( elem, [ type + "queue", key ] );
+ } )
+ } );
+ }
+} );
+
+jQuery.fn.extend( {
+ queue: function( type, data ) {
+ var setter = 2;
+
+ if ( typeof type !== "string" ) {
+ data = type;
+ type = "fx";
+ setter--;
+ }
+
+ if ( arguments.length < setter ) {
+ return jQuery.queue( this[ 0 ], type );
+ }
+
+ return data === undefined ?
+ this :
+ this.each( function() {
+ var queue = jQuery.queue( this, type, data );
+
+ // Ensure a hooks for this queue
+ jQuery._queueHooks( this, type );
+
+ if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
+ jQuery.dequeue( this, type );
+ }
+ } );
+ },
+ dequeue: function( type ) {
+ return this.each( function() {
+ jQuery.dequeue( this, type );
+ } );
+ },
+ clearQueue: function( type ) {
+ return this.queue( type || "fx", [] );
+ },
+
+ // Get a promise resolved when queues of a certain type
+ // are emptied (fx is the type by default)
+ promise: function( type, obj ) {
+ var tmp,
+ count = 1,
+ defer = jQuery.Deferred(),
+ elements = this,
+ i = this.length,
+ resolve = function() {
+ if ( !( --count ) ) {
+ defer.resolveWith( elements, [ elements ] );
+ }
+ };
+
+ if ( typeof type !== "string" ) {
+ obj = type;
+ type = undefined;
+ }
+ type = type || "fx";
+
+ while ( i-- ) {
+ tmp = dataPriv.get( elements[ i ], type + "queueHooks" );
+ if ( tmp && tmp.empty ) {
+ count++;
+ tmp.empty.add( resolve );
+ }
+ }
+ resolve();
+ return defer.promise( obj );
+ }
+} );
+var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
+
+var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
+
+
+var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
+
+var isHiddenWithinTree = function( elem, el ) {
+
+ // isHiddenWithinTree might be called from jQuery#filter function;
+ // in that case, element will be second argument
+ elem = el || elem;
+
+ // Inline style trumps all
+ return elem.style.display === "none" ||
+ elem.style.display === "" &&
+
+ // Otherwise, check computed style
+ // Support: Firefox <=43 - 45
+ // Disconnected elements can have computed display: none, so first confirm that elem is
+ // in the document.
+ jQuery.contains( elem.ownerDocument, elem ) &&
+
+ jQuery.css( elem, "display" ) === "none";
+ };
+
+var swap = function( elem, options, callback, args ) {
+ var ret, name,
+ old = {};
+
+ // Remember the old values, and insert the new ones
+ for ( name in options ) {
+ old[ name ] = elem.style[ name ];
+ elem.style[ name ] = options[ name ];
+ }
+
+ ret = callback.apply( elem, args || [] );
+
+ // Revert the old values
+ for ( name in options ) {
+ elem.style[ name ] = old[ name ];
+ }
+
+ return ret;
+};
+
+
+
+
+function adjustCSS( elem, prop, valueParts, tween ) {
+ var adjusted,
+ scale = 1,
+ maxIterations = 20,
+ currentValue = tween ?
+ function() {
+ return tween.cur();
+ } :
+ function() {
+ return jQuery.css( elem, prop, "" );
+ },
+ initial = currentValue(),
+ unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
+
+ // Starting value computation is required for potential unit mismatches
+ initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
+ rcssNum.exec( jQuery.css( elem, prop ) );
+
+ if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
+
+ // Trust units reported by jQuery.css
+ unit = unit || initialInUnit[ 3 ];
+
+ // Make sure we update the tween properties later on
+ valueParts = valueParts || [];
+
+ // Iteratively approximate from a nonzero starting point
+ initialInUnit = +initial || 1;
+
+ do {
+
+ // If previous iteration zeroed out, double until we get *something*.
+ // Use string for doubling so we don't accidentally see scale as unchanged below
+ scale = scale || ".5";
+
+ // Adjust and apply
+ initialInUnit = initialInUnit / scale;
+ jQuery.style( elem, prop, initialInUnit + unit );
+
+ // Update scale, tolerating zero or NaN from tween.cur()
+ // Break the loop if scale is unchanged or perfect, or if we've just had enough.
+ } while (
+ scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations
+ );
+ }
+
+ if ( valueParts ) {
+ initialInUnit = +initialInUnit || +initial || 0;
+
+ // Apply relative offset (+=/-=) if specified
+ adjusted = valueParts[ 1 ] ?
+ initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
+ +valueParts[ 2 ];
+ if ( tween ) {
+ tween.unit = unit;
+ tween.start = initialInUnit;
+ tween.end = adjusted;
+ }
+ }
+ return adjusted;
+}
+
+
+var defaultDisplayMap = {};
+
+function getDefaultDisplay( elem ) {
+ var temp,
+ doc = elem.ownerDocument,
+ nodeName = elem.nodeName,
+ display = defaultDisplayMap[ nodeName ];
+
+ if ( display ) {
+ return display;
+ }
+
+ temp = doc.body.appendChild( doc.createElement( nodeName ) );
+ display = jQuery.css( temp, "display" );
+
+ temp.parentNode.removeChild( temp );
+
+ if ( display === "none" ) {
+ display = "block";
+ }
+ defaultDisplayMap[ nodeName ] = display;
+
+ return display;
+}
+
+function showHide( elements, show ) {
+ var display, elem,
+ values = [],
+ index = 0,
+ length = elements.length;
+
+ // Determine new display value for elements that need to change
+ for ( ; index < length; index++ ) {
+ elem = elements[ index ];
+ if ( !elem.style ) {
+ continue;
+ }
+
+ display = elem.style.display;
+ if ( show ) {
+
+ // Since we force visibility upon cascade-hidden elements, an immediate (and slow)
+ // check is required in this first loop unless we have a nonempty display value (either
+ // inline or about-to-be-restored)
+ if ( display === "none" ) {
+ values[ index ] = dataPriv.get( elem, "display" ) || null;
+ if ( !values[ index ] ) {
+ elem.style.display = "";
+ }
+ }
+ if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) {
+ values[ index ] = getDefaultDisplay( elem );
+ }
+ } else {
+ if ( display !== "none" ) {
+ values[ index ] = "none";
+
+ // Remember what we're overwriting
+ dataPriv.set( elem, "display", display );
+ }
+ }
+ }
+
+ // Set the display of the elements in a second loop to avoid constant reflow
+ for ( index = 0; index < length; index++ ) {
+ if ( values[ index ] != null ) {
+ elements[ index ].style.display = values[ index ];
+ }
+ }
+
+ return elements;
+}
+
+jQuery.fn.extend( {
+ show: function() {
+ return showHide( this, true );
+ },
+ hide: function() {
+ return showHide( this );
+ },
+ toggle: function( state ) {
+ if ( typeof state === "boolean" ) {
+ return state ? this.show() : this.hide();
+ }
+
+ return this.each( function() {
+ if ( isHiddenWithinTree( this ) ) {
+ jQuery( this ).show();
+ } else {
+ jQuery( this ).hide();
+ }
+ } );
+ }
+} );
+var rcheckableType = ( /^(?:checkbox|radio)$/i );
+
+var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]+)/i );
+
+var rscriptType = ( /^$|\/(?:java|ecma)script/i );
+
+
+
+// We have to close these tags to support XHTML (#13200)
+var wrapMap = {
+
+ // Support: IE <=9 only
+ option: [ 1, "<select multiple='multiple'>", "</select>" ],
+
+ // XHTML parsers do not magically insert elements in the
+ // same way that tag soup parsers do. So we cannot shorten
+ // this by omitting <tbody> or other required elements.
+ thead: [ 1, "<table>", "</table>" ],
+ col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
+ tr: [ 2, "<table><tbody>", "</tbody></table>" ],
+ td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
+
+ _default: [ 0, "", "" ]
+};
+
+// Support: IE <=9 only
+wrapMap.optgroup = wrapMap.option;
+
+wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
+wrapMap.th = wrapMap.td;
+
+
+function getAll( context, tag ) {
+
+ // Support: IE <=9 - 11 only
+ // Use typeof to avoid zero-argument method invocation on host objects (#15151)
+ var ret;
+
+ if ( typeof context.getElementsByTagName !== "undefined" ) {
+ ret = context.getElementsByTagName( tag || "*" );
+
+ } else if ( typeof context.querySelectorAll !== "undefined" ) {
+ ret = context.querySelectorAll( tag || "*" );
+
+ } else {
+ ret = [];
+ }
+
+ if ( tag === undefined || tag && nodeName( context, tag ) ) {
+ return jQuery.merge( [ context ], ret );
+ }
+
+ return ret;
+}
+
+
+// Mark scripts as having already been evaluated
+function setGlobalEval( elems, refElements ) {
+ var i = 0,
+ l = elems.length;
+
+ for ( ; i < l; i++ ) {
+ dataPriv.set(
+ elems[ i ],
+ "globalEval",
+ !refElements || dataPriv.get( refElements[ i ], "globalEval" )
+ );
+ }
+}
+
+
+var rhtml = /<|&#?\w+;/;
+
+function buildFragment( elems, context, scripts, selection, ignored ) {
+ var elem, tmp, tag, wrap, contains, j,
+ fragment = context.createDocumentFragment(),
+ nodes = [],
+ i = 0,
+ l = elems.length;
+
+ for ( ; i < l; i++ ) {
+ elem = elems[ i ];
+
+ if ( elem || elem === 0 ) {
+
+ // Add nodes directly
+ if ( jQuery.type( elem ) === "object" ) {
+
+ // Support: Android <=4.0 only, PhantomJS 1 only
+ // push.apply(_, arraylike) throws on ancient WebKit
+ jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
+
+ // Convert non-html into a text node
+ } else if ( !rhtml.test( elem ) ) {
+ nodes.push( context.createTextNode( elem ) );
+
+ // Convert html into DOM nodes
+ } else {
+ tmp = tmp || fragment.appendChild( context.createElement( "div" ) );
+
+ // Deserialize a standard representation
+ tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
+ wrap = wrapMap[ tag ] || wrapMap._default;
+ tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
+
+ // Descend through wrappers to the right content
+ j = wrap[ 0 ];
+ while ( j-- ) {
+ tmp = tmp.lastChild;
+ }
+
+ // Support: Android <=4.0 only, PhantomJS 1 only
+ // push.apply(_, arraylike) throws on ancient WebKit
+ jQuery.merge( nodes, tmp.childNodes );
+
+ // Remember the top-level container
+ tmp = fragment.firstChild;
+
+ // Ensure the created nodes are orphaned (#12392)
+ tmp.textContent = "";
+ }
+ }
+ }
+
+ // Remove wrapper from fragment
+ fragment.textContent = "";
+
+ i = 0;
+ while ( ( elem = nodes[ i++ ] ) ) {
+
+ // Skip elements already in the context collection (trac-4087)
+ if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
+ if ( ignored ) {
+ ignored.push( elem );
+ }
+ continue;
+ }
+
+ contains = jQuery.contains( elem.ownerDocument, elem );
+
+ // Append to fragment
+ tmp = getAll( fragment.appendChild( elem ), "script" );
+
+ // Preserve script evaluation history
+ if ( contains ) {
+ setGlobalEval( tmp );
+ }
+
+ // Capture executables
+ if ( scripts ) {
+ j = 0;
+ while ( ( elem = tmp[ j++ ] ) ) {
+ if ( rscriptType.test( elem.type || "" ) ) {
+ scripts.push( elem );
+ }
+ }
+ }
+ }
+
+ return fragment;
+}
+
+
+( function() {
+ var fragment = document.createDocumentFragment(),
+ div = fragment.appendChild( document.createElement( "div" ) ),
+ input = document.createElement( "input" );
+
+ // Support: Android 4.0 - 4.3 only
+ // Check state lost if the name is set (#11217)
+ // Support: Windows Web Apps (WWA)
+ // `name` and `type` must use .setAttribute for WWA (#14901)
+ input.setAttribute( "type", "radio" );
+ input.setAttribute( "checked", "checked" );
+ input.setAttribute( "name", "t" );
+
+ div.appendChild( input );
+
+ // Support: Android <=4.1 only
+ // Older WebKit doesn't clone checked state correctly in fragments
+ support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
+
+ // Support: IE <=11 only
+ // Make sure textarea (and checkbox) defaultValue is properly cloned
+ div.innerHTML = "<textarea>x</textarea>";
+ support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
+} )();
+var documentElement = document.documentElement;
+
+
+
+var
+ rkeyEvent = /^key/,
+ rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
+ rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
+
+function returnTrue() {
+ return true;
+}
+
+function returnFalse() {
+ return false;
+}
+
+// Support: IE <=9 only
+// See #13393 for more info
+function safeActiveElement() {
+ try {
+ return document.activeElement;
+ } catch ( err ) { }
+}
+
+function on( elem, types, selector, data, fn, one ) {
+ var origFn, type;
+
+ // Types can be a map of types/handlers
+ if ( typeof types === "object" ) {
+
+ // ( types-Object, selector, data )
+ if ( typeof selector !== "string" ) {
+
+ // ( types-Object, data )
+ data = data || selector;
+ selector = undefined;
+ }
+ for ( type in types ) {
+ on( elem, type, selector, data, types[ type ], one );
+ }
+ return elem;
+ }
+
+ if ( data == null && fn == null ) {
+
+ // ( types, fn )
+ fn = selector;
+ data = selector = undefined;
+ } else if ( fn == null ) {
+ if ( typeof selector === "string" ) {
+
+ // ( types, selector, fn )
+ fn = data;
+ data = undefined;
+ } else {
+
+ // ( types, data, fn )
+ fn = data;
+ data = selector;
+ selector = undefined;
+ }
+ }
+ if ( fn === false ) {
+ fn = returnFalse;
+ } else if ( !fn ) {
+ return elem;
+ }
+
+ if ( one === 1 ) {
+ origFn = fn;
+ fn = function( event ) {
+
+ // Can use an empty set, since event contains the info
+ jQuery().off( event );
+ return origFn.apply( this, arguments );
+ };
+
+ // Use same guid so caller can remove using origFn
+ fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
+ }
+ return elem.each( function() {
+ jQuery.event.add( this, types, fn, data, selector );
+ } );
+}
+
+/*
+ * Helper functions for managing events -- not part of the public interface.
+ * Props to Dean Edwards' addEvent library for many of the ideas.
+ */
+jQuery.event = {
+
+ global: {},
+
+ add: function( elem, types, handler, data, selector ) {
+
+ var handleObjIn, eventHandle, tmp,
+ events, t, handleObj,
+ special, handlers, type, namespaces, origType,
+ elemData = dataPriv.get( elem );
+
+ // Don't attach events to noData or text/comment nodes (but allow plain objects)
+ if ( !elemData ) {
+ return;
+ }
+
+ // Caller can pass in an object of custom data in lieu of the handler
+ if ( handler.handler ) {
+ handleObjIn = handler;
+ handler = handleObjIn.handler;
+ selector = handleObjIn.selector;
+ }
+
+ // Ensure that invalid selectors throw exceptions at attach time
+ // Evaluate against documentElement in case elem is a non-element node (e.g., document)
+ if ( selector ) {
+ jQuery.find.matchesSelector( documentElement, selector );
+ }
+
+ // Make sure that the handler has a unique ID, used to find/remove it later
+ if ( !handler.guid ) {
+ handler.guid = jQuery.guid++;
+ }
+
+ // Init the element's event structure and main handler, if this is the first
+ if ( !( events = elemData.events ) ) {
+ events = elemData.events = {};
+ }
+ if ( !( eventHandle = elemData.handle ) ) {
+ eventHandle = elemData.handle = function( e ) {
+
+ // Discard the second event of a jQuery.event.trigger() and
+ // when an event is called after a page has unloaded
+ return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
+ jQuery.event.dispatch.apply( elem, arguments ) : undefined;
+ };
+ }
+
+ // Handle multiple events separated by a space
+ types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
+ t = types.length;
+ while ( t-- ) {
+ tmp = rtypenamespace.exec( types[ t ] ) || [];
+ type = origType = tmp[ 1 ];
+ namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
+
+ // There *must* be a type, no attaching namespace-only handlers
+ if ( !type ) {
+ continue;
+ }
+
+ // If event changes its type, use the special event handlers for the changed type
+ special = jQuery.event.special[ type ] || {};
+
+ // If selector defined, determine special event api type, otherwise given type
+ type = ( selector ? special.delegateType : special.bindType ) || type;
+
+ // Update special based on newly reset type
+ special = jQuery.event.special[ type ] || {};
+
+ // handleObj is passed to all event handlers
+ handleObj = jQuery.extend( {
+ type: type,
+ origType: origType,
+ data: data,
+ handler: handler,
+ guid: handler.guid,
+ selector: selector,
+ needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
+ namespace: namespaces.join( "." )
+ }, handleObjIn );
+
+ // Init the event handler queue if we're the first
+ if ( !( handlers = events[ type ] ) ) {
+ handlers = events[ type ] = [];
+ handlers.delegateCount = 0;
+
+ // Only use addEventListener if the special events handler returns false
+ if ( !special.setup ||
+ special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
+
+ if ( elem.addEventListener ) {
+ elem.addEventListener( type, eventHandle );
+ }
+ }
+ }
+
+ if ( special.add ) {
+ special.add.call( elem, handleObj );
+
+ if ( !handleObj.handler.guid ) {
+ handleObj.handler.guid = handler.guid;
+ }
+ }
+
+ // Add to the element's handler list, delegates in front
+ if ( selector ) {
+ handlers.splice( handlers.delegateCount++, 0, handleObj );
+ } else {
+ handlers.push( handleObj );
+ }
+
+ // Keep track of which events have ever been used, for event optimization
+ jQuery.event.global[ type ] = true;
+ }
+
+ },
+
+ // Detach an event or set of events from an element
+ remove: function( elem, types, handler, selector, mappedTypes ) {
+
+ var j, origCount, tmp,
+ events, t, handleObj,
+ special, handlers, type, namespaces, origType,
+ elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );
+
+ if ( !elemData || !( events = elemData.events ) ) {
+ return;
+ }
+
+ // Once for each type.namespace in types; type may be omitted
+ types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
+ t = types.length;
+ while ( t-- ) {
+ tmp = rtypenamespace.exec( types[ t ] ) || [];
+ type = origType = tmp[ 1 ];
+ namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
+
+ // Unbind all events (on this namespace, if provided) for the element
+ if ( !type ) {
+ for ( type in events ) {
+ jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
+ }
+ continue;
+ }
+
+ special = jQuery.event.special[ type ] || {};
+ type = ( selector ? special.delegateType : special.bindType ) || type;
+ handlers = events[ type ] || [];
+ tmp = tmp[ 2 ] &&
+ new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
+
+ // Remove matching events
+ origCount = j = handlers.length;
+ while ( j-- ) {
+ handleObj = handlers[ j ];
+
+ if ( ( mappedTypes || origType === handleObj.origType ) &&
+ ( !handler || handler.guid === handleObj.guid ) &&
+ ( !tmp || tmp.test( handleObj.namespace ) ) &&
+ ( !selector || selector === handleObj.selector ||
+ selector === "**" && handleObj.selector ) ) {
+ handlers.splice( j, 1 );
+
+ if ( handleObj.selector ) {
+ handlers.delegateCount--;
+ }
+ if ( special.remove ) {
+ special.remove.call( elem, handleObj );
+ }
+ }
+ }
+
+ // Remove generic event handler if we removed something and no more handlers exist
+ // (avoids potential for endless recursion during removal of special event handlers)
+ if ( origCount && !handlers.length ) {
+ if ( !special.teardown ||
+ special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
+
+ jQuery.removeEvent( elem, type, elemData.handle );
+ }
+
+ delete events[ type ];
+ }
+ }
+
+ // Remove data and the expando if it's no longer used
+ if ( jQuery.isEmptyObject( events ) ) {
+ dataPriv.remove( elem, "handle events" );
+ }
+ },
+
+ dispatch: function( nativeEvent ) {
+
+ // Make a writable jQuery.Event from the native event object
+ var event = jQuery.event.fix( nativeEvent );
+
+ var i, j, ret, matched, handleObj, handlerQueue,
+ args = new Array( arguments.length ),
+ handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [],
+ special = jQuery.event.special[ event.type ] || {};
+
+ // Use the fix-ed jQuery.Event rather than the (read-only) native event
+ args[ 0 ] = event;
+
+ for ( i = 1; i < arguments.length; i++ ) {
+ args[ i ] = arguments[ i ];
+ }
+
+ event.delegateTarget = this;
+
+ // Call the preDispatch hook for the mapped type, and let it bail if desired
+ if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
+ return;
+ }
+
+ // Determine handlers
+ handlerQueue = jQuery.event.handlers.call( this, event, handlers );
+
+ // Run delegates first; they may want to stop propagation beneath us
+ i = 0;
+ while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
+ event.currentTarget = matched.elem;
+
+ j = 0;
+ while ( ( handleObj = matched.handlers[ j++ ] ) &&
+ !event.isImmediatePropagationStopped() ) {
+
+ // Triggered event must either 1) have no namespace, or 2) have namespace(s)
+ // a subset or equal to those in the bound event (both can have no namespace).
+ if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {
+
+ event.handleObj = handleObj;
+ event.data = handleObj.data;
+
+ ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
+ handleObj.handler ).apply( matched.elem, args );
+
+ if ( ret !== undefined ) {
+ if ( ( event.result = ret ) === false ) {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ }
+ }
+ }
+ }
+
+ // Call the postDispatch hook for the mapped type
+ if ( special.postDispatch ) {
+ special.postDispatch.call( this, event );
+ }
+
+ return event.result;
+ },
+
+ handlers: function( event, handlers ) {
+ var i, handleObj, sel, matchedHandlers, matchedSelectors,
+ handlerQueue = [],
+ delegateCount = handlers.delegateCount,
+ cur = event.target;
+
+ // Find delegate handlers
+ if ( delegateCount &&
+
+ // Support: IE <=9
+ // Black-hole SVG <use> instance trees (trac-13180)
+ cur.nodeType &&
+
+ // Support: Firefox <=42
+ // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)
+ // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click
+ // Support: IE 11 only
+ // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)
+ !( event.type === "click" && event.button >= 1 ) ) {
+
+ for ( ; cur !== this; cur = cur.parentNode || this ) {
+
+ // Don't check non-elements (#13208)
+ // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
+ if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) {
+ matchedHandlers = [];
+ matchedSelectors = {};
+ for ( i = 0; i < delegateCount; i++ ) {
+ handleObj = handlers[ i ];
+
+ // Don't conflict with Object.prototype properties (#13203)
+ sel = handleObj.selector + " ";
+
+ if ( matchedSelectors[ sel ] === undefined ) {
+ matchedSelectors[ sel ] = handleObj.needsContext ?
+ jQuery( sel, this ).index( cur ) > -1 :
+ jQuery.find( sel, this, null, [ cur ] ).length;
+ }
+ if ( matchedSelectors[ sel ] ) {
+ matchedHandlers.push( handleObj );
+ }
+ }
+ if ( matchedHandlers.length ) {
+ handlerQueue.push( { elem: cur, handlers: matchedHandlers } );
+ }
+ }
+ }
+ }
+
+ // Add the remaining (directly-bound) handlers
+ cur = this;
+ if ( delegateCount < handlers.length ) {
+ handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );
+ }
+
+ return handlerQueue;
+ },
+
+ addProp: function( name, hook ) {
+ Object.defineProperty( jQuery.Event.prototype, name, {
+ enumerable: true,
+ configurable: true,
+
+ get: jQuery.isFunction( hook ) ?
+ function() {
+ if ( this.originalEvent ) {
+ return hook( this.originalEvent );
+ }
+ } :
+ function() {
+ if ( this.originalEvent ) {
+ return this.originalEvent[ name ];
+ }
+ },
+
+ set: function( value ) {
+ Object.defineProperty( this, name, {
+ enumerable: true,
+ configurable: true,
+ writable: true,
+ value: value
+ } );
+ }
+ } );
+ },
+
+ fix: function( originalEvent ) {
+ return originalEvent[ jQuery.expando ] ?
+ originalEvent :
+ new jQuery.Event( originalEvent );
+ },
+
+ special: {
+ load: {
+
+ // Prevent triggered image.load events from bubbling to window.load
+ noBubble: true
+ },
+ focus: {
+
+ // Fire native event if possible so blur/focus sequence is correct
+ trigger: function() {
+ if ( this !== safeActiveElement() && this.focus ) {
+ this.focus();
+ return false;
+ }
+ },
+ delegateType: "focusin"
+ },
+ blur: {
+ trigger: function() {
+ if ( this === safeActiveElement() && this.blur ) {
+ this.blur();
+ return false;
+ }
+ },
+ delegateType: "focusout"
+ },
+ click: {
+
+ // For checkbox, fire native event so checked state will be right
+ trigger: function() {
+ if ( this.type === "checkbox" && this.click && nodeName( this, "input" ) ) {
+ this.click();
+ return false;
+ }
+ },
+
+ // For cross-browser consistency, don't fire native .click() on links
+ _default: function( event ) {
+ return nodeName( event.target, "a" );
+ }
+ },
+
+ beforeunload: {
+ postDispatch: function( event ) {
+
+ // Support: Firefox 20+
+ // Firefox doesn't alert if the returnValue field is not set.
+ if ( event.result !== undefined && event.originalEvent ) {
+ event.originalEvent.returnValue = event.result;
+ }
+ }
+ }
+ }
+};
+
+jQuery.removeEvent = function( elem, type, handle ) {
+
+ // This "if" is needed for plain objects
+ if ( elem.removeEventListener ) {
+ elem.removeEventListener( type, handle );
+ }
+};
+
+jQuery.Event = function( src, props ) {
+
+ // Allow instantiation without the 'new' keyword
+ if ( !( this instanceof jQuery.Event ) ) {
+ return new jQuery.Event( src, props );
+ }
+
+ // Event object
+ if ( src && src.type ) {
+ this.originalEvent = src;
+ this.type = src.type;
+
+ // Events bubbling up the document may have been marked as prevented
+ // by a handler lower down the tree; reflect the correct value.
+ this.isDefaultPrevented = src.defaultPrevented ||
+ src.defaultPrevented === undefined &&
+
+ // Support: Android <=2.3 only
+ src.returnValue === false ?
+ returnTrue :
+ returnFalse;
+
+ // Create target properties
+ // Support: Safari <=6 - 7 only
+ // Target should not be a text node (#504, #13143)
+ this.target = ( src.target && src.target.nodeType === 3 ) ?
+ src.target.parentNode :
+ src.target;
+
+ this.currentTarget = src.currentTarget;
+ this.relatedTarget = src.relatedTarget;
+
+ // Event type
+ } else {
+ this.type = src;
+ }
+
+ // Put explicitly provided properties onto the event object
+ if ( props ) {
+ jQuery.extend( this, props );
+ }
+
+ // Create a timestamp if incoming event doesn't have one
+ this.timeStamp = src && src.timeStamp || jQuery.now();
+
+ // Mark it as fixed
+ this[ jQuery.expando ] = true;
+};
+
+// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
+// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
+jQuery.Event.prototype = {
+ constructor: jQuery.Event,
+ isDefaultPrevented: returnFalse,
+ isPropagationStopped: returnFalse,
+ isImmediatePropagationStopped: returnFalse,
+ isSimulated: false,
+
+ preventDefault: function() {
+ var e = this.originalEvent;
+
+ this.isDefaultPrevented = returnTrue;
+
+ if ( e && !this.isSimulated ) {
+ e.preventDefault();
+ }
+ },
+ stopPropagation: function() {
+ var e = this.originalEvent;
+
+ this.isPropagationStopped = returnTrue;
+
+ if ( e && !this.isSimulated ) {
+ e.stopPropagation();
+ }
+ },
+ stopImmediatePropagation: function() {
+ var e = this.originalEvent;
+
+ this.isImmediatePropagationStopped = returnTrue;
+
+ if ( e && !this.isSimulated ) {
+ e.stopImmediatePropagation();
+ }
+
+ this.stopPropagation();
+ }
+};
+
+// Includes all common event props including KeyEvent and MouseEvent specific props
+jQuery.each( {
+ altKey: true,
+ bubbles: true,
+ cancelable: true,
+ changedTouches: true,
+ ctrlKey: true,
+ detail: true,
+ eventPhase: true,
+ metaKey: true,
+ pageX: true,
+ pageY: true,
+ shiftKey: true,
+ view: true,
+ "char": true,
+ charCode: true,
+ key: true,
+ keyCode: true,
+ button: true,
+ buttons: true,
+ clientX: true,
+ clientY: true,
+ offsetX: true,
+ offsetY: true,
+ pointerId: true,
+ pointerType: true,
+ screenX: true,
+ screenY: true,
+ targetTouches: true,
+ toElement: true,
+ touches: true,
+
+ which: function( event ) {
+ var button = event.button;
+
+ // Add which for key events
+ if ( event.which == null && rkeyEvent.test( event.type ) ) {
+ return event.charCode != null ? event.charCode : event.keyCode;
+ }
+
+ // Add which for click: 1 === left; 2 === middle; 3 === right
+ if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {
+ if ( button & 1 ) {
+ return 1;
+ }
+
+ if ( button & 2 ) {
+ return 3;
+ }
+
+ if ( button & 4 ) {
+ return 2;
+ }
+
+ return 0;
+ }
+
+ return event.which;
+ }
+}, jQuery.event.addProp );
+
+// Create mouseenter/leave events using mouseover/out and event-time checks
+// so that event delegation works in jQuery.
+// Do the same for pointerenter/pointerleave and pointerover/pointerout
+//
+// Support: Safari 7 only
+// Safari sends mouseenter too often; see:
+// https://bugs.chromium.org/p/chromium/issues/detail?id=470258
+// for the description of the bug (it existed in older Chrome versions as well).
+jQuery.each( {
+ mouseenter: "mouseover",
+ mouseleave: "mouseout",
+ pointerenter: "pointerover",
+ pointerleave: "pointerout"
+}, function( orig, fix ) {
+ jQuery.event.special[ orig ] = {
+ delegateType: fix,
+ bindType: fix,
+
+ handle: function( event ) {
+ var ret,
+ target = this,
+ related = event.relatedTarget,
+ handleObj = event.handleObj;
+
+ // For mouseenter/leave call the handler if related is outside the target.
+ // NB: No relatedTarget if the mouse left/entered the browser window
+ if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
+ event.type = handleObj.origType;
+ ret = handleObj.handler.apply( this, arguments );
+ event.type = fix;
+ }
+ return ret;
+ }
+ };
+} );
+
+jQuery.fn.extend( {
+
+ on: function( types, selector, data, fn ) {
+ return on( this, types, selector, data, fn );
+ },
+ one: function( types, selector, data, fn ) {
+ return on( this, types, selector, data, fn, 1 );
+ },
+ off: function( types, selector, fn ) {
+ var handleObj, type;
+ if ( types && types.preventDefault && types.handleObj ) {
+
+ // ( event ) dispatched jQuery.Event
+ handleObj = types.handleObj;
+ jQuery( types.delegateTarget ).off(
+ handleObj.namespace ?
+ handleObj.origType + "." + handleObj.namespace :
+ handleObj.origType,
+ handleObj.selector,
+ handleObj.handler
+ );
+ return this;
+ }
+ if ( typeof types === "object" ) {
+
+ // ( types-object [, selector] )
+ for ( type in types ) {
+ this.off( type, selector, types[ type ] );
+ }
+ return this;
+ }
+ if ( selector === false || typeof selector === "function" ) {
+
+ // ( types [, fn] )
+ fn = selector;
+ selector = undefined;
+ }
+ if ( fn === false ) {
+ fn = returnFalse;
+ }
+ return this.each( function() {
+ jQuery.event.remove( this, types, fn, selector );
+ } );
+ }
+} );
+
+
+var
+
+ /* eslint-disable max-len */
+
+ // See https://github.com/eslint/eslint/issues/3229
+ rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,
+
+ /* eslint-enable */
+
+ // Support: IE <=10 - 11, Edge 12 - 13
+ // In IE/Edge using regex groups here causes severe slowdowns.
+ // See https://connect.microsoft.com/IE/feedback/details/1736512/
+ rnoInnerhtml = /<script|<style|<link/i,
+
+ // checked="checked" or checked
+ rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
+ rscriptTypeMasked = /^true\/(.*)/,
+ rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;
+
+// Prefer a tbody over its parent table for containing new rows
+function manipulationTarget( elem, content ) {
+ if ( nodeName( elem, "table" ) &&
+ nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) {
+
+ return jQuery( ">tbody", elem )[ 0 ] || elem;
+ }
+
+ return elem;
+}
+
+// Replace/restore the type attribute of script elements for safe DOM manipulation
+function disableScript( elem ) {
+ elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type;
+ return elem;
+}
+function restoreScript( elem ) {
+ var match = rscriptTypeMasked.exec( elem.type );
+
+ if ( match ) {
+ elem.type = match[ 1 ];
+ } else {
+ elem.removeAttribute( "type" );
+ }
+
+ return elem;
+}
+
+function cloneCopyEvent( src, dest ) {
+ var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;
+
+ if ( dest.nodeType !== 1 ) {
+ return;
+ }
+
+ // 1. Copy private data: events, handlers, etc.
+ if ( dataPriv.hasData( src ) ) {
+ pdataOld = dataPriv.access( src );
+ pdataCur = dataPriv.set( dest, pdataOld );
+ events = pdataOld.events;
+
+ if ( events ) {
+ delete pdataCur.handle;
+ pdataCur.events = {};
+
+ for ( type in events ) {
+ for ( i = 0, l = events[ type ].length; i < l; i++ ) {
+ jQuery.event.add( dest, type, events[ type ][ i ] );
+ }
+ }
+ }
+ }
+
+ // 2. Copy user data
+ if ( dataUser.hasData( src ) ) {
+ udataOld = dataUser.access( src );
+ udataCur = jQuery.extend( {}, udataOld );
+
+ dataUser.set( dest, udataCur );
+ }
+}
+
+// Fix IE bugs, see support tests
+function fixInput( src, dest ) {
+ var nodeName = dest.nodeName.toLowerCase();
+
+ // Fails to persist the checked state of a cloned checkbox or radio button.
+ if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
+ dest.checked = src.checked;
+
+ // Fails to return the selected option to the default selected state when cloning options
+ } else if ( nodeName === "input" || nodeName === "textarea" ) {
+ dest.defaultValue = src.defaultValue;
+ }
+}
+
+function domManip( collection, args, callback, ignored ) {
+
+ // Flatten any nested arrays
+ args = concat.apply( [], args );
+
+ var fragment, first, scripts, hasScripts, node, doc,
+ i = 0,
+ l = collection.length,
+ iNoClone = l - 1,
+ value = args[ 0 ],
+ isFunction = jQuery.isFunction( value );
+
+ // We can't cloneNode fragments that contain checked, in WebKit
+ if ( isFunction ||
+ ( l > 1 && typeof value === "string" &&
+ !support.checkClone && rchecked.test( value ) ) ) {
+ return collection.each( function( index ) {
+ var self = collection.eq( index );
+ if ( isFunction ) {
+ args[ 0 ] = value.call( this, index, self.html() );
+ }
+ domManip( self, args, callback, ignored );
+ } );
+ }
+
+ if ( l ) {
+ fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
+ first = fragment.firstChild;
+
+ if ( fragment.childNodes.length === 1 ) {
+ fragment = first;
+ }
+
+ // Require either new content or an interest in ignored elements to invoke the callback
+ if ( first || ignored ) {
+ scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
+ hasScripts = scripts.length;
+
+ // Use the original fragment for the last item
+ // instead of the first because it can end up
+ // being emptied incorrectly in certain situations (#8070).
+ for ( ; i < l; i++ ) {
+ node = fragment;
+
+ if ( i !== iNoClone ) {
+ node = jQuery.clone( node, true, true );
+
+ // Keep references to cloned scripts for later restoration
+ if ( hasScripts ) {
+
+ // Support: Android <=4.0 only, PhantomJS 1 only
+ // push.apply(_, arraylike) throws on ancient WebKit
+ jQuery.merge( scripts, getAll( node, "script" ) );
+ }
+ }
+
+ callback.call( collection[ i ], node, i );
+ }
+
+ if ( hasScripts ) {
+ doc = scripts[ scripts.length - 1 ].ownerDocument;
+
+ // Reenable scripts
+ jQuery.map( scripts, restoreScript );
+
+ // Evaluate executable scripts on first document insertion
+ for ( i = 0; i < hasScripts; i++ ) {
+ node = scripts[ i ];
+ if ( rscriptType.test( node.type || "" ) &&
+ !dataPriv.access( node, "globalEval" ) &&
+ jQuery.contains( doc, node ) ) {
+
+ if ( node.src ) {
+
+ // Optional AJAX dependency, but won't run scripts if not present
+ if ( jQuery._evalUrl ) {
+ jQuery._evalUrl( node.src );
+ }
+ } else {
+ DOMEval( node.textContent.replace( rcleanScript, "" ), doc );
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return collection;
+}
+
+function remove( elem, selector, keepData ) {
+ var node,
+ nodes = selector ? jQuery.filter( selector, elem ) : elem,
+ i = 0;
+
+ for ( ; ( node = nodes[ i ] ) != null; i++ ) {
+ if ( !keepData && node.nodeType === 1 ) {
+ jQuery.cleanData( getAll( node ) );
+ }
+
+ if ( node.parentNode ) {
+ if ( keepData && jQuery.contains( node.ownerDocument, node ) ) {
+ setGlobalEval( getAll( node, "script" ) );
+ }
+ node.parentNode.removeChild( node );
+ }
+ }
+
+ return elem;
+}
+
+jQuery.extend( {
+ htmlPrefilter: function( html ) {
+ return html.replace( rxhtmlTag, "<$1></$2>" );
+ },
+
+ clone: function( elem, dataAndEvents, deepDataAndEvents ) {
+ var i, l, srcElements, destElements,
+ clone = elem.cloneNode( true ),
+ inPage = jQuery.contains( elem.ownerDocument, elem );
+
+ // Fix IE cloning issues
+ if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
+ !jQuery.isXMLDoc( elem ) ) {
+
+ // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2
+ destElements = getAll( clone );
+ srcElements = getAll( elem );
+
+ for ( i = 0, l = srcElements.length; i < l; i++ ) {
+ fixInput( srcElements[ i ], destElements[ i ] );
+ }
+ }
+
+ // Copy the events from the original to the clone
+ if ( dataAndEvents ) {
+ if ( deepDataAndEvents ) {
+ srcElements = srcElements || getAll( elem );
+ destElements = destElements || getAll( clone );
+
+ for ( i = 0, l = srcElements.length; i < l; i++ ) {
+ cloneCopyEvent( srcElements[ i ], destElements[ i ] );
+ }
+ } else {
+ cloneCopyEvent( elem, clone );
+ }
+ }
+
+ // Preserve script evaluation history
+ destElements = getAll( clone, "script" );
+ if ( destElements.length > 0 ) {
+ setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
+ }
+
+ // Return the cloned set
+ return clone;
+ },
+
+ cleanData: function( elems ) {
+ var data, elem, type,
+ special = jQuery.event.special,
+ i = 0;
+
+ for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {
+ if ( acceptData( elem ) ) {
+ if ( ( data = elem[ dataPriv.expando ] ) ) {
+ if ( data.events ) {
+ for ( type in data.events ) {
+ if ( special[ type ] ) {
+ jQuery.event.remove( elem, type );
+
+ // This is a shortcut to avoid jQuery.event.remove's overhead
+ } else {
+ jQuery.removeEvent( elem, type, data.handle );
+ }
+ }
+ }
+
+ // Support: Chrome <=35 - 45+
+ // Assign undefined instead of using delete, see Data#remove
+ elem[ dataPriv.expando ] = undefined;
+ }
+ if ( elem[ dataUser.expando ] ) {
+
+ // Support: Chrome <=35 - 45+
+ // Assign undefined instead of using delete, see Data#remove
+ elem[ dataUser.expando ] = undefined;
+ }
+ }
+ }
+ }
+} );
+
+jQuery.fn.extend( {
+ detach: function( selector ) {
+ return remove( this, selector, true );
+ },
+
+ remove: function( selector ) {
+ return remove( this, selector );
+ },
+
+ text: function( value ) {
+ return access( this, function( value ) {
+ return value === undefined ?
+ jQuery.text( this ) :
+ this.empty().each( function() {
+ if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
+ this.textContent = value;
+ }
+ } );
+ }, null, value, arguments.length );
+ },
+
+ append: function() {
+ return domManip( this, arguments, function( elem ) {
+ if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
+ var target = manipulationTarget( this, elem );
+ target.appendChild( elem );
+ }
+ } );
+ },
+
+ prepend: function() {
+ return domManip( this, arguments, function( elem ) {
+ if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
+ var target = manipulationTarget( this, elem );
+ target.insertBefore( elem, target.firstChild );
+ }
+ } );
+ },
+
+ before: function() {
+ return domManip( this, arguments, function( elem ) {
+ if ( this.parentNode ) {
+ this.parentNode.insertBefore( elem, this );
+ }
+ } );
+ },
+
+ after: function() {
+ return domManip( this, arguments, function( elem ) {
+ if ( this.parentNode ) {
+ this.parentNode.insertBefore( elem, this.nextSibling );
+ }
+ } );
+ },
+
+ empty: function() {
+ var elem,
+ i = 0;
+
+ for ( ; ( elem = this[ i ] ) != null; i++ ) {
+ if ( elem.nodeType === 1 ) {
+
+ // Prevent memory leaks
+ jQuery.cleanData( getAll( elem, false ) );
+
+ // Remove any remaining nodes
+ elem.textContent = "";
+ }
+ }
+
+ return this;
+ },
+
+ clone: function( dataAndEvents, deepDataAndEvents ) {
+ dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
+ deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
+
+ return this.map( function() {
+ return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
+ } );
+ },
+
+ html: function( value ) {
+ return access( this, function( value ) {
+ var elem = this[ 0 ] || {},
+ i = 0,
+ l = this.length;
+
+ if ( value === undefined && elem.nodeType === 1 ) {
+ return elem.innerHTML;
+ }
+
+ // See if we can take a shortcut and just use innerHTML
+ if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
+ !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
+
+ value = jQuery.htmlPrefilter( value );
+
+ try {
+ for ( ; i < l; i++ ) {
+ elem = this[ i ] || {};
+
+ // Remove element nodes and prevent memory leaks
+ if ( elem.nodeType === 1 ) {
+ jQuery.cleanData( getAll( elem, false ) );
+ elem.innerHTML = value;
+ }
+ }
+
+ elem = 0;
+
+ // If using innerHTML throws an exception, use the fallback method
+ } catch ( e ) {}
+ }
+
+ if ( elem ) {
+ this.empty().append( value );
+ }
+ }, null, value, arguments.length );
+ },
+
+ replaceWith: function() {
+ var ignored = [];
+
+ // Make the changes, replacing each non-ignored context element with the new content
+ return domManip( this, arguments, function( elem ) {
+ var parent = this.parentNode;
+
+ if ( jQuery.inArray( this, ignored ) < 0 ) {
+ jQuery.cleanData( getAll( this ) );
+ if ( parent ) {
+ parent.replaceChild( elem, this );
+ }
+ }
+
+ // Force callback invocation
+ }, ignored );
+ }
+} );
+
+jQuery.each( {
+ appendTo: "append",
+ prependTo: "prepend",
+ insertBefore: "before",
+ insertAfter: "after",
+ replaceAll: "replaceWith"
+}, function( name, original ) {
+ jQuery.fn[ name ] = function( selector ) {
+ var elems,
+ ret = [],
+ insert = jQuery( selector ),
+ last = insert.length - 1,
+ i = 0;
+
+ for ( ; i <= last; i++ ) {
+ elems = i === last ? this : this.clone( true );
+ jQuery( insert[ i ] )[ original ]( elems );
+
+ // Support: Android <=4.0 only, PhantomJS 1 only
+ // .get() because push.apply(_, arraylike) throws on ancient WebKit
+ push.apply( ret, elems.get() );
+ }
+
+ return this.pushStack( ret );
+ };
+} );
+var rmargin = ( /^margin/ );
+
+var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
+
+var getStyles = function( elem ) {
+
+ // Support: IE <=11 only, Firefox <=30 (#15098, #14150)
+ // IE throws on elements created in popups
+ // FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
+ var view = elem.ownerDocument.defaultView;
+
+ if ( !view || !view.opener ) {
+ view = window;
+ }
+
+ return view.getComputedStyle( elem );
+ };
+
+
+
+( function() {
+
+ // Executing both pixelPosition & boxSizingReliable tests require only one layout
+ // so they're executed at the same time to save the second computation.
+ function computeStyleTests() {
+
+ // This is a singleton, we need to execute it only once
+ if ( !div ) {
+ return;
+ }
+
+ div.style.cssText =
+ "box-sizing:border-box;" +
+ "position:relative;display:block;" +
+ "margin:auto;border:1px;padding:1px;" +
+ "top:1%;width:50%";
+ div.innerHTML = "";
+ documentElement.appendChild( container );
+
+ var divStyle = window.getComputedStyle( div );
+ pixelPositionVal = divStyle.top !== "1%";
+
+ // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44
+ reliableMarginLeftVal = divStyle.marginLeft === "2px";
+ boxSizingReliableVal = divStyle.width === "4px";
+
+ // Support: Android 4.0 - 4.3 only
+ // Some styles come back with percentage values, even though they shouldn't
+ div.style.marginRight = "50%";
+ pixelMarginRightVal = divStyle.marginRight === "4px";
+
+ documentElement.removeChild( container );
+
+ // Nullify the div so it wouldn't be stored in the memory and
+ // it will also be a sign that checks already performed
+ div = null;
+ }
+
+ var pixelPositionVal, boxSizingReliableVal, pixelMarginRightVal, reliableMarginLeftVal,
+ container = document.createElement( "div" ),
+ div = document.createElement( "div" );
+
+ // Finish early in limited (non-browser) environments
+ if ( !div.style ) {
+ return;
+ }
+
+ // Support: IE <=9 - 11 only
+ // Style of cloned element affects source element cloned (#8908)
+ div.style.backgroundClip = "content-box";
+ div.cloneNode( true ).style.backgroundClip = "";
+ support.clearCloneStyle = div.style.backgroundClip === "content-box";
+
+ container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" +
+ "padding:0;margin-top:1px;position:absolute";
+ container.appendChild( div );
+
+ jQuery.extend( support, {
+ pixelPosition: function() {
+ computeStyleTests();
+ return pixelPositionVal;
+ },
+ boxSizingReliable: function() {
+ computeStyleTests();
+ return boxSizingReliableVal;
+ },
+ pixelMarginRight: function() {
+ computeStyleTests();
+ return pixelMarginRightVal;
+ },
+ reliableMarginLeft: function() {
+ computeStyleTests();
+ return reliableMarginLeftVal;
+ }
+ } );
+} )();
+
+
+function curCSS( elem, name, computed ) {
+ var width, minWidth, maxWidth, ret,
+
+ // Support: Firefox 51+
+ // Retrieving style before computed somehow
+ // fixes an issue with getting wrong values
+ // on detached elements
+ style = elem.style;
+
+ computed = computed || getStyles( elem );
+
+ // getPropertyValue is needed for:
+ // .css('filter') (IE 9 only, #12537)
+ // .css('--customProperty) (#3144)
+ if ( computed ) {
+ ret = computed.getPropertyValue( name ) || computed[ name ];
+
+ if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
+ ret = jQuery.style( elem, name );
+ }
+
+ // A tribute to the "awesome hack by Dean Edwards"
+ // Android Browser returns percentage for some values,
+ // but width seems to be reliably pixels.
+ // This is against the CSSOM draft spec:
+ // https://drafts.csswg.org/cssom/#resolved-values
+ if ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) {
+
+ // Remember the original values
+ width = style.width;
+ minWidth = style.minWidth;
+ maxWidth = style.maxWidth;
+
+ // Put in the new values to get a computed value out
+ style.minWidth = style.maxWidth = style.width = ret;
+ ret = computed.width;
+
+ // Revert the changed values
+ style.width = width;
+ style.minWidth = minWidth;
+ style.maxWidth = maxWidth;
+ }
+ }
+
+ return ret !== undefined ?
+
+ // Support: IE <=9 - 11 only
+ // IE returns zIndex value as an integer.
+ ret + "" :
+ ret;
+}
+
+
+function addGetHookIf( conditionFn, hookFn ) {
+
+ // Define the hook, we'll check on the first run if it's really needed.
+ return {
+ get: function() {
+ if ( conditionFn() ) {
+
+ // Hook not needed (or it's not possible to use it due
+ // to missing dependency), remove it.
+ delete this.get;
+ return;
+ }
+
+ // Hook needed; redefine it so that the support test is not executed again.
+ return ( this.get = hookFn ).apply( this, arguments );
+ }
+ };
+}
+
+
+var
+
+ // Swappable if display is none or starts with table
+ // except "table", "table-cell", or "table-caption"
+ // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
+ rdisplayswap = /^(none|table(?!-c[ea]).+)/,
+ rcustomProp = /^--/,
+ cssShow = { position: "absolute", visibility: "hidden", display: "block" },
+ cssNormalTransform = {
+ letterSpacing: "0",
+ fontWeight: "400"
+ },
+
+ cssPrefixes = [ "Webkit", "Moz", "ms" ],
+ emptyStyle = document.createElement( "div" ).style;
+
+// Return a css property mapped to a potentially vendor prefixed property
+function vendorPropName( name ) {
+
+ // Shortcut for names that are not vendor prefixed
+ if ( name in emptyStyle ) {
+ return name;
+ }
+
+ // Check for vendor prefixed names
+ var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),
+ i = cssPrefixes.length;
+
+ while ( i-- ) {
+ name = cssPrefixes[ i ] + capName;
+ if ( name in emptyStyle ) {
+ return name;
+ }
+ }
+}
+
+// Return a property mapped along what jQuery.cssProps suggests or to
+// a vendor prefixed property.
+function finalPropName( name ) {
+ var ret = jQuery.cssProps[ name ];
+ if ( !ret ) {
+ ret = jQuery.cssProps[ name ] = vendorPropName( name ) || name;
+ }
+ return ret;
+}
+
+function setPositiveNumber( elem, value, subtract ) {
+
+ // Any relative (+/-) values have already been
+ // normalized at this point
+ var matches = rcssNum.exec( value );
+ return matches ?
+
+ // Guard against undefined "subtract", e.g., when used as in cssHooks
+ Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :
+ value;
+}
+
+function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
+ var i,
+ val = 0;
+
+ // If we already have the right measurement, avoid augmentation
+ if ( extra === ( isBorderBox ? "border" : "content" ) ) {
+ i = 4;
+
+ // Otherwise initialize for horizontal or vertical properties
+ } else {
+ i = name === "width" ? 1 : 0;
+ }
+
+ for ( ; i < 4; i += 2 ) {
+
+ // Both box models exclude margin, so add it if we want it
+ if ( extra === "margin" ) {
+ val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
+ }
+
+ if ( isBorderBox ) {
+
+ // border-box includes padding, so remove it if we want content
+ if ( extra === "content" ) {
+ val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
+ }
+
+ // At this point, extra isn't border nor margin, so remove border
+ if ( extra !== "margin" ) {
+ val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
+ }
+ } else {
+
+ // At this point, extra isn't content, so add padding
+ val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
+
+ // At this point, extra isn't content nor padding, so add border
+ if ( extra !== "padding" ) {
+ val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
+ }
+ }
+ }
+
+ return val;
+}
+
+function getWidthOrHeight( elem, name, extra ) {
+
+ // Start with computed style
+ var valueIsBorderBox,
+ styles = getStyles( elem ),
+ val = curCSS( elem, name, styles ),
+ isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
+
+ // Computed unit is not pixels. Stop here and return.
+ if ( rnumnonpx.test( val ) ) {
+ return val;
+ }
+
+ // Check for style in case a browser which returns unreliable values
+ // for getComputedStyle silently falls back to the reliable elem.style
+ valueIsBorderBox = isBorderBox &&
+ ( support.boxSizingReliable() || val === elem.style[ name ] );
+
+ // Fall back to offsetWidth/Height when value is "auto"
+ // This happens for inline elements with no explicit setting (gh-3571)
+ if ( val === "auto" ) {
+ val = elem[ "offset" + name[ 0 ].toUpperCase() + name.slice( 1 ) ];
+ }
+
+ // Normalize "", auto, and prepare for extra
+ val = parseFloat( val ) || 0;
+
+ // Use the active box-sizing model to add/subtract irrelevant styles
+ return ( val +
+ augmentWidthOrHeight(
+ elem,
+ name,
+ extra || ( isBorderBox ? "border" : "content" ),
+ valueIsBorderBox,
+ styles
+ )
+ ) + "px";
+}
+
+jQuery.extend( {
+
+ // Add in style property hooks for overriding the default
+ // behavior of getting and setting a style property
+ cssHooks: {
+ opacity: {
+ get: function( elem, computed ) {
+ if ( computed ) {
+
+ // We should always get a number back from opacity
+ var ret = curCSS( elem, "opacity" );
+ return ret === "" ? "1" : ret;
+ }
+ }
+ }
+ },
+
+ // Don't automatically add "px" to these possibly-unitless properties
+ cssNumber: {
+ "animationIterationCount": true,
+ "columnCount": true,
+ "fillOpacity": true,
+ "flexGrow": true,
+ "flexShrink": true,
+ "fontWeight": true,
+ "lineHeight": true,
+ "opacity": true,
+ "order": true,
+ "orphans": true,
+ "widows": true,
+ "zIndex": true,
+ "zoom": true
+ },
+
+ // Add in properties whose names you wish to fix before
+ // setting or getting the value
+ cssProps: {
+ "float": "cssFloat"
+ },
+
+ // Get and set the style property on a DOM Node
+ style: function( elem, name, value, extra ) {
+
+ // Don't set styles on text and comment nodes
+ if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
+ return;
+ }
+
+ // Make sure that we're working with the right name
+ var ret, type, hooks,
+ origName = jQuery.camelCase( name ),
+ isCustomProp = rcustomProp.test( name ),
+ style = elem.style;
+
+ // Make sure that we're working with the right name. We don't
+ // want to query the value if it is a CSS custom property
+ // since they are user-defined.
+ if ( !isCustomProp ) {
+ name = finalPropName( origName );
+ }
+
+ // Gets hook for the prefixed version, then unprefixed version
+ hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
+
+ // Check if we're setting a value
+ if ( value !== undefined ) {
+ type = typeof value;
+
+ // Convert "+=" or "-=" to relative numbers (#7345)
+ if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
+ value = adjustCSS( elem, name, ret );
+
+ // Fixes bug #9237
+ type = "number";
+ }
+
+ // Make sure that null and NaN values aren't set (#7116)
+ if ( value == null || value !== value ) {
+ return;
+ }
+
+ // If a number was passed in, add the unit (except for certain CSS properties)
+ if ( type === "number" ) {
+ value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
+ }
+
+ // background-* props affect original clone's values
+ if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
+ style[ name ] = "inherit";
+ }
+
+ // If a hook was provided, use that value, otherwise just set the specified value
+ if ( !hooks || !( "set" in hooks ) ||
+ ( value = hooks.set( elem, value, extra ) ) !== undefined ) {
+
+ if ( isCustomProp ) {
+ style.setProperty( name, value );
+ } else {
+ style[ name ] = value;
+ }
+ }
+
+ } else {
+
+ // If a hook was provided get the non-computed value from there
+ if ( hooks && "get" in hooks &&
+ ( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
+
+ return ret;
+ }
+
+ // Otherwise just get the value from the style object
+ return style[ name ];
+ }
+ },
+
+ css: function( elem, name, extra, styles ) {
+ var val, num, hooks,
+ origName = jQuery.camelCase( name ),
+ isCustomProp = rcustomProp.test( name );
+
+ // Make sure that we're working with the right name. We don't
+ // want to modify the value if it is a CSS custom property
+ // since they are user-defined.
+ if ( !isCustomProp ) {
+ name = finalPropName( origName );
+ }
+
+ // Try prefixed name followed by the unprefixed name
+ hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
+
+ // If a hook was provided get the computed value from there
+ if ( hooks && "get" in hooks ) {
+ val = hooks.get( elem, true, extra );
+ }
+
+ // Otherwise, if a way to get the computed value exists, use that
+ if ( val === undefined ) {
+ val = curCSS( elem, name, styles );
+ }
+
+ // Convert "normal" to computed value
+ if ( val === "normal" && name in cssNormalTransform ) {
+ val = cssNormalTransform[ name ];
+ }
+
+ // Make numeric if forced or a qualifier was provided and val looks numeric
+ if ( extra === "" || extra ) {
+ num = parseFloat( val );
+ return extra === true || isFinite( num ) ? num || 0 : val;
+ }
+
+ return val;
+ }
+} );
+
+jQuery.each( [ "height", "width" ], function( i, name ) {
+ jQuery.cssHooks[ name ] = {
+ get: function( elem, computed, extra ) {
+ if ( computed ) {
+
+ // Certain elements can have dimension info if we invisibly show them
+ // but it must have a current display style that would benefit
+ return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
+
+ // Support: Safari 8+
+ // Table columns in Safari have non-zero offsetWidth & zero
+ // getBoundingClientRect().width unless display is changed.
+ // Support: IE <=11 only
+ // Running getBoundingClientRect on a disconnected node
+ // in IE throws an error.
+ ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?
+ swap( elem, cssShow, function() {
+ return getWidthOrHeight( elem, name, extra );
+ } ) :
+ getWidthOrHeight( elem, name, extra );
+ }
+ },
+
+ set: function( elem, value, extra ) {
+ var matches,
+ styles = extra && getStyles( elem ),
+ subtract = extra && augmentWidthOrHeight(
+ elem,
+ name,
+ extra,
+ jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
+ styles
+ );
+
+ // Convert to pixels if value adjustment is needed
+ if ( subtract && ( matches = rcssNum.exec( value ) ) &&
+ ( matches[ 3 ] || "px" ) !== "px" ) {
+
+ elem.style[ name ] = value;
+ value = jQuery.css( elem, name );
+ }
+
+ return setPositiveNumber( elem, value, subtract );
+ }
+ };
+} );
+
+jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
+ function( elem, computed ) {
+ if ( computed ) {
+ return ( parseFloat( curCSS( elem, "marginLeft" ) ) ||
+ elem.getBoundingClientRect().left -
+ swap( elem, { marginLeft: 0 }, function() {
+ return elem.getBoundingClientRect().left;
+ } )
+ ) + "px";
+ }
+ }
+);
+
+// These hooks are used by animate to expand properties
+jQuery.each( {
+ margin: "",
+ padding: "",
+ border: "Width"
+}, function( prefix, suffix ) {
+ jQuery.cssHooks[ prefix + suffix ] = {
+ expand: function( value ) {
+ var i = 0,
+ expanded = {},
+
+ // Assumes a single number if not a string
+ parts = typeof value === "string" ? value.split( " " ) : [ value ];
+
+ for ( ; i < 4; i++ ) {
+ expanded[ prefix + cssExpand[ i ] + suffix ] =
+ parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
+ }
+
+ return expanded;
+ }
+ };
+
+ if ( !rmargin.test( prefix ) ) {
+ jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
+ }
+} );
+
+jQuery.fn.extend( {
+ css: function( name, value ) {
+ return access( this, function( elem, name, value ) {
+ var styles, len,
+ map = {},
+ i = 0;
+
+ if ( Array.isArray( name ) ) {
+ styles = getStyles( elem );
+ len = name.length;
+
+ for ( ; i < len; i++ ) {
+ map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
+ }
+
+ return map;
+ }
+
+ return value !== undefined ?
+ jQuery.style( elem, name, value ) :
+ jQuery.css( elem, name );
+ }, name, value, arguments.length > 1 );
+ }
+} );
+
+
+function Tween( elem, options, prop, end, easing ) {
+ return new Tween.prototype.init( elem, options, prop, end, easing );
+}
+jQuery.Tween = Tween;
+
+Tween.prototype = {
+ constructor: Tween,
+ init: function( elem, options, prop, end, easing, unit ) {
+ this.elem = elem;
+ this.prop = prop;
+ this.easing = easing || jQuery.easing._default;
+ this.options = options;
+ this.start = this.now = this.cur();
+ this.end = end;
+ this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
+ },
+ cur: function() {
+ var hooks = Tween.propHooks[ this.prop ];
+
+ return hooks && hooks.get ?
+ hooks.get( this ) :
+ Tween.propHooks._default.get( this );
+ },
+ run: function( percent ) {
+ var eased,
+ hooks = Tween.propHooks[ this.prop ];
+
+ if ( this.options.duration ) {
+ this.pos = eased = jQuery.easing[ this.easing ](
+ percent, this.options.duration * percent, 0, 1, this.options.duration
+ );
+ } else {
+ this.pos = eased = percent;
+ }
+ this.now = ( this.end - this.start ) * eased + this.start;
+
+ if ( this.options.step ) {
+ this.options.step.call( this.elem, this.now, this );
+ }
+
+ if ( hooks && hooks.set ) {
+ hooks.set( this );
+ } else {
+ Tween.propHooks._default.set( this );
+ }
+ return this;
+ }
+};
+
+Tween.prototype.init.prototype = Tween.prototype;
+
+Tween.propHooks = {
+ _default: {
+ get: function( tween ) {
+ var result;
+
+ // Use a property on the element directly when it is not a DOM element,
+ // or when there is no matching style property that exists.
+ if ( tween.elem.nodeType !== 1 ||
+ tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
+ return tween.elem[ tween.prop ];
+ }
+
+ // Passing an empty string as a 3rd parameter to .css will automatically
+ // attempt a parseFloat and fallback to a string if the parse fails.
+ // Simple values such as "10px" are parsed to Float;
+ // complex values such as "rotate(1rad)" are returned as-is.
+ result = jQuery.css( tween.elem, tween.prop, "" );
+
+ // Empty strings, null, undefined and "auto" are converted to 0.
+ return !result || result === "auto" ? 0 : result;
+ },
+ set: function( tween ) {
+
+ // Use step hook for back compat.
+ // Use cssHook if its there.
+ // Use .style if available and use plain properties where available.
+ if ( jQuery.fx.step[ tween.prop ] ) {
+ jQuery.fx.step[ tween.prop ]( tween );
+ } else if ( tween.elem.nodeType === 1 &&
+ ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null ||
+ jQuery.cssHooks[ tween.prop ] ) ) {
+ jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
+ } else {
+ tween.elem[ tween.prop ] = tween.now;
+ }
+ }
+ }
+};
+
+// Support: IE <=9 only
+// Panic based approach to setting things on disconnected nodes
+Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
+ set: function( tween ) {
+ if ( tween.elem.nodeType && tween.elem.parentNode ) {
+ tween.elem[ tween.prop ] = tween.now;
+ }
+ }
+};
+
+jQuery.easing = {
+ linear: function( p ) {
+ return p;
+ },
+ swing: function( p ) {
+ return 0.5 - Math.cos( p * Math.PI ) / 2;
+ },
+ _default: "swing"
+};
+
+jQuery.fx = Tween.prototype.init;
+
+// Back compat <1.8 extension point
+jQuery.fx.step = {};
+
+
+
+
+var
+ fxNow, inProgress,
+ rfxtypes = /^(?:toggle|show|hide)$/,
+ rrun = /queueHooks$/;
+
+function schedule() {
+ if ( inProgress ) {
+ if ( document.hidden === false && window.requestAnimationFrame ) {
+ window.requestAnimationFrame( schedule );
+ } else {
+ window.setTimeout( schedule, jQuery.fx.interval );
+ }
+
+ jQuery.fx.tick();
+ }
+}
+
+// Animations created synchronously will run synchronously
+function createFxNow() {
+ window.setTimeout( function() {
+ fxNow = undefined;
+ } );
+ return ( fxNow = jQuery.now() );
+}
+
+// Generate parameters to create a standard animation
+function genFx( type, includeWidth ) {
+ var which,
+ i = 0,
+ attrs = { height: type };
+
+ // If we include width, step value is 1 to do all cssExpand values,
+ // otherwise step value is 2 to skip over Left and Right
+ includeWidth = includeWidth ? 1 : 0;
+ for ( ; i < 4; i += 2 - includeWidth ) {
+ which = cssExpand[ i ];
+ attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
+ }
+
+ if ( includeWidth ) {
+ attrs.opacity = attrs.width = type;
+ }
+
+ return attrs;
+}
+
+function createTween( value, prop, animation ) {
+ var tween,
+ collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
+ index = 0,
+ length = collection.length;
+ for ( ; index < length; index++ ) {
+ if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
+
+ // We're done with this property
+ return tween;
+ }
+ }
+}
+
+function defaultPrefilter( elem, props, opts ) {
+ var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,
+ isBox = "width" in props || "height" in props,
+ anim = this,
+ orig = {},
+ style = elem.style,
+ hidden = elem.nodeType && isHiddenWithinTree( elem ),
+ dataShow = dataPriv.get( elem, "fxshow" );
+
+ // Queue-skipping animations hijack the fx hooks
+ if ( !opts.queue ) {
+ hooks = jQuery._queueHooks( elem, "fx" );
+ if ( hooks.unqueued == null ) {
+ hooks.unqueued = 0;
+ oldfire = hooks.empty.fire;
+ hooks.empty.fire = function() {
+ if ( !hooks.unqueued ) {
+ oldfire();
+ }
+ };
+ }
+ hooks.unqueued++;
+
+ anim.always( function() {
+
+ // Ensure the complete handler is called before this completes
+ anim.always( function() {
+ hooks.unqueued--;
+ if ( !jQuery.queue( elem, "fx" ).length ) {
+ hooks.empty.fire();
+ }
+ } );
+ } );
+ }
+
+ // Detect show/hide animations
+ for ( prop in props ) {
+ value = props[ prop ];
+ if ( rfxtypes.test( value ) ) {
+ delete props[ prop ];
+ toggle = toggle || value === "toggle";
+ if ( value === ( hidden ? "hide" : "show" ) ) {
+
+ // Pretend to be hidden if this is a "show" and
+ // there is still data from a stopped show/hide
+ if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
+ hidden = true;
+
+ // Ignore all other no-op show/hide data
+ } else {
+ continue;
+ }
+ }
+ orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
+ }
+ }
+
+ // Bail out if this is a no-op like .hide().hide()
+ propTween = !jQuery.isEmptyObject( props );
+ if ( !propTween && jQuery.isEmptyObject( orig ) ) {
+ return;
+ }
+
+ // Restrict "overflow" and "display" styles during box animations
+ if ( isBox && elem.nodeType === 1 ) {
+
+ // Support: IE <=9 - 11, Edge 12 - 13
+ // Record all 3 overflow attributes because IE does not infer the shorthand
+ // from identically-valued overflowX and overflowY
+ opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
+
+ // Identify a display type, preferring old show/hide data over the CSS cascade
+ restoreDisplay = dataShow && dataShow.display;
+ if ( restoreDisplay == null ) {
+ restoreDisplay = dataPriv.get( elem, "display" );
+ }
+ display = jQuery.css( elem, "display" );
+ if ( display === "none" ) {
+ if ( restoreDisplay ) {
+ display = restoreDisplay;
+ } else {
+
+ // Get nonempty value(s) by temporarily forcing visibility
+ showHide( [ elem ], true );
+ restoreDisplay = elem.style.display || restoreDisplay;
+ display = jQuery.css( elem, "display" );
+ showHide( [ elem ] );
+ }
+ }
+
+ // Animate inline elements as inline-block
+ if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) {
+ if ( jQuery.css( elem, "float" ) === "none" ) {
+
+ // Restore the original display value at the end of pure show/hide animations
+ if ( !propTween ) {
+ anim.done( function() {
+ style.display = restoreDisplay;
+ } );
+ if ( restoreDisplay == null ) {
+ display = style.display;
+ restoreDisplay = display === "none" ? "" : display;
+ }
+ }
+ style.display = "inline-block";
+ }
+ }
+ }
+
+ if ( opts.overflow ) {
+ style.overflow = "hidden";
+ anim.always( function() {
+ style.overflow = opts.overflow[ 0 ];
+ style.overflowX = opts.overflow[ 1 ];
+ style.overflowY = opts.overflow[ 2 ];
+ } );
+ }
+
+ // Implement show/hide animations
+ propTween = false;
+ for ( prop in orig ) {
+
+ // General show/hide setup for this element animation
+ if ( !propTween ) {
+ if ( dataShow ) {
+ if ( "hidden" in dataShow ) {
+ hidden = dataShow.hidden;
+ }
+ } else {
+ dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } );
+ }
+
+ // Store hidden/visible for toggle so `.stop().toggle()` "reverses"
+ if ( toggle ) {
+ dataShow.hidden = !hidden;
+ }
+
+ // Show elements before animating them
+ if ( hidden ) {
+ showHide( [ elem ], true );
+ }
+
+ /* eslint-disable no-loop-func */
+
+ anim.done( function() {
+
+ /* eslint-enable no-loop-func */
+
+ // The final step of a "hide" animation is actually hiding the element
+ if ( !hidden ) {
+ showHide( [ elem ] );
+ }
+ dataPriv.remove( elem, "fxshow" );
+ for ( prop in orig ) {
+ jQuery.style( elem, prop, orig[ prop ] );
+ }
+ } );
+ }
+
+ // Per-property setup
+ propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
+ if ( !( prop in dataShow ) ) {
+ dataShow[ prop ] = propTween.start;
+ if ( hidden ) {
+ propTween.end = propTween.start;
+ propTween.start = 0;
+ }
+ }
+ }
+}
+
+function propFilter( props, specialEasing ) {
+ var index, name, easing, value, hooks;
+
+ // camelCase, specialEasing and expand cssHook pass
+ for ( index in props ) {
+ name = jQuery.camelCase( index );
+ easing = specialEasing[ name ];
+ value = props[ index ];
+ if ( Array.isArray( value ) ) {
+ easing = value[ 1 ];
+ value = props[ index ] = value[ 0 ];
+ }
+
+ if ( index !== name ) {
+ props[ name ] = value;
+ delete props[ index ];
+ }
+
+ hooks = jQuery.cssHooks[ name ];
+ if ( hooks && "expand" in hooks ) {
+ value = hooks.expand( value );
+ delete props[ name ];
+
+ // Not quite $.extend, this won't overwrite existing keys.
+ // Reusing 'index' because we have the correct "name"
+ for ( index in value ) {
+ if ( !( index in props ) ) {
+ props[ index ] = value[ index ];
+ specialEasing[ index ] = easing;
+ }
+ }
+ } else {
+ specialEasing[ name ] = easing;
+ }
+ }
+}
+
+function Animation( elem, properties, options ) {
+ var result,
+ stopped,
+ index = 0,
+ length = Animation.prefilters.length,
+ deferred = jQuery.Deferred().always( function() {
+
+ // Don't match elem in the :animated selector
+ delete tick.elem;
+ } ),
+ tick = function() {
+ if ( stopped ) {
+ return false;
+ }
+ var currentTime = fxNow || createFxNow(),
+ remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
+
+ // Support: Android 2.3 only
+ // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
+ temp = remaining / animation.duration || 0,
+ percent = 1 - temp,
+ index = 0,
+ length = animation.tweens.length;
+
+ for ( ; index < length; index++ ) {
+ animation.tweens[ index ].run( percent );
+ }
+
+ deferred.notifyWith( elem, [ animation, percent, remaining ] );
+
+ // If there's more to do, yield
+ if ( percent < 1 && length ) {
+ return remaining;
+ }
+
+ // If this was an empty animation, synthesize a final progress notification
+ if ( !length ) {
+ deferred.notifyWith( elem, [ animation, 1, 0 ] );
+ }
+
+ // Resolve the animation and report its conclusion
+ deferred.resolveWith( elem, [ animation ] );
+ return false;
+ },
+ animation = deferred.promise( {
+ elem: elem,
+ props: jQuery.extend( {}, properties ),
+ opts: jQuery.extend( true, {
+ specialEasing: {},
+ easing: jQuery.easing._default
+ }, options ),
+ originalProperties: properties,
+ originalOptions: options,
+ startTime: fxNow || createFxNow(),
+ duration: options.duration,
+ tweens: [],
+ createTween: function( prop, end ) {
+ var tween = jQuery.Tween( elem, animation.opts, prop, end,
+ animation.opts.specialEasing[ prop ] || animation.opts.easing );
+ animation.tweens.push( tween );
+ return tween;
+ },
+ stop: function( gotoEnd ) {
+ var index = 0,
+
+ // If we are going to the end, we want to run all the tweens
+ // otherwise we skip this part
+ length = gotoEnd ? animation.tweens.length : 0;
+ if ( stopped ) {
+ return this;
+ }
+ stopped = true;
+ for ( ; index < length; index++ ) {
+ animation.tweens[ index ].run( 1 );
+ }
+
+ // Resolve when we played the last frame; otherwise, reject
+ if ( gotoEnd ) {
+ deferred.notifyWith( elem, [ animation, 1, 0 ] );
+ deferred.resolveWith( elem, [ animation, gotoEnd ] );
+ } else {
+ deferred.rejectWith( elem, [ animation, gotoEnd ] );
+ }
+ return this;
+ }
+ } ),
+ props = animation.props;
+
+ propFilter( props, animation.opts.specialEasing );
+
+ for ( ; index < length; index++ ) {
+ result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
+ if ( result ) {
+ if ( jQuery.isFunction( result.stop ) ) {
+ jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
+ jQuery.proxy( result.stop, result );
+ }
+ return result;
+ }
+ }
+
+ jQuery.map( props, createTween, animation );
+
+ if ( jQuery.isFunction( animation.opts.start ) ) {
+ animation.opts.start.call( elem, animation );
+ }
+
+ // Attach callbacks from options
+ animation
+ .progress( animation.opts.progress )
+ .done( animation.opts.done, animation.opts.complete )
+ .fail( animation.opts.fail )
+ .always( animation.opts.always );
+
+ jQuery.fx.timer(
+ jQuery.extend( tick, {
+ elem: elem,
+ anim: animation,
+ queue: animation.opts.queue
+ } )
+ );
+
+ return animation;
+}
+
+jQuery.Animation = jQuery.extend( Animation, {
+
+ tweeners: {
+ "*": [ function( prop, value ) {
+ var tween = this.createTween( prop, value );
+ adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
+ return tween;
+ } ]
+ },
+
+ tweener: function( props, callback ) {
+ if ( jQuery.isFunction( props ) ) {
+ callback = props;
+ props = [ "*" ];
+ } else {
+ props = props.match( rnothtmlwhite );
+ }
+
+ var prop,
+ index = 0,
+ length = props.length;
+
+ for ( ; index < length; index++ ) {
+ prop = props[ index ];
+ Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
+ Animation.tweeners[ prop ].unshift( callback );
+ }
+ },
+
+ prefilters: [ defaultPrefilter ],
+
+ prefilter: function( callback, prepend ) {
+ if ( prepend ) {
+ Animation.prefilters.unshift( callback );
+ } else {
+ Animation.prefilters.push( callback );
+ }
+ }
+} );
+
+jQuery.speed = function( speed, easing, fn ) {
+ var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
+ complete: fn || !fn && easing ||
+ jQuery.isFunction( speed ) && speed,
+ duration: speed,
+ easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
+ };
+
+ // Go to the end state if fx are off
+ if ( jQuery.fx.off ) {
+ opt.duration = 0;
+
+ } else {
+ if ( typeof opt.duration !== "number" ) {
+ if ( opt.duration in jQuery.fx.speeds ) {
+ opt.duration = jQuery.fx.speeds[ opt.duration ];
+
+ } else {
+ opt.duration = jQuery.fx.speeds._default;
+ }
+ }
+ }
+
+ // Normalize opt.queue - true/undefined/null -> "fx"
+ if ( opt.queue == null || opt.queue === true ) {
+ opt.queue = "fx";
+ }
+
+ // Queueing
+ opt.old = opt.complete;
+
+ opt.complete = function() {
+ if ( jQuery.isFunction( opt.old ) ) {
+ opt.old.call( this );
+ }
+
+ if ( opt.queue ) {
+ jQuery.dequeue( this, opt.queue );
+ }
+ };
+
+ return opt;
+};
+
+jQuery.fn.extend( {
+ fadeTo: function( speed, to, easing, callback ) {
+
+ // Show any hidden elements after setting opacity to 0
+ return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show()
+
+ // Animate to the value specified
+ .end().animate( { opacity: to }, speed, easing, callback );
+ },
+ animate: function( prop, speed, easing, callback ) {
+ var empty = jQuery.isEmptyObject( prop ),
+ optall = jQuery.speed( speed, easing, callback ),
+ doAnimation = function() {
+
+ // Operate on a copy of prop so per-property easing won't be lost
+ var anim = Animation( this, jQuery.extend( {}, prop ), optall );
+
+ // Empty animations, or finishing resolves immediately
+ if ( empty || dataPriv.get( this, "finish" ) ) {
+ anim.stop( true );
+ }
+ };
+ doAnimation.finish = doAnimation;
+
+ return empty || optall.queue === false ?
+ this.each( doAnimation ) :
+ this.queue( optall.queue, doAnimation );
+ },
+ stop: function( type, clearQueue, gotoEnd ) {
+ var stopQueue = function( hooks ) {
+ var stop = hooks.stop;
+ delete hooks.stop;
+ stop( gotoEnd );
+ };
+
+ if ( typeof type !== "string" ) {
+ gotoEnd = clearQueue;
+ clearQueue = type;
+ type = undefined;
+ }
+ if ( clearQueue && type !== false ) {
+ this.queue( type || "fx", [] );
+ }
+
+ return this.each( function() {
+ var dequeue = true,
+ index = type != null && type + "queueHooks",
+ timers = jQuery.timers,
+ data = dataPriv.get( this );
+
+ if ( index ) {
+ if ( data[ index ] && data[ index ].stop ) {
+ stopQueue( data[ index ] );
+ }
+ } else {
+ for ( index in data ) {
+ if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
+ stopQueue( data[ index ] );
+ }
+ }
+ }
+
+ for ( index = timers.length; index--; ) {
+ if ( timers[ index ].elem === this &&
+ ( type == null || timers[ index ].queue === type ) ) {
+
+ timers[ index ].anim.stop( gotoEnd );
+ dequeue = false;
+ timers.splice( index, 1 );
+ }
+ }
+
+ // Start the next in the queue if the last step wasn't forced.
+ // Timers currently will call their complete callbacks, which
+ // will dequeue but only if they were gotoEnd.
+ if ( dequeue || !gotoEnd ) {
+ jQuery.dequeue( this, type );
+ }
+ } );
+ },
+ finish: function( type ) {
+ if ( type !== false ) {
+ type = type || "fx";
+ }
+ return this.each( function() {
+ var index,
+ data = dataPriv.get( this ),
+ queue = data[ type + "queue" ],
+ hooks = data[ type + "queueHooks" ],
+ timers = jQuery.timers,
+ length = queue ? queue.length : 0;
+
+ // Enable finishing flag on private data
+ data.finish = true;
+
+ // Empty the queue first
+ jQuery.queue( this, type, [] );
+
+ if ( hooks && hooks.stop ) {
+ hooks.stop.call( this, true );
+ }
+
+ // Look for any active animations, and finish them
+ for ( index = timers.length; index--; ) {
+ if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
+ timers[ index ].anim.stop( true );
+ timers.splice( index, 1 );
+ }
+ }
+
+ // Look for any animations in the old queue and finish them
+ for ( index = 0; index < length; index++ ) {
+ if ( queue[ index ] && queue[ index ].finish ) {
+ queue[ index ].finish.call( this );
+ }
+ }
+
+ // Turn off finishing flag
+ delete data.finish;
+ } );
+ }
+} );
+
+jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) {
+ var cssFn = jQuery.fn[ name ];
+ jQuery.fn[ name ] = function( speed, easing, callback ) {
+ return speed == null || typeof speed === "boolean" ?
+ cssFn.apply( this, arguments ) :
+ this.animate( genFx( name, true ), speed, easing, callback );
+ };
+} );
+
+// Generate shortcuts for custom animations
+jQuery.each( {
+ slideDown: genFx( "show" ),
+ slideUp: genFx( "hide" ),
+ slideToggle: genFx( "toggle" ),
+ fadeIn: { opacity: "show" },
+ fadeOut: { opacity: "hide" },
+ fadeToggle: { opacity: "toggle" }
+}, function( name, props ) {
+ jQuery.fn[ name ] = function( speed, easing, callback ) {
+ return this.animate( props, speed, easing, callback );
+ };
+} );
+
+jQuery.timers = [];
+jQuery.fx.tick = function() {
+ var timer,
+ i = 0,
+ timers = jQuery.timers;
+
+ fxNow = jQuery.now();
+
+ for ( ; i < timers.length; i++ ) {
+ timer = timers[ i ];
+
+ // Run the timer and safely remove it when done (allowing for external removal)
+ if ( !timer() && timers[ i ] === timer ) {
+ timers.splice( i--, 1 );
+ }
+ }
+
+ if ( !timers.length ) {
+ jQuery.fx.stop();
+ }
+ fxNow = undefined;
+};
+
+jQuery.fx.timer = function( timer ) {
+ jQuery.timers.push( timer );
+ jQuery.fx.start();
+};
+
+jQuery.fx.interval = 13;
+jQuery.fx.start = function() {
+ if ( inProgress ) {
+ return;
+ }
+
+ inProgress = true;
+ schedule();
+};
+
+jQuery.fx.stop = function() {
+ inProgress = null;
+};
+
+jQuery.fx.speeds = {
+ slow: 600,
+ fast: 200,
+
+ // Default speed
+ _default: 400
+};
+
+
+// Based off of the plugin by Clint Helfers, with permission.
+// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
+jQuery.fn.delay = function( time, type ) {
+ time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
+ type = type || "fx";
+
+ return this.queue( type, function( next, hooks ) {
+ var timeout = window.setTimeout( next, time );
+ hooks.stop = function() {
+ window.clearTimeout( timeout );
+ };
+ } );
+};
+
+
+( function() {
+ var input = document.createElement( "input" ),
+ select = document.createElement( "select" ),
+ opt = select.appendChild( document.createElement( "option" ) );
+
+ input.type = "checkbox";
+
+ // Support: Android <=4.3 only
+ // Default value for a checkbox should be "on"
+ support.checkOn = input.value !== "";
+
+ // Support: IE <=11 only
+ // Must access selectedIndex to make default options select
+ support.optSelected = opt.selected;
+
+ // Support: IE <=11 only
+ // An input loses its value after becoming a radio
+ input = document.createElement( "input" );
+ input.value = "t";
+ input.type = "radio";
+ support.radioValue = input.value === "t";
+} )();
+
+
+var boolHook,
+ attrHandle = jQuery.expr.attrHandle;
+
+jQuery.fn.extend( {
+ attr: function( name, value ) {
+ return access( this, jQuery.attr, name, value, arguments.length > 1 );
+ },
+
+ removeAttr: function( name ) {
+ return this.each( function() {
+ jQuery.removeAttr( this, name );
+ } );
+ }
+} );
+
+jQuery.extend( {
+ attr: function( elem, name, value ) {
+ var ret, hooks,
+ nType = elem.nodeType;
+
+ // Don't get/set attributes on text, comment and attribute nodes
+ if ( nType === 3 || nType === 8 || nType === 2 ) {
+ return;
+ }
+
+ // Fallback to prop when attributes are not supported
+ if ( typeof elem.getAttribute === "undefined" ) {
+ return jQuery.prop( elem, name, value );
+ }
+
+ // Attribute hooks are determined by the lowercase version
+ // Grab necessary hook if one is defined
+ if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
+ hooks = jQuery.attrHooks[ name.toLowerCase() ] ||
+ ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );
+ }
+
+ if ( value !== undefined ) {
+ if ( value === null ) {
+ jQuery.removeAttr( elem, name );
+ return;
+ }
+
+ if ( hooks && "set" in hooks &&
+ ( ret = hooks.set( elem, value, name ) ) !== undefined ) {
+ return ret;
+ }
+
+ elem.setAttribute( name, value + "" );
+ return value;
+ }
+
+ if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
+ return ret;
+ }
+
+ ret = jQuery.find.attr( elem, name );
+
+ // Non-existent attributes return null, we normalize to undefined
+ return ret == null ? undefined : ret;
+ },
+
+ attrHooks: {
+ type: {
+ set: function( elem, value ) {
+ if ( !support.radioValue && value === "radio" &&
+ nodeName( elem, "input" ) ) {
+ var val = elem.value;
+ elem.setAttribute( "type", value );
+ if ( val ) {
+ elem.value = val;
+ }
+ return value;
+ }
+ }
+ }
+ },
+
+ removeAttr: function( elem, value ) {
+ var name,
+ i = 0,
+
+ // Attribute names can contain non-HTML whitespace characters
+ // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
+ attrNames = value && value.match( rnothtmlwhite );
+
+ if ( attrNames && elem.nodeType === 1 ) {
+ while ( ( name = attrNames[ i++ ] ) ) {
+ elem.removeAttribute( name );
+ }
+ }
+ }
+} );
+
+// Hooks for boolean attributes
+boolHook = {
+ set: function( elem, value, name ) {
+ if ( value === false ) {
+
+ // Remove boolean attributes when set to false
+ jQuery.removeAttr( elem, name );
+ } else {
+ elem.setAttribute( name, name );
+ }
+ return name;
+ }
+};
+
+jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
+ var getter = attrHandle[ name ] || jQuery.find.attr;
+
+ attrHandle[ name ] = function( elem, name, isXML ) {
+ var ret, handle,
+ lowercaseName = name.toLowerCase();
+
+ if ( !isXML ) {
+
+ // Avoid an infinite loop by temporarily removing this function from the getter
+ handle = attrHandle[ lowercaseName ];
+ attrHandle[ lowercaseName ] = ret;
+ ret = getter( elem, name, isXML ) != null ?
+ lowercaseName :
+ null;
+ attrHandle[ lowercaseName ] = handle;
+ }
+ return ret;
+ };
+} );
+
+
+
+
+var rfocusable = /^(?:input|select|textarea|button)$/i,
+ rclickable = /^(?:a|area)$/i;
+
+jQuery.fn.extend( {
+ prop: function( name, value ) {
+ return access( this, jQuery.prop, name, value, arguments.length > 1 );
+ },
+
+ removeProp: function( name ) {
+ return this.each( function() {
+ delete this[ jQuery.propFix[ name ] || name ];
+ } );
+ }
+} );
+
+jQuery.extend( {
+ prop: function( elem, name, value ) {
+ var ret, hooks,
+ nType = elem.nodeType;
+
+ // Don't get/set properties on text, comment and attribute nodes
+ if ( nType === 3 || nType === 8 || nType === 2 ) {
+ return;
+ }
+
+ if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
+
+ // Fix name and attach hooks
+ name = jQuery.propFix[ name ] || name;
+ hooks = jQuery.propHooks[ name ];
+ }
+
+ if ( value !== undefined ) {
+ if ( hooks && "set" in hooks &&
+ ( ret = hooks.set( elem, value, name ) ) !== undefined ) {
+ return ret;
+ }
+
+ return ( elem[ name ] = value );
+ }
+
+ if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
+ return ret;
+ }
+
+ return elem[ name ];
+ },
+
+ propHooks: {
+ tabIndex: {
+ get: function( elem ) {
+
+ // Support: IE <=9 - 11 only
+ // elem.tabIndex doesn't always return the
+ // correct value when it hasn't been explicitly set
+ // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
+ // Use proper attribute retrieval(#12072)
+ var tabindex = jQuery.find.attr( elem, "tabindex" );
+
+ if ( tabindex ) {
+ return parseInt( tabindex, 10 );
+ }
+
+ if (
+ rfocusable.test( elem.nodeName ) ||
+ rclickable.test( elem.nodeName ) &&
+ elem.href
+ ) {
+ return 0;
+ }
+
+ return -1;
+ }
+ }
+ },
+
+ propFix: {
+ "for": "htmlFor",
+ "class": "className"
+ }
+} );
+
+// Support: IE <=11 only
+// Accessing the selectedIndex property
+// forces the browser to respect setting selected
+// on the option
+// The getter ensures a default option is selected
+// when in an optgroup
+// eslint rule "no-unused-expressions" is disabled for this code
+// since it considers such accessions noop
+if ( !support.optSelected ) {
+ jQuery.propHooks.selected = {
+ get: function( elem ) {
+
+ /* eslint no-unused-expressions: "off" */
+
+ var parent = elem.parentNode;
+ if ( parent && parent.parentNode ) {
+ parent.parentNode.selectedIndex;
+ }
+ return null;
+ },
+ set: function( elem ) {
+
+ /* eslint no-unused-expressions: "off" */
+
+ var parent = elem.parentNode;
+ if ( parent ) {
+ parent.selectedIndex;
+
+ if ( parent.parentNode ) {
+ parent.parentNode.selectedIndex;
+ }
+ }
+ }
+ };
+}
+
+jQuery.each( [
+ "tabIndex",
+ "readOnly",
+ "maxLength",
+ "cellSpacing",
+ "cellPadding",
+ "rowSpan",
+ "colSpan",
+ "useMap",
+ "frameBorder",
+ "contentEditable"
+], function() {
+ jQuery.propFix[ this.toLowerCase() ] = this;
+} );
+
+
+
+
+ // Strip and collapse whitespace according to HTML spec
+ // https://html.spec.whatwg.org/multipage/infrastructure.html#strip-and-collapse-whitespace
+ function stripAndCollapse( value ) {
+ var tokens = value.match( rnothtmlwhite ) || [];
+ return tokens.join( " " );
+ }
+
+
+function getClass( elem ) {
+ return elem.getAttribute && elem.getAttribute( "class" ) || "";
+}
+
+jQuery.fn.extend( {
+ addClass: function( value ) {
+ var classes, elem, cur, curValue, clazz, j, finalValue,
+ i = 0;
+
+ if ( jQuery.isFunction( value ) ) {
+ return this.each( function( j ) {
+ jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
+ } );
+ }
+
+ if ( typeof value === "string" && value ) {
+ classes = value.match( rnothtmlwhite ) || [];
+
+ while ( ( elem = this[ i++ ] ) ) {
+ curValue = getClass( elem );
+ cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
+
+ if ( cur ) {
+ j = 0;
+ while ( ( clazz = classes[ j++ ] ) ) {
+ if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
+ cur += clazz + " ";
+ }
+ }
+
+ // Only assign if different to avoid unneeded rendering.
+ finalValue = stripAndCollapse( cur );
+ if ( curValue !== finalValue ) {
+ elem.setAttribute( "class", finalValue );
+ }
+ }
+ }
+ }
+
+ return this;
+ },
+
+ removeClass: function( value ) {
+ var classes, elem, cur, curValue, clazz, j, finalValue,
+ i = 0;
+
+ if ( jQuery.isFunction( value ) ) {
+ return this.each( function( j ) {
+ jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
+ } );
+ }
+
+ if ( !arguments.length ) {
+ return this.attr( "class", "" );
+ }
+
+ if ( typeof value === "string" && value ) {
+ classes = value.match( rnothtmlwhite ) || [];
+
+ while ( ( elem = this[ i++ ] ) ) {
+ curValue = getClass( elem );
+
+ // This expression is here for better compressibility (see addClass)
+ cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
+
+ if ( cur ) {
+ j = 0;
+ while ( ( clazz = classes[ j++ ] ) ) {
+
+ // Remove *all* instances
+ while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
+ cur = cur.replace( " " + clazz + " ", " " );
+ }
+ }
+
+ // Only assign if different to avoid unneeded rendering.
+ finalValue = stripAndCollapse( cur );
+ if ( curValue !== finalValue ) {
+ elem.setAttribute( "class", finalValue );
+ }
+ }
+ }
+ }
+
+ return this;
+ },
+
+ toggleClass: function( value, stateVal ) {
+ var type = typeof value;
+
+ if ( typeof stateVal === "boolean" && type === "string" ) {
+ return stateVal ? this.addClass( value ) : this.removeClass( value );
+ }
+
+ if ( jQuery.isFunction( value ) ) {
+ return this.each( function( i ) {
+ jQuery( this ).toggleClass(
+ value.call( this, i, getClass( this ), stateVal ),
+ stateVal
+ );
+ } );
+ }
+
+ return this.each( function() {
+ var className, i, self, classNames;
+
+ if ( type === "string" ) {
+
+ // Toggle individual class names
+ i = 0;
+ self = jQuery( this );
+ classNames = value.match( rnothtmlwhite ) || [];
+
+ while ( ( className = classNames[ i++ ] ) ) {
+
+ // Check each className given, space separated list
+ if ( self.hasClass( className ) ) {
+ self.removeClass( className );
+ } else {
+ self.addClass( className );
+ }
+ }
+
+ // Toggle whole class name
+ } else if ( value === undefined || type === "boolean" ) {
+ className = getClass( this );
+ if ( className ) {
+
+ // Store className if set
+ dataPriv.set( this, "__className__", className );
+ }
+
+ // If the element has a class name or if we're passed `false`,
+ // then remove the whole classname (if there was one, the above saved it).
+ // Otherwise bring back whatever was previously saved (if anything),
+ // falling back to the empty string if nothing was stored.
+ if ( this.setAttribute ) {
+ this.setAttribute( "class",
+ className || value === false ?
+ "" :
+ dataPriv.get( this, "__className__" ) || ""
+ );
+ }
+ }
+ } );
+ },
+
+ hasClass: function( selector ) {
+ var className, elem,
+ i = 0;
+
+ className = " " + selector + " ";
+ while ( ( elem = this[ i++ ] ) ) {
+ if ( elem.nodeType === 1 &&
+ ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+} );
+
+
+
+
+var rreturn = /\r/g;
+
+jQuery.fn.extend( {
+ val: function( value ) {
+ var hooks, ret, isFunction,
+ elem = this[ 0 ];
+
+ if ( !arguments.length ) {
+ if ( elem ) {
+ hooks = jQuery.valHooks[ elem.type ] ||
+ jQuery.valHooks[ elem.nodeName.toLowerCase() ];
+
+ if ( hooks &&
+ "get" in hooks &&
+ ( ret = hooks.get( elem, "value" ) ) !== undefined
+ ) {
+ return ret;
+ }
+
+ ret = elem.value;
+
+ // Handle most common string cases
+ if ( typeof ret === "string" ) {
+ return ret.replace( rreturn, "" );
+ }
+
+ // Handle cases where value is null/undef or number
+ return ret == null ? "" : ret;
+ }
+
+ return;
+ }
+
+ isFunction = jQuery.isFunction( value );
+
+ return this.each( function( i ) {
+ var val;
+
+ if ( this.nodeType !== 1 ) {
+ return;
+ }
+
+ if ( isFunction ) {
+ val = value.call( this, i, jQuery( this ).val() );
+ } else {
+ val = value;
+ }
+
+ // Treat null/undefined as ""; convert numbers to string
+ if ( val == null ) {
+ val = "";
+
+ } else if ( typeof val === "number" ) {
+ val += "";
+
+ } else if ( Array.isArray( val ) ) {
+ val = jQuery.map( val, function( value ) {
+ return value == null ? "" : value + "";
+ } );
+ }
+
+ hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
+
+ // If set returns undefined, fall back to normal setting
+ if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
+ this.value = val;
+ }
+ } );
+ }
+} );
+
+jQuery.extend( {
+ valHooks: {
+ option: {
+ get: function( elem ) {
+
+ var val = jQuery.find.attr( elem, "value" );
+ return val != null ?
+ val :
+
+ // Support: IE <=10 - 11 only
+ // option.text throws exceptions (#14686, #14858)
+ // Strip and collapse whitespace
+ // https://html.spec.whatwg.org/#strip-and-collapse-whitespace
+ stripAndCollapse( jQuery.text( elem ) );
+ }
+ },
+ select: {
+ get: function( elem ) {
+ var value, option, i,
+ options = elem.options,
+ index = elem.selectedIndex,
+ one = elem.type === "select-one",
+ values = one ? null : [],
+ max = one ? index + 1 : options.length;
+
+ if ( index < 0 ) {
+ i = max;
+
+ } else {
+ i = one ? index : 0;
+ }
+
+ // Loop through all the selected options
+ for ( ; i < max; i++ ) {
+ option = options[ i ];
+
+ // Support: IE <=9 only
+ // IE8-9 doesn't update selected after form reset (#2551)
+ if ( ( option.selected || i === index ) &&
+
+ // Don't return options that are disabled or in a disabled optgroup
+ !option.disabled &&
+ ( !option.parentNode.disabled ||
+ !nodeName( option.parentNode, "optgroup" ) ) ) {
+
+ // Get the specific value for the option
+ value = jQuery( option ).val();
+
+ // We don't need an array for one selects
+ if ( one ) {
+ return value;
+ }
+
+ // Multi-Selects return an array
+ values.push( value );
+ }
+ }
+
+ return values;
+ },
+
+ set: function( elem, value ) {
+ var optionSet, option,
+ options = elem.options,
+ values = jQuery.makeArray( value ),
+ i = options.length;
+
+ while ( i-- ) {
+ option = options[ i ];
+
+ /* eslint-disable no-cond-assign */
+
+ if ( option.selected =
+ jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1
+ ) {
+ optionSet = true;
+ }
+
+ /* eslint-enable no-cond-assign */
+ }
+
+ // Force browsers to behave consistently when non-matching value is set
+ if ( !optionSet ) {
+ elem.selectedIndex = -1;
+ }
+ return values;
+ }
+ }
+ }
+} );
+
+// Radios and checkboxes getter/setter
+jQuery.each( [ "radio", "checkbox" ], function() {
+ jQuery.valHooks[ this ] = {
+ set: function( elem, value ) {
+ if ( Array.isArray( value ) ) {
+ return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
+ }
+ }
+ };
+ if ( !support.checkOn ) {
+ jQuery.valHooks[ this ].get = function( elem ) {
+ return elem.getAttribute( "value" ) === null ? "on" : elem.value;
+ };
+ }
+} );
+
+
+
+
+// Return jQuery for attributes-only inclusion
+
+
+var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/;
+
+jQuery.extend( jQuery.event, {
+
+ trigger: function( event, data, elem, onlyHandlers ) {
+
+ var i, cur, tmp, bubbleType, ontype, handle, special,
+ eventPath = [ elem || document ],
+ type = hasOwn.call( event, "type" ) ? event.type : event,
+ namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
+
+ cur = tmp = elem = elem || document;
+
+ // Don't do events on text and comment nodes
+ if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+ return;
+ }
+
+ // focus/blur morphs to focusin/out; ensure we're not firing them right now
+ if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
+ return;
+ }
+
+ if ( type.indexOf( "." ) > -1 ) {
+
+ // Namespaced trigger; create a regexp to match event type in handle()
+ namespaces = type.split( "." );
+ type = namespaces.shift();
+ namespaces.sort();
+ }
+ ontype = type.indexOf( ":" ) < 0 && "on" + type;
+
+ // Caller can pass in a jQuery.Event object, Object, or just an event type string
+ event = event[ jQuery.expando ] ?
+ event :
+ new jQuery.Event( type, typeof event === "object" && event );
+
+ // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
+ event.isTrigger = onlyHandlers ? 2 : 3;
+ event.namespace = namespaces.join( "." );
+ event.rnamespace = event.namespace ?
+ new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
+ null;
+
+ // Clean up the event in case it is being reused
+ event.result = undefined;
+ if ( !event.target ) {
+ event.target = elem;
+ }
+
+ // Clone any incoming data and prepend the event, creating the handler arg list
+ data = data == null ?
+ [ event ] :
+ jQuery.makeArray( data, [ event ] );
+
+ // Allow special events to draw outside the lines
+ special = jQuery.event.special[ type ] || {};
+ if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
+ return;
+ }
+
+ // Determine event propagation path in advance, per W3C events spec (#9951)
+ // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
+ if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
+
+ bubbleType = special.delegateType || type;
+ if ( !rfocusMorph.test( bubbleType + type ) ) {
+ cur = cur.parentNode;
+ }
+ for ( ; cur; cur = cur.parentNode ) {
+ eventPath.push( cur );
+ tmp = cur;
+ }
+
+ // Only add window if we got to document (e.g., not plain obj or detached DOM)
+ if ( tmp === ( elem.ownerDocument || document ) ) {
+ eventPath.push( tmp.defaultView || tmp.parentWindow || window );
+ }
+ }
+
+ // Fire handlers on the event path
+ i = 0;
+ while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
+
+ event.type = i > 1 ?
+ bubbleType :
+ special.bindType || type;
+
+ // jQuery handler
+ handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] &&
+ dataPriv.get( cur, "handle" );
+ if ( handle ) {
+ handle.apply( cur, data );
+ }
+
+ // Native handler
+ handle = ontype && cur[ ontype ];
+ if ( handle && handle.apply && acceptData( cur ) ) {
+ event.result = handle.apply( cur, data );
+ if ( event.result === false ) {
+ event.preventDefault();
+ }
+ }
+ }
+ event.type = type;
+
+ // If nobody prevented the default action, do it now
+ if ( !onlyHandlers && !event.isDefaultPrevented() ) {
+
+ if ( ( !special._default ||
+ special._default.apply( eventPath.pop(), data ) === false ) &&
+ acceptData( elem ) ) {
+
+ // Call a native DOM method on the target with the same name as the event.
+ // Don't do default actions on window, that's where global variables be (#6170)
+ if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {
+
+ // Don't re-trigger an onFOO event when we call its FOO() method
+ tmp = elem[ ontype ];
+
+ if ( tmp ) {
+ elem[ ontype ] = null;
+ }
+
+ // Prevent re-triggering of the same event, since we already bubbled it above
+ jQuery.event.triggered = type;
+ elem[ type ]();
+ jQuery.event.triggered = undefined;
+
+ if ( tmp ) {
+ elem[ ontype ] = tmp;
+ }
+ }
+ }
+ }
+
+ return event.result;
+ },
+
+ // Piggyback on a donor event to simulate a different one
+ // Used only for `focus(in | out)` events
+ simulate: function( type, elem, event ) {
+ var e = jQuery.extend(
+ new jQuery.Event(),
+ event,
+ {
+ type: type,
+ isSimulated: true
+ }
+ );
+
+ jQuery.event.trigger( e, null, elem );
+ }
+
+} );
+
+jQuery.fn.extend( {
+
+ trigger: function( type, data ) {
+ return this.each( function() {
+ jQuery.event.trigger( type, data, this );
+ } );
+ },
+ triggerHandler: function( type, data ) {
+ var elem = this[ 0 ];
+ if ( elem ) {
+ return jQuery.event.trigger( type, data, elem, true );
+ }
+ }
+} );
+
+
+jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " +
+ "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
+ "change select submit keydown keypress keyup contextmenu" ).split( " " ),
+ function( i, name ) {
+
+ // Handle event binding
+ jQuery.fn[ name ] = function( data, fn ) {
+ return arguments.length > 0 ?
+ this.on( name, null, data, fn ) :
+ this.trigger( name );
+ };
+} );
+
+jQuery.fn.extend( {
+ hover: function( fnOver, fnOut ) {
+ return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
+ }
+} );
+
+
+
+
+support.focusin = "onfocusin" in window;
+
+
+// Support: Firefox <=44
+// Firefox doesn't have focus(in | out) events
+// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
+//
+// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1
+// focus(in | out) events fire after focus & blur events,
+// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
+// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857
+if ( !support.focusin ) {
+ jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {
+
+ // Attach a single capturing handler on the document while someone wants focusin/focusout
+ var handler = function( event ) {
+ jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );
+ };
+
+ jQuery.event.special[ fix ] = {
+ setup: function() {
+ var doc = this.ownerDocument || this,
+ attaches = dataPriv.access( doc, fix );
+
+ if ( !attaches ) {
+ doc.addEventListener( orig, handler, true );
+ }
+ dataPriv.access( doc, fix, ( attaches || 0 ) + 1 );
+ },
+ teardown: function() {
+ var doc = this.ownerDocument || this,
+ attaches = dataPriv.access( doc, fix ) - 1;
+
+ if ( !attaches ) {
+ doc.removeEventListener( orig, handler, true );
+ dataPriv.remove( doc, fix );
+
+ } else {
+ dataPriv.access( doc, fix, attaches );
+ }
+ }
+ };
+ } );
+}
+var location = window.location;
+
+var nonce = jQuery.now();
+
+var rquery = ( /\?/ );
+
+
+
+// Cross-browser xml parsing
+jQuery.parseXML = function( data ) {
+ var xml;
+ if ( !data || typeof data !== "string" ) {
+ return null;
+ }
+
+ // Support: IE 9 - 11 only
+ // IE throws on parseFromString with invalid input.
+ try {
+ xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );
+ } catch ( e ) {
+ xml = undefined;
+ }
+
+ if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
+ jQuery.error( "Invalid XML: " + data );
+ }
+ return xml;
+};
+
+
+var
+ rbracket = /\[\]$/,
+ rCRLF = /\r?\n/g,
+ rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
+ rsubmittable = /^(?:input|select|textarea|keygen)/i;
+
+function buildParams( prefix, obj, traditional, add ) {
+ var name;
+
+ if ( Array.isArray( obj ) ) {
+
+ // Serialize array item.
+ jQuery.each( obj, function( i, v ) {
+ if ( traditional || rbracket.test( prefix ) ) {
+
+ // Treat each array item as a scalar.
+ add( prefix, v );
+
+ } else {
+
+ // Item is non-scalar (array or object), encode its numeric index.
+ buildParams(
+ prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
+ v,
+ traditional,
+ add
+ );
+ }
+ } );
+
+ } else if ( !traditional && jQuery.type( obj ) === "object" ) {
+
+ // Serialize object item.
+ for ( name in obj ) {
+ buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
+ }
+
+ } else {
+
+ // Serialize scalar item.
+ add( prefix, obj );
+ }
+}
+
+// Serialize an array of form elements or a set of
+// key/values into a query string
+jQuery.param = function( a, traditional ) {
+ var prefix,
+ s = [],
+ add = function( key, valueOrFunction ) {
+
+ // If value is a function, invoke it and use its return value
+ var value = jQuery.isFunction( valueOrFunction ) ?
+ valueOrFunction() :
+ valueOrFunction;
+
+ s[ s.length ] = encodeURIComponent( key ) + "=" +
+ encodeURIComponent( value == null ? "" : value );
+ };
+
+ // If an array was passed in, assume that it is an array of form elements.
+ if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
+
+ // Serialize the form elements
+ jQuery.each( a, function() {
+ add( this.name, this.value );
+ } );
+
+ } else {
+
+ // If traditional, encode the "old" way (the way 1.3.2 or older
+ // did it), otherwise encode params recursively.
+ for ( prefix in a ) {
+ buildParams( prefix, a[ prefix ], traditional, add );
+ }
+ }
+
+ // Return the resulting serialization
+ return s.join( "&" );
+};
+
+jQuery.fn.extend( {
+ serialize: function() {
+ return jQuery.param( this.serializeArray() );
+ },
+ serializeArray: function() {
+ return this.map( function() {
+
+ // Can add propHook for "elements" to filter or add form elements
+ var elements = jQuery.prop( this, "elements" );
+ return elements ? jQuery.makeArray( elements ) : this;
+ } )
+ .filter( function() {
+ var type = this.type;
+
+ // Use .is( ":disabled" ) so that fieldset[disabled] works
+ return this.name && !jQuery( this ).is( ":disabled" ) &&
+ rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
+ ( this.checked || !rcheckableType.test( type ) );
+ } )
+ .map( function( i, elem ) {
+ var val = jQuery( this ).val();
+
+ if ( val == null ) {
+ return null;
+ }
+
+ if ( Array.isArray( val ) ) {
+ return jQuery.map( val, function( val ) {
+ return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+ } );
+ }
+
+ return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+ } ).get();
+ }
+} );
+
+
+var
+ r20 = /%20/g,
+ rhash = /#.*$/,
+ rantiCache = /([?&])_=[^&]*/,
+ rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
+
+ // #7653, #8125, #8152: local protocol detection
+ rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
+ rnoContent = /^(?:GET|HEAD)$/,
+ rprotocol = /^\/\//,
+
+ /* Prefilters
+ * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
+ * 2) These are called:
+ * - BEFORE asking for a transport
+ * - AFTER param serialization (s.data is a string if s.processData is true)
+ * 3) key is the dataType
+ * 4) the catchall symbol "*" can be used
+ * 5) execution will start with transport dataType and THEN continue down to "*" if needed
+ */
+ prefilters = {},
+
+ /* Transports bindings
+ * 1) key is the dataType
+ * 2) the catchall symbol "*" can be used
+ * 3) selection will start with transport dataType and THEN go to "*" if needed
+ */
+ transports = {},
+
+ // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
+ allTypes = "*/".concat( "*" ),
+
+ // Anchor tag for parsing the document origin
+ originAnchor = document.createElement( "a" );
+ originAnchor.href = location.href;
+
+// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
+function addToPrefiltersOrTransports( structure ) {
+
+ // dataTypeExpression is optional and defaults to "*"
+ return function( dataTypeExpression, func ) {
+
+ if ( typeof dataTypeExpression !== "string" ) {
+ func = dataTypeExpression;
+ dataTypeExpression = "*";
+ }
+
+ var dataType,
+ i = 0,
+ dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];
+
+ if ( jQuery.isFunction( func ) ) {
+
+ // For each dataType in the dataTypeExpression
+ while ( ( dataType = dataTypes[ i++ ] ) ) {
+
+ // Prepend if requested
+ if ( dataType[ 0 ] === "+" ) {
+ dataType = dataType.slice( 1 ) || "*";
+ ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );
+
+ // Otherwise append
+ } else {
+ ( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
+ }
+ }
+ }
+ };
+}
+
+// Base inspection function for prefilters and transports
+function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
+
+ var inspected = {},
+ seekingTransport = ( structure === transports );
+
+ function inspect( dataType ) {
+ var selected;
+ inspected[ dataType ] = true;
+ jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
+ var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
+ if ( typeof dataTypeOrTransport === "string" &&
+ !seekingTransport && !inspected[ dataTypeOrTransport ] ) {
+
+ options.dataTypes.unshift( dataTypeOrTransport );
+ inspect( dataTypeOrTransport );
+ return false;
+ } else if ( seekingTransport ) {
+ return !( selected = dataTypeOrTransport );
+ }
+ } );
+ return selected;
+ }
+
+ return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
+}
+
+// A special extend for ajax options
+// that takes "flat" options (not to be deep extended)
+// Fixes #9887
+function ajaxExtend( target, src ) {
+ var key, deep,
+ flatOptions = jQuery.ajaxSettings.flatOptions || {};
+
+ for ( key in src ) {
+ if ( src[ key ] !== undefined ) {
+ ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
+ }
+ }
+ if ( deep ) {
+ jQuery.extend( true, target, deep );
+ }
+
+ return target;
+}
+
+/* Handles responses to an ajax request:
+ * - finds the right dataType (mediates between content-type and expected dataType)
+ * - returns the corresponding response
+ */
+function ajaxHandleResponses( s, jqXHR, responses ) {
+
+ var ct, type, finalDataType, firstDataType,
+ contents = s.contents,
+ dataTypes = s.dataTypes;
+
+ // Remove auto dataType and get content-type in the process
+ while ( dataTypes[ 0 ] === "*" ) {
+ dataTypes.shift();
+ if ( ct === undefined ) {
+ ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
+ }
+ }
+
+ // Check if we're dealing with a known content-type
+ if ( ct ) {
+ for ( type in contents ) {
+ if ( contents[ type ] && contents[ type ].test( ct ) ) {
+ dataTypes.unshift( type );
+ break;
+ }
+ }
+ }
+
+ // Check to see if we have a response for the expected dataType
+ if ( dataTypes[ 0 ] in responses ) {
+ finalDataType = dataTypes[ 0 ];
+ } else {
+
+ // Try convertible dataTypes
+ for ( type in responses ) {
+ if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
+ finalDataType = type;
+ break;
+ }
+ if ( !firstDataType ) {
+ firstDataType = type;
+ }
+ }
+
+ // Or just use first one
+ finalDataType = finalDataType || firstDataType;
+ }
+
+ // If we found a dataType
+ // We add the dataType to the list if needed
+ // and return the corresponding response
+ if ( finalDataType ) {
+ if ( finalDataType !== dataTypes[ 0 ] ) {
+ dataTypes.unshift( finalDataType );
+ }
+ return responses[ finalDataType ];
+ }
+}
+
+/* Chain conversions given the request and the original response
+ * Also sets the responseXXX fields on the jqXHR instance
+ */
+function ajaxConvert( s, response, jqXHR, isSuccess ) {
+ var conv2, current, conv, tmp, prev,
+ converters = {},
+
+ // Work with a copy of dataTypes in case we need to modify it for conversion
+ dataTypes = s.dataTypes.slice();
+
+ // Create converters map with lowercased keys
+ if ( dataTypes[ 1 ] ) {
+ for ( conv in s.converters ) {
+ converters[ conv.toLowerCase() ] = s.converters[ conv ];
+ }
+ }
+
+ current = dataTypes.shift();
+
+ // Convert to each sequential dataType
+ while ( current ) {
+
+ if ( s.responseFields[ current ] ) {
+ jqXHR[ s.responseFields[ current ] ] = response;
+ }
+
+ // Apply the dataFilter if provided
+ if ( !prev && isSuccess && s.dataFilter ) {
+ response = s.dataFilter( response, s.dataType );
+ }
+
+ prev = current;
+ current = dataTypes.shift();
+
+ if ( current ) {
+
+ // There's only work to do if current dataType is non-auto
+ if ( current === "*" ) {
+
+ current = prev;
+
+ // Convert response if prev dataType is non-auto and differs from current
+ } else if ( prev !== "*" && prev !== current ) {
+
+ // Seek a direct converter
+ conv = converters[ prev + " " + current ] || converters[ "* " + current ];
+
+ // If none found, seek a pair
+ if ( !conv ) {
+ for ( conv2 in converters ) {
+
+ // If conv2 outputs current
+ tmp = conv2.split( " " );
+ if ( tmp[ 1 ] === current ) {
+
+ // If prev can be converted to accepted input
+ conv = converters[ prev + " " + tmp[ 0 ] ] ||
+ converters[ "* " + tmp[ 0 ] ];
+ if ( conv ) {
+
+ // Condense equivalence converters
+ if ( conv === true ) {
+ conv = converters[ conv2 ];
+
+ // Otherwise, insert the intermediate dataType
+ } else if ( converters[ conv2 ] !== true ) {
+ current = tmp[ 0 ];
+ dataTypes.unshift( tmp[ 1 ] );
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ // Apply converter (if not an equivalence)
+ if ( conv !== true ) {
+
+ // Unless errors are allowed to bubble, catch and return them
+ if ( conv && s.throws ) {
+ response = conv( response );
+ } else {
+ try {
+ response = conv( response );
+ } catch ( e ) {
+ return {
+ state: "parsererror",
+ error: conv ? e : "No conversion from " + prev + " to " + current
+ };
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return { state: "success", data: response };
+}
+
+jQuery.extend( {
+
+ // Counter for holding the number of active queries
+ active: 0,
+
+ // Last-Modified header cache for next request
+ lastModified: {},
+ etag: {},
+
+ ajaxSettings: {
+ url: location.href,
+ type: "GET",
+ isLocal: rlocalProtocol.test( location.protocol ),
+ global: true,
+ processData: true,
+ async: true,
+ contentType: "application/x-www-form-urlencoded; charset=UTF-8",
+
+ /*
+ timeout: 0,
+ data: null,
+ dataType: null,
+ username: null,
+ password: null,
+ cache: null,
+ throws: false,
+ traditional: false,
+ headers: {},
+ */
+
+ accepts: {
+ "*": allTypes,
+ text: "text/plain",
+ html: "text/html",
+ xml: "application/xml, text/xml",
+ json: "application/json, text/javascript"
+ },
+
+ contents: {
+ xml: /\bxml\b/,
+ html: /\bhtml/,
+ json: /\bjson\b/
+ },
+
+ responseFields: {
+ xml: "responseXML",
+ text: "responseText",
+ json: "responseJSON"
+ },
+
+ // Data converters
+ // Keys separate source (or catchall "*") and destination types with a single space
+ converters: {
+
+ // Convert anything to text
+ "* text": String,
+
+ // Text to html (true = no transformation)
+ "text html": true,
+
+ // Evaluate text as a json expression
+ "text json": JSON.parse,
+
+ // Parse text as xml
+ "text xml": jQuery.parseXML
+ },
+
+ // For options that shouldn't be deep extended:
+ // you can add your own custom options here if
+ // and when you create one that shouldn't be
+ // deep extended (see ajaxExtend)
+ flatOptions: {
+ url: true,
+ context: true
+ }
+ },
+
+ // Creates a full fledged settings object into target
+ // with both ajaxSettings and settings fields.
+ // If target is omitted, writes into ajaxSettings.
+ ajaxSetup: function( target, settings ) {
+ return settings ?
+
+ // Building a settings object
+ ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
+
+ // Extending ajaxSettings
+ ajaxExtend( jQuery.ajaxSettings, target );
+ },
+
+ ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
+ ajaxTransport: addToPrefiltersOrTransports( transports ),
+
+ // Main method
+ ajax: function( url, options ) {
+
+ // If url is an object, simulate pre-1.5 signature
+ if ( typeof url === "object" ) {
+ options = url;
+ url = undefined;
+ }
+
+ // Force options to be an object
+ options = options || {};
+
+ var transport,
+
+ // URL without anti-cache param
+ cacheURL,
+
+ // Response headers
+ responseHeadersString,
+ responseHeaders,
+
+ // timeout handle
+ timeoutTimer,
+
+ // Url cleanup var
+ urlAnchor,
+
+ // Request state (becomes false upon send and true upon completion)
+ completed,
+
+ // To know if global events are to be dispatched
+ fireGlobals,
+
+ // Loop variable
+ i,
+
+ // uncached part of the url
+ uncached,
+
+ // Create the final options object
+ s = jQuery.ajaxSetup( {}, options ),
+
+ // Callbacks context
+ callbackContext = s.context || s,
+
+ // Context for global events is callbackContext if it is a DOM node or jQuery collection
+ globalEventContext = s.context &&
+ ( callbackContext.nodeType || callbackContext.jquery ) ?
+ jQuery( callbackContext ) :
+ jQuery.event,
+
+ // Deferreds
+ deferred = jQuery.Deferred(),
+ completeDeferred = jQuery.Callbacks( "once memory" ),
+
+ // Status-dependent callbacks
+ statusCode = s.statusCode || {},
+
+ // Headers (they are sent all at once)
+ requestHeaders = {},
+ requestHeadersNames = {},
+
+ // Default abort message
+ strAbort = "canceled",
+
+ // Fake xhr
+ jqXHR = {
+ readyState: 0,
+
+ // Builds headers hashtable if needed
+ getResponseHeader: function( key ) {
+ var match;
+ if ( completed ) {
+ if ( !responseHeaders ) {
+ responseHeaders = {};
+ while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
+ responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];
+ }
+ }
+ match = responseHeaders[ key.toLowerCase() ];
+ }
+ return match == null ? null : match;
+ },
+
+ // Raw string
+ getAllResponseHeaders: function() {
+ return completed ? responseHeadersString : null;
+ },
+
+ // Caches the header
+ setRequestHeader: function( name, value ) {
+ if ( completed == null ) {
+ name = requestHeadersNames[ name.toLowerCase() ] =
+ requestHeadersNames[ name.toLowerCase() ] || name;
+ requestHeaders[ name ] = value;
+ }
+ return this;
+ },
+
+ // Overrides response content-type header
+ overrideMimeType: function( type ) {
+ if ( completed == null ) {
+ s.mimeType = type;
+ }
+ return this;
+ },
+
+ // Status-dependent callbacks
+ statusCode: function( map ) {
+ var code;
+ if ( map ) {
+ if ( completed ) {
+
+ // Execute the appropriate callbacks
+ jqXHR.always( map[ jqXHR.status ] );
+ } else {
+
+ // Lazy-add the new callbacks in a way that preserves old ones
+ for ( code in map ) {
+ statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
+ }
+ }
+ }
+ return this;
+ },
+
+ // Cancel the request
+ abort: function( statusText ) {
+ var finalText = statusText || strAbort;
+ if ( transport ) {
+ transport.abort( finalText );
+ }
+ done( 0, finalText );
+ return this;
+ }
+ };
+
+ // Attach deferreds
+ deferred.promise( jqXHR );
+
+ // Add protocol if not provided (prefilters might expect it)
+ // Handle falsy url in the settings object (#10093: consistency with old signature)
+ // We also use the url parameter if available
+ s.url = ( ( url || s.url || location.href ) + "" )
+ .replace( rprotocol, location.protocol + "//" );
+
+ // Alias method option to type as per ticket #12004
+ s.type = options.method || options.type || s.method || s.type;
+
+ // Extract dataTypes list
+ s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ];
+
+ // A cross-domain request is in order when the origin doesn't match the current origin.
+ if ( s.crossDomain == null ) {
+ urlAnchor = document.createElement( "a" );
+
+ // Support: IE <=8 - 11, Edge 12 - 13
+ // IE throws exception on accessing the href property if url is malformed,
+ // e.g. http://example.com:80x/
+ try {
+ urlAnchor.href = s.url;
+
+ // Support: IE <=8 - 11 only
+ // Anchor's host property isn't correctly set when s.url is relative
+ urlAnchor.href = urlAnchor.href;
+ s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
+ urlAnchor.protocol + "//" + urlAnchor.host;
+ } catch ( e ) {
+
+ // If there is an error parsing the URL, assume it is crossDomain,
+ // it can be rejected by the transport if it is invalid
+ s.crossDomain = true;
+ }
+ }
+
+ // Convert data if not already a string
+ if ( s.data && s.processData && typeof s.data !== "string" ) {
+ s.data = jQuery.param( s.data, s.traditional );
+ }
+
+ // Apply prefilters
+ inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
+
+ // If request was aborted inside a prefilter, stop there
+ if ( completed ) {
+ return jqXHR;
+ }
+
+ // We can fire global events as of now if asked to
+ // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
+ fireGlobals = jQuery.event && s.global;
+
+ // Watch for a new set of requests
+ if ( fireGlobals && jQuery.active++ === 0 ) {
+ jQuery.event.trigger( "ajaxStart" );
+ }
+
+ // Uppercase the type
+ s.type = s.type.toUpperCase();
+
+ // Determine if request has content
+ s.hasContent = !rnoContent.test( s.type );
+
+ // Save the URL in case we're toying with the If-Modified-Since
+ // and/or If-None-Match header later on
+ // Remove hash to simplify url manipulation
+ cacheURL = s.url.replace( rhash, "" );
+
+ // More options handling for requests with no content
+ if ( !s.hasContent ) {
+
+ // Remember the hash so we can put it back
+ uncached = s.url.slice( cacheURL.length );
+
+ // If data is available, append data to url
+ if ( s.data ) {
+ cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data;
+
+ // #9682: remove data so that it's not used in an eventual retry
+ delete s.data;
+ }
+
+ // Add or update anti-cache param if needed
+ if ( s.cache === false ) {
+ cacheURL = cacheURL.replace( rantiCache, "$1" );
+ uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce++ ) + uncached;
+ }
+
+ // Put hash and anti-cache on the URL that will be requested (gh-1732)
+ s.url = cacheURL + uncached;
+
+ // Change '%20' to '+' if this is encoded form body content (gh-2658)
+ } else if ( s.data && s.processData &&
+ ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) {
+ s.data = s.data.replace( r20, "+" );
+ }
+
+ // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+ if ( s.ifModified ) {
+ if ( jQuery.lastModified[ cacheURL ] ) {
+ jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
+ }
+ if ( jQuery.etag[ cacheURL ] ) {
+ jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
+ }
+ }
+
+ // Set the correct header, if data is being sent
+ if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
+ jqXHR.setRequestHeader( "Content-Type", s.contentType );
+ }
+
+ // Set the Accepts header for the server, depending on the dataType
+ jqXHR.setRequestHeader(
+ "Accept",
+ s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
+ s.accepts[ s.dataTypes[ 0 ] ] +
+ ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
+ s.accepts[ "*" ]
+ );
+
+ // Check for headers option
+ for ( i in s.headers ) {
+ jqXHR.setRequestHeader( i, s.headers[ i ] );
+ }
+
+ // Allow custom headers/mimetypes and early abort
+ if ( s.beforeSend &&
+ ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {
+
+ // Abort if not done already and return
+ return jqXHR.abort();
+ }
+
+ // Aborting is no longer a cancellation
+ strAbort = "abort";
+
+ // Install callbacks on deferreds
+ completeDeferred.add( s.complete );
+ jqXHR.done( s.success );
+ jqXHR.fail( s.error );
+
+ // Get transport
+ transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
+
+ // If no transport, we auto-abort
+ if ( !transport ) {
+ done( -1, "No Transport" );
+ } else {
+ jqXHR.readyState = 1;
+
+ // Send global event
+ if ( fireGlobals ) {
+ globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
+ }
+
+ // If request was aborted inside ajaxSend, stop there
+ if ( completed ) {
+ return jqXHR;
+ }
+
+ // Timeout
+ if ( s.async && s.timeout > 0 ) {
+ timeoutTimer = window.setTimeout( function() {
+ jqXHR.abort( "timeout" );
+ }, s.timeout );
+ }
+
+ try {
+ completed = false;
+ transport.send( requestHeaders, done );
+ } catch ( e ) {
+
+ // Rethrow post-completion exceptions
+ if ( completed ) {
+ throw e;
+ }
+
+ // Propagate others as results
+ done( -1, e );
+ }
+ }
+
+ // Callback for when everything is done
+ function done( status, nativeStatusText, responses, headers ) {
+ var isSuccess, success, error, response, modified,
+ statusText = nativeStatusText;
+
+ // Ignore repeat invocations
+ if ( completed ) {
+ return;
+ }
+
+ completed = true;
+
+ // Clear timeout if it exists
+ if ( timeoutTimer ) {
+ window.clearTimeout( timeoutTimer );
+ }
+
+ // Dereference transport for early garbage collection
+ // (no matter how long the jqXHR object will be used)
+ transport = undefined;
+
+ // Cache response headers
+ responseHeadersString = headers || "";
+
+ // Set readyState
+ jqXHR.readyState = status > 0 ? 4 : 0;
+
+ // Determine if successful
+ isSuccess = status >= 200 && status < 300 || status === 304;
+
+ // Get response data
+ if ( responses ) {
+ response = ajaxHandleResponses( s, jqXHR, responses );
+ }
+
+ // Convert no matter what (that way responseXXX fields are always set)
+ response = ajaxConvert( s, response, jqXHR, isSuccess );
+
+ // If successful, handle type chaining
+ if ( isSuccess ) {
+
+ // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+ if ( s.ifModified ) {
+ modified = jqXHR.getResponseHeader( "Last-Modified" );
+ if ( modified ) {
+ jQuery.lastModified[ cacheURL ] = modified;
+ }
+ modified = jqXHR.getResponseHeader( "etag" );
+ if ( modified ) {
+ jQuery.etag[ cacheURL ] = modified;
+ }
+ }
+
+ // if no content
+ if ( status === 204 || s.type === "HEAD" ) {
+ statusText = "nocontent";
+
+ // if not modified
+ } else if ( status === 304 ) {
+ statusText = "notmodified";
+
+ // If we have data, let's convert it
+ } else {
+ statusText = response.state;
+ success = response.data;
+ error = response.error;
+ isSuccess = !error;
+ }
+ } else {
+
+ // Extract error from statusText and normalize for non-aborts
+ error = statusText;
+ if ( status || !statusText ) {
+ statusText = "error";
+ if ( status < 0 ) {
+ status = 0;
+ }
+ }
+ }
+
+ // Set data for the fake xhr object
+ jqXHR.status = status;
+ jqXHR.statusText = ( nativeStatusText || statusText ) + "";
+
+ // Success/Error
+ if ( isSuccess ) {
+ deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
+ } else {
+ deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
+ }
+
+ // Status-dependent callbacks
+ jqXHR.statusCode( statusCode );
+ statusCode = undefined;
+
+ if ( fireGlobals ) {
+ globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
+ [ jqXHR, s, isSuccess ? success : error ] );
+ }
+
+ // Complete
+ completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
+
+ if ( fireGlobals ) {
+ globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
+
+ // Handle the global AJAX counter
+ if ( !( --jQuery.active ) ) {
+ jQuery.event.trigger( "ajaxStop" );
+ }
+ }
+ }
+
+ return jqXHR;
+ },
+
+ getJSON: function( url, data, callback ) {
+ return jQuery.get( url, data, callback, "json" );
+ },
+
+ getScript: function( url, callback ) {
+ return jQuery.get( url, undefined, callback, "script" );
+ }
+} );
+
+jQuery.each( [ "get", "post" ], function( i, method ) {
+ jQuery[ method ] = function( url, data, callback, type ) {
+
+ // Shift arguments if data argument was omitted
+ if ( jQuery.isFunction( data ) ) {
+ type = type || callback;
+ callback = data;
+ data = undefined;
+ }
+
+ // The url can be an options object (which then must have .url)
+ return jQuery.ajax( jQuery.extend( {
+ url: url,
+ type: method,
+ dataType: type,
+ data: data,
+ success: callback
+ }, jQuery.isPlainObject( url ) && url ) );
+ };
+} );
+
+
+jQuery._evalUrl = function( url ) {
+ return jQuery.ajax( {
+ url: url,
+
+ // Make this explicit, since user can override this through ajaxSetup (#11264)
+ type: "GET",
+ dataType: "script",
+ cache: true,
+ async: false,
+ global: false,
+ "throws": true
+ } );
+};
+
+
+jQuery.fn.extend( {
+ wrapAll: function( html ) {
+ var wrap;
+
+ if ( this[ 0 ] ) {
+ if ( jQuery.isFunction( html ) ) {
+ html = html.call( this[ 0 ] );
+ }
+
+ // The elements to wrap the target around
+ wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
+
+ if ( this[ 0 ].parentNode ) {
+ wrap.insertBefore( this[ 0 ] );
+ }
+
+ wrap.map( function() {
+ var elem = this;
+
+ while ( elem.firstElementChild ) {
+ elem = elem.firstElementChild;
+ }
+
+ return elem;
+ } ).append( this );
+ }
+
+ return this;
+ },
+
+ wrapInner: function( html ) {
+ if ( jQuery.isFunction( html ) ) {
+ return this.each( function( i ) {
+ jQuery( this ).wrapInner( html.call( this, i ) );
+ } );
+ }
+
+ return this.each( function() {
+ var self = jQuery( this ),
+ contents = self.contents();
+
+ if ( contents.length ) {
+ contents.wrapAll( html );
+
+ } else {
+ self.append( html );
+ }
+ } );
+ },
+
+ wrap: function( html ) {
+ var isFunction = jQuery.isFunction( html );
+
+ return this.each( function( i ) {
+ jQuery( this ).wrapAll( isFunction ? html.call( this, i ) : html );
+ } );
+ },
+
+ unwrap: function( selector ) {
+ this.parent( selector ).not( "body" ).each( function() {
+ jQuery( this ).replaceWith( this.childNodes );
+ } );
+ return this;
+ }
+} );
+
+
+jQuery.expr.pseudos.hidden = function( elem ) {
+ return !jQuery.expr.pseudos.visible( elem );
+};
+jQuery.expr.pseudos.visible = function( elem ) {
+ return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
+};
+
+
+
+
+jQuery.ajaxSettings.xhr = function() {
+ try {
+ return new window.XMLHttpRequest();
+ } catch ( e ) {}
+};
+
+var xhrSuccessStatus = {
+
+ // File protocol always yields status code 0, assume 200
+ 0: 200,
+
+ // Support: IE <=9 only
+ // #1450: sometimes IE returns 1223 when it should be 204
+ 1223: 204
+ },
+ xhrSupported = jQuery.ajaxSettings.xhr();
+
+support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
+support.ajax = xhrSupported = !!xhrSupported;
+
+jQuery.ajaxTransport( function( options ) {
+ var callback, errorCallback;
+
+ // Cross domain only allowed if supported through XMLHttpRequest
+ if ( support.cors || xhrSupported && !options.crossDomain ) {
+ return {
+ send: function( headers, complete ) {
+ var i,
+ xhr = options.xhr();
+
+ xhr.open(
+ options.type,
+ options.url,
+ options.async,
+ options.username,
+ options.password
+ );
+
+ // Apply custom fields if provided
+ if ( options.xhrFields ) {
+ for ( i in options.xhrFields ) {
+ xhr[ i ] = options.xhrFields[ i ];
+ }
+ }
+
+ // Override mime type if needed
+ if ( options.mimeType && xhr.overrideMimeType ) {
+ xhr.overrideMimeType( options.mimeType );
+ }
+
+ // X-Requested-With header
+ // For cross-domain requests, seeing as conditions for a preflight are
+ // akin to a jigsaw puzzle, we simply never set it to be sure.
+ // (it can always be set on a per-request basis or even using ajaxSetup)
+ // For same-domain requests, won't change header if already provided.
+ if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
+ headers[ "X-Requested-With" ] = "XMLHttpRequest";
+ }
+
+ // Set headers
+ for ( i in headers ) {
+ xhr.setRequestHeader( i, headers[ i ] );
+ }
+
+ // Callback
+ callback = function( type ) {
+ return function() {
+ if ( callback ) {
+ callback = errorCallback = xhr.onload =
+ xhr.onerror = xhr.onabort = xhr.onreadystatechange = null;
+
+ if ( type === "abort" ) {
+ xhr.abort();
+ } else if ( type === "error" ) {
+
+ // Support: IE <=9 only
+ // On a manual native abort, IE9 throws
+ // errors on any property access that is not readyState
+ if ( typeof xhr.status !== "number" ) {
+ complete( 0, "error" );
+ } else {
+ complete(
+
+ // File: protocol always yields status 0; see #8605, #14207
+ xhr.status,
+ xhr.statusText
+ );
+ }
+ } else {
+ complete(
+ xhrSuccessStatus[ xhr.status ] || xhr.status,
+ xhr.statusText,
+
+ // Support: IE <=9 only
+ // IE9 has no XHR2 but throws on binary (trac-11426)
+ // For XHR2 non-text, let the caller handle it (gh-2498)
+ ( xhr.responseType || "text" ) !== "text" ||
+ typeof xhr.responseText !== "string" ?
+ { binary: xhr.response } :
+ { text: xhr.responseText },
+ xhr.getAllResponseHeaders()
+ );
+ }
+ }
+ };
+ };
+
+ // Listen to events
+ xhr.onload = callback();
+ errorCallback = xhr.onerror = callback( "error" );
+
+ // Support: IE 9 only
+ // Use onreadystatechange to replace onabort
+ // to handle uncaught aborts
+ if ( xhr.onabort !== undefined ) {
+ xhr.onabort = errorCallback;
+ } else {
+ xhr.onreadystatechange = function() {
+
+ // Check readyState before timeout as it changes
+ if ( xhr.readyState === 4 ) {
+
+ // Allow onerror to be called first,
+ // but that will not handle a native abort
+ // Also, save errorCallback to a variable
+ // as xhr.onerror cannot be accessed
+ window.setTimeout( function() {
+ if ( callback ) {
+ errorCallback();
+ }
+ } );
+ }
+ };
+ }
+
+ // Create the abort callback
+ callback = callback( "abort" );
+
+ try {
+
+ // Do send the request (this may raise an exception)
+ xhr.send( options.hasContent && options.data || null );
+ } catch ( e ) {
+
+ // #14683: Only rethrow if this hasn't been notified as an error yet
+ if ( callback ) {
+ throw e;
+ }
+ }
+ },
+
+ abort: function() {
+ if ( callback ) {
+ callback();
+ }
+ }
+ };
+ }
+} );
+
+
+
+
+// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)
+jQuery.ajaxPrefilter( function( s ) {
+ if ( s.crossDomain ) {
+ s.contents.script = false;
+ }
+} );
+
+// Install script dataType
+jQuery.ajaxSetup( {
+ accepts: {
+ script: "text/javascript, application/javascript, " +
+ "application/ecmascript, application/x-ecmascript"
+ },
+ contents: {
+ script: /\b(?:java|ecma)script\b/
+ },
+ converters: {
+ "text script": function( text ) {
+ jQuery.globalEval( text );
+ return text;
+ }
+ }
+} );
+
+// Handle cache's special case and crossDomain
+jQuery.ajaxPrefilter( "script", function( s ) {
+ if ( s.cache === undefined ) {
+ s.cache = false;
+ }
+ if ( s.crossDomain ) {
+ s.type = "GET";
+ }
+} );
+
+// Bind script tag hack transport
+jQuery.ajaxTransport( "script", function( s ) {
+
+ // This transport only deals with cross domain requests
+ if ( s.crossDomain ) {
+ var script, callback;
+ return {
+ send: function( _, complete ) {
+ script = jQuery( "<script>" ).prop( {
+ charset: s.scriptCharset,
+ src: s.url
+ } ).on(
+ "load error",
+ callback = function( evt ) {
+ script.remove();
+ callback = null;
+ if ( evt ) {
+ complete( evt.type === "error" ? 404 : 200, evt.type );
+ }
+ }
+ );
+
+ // Use native DOM manipulation to avoid our domManip AJAX trickery
+ document.head.appendChild( script[ 0 ] );
+ },
+ abort: function() {
+ if ( callback ) {
+ callback();
+ }
+ }
+ };
+ }
+} );
+
+
+
+
+var oldCallbacks = [],
+ rjsonp = /(=)\?(?=&|$)|\?\?/;
+
+// Default jsonp settings
+jQuery.ajaxSetup( {
+ jsonp: "callback",
+ jsonpCallback: function() {
+ var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
+ this[ callback ] = true;
+ return callback;
+ }
+} );
+
+// Detect, normalize options and install callbacks for jsonp requests
+jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
+
+ var callbackName, overwritten, responseContainer,
+ jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
+ "url" :
+ typeof s.data === "string" &&
+ ( s.contentType || "" )
+ .indexOf( "application/x-www-form-urlencoded" ) === 0 &&
+ rjsonp.test( s.data ) && "data"
+ );
+
+ // Handle iff the expected data type is "jsonp" or we have a parameter to set
+ if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
+
+ // Get callback name, remembering preexisting value associated with it
+ callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
+ s.jsonpCallback() :
+ s.jsonpCallback;
+
+ // Insert callback into url or form data
+ if ( jsonProp ) {
+ s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
+ } else if ( s.jsonp !== false ) {
+ s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
+ }
+
+ // Use data converter to retrieve json after script execution
+ s.converters[ "script json" ] = function() {
+ if ( !responseContainer ) {
+ jQuery.error( callbackName + " was not called" );
+ }
+ return responseContainer[ 0 ];
+ };
+
+ // Force json dataType
+ s.dataTypes[ 0 ] = "json";
+
+ // Install callback
+ overwritten = window[ callbackName ];
+ window[ callbackName ] = function() {
+ responseContainer = arguments;
+ };
+
+ // Clean-up function (fires after converters)
+ jqXHR.always( function() {
+
+ // If previous value didn't exist - remove it
+ if ( overwritten === undefined ) {
+ jQuery( window ).removeProp( callbackName );
+
+ // Otherwise restore preexisting value
+ } else {
+ window[ callbackName ] = overwritten;
+ }
+
+ // Save back as free
+ if ( s[ callbackName ] ) {
+
+ // Make sure that re-using the options doesn't screw things around
+ s.jsonpCallback = originalSettings.jsonpCallback;
+
+ // Save the callback name for future use
+ oldCallbacks.push( callbackName );
+ }
+
+ // Call if it was a function and we have a response
+ if ( responseContainer && jQuery.isFunction( overwritten ) ) {
+ overwritten( responseContainer[ 0 ] );
+ }
+
+ responseContainer = overwritten = undefined;
+ } );
+
+ // Delegate to script
+ return "script";
+ }
+} );
+
+
+
+
+// Support: Safari 8 only
+// In Safari 8 documents created via document.implementation.createHTMLDocument
+// collapse sibling forms: the second one becomes a child of the first one.
+// Because of that, this security measure has to be disabled in Safari 8.
+// https://bugs.webkit.org/show_bug.cgi?id=137337
+support.createHTMLDocument = ( function() {
+ var body = document.implementation.createHTMLDocument( "" ).body;
+ body.innerHTML = "<form></form><form></form>";
+ return body.childNodes.length === 2;
+} )();
+
+
+// Argument "data" should be string of html
+// context (optional): If specified, the fragment will be created in this context,
+// defaults to document
+// keepScripts (optional): If true, will include scripts passed in the html string
+jQuery.parseHTML = function( data, context, keepScripts ) {
+ if ( typeof data !== "string" ) {
+ return [];
+ }
+ if ( typeof context === "boolean" ) {
+ keepScripts = context;
+ context = false;
+ }
+
+ var base, parsed, scripts;
+
+ if ( !context ) {
+
+ // Stop scripts or inline event handlers from being executed immediately
+ // by using document.implementation
+ if ( support.createHTMLDocument ) {
+ context = document.implementation.createHTMLDocument( "" );
+
+ // Set the base href for the created document
+ // so any parsed elements with URLs
+ // are based on the document's URL (gh-2965)
+ base = context.createElement( "base" );
+ base.href = document.location.href;
+ context.head.appendChild( base );
+ } else {
+ context = document;
+ }
+ }
+
+ parsed = rsingleTag.exec( data );
+ scripts = !keepScripts && [];
+
+ // Single tag
+ if ( parsed ) {
+ return [ context.createElement( parsed[ 1 ] ) ];
+ }
+
+ parsed = buildFragment( [ data ], context, scripts );
+
+ if ( scripts && scripts.length ) {
+ jQuery( scripts ).remove();
+ }
+
+ return jQuery.merge( [], parsed.childNodes );
+};
+
+
+/**
+ * Load a url into a page
+ */
+jQuery.fn.load = function( url, params, callback ) {
+ var selector, type, response,
+ self = this,
+ off = url.indexOf( " " );
+
+ if ( off > -1 ) {
+ selector = stripAndCollapse( url.slice( off ) );
+ url = url.slice( 0, off );
+ }
+
+ // If it's a function
+ if ( jQuery.isFunction( params ) ) {
+
+ // We assume that it's the callback
+ callback = params;
+ params = undefined;
+
+ // Otherwise, build a param string
+ } else if ( params && typeof params === "object" ) {
+ type = "POST";
+ }
+
+ // If we have elements to modify, make the request
+ if ( self.length > 0 ) {
+ jQuery.ajax( {
+ url: url,
+
+ // If "type" variable is undefined, then "GET" method will be used.
+ // Make value of this field explicit since
+ // user can override it through ajaxSetup method
+ type: type || "GET",
+ dataType: "html",
+ data: params
+ } ).done( function( responseText ) {
+
+ // Save response for use in complete callback
+ response = arguments;
+
+ self.html( selector ?
+
+ // If a selector was specified, locate the right elements in a dummy div
+ // Exclude scripts to avoid IE 'Permission Denied' errors
+ jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :
+
+ // Otherwise use the full result
+ responseText );
+
+ // If the request succeeds, this function gets "data", "status", "jqXHR"
+ // but they are ignored because response was set above.
+ // If it fails, this function gets "jqXHR", "status", "error"
+ } ).always( callback && function( jqXHR, status ) {
+ self.each( function() {
+ callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
+ } );
+ } );
+ }
+
+ return this;
+};
+
+
+
+
+// Attach a bunch of functions for handling common AJAX events
+jQuery.each( [
+ "ajaxStart",
+ "ajaxStop",
+ "ajaxComplete",
+ "ajaxError",
+ "ajaxSuccess",
+ "ajaxSend"
+], function( i, type ) {
+ jQuery.fn[ type ] = function( fn ) {
+ return this.on( type, fn );
+ };
+} );
+
+
+
+
+jQuery.expr.pseudos.animated = function( elem ) {
+ return jQuery.grep( jQuery.timers, function( fn ) {
+ return elem === fn.elem;
+ } ).length;
+};
+
+
+
+
+jQuery.offset = {
+ setOffset: function( elem, options, i ) {
+ var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
+ position = jQuery.css( elem, "position" ),
+ curElem = jQuery( elem ),
+ props = {};
+
+ // Set position first, in-case top/left are set even on static elem
+ if ( position === "static" ) {
+ elem.style.position = "relative";
+ }
+
+ curOffset = curElem.offset();
+ curCSSTop = jQuery.css( elem, "top" );
+ curCSSLeft = jQuery.css( elem, "left" );
+ calculatePosition = ( position === "absolute" || position === "fixed" ) &&
+ ( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;
+
+ // Need to be able to calculate position if either
+ // top or left is auto and position is either absolute or fixed
+ if ( calculatePosition ) {
+ curPosition = curElem.position();
+ curTop = curPosition.top;
+ curLeft = curPosition.left;
+
+ } else {
+ curTop = parseFloat( curCSSTop ) || 0;
+ curLeft = parseFloat( curCSSLeft ) || 0;
+ }
+
+ if ( jQuery.isFunction( options ) ) {
+
+ // Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
+ options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
+ }
+
+ if ( options.top != null ) {
+ props.top = ( options.top - curOffset.top ) + curTop;
+ }
+ if ( options.left != null ) {
+ props.left = ( options.left - curOffset.left ) + curLeft;
+ }
+
+ if ( "using" in options ) {
+ options.using.call( elem, props );
+
+ } else {
+ curElem.css( props );
+ }
+ }
+};
+
+jQuery.fn.extend( {
+ offset: function( options ) {
+
+ // Preserve chaining for setter
+ if ( arguments.length ) {
+ return options === undefined ?
+ this :
+ this.each( function( i ) {
+ jQuery.offset.setOffset( this, options, i );
+ } );
+ }
+
+ var doc, docElem, rect, win,
+ elem = this[ 0 ];
+
+ if ( !elem ) {
+ return;
+ }
+
+ // Return zeros for disconnected and hidden (display: none) elements (gh-2310)
+ // Support: IE <=11 only
+ // Running getBoundingClientRect on a
+ // disconnected node in IE throws an error
+ if ( !elem.getClientRects().length ) {
+ return { top: 0, left: 0 };
+ }
+
+ rect = elem.getBoundingClientRect();
+
+ doc = elem.ownerDocument;
+ docElem = doc.documentElement;
+ win = doc.defaultView;
+
+ return {
+ top: rect.top + win.pageYOffset - docElem.clientTop,
+ left: rect.left + win.pageXOffset - docElem.clientLeft
+ };
+ },
+
+ position: function() {
+ if ( !this[ 0 ] ) {
+ return;
+ }
+
+ var offsetParent, offset,
+ elem = this[ 0 ],
+ parentOffset = { top: 0, left: 0 };
+
+ // Fixed elements are offset from window (parentOffset = {top:0, left: 0},
+ // because it is its only offset parent
+ if ( jQuery.css( elem, "position" ) === "fixed" ) {
+
+ // Assume getBoundingClientRect is there when computed position is fixed
+ offset = elem.getBoundingClientRect();
+
+ } else {
+
+ // Get *real* offsetParent
+ offsetParent = this.offsetParent();
+
+ // Get correct offsets
+ offset = this.offset();
+ if ( !nodeName( offsetParent[ 0 ], "html" ) ) {
+ parentOffset = offsetParent.offset();
+ }
+
+ // Add offsetParent borders
+ parentOffset = {
+ top: parentOffset.top + jQuery.css( offsetParent[ 0 ], "borderTopWidth", true ),
+ left: parentOffset.left + jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true )
+ };
+ }
+
+ // Subtract parent offsets and element margins
+ return {
+ top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
+ left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
+ };
+ },
+
+ // This method will return documentElement in the following cases:
+ // 1) For the element inside the iframe without offsetParent, this method will return
+ // documentElement of the parent window
+ // 2) For the hidden or detached element
+ // 3) For body or html element, i.e. in case of the html node - it will return itself
+ //
+ // but those exceptions were never presented as a real life use-cases
+ // and might be considered as more preferable results.
+ //
+ // This logic, however, is not guaranteed and can change at any point in the future
+ offsetParent: function() {
+ return this.map( function() {
+ var offsetParent = this.offsetParent;
+
+ while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {
+ offsetParent = offsetParent.offsetParent;
+ }
+
+ return offsetParent || documentElement;
+ } );
+ }
+} );
+
+// Create scrollLeft and scrollTop methods
+jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
+ var top = "pageYOffset" === prop;
+
+ jQuery.fn[ method ] = function( val ) {
+ return access( this, function( elem, method, val ) {
+
+ // Coalesce documents and windows
+ var win;
+ if ( jQuery.isWindow( elem ) ) {
+ win = elem;
+ } else if ( elem.nodeType === 9 ) {
+ win = elem.defaultView;
+ }
+
+ if ( val === undefined ) {
+ return win ? win[ prop ] : elem[ method ];
+ }
+
+ if ( win ) {
+ win.scrollTo(
+ !top ? val : win.pageXOffset,
+ top ? val : win.pageYOffset
+ );
+
+ } else {
+ elem[ method ] = val;
+ }
+ }, method, val, arguments.length );
+ };
+} );
+
+// Support: Safari <=7 - 9.1, Chrome <=37 - 49
+// Add the top/left cssHooks using jQuery.fn.position
+// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
+// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347
+// getComputedStyle returns percent when specified for top/left/bottom/right;
+// rather than make the css module depend on the offset module, just check for it here
+jQuery.each( [ "top", "left" ], function( i, prop ) {
+ jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
+ function( elem, computed ) {
+ if ( computed ) {
+ computed = curCSS( elem, prop );
+
+ // If curCSS returns percentage, fallback to offset
+ return rnumnonpx.test( computed ) ?
+ jQuery( elem ).position()[ prop ] + "px" :
+ computed;
+ }
+ }
+ );
+} );
+
+
+// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
+jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
+ jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name },
+ function( defaultExtra, funcName ) {
+
+ // Margin is only for outerHeight, outerWidth
+ jQuery.fn[ funcName ] = function( margin, value ) {
+ var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
+ extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
+
+ return access( this, function( elem, type, value ) {
+ var doc;
+
+ if ( jQuery.isWindow( elem ) ) {
+
+ // $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)
+ return funcName.indexOf( "outer" ) === 0 ?
+ elem[ "inner" + name ] :
+ elem.document.documentElement[ "client" + name ];
+ }
+
+ // Get document width or height
+ if ( elem.nodeType === 9 ) {
+ doc = elem.documentElement;
+
+ // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
+ // whichever is greatest
+ return Math.max(
+ elem.body[ "scroll" + name ], doc[ "scroll" + name ],
+ elem.body[ "offset" + name ], doc[ "offset" + name ],
+ doc[ "client" + name ]
+ );
+ }
+
+ return value === undefined ?
+
+ // Get width or height on the element, requesting but not forcing parseFloat
+ jQuery.css( elem, type, extra ) :
+
+ // Set width or height on the element
+ jQuery.style( elem, type, value, extra );
+ }, type, chainable ? margin : undefined, chainable );
+ };
+ } );
+} );
+
+
+jQuery.fn.extend( {
+
+ bind: function( types, data, fn ) {
+ return this.on( types, null, data, fn );
+ },
+ unbind: function( types, fn ) {
+ return this.off( types, null, fn );
+ },
+
+ delegate: function( selector, types, data, fn ) {
+ return this.on( types, selector, data, fn );
+ },
+ undelegate: function( selector, types, fn ) {
+
+ // ( namespace ) or ( selector, types [, fn] )
+ return arguments.length === 1 ?
+ this.off( selector, "**" ) :
+ this.off( types, selector || "**", fn );
+ }
+} );
+
+jQuery.holdReady = function( hold ) {
+ if ( hold ) {
+ jQuery.readyWait++;
+ } else {
+ jQuery.ready( true );
+ }
+};
+jQuery.isArray = Array.isArray;
+jQuery.parseJSON = JSON.parse;
+jQuery.nodeName = nodeName;
+
+
+
+
+// Register as a named AMD module, since jQuery can be concatenated with other
+// files that may use define, but not via a proper concatenation script that
+// understands anonymous AMD modules. A named AMD is safest and most robust
+// way to register. Lowercase jquery is used because AMD module names are
+// derived from file names, and jQuery is normally delivered in a lowercase
+// file name. Do this after creating the global so that if an AMD module wants
+// to call noConflict to hide this version of jQuery, it will work.
+
+// Note that for maximum portability, libraries that are not jQuery should
+// declare themselves as anonymous modules, and avoid setting a global if an
+// AMD loader is present. jQuery is a special case. For more information, see
+// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
+
+if ( typeof define === "function" && define.amd ) {
+ define( "jquery", [], function() {
+ return jQuery;
+ } );
+}
+
+
+
+
+var
+
+ // Map over jQuery in case of overwrite
+ _jQuery = window.jQuery,
+
+ // Map over the $ in case of overwrite
+ _$ = window.$;
+
+jQuery.noConflict = function( deep ) {
+ if ( window.$ === jQuery ) {
+ window.$ = _$;
+ }
+
+ if ( deep && window.jQuery === jQuery ) {
+ window.jQuery = _jQuery;
+ }
+
+ return jQuery;
+};
+
+// Expose jQuery and $ identifiers, even in AMD
+// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
+// and CommonJS for browser emulators (#13566)
+if ( !noGlobal ) {
+ window.jQuery = window.$ = jQuery;
+}
+
+
+
+
+return jQuery;
+} );
diff --git a/doc/html/_static/jquery.js b/doc/html/_static/jquery.js
new file mode 100644
index 0000000..644d35e
--- /dev/null
+++ b/doc/html/_static/jquery.js
@@ -0,0 +1,4 @@
+/*! jQuery v3.2.1 | (c) JS Foundation and other contributors | jquery.org/license */
+!function(a,b){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){"use strict";var c=[],d=a.document,e=Object.getPrototypeOf,f=c.slice,g=c.concat,h=c.push,i=c.indexOf,j={},k=j.toString,l=j.hasOwnProperty,m=l.toString,n=m.call(Object),o={};function p(a,b){b=b||d;var c=b.createElement("script");c.text=a,b.head.appendChild(c).parentNode.removeChild(c)}var q="3.2.1",r=function(a,b){return new r.fn.init(a,b)},s=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,t=/^-ms-/,u=/-([a-z])/g,v=function(a,b){return b.toUpperCase()};r.fn=r.prototype={jquery:q,constructor:r,length:0,toArray:function(){return f.call(this)},get:function(a){return null==a?f.call(this):a<0?this[a+this.length]:this[a]},pushStack:function(a){var b=r.merge(this.constructor(),a);return b.prevObject=this,b},each:function(a){return r.each(this,a)},map:function(a){return this.pushStack(r.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(f.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(a<0?b:0);return this.pushStack(c>=0&&c<b?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:h,sort:c.sort,splice:c.splice},r.extend=r.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||r.isFunction(g)||(g={}),h===i&&(g=this,h--);h<i;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(r.isPlainObject(d)||(e=Array.isArray(d)))?(e?(e=!1,f=c&&Array.isArray(c)?c:[]):f=c&&r.isPlainObject(c)?c:{},g[b]=r.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},r.extend({expando:"jQuery"+(q+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===r.type(a)},isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){var b=r.type(a);return("number"===b||"string"===b)&&!isNaN(a-parseFloat(a))},isPlainObject:function(a){var b,c;return!(!a||"[object Object]"!==k.call(a))&&(!(b=e(a))||(c=l.call(b,"constructor")&&b.constructor,"function"==typeof c&&m.call(c)===n))},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?j[k.call(a)]||"object":typeof a},globalEval:function(a){p(a)},camelCase:function(a){return a.replace(t,"ms-").replace(u,v)},each:function(a,b){var c,d=0;if(w(a)){for(c=a.length;d<c;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(s,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(w(Object(a))?r.merge(c,"string"==typeof a?[a]:a):h.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:i.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;d<c;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;f<g;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,f=0,h=[];if(w(a))for(d=a.length;f<d;f++)e=b(a[f],f,c),null!=e&&h.push(e);else for(f in a)e=b(a[f],f,c),null!=e&&h.push(e);return g.apply([],h)},guid:1,proxy:function(a,b){var c,d,e;if("string"==typeof b&&(c=a[b],b=a,a=c),r.isFunction(a))return d=f.call(arguments,2),e=function(){return a.apply(b||this,d.concat(f.call(arguments)))},e.guid=a.guid=a.guid||r.guid++,e},now:Date.now,support:o}),"function"==typeof Symbol&&(r.fn[Symbol.iterator]=c[Symbol.iterator]),r.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){j["[object "+b+"]"]=b.toLowerCase()});function w(a){var b=!!a&&"length"in a&&a.length,c=r.type(a);return"function"!==c&&!r.isWindow(a)&&("array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a)}var x=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;c<d;c++)if(a[c]===b)return c;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\0-\\xa0])+",M="\\["+K+"*("+L+")(?:"+K+"*([*^$|!~]?=)"+K+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+L+"))|)"+K+"*\\]",N=":("+L+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+M+")*)|.*)\\)|)",O=new RegExp(K+"+","g"),P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(N),U=new RegExp("^"+L+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+N),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),aa=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:d<0?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ba=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ca=function(a,b){return b?"\0"===a?"\ufffd":a.slice(0,-1)+"\\"+a.charCodeAt(a.length-1).toString(16)+" ":"\\"+a},da=function(){m()},ea=ta(function(a){return a.disabled===!0&&("form"in a||"label"in a)},{dir:"parentNode",next:"legend"});try{G.apply(D=H.call(v.childNodes),v.childNodes),D[v.childNodes.length].nodeType}catch(fa){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s=b&&b.ownerDocument,w=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==w&&9!==w&&11!==w)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==w&&(l=Z.exec(a)))if(f=l[1]){if(9===w){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(s&&(j=s.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(l[2])return G.apply(d,b.getElementsByTagName(a)),d;if((f=l[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==w)s=b,r=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(ba,ca):b.setAttribute("id",k=u),o=g(a),h=o.length;while(h--)o[h]="#"+k+" "+sa(o[h]);r=o.join(","),s=$.test(a)&&qa(b.parentNode)||b}if(r)try{return G.apply(d,s.querySelectorAll(r)),d}catch(x){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(P,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("fieldset");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&a.sourceIndex-b.sourceIndex;if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return function(b){return"form"in b?b.parentNode&&b.disabled===!1?"label"in b?"label"in b.parentNode?b.parentNode.disabled===a:b.disabled===a:b.isDisabled===a||b.isDisabled!==!a&&ea(b)===a:b.disabled===a:"label"in b&&b.disabled===a}}function pa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function qa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return!!b&&"HTML"!==b.nodeName},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),v!==n&&(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(n.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){return a.getAttribute("id")===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}}):(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c,d,e,f=b.getElementById(a);if(f){if(c=f.getAttributeNode("id"),c&&c.value===a)return[f];e=b.getElementsByName(a),d=0;while(f=e[d++])if(c=f.getAttributeNode("id"),c&&c.value===a)return[f]}return[]}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){if("undefined"!=typeof b.getElementsByClassName&&p)return b.getElementsByClassName(a)},r=[],q=[],(c.qsa=Y.test(n.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\r\\' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){a.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+K+"*[*^$|!~]?="),2!==a.querySelectorAll(":enabled").length&&q.push(":enabled",":disabled"),o.appendChild(a).disabled=!0,2!==a.querySelectorAll(":disabled").length&&q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Y.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"*"),s.call(a,"[s!='']:x"),r.push("!=",N)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Y.test(o.compareDocumentPosition),t=b||Y.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?I(k,a)-I(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?I(k,a)-I(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?la(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(S,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.escape=function(a){return(a+"").replace(ba,ca)},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(_,aa),a[3]=(a[3]||a[4]||a[5]||"").replace(_,aa),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return V.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&T.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(_,aa).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:!b||(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(O," ")+" ").indexOf(c)>-1:"|="===b&&(e===c||e.slice(0,c.length+1)===c+"-"))}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(P,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(_,aa),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return U.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(_,aa).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:oa(!1),disabled:oa(!0),checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:pa(function(){return[0]}),last:pa(function(a,b){return[b-1]}),eq:pa(function(a,b,c){return[c<0?c+b:c]}),even:pa(function(a,b){for(var c=0;c<b;c+=2)a.push(c);return a}),odd:pa(function(a,b){for(var c=1;c<b;c+=2)a.push(c);return a}),lt:pa(function(a,b,c){for(var d=c<0?c+b:c;--d>=0;)a.push(d);return a}),gt:pa(function(a,b,c){for(var d=c<0?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=ma(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=na(b);function ra(){}ra.prototype=d.filters=d.pseudos,d.setFilters=new ra,g=ga.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){c&&!(e=Q.exec(h))||(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=R.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(P," ")}),h=h.slice(c.length));for(g in d.filter)!(e=V[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?ga.error(a):z(a,i).slice(0)};function sa(a){for(var b=0,c=a.length,d="";b<c;b++)d+=a[b].value;return d}function ta(a,b,c){var d=b.dir,e=b.next,f=e||d,g=c&&"parentNode"===f,h=x++;return b.first?function(b,c,e){while(b=b[d])if(1===b.nodeType||g)return a(b,c,e);return!1}:function(b,c,i){var j,k,l,m=[w,h];if(i){while(b=b[d])if((1===b.nodeType||g)&&a(b,c,i))return!0}else while(b=b[d])if(1===b.nodeType||g)if(l=b[u]||(b[u]={}),k=l[b.uniqueID]||(l[b.uniqueID]={}),e&&e===b.nodeName.toLowerCase())b=b[d]||b;else{if((j=k[f])&&j[0]===w&&j[1]===h)return m[2]=j[2];if(k[f]=m,m[2]=a(b,c,i))return!0}return!1}}function ua(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function va(a,b,c){for(var d=0,e=b.length;d<e;d++)ga(a,b[d],c);return c}function wa(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;h<i;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function xa(a,b,c,d,e,f){return d&&!d[u]&&(d=xa(d)),e&&!e[u]&&(e=xa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||va(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:wa(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=wa(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?I(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=wa(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ya(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ta(function(a){return a===b},h,!0),l=ta(function(a){return I(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];i<f;i++)if(c=d.relative[a[i].type])m=[ta(ua(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;e<f;e++)if(d.relative[a[e].type])break;return xa(i>1&&ua(m),i>1&&sa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(P,"$1"),c,i<e&&ya(a.slice(i,e)),e<f&&ya(a=a.slice(e)),e<f&&sa(a))}m.push(c)}return ua(m)}function za(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=E.call(i));u=wa(u)}G.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&ga.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=ya(b[c]),f[u]?d.push(f):e.push(f);f=A(a,za(e,d)),f.selector=a}return f},i=ga.select=function(a,b,c,e){var f,i,j,k,l,m="function"==typeof a&&a,n=!e&&g(a=m.selector||a);if(c=c||[],1===n.length){if(i=n[0]=n[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&9===b.nodeType&&p&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(_,aa),b)||[])[0],!b)return c;m&&(b=b.parentNode),a=a.slice(i.shift().value.length)}f=V.needsContext.test(a)?0:i.length;while(f--){if(j=i[f],d.relative[k=j.type])break;if((l=d.find[k])&&(e=l(j.matches[0].replace(_,aa),$.test(i[0].type)&&qa(b.parentNode)||b))){if(i.splice(f,1),a=e.length&&sa(i),!a)return G.apply(c,e),c;break}}}return(m||h(a,n))(e,b,!p,c,!b||$.test(a)&&qa(b.parentNode)||b),c},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("fieldset"))}),ja(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){if(!c)return a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){if(!c&&"input"===a.nodeName.toLowerCase())return a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(J,function(a,b,c){var d;if(!c)return a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);r.find=x,r.expr=x.selectors,r.expr[":"]=r.expr.pseudos,r.uniqueSort=r.unique=x.uniqueSort,r.text=x.getText,r.isXMLDoc=x.isXML,r.contains=x.contains,r.escapeSelector=x.escape;var y=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&r(a).is(c))break;d.push(a)}return d},z=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},A=r.expr.match.needsContext;function B(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()}var C=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i,D=/^.[^:#\[\.,]*$/;function E(a,b,c){return r.isFunction(b)?r.grep(a,function(a,d){return!!b.call(a,d,a)!==c}):b.nodeType?r.grep(a,function(a){return a===b!==c}):"string"!=typeof b?r.grep(a,function(a){return i.call(b,a)>-1!==c}):D.test(b)?r.filter(b,a,c):(b=r.filter(b,a),r.grep(a,function(a){return i.call(b,a)>-1!==c&&1===a.nodeType}))}r.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?r.find.matchesSelector(d,a)?[d]:[]:r.find.matches(a,r.grep(b,function(a){return 1===a.nodeType}))},r.fn.extend({find:function(a){var b,c,d=this.length,e=this;if("string"!=typeof a)return this.pushStack(r(a).filter(function(){for(b=0;b<d;b++)if(r.contains(e[b],this))return!0}));for(c=this.pushStack([]),b=0;b<d;b++)r.find(a,e[b],c);return d>1?r.uniqueSort(c):c},filter:function(a){return this.pushStack(E(this,a||[],!1))},not:function(a){return this.pushStack(E(this,a||[],!0))},is:function(a){return!!E(this,"string"==typeof a&&A.test(a)?r(a):a||[],!1).length}});var F,G=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,H=r.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||F,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:G.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof r?b[0]:b,r.merge(this,r.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),C.test(e[1])&&r.isPlainObject(b))for(e in b)r.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&(this[0]=f,this.length=1),this}return a.nodeType?(this[0]=a,this.length=1,this):r.isFunction(a)?void 0!==c.ready?c.ready(a):a(r):r.makeArray(a,this)};H.prototype=r.fn,F=r(d);var I=/^(?:parents|prev(?:Until|All))/,J={children:!0,contents:!0,next:!0,prev:!0};r.fn.extend({has:function(a){var b=r(a,this),c=b.length;return this.filter(function(){for(var a=0;a<c;a++)if(r.contains(this,b[a]))return!0})},closest:function(a,b){var c,d=0,e=this.length,f=[],g="string"!=typeof a&&r(a);if(!A.test(a))for(;d<e;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&r.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?r.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?i.call(r(a),this[0]):i.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(r.uniqueSort(r.merge(this.get(),r(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function K(a,b){while((a=a[b])&&1!==a.nodeType);return a}r.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return y(a,"parentNode")},parentsUntil:function(a,b,c){return y(a,"parentNode",c)},next:function(a){return K(a,"nextSibling")},prev:function(a){return K(a,"previousSibling")},nextAll:function(a){return y(a,"nextSibling")},prevAll:function(a){return y(a,"previousSibling")},nextUntil:function(a,b,c){return y(a,"nextSibling",c)},prevUntil:function(a,b,c){return y(a,"previousSibling",c)},siblings:function(a){return z((a.parentNode||{}).firstChild,a)},children:function(a){return z(a.firstChild)},contents:function(a){return B(a,"iframe")?a.contentDocument:(B(a,"template")&&(a=a.content||a),r.merge([],a.childNodes))}},function(a,b){r.fn[a]=function(c,d){var e=r.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=r.filter(d,e)),this.length>1&&(J[a]||r.uniqueSort(e),I.test(a)&&e.reverse()),this.pushStack(e)}});var L=/[^\x20\t\r\n\f]+/g;function M(a){var b={};return r.each(a.match(L)||[],function(a,c){b[c]=!0}),b}r.Callbacks=function(a){a="string"==typeof a?M(a):r.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=e||a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h<f.length)f[h].apply(c[0],c[1])===!1&&a.stopOnFalse&&(h=f.length,c=!1)}a.memory||(c=!1),b=!1,e&&(f=c?[]:"")},j={add:function(){return f&&(c&&!b&&(h=f.length-1,g.push(c)),function d(b){r.each(b,function(b,c){r.isFunction(c)?a.unique&&j.has(c)||f.push(c):c&&c.length&&"string"!==r.type(c)&&d(c)})}(arguments),c&&!b&&i()),this},remove:function(){return r.each(arguments,function(a,b){var c;while((c=r.inArray(b,f,c))>-1)f.splice(c,1),c<=h&&h--}),this},has:function(a){return a?r.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||b||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j};function N(a){return a}function O(a){throw a}function P(a,b,c,d){var e;try{a&&r.isFunction(e=a.promise)?e.call(a).done(b).fail(c):a&&r.isFunction(e=a.then)?e.call(a,b,c):b.apply(void 0,[a].slice(d))}catch(a){c.apply(void 0,[a])}}r.extend({Deferred:function(b){var c=[["notify","progress",r.Callbacks("memory"),r.Callbacks("memory"),2],["resolve","done",r.Callbacks("once memory"),r.Callbacks("once memory"),0,"resolved"],["reject","fail",r.Callbacks("once memory"),r.Callbacks("once memory"),1,"rejected"]],d="pending",e={state:function(){return d},always:function(){return f.done(arguments).fail(arguments),this},"catch":function(a){return e.then(null,a)},pipe:function(){var a=arguments;return r.Deferred(function(b){r.each(c,function(c,d){var e=r.isFunction(a[d[4]])&&a[d[4]];f[d[1]](function(){var a=e&&e.apply(this,arguments);a&&r.isFunction(a.promise)?a.promise().progress(b.notify).done(b.resolve).fail(b.reject):b[d[0]+"With"](this,e?[a]:arguments)})}),a=null}).promise()},then:function(b,d,e){var f=0;function g(b,c,d,e){return function(){var h=this,i=arguments,j=function(){var a,j;if(!(b<f)){if(a=d.apply(h,i),a===c.promise())throw new TypeError("Thenable self-resolution");j=a&&("object"==typeof a||"function"==typeof a)&&a.then,r.isFunction(j)?e?j.call(a,g(f,c,N,e),g(f,c,O,e)):(f++,j.call(a,g(f,c,N,e),g(f,c,O,e),g(f,c,N,c.notifyWith))):(d!==N&&(h=void 0,i=[a]),(e||c.resolveWith)(h,i))}},k=e?j:function(){try{j()}catch(a){r.Deferred.exceptionHook&&r.Deferred.exceptionHook(a,k.stackTrace),b+1>=f&&(d!==O&&(h=void 0,i=[a]),c.rejectWith(h,i))}};b?k():(r.Deferred.getStackHook&&(k.stackTrace=r.Deferred.getStackHook()),a.setTimeout(k))}}return r.Deferred(function(a){c[0][3].add(g(0,a,r.isFunction(e)?e:N,a.notifyWith)),c[1][3].add(g(0,a,r.isFunction(b)?b:N)),c[2][3].add(g(0,a,r.isFunction(d)?d:O))}).promise()},promise:function(a){return null!=a?r.extend(a,e):e}},f={};return r.each(c,function(a,b){var g=b[2],h=b[5];e[b[1]]=g.add,h&&g.add(function(){d=h},c[3-a][2].disable,c[0][2].lock),g.add(b[3].fire),f[b[0]]=function(){return f[b[0]+"With"](this===f?void 0:this,arguments),this},f[b[0]+"With"]=g.fireWith}),e.promise(f),b&&b.call(f,f),f},when:function(a){var b=arguments.length,c=b,d=Array(c),e=f.call(arguments),g=r.Deferred(),h=function(a){return function(c){d[a]=this,e[a]=arguments.length>1?f.call(arguments):c,--b||g.resolveWith(d,e)}};if(b<=1&&(P(a,g.done(h(c)).resolve,g.reject,!b),"pending"===g.state()||r.isFunction(e[c]&&e[c].then)))return g.then();while(c--)P(e[c],h(c),g.reject);return g.promise()}});var Q=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;r.Deferred.exceptionHook=function(b,c){a.console&&a.console.warn&&b&&Q.test(b.name)&&a.console.warn("jQuery.Deferred exception: "+b.message,b.stack,c)},r.readyException=function(b){a.setTimeout(function(){throw b})};var R=r.Deferred();r.fn.ready=function(a){return R.then(a)["catch"](function(a){r.readyException(a)}),this},r.extend({isReady:!1,readyWait:1,ready:function(a){(a===!0?--r.readyWait:r.isReady)||(r.isReady=!0,a!==!0&&--r.readyWait>0||R.resolveWith(d,[r]))}}),r.ready.then=R.then;function S(){d.removeEventListener("DOMContentLoaded",S),
+a.removeEventListener("load",S),r.ready()}"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(r.ready):(d.addEventListener("DOMContentLoaded",S),a.addEventListener("load",S));var T=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===r.type(c)){e=!0;for(h in c)T(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,r.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(r(a),c)})),b))for(;h<i;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},U=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function V(){this.expando=r.expando+V.uid++}V.uid=1,V.prototype={cache:function(a){var b=a[this.expando];return b||(b={},U(a)&&(a.nodeType?a[this.expando]=b:Object.defineProperty(a,this.expando,{value:b,configurable:!0}))),b},set:function(a,b,c){var d,e=this.cache(a);if("string"==typeof b)e[r.camelCase(b)]=c;else for(d in b)e[r.camelCase(d)]=b[d];return e},get:function(a,b){return void 0===b?this.cache(a):a[this.expando]&&a[this.expando][r.camelCase(b)]},access:function(a,b,c){return void 0===b||b&&"string"==typeof b&&void 0===c?this.get(a,b):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d=a[this.expando];if(void 0!==d){if(void 0!==b){Array.isArray(b)?b=b.map(r.camelCase):(b=r.camelCase(b),b=b in d?[b]:b.match(L)||[]),c=b.length;while(c--)delete d[b[c]]}(void 0===b||r.isEmptyObject(d))&&(a.nodeType?a[this.expando]=void 0:delete a[this.expando])}},hasData:function(a){var b=a[this.expando];return void 0!==b&&!r.isEmptyObject(b)}};var W=new V,X=new V,Y=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Z=/[A-Z]/g;function $(a){return"true"===a||"false"!==a&&("null"===a?null:a===+a+""?+a:Y.test(a)?JSON.parse(a):a)}function _(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(Z,"-$&").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c=$(c)}catch(e){}X.set(a,b,c)}else c=void 0;return c}r.extend({hasData:function(a){return X.hasData(a)||W.hasData(a)},data:function(a,b,c){return X.access(a,b,c)},removeData:function(a,b){X.remove(a,b)},_data:function(a,b,c){return W.access(a,b,c)},_removeData:function(a,b){W.remove(a,b)}}),r.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=X.get(f),1===f.nodeType&&!W.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=r.camelCase(d.slice(5)),_(f,d,e[d])));W.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){X.set(this,a)}):T(this,function(b){var c;if(f&&void 0===b){if(c=X.get(f,a),void 0!==c)return c;if(c=_(f,a),void 0!==c)return c}else this.each(function(){X.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){X.remove(this,a)})}}),r.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=W.get(a,b),c&&(!d||Array.isArray(c)?d=W.access(a,b,r.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=r.queue(a,b),d=c.length,e=c.shift(),f=r._queueHooks(a,b),g=function(){r.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return W.get(a,c)||W.access(a,c,{empty:r.Callbacks("once memory").add(function(){W.remove(a,[b+"queue",c])})})}}),r.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?r.queue(this[0],a):void 0===b?this:this.each(function(){var c=r.queue(this,a,b);r._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&r.dequeue(this,a)})},dequeue:function(a){return this.each(function(){r.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=r.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=W.get(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var aa=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,ba=new RegExp("^(?:([+-])=|)("+aa+")([a-z%]*)$","i"),ca=["Top","Right","Bottom","Left"],da=function(a,b){return a=b||a,"none"===a.style.display||""===a.style.display&&r.contains(a.ownerDocument,a)&&"none"===r.css(a,"display")},ea=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};function fa(a,b,c,d){var e,f=1,g=20,h=d?function(){return d.cur()}:function(){return r.css(a,b,"")},i=h(),j=c&&c[3]||(r.cssNumber[b]?"":"px"),k=(r.cssNumber[b]||"px"!==j&&+i)&&ba.exec(r.css(a,b));if(k&&k[3]!==j){j=j||k[3],c=c||[],k=+i||1;do f=f||".5",k/=f,r.style(a,b,k+j);while(f!==(f=h()/i)&&1!==f&&--g)}return c&&(k=+k||+i||0,e=c[1]?k+(c[1]+1)*c[2]:+c[2],d&&(d.unit=j,d.start=k,d.end=e)),e}var ga={};function ha(a){var b,c=a.ownerDocument,d=a.nodeName,e=ga[d];return e?e:(b=c.body.appendChild(c.createElement(d)),e=r.css(b,"display"),b.parentNode.removeChild(b),"none"===e&&(e="block"),ga[d]=e,e)}function ia(a,b){for(var c,d,e=[],f=0,g=a.length;f<g;f++)d=a[f],d.style&&(c=d.style.display,b?("none"===c&&(e[f]=W.get(d,"display")||null,e[f]||(d.style.display="")),""===d.style.display&&da(d)&&(e[f]=ha(d))):"none"!==c&&(e[f]="none",W.set(d,"display",c)));for(f=0;f<g;f++)null!=e[f]&&(a[f].style.display=e[f]);return a}r.fn.extend({show:function(){return ia(this,!0)},hide:function(){return ia(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){da(this)?r(this).show():r(this).hide()})}});var ja=/^(?:checkbox|radio)$/i,ka=/<([a-z][^\/\0>\x20\t\r\n\f]+)/i,la=/^$|\/(?:java|ecma)script/i,ma={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};ma.optgroup=ma.option,ma.tbody=ma.tfoot=ma.colgroup=ma.caption=ma.thead,ma.th=ma.td;function na(a,b){var c;return c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[],void 0===b||b&&B(a,b)?r.merge([a],c):c}function oa(a,b){for(var c=0,d=a.length;c<d;c++)W.set(a[c],"globalEval",!b||W.get(b[c],"globalEval"))}var pa=/<|&#?\w+;/;function qa(a,b,c,d,e){for(var f,g,h,i,j,k,l=b.createDocumentFragment(),m=[],n=0,o=a.length;n<o;n++)if(f=a[n],f||0===f)if("object"===r.type(f))r.merge(m,f.nodeType?[f]:f);else if(pa.test(f)){g=g||l.appendChild(b.createElement("div")),h=(ka.exec(f)||["",""])[1].toLowerCase(),i=ma[h]||ma._default,g.innerHTML=i[1]+r.htmlPrefilter(f)+i[2],k=i[0];while(k--)g=g.lastChild;r.merge(m,g.childNodes),g=l.firstChild,g.textContent=""}else m.push(b.createTextNode(f));l.textContent="",n=0;while(f=m[n++])if(d&&r.inArray(f,d)>-1)e&&e.push(f);else if(j=r.contains(f.ownerDocument,f),g=na(l.appendChild(f),"script"),j&&oa(g),c){k=0;while(f=g[k++])la.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),o.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="<textarea>x</textarea>",o.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var ra=d.documentElement,sa=/^key/,ta=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,ua=/^([^.]*)(?:\.(.+)|)/;function va(){return!0}function wa(){return!1}function xa(){try{return d.activeElement}catch(a){}}function ya(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)ya(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=wa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return r().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=r.guid++)),a.each(function(){r.event.add(this,b,e,d,c)})}r.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.get(a);if(q){c.handler&&(f=c,c=f.handler,e=f.selector),e&&r.find.matchesSelector(ra,e),c.guid||(c.guid=r.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(L)||[""],j=b.length;while(j--)h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n&&(l=r.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=r.event.special[n]||{},k=r.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&r.expr.match.needsContext.test(e),namespace:o.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),r.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.hasData(a)&&W.get(a);if(q&&(i=q.events)){b=(b||"").match(L)||[""],j=b.length;while(j--)if(h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n){l=r.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&p!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,o,q.handle)!==!1||r.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)r.event.remove(a,n+b[j],c,d,!0);r.isEmptyObject(i)&&W.remove(a,"handle events")}},dispatch:function(a){var b=r.event.fix(a),c,d,e,f,g,h,i=new Array(arguments.length),j=(W.get(this,"events")||{})[b.type]||[],k=r.event.special[b.type]||{};for(i[0]=b,c=1;c<arguments.length;c++)i[c]=arguments[c];if(b.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,b)!==!1){h=r.event.handlers.call(this,b,j),c=0;while((f=h[c++])&&!b.isPropagationStopped()){b.currentTarget=f.elem,d=0;while((g=f.handlers[d++])&&!b.isImmediatePropagationStopped())b.rnamespace&&!b.rnamespace.test(g.namespace)||(b.handleObj=g,b.data=g.data,e=((r.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(b.result=e)===!1&&(b.preventDefault(),b.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,b),b.result}},handlers:function(a,b){var c,d,e,f,g,h=[],i=b.delegateCount,j=a.target;if(i&&j.nodeType&&!("click"===a.type&&a.button>=1))for(;j!==this;j=j.parentNode||this)if(1===j.nodeType&&("click"!==a.type||j.disabled!==!0)){for(f=[],g={},c=0;c<i;c++)d=b[c],e=d.selector+" ",void 0===g[e]&&(g[e]=d.needsContext?r(e,this).index(j)>-1:r.find(e,this,null,[j]).length),g[e]&&f.push(d);f.length&&h.push({elem:j,handlers:f})}return j=this,i<b.length&&h.push({elem:j,handlers:b.slice(i)}),h},addProp:function(a,b){Object.defineProperty(r.Event.prototype,a,{enumerable:!0,configurable:!0,get:r.isFunction(b)?function(){if(this.originalEvent)return b(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[a]},set:function(b){Object.defineProperty(this,a,{enumerable:!0,configurable:!0,writable:!0,value:b})}})},fix:function(a){return a[r.expando]?a:new r.Event(a)},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==xa()&&this.focus)return this.focus(),!1},delegateType:"focusin"},blur:{trigger:function(){if(this===xa()&&this.blur)return this.blur(),!1},delegateType:"focusout"},click:{trigger:function(){if("checkbox"===this.type&&this.click&&B(this,"input"))return this.click(),!1},_default:function(a){return B(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}}},r.removeEvent=function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c)},r.Event=function(a,b){return this instanceof r.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?va:wa,this.target=a.target&&3===a.target.nodeType?a.target.parentNode:a.target,this.currentTarget=a.currentTarget,this.relatedTarget=a.relatedTarget):this.type=a,b&&r.extend(this,b),this.timeStamp=a&&a.timeStamp||r.now(),void(this[r.expando]=!0)):new r.Event(a,b)},r.Event.prototype={constructor:r.Event,isDefaultPrevented:wa,isPropagationStopped:wa,isImmediatePropagationStopped:wa,isSimulated:!1,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=va,a&&!this.isSimulated&&a.preventDefault()},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=va,a&&!this.isSimulated&&a.stopPropagation()},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=va,a&&!this.isSimulated&&a.stopImmediatePropagation(),this.stopPropagation()}},r.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,"char":!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:function(a){var b=a.button;return null==a.which&&sa.test(a.type)?null!=a.charCode?a.charCode:a.keyCode:!a.which&&void 0!==b&&ta.test(a.type)?1&b?1:2&b?3:4&b?2:0:a.which}},r.event.addProp),r.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){r.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return e&&(e===d||r.contains(d,e))||(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),r.fn.extend({on:function(a,b,c,d){return ya(this,a,b,c,d)},one:function(a,b,c,d){return ya(this,a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,r(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return b!==!1&&"function"!=typeof b||(c=b,b=void 0),c===!1&&(c=wa),this.each(function(){r.event.remove(this,a,c,b)})}});var za=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,Aa=/<script|<style|<link/i,Ba=/checked\s*(?:[^=]|=\s*.checked.)/i,Ca=/^true\/(.*)/,Da=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function Ea(a,b){return B(a,"table")&&B(11!==b.nodeType?b:b.firstChild,"tr")?r(">tbody",a)[0]||a:a}function Fa(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function Ga(a){var b=Ca.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ha(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(W.hasData(a)&&(f=W.access(a),g=W.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;c<d;c++)r.event.add(b,e,j[e][c])}X.hasData(a)&&(h=X.access(a),i=r.extend({},h),X.set(b,i))}}function Ia(a,b){var c=b.nodeName.toLowerCase();"input"===c&&ja.test(a.type)?b.checked=a.checked:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}function Ja(a,b,c,d){b=g.apply([],b);var e,f,h,i,j,k,l=0,m=a.length,n=m-1,q=b[0],s=r.isFunction(q);if(s||m>1&&"string"==typeof q&&!o.checkClone&&Ba.test(q))return a.each(function(e){var f=a.eq(e);s&&(b[0]=q.call(this,e,f.html())),Ja(f,b,c,d)});if(m&&(e=qa(b,a[0].ownerDocument,!1,a,d),f=e.firstChild,1===e.childNodes.length&&(e=f),f||d)){for(h=r.map(na(e,"script"),Fa),i=h.length;l<m;l++)j=e,l!==n&&(j=r.clone(j,!0,!0),i&&r.merge(h,na(j,"script"))),c.call(a[l],j,l);if(i)for(k=h[h.length-1].ownerDocument,r.map(h,Ga),l=0;l<i;l++)j=h[l],la.test(j.type||"")&&!W.access(j,"globalEval")&&r.contains(k,j)&&(j.src?r._evalUrl&&r._evalUrl(j.src):p(j.textContent.replace(Da,""),k))}return a}function Ka(a,b,c){for(var d,e=b?r.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||r.cleanData(na(d)),d.parentNode&&(c&&r.contains(d.ownerDocument,d)&&oa(na(d,"script")),d.parentNode.removeChild(d));return a}r.extend({htmlPrefilter:function(a){return a.replace(za,"<$1></$2>")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=r.contains(a.ownerDocument,a);if(!(o.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||r.isXMLDoc(a)))for(g=na(h),f=na(a),d=0,e=f.length;d<e;d++)Ia(f[d],g[d]);if(b)if(c)for(f=f||na(a),g=g||na(h),d=0,e=f.length;d<e;d++)Ha(f[d],g[d]);else Ha(a,h);return g=na(h,"script"),g.length>0&&oa(g,!i&&na(a,"script")),h},cleanData:function(a){for(var b,c,d,e=r.event.special,f=0;void 0!==(c=a[f]);f++)if(U(c)){if(b=c[W.expando]){if(b.events)for(d in b.events)e[d]?r.event.remove(c,d):r.removeEvent(c,d,b.handle);c[W.expando]=void 0}c[X.expando]&&(c[X.expando]=void 0)}}}),r.fn.extend({detach:function(a){return Ka(this,a,!0)},remove:function(a){return Ka(this,a)},text:function(a){return T(this,function(a){return void 0===a?r.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return Ja(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ea(this,a);b.appendChild(a)}})},prepend:function(){return Ja(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ea(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ja(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ja(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(r.cleanData(na(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null!=a&&a,b=null==b?a:b,this.map(function(){return r.clone(this,a,b)})},html:function(a){return T(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!Aa.test(a)&&!ma[(ka.exec(a)||["",""])[1].toLowerCase()]){a=r.htmlPrefilter(a);try{for(;c<d;c++)b=this[c]||{},1===b.nodeType&&(r.cleanData(na(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ja(this,arguments,function(b){var c=this.parentNode;r.inArray(this,a)<0&&(r.cleanData(na(this)),c&&c.replaceChild(b,this))},a)}}),r.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){r.fn[a]=function(a){for(var c,d=[],e=r(a),f=e.length-1,g=0;g<=f;g++)c=g===f?this:this.clone(!0),r(e[g])[b](c),h.apply(d,c.get());return this.pushStack(d)}});var La=/^margin/,Ma=new RegExp("^("+aa+")(?!px)[a-z%]+$","i"),Na=function(b){var c=b.ownerDocument.defaultView;return c&&c.opener||(c=a),c.getComputedStyle(b)};!function(){function b(){if(i){i.style.cssText="box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%",i.innerHTML="",ra.appendChild(h);var b=a.getComputedStyle(i);c="1%"!==b.top,g="2px"===b.marginLeft,e="4px"===b.width,i.style.marginRight="50%",f="4px"===b.marginRight,ra.removeChild(h),i=null}}var c,e,f,g,h=d.createElement("div"),i=d.createElement("div");i.style&&(i.style.backgroundClip="content-box",i.cloneNode(!0).style.backgroundClip="",o.clearCloneStyle="content-box"===i.style.backgroundClip,h.style.cssText="border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute",h.appendChild(i),r.extend(o,{pixelPosition:function(){return b(),c},boxSizingReliable:function(){return b(),e},pixelMarginRight:function(){return b(),f},reliableMarginLeft:function(){return b(),g}}))}();function Oa(a,b,c){var d,e,f,g,h=a.style;return c=c||Na(a),c&&(g=c.getPropertyValue(b)||c[b],""!==g||r.contains(a.ownerDocument,a)||(g=r.style(a,b)),!o.pixelMarginRight()&&Ma.test(g)&&La.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0!==g?g+"":g}function Pa(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}var Qa=/^(none|table(?!-c[ea]).+)/,Ra=/^--/,Sa={position:"absolute",visibility:"hidden",display:"block"},Ta={letterSpacing:"0",fontWeight:"400"},Ua=["Webkit","Moz","ms"],Va=d.createElement("div").style;function Wa(a){if(a in Va)return a;var b=a[0].toUpperCase()+a.slice(1),c=Ua.length;while(c--)if(a=Ua[c]+b,a in Va)return a}function Xa(a){var b=r.cssProps[a];return b||(b=r.cssProps[a]=Wa(a)||a),b}function Ya(a,b,c){var d=ba.exec(b);return d?Math.max(0,d[2]-(c||0))+(d[3]||"px"):b}function Za(a,b,c,d,e){var f,g=0;for(f=c===(d?"border":"content")?4:"width"===b?1:0;f<4;f+=2)"margin"===c&&(g+=r.css(a,c+ca[f],!0,e)),d?("content"===c&&(g-=r.css(a,"padding"+ca[f],!0,e)),"margin"!==c&&(g-=r.css(a,"border"+ca[f]+"Width",!0,e))):(g+=r.css(a,"padding"+ca[f],!0,e),"padding"!==c&&(g+=r.css(a,"border"+ca[f]+"Width",!0,e)));return g}function $a(a,b,c){var d,e=Na(a),f=Oa(a,b,e),g="border-box"===r.css(a,"boxSizing",!1,e);return Ma.test(f)?f:(d=g&&(o.boxSizingReliable()||f===a.style[b]),"auto"===f&&(f=a["offset"+b[0].toUpperCase()+b.slice(1)]),f=parseFloat(f)||0,f+Za(a,b,c||(g?"border":"content"),d,e)+"px")}r.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Oa(a,"opacity");return""===c?"1":c}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=r.camelCase(b),i=Ra.test(b),j=a.style;return i||(b=Xa(h)),g=r.cssHooks[b]||r.cssHooks[h],void 0===c?g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:j[b]:(f=typeof c,"string"===f&&(e=ba.exec(c))&&e[1]&&(c=fa(a,b,e),f="number"),null!=c&&c===c&&("number"===f&&(c+=e&&e[3]||(r.cssNumber[h]?"":"px")),o.clearCloneStyle||""!==c||0!==b.indexOf("background")||(j[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i?j.setProperty(b,c):j[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=r.camelCase(b),i=Ra.test(b);return i||(b=Xa(h)),g=r.cssHooks[b]||r.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=Oa(a,b,d)),"normal"===e&&b in Ta&&(e=Ta[b]),""===c||c?(f=parseFloat(e),c===!0||isFinite(f)?f||0:e):e}}),r.each(["height","width"],function(a,b){r.cssHooks[b]={get:function(a,c,d){if(c)return!Qa.test(r.css(a,"display"))||a.getClientRects().length&&a.getBoundingClientRect().width?$a(a,b,d):ea(a,Sa,function(){return $a(a,b,d)})},set:function(a,c,d){var e,f=d&&Na(a),g=d&&Za(a,b,d,"border-box"===r.css(a,"boxSizing",!1,f),f);return g&&(e=ba.exec(c))&&"px"!==(e[3]||"px")&&(a.style[b]=c,c=r.css(a,b)),Ya(a,c,g)}}}),r.cssHooks.marginLeft=Pa(o.reliableMarginLeft,function(a,b){if(b)return(parseFloat(Oa(a,"marginLeft"))||a.getBoundingClientRect().left-ea(a,{marginLeft:0},function(){return a.getBoundingClientRect().left}))+"px"}),r.each({margin:"",padding:"",border:"Width"},function(a,b){r.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];d<4;d++)e[a+ca[d]+b]=f[d]||f[d-2]||f[0];return e}},La.test(a)||(r.cssHooks[a+b].set=Ya)}),r.fn.extend({css:function(a,b){return T(this,function(a,b,c){var d,e,f={},g=0;if(Array.isArray(b)){for(d=Na(a),e=b.length;g<e;g++)f[b[g]]=r.css(a,b[g],!1,d);return f}return void 0!==c?r.style(a,b,c):r.css(a,b)},a,b,arguments.length>1)}});function _a(a,b,c,d,e){return new _a.prototype.init(a,b,c,d,e)}r.Tween=_a,_a.prototype={constructor:_a,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||r.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(r.cssNumber[c]?"":"px")},cur:function(){var a=_a.propHooks[this.prop];return a&&a.get?a.get(this):_a.propHooks._default.get(this)},run:function(a){var b,c=_a.propHooks[this.prop];return this.options.duration?this.pos=b=r.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):_a.propHooks._default.set(this),this}},_a.prototype.init.prototype=_a.prototype,_a.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=r.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){r.fx.step[a.prop]?r.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[r.cssProps[a.prop]]&&!r.cssHooks[a.prop]?a.elem[a.prop]=a.now:r.style(a.elem,a.prop,a.now+a.unit)}}},_a.propHooks.scrollTop=_a.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},r.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},r.fx=_a.prototype.init,r.fx.step={};var ab,bb,cb=/^(?:toggle|show|hide)$/,db=/queueHooks$/;function eb(){bb&&(d.hidden===!1&&a.requestAnimationFrame?a.requestAnimationFrame(eb):a.setTimeout(eb,r.fx.interval),r.fx.tick())}function fb(){return a.setTimeout(function(){ab=void 0}),ab=r.now()}function gb(a,b){var c,d=0,e={height:a};for(b=b?1:0;d<4;d+=2-b)c=ca[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function hb(a,b,c){for(var d,e=(kb.tweeners[b]||[]).concat(kb.tweeners["*"]),f=0,g=e.length;f<g;f++)if(d=e[f].call(c,b,a))return d}function ib(a,b,c){var d,e,f,g,h,i,j,k,l="width"in b||"height"in b,m=this,n={},o=a.style,p=a.nodeType&&da(a),q=W.get(a,"fxshow");c.queue||(g=r._queueHooks(a,"fx"),null==g.unqueued&&(g.unqueued=0,h=g.empty.fire,g.empty.fire=function(){g.unqueued||h()}),g.unqueued++,m.always(function(){m.always(function(){g.unqueued--,r.queue(a,"fx").length||g.empty.fire()})}));for(d in b)if(e=b[d],cb.test(e)){if(delete b[d],f=f||"toggle"===e,e===(p?"hide":"show")){if("show"!==e||!q||void 0===q[d])continue;p=!0}n[d]=q&&q[d]||r.style(a,d)}if(i=!r.isEmptyObject(b),i||!r.isEmptyObject(n)){l&&1===a.nodeType&&(c.overflow=[o.overflow,o.overflowX,o.overflowY],j=q&&q.display,null==j&&(j=W.get(a,"display")),k=r.css(a,"display"),"none"===k&&(j?k=j:(ia([a],!0),j=a.style.display||j,k=r.css(a,"display"),ia([a]))),("inline"===k||"inline-block"===k&&null!=j)&&"none"===r.css(a,"float")&&(i||(m.done(function(){o.display=j}),null==j&&(k=o.display,j="none"===k?"":k)),o.display="inline-block")),c.overflow&&(o.overflow="hidden",m.always(function(){o.overflow=c.overflow[0],o.overflowX=c.overflow[1],o.overflowY=c.overflow[2]})),i=!1;for(d in n)i||(q?"hidden"in q&&(p=q.hidden):q=W.access(a,"fxshow",{display:j}),f&&(q.hidden=!p),p&&ia([a],!0),m.done(function(){p||ia([a]),W.remove(a,"fxshow");for(d in n)r.style(a,d,n[d])})),i=hb(p?q[d]:0,d,m),d in q||(q[d]=i.start,p&&(i.end=i.start,i.start=0))}}function jb(a,b){var c,d,e,f,g;for(c in a)if(d=r.camelCase(c),e=b[d],f=a[c],Array.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=r.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kb(a,b,c){var d,e,f=0,g=kb.prefilters.length,h=r.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=ab||fb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;g<i;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),f<1&&i?c:(i||h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:r.extend({},b),opts:r.extend(!0,{specialEasing:{},easing:r.easing._default},c),originalProperties:b,originalOptions:c,startTime:ab||fb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=r.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;c<d;c++)j.tweens[c].run(1);return b?(h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j,b])):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jb(k,j.opts.specialEasing);f<g;f++)if(d=kb.prefilters[f].call(j,a,k,j.opts))return r.isFunction(d.stop)&&(r._queueHooks(j.elem,j.opts.queue).stop=r.proxy(d.stop,d)),d;return r.map(k,hb,j),r.isFunction(j.opts.start)&&j.opts.start.call(a,j),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always),r.fx.timer(r.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j}r.Animation=r.extend(kb,{tweeners:{"*":[function(a,b){var c=this.createTween(a,b);return fa(c.elem,a,ba.exec(b),c),c}]},tweener:function(a,b){r.isFunction(a)?(b=a,a=["*"]):a=a.match(L);for(var c,d=0,e=a.length;d<e;d++)c=a[d],kb.tweeners[c]=kb.tweeners[c]||[],kb.tweeners[c].unshift(b)},prefilters:[ib],prefilter:function(a,b){b?kb.prefilters.unshift(a):kb.prefilters.push(a)}}),r.speed=function(a,b,c){var d=a&&"object"==typeof a?r.extend({},a):{complete:c||!c&&b||r.isFunction(a)&&a,duration:a,easing:c&&b||b&&!r.isFunction(b)&&b};return r.fx.off?d.duration=0:"number"!=typeof d.duration&&(d.duration in r.fx.speeds?d.duration=r.fx.speeds[d.duration]:d.duration=r.fx.speeds._default),null!=d.queue&&d.queue!==!0||(d.queue="fx"),d.old=d.complete,d.complete=function(){r.isFunction(d.old)&&d.old.call(this),d.queue&&r.dequeue(this,d.queue)},d},r.fn.extend({fadeTo:function(a,b,c,d){return this.filter(da).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=r.isEmptyObject(a),f=r.speed(b,c,d),g=function(){var b=kb(this,r.extend({},a),f);(e||W.get(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=r.timers,g=W.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&db.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));!b&&c||r.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=W.get(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=r.timers,g=d?d.length:0;for(c.finish=!0,r.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;b<g;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),r.each(["toggle","show","hide"],function(a,b){var c=r.fn[b];r.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(gb(b,!0),a,d,e)}}),r.each({slideDown:gb("show"),slideUp:gb("hide"),slideToggle:gb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){r.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),r.timers=[],r.fx.tick=function(){var a,b=0,c=r.timers;for(ab=r.now();b<c.length;b++)a=c[b],a()||c[b]!==a||c.splice(b--,1);c.length||r.fx.stop(),ab=void 0},r.fx.timer=function(a){r.timers.push(a),r.fx.start()},r.fx.interval=13,r.fx.start=function(){bb||(bb=!0,eb())},r.fx.stop=function(){bb=null},r.fx.speeds={slow:600,fast:200,_default:400},r.fn.delay=function(b,c){return b=r.fx?r.fx.speeds[b]||b:b,c=c||"fx",this.queue(c,function(c,d){var e=a.setTimeout(c,b);d.stop=function(){a.clearTimeout(e)}})},function(){var a=d.createElement("input"),b=d.createElement("select"),c=b.appendChild(d.createElement("option"));a.type="checkbox",o.checkOn=""!==a.value,o.optSelected=c.selected,a=d.createElement("input"),a.value="t",a.type="radio",o.radioValue="t"===a.value}();var lb,mb=r.expr.attrHandle;r.fn.extend({attr:function(a,b){return T(this,r.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){r.removeAttr(this,a)})}}),r.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?r.prop(a,b,c):(1===f&&r.isXMLDoc(a)||(e=r.attrHooks[b.toLowerCase()]||(r.expr.match.bool.test(b)?lb:void 0)),void 0!==c?null===c?void r.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=r.find.attr(a,b),
+null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!o.radioValue&&"radio"===b&&B(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d=0,e=b&&b.match(L);if(e&&1===a.nodeType)while(c=e[d++])a.removeAttribute(c)}}),lb={set:function(a,b,c){return b===!1?r.removeAttr(a,c):a.setAttribute(c,c),c}},r.each(r.expr.match.bool.source.match(/\w+/g),function(a,b){var c=mb[b]||r.find.attr;mb[b]=function(a,b,d){var e,f,g=b.toLowerCase();return d||(f=mb[g],mb[g]=e,e=null!=c(a,b,d)?g:null,mb[g]=f),e}});var nb=/^(?:input|select|textarea|button)$/i,ob=/^(?:a|area)$/i;r.fn.extend({prop:function(a,b){return T(this,r.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[r.propFix[a]||a]})}}),r.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&r.isXMLDoc(a)||(b=r.propFix[b]||b,e=r.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=r.find.attr(a,"tabindex");return b?parseInt(b,10):nb.test(a.nodeName)||ob.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),o.optSelected||(r.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),r.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){r.propFix[this.toLowerCase()]=this});function pb(a){var b=a.match(L)||[];return b.join(" ")}function qb(a){return a.getAttribute&&a.getAttribute("class")||""}r.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).addClass(a.call(this,b,qb(this)))});if("string"==typeof a&&a){b=a.match(L)||[];while(c=this[i++])if(e=qb(c),d=1===c.nodeType&&" "+pb(e)+" "){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=pb(d),e!==h&&c.setAttribute("class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).removeClass(a.call(this,b,qb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(L)||[];while(c=this[i++])if(e=qb(c),d=1===c.nodeType&&" "+pb(e)+" "){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=pb(d),e!==h&&c.setAttribute("class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):r.isFunction(a)?this.each(function(c){r(this).toggleClass(a.call(this,c,qb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=r(this),f=a.match(L)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=qb(this),b&&W.set(this,"__className__",b),this.setAttribute&&this.setAttribute("class",b||a===!1?"":W.get(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+pb(qb(c))+" ").indexOf(b)>-1)return!0;return!1}});var rb=/\r/g;r.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=r.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,r(this).val()):a,null==e?e="":"number"==typeof e?e+="":Array.isArray(e)&&(e=r.map(e,function(a){return null==a?"":a+""})),b=r.valHooks[this.type]||r.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=r.valHooks[e.type]||r.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(rb,""):null==c?"":c)}}}),r.extend({valHooks:{option:{get:function(a){var b=r.find.attr(a,"value");return null!=b?b:pb(r.text(a))}},select:{get:function(a){var b,c,d,e=a.options,f=a.selectedIndex,g="select-one"===a.type,h=g?null:[],i=g?f+1:e.length;for(d=f<0?i:g?f:0;d<i;d++)if(c=e[d],(c.selected||d===f)&&!c.disabled&&(!c.parentNode.disabled||!B(c.parentNode,"optgroup"))){if(b=r(c).val(),g)return b;h.push(b)}return h},set:function(a,b){var c,d,e=a.options,f=r.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=r.inArray(r.valHooks.option.get(d),f)>-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),r.each(["radio","checkbox"],function(){r.valHooks[this]={set:function(a,b){if(Array.isArray(b))return a.checked=r.inArray(r(a).val(),b)>-1}},o.checkOn||(r.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var sb=/^(?:focusinfocus|focusoutblur)$/;r.extend(r.event,{trigger:function(b,c,e,f){var g,h,i,j,k,m,n,o=[e||d],p=l.call(b,"type")?b.type:b,q=l.call(b,"namespace")?b.namespace.split("."):[];if(h=i=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!sb.test(p+r.event.triggered)&&(p.indexOf(".")>-1&&(q=p.split("."),p=q.shift(),q.sort()),k=p.indexOf(":")<0&&"on"+p,b=b[r.expando]?b:new r.Event(p,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=q.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:r.makeArray(c,[b]),n=r.event.special[p]||{},f||!n.trigger||n.trigger.apply(e,c)!==!1)){if(!f&&!n.noBubble&&!r.isWindow(e)){for(j=n.delegateType||p,sb.test(j+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),i=h;i===(e.ownerDocument||d)&&o.push(i.defaultView||i.parentWindow||a)}g=0;while((h=o[g++])&&!b.isPropagationStopped())b.type=g>1?j:n.bindType||p,m=(W.get(h,"events")||{})[b.type]&&W.get(h,"handle"),m&&m.apply(h,c),m=k&&h[k],m&&m.apply&&U(h)&&(b.result=m.apply(h,c),b.result===!1&&b.preventDefault());return b.type=p,f||b.isDefaultPrevented()||n._default&&n._default.apply(o.pop(),c)!==!1||!U(e)||k&&r.isFunction(e[p])&&!r.isWindow(e)&&(i=e[k],i&&(e[k]=null),r.event.triggered=p,e[p](),r.event.triggered=void 0,i&&(e[k]=i)),b.result}},simulate:function(a,b,c){var d=r.extend(new r.Event,c,{type:a,isSimulated:!0});r.event.trigger(d,null,b)}}),r.fn.extend({trigger:function(a,b){return this.each(function(){r.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];if(c)return r.event.trigger(a,b,c,!0)}}),r.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(a,b){r.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),r.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),o.focusin="onfocusin"in a,o.focusin||r.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){r.event.simulate(b,a.target,r.event.fix(a))};r.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=W.access(d,b);e||d.addEventListener(a,c,!0),W.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=W.access(d,b)-1;e?W.access(d,b,e):(d.removeEventListener(a,c,!0),W.remove(d,b))}}});var tb=a.location,ub=r.now(),vb=/\?/;r.parseXML=function(b){var c;if(!b||"string"!=typeof b)return null;try{c=(new a.DOMParser).parseFromString(b,"text/xml")}catch(d){c=void 0}return c&&!c.getElementsByTagName("parsererror").length||r.error("Invalid XML: "+b),c};var wb=/\[\]$/,xb=/\r?\n/g,yb=/^(?:submit|button|image|reset|file)$/i,zb=/^(?:input|select|textarea|keygen)/i;function Ab(a,b,c,d){var e;if(Array.isArray(b))r.each(b,function(b,e){c||wb.test(a)?d(a,e):Ab(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==r.type(b))d(a,b);else for(e in b)Ab(a+"["+e+"]",b[e],c,d)}r.param=function(a,b){var c,d=[],e=function(a,b){var c=r.isFunction(b)?b():b;d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(null==c?"":c)};if(Array.isArray(a)||a.jquery&&!r.isPlainObject(a))r.each(a,function(){e(this.name,this.value)});else for(c in a)Ab(c,a[c],b,e);return d.join("&")},r.fn.extend({serialize:function(){return r.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=r.prop(this,"elements");return a?r.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!r(this).is(":disabled")&&zb.test(this.nodeName)&&!yb.test(a)&&(this.checked||!ja.test(a))}).map(function(a,b){var c=r(this).val();return null==c?null:Array.isArray(c)?r.map(c,function(a){return{name:b.name,value:a.replace(xb,"\r\n")}}):{name:b.name,value:c.replace(xb,"\r\n")}}).get()}});var Bb=/%20/g,Cb=/#.*$/,Db=/([?&])_=[^&]*/,Eb=/^(.*?):[ \t]*([^\r\n]*)$/gm,Fb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Gb=/^(?:GET|HEAD)$/,Hb=/^\/\//,Ib={},Jb={},Kb="*/".concat("*"),Lb=d.createElement("a");Lb.href=tb.href;function Mb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(L)||[];if(r.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Nb(a,b,c,d){var e={},f=a===Jb;function g(h){var i;return e[h]=!0,r.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Ob(a,b){var c,d,e=r.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&r.extend(!0,a,d),a}function Pb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}if(f)return f!==i[0]&&i.unshift(f),c[f]}function Qb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}r.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:tb.href,type:"GET",isLocal:Fb.test(tb.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Kb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":r.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Ob(Ob(a,r.ajaxSettings),b):Ob(r.ajaxSettings,a)},ajaxPrefilter:Mb(Ib),ajaxTransport:Mb(Jb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var e,f,g,h,i,j,k,l,m,n,o=r.ajaxSetup({},c),p=o.context||o,q=o.context&&(p.nodeType||p.jquery)?r(p):r.event,s=r.Deferred(),t=r.Callbacks("once memory"),u=o.statusCode||{},v={},w={},x="canceled",y={readyState:0,getResponseHeader:function(a){var b;if(k){if(!h){h={};while(b=Eb.exec(g))h[b[1].toLowerCase()]=b[2]}b=h[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return k?g:null},setRequestHeader:function(a,b){return null==k&&(a=w[a.toLowerCase()]=w[a.toLowerCase()]||a,v[a]=b),this},overrideMimeType:function(a){return null==k&&(o.mimeType=a),this},statusCode:function(a){var b;if(a)if(k)y.always(a[y.status]);else for(b in a)u[b]=[u[b],a[b]];return this},abort:function(a){var b=a||x;return e&&e.abort(b),A(0,b),this}};if(s.promise(y),o.url=((b||o.url||tb.href)+"").replace(Hb,tb.protocol+"//"),o.type=c.method||c.type||o.method||o.type,o.dataTypes=(o.dataType||"*").toLowerCase().match(L)||[""],null==o.crossDomain){j=d.createElement("a");try{j.href=o.url,j.href=j.href,o.crossDomain=Lb.protocol+"//"+Lb.host!=j.protocol+"//"+j.host}catch(z){o.crossDomain=!0}}if(o.data&&o.processData&&"string"!=typeof o.data&&(o.data=r.param(o.data,o.traditional)),Nb(Ib,o,c,y),k)return y;l=r.event&&o.global,l&&0===r.active++&&r.event.trigger("ajaxStart"),o.type=o.type.toUpperCase(),o.hasContent=!Gb.test(o.type),f=o.url.replace(Cb,""),o.hasContent?o.data&&o.processData&&0===(o.contentType||"").indexOf("application/x-www-form-urlencoded")&&(o.data=o.data.replace(Bb,"+")):(n=o.url.slice(f.length),o.data&&(f+=(vb.test(f)?"&":"?")+o.data,delete o.data),o.cache===!1&&(f=f.replace(Db,"$1"),n=(vb.test(f)?"&":"?")+"_="+ub++ +n),o.url=f+n),o.ifModified&&(r.lastModified[f]&&y.setRequestHeader("If-Modified-Since",r.lastModified[f]),r.etag[f]&&y.setRequestHeader("If-None-Match",r.etag[f])),(o.data&&o.hasContent&&o.contentType!==!1||c.contentType)&&y.setRequestHeader("Content-Type",o.contentType),y.setRequestHeader("Accept",o.dataTypes[0]&&o.accepts[o.dataTypes[0]]?o.accepts[o.dataTypes[0]]+("*"!==o.dataTypes[0]?", "+Kb+"; q=0.01":""):o.accepts["*"]);for(m in o.headers)y.setRequestHeader(m,o.headers[m]);if(o.beforeSend&&(o.beforeSend.call(p,y,o)===!1||k))return y.abort();if(x="abort",t.add(o.complete),y.done(o.success),y.fail(o.error),e=Nb(Jb,o,c,y)){if(y.readyState=1,l&&q.trigger("ajaxSend",[y,o]),k)return y;o.async&&o.timeout>0&&(i=a.setTimeout(function(){y.abort("timeout")},o.timeout));try{k=!1,e.send(v,A)}catch(z){if(k)throw z;A(-1,z)}}else A(-1,"No Transport");function A(b,c,d,h){var j,m,n,v,w,x=c;k||(k=!0,i&&a.clearTimeout(i),e=void 0,g=h||"",y.readyState=b>0?4:0,j=b>=200&&b<300||304===b,d&&(v=Pb(o,y,d)),v=Qb(o,v,y,j),j?(o.ifModified&&(w=y.getResponseHeader("Last-Modified"),w&&(r.lastModified[f]=w),w=y.getResponseHeader("etag"),w&&(r.etag[f]=w)),204===b||"HEAD"===o.type?x="nocontent":304===b?x="notmodified":(x=v.state,m=v.data,n=v.error,j=!n)):(n=x,!b&&x||(x="error",b<0&&(b=0))),y.status=b,y.statusText=(c||x)+"",j?s.resolveWith(p,[m,x,y]):s.rejectWith(p,[y,x,n]),y.statusCode(u),u=void 0,l&&q.trigger(j?"ajaxSuccess":"ajaxError",[y,o,j?m:n]),t.fireWith(p,[y,x]),l&&(q.trigger("ajaxComplete",[y,o]),--r.active||r.event.trigger("ajaxStop")))}return y},getJSON:function(a,b,c){return r.get(a,b,c,"json")},getScript:function(a,b){return r.get(a,void 0,b,"script")}}),r.each(["get","post"],function(a,b){r[b]=function(a,c,d,e){return r.isFunction(c)&&(e=e||d,d=c,c=void 0),r.ajax(r.extend({url:a,type:b,dataType:e,data:c,success:d},r.isPlainObject(a)&&a))}}),r._evalUrl=function(a){return r.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},r.fn.extend({wrapAll:function(a){var b;return this[0]&&(r.isFunction(a)&&(a=a.call(this[0])),b=r(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this},wrapInner:function(a){return r.isFunction(a)?this.each(function(b){r(this).wrapInner(a.call(this,b))}):this.each(function(){var b=r(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=r.isFunction(a);return this.each(function(c){r(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(a){return this.parent(a).not("body").each(function(){r(this).replaceWith(this.childNodes)}),this}}),r.expr.pseudos.hidden=function(a){return!r.expr.pseudos.visible(a)},r.expr.pseudos.visible=function(a){return!!(a.offsetWidth||a.offsetHeight||a.getClientRects().length)},r.ajaxSettings.xhr=function(){try{return new a.XMLHttpRequest}catch(b){}};var Rb={0:200,1223:204},Sb=r.ajaxSettings.xhr();o.cors=!!Sb&&"withCredentials"in Sb,o.ajax=Sb=!!Sb,r.ajaxTransport(function(b){var c,d;if(o.cors||Sb&&!b.crossDomain)return{send:function(e,f){var g,h=b.xhr();if(h.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(g in b.xhrFields)h[g]=b.xhrFields[g];b.mimeType&&h.overrideMimeType&&h.overrideMimeType(b.mimeType),b.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest");for(g in e)h.setRequestHeader(g,e[g]);c=function(a){return function(){c&&(c=d=h.onload=h.onerror=h.onabort=h.onreadystatechange=null,"abort"===a?h.abort():"error"===a?"number"!=typeof h.status?f(0,"error"):f(h.status,h.statusText):f(Rb[h.status]||h.status,h.statusText,"text"!==(h.responseType||"text")||"string"!=typeof h.responseText?{binary:h.response}:{text:h.responseText},h.getAllResponseHeaders()))}},h.onload=c(),d=h.onerror=c("error"),void 0!==h.onabort?h.onabort=d:h.onreadystatechange=function(){4===h.readyState&&a.setTimeout(function(){c&&d()})},c=c("abort");try{h.send(b.hasContent&&b.data||null)}catch(i){if(c)throw i}},abort:function(){c&&c()}}}),r.ajaxPrefilter(function(a){a.crossDomain&&(a.contents.script=!1)}),r.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return r.globalEval(a),a}}}),r.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),r.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(e,f){b=r("<script>").prop({charset:a.scriptCharset,src:a.url}).on("load error",c=function(a){b.remove(),c=null,a&&f("error"===a.type?404:200,a.type)}),d.head.appendChild(b[0])},abort:function(){c&&c()}}}});var Tb=[],Ub=/(=)\?(?=&|$)|\?\?/;r.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=Tb.pop()||r.expando+"_"+ub++;return this[a]=!0,a}}),r.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(Ub.test(b.url)?"url":"string"==typeof b.data&&0===(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ub.test(b.data)&&"data");if(h||"jsonp"===b.dataTypes[0])return e=b.jsonpCallback=r.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(Ub,"$1"+e):b.jsonp!==!1&&(b.url+=(vb.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||r.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){void 0===f?r(a).removeProp(e):a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,Tb.push(e)),g&&r.isFunction(f)&&f(g[0]),g=f=void 0}),"script"}),o.createHTMLDocument=function(){var a=d.implementation.createHTMLDocument("").body;return a.innerHTML="<form></form><form></form>",2===a.childNodes.length}(),r.parseHTML=function(a,b,c){if("string"!=typeof a)return[];"boolean"==typeof b&&(c=b,b=!1);var e,f,g;return b||(o.createHTMLDocument?(b=d.implementation.createHTMLDocument(""),e=b.createElement("base"),e.href=d.location.href,b.head.appendChild(e)):b=d),f=C.exec(a),g=!c&&[],f?[b.createElement(f[1])]:(f=qa([a],b,g),g&&g.length&&r(g).remove(),r.merge([],f.childNodes))},r.fn.load=function(a,b,c){var d,e,f,g=this,h=a.indexOf(" ");return h>-1&&(d=pb(a.slice(h)),a=a.slice(0,h)),r.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&r.ajax({url:a,type:e||"GET",dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?r("<div>").append(r.parseHTML(a)).find(d):a)}).always(c&&function(a,b){g.each(function(){c.apply(this,f||[a.responseText,b,a])})}),this},r.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){r.fn[b]=function(a){return this.on(b,a)}}),r.expr.pseudos.animated=function(a){return r.grep(r.timers,function(b){return a===b.elem}).length},r.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=r.css(a,"position"),l=r(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=r.css(a,"top"),i=r.css(a,"left"),j=("absolute"===k||"fixed"===k)&&(f+i).indexOf("auto")>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),r.isFunction(b)&&(b=b.call(a,c,r.extend({},h))),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},r.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){r.offset.setOffset(this,a,b)});var b,c,d,e,f=this[0];if(f)return f.getClientRects().length?(d=f.getBoundingClientRect(),b=f.ownerDocument,c=b.documentElement,e=b.defaultView,{top:d.top+e.pageYOffset-c.clientTop,left:d.left+e.pageXOffset-c.clientLeft}):{top:0,left:0}},position:function(){if(this[0]){var a,b,c=this[0],d={top:0,left:0};return"fixed"===r.css(c,"position")?b=c.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),B(a[0],"html")||(d=a.offset()),d={top:d.top+r.css(a[0],"borderTopWidth",!0),left:d.left+r.css(a[0],"borderLeftWidth",!0)}),{top:b.top-d.top-r.css(c,"marginTop",!0),left:b.left-d.left-r.css(c,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent;while(a&&"static"===r.css(a,"position"))a=a.offsetParent;return a||ra})}}),r.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c="pageYOffset"===b;r.fn[a]=function(d){return T(this,function(a,d,e){var f;return r.isWindow(a)?f=a:9===a.nodeType&&(f=a.defaultView),void 0===e?f?f[b]:a[d]:void(f?f.scrollTo(c?f.pageXOffset:e,c?e:f.pageYOffset):a[d]=e)},a,d,arguments.length)}}),r.each(["top","left"],function(a,b){r.cssHooks[b]=Pa(o.pixelPosition,function(a,c){if(c)return c=Oa(a,b),Ma.test(c)?r(a).position()[b]+"px":c})}),r.each({Height:"height",Width:"width"},function(a,b){r.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){r.fn[d]=function(e,f){var g=arguments.length&&(c||"boolean"!=typeof e),h=c||(e===!0||f===!0?"margin":"border");return T(this,function(b,c,e){var f;return r.isWindow(b)?0===d.indexOf("outer")?b["inner"+a]:b.document.documentElement["client"+a]:9===b.nodeType?(f=b.documentElement,Math.max(b.body["scroll"+a],f["scroll"+a],b.body["offset"+a],f["offset"+a],f["client"+a])):void 0===e?r.css(b,c,h):r.style(b,c,e,h)},b,g?e:void 0,g)}})}),r.fn.extend({bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}}),r.holdReady=function(a){a?r.readyWait++:r.ready(!0)},r.isArray=Array.isArray,r.parseJSON=JSON.parse,r.nodeName=B,"function"==typeof define&&define.amd&&define("jquery",[],function(){return r});var Vb=a.jQuery,Wb=a.$;return r.noConflict=function(b){return a.$===r&&(a.$=Wb),b&&a.jQuery===r&&(a.jQuery=Vb),r},b||(a.jQuery=a.$=r),r});
diff --git a/doc/html/_static/language_data.js b/doc/html/_static/language_data.js
new file mode 100644
index 0000000..5266fb1
--- /dev/null
+++ b/doc/html/_static/language_data.js
@@ -0,0 +1,297 @@
+/*
+ * language_data.js
+ * ~~~~~~~~~~~~~~~~
+ *
+ * This script contains the language-specific data used by searchtools.js,
+ * namely the list of stopwords, stemmer, scorer and splitter.
+ *
+ * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+var stopwords = ["a","and","are","as","at","be","but","by","for","if","in","into","is","it","near","no","not","of","on","or","such","that","the","their","then","there","these","they","this","to","was","will","with"];
+
+
+/* Non-minified version JS is _stemmer.js if file is provided */
+/**
+ * Porter Stemmer
+ */
+var Stemmer = function() {
+
+ var step2list = {
+ ational: 'ate',
+ tional: 'tion',
+ enci: 'ence',
+ anci: 'ance',
+ izer: 'ize',
+ bli: 'ble',
+ alli: 'al',
+ entli: 'ent',
+ eli: 'e',
+ ousli: 'ous',
+ ization: 'ize',
+ ation: 'ate',
+ ator: 'ate',
+ alism: 'al',
+ iveness: 'ive',
+ fulness: 'ful',
+ ousness: 'ous',
+ aliti: 'al',
+ iviti: 'ive',
+ biliti: 'ble',
+ logi: 'log'
+ };
+
+ var step3list = {
+ icate: 'ic',
+ ative: '',
+ alize: 'al',
+ iciti: 'ic',
+ ical: 'ic',
+ ful: '',
+ ness: ''
+ };
+
+ var c = "[^aeiou]"; // consonant
+ var v = "[aeiouy]"; // vowel
+ var C = c + "[^aeiouy]*"; // consonant sequence
+ var V = v + "[aeiou]*"; // vowel sequence
+
+ var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0
+ var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1
+ var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1
+ var s_v = "^(" + C + ")?" + v; // vowel in stem
+
+ this.stemWord = function (w) {
+ var stem;
+ var suffix;
+ var firstch;
+ var origword = w;
+
+ if (w.length < 3)
+ return w;
+
+ var re;
+ var re2;
+ var re3;
+ var re4;
+
+ firstch = w.substr(0,1);
+ if (firstch == "y")
+ w = firstch.toUpperCase() + w.substr(1);
+
+ // Step 1a
+ re = /^(.+?)(ss|i)es$/;
+ re2 = /^(.+?)([^s])s$/;
+
+ if (re.test(w))
+ w = w.replace(re,"$1$2");
+ else if (re2.test(w))
+ w = w.replace(re2,"$1$2");
+
+ // Step 1b
+ re = /^(.+?)eed$/;
+ re2 = /^(.+?)(ed|ing)$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ re = new RegExp(mgr0);
+ if (re.test(fp[1])) {
+ re = /.$/;
+ w = w.replace(re,"");
+ }
+ }
+ else if (re2.test(w)) {
+ var fp = re2.exec(w);
+ stem = fp[1];
+ re2 = new RegExp(s_v);
+ if (re2.test(stem)) {
+ w = stem;
+ re2 = /(at|bl|iz)$/;
+ re3 = new RegExp("([^aeiouylsz])\\1$");
+ re4 = new RegExp("^" + C + v + "[^aeiouwxy]$");
+ if (re2.test(w))
+ w = w + "e";
+ else if (re3.test(w)) {
+ re = /.$/;
+ w = w.replace(re,"");
+ }
+ else if (re4.test(w))
+ w = w + "e";
+ }
+ }
+
+ // Step 1c
+ re = /^(.+?)y$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ re = new RegExp(s_v);
+ if (re.test(stem))
+ w = stem + "i";
+ }
+
+ // Step 2
+ re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ suffix = fp[2];
+ re = new RegExp(mgr0);
+ if (re.test(stem))
+ w = stem + step2list[suffix];
+ }
+
+ // Step 3
+ re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ suffix = fp[2];
+ re = new RegExp(mgr0);
+ if (re.test(stem))
+ w = stem + step3list[suffix];
+ }
+
+ // Step 4
+ re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;
+ re2 = /^(.+?)(s|t)(ion)$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ re = new RegExp(mgr1);
+ if (re.test(stem))
+ w = stem;
+ }
+ else if (re2.test(w)) {
+ var fp = re2.exec(w);
+ stem = fp[1] + fp[2];
+ re2 = new RegExp(mgr1);
+ if (re2.test(stem))
+ w = stem;
+ }
+
+ // Step 5
+ re = /^(.+?)e$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ re = new RegExp(mgr1);
+ re2 = new RegExp(meq1);
+ re3 = new RegExp("^" + C + v + "[^aeiouwxy]$");
+ if (re.test(stem) || (re2.test(stem) && !(re3.test(stem))))
+ w = stem;
+ }
+ re = /ll$/;
+ re2 = new RegExp(mgr1);
+ if (re.test(w) && re2.test(w)) {
+ re = /.$/;
+ w = w.replace(re,"");
+ }
+
+ // and turn initial Y back to y
+ if (firstch == "y")
+ w = firstch.toLowerCase() + w.substr(1);
+ return w;
+ }
+}
+
+
+
+
+
+var splitChars = (function() {
+ var result = {};
+ var singles = [96, 180, 187, 191, 215, 247, 749, 885, 903, 907, 909, 930, 1014, 1648,
+ 1748, 1809, 2416, 2473, 2481, 2526, 2601, 2609, 2612, 2615, 2653, 2702,
+ 2706, 2729, 2737, 2740, 2857, 2865, 2868, 2910, 2928, 2948, 2961, 2971,
+ 2973, 3085, 3089, 3113, 3124, 3213, 3217, 3241, 3252, 3295, 3341, 3345,
+ 3369, 3506, 3516, 3633, 3715, 3721, 3736, 3744, 3748, 3750, 3756, 3761,
+ 3781, 3912, 4239, 4347, 4681, 4695, 4697, 4745, 4785, 4799, 4801, 4823,
+ 4881, 5760, 5901, 5997, 6313, 7405, 8024, 8026, 8028, 8030, 8117, 8125,
+ 8133, 8181, 8468, 8485, 8487, 8489, 8494, 8527, 11311, 11359, 11687, 11695,
+ 11703, 11711, 11719, 11727, 11735, 12448, 12539, 43010, 43014, 43019, 43587,
+ 43696, 43713, 64286, 64297, 64311, 64317, 64319, 64322, 64325, 65141];
+ var i, j, start, end;
+ for (i = 0; i < singles.length; i++) {
+ result[singles[i]] = true;
+ }
+ var ranges = [[0, 47], [58, 64], [91, 94], [123, 169], [171, 177], [182, 184], [706, 709],
+ [722, 735], [741, 747], [751, 879], [888, 889], [894, 901], [1154, 1161],
+ [1318, 1328], [1367, 1368], [1370, 1376], [1416, 1487], [1515, 1519], [1523, 1568],
+ [1611, 1631], [1642, 1645], [1750, 1764], [1767, 1773], [1789, 1790], [1792, 1807],
+ [1840, 1868], [1958, 1968], [1970, 1983], [2027, 2035], [2038, 2041], [2043, 2047],
+ [2070, 2073], [2075, 2083], [2085, 2087], [2089, 2307], [2362, 2364], [2366, 2383],
+ [2385, 2391], [2402, 2405], [2419, 2424], [2432, 2436], [2445, 2446], [2449, 2450],
+ [2483, 2485], [2490, 2492], [2494, 2509], [2511, 2523], [2530, 2533], [2546, 2547],
+ [2554, 2564], [2571, 2574], [2577, 2578], [2618, 2648], [2655, 2661], [2672, 2673],
+ [2677, 2692], [2746, 2748], [2750, 2767], [2769, 2783], [2786, 2789], [2800, 2820],
+ [2829, 2830], [2833, 2834], [2874, 2876], [2878, 2907], [2914, 2917], [2930, 2946],
+ [2955, 2957], [2966, 2968], [2976, 2978], [2981, 2983], [2987, 2989], [3002, 3023],
+ [3025, 3045], [3059, 3076], [3130, 3132], [3134, 3159], [3162, 3167], [3170, 3173],
+ [3184, 3191], [3199, 3204], [3258, 3260], [3262, 3293], [3298, 3301], [3312, 3332],
+ [3386, 3388], [3390, 3423], [3426, 3429], [3446, 3449], [3456, 3460], [3479, 3481],
+ [3518, 3519], [3527, 3584], [3636, 3647], [3655, 3663], [3674, 3712], [3717, 3718],
+ [3723, 3724], [3726, 3731], [3752, 3753], [3764, 3772], [3774, 3775], [3783, 3791],
+ [3802, 3803], [3806, 3839], [3841, 3871], [3892, 3903], [3949, 3975], [3980, 4095],
+ [4139, 4158], [4170, 4175], [4182, 4185], [4190, 4192], [4194, 4196], [4199, 4205],
+ [4209, 4212], [4226, 4237], [4250, 4255], [4294, 4303], [4349, 4351], [4686, 4687],
+ [4702, 4703], [4750, 4751], [4790, 4791], [4806, 4807], [4886, 4887], [4955, 4968],
+ [4989, 4991], [5008, 5023], [5109, 5120], [5741, 5742], [5787, 5791], [5867, 5869],
+ [5873, 5887], [5906, 5919], [5938, 5951], [5970, 5983], [6001, 6015], [6068, 6102],
+ [6104, 6107], [6109, 6111], [6122, 6127], [6138, 6159], [6170, 6175], [6264, 6271],
+ [6315, 6319], [6390, 6399], [6429, 6469], [6510, 6511], [6517, 6527], [6572, 6592],
+ [6600, 6607], [6619, 6655], [6679, 6687], [6741, 6783], [6794, 6799], [6810, 6822],
+ [6824, 6916], [6964, 6980], [6988, 6991], [7002, 7042], [7073, 7085], [7098, 7167],
+ [7204, 7231], [7242, 7244], [7294, 7400], [7410, 7423], [7616, 7679], [7958, 7959],
+ [7966, 7967], [8006, 8007], [8014, 8015], [8062, 8063], [8127, 8129], [8141, 8143],
+ [8148, 8149], [8156, 8159], [8173, 8177], [8189, 8303], [8306, 8307], [8314, 8318],
+ [8330, 8335], [8341, 8449], [8451, 8454], [8456, 8457], [8470, 8472], [8478, 8483],
+ [8506, 8507], [8512, 8516], [8522, 8525], [8586, 9311], [9372, 9449], [9472, 10101],
+ [10132, 11263], [11493, 11498], [11503, 11516], [11518, 11519], [11558, 11567],
+ [11622, 11630], [11632, 11647], [11671, 11679], [11743, 11822], [11824, 12292],
+ [12296, 12320], [12330, 12336], [12342, 12343], [12349, 12352], [12439, 12444],
+ [12544, 12548], [12590, 12592], [12687, 12689], [12694, 12703], [12728, 12783],
+ [12800, 12831], [12842, 12880], [12896, 12927], [12938, 12976], [12992, 13311],
+ [19894, 19967], [40908, 40959], [42125, 42191], [42238, 42239], [42509, 42511],
+ [42540, 42559], [42592, 42593], [42607, 42622], [42648, 42655], [42736, 42774],
+ [42784, 42785], [42889, 42890], [42893, 43002], [43043, 43055], [43062, 43071],
+ [43124, 43137], [43188, 43215], [43226, 43249], [43256, 43258], [43260, 43263],
+ [43302, 43311], [43335, 43359], [43389, 43395], [43443, 43470], [43482, 43519],
+ [43561, 43583], [43596, 43599], [43610, 43615], [43639, 43641], [43643, 43647],
+ [43698, 43700], [43703, 43704], [43710, 43711], [43715, 43738], [43742, 43967],
+ [44003, 44015], [44026, 44031], [55204, 55215], [55239, 55242], [55292, 55295],
+ [57344, 63743], [64046, 64047], [64110, 64111], [64218, 64255], [64263, 64274],
+ [64280, 64284], [64434, 64466], [64830, 64847], [64912, 64913], [64968, 65007],
+ [65020, 65135], [65277, 65295], [65306, 65312], [65339, 65344], [65371, 65381],
+ [65471, 65473], [65480, 65481], [65488, 65489], [65496, 65497]];
+ for (i = 0; i < ranges.length; i++) {
+ start = ranges[i][0];
+ end = ranges[i][1];
+ for (j = start; j <= end; j++) {
+ result[j] = true;
+ }
+ }
+ return result;
+})();
+
+function splitQuery(query) {
+ var result = [];
+ var start = -1;
+ for (var i = 0; i < query.length; i++) {
+ if (splitChars[query.charCodeAt(i)]) {
+ if (start !== -1) {
+ result.push(query.slice(start, i));
+ start = -1;
+ }
+ } else if (start === -1) {
+ start = i;
+ }
+ }
+ if (start !== -1) {
+ result.push(query.slice(start));
+ }
+ return result;
+}
+
+
diff --git a/doc/html/_static/minus.png b/doc/html/_static/minus.png
new file mode 100644
index 0000000..d96755f
--- /dev/null
+++ b/doc/html/_static/minus.png
Binary files differ
diff --git a/doc/html/_static/plus.png b/doc/html/_static/plus.png
new file mode 100644
index 0000000..7107cec
--- /dev/null
+++ b/doc/html/_static/plus.png
Binary files differ
diff --git a/doc/html/_static/pygments.css b/doc/html/_static/pygments.css
new file mode 100644
index 0000000..20c4814
--- /dev/null
+++ b/doc/html/_static/pygments.css
@@ -0,0 +1,69 @@
+.highlight .hll { background-color: #ffffcc }
+.highlight { background: #eeffcc; }
+.highlight .c { color: #408090; font-style: italic } /* Comment */
+.highlight .err { border: 1px solid #FF0000 } /* Error */
+.highlight .k { color: #007020; font-weight: bold } /* Keyword */
+.highlight .o { color: #666666 } /* Operator */
+.highlight .ch { color: #408090; font-style: italic } /* Comment.Hashbang */
+.highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */
+.highlight .cp { color: #007020 } /* Comment.Preproc */
+.highlight .cpf { color: #408090; font-style: italic } /* Comment.PreprocFile */
+.highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */
+.highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */
+.highlight .gd { color: #A00000 } /* Generic.Deleted */
+.highlight .ge { font-style: italic } /* Generic.Emph */
+.highlight .gr { color: #FF0000 } /* Generic.Error */
+.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.highlight .gi { color: #00A000 } /* Generic.Inserted */
+.highlight .go { color: #333333 } /* Generic.Output */
+.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
+.highlight .gs { font-weight: bold } /* Generic.Strong */
+.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.highlight .gt { color: #0044DD } /* Generic.Traceback */
+.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */
+.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */
+.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */
+.highlight .kp { color: #007020 } /* Keyword.Pseudo */
+.highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */
+.highlight .kt { color: #902000 } /* Keyword.Type */
+.highlight .m { color: #208050 } /* Literal.Number */
+.highlight .s { color: #4070a0 } /* Literal.String */
+.highlight .na { color: #4070a0 } /* Name.Attribute */
+.highlight .nb { color: #007020 } /* Name.Builtin */
+.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */
+.highlight .no { color: #60add5 } /* Name.Constant */
+.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */
+.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */
+.highlight .ne { color: #007020 } /* Name.Exception */
+.highlight .nf { color: #06287e } /* Name.Function */
+.highlight .nl { color: #002070; font-weight: bold } /* Name.Label */
+.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
+.highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */
+.highlight .nv { color: #bb60d5 } /* Name.Variable */
+.highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */
+.highlight .w { color: #bbbbbb } /* Text.Whitespace */
+.highlight .mb { color: #208050 } /* Literal.Number.Bin */
+.highlight .mf { color: #208050 } /* Literal.Number.Float */
+.highlight .mh { color: #208050 } /* Literal.Number.Hex */
+.highlight .mi { color: #208050 } /* Literal.Number.Integer */
+.highlight .mo { color: #208050 } /* Literal.Number.Oct */
+.highlight .sa { color: #4070a0 } /* Literal.String.Affix */
+.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */
+.highlight .sc { color: #4070a0 } /* Literal.String.Char */
+.highlight .dl { color: #4070a0 } /* Literal.String.Delimiter */
+.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */
+.highlight .s2 { color: #4070a0 } /* Literal.String.Double */
+.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */
+.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */
+.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */
+.highlight .sx { color: #c65d09 } /* Literal.String.Other */
+.highlight .sr { color: #235388 } /* Literal.String.Regex */
+.highlight .s1 { color: #4070a0 } /* Literal.String.Single */
+.highlight .ss { color: #517918 } /* Literal.String.Symbol */
+.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */
+.highlight .fm { color: #06287e } /* Name.Function.Magic */
+.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */
+.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */
+.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */
+.highlight .vm { color: #bb60d5 } /* Name.Variable.Magic */
+.highlight .il { color: #208050 } /* Literal.Number.Integer.Long */ \ No newline at end of file
diff --git a/doc/html/_static/searchtools.js b/doc/html/_static/searchtools.js
new file mode 100644
index 0000000..5ff3180
--- /dev/null
+++ b/doc/html/_static/searchtools.js
@@ -0,0 +1,481 @@
+/*
+ * searchtools.js
+ * ~~~~~~~~~~~~~~~~
+ *
+ * Sphinx JavaScript utilities for the full-text search.
+ *
+ * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+if (!Scorer) {
+ /**
+ * Simple result scoring code.
+ */
+ var Scorer = {
+ // Implement the following function to further tweak the score for each result
+ // The function takes a result array [filename, title, anchor, descr, score]
+ // and returns the new score.
+ /*
+ score: function(result) {
+ return result[4];
+ },
+ */
+
+ // query matches the full name of an object
+ objNameMatch: 11,
+ // or matches in the last dotted part of the object name
+ objPartialMatch: 6,
+ // Additive scores depending on the priority of the object
+ objPrio: {0: 15, // used to be importantResults
+ 1: 5, // used to be objectResults
+ 2: -5}, // used to be unimportantResults
+ // Used when the priority is not in the mapping.
+ objPrioDefault: 0,
+
+ // query found in title
+ title: 15,
+ // query found in terms
+ term: 5
+ };
+}
+
+if (!splitQuery) {
+ function splitQuery(query) {
+ return query.split(/\s+/);
+ }
+}
+
+/**
+ * Search Module
+ */
+var Search = {
+
+ _index : null,
+ _queued_query : null,
+ _pulse_status : -1,
+
+ init : function() {
+ var params = $.getQueryParameters();
+ if (params.q) {
+ var query = params.q[0];
+ $('input[name="q"]')[0].value = query;
+ this.performSearch(query);
+ }
+ },
+
+ loadIndex : function(url) {
+ $.ajax({type: "GET", url: url, data: null,
+ dataType: "script", cache: true,
+ complete: function(jqxhr, textstatus) {
+ if (textstatus != "success") {
+ document.getElementById("searchindexloader").src = url;
+ }
+ }});
+ },
+
+ setIndex : function(index) {
+ var q;
+ this._index = index;
+ if ((q = this._queued_query) !== null) {
+ this._queued_query = null;
+ Search.query(q);
+ }
+ },
+
+ hasIndex : function() {
+ return this._index !== null;
+ },
+
+ deferQuery : function(query) {
+ this._queued_query = query;
+ },
+
+ stopPulse : function() {
+ this._pulse_status = 0;
+ },
+
+ startPulse : function() {
+ if (this._pulse_status >= 0)
+ return;
+ function pulse() {
+ var i;
+ Search._pulse_status = (Search._pulse_status + 1) % 4;
+ var dotString = '';
+ for (i = 0; i < Search._pulse_status; i++)
+ dotString += '.';
+ Search.dots.text(dotString);
+ if (Search._pulse_status > -1)
+ window.setTimeout(pulse, 500);
+ }
+ pulse();
+ },
+
+ /**
+ * perform a search for something (or wait until index is loaded)
+ */
+ performSearch : function(query) {
+ // create the required interface elements
+ this.out = $('#search-results');
+ this.title = $('<h2>' + _('Searching') + '</h2>').appendTo(this.out);
+ this.dots = $('<span></span>').appendTo(this.title);
+ this.status = $('<p style="display: none"></p>').appendTo(this.out);
+ this.output = $('<ul class="search"/>').appendTo(this.out);
+
+ $('#search-progress').text(_('Preparing search...'));
+ this.startPulse();
+
+ // index already loaded, the browser was quick!
+ if (this.hasIndex())
+ this.query(query);
+ else
+ this.deferQuery(query);
+ },
+
+ /**
+ * execute search (requires search index to be loaded)
+ */
+ query : function(query) {
+ var i;
+
+ // stem the searchterms and add them to the correct list
+ var stemmer = new Stemmer();
+ var searchterms = [];
+ var excluded = [];
+ var hlterms = [];
+ var tmp = splitQuery(query);
+ var objectterms = [];
+ for (i = 0; i < tmp.length; i++) {
+ if (tmp[i] !== "") {
+ objectterms.push(tmp[i].toLowerCase());
+ }
+
+ if ($u.indexOf(stopwords, tmp[i].toLowerCase()) != -1 || tmp[i].match(/^\d+$/) ||
+ tmp[i] === "") {
+ // skip this "word"
+ continue;
+ }
+ // stem the word
+ var word = stemmer.stemWord(tmp[i].toLowerCase());
+ // prevent stemmer from cutting word smaller than two chars
+ if(word.length < 3 && tmp[i].length >= 3) {
+ word = tmp[i];
+ }
+ var toAppend;
+ // select the correct list
+ if (word[0] == '-') {
+ toAppend = excluded;
+ word = word.substr(1);
+ }
+ else {
+ toAppend = searchterms;
+ hlterms.push(tmp[i].toLowerCase());
+ }
+ // only add if not already in the list
+ if (!$u.contains(toAppend, word))
+ toAppend.push(word);
+ }
+ var highlightstring = '?highlight=' + $.urlencode(hlterms.join(" "));
+
+ // console.debug('SEARCH: searching for:');
+ // console.info('required: ', searchterms);
+ // console.info('excluded: ', excluded);
+
+ // prepare search
+ var terms = this._index.terms;
+ var titleterms = this._index.titleterms;
+
+ // array of [filename, title, anchor, descr, score]
+ var results = [];
+ $('#search-progress').empty();
+
+ // lookup as object
+ for (i = 0; i < objectterms.length; i++) {
+ var others = [].concat(objectterms.slice(0, i),
+ objectterms.slice(i+1, objectterms.length));
+ results = results.concat(this.performObjectSearch(objectterms[i], others));
+ }
+
+ // lookup as search terms in fulltext
+ results = results.concat(this.performTermsSearch(searchterms, excluded, terms, titleterms));
+
+ // let the scorer override scores with a custom scoring function
+ if (Scorer.score) {
+ for (i = 0; i < results.length; i++)
+ results[i][4] = Scorer.score(results[i]);
+ }
+
+ // now sort the results by score (in opposite order of appearance, since the
+ // display function below uses pop() to retrieve items) and then
+ // alphabetically
+ results.sort(function(a, b) {
+ var left = a[4];
+ var right = b[4];
+ if (left > right) {
+ return 1;
+ } else if (left < right) {
+ return -1;
+ } else {
+ // same score: sort alphabetically
+ left = a[1].toLowerCase();
+ right = b[1].toLowerCase();
+ return (left > right) ? -1 : ((left < right) ? 1 : 0);
+ }
+ });
+
+ // for debugging
+ //Search.lastresults = results.slice(); // a copy
+ //console.info('search results:', Search.lastresults);
+
+ // print the results
+ var resultCount = results.length;
+ function displayNextItem() {
+ // results left, load the summary and display it
+ if (results.length) {
+ var item = results.pop();
+ var listItem = $('<li style="display:none"></li>');
+ if (DOCUMENTATION_OPTIONS.FILE_SUFFIX === '') {
+ // dirhtml builder
+ var dirname = item[0] + '/';
+ if (dirname.match(/\/index\/$/)) {
+ dirname = dirname.substring(0, dirname.length-6);
+ } else if (dirname == 'index/') {
+ dirname = '';
+ }
+ listItem.append($('<a/>').attr('href',
+ DOCUMENTATION_OPTIONS.URL_ROOT + dirname +
+ highlightstring + item[2]).html(item[1]));
+ } else {
+ // normal html builders
+ listItem.append($('<a/>').attr('href',
+ item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX +
+ highlightstring + item[2]).html(item[1]));
+ }
+ if (item[3]) {
+ listItem.append($('<span> (' + item[3] + ')</span>'));
+ Search.output.append(listItem);
+ listItem.slideDown(5, function() {
+ displayNextItem();
+ });
+ } else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) {
+ var suffix = DOCUMENTATION_OPTIONS.SOURCELINK_SUFFIX;
+ if (suffix === undefined) {
+ suffix = '.txt';
+ }
+ $.ajax({url: DOCUMENTATION_OPTIONS.URL_ROOT + '_sources/' + item[5] + (item[5].slice(-suffix.length) === suffix ? '' : suffix),
+ dataType: "text",
+ complete: function(jqxhr, textstatus) {
+ var data = jqxhr.responseText;
+ if (data !== '' && data !== undefined) {
+ listItem.append(Search.makeSearchSummary(data, searchterms, hlterms));
+ }
+ Search.output.append(listItem);
+ listItem.slideDown(5, function() {
+ displayNextItem();
+ });
+ }});
+ } else {
+ // no source available, just display title
+ Search.output.append(listItem);
+ listItem.slideDown(5, function() {
+ displayNextItem();
+ });
+ }
+ }
+ // search finished, update title and status message
+ else {
+ Search.stopPulse();
+ Search.title.text(_('Search Results'));
+ if (!resultCount)
+ Search.status.text(_('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.'));
+ else
+ Search.status.text(_('Search finished, found %s page(s) matching the search query.').replace('%s', resultCount));
+ Search.status.fadeIn(500);
+ }
+ }
+ displayNextItem();
+ },
+
+ /**
+ * search for object names
+ */
+ performObjectSearch : function(object, otherterms) {
+ var filenames = this._index.filenames;
+ var docnames = this._index.docnames;
+ var objects = this._index.objects;
+ var objnames = this._index.objnames;
+ var titles = this._index.titles;
+
+ var i;
+ var results = [];
+
+ for (var prefix in objects) {
+ for (var name in objects[prefix]) {
+ var fullname = (prefix ? prefix + '.' : '') + name;
+ if (fullname.toLowerCase().indexOf(object) > -1) {
+ var score = 0;
+ var parts = fullname.split('.');
+ // check for different match types: exact matches of full name or
+ // "last name" (i.e. last dotted part)
+ if (fullname == object || parts[parts.length - 1] == object) {
+ score += Scorer.objNameMatch;
+ // matches in last name
+ } else if (parts[parts.length - 1].indexOf(object) > -1) {
+ score += Scorer.objPartialMatch;
+ }
+ var match = objects[prefix][name];
+ var objname = objnames[match[1]][2];
+ var title = titles[match[0]];
+ // If more than one term searched for, we require other words to be
+ // found in the name/title/description
+ if (otherterms.length > 0) {
+ var haystack = (prefix + ' ' + name + ' ' +
+ objname + ' ' + title).toLowerCase();
+ var allfound = true;
+ for (i = 0; i < otherterms.length; i++) {
+ if (haystack.indexOf(otherterms[i]) == -1) {
+ allfound = false;
+ break;
+ }
+ }
+ if (!allfound) {
+ continue;
+ }
+ }
+ var descr = objname + _(', in ') + title;
+
+ var anchor = match[3];
+ if (anchor === '')
+ anchor = fullname;
+ else if (anchor == '-')
+ anchor = objnames[match[1]][1] + '-' + fullname;
+ // add custom score for some objects according to scorer
+ if (Scorer.objPrio.hasOwnProperty(match[2])) {
+ score += Scorer.objPrio[match[2]];
+ } else {
+ score += Scorer.objPrioDefault;
+ }
+ results.push([docnames[match[0]], fullname, '#'+anchor, descr, score, filenames[match[0]]]);
+ }
+ }
+ }
+
+ return results;
+ },
+
+ /**
+ * search for full-text terms in the index
+ */
+ performTermsSearch : function(searchterms, excluded, terms, titleterms) {
+ var docnames = this._index.docnames;
+ var filenames = this._index.filenames;
+ var titles = this._index.titles;
+
+ var i, j, file;
+ var fileMap = {};
+ var scoreMap = {};
+ var results = [];
+
+ // perform the search on the required terms
+ for (i = 0; i < searchterms.length; i++) {
+ var word = searchterms[i];
+ var files = [];
+ var _o = [
+ {files: terms[word], score: Scorer.term},
+ {files: titleterms[word], score: Scorer.title}
+ ];
+
+ // no match but word was a required one
+ if ($u.every(_o, function(o){return o.files === undefined;})) {
+ break;
+ }
+ // found search word in contents
+ $u.each(_o, function(o) {
+ var _files = o.files;
+ if (_files === undefined)
+ return
+
+ if (_files.length === undefined)
+ _files = [_files];
+ files = files.concat(_files);
+
+ // set score for the word in each file to Scorer.term
+ for (j = 0; j < _files.length; j++) {
+ file = _files[j];
+ if (!(file in scoreMap))
+ scoreMap[file] = {}
+ scoreMap[file][word] = o.score;
+ }
+ });
+
+ // create the mapping
+ for (j = 0; j < files.length; j++) {
+ file = files[j];
+ if (file in fileMap)
+ fileMap[file].push(word);
+ else
+ fileMap[file] = [word];
+ }
+ }
+
+ // now check if the files don't contain excluded terms
+ for (file in fileMap) {
+ var valid = true;
+
+ // check if all requirements are matched
+ if (fileMap[file].length != searchterms.length)
+ continue;
+
+ // ensure that none of the excluded terms is in the search result
+ for (i = 0; i < excluded.length; i++) {
+ if (terms[excluded[i]] == file ||
+ titleterms[excluded[i]] == file ||
+ $u.contains(terms[excluded[i]] || [], file) ||
+ $u.contains(titleterms[excluded[i]] || [], file)) {
+ valid = false;
+ break;
+ }
+ }
+
+ // if we have still a valid result we can add it to the result list
+ if (valid) {
+ // select one (max) score for the file.
+ // for better ranking, we should calculate ranking by using words statistics like basic tf-idf...
+ var score = $u.max($u.map(fileMap[file], function(w){return scoreMap[file][w]}));
+ results.push([docnames[file], titles[file], '', null, score, filenames[file]]);
+ }
+ }
+ return results;
+ },
+
+ /**
+ * helper function to return a node containing the
+ * search summary for a given text. keywords is a list
+ * of stemmed words, hlwords is the list of normal, unstemmed
+ * words. the first one is used to find the occurrence, the
+ * latter for highlighting it.
+ */
+ makeSearchSummary : function(text, keywords, hlwords) {
+ var textLower = text.toLowerCase();
+ var start = 0;
+ $.each(keywords, function() {
+ var i = textLower.indexOf(this.toLowerCase());
+ if (i > -1)
+ start = i;
+ });
+ start = Math.max(start - 120, 0);
+ var excerpt = ((start > 0) ? '...' : '') +
+ $.trim(text.substr(start, 240)) +
+ ((start + 240 - text.length) ? '...' : '');
+ var rv = $('<div class="context"></div>').text(excerpt);
+ $.each(hlwords, function() {
+ rv = rv.highlightText(this, 'highlighted');
+ });
+ return rv;
+ }
+};
+
+$(document).ready(function() {
+ Search.init();
+});
diff --git a/doc/html/_static/underscore-1.3.1.js b/doc/html/_static/underscore-1.3.1.js
new file mode 100644
index 0000000..208d4cd
--- /dev/null
+++ b/doc/html/_static/underscore-1.3.1.js
@@ -0,0 +1,999 @@
+// Underscore.js 1.3.1
+// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
+// Underscore is freely distributable under the MIT license.
+// Portions of Underscore are inspired or borrowed from Prototype,
+// Oliver Steele's Functional, and John Resig's Micro-Templating.
+// For all details and documentation:
+// http://documentcloud.github.com/underscore
+
+(function() {
+
+ // Baseline setup
+ // --------------
+
+ // Establish the root object, `window` in the browser, or `global` on the server.
+ var root = this;
+
+ // Save the previous value of the `_` variable.
+ var previousUnderscore = root._;
+
+ // Establish the object that gets returned to break out of a loop iteration.
+ var breaker = {};
+
+ // Save bytes in the minified (but not gzipped) version:
+ var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
+
+ // Create quick reference variables for speed access to core prototypes.
+ var slice = ArrayProto.slice,
+ unshift = ArrayProto.unshift,
+ toString = ObjProto.toString,
+ hasOwnProperty = ObjProto.hasOwnProperty;
+
+ // All **ECMAScript 5** native function implementations that we hope to use
+ // are declared here.
+ var
+ nativeForEach = ArrayProto.forEach,
+ nativeMap = ArrayProto.map,
+ nativeReduce = ArrayProto.reduce,
+ nativeReduceRight = ArrayProto.reduceRight,
+ nativeFilter = ArrayProto.filter,
+ nativeEvery = ArrayProto.every,
+ nativeSome = ArrayProto.some,
+ nativeIndexOf = ArrayProto.indexOf,
+ nativeLastIndexOf = ArrayProto.lastIndexOf,
+ nativeIsArray = Array.isArray,
+ nativeKeys = Object.keys,
+ nativeBind = FuncProto.bind;
+
+ // Create a safe reference to the Underscore object for use below.
+ var _ = function(obj) { return new wrapper(obj); };
+
+ // Export the Underscore object for **Node.js**, with
+ // backwards-compatibility for the old `require()` API. If we're in
+ // the browser, add `_` as a global object via a string identifier,
+ // for Closure Compiler "advanced" mode.
+ if (typeof exports !== 'undefined') {
+ if (typeof module !== 'undefined' && module.exports) {
+ exports = module.exports = _;
+ }
+ exports._ = _;
+ } else {
+ root['_'] = _;
+ }
+
+ // Current version.
+ _.VERSION = '1.3.1';
+
+ // Collection Functions
+ // --------------------
+
+ // The cornerstone, an `each` implementation, aka `forEach`.
+ // Handles objects with the built-in `forEach`, arrays, and raw objects.
+ // Delegates to **ECMAScript 5**'s native `forEach` if available.
+ var each = _.each = _.forEach = function(obj, iterator, context) {
+ if (obj == null) return;
+ if (nativeForEach && obj.forEach === nativeForEach) {
+ obj.forEach(iterator, context);
+ } else if (obj.length === +obj.length) {
+ for (var i = 0, l = obj.length; i < l; i++) {
+ if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) return;
+ }
+ } else {
+ for (var key in obj) {
+ if (_.has(obj, key)) {
+ if (iterator.call(context, obj[key], key, obj) === breaker) return;
+ }
+ }
+ }
+ };
+
+ // Return the results of applying the iterator to each element.
+ // Delegates to **ECMAScript 5**'s native `map` if available.
+ _.map = _.collect = function(obj, iterator, context) {
+ var results = [];
+ if (obj == null) return results;
+ if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
+ each(obj, function(value, index, list) {
+ results[results.length] = iterator.call(context, value, index, list);
+ });
+ if (obj.length === +obj.length) results.length = obj.length;
+ return results;
+ };
+
+ // **Reduce** builds up a single result from a list of values, aka `inject`,
+ // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
+ _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
+ var initial = arguments.length > 2;
+ if (obj == null) obj = [];
+ if (nativeReduce && obj.reduce === nativeReduce) {
+ if (context) iterator = _.bind(iterator, context);
+ return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
+ }
+ each(obj, function(value, index, list) {
+ if (!initial) {
+ memo = value;
+ initial = true;
+ } else {
+ memo = iterator.call(context, memo, value, index, list);
+ }
+ });
+ if (!initial) throw new TypeError('Reduce of empty array with no initial value');
+ return memo;
+ };
+
+ // The right-associative version of reduce, also known as `foldr`.
+ // Delegates to **ECMAScript 5**'s native `reduceRight` if available.
+ _.reduceRight = _.foldr = function(obj, iterator, memo, context) {
+ var initial = arguments.length > 2;
+ if (obj == null) obj = [];
+ if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
+ if (context) iterator = _.bind(iterator, context);
+ return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
+ }
+ var reversed = _.toArray(obj).reverse();
+ if (context && !initial) iterator = _.bind(iterator, context);
+ return initial ? _.reduce(reversed, iterator, memo, context) : _.reduce(reversed, iterator);
+ };
+
+ // Return the first value which passes a truth test. Aliased as `detect`.
+ _.find = _.detect = function(obj, iterator, context) {
+ var result;
+ any(obj, function(value, index, list) {
+ if (iterator.call(context, value, index, list)) {
+ result = value;
+ return true;
+ }
+ });
+ return result;
+ };
+
+ // Return all the elements that pass a truth test.
+ // Delegates to **ECMAScript 5**'s native `filter` if available.
+ // Aliased as `select`.
+ _.filter = _.select = function(obj, iterator, context) {
+ var results = [];
+ if (obj == null) return results;
+ if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
+ each(obj, function(value, index, list) {
+ if (iterator.call(context, value, index, list)) results[results.length] = value;
+ });
+ return results;
+ };
+
+ // Return all the elements for which a truth test fails.
+ _.reject = function(obj, iterator, context) {
+ var results = [];
+ if (obj == null) return results;
+ each(obj, function(value, index, list) {
+ if (!iterator.call(context, value, index, list)) results[results.length] = value;
+ });
+ return results;
+ };
+
+ // Determine whether all of the elements match a truth test.
+ // Delegates to **ECMAScript 5**'s native `every` if available.
+ // Aliased as `all`.
+ _.every = _.all = function(obj, iterator, context) {
+ var result = true;
+ if (obj == null) return result;
+ if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
+ each(obj, function(value, index, list) {
+ if (!(result = result && iterator.call(context, value, index, list))) return breaker;
+ });
+ return result;
+ };
+
+ // Determine if at least one element in the object matches a truth test.
+ // Delegates to **ECMAScript 5**'s native `some` if available.
+ // Aliased as `any`.
+ var any = _.some = _.any = function(obj, iterator, context) {
+ iterator || (iterator = _.identity);
+ var result = false;
+ if (obj == null) return result;
+ if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
+ each(obj, function(value, index, list) {
+ if (result || (result = iterator.call(context, value, index, list))) return breaker;
+ });
+ return !!result;
+ };
+
+ // Determine if a given value is included in the array or object using `===`.
+ // Aliased as `contains`.
+ _.include = _.contains = function(obj, target) {
+ var found = false;
+ if (obj == null) return found;
+ if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
+ found = any(obj, function(value) {
+ return value === target;
+ });
+ return found;
+ };
+
+ // Invoke a method (with arguments) on every item in a collection.
+ _.invoke = function(obj, method) {
+ var args = slice.call(arguments, 2);
+ return _.map(obj, function(value) {
+ return (_.isFunction(method) ? method || value : value[method]).apply(value, args);
+ });
+ };
+
+ // Convenience version of a common use case of `map`: fetching a property.
+ _.pluck = function(obj, key) {
+ return _.map(obj, function(value){ return value[key]; });
+ };
+
+ // Return the maximum element or (element-based computation).
+ _.max = function(obj, iterator, context) {
+ if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj);
+ if (!iterator && _.isEmpty(obj)) return -Infinity;
+ var result = {computed : -Infinity};
+ each(obj, function(value, index, list) {
+ var computed = iterator ? iterator.call(context, value, index, list) : value;
+ computed >= result.computed && (result = {value : value, computed : computed});
+ });
+ return result.value;
+ };
+
+ // Return the minimum element (or element-based computation).
+ _.min = function(obj, iterator, context) {
+ if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj);
+ if (!iterator && _.isEmpty(obj)) return Infinity;
+ var result = {computed : Infinity};
+ each(obj, function(value, index, list) {
+ var computed = iterator ? iterator.call(context, value, index, list) : value;
+ computed < result.computed && (result = {value : value, computed : computed});
+ });
+ return result.value;
+ };
+
+ // Shuffle an array.
+ _.shuffle = function(obj) {
+ var shuffled = [], rand;
+ each(obj, function(value, index, list) {
+ if (index == 0) {
+ shuffled[0] = value;
+ } else {
+ rand = Math.floor(Math.random() * (index + 1));
+ shuffled[index] = shuffled[rand];
+ shuffled[rand] = value;
+ }
+ });
+ return shuffled;
+ };
+
+ // Sort the object's values by a criterion produced by an iterator.
+ _.sortBy = function(obj, iterator, context) {
+ return _.pluck(_.map(obj, function(value, index, list) {
+ return {
+ value : value,
+ criteria : iterator.call(context, value, index, list)
+ };
+ }).sort(function(left, right) {
+ var a = left.criteria, b = right.criteria;
+ return a < b ? -1 : a > b ? 1 : 0;
+ }), 'value');
+ };
+
+ // Groups the object's values by a criterion. Pass either a string attribute
+ // to group by, or a function that returns the criterion.
+ _.groupBy = function(obj, val) {
+ var result = {};
+ var iterator = _.isFunction(val) ? val : function(obj) { return obj[val]; };
+ each(obj, function(value, index) {
+ var key = iterator(value, index);
+ (result[key] || (result[key] = [])).push(value);
+ });
+ return result;
+ };
+
+ // Use a comparator function to figure out at what index an object should
+ // be inserted so as to maintain order. Uses binary search.
+ _.sortedIndex = function(array, obj, iterator) {
+ iterator || (iterator = _.identity);
+ var low = 0, high = array.length;
+ while (low < high) {
+ var mid = (low + high) >> 1;
+ iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid;
+ }
+ return low;
+ };
+
+ // Safely convert anything iterable into a real, live array.
+ _.toArray = function(iterable) {
+ if (!iterable) return [];
+ if (iterable.toArray) return iterable.toArray();
+ if (_.isArray(iterable)) return slice.call(iterable);
+ if (_.isArguments(iterable)) return slice.call(iterable);
+ return _.values(iterable);
+ };
+
+ // Return the number of elements in an object.
+ _.size = function(obj) {
+ return _.toArray(obj).length;
+ };
+
+ // Array Functions
+ // ---------------
+
+ // Get the first element of an array. Passing **n** will return the first N
+ // values in the array. Aliased as `head`. The **guard** check allows it to work
+ // with `_.map`.
+ _.first = _.head = function(array, n, guard) {
+ return (n != null) && !guard ? slice.call(array, 0, n) : array[0];
+ };
+
+ // Returns everything but the last entry of the array. Especcialy useful on
+ // the arguments object. Passing **n** will return all the values in
+ // the array, excluding the last N. The **guard** check allows it to work with
+ // `_.map`.
+ _.initial = function(array, n, guard) {
+ return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));
+ };
+
+ // Get the last element of an array. Passing **n** will return the last N
+ // values in the array. The **guard** check allows it to work with `_.map`.
+ _.last = function(array, n, guard) {
+ if ((n != null) && !guard) {
+ return slice.call(array, Math.max(array.length - n, 0));
+ } else {
+ return array[array.length - 1];
+ }
+ };
+
+ // Returns everything but the first entry of the array. Aliased as `tail`.
+ // Especially useful on the arguments object. Passing an **index** will return
+ // the rest of the values in the array from that index onward. The **guard**
+ // check allows it to work with `_.map`.
+ _.rest = _.tail = function(array, index, guard) {
+ return slice.call(array, (index == null) || guard ? 1 : index);
+ };
+
+ // Trim out all falsy values from an array.
+ _.compact = function(array) {
+ return _.filter(array, function(value){ return !!value; });
+ };
+
+ // Return a completely flattened version of an array.
+ _.flatten = function(array, shallow) {
+ return _.reduce(array, function(memo, value) {
+ if (_.isArray(value)) return memo.concat(shallow ? value : _.flatten(value));
+ memo[memo.length] = value;
+ return memo;
+ }, []);
+ };
+
+ // Return a version of the array that does not contain the specified value(s).
+ _.without = function(array) {
+ return _.difference(array, slice.call(arguments, 1));
+ };
+
+ // Produce a duplicate-free version of the array. If the array has already
+ // been sorted, you have the option of using a faster algorithm.
+ // Aliased as `unique`.
+ _.uniq = _.unique = function(array, isSorted, iterator) {
+ var initial = iterator ? _.map(array, iterator) : array;
+ var result = [];
+ _.reduce(initial, function(memo, el, i) {
+ if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) {
+ memo[memo.length] = el;
+ result[result.length] = array[i];
+ }
+ return memo;
+ }, []);
+ return result;
+ };
+
+ // Produce an array that contains the union: each distinct element from all of
+ // the passed-in arrays.
+ _.union = function() {
+ return _.uniq(_.flatten(arguments, true));
+ };
+
+ // Produce an array that contains every item shared between all the
+ // passed-in arrays. (Aliased as "intersect" for back-compat.)
+ _.intersection = _.intersect = function(array) {
+ var rest = slice.call(arguments, 1);
+ return _.filter(_.uniq(array), function(item) {
+ return _.every(rest, function(other) {
+ return _.indexOf(other, item) >= 0;
+ });
+ });
+ };
+
+ // Take the difference between one array and a number of other arrays.
+ // Only the elements present in just the first array will remain.
+ _.difference = function(array) {
+ var rest = _.flatten(slice.call(arguments, 1));
+ return _.filter(array, function(value){ return !_.include(rest, value); });
+ };
+
+ // Zip together multiple lists into a single array -- elements that share
+ // an index go together.
+ _.zip = function() {
+ var args = slice.call(arguments);
+ var length = _.max(_.pluck(args, 'length'));
+ var results = new Array(length);
+ for (var i = 0; i < length; i++) results[i] = _.pluck(args, "" + i);
+ return results;
+ };
+
+ // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),
+ // we need this function. Return the position of the first occurrence of an
+ // item in an array, or -1 if the item is not included in the array.
+ // Delegates to **ECMAScript 5**'s native `indexOf` if available.
+ // If the array is large and already in sort order, pass `true`
+ // for **isSorted** to use binary search.
+ _.indexOf = function(array, item, isSorted) {
+ if (array == null) return -1;
+ var i, l;
+ if (isSorted) {
+ i = _.sortedIndex(array, item);
+ return array[i] === item ? i : -1;
+ }
+ if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item);
+ for (i = 0, l = array.length; i < l; i++) if (i in array && array[i] === item) return i;
+ return -1;
+ };
+
+ // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
+ _.lastIndexOf = function(array, item) {
+ if (array == null) return -1;
+ if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item);
+ var i = array.length;
+ while (i--) if (i in array && array[i] === item) return i;
+ return -1;
+ };
+
+ // Generate an integer Array containing an arithmetic progression. A port of
+ // the native Python `range()` function. See
+ // [the Python documentation](http://docs.python.org/library/functions.html#range).
+ _.range = function(start, stop, step) {
+ if (arguments.length <= 1) {
+ stop = start || 0;
+ start = 0;
+ }
+ step = arguments[2] || 1;
+
+ var len = Math.max(Math.ceil((stop - start) / step), 0);
+ var idx = 0;
+ var range = new Array(len);
+
+ while(idx < len) {
+ range[idx++] = start;
+ start += step;
+ }
+
+ return range;
+ };
+
+ // Function (ahem) Functions
+ // ------------------
+
+ // Reusable constructor function for prototype setting.
+ var ctor = function(){};
+
+ // Create a function bound to a given object (assigning `this`, and arguments,
+ // optionally). Binding with arguments is also known as `curry`.
+ // Delegates to **ECMAScript 5**'s native `Function.bind` if available.
+ // We check for `func.bind` first, to fail fast when `func` is undefined.
+ _.bind = function bind(func, context) {
+ var bound, args;
+ if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
+ if (!_.isFunction(func)) throw new TypeError;
+ args = slice.call(arguments, 2);
+ return bound = function() {
+ if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
+ ctor.prototype = func.prototype;
+ var self = new ctor;
+ var result = func.apply(self, args.concat(slice.call(arguments)));
+ if (Object(result) === result) return result;
+ return self;
+ };
+ };
+
+ // Bind all of an object's methods to that object. Useful for ensuring that
+ // all callbacks defined on an object belong to it.
+ _.bindAll = function(obj) {
+ var funcs = slice.call(arguments, 1);
+ if (funcs.length == 0) funcs = _.functions(obj);
+ each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
+ return obj;
+ };
+
+ // Memoize an expensive function by storing its results.
+ _.memoize = function(func, hasher) {
+ var memo = {};
+ hasher || (hasher = _.identity);
+ return function() {
+ var key = hasher.apply(this, arguments);
+ return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
+ };
+ };
+
+ // Delays a function for the given number of milliseconds, and then calls
+ // it with the arguments supplied.
+ _.delay = function(func, wait) {
+ var args = slice.call(arguments, 2);
+ return setTimeout(function(){ return func.apply(func, args); }, wait);
+ };
+
+ // Defers a function, scheduling it to run after the current call stack has
+ // cleared.
+ _.defer = function(func) {
+ return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
+ };
+
+ // Returns a function, that, when invoked, will only be triggered at most once
+ // during a given window of time.
+ _.throttle = function(func, wait) {
+ var context, args, timeout, throttling, more;
+ var whenDone = _.debounce(function(){ more = throttling = false; }, wait);
+ return function() {
+ context = this; args = arguments;
+ var later = function() {
+ timeout = null;
+ if (more) func.apply(context, args);
+ whenDone();
+ };
+ if (!timeout) timeout = setTimeout(later, wait);
+ if (throttling) {
+ more = true;
+ } else {
+ func.apply(context, args);
+ }
+ whenDone();
+ throttling = true;
+ };
+ };
+
+ // Returns a function, that, as long as it continues to be invoked, will not
+ // be triggered. The function will be called after it stops being called for
+ // N milliseconds.
+ _.debounce = function(func, wait) {
+ var timeout;
+ return function() {
+ var context = this, args = arguments;
+ var later = function() {
+ timeout = null;
+ func.apply(context, args);
+ };
+ clearTimeout(timeout);
+ timeout = setTimeout(later, wait);
+ };
+ };
+
+ // Returns a function that will be executed at most one time, no matter how
+ // often you call it. Useful for lazy initialization.
+ _.once = function(func) {
+ var ran = false, memo;
+ return function() {
+ if (ran) return memo;
+ ran = true;
+ return memo = func.apply(this, arguments);
+ };
+ };
+
+ // Returns the first function passed as an argument to the second,
+ // allowing you to adjust arguments, run code before and after, and
+ // conditionally execute the original function.
+ _.wrap = function(func, wrapper) {
+ return function() {
+ var args = [func].concat(slice.call(arguments, 0));
+ return wrapper.apply(this, args);
+ };
+ };
+
+ // Returns a function that is the composition of a list of functions, each
+ // consuming the return value of the function that follows.
+ _.compose = function() {
+ var funcs = arguments;
+ return function() {
+ var args = arguments;
+ for (var i = funcs.length - 1; i >= 0; i--) {
+ args = [funcs[i].apply(this, args)];
+ }
+ return args[0];
+ };
+ };
+
+ // Returns a function that will only be executed after being called N times.
+ _.after = function(times, func) {
+ if (times <= 0) return func();
+ return function() {
+ if (--times < 1) { return func.apply(this, arguments); }
+ };
+ };
+
+ // Object Functions
+ // ----------------
+
+ // Retrieve the names of an object's properties.
+ // Delegates to **ECMAScript 5**'s native `Object.keys`
+ _.keys = nativeKeys || function(obj) {
+ if (obj !== Object(obj)) throw new TypeError('Invalid object');
+ var keys = [];
+ for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key;
+ return keys;
+ };
+
+ // Retrieve the values of an object's properties.
+ _.values = function(obj) {
+ return _.map(obj, _.identity);
+ };
+
+ // Return a sorted list of the function names available on the object.
+ // Aliased as `methods`
+ _.functions = _.methods = function(obj) {
+ var names = [];
+ for (var key in obj) {
+ if (_.isFunction(obj[key])) names.push(key);
+ }
+ return names.sort();
+ };
+
+ // Extend a given object with all the properties in passed-in object(s).
+ _.extend = function(obj) {
+ each(slice.call(arguments, 1), function(source) {
+ for (var prop in source) {
+ obj[prop] = source[prop];
+ }
+ });
+ return obj;
+ };
+
+ // Fill in a given object with default properties.
+ _.defaults = function(obj) {
+ each(slice.call(arguments, 1), function(source) {
+ for (var prop in source) {
+ if (obj[prop] == null) obj[prop] = source[prop];
+ }
+ });
+ return obj;
+ };
+
+ // Create a (shallow-cloned) duplicate of an object.
+ _.clone = function(obj) {
+ if (!_.isObject(obj)) return obj;
+ return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
+ };
+
+ // Invokes interceptor with the obj, and then returns obj.
+ // The primary purpose of this method is to "tap into" a method chain, in
+ // order to perform operations on intermediate results within the chain.
+ _.tap = function(obj, interceptor) {
+ interceptor(obj);
+ return obj;
+ };
+
+ // Internal recursive comparison function.
+ function eq(a, b, stack) {
+ // Identical objects are equal. `0 === -0`, but they aren't identical.
+ // See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal.
+ if (a === b) return a !== 0 || 1 / a == 1 / b;
+ // A strict comparison is necessary because `null == undefined`.
+ if (a == null || b == null) return a === b;
+ // Unwrap any wrapped objects.
+ if (a._chain) a = a._wrapped;
+ if (b._chain) b = b._wrapped;
+ // Invoke a custom `isEqual` method if one is provided.
+ if (a.isEqual && _.isFunction(a.isEqual)) return a.isEqual(b);
+ if (b.isEqual && _.isFunction(b.isEqual)) return b.isEqual(a);
+ // Compare `[[Class]]` names.
+ var className = toString.call(a);
+ if (className != toString.call(b)) return false;
+ switch (className) {
+ // Strings, numbers, dates, and booleans are compared by value.
+ case '[object String]':
+ // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
+ // equivalent to `new String("5")`.
+ return a == String(b);
+ case '[object Number]':
+ // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for
+ // other numeric values.
+ return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);
+ case '[object Date]':
+ case '[object Boolean]':
+ // Coerce dates and booleans to numeric primitive values. Dates are compared by their
+ // millisecond representations. Note that invalid dates with millisecond representations
+ // of `NaN` are not equivalent.
+ return +a == +b;
+ // RegExps are compared by their source patterns and flags.
+ case '[object RegExp]':
+ return a.source == b.source &&
+ a.global == b.global &&
+ a.multiline == b.multiline &&
+ a.ignoreCase == b.ignoreCase;
+ }
+ if (typeof a != 'object' || typeof b != 'object') return false;
+ // Assume equality for cyclic structures. The algorithm for detecting cyclic
+ // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
+ var length = stack.length;
+ while (length--) {
+ // Linear search. Performance is inversely proportional to the number of
+ // unique nested structures.
+ if (stack[length] == a) return true;
+ }
+ // Add the first object to the stack of traversed objects.
+ stack.push(a);
+ var size = 0, result = true;
+ // Recursively compare objects and arrays.
+ if (className == '[object Array]') {
+ // Compare array lengths to determine if a deep comparison is necessary.
+ size = a.length;
+ result = size == b.length;
+ if (result) {
+ // Deep compare the contents, ignoring non-numeric properties.
+ while (size--) {
+ // Ensure commutative equality for sparse arrays.
+ if (!(result = size in a == size in b && eq(a[size], b[size], stack))) break;
+ }
+ }
+ } else {
+ // Objects with different constructors are not equivalent.
+ if ('constructor' in a != 'constructor' in b || a.constructor != b.constructor) return false;
+ // Deep compare objects.
+ for (var key in a) {
+ if (_.has(a, key)) {
+ // Count the expected number of properties.
+ size++;
+ // Deep compare each member.
+ if (!(result = _.has(b, key) && eq(a[key], b[key], stack))) break;
+ }
+ }
+ // Ensure that both objects contain the same number of properties.
+ if (result) {
+ for (key in b) {
+ if (_.has(b, key) && !(size--)) break;
+ }
+ result = !size;
+ }
+ }
+ // Remove the first object from the stack of traversed objects.
+ stack.pop();
+ return result;
+ }
+
+ // Perform a deep comparison to check if two objects are equal.
+ _.isEqual = function(a, b) {
+ return eq(a, b, []);
+ };
+
+ // Is a given array, string, or object empty?
+ // An "empty" object has no enumerable own-properties.
+ _.isEmpty = function(obj) {
+ if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
+ for (var key in obj) if (_.has(obj, key)) return false;
+ return true;
+ };
+
+ // Is a given value a DOM element?
+ _.isElement = function(obj) {
+ return !!(obj && obj.nodeType == 1);
+ };
+
+ // Is a given value an array?
+ // Delegates to ECMA5's native Array.isArray
+ _.isArray = nativeIsArray || function(obj) {
+ return toString.call(obj) == '[object Array]';
+ };
+
+ // Is a given variable an object?
+ _.isObject = function(obj) {
+ return obj === Object(obj);
+ };
+
+ // Is a given variable an arguments object?
+ _.isArguments = function(obj) {
+ return toString.call(obj) == '[object Arguments]';
+ };
+ if (!_.isArguments(arguments)) {
+ _.isArguments = function(obj) {
+ return !!(obj && _.has(obj, 'callee'));
+ };
+ }
+
+ // Is a given value a function?
+ _.isFunction = function(obj) {
+ return toString.call(obj) == '[object Function]';
+ };
+
+ // Is a given value a string?
+ _.isString = function(obj) {
+ return toString.call(obj) == '[object String]';
+ };
+
+ // Is a given value a number?
+ _.isNumber = function(obj) {
+ return toString.call(obj) == '[object Number]';
+ };
+
+ // Is the given value `NaN`?
+ _.isNaN = function(obj) {
+ // `NaN` is the only value for which `===` is not reflexive.
+ return obj !== obj;
+ };
+
+ // Is a given value a boolean?
+ _.isBoolean = function(obj) {
+ return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
+ };
+
+ // Is a given value a date?
+ _.isDate = function(obj) {
+ return toString.call(obj) == '[object Date]';
+ };
+
+ // Is the given value a regular expression?
+ _.isRegExp = function(obj) {
+ return toString.call(obj) == '[object RegExp]';
+ };
+
+ // Is a given value equal to null?
+ _.isNull = function(obj) {
+ return obj === null;
+ };
+
+ // Is a given variable undefined?
+ _.isUndefined = function(obj) {
+ return obj === void 0;
+ };
+
+ // Has own property?
+ _.has = function(obj, key) {
+ return hasOwnProperty.call(obj, key);
+ };
+
+ // Utility Functions
+ // -----------------
+
+ // Run Underscore.js in *noConflict* mode, returning the `_` variable to its
+ // previous owner. Returns a reference to the Underscore object.
+ _.noConflict = function() {
+ root._ = previousUnderscore;
+ return this;
+ };
+
+ // Keep the identity function around for default iterators.
+ _.identity = function(value) {
+ return value;
+ };
+
+ // Run a function **n** times.
+ _.times = function (n, iterator, context) {
+ for (var i = 0; i < n; i++) iterator.call(context, i);
+ };
+
+ // Escape a string for HTML interpolation.
+ _.escape = function(string) {
+ return (''+string).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#x27;').replace(/\//g,'&#x2F;');
+ };
+
+ // Add your own custom functions to the Underscore object, ensuring that
+ // they're correctly added to the OOP wrapper as well.
+ _.mixin = function(obj) {
+ each(_.functions(obj), function(name){
+ addToWrapper(name, _[name] = obj[name]);
+ });
+ };
+
+ // Generate a unique integer id (unique within the entire client session).
+ // Useful for temporary DOM ids.
+ var idCounter = 0;
+ _.uniqueId = function(prefix) {
+ var id = idCounter++;
+ return prefix ? prefix + id : id;
+ };
+
+ // By default, Underscore uses ERB-style template delimiters, change the
+ // following template settings to use alternative delimiters.
+ _.templateSettings = {
+ evaluate : /<%([\s\S]+?)%>/g,
+ interpolate : /<%=([\s\S]+?)%>/g,
+ escape : /<%-([\s\S]+?)%>/g
+ };
+
+ // When customizing `templateSettings`, if you don't want to define an
+ // interpolation, evaluation or escaping regex, we need one that is
+ // guaranteed not to match.
+ var noMatch = /.^/;
+
+ // Within an interpolation, evaluation, or escaping, remove HTML escaping
+ // that had been previously added.
+ var unescape = function(code) {
+ return code.replace(/\\\\/g, '\\').replace(/\\'/g, "'");
+ };
+
+ // JavaScript micro-templating, similar to John Resig's implementation.
+ // Underscore templating handles arbitrary delimiters, preserves whitespace,
+ // and correctly escapes quotes within interpolated code.
+ _.template = function(str, data) {
+ var c = _.templateSettings;
+ var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' +
+ 'with(obj||{}){__p.push(\'' +
+ str.replace(/\\/g, '\\\\')
+ .replace(/'/g, "\\'")
+ .replace(c.escape || noMatch, function(match, code) {
+ return "',_.escape(" + unescape(code) + "),'";
+ })
+ .replace(c.interpolate || noMatch, function(match, code) {
+ return "'," + unescape(code) + ",'";
+ })
+ .replace(c.evaluate || noMatch, function(match, code) {
+ return "');" + unescape(code).replace(/[\r\n\t]/g, ' ') + ";__p.push('";
+ })
+ .replace(/\r/g, '\\r')
+ .replace(/\n/g, '\\n')
+ .replace(/\t/g, '\\t')
+ + "');}return __p.join('');";
+ var func = new Function('obj', '_', tmpl);
+ if (data) return func(data, _);
+ return function(data) {
+ return func.call(this, data, _);
+ };
+ };
+
+ // Add a "chain" function, which will delegate to the wrapper.
+ _.chain = function(obj) {
+ return _(obj).chain();
+ };
+
+ // The OOP Wrapper
+ // ---------------
+
+ // If Underscore is called as a function, it returns a wrapped object that
+ // can be used OO-style. This wrapper holds altered versions of all the
+ // underscore functions. Wrapped objects may be chained.
+ var wrapper = function(obj) { this._wrapped = obj; };
+
+ // Expose `wrapper.prototype` as `_.prototype`
+ _.prototype = wrapper.prototype;
+
+ // Helper function to continue chaining intermediate results.
+ var result = function(obj, chain) {
+ return chain ? _(obj).chain() : obj;
+ };
+
+ // A method to easily add functions to the OOP wrapper.
+ var addToWrapper = function(name, func) {
+ wrapper.prototype[name] = function() {
+ var args = slice.call(arguments);
+ unshift.call(args, this._wrapped);
+ return result(func.apply(_, args), this._chain);
+ };
+ };
+
+ // Add all of the Underscore functions to the wrapper object.
+ _.mixin(_);
+
+ // Add all mutator Array functions to the wrapper.
+ each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
+ var method = ArrayProto[name];
+ wrapper.prototype[name] = function() {
+ var wrapped = this._wrapped;
+ method.apply(wrapped, arguments);
+ var length = wrapped.length;
+ if ((name == 'shift' || name == 'splice') && length === 0) delete wrapped[0];
+ return result(wrapped, this._chain);
+ };
+ });
+
+ // Add all accessor Array functions to the wrapper.
+ each(['concat', 'join', 'slice'], function(name) {
+ var method = ArrayProto[name];
+ wrapper.prototype[name] = function() {
+ return result(method.apply(this._wrapped, arguments), this._chain);
+ };
+ });
+
+ // Start chaining a wrapped Underscore object.
+ wrapper.prototype.chain = function() {
+ this._chain = true;
+ return this;
+ };
+
+ // Extracts the result from a wrapped and chained object.
+ wrapper.prototype.value = function() {
+ return this._wrapped;
+ };
+
+}).call(this);
diff --git a/doc/html/_static/underscore.js b/doc/html/_static/underscore.js
new file mode 100644
index 0000000..5b55f32
--- /dev/null
+++ b/doc/html/_static/underscore.js
@@ -0,0 +1,31 @@
+// Underscore.js 1.3.1
+// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
+// Underscore is freely distributable under the MIT license.
+// Portions of Underscore are inspired or borrowed from Prototype,
+// Oliver Steele's Functional, and John Resig's Micro-Templating.
+// For all details and documentation:
+// http://documentcloud.github.com/underscore
+(function(){function q(a,c,d){if(a===c)return a!==0||1/a==1/c;if(a==null||c==null)return a===c;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return false;switch(e){case "[object String]":return a==String(c);case "[object Number]":return a!=+a?c!=+c:a==0?1/a==1/c:a==+c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source==
+c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if(typeof a!="object"||typeof c!="object")return false;for(var f=d.length;f--;)if(d[f]==a)return true;d.push(a);var f=0,g=true;if(e=="[object Array]"){if(f=a.length,g=f==c.length)for(;f--;)if(!(g=f in a==f in c&&q(a[f],c[f],d)))break}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return false;for(var h in a)if(b.has(a,h)&&(f++,!(g=b.has(c,h)&&q(a[h],c[h],d))))break;if(g){for(h in c)if(b.has(c,
+h)&&!f--)break;g=!f}}d.pop();return g}var r=this,G=r._,n={},k=Array.prototype,o=Object.prototype,i=k.slice,H=k.unshift,l=o.toString,I=o.hasOwnProperty,w=k.forEach,x=k.map,y=k.reduce,z=k.reduceRight,A=k.filter,B=k.every,C=k.some,p=k.indexOf,D=k.lastIndexOf,o=Array.isArray,J=Object.keys,s=Function.prototype.bind,b=function(a){return new m(a)};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports)exports=module.exports=b;exports._=b}else r._=b;b.VERSION="1.3.1";var j=b.each=
+b.forEach=function(a,c,d){if(a!=null)if(w&&a.forEach===w)a.forEach(c,d);else if(a.length===+a.length)for(var e=0,f=a.length;e<f;e++){if(e in a&&c.call(d,a[e],e,a)===n)break}else for(e in a)if(b.has(a,e)&&c.call(d,a[e],e,a)===n)break};b.map=b.collect=function(a,c,b){var e=[];if(a==null)return e;if(x&&a.map===x)return a.map(c,b);j(a,function(a,g,h){e[e.length]=c.call(b,a,g,h)});if(a.length===+a.length)e.length=a.length;return e};b.reduce=b.foldl=b.inject=function(a,c,d,e){var f=arguments.length>2;a==
+null&&(a=[]);if(y&&a.reduce===y)return e&&(c=b.bind(c,e)),f?a.reduce(c,d):a.reduce(c);j(a,function(a,b,i){f?d=c.call(e,d,a,b,i):(d=a,f=true)});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(z&&a.reduceRight===z)return e&&(c=b.bind(c,e)),f?a.reduceRight(c,d):a.reduceRight(c);var g=b.toArray(a).reverse();e&&!f&&(c=b.bind(c,e));return f?b.reduce(g,c,d,e):b.reduce(g,c)};b.find=b.detect=
+function(a,c,b){var e;E(a,function(a,g,h){if(c.call(b,a,g,h))return e=a,true});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(A&&a.filter===A)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(B&&a.every===B)return a.every(c,b);j(a,function(a,g,h){if(!(e=
+e&&c.call(b,a,g,h)))return n});return e};var E=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=false;if(a==null)return e;if(C&&a.some===C)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return n});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;return p&&a.indexOf===p?a.indexOf(c)!=-1:b=E(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,function(a){return(b.isFunction(c)?c||a:a[c]).apply(a,d)})};b.pluck=
+function(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b<e.computed&&(e={value:a,computed:b})});
+return e.value};b.shuffle=function(a){var b=[],d;j(a,function(a,f){f==0?b[0]=a:(d=Math.floor(Math.random()*(f+1)),b[f]=b[d],b[d]=a)});return b};b.sortBy=function(a,c,d){return b.pluck(b.map(a,function(a,b,g){return{value:a,criteria:c.call(d,a,b,g)}}).sort(function(a,b){var c=a.criteria,d=b.criteria;return c<d?-1:c>d?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};j(a,function(a,b){var c=e(a,b);(d[c]||(d[c]=[])).push(a)});return d};b.sortedIndex=function(a,
+c,d){d||(d=b.identity);for(var e=0,f=a.length;e<f;){var g=e+f>>1;d(a[g])<d(c)?e=g+1:f=g}return e};b.toArray=function(a){return!a?[]:a.toArray?a.toArray():b.isArray(a)?i.call(a):b.isArguments(a)?i.call(a):b.values(a)};b.size=function(a){return b.toArray(a).length};b.first=b.head=function(a,b,d){return b!=null&&!d?i.call(a,0,b):a[0]};b.initial=function(a,b,d){return i.call(a,0,a.length-(b==null||d?1:b))};b.last=function(a,b,d){return b!=null&&!d?i.call(a,Math.max(a.length-b,0)):a[a.length-1]};b.rest=
+b.tail=function(a,b,d){return i.call(a,b==null||d?1:b)};b.compact=function(a){return b.filter(a,function(a){return!!a})};b.flatten=function(a,c){return b.reduce(a,function(a,e){if(b.isArray(e))return a.concat(c?e:b.flatten(e));a[a.length]=e;return a},[])};b.without=function(a){return b.difference(a,i.call(arguments,1))};b.uniq=b.unique=function(a,c,d){var d=d?b.map(a,d):a,e=[];b.reduce(d,function(d,g,h){if(0==h||(c===true?b.last(d)!=g:!b.include(d,g)))d[d.length]=g,e[e.length]=a[h];return d},[]);
+return e};b.union=function(){return b.uniq(b.flatten(arguments,true))};b.intersection=b.intersect=function(a){var c=i.call(arguments,1);return b.filter(b.uniq(a),function(a){return b.every(c,function(c){return b.indexOf(c,a)>=0})})};b.difference=function(a){var c=b.flatten(i.call(arguments,1));return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e<c;e++)d[e]=b.pluck(a,""+e);return d};b.indexOf=function(a,c,
+d){if(a==null)return-1;var e;if(d)return d=b.sortedIndex(a,c),a[d]===c?d:-1;if(p&&a.indexOf===p)return a.indexOf(c);for(d=0,e=a.length;d<e;d++)if(d in a&&a[d]===c)return d;return-1};b.lastIndexOf=function(a,b){if(a==null)return-1;if(D&&a.lastIndexOf===D)return a.lastIndexOf(b);for(var d=a.length;d--;)if(d in a&&a[d]===b)return d;return-1};b.range=function(a,b,d){arguments.length<=1&&(b=a||0,a=0);for(var d=arguments[2]||1,e=Math.max(Math.ceil((b-a)/d),0),f=0,g=Array(e);f<e;)g[f++]=a,a+=d;return g};
+var F=function(){};b.bind=function(a,c){var d,e;if(a.bind===s&&s)return s.apply(a,i.call(arguments,1));if(!b.isFunction(a))throw new TypeError;e=i.call(arguments,2);return d=function(){if(!(this instanceof d))return a.apply(c,e.concat(i.call(arguments)));F.prototype=a.prototype;var b=new F,g=a.apply(b,e.concat(i.call(arguments)));return Object(g)===g?g:b}};b.bindAll=function(a){var c=i.call(arguments,1);c.length==0&&(c=b.functions(a));j(c,function(c){a[c]=b.bind(a[c],a)});return a};b.memoize=function(a,
+c){var d={};c||(c=b.identity);return function(){var e=c.apply(this,arguments);return b.has(d,e)?d[e]:d[e]=a.apply(this,arguments)}};b.delay=function(a,b){var d=i.call(arguments,2);return setTimeout(function(){return a.apply(a,d)},b)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(i.call(arguments,1)))};b.throttle=function(a,c){var d,e,f,g,h,i=b.debounce(function(){h=g=false},c);return function(){d=this;e=arguments;var b;f||(f=setTimeout(function(){f=null;h&&a.apply(d,e);i()},c));g?h=true:
+a.apply(d,e);i();g=true}};b.debounce=function(a,b){var d;return function(){var e=this,f=arguments;clearTimeout(d);d=setTimeout(function(){d=null;a.apply(e,f)},b)}};b.once=function(a){var b=false,d;return function(){if(b)return d;b=true;return d=a.apply(this,arguments)}};b.wrap=function(a,b){return function(){var d=[a].concat(i.call(arguments,0));return b.apply(this,d)}};b.compose=function(){var a=arguments;return function(){for(var b=arguments,d=a.length-1;d>=0;d--)b=[a[d].apply(this,b)];return b[0]}};
+b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=J||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var c=[],d;for(d in a)b.has(a,d)&&(c[c.length]=d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]=b[d]});return a};b.defaults=function(a){j(i.call(arguments,
+1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return q(a,b,[])};b.isEmpty=function(a){if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(b.has(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=o||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)};
+b.isArguments=function(a){return l.call(a)=="[object Arguments]"};if(!b.isArguments(arguments))b.isArguments=function(a){return!(!a||!b.has(a,"callee"))};b.isFunction=function(a){return l.call(a)=="[object Function]"};b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isDate=function(a){return l.call(a)=="[object Date]"};
+b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.has=function(a,b){return I.call(a,b)};b.noConflict=function(){r._=G;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e<a;e++)b.call(d,e)};b.escape=function(a){return(""+a).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#x27;").replace(/\//g,"&#x2F;")};b.mixin=function(a){j(b.functions(a),
+function(c){K(c,b[c]=a[c])})};var L=0;b.uniqueId=function(a){var b=L++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var t=/.^/,u=function(a){return a.replace(/\\\\/g,"\\").replace(/\\'/g,"'")};b.template=function(a,c){var d=b.templateSettings,d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.escape||t,function(a,b){return"',_.escape("+
+u(b)+"),'"}).replace(d.interpolate||t,function(a,b){return"',"+u(b)+",'"}).replace(d.evaluate||t,function(a,b){return"');"+u(b).replace(/[\r\n\t]/g," ")+";__p.push('"}).replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');",e=new Function("obj","_",d);return c?e(c,b):function(a){return e.call(this,a,b)}};b.chain=function(a){return b(a).chain()};var m=function(a){this._wrapped=a};b.prototype=m.prototype;var v=function(a,c){return c?b(a).chain():a},K=function(a,c){m.prototype[a]=
+function(){var a=i.call(arguments);H.call(a,this._wrapped);return v(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];m.prototype[a]=function(){var d=this._wrapped;b.apply(d,arguments);var e=d.length;(a=="shift"||a=="splice")&&e===0&&delete d[0];return v(d,this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];m.prototype[a]=function(){return v(b.apply(this._wrapped,arguments),this._chain)}});m.prototype.chain=function(){this._chain=
+true;return this};m.prototype.value=function(){return this._wrapped}}).call(this);
diff --git a/doc/html/_static/up-pressed.png b/doc/html/_static/up-pressed.png
new file mode 100644
index 0000000..acee3b6
--- /dev/null
+++ b/doc/html/_static/up-pressed.png
Binary files differ
diff --git a/doc/html/_static/up.png b/doc/html/_static/up.png
new file mode 100644
index 0000000..2a940a7
--- /dev/null
+++ b/doc/html/_static/up.png
Binary files differ
diff --git a/doc/html/_static/websupport.js b/doc/html/_static/websupport.js
new file mode 100644
index 0000000..3b4999e
--- /dev/null
+++ b/doc/html/_static/websupport.js
@@ -0,0 +1,808 @@
+/*
+ * websupport.js
+ * ~~~~~~~~~~~~~
+ *
+ * sphinx.websupport utilities for all documentation.
+ *
+ * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+(function($) {
+ $.fn.autogrow = function() {
+ return this.each(function() {
+ var textarea = this;
+
+ $.fn.autogrow.resize(textarea);
+
+ $(textarea)
+ .focus(function() {
+ textarea.interval = setInterval(function() {
+ $.fn.autogrow.resize(textarea);
+ }, 500);
+ })
+ .blur(function() {
+ clearInterval(textarea.interval);
+ });
+ });
+ };
+
+ $.fn.autogrow.resize = function(textarea) {
+ var lineHeight = parseInt($(textarea).css('line-height'), 10);
+ var lines = textarea.value.split('\n');
+ var columns = textarea.cols;
+ var lineCount = 0;
+ $.each(lines, function() {
+ lineCount += Math.ceil(this.length / columns) || 1;
+ });
+ var height = lineHeight * (lineCount + 1);
+ $(textarea).css('height', height);
+ };
+})(jQuery);
+
+(function($) {
+ var comp, by;
+
+ function init() {
+ initEvents();
+ initComparator();
+ }
+
+ function initEvents() {
+ $(document).on("click", 'a.comment-close', function(event) {
+ event.preventDefault();
+ hide($(this).attr('id').substring(2));
+ });
+ $(document).on("click", 'a.vote', function(event) {
+ event.preventDefault();
+ handleVote($(this));
+ });
+ $(document).on("click", 'a.reply', function(event) {
+ event.preventDefault();
+ openReply($(this).attr('id').substring(2));
+ });
+ $(document).on("click", 'a.close-reply', function(event) {
+ event.preventDefault();
+ closeReply($(this).attr('id').substring(2));
+ });
+ $(document).on("click", 'a.sort-option', function(event) {
+ event.preventDefault();
+ handleReSort($(this));
+ });
+ $(document).on("click", 'a.show-proposal', function(event) {
+ event.preventDefault();
+ showProposal($(this).attr('id').substring(2));
+ });
+ $(document).on("click", 'a.hide-proposal', function(event) {
+ event.preventDefault();
+ hideProposal($(this).attr('id').substring(2));
+ });
+ $(document).on("click", 'a.show-propose-change', function(event) {
+ event.preventDefault();
+ showProposeChange($(this).attr('id').substring(2));
+ });
+ $(document).on("click", 'a.hide-propose-change', function(event) {
+ event.preventDefault();
+ hideProposeChange($(this).attr('id').substring(2));
+ });
+ $(document).on("click", 'a.accept-comment', function(event) {
+ event.preventDefault();
+ acceptComment($(this).attr('id').substring(2));
+ });
+ $(document).on("click", 'a.delete-comment', function(event) {
+ event.preventDefault();
+ deleteComment($(this).attr('id').substring(2));
+ });
+ $(document).on("click", 'a.comment-markup', function(event) {
+ event.preventDefault();
+ toggleCommentMarkupBox($(this).attr('id').substring(2));
+ });
+ }
+
+ /**
+ * Set comp, which is a comparator function used for sorting and
+ * inserting comments into the list.
+ */
+ function setComparator() {
+ // If the first three letters are "asc", sort in ascending order
+ // and remove the prefix.
+ if (by.substring(0,3) == 'asc') {
+ var i = by.substring(3);
+ comp = function(a, b) { return a[i] - b[i]; };
+ } else {
+ // Otherwise sort in descending order.
+ comp = function(a, b) { return b[by] - a[by]; };
+ }
+
+ // Reset link styles and format the selected sort option.
+ $('a.sel').attr('href', '#').removeClass('sel');
+ $('a.by' + by).removeAttr('href').addClass('sel');
+ }
+
+ /**
+ * Create a comp function. If the user has preferences stored in
+ * the sortBy cookie, use those, otherwise use the default.
+ */
+ function initComparator() {
+ by = 'rating'; // Default to sort by rating.
+ // If the sortBy cookie is set, use that instead.
+ if (document.cookie.length > 0) {
+ var start = document.cookie.indexOf('sortBy=');
+ if (start != -1) {
+ start = start + 7;
+ var end = document.cookie.indexOf(";", start);
+ if (end == -1) {
+ end = document.cookie.length;
+ by = unescape(document.cookie.substring(start, end));
+ }
+ }
+ }
+ setComparator();
+ }
+
+ /**
+ * Show a comment div.
+ */
+ function show(id) {
+ $('#ao' + id).hide();
+ $('#ah' + id).show();
+ var context = $.extend({id: id}, opts);
+ var popup = $(renderTemplate(popupTemplate, context)).hide();
+ popup.find('textarea[name="proposal"]').hide();
+ popup.find('a.by' + by).addClass('sel');
+ var form = popup.find('#cf' + id);
+ form.submit(function(event) {
+ event.preventDefault();
+ addComment(form);
+ });
+ $('#s' + id).after(popup);
+ popup.slideDown('fast', function() {
+ getComments(id);
+ });
+ }
+
+ /**
+ * Hide a comment div.
+ */
+ function hide(id) {
+ $('#ah' + id).hide();
+ $('#ao' + id).show();
+ var div = $('#sc' + id);
+ div.slideUp('fast', function() {
+ div.remove();
+ });
+ }
+
+ /**
+ * Perform an ajax request to get comments for a node
+ * and insert the comments into the comments tree.
+ */
+ function getComments(id) {
+ $.ajax({
+ type: 'GET',
+ url: opts.getCommentsURL,
+ data: {node: id},
+ success: function(data, textStatus, request) {
+ var ul = $('#cl' + id);
+ var speed = 100;
+ $('#cf' + id)
+ .find('textarea[name="proposal"]')
+ .data('source', data.source);
+
+ if (data.comments.length === 0) {
+ ul.html('<li>No comments yet.</li>');
+ ul.data('empty', true);
+ } else {
+ // If there are comments, sort them and put them in the list.
+ var comments = sortComments(data.comments);
+ speed = data.comments.length * 100;
+ appendComments(comments, ul);
+ ul.data('empty', false);
+ }
+ $('#cn' + id).slideUp(speed + 200);
+ ul.slideDown(speed);
+ },
+ error: function(request, textStatus, error) {
+ showError('Oops, there was a problem retrieving the comments.');
+ },
+ dataType: 'json'
+ });
+ }
+
+ /**
+ * Add a comment via ajax and insert the comment into the comment tree.
+ */
+ function addComment(form) {
+ var node_id = form.find('input[name="node"]').val();
+ var parent_id = form.find('input[name="parent"]').val();
+ var text = form.find('textarea[name="comment"]').val();
+ var proposal = form.find('textarea[name="proposal"]').val();
+
+ if (text == '') {
+ showError('Please enter a comment.');
+ return;
+ }
+
+ // Disable the form that is being submitted.
+ form.find('textarea,input').attr('disabled', 'disabled');
+
+ // Send the comment to the server.
+ $.ajax({
+ type: "POST",
+ url: opts.addCommentURL,
+ dataType: 'json',
+ data: {
+ node: node_id,
+ parent: parent_id,
+ text: text,
+ proposal: proposal
+ },
+ success: function(data, textStatus, error) {
+ // Reset the form.
+ if (node_id) {
+ hideProposeChange(node_id);
+ }
+ form.find('textarea')
+ .val('')
+ .add(form.find('input'))
+ .removeAttr('disabled');
+ var ul = $('#cl' + (node_id || parent_id));
+ if (ul.data('empty')) {
+ $(ul).empty();
+ ul.data('empty', false);
+ }
+ insertComment(data.comment);
+ var ao = $('#ao' + node_id);
+ ao.find('img').attr({'src': opts.commentBrightImage});
+ if (node_id) {
+ // if this was a "root" comment, remove the commenting box
+ // (the user can get it back by reopening the comment popup)
+ $('#ca' + node_id).slideUp();
+ }
+ },
+ error: function(request, textStatus, error) {
+ form.find('textarea,input').removeAttr('disabled');
+ showError('Oops, there was a problem adding the comment.');
+ }
+ });
+ }
+
+ /**
+ * Recursively append comments to the main comment list and children
+ * lists, creating the comment tree.
+ */
+ function appendComments(comments, ul) {
+ $.each(comments, function() {
+ var div = createCommentDiv(this);
+ ul.append($(document.createElement('li')).html(div));
+ appendComments(this.children, div.find('ul.comment-children'));
+ // To avoid stagnating data, don't store the comments children in data.
+ this.children = null;
+ div.data('comment', this);
+ });
+ }
+
+ /**
+ * After adding a new comment, it must be inserted in the correct
+ * location in the comment tree.
+ */
+ function insertComment(comment) {
+ var div = createCommentDiv(comment);
+
+ // To avoid stagnating data, don't store the comments children in data.
+ comment.children = null;
+ div.data('comment', comment);
+
+ var ul = $('#cl' + (comment.node || comment.parent));
+ var siblings = getChildren(ul);
+
+ var li = $(document.createElement('li'));
+ li.hide();
+
+ // Determine where in the parents children list to insert this comment.
+ for(var i=0; i < siblings.length; i++) {
+ if (comp(comment, siblings[i]) <= 0) {
+ $('#cd' + siblings[i].id)
+ .parent()
+ .before(li.html(div));
+ li.slideDown('fast');
+ return;
+ }
+ }
+
+ // If we get here, this comment rates lower than all the others,
+ // or it is the only comment in the list.
+ ul.append(li.html(div));
+ li.slideDown('fast');
+ }
+
+ function acceptComment(id) {
+ $.ajax({
+ type: 'POST',
+ url: opts.acceptCommentURL,
+ data: {id: id},
+ success: function(data, textStatus, request) {
+ $('#cm' + id).fadeOut('fast');
+ $('#cd' + id).removeClass('moderate');
+ },
+ error: function(request, textStatus, error) {
+ showError('Oops, there was a problem accepting the comment.');
+ }
+ });
+ }
+
+ function deleteComment(id) {
+ $.ajax({
+ type: 'POST',
+ url: opts.deleteCommentURL,
+ data: {id: id},
+ success: function(data, textStatus, request) {
+ var div = $('#cd' + id);
+ if (data == 'delete') {
+ // Moderator mode: remove the comment and all children immediately
+ div.slideUp('fast', function() {
+ div.remove();
+ });
+ return;
+ }
+ // User mode: only mark the comment as deleted
+ div
+ .find('span.user-id:first')
+ .text('[deleted]').end()
+ .find('div.comment-text:first')
+ .text('[deleted]').end()
+ .find('#cm' + id + ', #dc' + id + ', #ac' + id + ', #rc' + id +
+ ', #sp' + id + ', #hp' + id + ', #cr' + id + ', #rl' + id)
+ .remove();
+ var comment = div.data('comment');
+ comment.username = '[deleted]';
+ comment.text = '[deleted]';
+ div.data('comment', comment);
+ },
+ error: function(request, textStatus, error) {
+ showError('Oops, there was a problem deleting the comment.');
+ }
+ });
+ }
+
+ function showProposal(id) {
+ $('#sp' + id).hide();
+ $('#hp' + id).show();
+ $('#pr' + id).slideDown('fast');
+ }
+
+ function hideProposal(id) {
+ $('#hp' + id).hide();
+ $('#sp' + id).show();
+ $('#pr' + id).slideUp('fast');
+ }
+
+ function showProposeChange(id) {
+ $('#pc' + id).hide();
+ $('#hc' + id).show();
+ var textarea = $('#pt' + id);
+ textarea.val(textarea.data('source'));
+ $.fn.autogrow.resize(textarea[0]);
+ textarea.slideDown('fast');
+ }
+
+ function hideProposeChange(id) {
+ $('#hc' + id).hide();
+ $('#pc' + id).show();
+ var textarea = $('#pt' + id);
+ textarea.val('').removeAttr('disabled');
+ textarea.slideUp('fast');
+ }
+
+ function toggleCommentMarkupBox(id) {
+ $('#mb' + id).toggle();
+ }
+
+ /** Handle when the user clicks on a sort by link. */
+ function handleReSort(link) {
+ var classes = link.attr('class').split(/\s+/);
+ for (var i=0; i<classes.length; i++) {
+ if (classes[i] != 'sort-option') {
+ by = classes[i].substring(2);
+ }
+ }
+ setComparator();
+ // Save/update the sortBy cookie.
+ var expiration = new Date();
+ expiration.setDate(expiration.getDate() + 365);
+ document.cookie= 'sortBy=' + escape(by) +
+ ';expires=' + expiration.toUTCString();
+ $('ul.comment-ul').each(function(index, ul) {
+ var comments = getChildren($(ul), true);
+ comments = sortComments(comments);
+ appendComments(comments, $(ul).empty());
+ });
+ }
+
+ /**
+ * Function to process a vote when a user clicks an arrow.
+ */
+ function handleVote(link) {
+ if (!opts.voting) {
+ showError("You'll need to login to vote.");
+ return;
+ }
+
+ var id = link.attr('id');
+ if (!id) {
+ // Didn't click on one of the voting arrows.
+ return;
+ }
+ // If it is an unvote, the new vote value is 0,
+ // Otherwise it's 1 for an upvote, or -1 for a downvote.
+ var value = 0;
+ if (id.charAt(1) != 'u') {
+ value = id.charAt(0) == 'u' ? 1 : -1;
+ }
+ // The data to be sent to the server.
+ var d = {
+ comment_id: id.substring(2),
+ value: value
+ };
+
+ // Swap the vote and unvote links.
+ link.hide();
+ $('#' + id.charAt(0) + (id.charAt(1) == 'u' ? 'v' : 'u') + d.comment_id)
+ .show();
+
+ // The div the comment is displayed in.
+ var div = $('div#cd' + d.comment_id);
+ var data = div.data('comment');
+
+ // If this is not an unvote, and the other vote arrow has
+ // already been pressed, unpress it.
+ if ((d.value !== 0) && (data.vote === d.value * -1)) {
+ $('#' + (d.value == 1 ? 'd' : 'u') + 'u' + d.comment_id).hide();
+ $('#' + (d.value == 1 ? 'd' : 'u') + 'v' + d.comment_id).show();
+ }
+
+ // Update the comments rating in the local data.
+ data.rating += (data.vote === 0) ? d.value : (d.value - data.vote);
+ data.vote = d.value;
+ div.data('comment', data);
+
+ // Change the rating text.
+ div.find('.rating:first')
+ .text(data.rating + ' point' + (data.rating == 1 ? '' : 's'));
+
+ // Send the vote information to the server.
+ $.ajax({
+ type: "POST",
+ url: opts.processVoteURL,
+ data: d,
+ error: function(request, textStatus, error) {
+ showError('Oops, there was a problem casting that vote.');
+ }
+ });
+ }
+
+ /**
+ * Open a reply form used to reply to an existing comment.
+ */
+ function openReply(id) {
+ // Swap out the reply link for the hide link
+ $('#rl' + id).hide();
+ $('#cr' + id).show();
+
+ // Add the reply li to the children ul.
+ var div = $(renderTemplate(replyTemplate, {id: id})).hide();
+ $('#cl' + id)
+ .prepend(div)
+ // Setup the submit handler for the reply form.
+ .find('#rf' + id)
+ .submit(function(event) {
+ event.preventDefault();
+ addComment($('#rf' + id));
+ closeReply(id);
+ })
+ .find('input[type=button]')
+ .click(function() {
+ closeReply(id);
+ });
+ div.slideDown('fast', function() {
+ $('#rf' + id).find('textarea').focus();
+ });
+ }
+
+ /**
+ * Close the reply form opened with openReply.
+ */
+ function closeReply(id) {
+ // Remove the reply div from the DOM.
+ $('#rd' + id).slideUp('fast', function() {
+ $(this).remove();
+ });
+
+ // Swap out the hide link for the reply link
+ $('#cr' + id).hide();
+ $('#rl' + id).show();
+ }
+
+ /**
+ * Recursively sort a tree of comments using the comp comparator.
+ */
+ function sortComments(comments) {
+ comments.sort(comp);
+ $.each(comments, function() {
+ this.children = sortComments(this.children);
+ });
+ return comments;
+ }
+
+ /**
+ * Get the children comments from a ul. If recursive is true,
+ * recursively include childrens' children.
+ */
+ function getChildren(ul, recursive) {
+ var children = [];
+ ul.children().children("[id^='cd']")
+ .each(function() {
+ var comment = $(this).data('comment');
+ if (recursive)
+ comment.children = getChildren($(this).find('#cl' + comment.id), true);
+ children.push(comment);
+ });
+ return children;
+ }
+
+ /** Create a div to display a comment in. */
+ function createCommentDiv(comment) {
+ if (!comment.displayed && !opts.moderator) {
+ return $('<div class="moderate">Thank you! Your comment will show up '
+ + 'once it is has been approved by a moderator.</div>');
+ }
+ // Prettify the comment rating.
+ comment.pretty_rating = comment.rating + ' point' +
+ (comment.rating == 1 ? '' : 's');
+ // Make a class (for displaying not yet moderated comments differently)
+ comment.css_class = comment.displayed ? '' : ' moderate';
+ // Create a div for this comment.
+ var context = $.extend({}, opts, comment);
+ var div = $(renderTemplate(commentTemplate, context));
+
+ // If the user has voted on this comment, highlight the correct arrow.
+ if (comment.vote) {
+ var direction = (comment.vote == 1) ? 'u' : 'd';
+ div.find('#' + direction + 'v' + comment.id).hide();
+ div.find('#' + direction + 'u' + comment.id).show();
+ }
+
+ if (opts.moderator || comment.text != '[deleted]') {
+ div.find('a.reply').show();
+ if (comment.proposal_diff)
+ div.find('#sp' + comment.id).show();
+ if (opts.moderator && !comment.displayed)
+ div.find('#cm' + comment.id).show();
+ if (opts.moderator || (opts.username == comment.username))
+ div.find('#dc' + comment.id).show();
+ }
+ return div;
+ }
+
+ /**
+ * A simple template renderer. Placeholders such as <%id%> are replaced
+ * by context['id'] with items being escaped. Placeholders such as <#id#>
+ * are not escaped.
+ */
+ function renderTemplate(template, context) {
+ var esc = $(document.createElement('div'));
+
+ function handle(ph, escape) {
+ var cur = context;
+ $.each(ph.split('.'), function() {
+ cur = cur[this];
+ });
+ return escape ? esc.text(cur || "").html() : cur;
+ }
+
+ return template.replace(/<([%#])([\w\.]*)\1>/g, function() {
+ return handle(arguments[2], arguments[1] == '%' ? true : false);
+ });
+ }
+
+ /** Flash an error message briefly. */
+ function showError(message) {
+ $(document.createElement('div')).attr({'class': 'popup-error'})
+ .append($(document.createElement('div'))
+ .attr({'class': 'error-message'}).text(message))
+ .appendTo('body')
+ .fadeIn("slow")
+ .delay(2000)
+ .fadeOut("slow");
+ }
+
+ /** Add a link the user uses to open the comments popup. */
+ $.fn.comment = function() {
+ return this.each(function() {
+ var id = $(this).attr('id').substring(1);
+ var count = COMMENT_METADATA[id];
+ var title = count + ' comment' + (count == 1 ? '' : 's');
+ var image = count > 0 ? opts.commentBrightImage : opts.commentImage;
+ var addcls = count == 0 ? ' nocomment' : '';
+ $(this)
+ .append(
+ $(document.createElement('a')).attr({
+ href: '#',
+ 'class': 'sphinx-comment-open' + addcls,
+ id: 'ao' + id
+ })
+ .append($(document.createElement('img')).attr({
+ src: image,
+ alt: 'comment',
+ title: title
+ }))
+ .click(function(event) {
+ event.preventDefault();
+ show($(this).attr('id').substring(2));
+ })
+ )
+ .append(
+ $(document.createElement('a')).attr({
+ href: '#',
+ 'class': 'sphinx-comment-close hidden',
+ id: 'ah' + id
+ })
+ .append($(document.createElement('img')).attr({
+ src: opts.closeCommentImage,
+ alt: 'close',
+ title: 'close'
+ }))
+ .click(function(event) {
+ event.preventDefault();
+ hide($(this).attr('id').substring(2));
+ })
+ );
+ });
+ };
+
+ var opts = {
+ processVoteURL: '/_process_vote',
+ addCommentURL: '/_add_comment',
+ getCommentsURL: '/_get_comments',
+ acceptCommentURL: '/_accept_comment',
+ deleteCommentURL: '/_delete_comment',
+ commentImage: '/static/_static/comment.png',
+ closeCommentImage: '/static/_static/comment-close.png',
+ loadingImage: '/static/_static/ajax-loader.gif',
+ commentBrightImage: '/static/_static/comment-bright.png',
+ upArrow: '/static/_static/up.png',
+ downArrow: '/static/_static/down.png',
+ upArrowPressed: '/static/_static/up-pressed.png',
+ downArrowPressed: '/static/_static/down-pressed.png',
+ voting: false,
+ moderator: false
+ };
+
+ if (typeof COMMENT_OPTIONS != "undefined") {
+ opts = jQuery.extend(opts, COMMENT_OPTIONS);
+ }
+
+ var popupTemplate = '\
+ <div class="sphinx-comments" id="sc<%id%>">\
+ <p class="sort-options">\
+ Sort by:\
+ <a href="#" class="sort-option byrating">best rated</a>\
+ <a href="#" class="sort-option byascage">newest</a>\
+ <a href="#" class="sort-option byage">oldest</a>\
+ </p>\
+ <div class="comment-header">Comments</div>\
+ <div class="comment-loading" id="cn<%id%>">\
+ loading comments... <img src="<%loadingImage%>" alt="" /></div>\
+ <ul id="cl<%id%>" class="comment-ul"></ul>\
+ <div id="ca<%id%>">\
+ <p class="add-a-comment">Add a comment\
+ (<a href="#" class="comment-markup" id="ab<%id%>">markup</a>):</p>\
+ <div class="comment-markup-box" id="mb<%id%>">\
+ reStructured text markup: <i>*emph*</i>, <b>**strong**</b>, \
+ <code>``code``</code>, \
+ code blocks: <code>::</code> and an indented block after blank line</div>\
+ <form method="post" id="cf<%id%>" class="comment-form" action="">\
+ <textarea name="comment" cols="80"></textarea>\
+ <p class="propose-button">\
+ <a href="#" id="pc<%id%>" class="show-propose-change">\
+ Propose a change &#9657;\
+ </a>\
+ <a href="#" id="hc<%id%>" class="hide-propose-change">\
+ Propose a change &#9663;\
+ </a>\
+ </p>\
+ <textarea name="proposal" id="pt<%id%>" cols="80"\
+ spellcheck="false"></textarea>\
+ <input type="submit" value="Add comment" />\
+ <input type="hidden" name="node" value="<%id%>" />\
+ <input type="hidden" name="parent" value="" />\
+ </form>\
+ </div>\
+ </div>';
+
+ var commentTemplate = '\
+ <div id="cd<%id%>" class="sphinx-comment<%css_class%>">\
+ <div class="vote">\
+ <div class="arrow">\
+ <a href="#" id="uv<%id%>" class="vote" title="vote up">\
+ <img src="<%upArrow%>" />\
+ </a>\
+ <a href="#" id="uu<%id%>" class="un vote" title="vote up">\
+ <img src="<%upArrowPressed%>" />\
+ </a>\
+ </div>\
+ <div class="arrow">\
+ <a href="#" id="dv<%id%>" class="vote" title="vote down">\
+ <img src="<%downArrow%>" id="da<%id%>" />\
+ </a>\
+ <a href="#" id="du<%id%>" class="un vote" title="vote down">\
+ <img src="<%downArrowPressed%>" />\
+ </a>\
+ </div>\
+ </div>\
+ <div class="comment-content">\
+ <p class="tagline comment">\
+ <span class="user-id"><%username%></span>\
+ <span class="rating"><%pretty_rating%></span>\
+ <span class="delta"><%time.delta%></span>\
+ </p>\
+ <div class="comment-text comment"><#text#></div>\
+ <p class="comment-opts comment">\
+ <a href="#" class="reply hidden" id="rl<%id%>">reply &#9657;</a>\
+ <a href="#" class="close-reply" id="cr<%id%>">reply &#9663;</a>\
+ <a href="#" id="sp<%id%>" class="show-proposal">proposal &#9657;</a>\
+ <a href="#" id="hp<%id%>" class="hide-proposal">proposal &#9663;</a>\
+ <a href="#" id="dc<%id%>" class="delete-comment hidden">delete</a>\
+ <span id="cm<%id%>" class="moderation hidden">\
+ <a href="#" id="ac<%id%>" class="accept-comment">accept</a>\
+ </span>\
+ </p>\
+ <pre class="proposal" id="pr<%id%>">\
+<#proposal_diff#>\
+ </pre>\
+ <ul class="comment-children" id="cl<%id%>"></ul>\
+ </div>\
+ <div class="clearleft"></div>\
+ </div>\
+ </div>';
+
+ var replyTemplate = '\
+ <li>\
+ <div class="reply-div" id="rd<%id%>">\
+ <form id="rf<%id%>">\
+ <textarea name="comment" cols="80"></textarea>\
+ <input type="submit" value="Add reply" />\
+ <input type="button" value="Cancel" />\
+ <input type="hidden" name="parent" value="<%id%>" />\
+ <input type="hidden" name="node" value="" />\
+ </form>\
+ </div>\
+ </li>';
+
+ $(document).ready(function() {
+ init();
+ });
+})(jQuery);
+
+$(document).ready(function() {
+ // add comment anchors for all paragraphs that are commentable
+ $('.sphinx-has-comment').comment();
+
+ // highlight search words in search results
+ $("div.context").each(function() {
+ var params = $.getQueryParameters();
+ var terms = (params.q) ? params.q[0].split(/\s+/) : [];
+ var result = $(this);
+ $.each(terms, function() {
+ result.highlightText(this.toLowerCase(), 'highlighted');
+ });
+ });
+
+ // directly open comment window if requested
+ var anchor = document.location.hash;
+ if (anchor.substring(0, 9) == '#comment-') {
+ $('#ao' + anchor.substring(9)).click();
+ document.location.hash = '#s' + anchor.substring(9);
+ }
+});
diff --git a/doc/html/genindex.html b/doc/html/genindex.html
new file mode 100644
index 0000000..9cd9ca4
--- /dev/null
+++ b/doc/html/genindex.html
@@ -0,0 +1,1731 @@
+
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>Index &#8212; M2Crypto documentation</title>
+ <link rel="stylesheet" href="_static/alabaster.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <script type="text/javascript" src="_static/language_data.js"></script>
+ <link rel="index" title="Index" href="#" />
+ <link rel="search" title="Search" href="search.html" />
+
+ <link rel="stylesheet" href="_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+
+<h1 id="index">Index</h1>
+
+<div class="genindex-jumpbox">
+ <a href="#A"><strong>A</strong></a>
+ | <a href="#B"><strong>B</strong></a>
+ | <a href="#C"><strong>C</strong></a>
+ | <a href="#D"><strong>D</strong></a>
+ | <a href="#E"><strong>E</strong></a>
+ | <a href="#F"><strong>F</strong></a>
+ | <a href="#G"><strong>G</strong></a>
+ | <a href="#H"><strong>H</strong></a>
+ | <a href="#I"><strong>I</strong></a>
+ | <a href="#K"><strong>K</strong></a>
+ | <a href="#L"><strong>L</strong></a>
+ | <a href="#M"><strong>M</strong></a>
+ | <a href="#N"><strong>N</strong></a>
+ | <a href="#O"><strong>O</strong></a>
+ | <a href="#P"><strong>P</strong></a>
+ | <a href="#Q"><strong>Q</strong></a>
+ | <a href="#R"><strong>R</strong></a>
+ | <a href="#S"><strong>S</strong></a>
+ | <a href="#T"><strong>T</strong></a>
+ | <a href="#U"><strong>U</strong></a>
+ | <a href="#V"><strong>V</strong></a>
+ | <a href="#W"><strong>W</strong></a>
+ | <a href="#X"><strong>X</strong></a>
+
+</div>
+<h2 id="A">A</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+ <td style="width: 33%; vertical-align: top;"><ul>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.accept">accept() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.accept_ssl">accept_ssl() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509_Store.add_cert">add_cert() (M2Crypto.X509.X509_Store method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509_Name.add_entry_by_txt">add_entry_by_txt() (M2Crypto.X509.X509_Name method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509.add_ext">add_ext() (M2Crypto.X509.X509 method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.Request.add_extensions">add_extensions() (M2Crypto.X509.Request method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.add_session">add_session() (M2Crypto.SSL.Context.Context method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509_Store.add_x509">add_x509() (M2Crypto.X509.X509_Store method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EVP.PKey.as_der">as_der() (M2Crypto.EVP.PKey method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Session.Session.as_der">(M2Crypto.SSL.Session.Session method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.Request.as_der">(M2Crypto.X509.Request method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509.as_der">(M2Crypto.X509.X509 method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509_Name.as_der">(M2Crypto.X509.X509_Name method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509_Stack.as_der">(M2Crypto.X509.X509_Stack method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509_Name.as_hash">as_hash() (M2Crypto.X509.X509_Name method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EC.EC.as_pem">as_pem() (M2Crypto.EC.EC method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.EVP.PKey.as_pem">(M2Crypto.EVP.PKey method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.RSA.RSA.as_pem">(M2Crypto.RSA.RSA method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.Request.as_pem">(M2Crypto.X509.Request method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509.as_pem">(M2Crypto.X509.X509 method)</a>
+</li>
+ </ul></li>
+ </ul></td>
+ <td style="width: 33%; vertical-align: top;"><ul>
+ <li><a href="M2Crypto.html#M2Crypto.ASN1.ASN1_String.as_text">as_text() (M2Crypto.ASN1.ASN1_String method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Session.Session.as_text">(M2Crypto.SSL.Session.Session method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.CRL.as_text">(M2Crypto.X509.CRL method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.Request.as_text">(M2Crypto.X509.Request method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509.as_text">(M2Crypto.X509.X509 method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509_Name.as_text">(M2Crypto.X509.X509_Name method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.html#M2Crypto.ASN1.ASN1_Integer">ASN1_Integer (class in M2Crypto.ASN1)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.ASN1.ASN1_Object">ASN1_Object (class in M2Crypto.ASN1)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.ASN1.ASN1_String">ASN1_String (class in M2Crypto.ASN1)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.ASN1.ASN1_TIME">ASN1_TIME (class in M2Crypto.ASN1)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.ASN1.ASN1_UTCTIME">ASN1_UTCTIME (in module M2Crypto.ASN1)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EVP.PKey.assign_rsa">assign_rsa() (M2Crypto.EVP.PKey method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.ftpslib.FTP_TLS.auth_ssl">auth_ssl() (M2Crypto.ftpslib.FTP_TLS method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.ftpslib.FTP_TLS.auth_tls">auth_tls() (M2Crypto.ftpslib.FTP_TLS method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.AuthCookie.AuthCookie">AuthCookie (class in M2Crypto.AuthCookie)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.AuthCookie.AuthCookieJar">AuthCookieJar (class in M2Crypto.AuthCookie)</a>
+</li>
+ </ul></td>
+</tr></table>
+
+<h2 id="B">B</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+ <td style="width: 33%; vertical-align: top;"><ul>
+ <li><a href="M2Crypto.html#M2Crypto.util.bin_to_hex">bin_to_hex() (in module M2Crypto.util)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.bind">bind() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.BIO.BIO">BIO (class in M2Crypto.BIO)</a>
+</li>
+ </ul></td>
+ <td style="width: 33%; vertical-align: top;"><ul>
+ <li><a href="M2Crypto.html#M2Crypto.BIO.BIO.bio_ptr">bio_ptr() (M2Crypto.BIO.BIO method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.BIO.BIOError">BIOError</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.m2urllib2.build_opener">build_opener() (in module M2Crypto.m2urllib2)</a>
+</li>
+ </ul></td>
+</tr></table>
+
+<h2 id="C">C</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+ <td style="width: 33%; vertical-align: top;"><ul>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509.check_ca">check_ca() (M2Crypto.X509.X509 method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.DSA.DSA.check_key">check_key() (M2Crypto.DSA.DSA method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.DSA.DSA_pub.check_key">(M2Crypto.DSA.DSA_pub method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EC.EC.check_key">(M2Crypto.EC.EC method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.RSA.RSA.check_key">(M2Crypto.RSA.RSA method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.RSA.RSA_pub.check_key">(M2Crypto.RSA.RSA_pub method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.html#M2Crypto.DH.DH.check_params">check_params() (M2Crypto.DH.DH method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509.check_purpose">check_purpose() (M2Crypto.X509.X509 method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Checker.Checker">Checker (class in M2Crypto.SSL.Checker)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EVP.Cipher">Cipher (class in M2Crypto.EVP)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.SMIME.Cipher">(class in M2Crypto.SMIME)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Cipher.Cipher">(class in M2Crypto.SSL.Cipher)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Cipher.Cipher_Stack">Cipher_Stack (class in M2Crypto.SSL.Cipher)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.BIO.CipherStream">CipherStream (class in M2Crypto.BIO)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.Engine.cleanup">cleanup() (in module M2Crypto.Engine)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.threading.cleanup">(in module M2Crypto.threading)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.clear">clear() (M2Crypto.SSL.Connection.Connection method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper.clear">(M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.clientPostConnectionCheck">clientPostConnectionCheck (M2Crypto.SSL.Connection.Connection attribute)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.BIO.BIO.close">close() (M2Crypto.BIO.BIO method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.BIO.CipherStream.close">(M2Crypto.BIO.CipherStream method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.BIO.File.close">(M2Crypto.BIO.File method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.BIO.IOBuffer.close">(M2Crypto.BIO.IOBuffer method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.BIO.MemoryBuffer.close">(M2Crypto.BIO.MemoryBuffer method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.close">(M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.close">(M2Crypto.SSL.Context.Context method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.httpslib.HTTPSConnection.close">(M2Crypto.httpslib.HTTPSConnection method)</a>
+</li>
+ </ul></li>
+ </ul></td>
+ <td style="width: 33%; vertical-align: top;"><ul>
+ <li><a href="M2Crypto.html#M2Crypto.EC.EC.compute_dh_key">compute_dh_key() (M2Crypto.EC.EC method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.DH.DH.compute_key">compute_key() (M2Crypto.DH.DH method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.httpslib.HTTPSConnection.connect">connect() (M2Crypto.httpslib.HTTPSConnection method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.connect">(M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.ssl_dispatcher.ssl_dispatcher.connect">(M2Crypto.SSL.ssl_dispatcher.ssl_dispatcher method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.httpslib.ProxyHTTPSConnection.connect">(M2Crypto.httpslib.ProxyHTTPSConnection method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.connect_ssl">connect_ssl() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection">Connection (class in M2Crypto.SSL.Connection)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper.connectionLost">connectionLost() (M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper.connectionMade">connectionMade() (M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.TwistedProtocolWrapper.connectSSL">connectSSL() (in module M2Crypto.SSL.TwistedProtocolWrapper)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.TwistedProtocolWrapper.connectTCP">connectTCP() (in module M2Crypto.SSL.TwistedProtocolWrapper)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Context.Context">Context (class in M2Crypto.SSL.Context)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509_Name_Entry.create_by_txt">create_by_txt() (M2Crypto.X509.X509_Name_Entry method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.ssl_dispatcher.ssl_dispatcher.create_socket">create_socket() (M2Crypto.SSL.ssl_dispatcher.ssl_dispatcher method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.CRL">CRL (class in M2Crypto.X509)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.Engine.Engine.ctrl_cmd_string">ctrl_cmd_string() (M2Crypto.Engine.Engine method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Context.ctxmap">ctxmap() (in module M2Crypto.SSL.Context)</a>
+</li>
+ </ul></td>
+</tr></table>
+
+<h2 id="D">D</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+ <td style="width: 33%; vertical-align: top;"><ul>
+ <li><a href="M2Crypto.html#M2Crypto.AuthCookie.AuthCookie.data">data() (M2Crypto.AuthCookie.AuthCookie method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper.dataReceived">dataReceived() (M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.SMIME.SMIME.decrypt">decrypt() (M2Crypto.SMIME.SMIME method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.httpslib.HTTPSConnection.default_port">default_port (M2Crypto.httpslib.HTTPSConnection attribute)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.DH.DH">DH (class in M2Crypto.DH)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.DH.DHError">DHError</a>
+</li>
+ </ul></td>
+ <td style="width: 33%; vertical-align: top;"><ul>
+ <li><a href="M2Crypto.html#M2Crypto.EVP.HMAC.digest">digest() (M2Crypto.EVP.HMAC method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.EVP.MessageDigest.digest">(M2Crypto.EVP.MessageDigest method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.html#M2Crypto.BIO.SSLBio.do_handshake">do_handshake() (M2Crypto.BIO.SSLBio method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.DSA.DSA">DSA (class in M2Crypto.DSA)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.DSA.DSA_pub">DSA_pub (class in M2Crypto.DSA)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.DSA.DSAError">DSAError</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.ASN1.LocalTimezone.dst">dst() (M2Crypto.ASN1.LocalTimezone method)</a>
+</li>
+ </ul></td>
+</tr></table>
+
+<h2 id="E">E</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+ <td style="width: 33%; vertical-align: top;"><ul>
+ <li><a href="M2Crypto.html#M2Crypto.EC.EC">EC (class in M2Crypto.EC)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EC.ec_error">ec_error() (in module M2Crypto.EC)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EC.EC_pub">EC_pub (class in M2Crypto.EC)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EC.ECError">ECError</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.SMIME.SMIME.encrypt">encrypt() (M2Crypto.SMIME.SMIME method)</a>
+</li>
+ </ul></td>
+ <td style="width: 33%; vertical-align: top;"><ul>
+ <li><a href="M2Crypto.html#M2Crypto.httpslib.ProxyHTTPSConnection.endheaders">endheaders() (M2Crypto.httpslib.ProxyHTTPSConnection method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.Engine.Engine">Engine (class in M2Crypto.Engine)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.Engine.EngineError">EngineError</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509_Name.entry_count">entry_count() (M2Crypto.X509.X509_Name method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EVP.EVPError">EVPError</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.AuthCookie.AuthCookie.expiry">expiry() (M2Crypto.AuthCookie.AuthCookie method)</a>
+</li>
+ </ul></td>
+</tr></table>
+
+<h2 id="F">F</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+ <td style="width: 33%; vertical-align: top;"><ul>
+ <li><a href="M2Crypto.html#M2Crypto.BIO.File">File (class in M2Crypto.BIO)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.BIO.BIO.fileno">fileno() (M2Crypto.BIO.BIO method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.fileno">(M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.html#M2Crypto.EVP.Cipher.final">final() (M2Crypto.EVP.Cipher method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.EVP.HMAC.final">(M2Crypto.EVP.HMAC method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EVP.MessageDigest.final">(M2Crypto.EVP.MessageDigest method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EVP.PKey.final">(M2Crypto.EVP.PKey method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.RC4.RC4.final">(M2Crypto.RC4.RC4 method)</a>
+</li>
+ </ul></li>
+ </ul></td>
+ <td style="width: 33%; vertical-align: top;"><ul>
+ <li><a href="M2Crypto.html#M2Crypto.Engine.Engine.finish">finish() (M2Crypto.Engine.Engine method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.BIO.BIO.flush">flush() (M2Crypto.BIO.BIO method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.BIO.File.flush">(M2Crypto.BIO.File method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.SSLServer.ForkingSSLServer">ForkingSSLServer (class in M2Crypto.SSL.SSLServer)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.ftpslib.FTP_TLS">FTP_TLS (class in M2Crypto.ftpslib)</a>
+</li>
+ </ul></td>
+</tr></table>
+
+<h2 id="G">G</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+ <td style="width: 33%; vertical-align: top;"><ul>
+ <li><a href="M2Crypto.html#M2Crypto.RSA.gen_key">gen_key() (in module M2Crypto.RSA)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.DH.DH.gen_key">(M2Crypto.DH.DH method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.DSA.DSA.gen_key">(M2Crypto.DSA.DSA method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EC.EC.gen_key">(M2Crypto.EC.EC method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.html#M2Crypto.DH.gen_params">gen_params() (in module M2Crypto.DH)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.DSA.gen_params">(in module M2Crypto.DSA)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EC.gen_params">(in module M2Crypto.EC)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.html#M2Crypto.util.genparam_callback">genparam_callback() (in module M2Crypto.util)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.SMIME.PKCS7.get0_signers">get0_signers() (M2Crypto.SMIME.PKCS7 method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509_Store_Context.get1_chain">get1_chain() (M2Crypto.X509.X509_Store_Context method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.get_allow_unknown_ca">get_allow_unknown_ca() (M2Crypto.SSL.Context.Context method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EC.get_builtin_curves">get_builtin_curves() (in module M2Crypto.EC)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.get_cert_store">get_cert_store() (M2Crypto.SSL.Context.Context method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.get_cipher">get_cipher() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.get_cipher_list">get_cipher_list() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.get_ciphers">get_ciphers() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.get_context">get_context() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509_Extension.get_critical">get_critical() (M2Crypto.X509.X509_Extension method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509_Store_Context.get_current_cert">get_current_cert() (M2Crypto.X509.X509_Store_Context method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509_Name_Entry.get_data">get_data() (M2Crypto.X509.X509_Name_Entry method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.ASN1.ASN1_TIME.get_datetime">get_datetime() (M2Crypto.ASN1.ASN1_TIME method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.get_default_session_timeout">get_default_session_timeout() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EC.EC_pub.get_der">get_der() (M2Crypto.EC.EC_pub method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509_Name.get_entries_by_nid">get_entries_by_nid() (M2Crypto.X509.X509_Name method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.Err.get_error">get_error() (in module M2Crypto.Err)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509_Store_Context.get_error">(M2Crypto.X509.X509_Store_Context method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.html#M2Crypto.Err.get_error_code">get_error_code() (in module M2Crypto.Err)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509_Store_Context.get_error_depth">get_error_depth() (M2Crypto.X509.X509_Store_Context method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.Err.get_error_func">get_error_func() (in module M2Crypto.Err)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.Err.get_error_lib">get_error_lib() (in module M2Crypto.Err)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.Err.get_error_message">get_error_message() (in module M2Crypto.Err)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.Err.get_error_reason">get_error_reason() (in module M2Crypto.Err)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509.get_ext">get_ext() (M2Crypto.X509.X509 method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509.get_ext_at">get_ext_at() (M2Crypto.X509.X509 method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509.get_ext_count">get_ext_count() (M2Crypto.X509.X509 method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509.get_fingerprint">get_fingerprint() (M2Crypto.X509.X509 method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.Engine.Engine.get_id">get_id() (M2Crypto.Engine.Engine method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509.get_issuer">get_issuer() (M2Crypto.X509.X509 method)</a>
+</li>
+ </ul></td>
+ <td style="width: 33%; vertical-align: top;"><ul>
+ <li><a href="M2Crypto.html#M2Crypto.EC.EC_pub.get_key">get_key() (M2Crypto.EC.EC_pub method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EVP.PKey.get_modulus">get_modulus() (M2Crypto.EVP.PKey method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.Engine.Engine.get_name">get_name() (M2Crypto.Engine.Engine method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509_Extension.get_name">(M2Crypto.X509.X509_Extension method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509.get_not_after">get_not_after() (M2Crypto.X509.X509 method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509.get_not_before">get_not_before() (M2Crypto.X509.X509 method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509_Name_Entry.get_object">get_object() (M2Crypto.X509.X509_Name_Entry method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.get_peer_cert">get_peer_cert() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.get_peer_cert_chain">get_peer_cert_chain() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.Request.get_pubkey">get_pubkey() (M2Crypto.X509.Request method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509.get_pubkey">(M2Crypto.X509.X509 method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.html#M2Crypto.EVP.PKey.get_rsa">get_rsa() (M2Crypto.EVP.PKey method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509.get_serial_number">get_serial_number() (M2Crypto.X509.X509 method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.httpslib.HTTPSConnection.get_session">get_session() (M2Crypto.httpslib.HTTPSConnection method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.get_session">(M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.get_session_cache_mode">get_session_cache_mode() (M2Crypto.SSL.Context.Context method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.get_session_timeout">get_session_timeout() (M2Crypto.SSL.Context.Context method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.get_shutdown">get_shutdown() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.get_socket_read_timeout">get_socket_read_timeout() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.get_socket_write_timeout">get_socket_write_timeout() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.get_state">get_state() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.Request.get_subject">get_subject() (M2Crypto.X509.Request method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509.get_subject">(M2Crypto.X509.X509 method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Session.Session.get_time">get_time() (M2Crypto.SSL.Session.Session method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Session.Session.get_timeout">get_timeout() (M2Crypto.SSL.Session.Session method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509_Extension.get_value">get_value() (M2Crypto.X509.X509_Extension method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.get_verify_depth">get_verify_depth() (M2Crypto.SSL.Connection.Connection method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.get_verify_depth">(M2Crypto.SSL.Context.Context method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.get_verify_mode">get_verify_mode() (M2Crypto.SSL.Connection.Connection method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.get_verify_mode">(M2Crypto.SSL.Context.Context method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.get_verify_result">get_verify_result() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.get_version">get_version() (M2Crypto.SSL.Connection.Connection method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.X509.Request.get_version">(M2Crypto.X509.Request method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509.get_version">(M2Crypto.X509.X509 method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.html#M2Crypto.Err.get_x509_verify_error">get_x509_verify_error() (in module M2Crypto.Err)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.getpeername">getpeername() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.getsockname">getsockname() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.getsockopt">getsockopt() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.BIO.MemoryBuffer.getvalue">getvalue() (M2Crypto.BIO.MemoryBuffer method)</a>
+</li>
+ </ul></td>
+</tr></table>
+
+<h2 id="H">H</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+ <td style="width: 33%; vertical-align: top;"><ul>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.SSLServer.SSLServer.handle_error">handle_error() (M2Crypto.SSL.SSLServer.SSLServer method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.SSLServer.SSLServer.handle_request">handle_request() (M2Crypto.SSL.SSLServer.SSLServer method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.AuthCookie.AuthCookie.headerValue">headerValue() (M2Crypto.AuthCookie.AuthCookie method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EVP.HMAC">HMAC (class in M2Crypto.EVP)</a>
+</li>
+ </ul></td>
+ <td style="width: 33%; vertical-align: top;"><ul>
+ <li><a href="M2Crypto.html#M2Crypto.EVP.hmac">hmac() (in module M2Crypto.EVP)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.m2urllib2.HTTPSHandler.https_open">https_open() (M2Crypto.m2urllib2.HTTPSHandler method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.m2urllib2.HTTPSHandler.https_request">https_request() (M2Crypto.m2urllib2.HTTPSHandler method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.httpslib.HTTPSConnection">HTTPSConnection (class in M2Crypto.httpslib)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.m2urllib2.HTTPSHandler">HTTPSHandler (class in M2Crypto.m2urllib2)</a>
+</li>
+ </ul></td>
+</tr></table>
+
+<h2 id="I">I</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+ <td style="width: 33%; vertical-align: top;"><ul>
+ <li><a href="M2Crypto.html#M2Crypto.threading.init">init() (in module M2Crypto.threading)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.Engine.Engine.init">(M2Crypto.Engine.Engine method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.html#M2Crypto.BIO.IOBuffer">IOBuffer (class in M2Crypto.BIO)</a>
+</li>
+ </ul></td>
+ <td style="width: 33%; vertical-align: top;"><ul>
+ <li><a href="M2Crypto.html#M2Crypto.AuthCookie.AuthCookie.isExpired">isExpired() (M2Crypto.AuthCookie.AuthCookie method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.AuthCookie.AuthCookieJar.isGoodCookie">isGoodCookie() (M2Crypto.AuthCookie.AuthCookieJar method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.AuthCookie.AuthCookieJar.isGoodCookieString">isGoodCookieString() (M2Crypto.AuthCookie.AuthCookieJar method)</a>
+</li>
+ </ul></td>
+</tr></table>
+
+<h2 id="K">K</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+ <td style="width: 33%; vertical-align: top;"><ul>
+ <li><a href="M2Crypto.html#M2Crypto.RSA.keygen_callback">keygen_callback() (in module M2Crypto.RSA)</a>
+</li>
+ </ul></td>
+</tr></table>
+
+<h2 id="L">L</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+ <td style="width: 33%; vertical-align: top;"><ul>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.listen">listen() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.TwistedProtocolWrapper.listenSSL">listenSSL() (in module M2Crypto.SSL.TwistedProtocolWrapper)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.TwistedProtocolWrapper.listenTCP">listenTCP() (in module M2Crypto.SSL.TwistedProtocolWrapper)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.load_cert">load_cert() (in module M2Crypto.X509)</a>
+
+ <ul>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.load_cert">(M2Crypto.SSL.Context.Context method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.load_cert_bio">load_cert_bio() (in module M2Crypto.X509)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.load_cert_chain">load_cert_chain() (M2Crypto.SSL.Context.Context method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.load_cert_der_string">load_cert_der_string() (in module M2Crypto.X509)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.load_cert_string">load_cert_string() (in module M2Crypto.X509)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.Engine.Engine.load_certificate">load_certificate() (M2Crypto.Engine.Engine method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.load_client_CA">load_client_CA() (M2Crypto.SSL.Context.Context method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.load_client_ca">load_client_ca() (M2Crypto.SSL.Context.Context method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.load_crl">load_crl() (in module M2Crypto.X509)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.Engine.load_dynamic">load_dynamic() (in module M2Crypto.Engine)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.Engine.load_dynamic_engine">load_dynamic_engine() (in module M2Crypto.Engine)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.Rand.load_file">load_file() (in module M2Crypto.Rand)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509_Store.load_info">load_info() (M2Crypto.X509.X509_Store method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.DSA.load_key">load_key() (in module M2Crypto.DSA)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.SMIME.SMIME.load_key">(M2Crypto.SMIME.SMIME method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EC.load_key">(in module M2Crypto.EC)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EVP.load_key">(in module M2Crypto.EVP)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.RSA.load_key">(in module M2Crypto.RSA)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.html#M2Crypto.DSA.load_key_bio">load_key_bio() (in module M2Crypto.DSA)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.SMIME.SMIME.load_key_bio">(M2Crypto.SMIME.SMIME method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EC.load_key_bio">(in module M2Crypto.EC)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EVP.load_key_bio">(in module M2Crypto.EVP)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.RSA.load_key_bio">(in module M2Crypto.RSA)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.html#M2Crypto.EVP.load_key_bio_pubkey">load_key_bio_pubkey() (in module M2Crypto.EVP)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EC.load_key_string">load_key_string() (in module M2Crypto.EC)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.EVP.load_key_string">(in module M2Crypto.EVP)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.RSA.load_key_string">(in module M2Crypto.RSA)</a>
+</li>
+ </ul></li>
+ </ul></td>
+ <td style="width: 33%; vertical-align: top;"><ul>
+ <li><a href="M2Crypto.html#M2Crypto.EC.load_key_string_pubkey">load_key_string_pubkey() (in module M2Crypto.EC)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.EVP.load_key_string_pubkey">(in module M2Crypto.EVP)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509_Store.load_locations">load_locations() (M2Crypto.X509.X509_Store method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.Engine.load_openssl">load_openssl() (in module M2Crypto.Engine)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.DH.load_params">load_params() (in module M2Crypto.DH)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.DSA.load_params">(in module M2Crypto.DSA)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.html#M2Crypto.DH.load_params_bio">load_params_bio() (in module M2Crypto.DH)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.DSA.load_params_bio">(in module M2Crypto.DSA)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.html#M2Crypto.SMIME.load_pkcs7">load_pkcs7() (in module M2Crypto.SMIME)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.SMIME.load_pkcs7_bio">load_pkcs7_bio() (in module M2Crypto.SMIME)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.SMIME.load_pkcs7_bio_der">load_pkcs7_bio_der() (in module M2Crypto.SMIME)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.SMIME.load_pkcs7_der">load_pkcs7_der() (in module M2Crypto.SMIME)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.Engine.Engine.load_private_key">load_private_key() (M2Crypto.Engine.Engine method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.DSA.load_pub_key">load_pub_key() (in module M2Crypto.DSA)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.EC.load_pub_key">(in module M2Crypto.EC)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.RSA.load_pub_key">(in module M2Crypto.RSA)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.html#M2Crypto.DSA.load_pub_key_bio">load_pub_key_bio() (in module M2Crypto.DSA)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.EC.load_pub_key_bio">(in module M2Crypto.EC)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.RSA.load_pub_key_bio">(in module M2Crypto.RSA)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.html#M2Crypto.Engine.Engine.load_public_key">load_public_key() (M2Crypto.Engine.Engine method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.load_request">load_request() (in module M2Crypto.X509)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.load_request_bio">load_request_bio() (in module M2Crypto.X509)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.load_request_der_string">load_request_der_string() (in module M2Crypto.X509)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.load_request_string">load_request_string() (in module M2Crypto.X509)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Session.load_session">load_session() (in module M2Crypto.SSL.Session)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.load_verify_info">load_verify_info() (M2Crypto.SSL.Context.Context method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.load_verify_locations">load_verify_locations() (M2Crypto.SSL.Context.Context method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.ASN1.LocalTimezone">LocalTimezone (class in M2Crypto.ASN1)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper.loseConnection">loseConnection() (M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper method)</a>
+</li>
+ </ul></td>
+</tr></table>
+
+<h2 id="M">M</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+ <td style="width: 33%; vertical-align: top;"><ul>
+ <li><a href="M2Crypto.html#M2Crypto.ASN1.ASN1_Integer.m2_asn1_integer_free">m2_asn1_integer_free() (M2Crypto.ASN1.ASN1_Integer method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.ASN1.ASN1_Object.m2_asn1_object_free">m2_asn1_object_free() (M2Crypto.ASN1.ASN1_Object method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.ASN1.ASN1_String.m2_asn1_string_free">m2_asn1_string_free() (M2Crypto.ASN1.ASN1_String method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.ASN1.ASN1_TIME.m2_asn1_time_free">m2_asn1_time_free() (M2Crypto.ASN1.ASN1_TIME method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.BIO.BIO.m2_bio_free">m2_bio_free() (M2Crypto.BIO.BIO method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.BIO.CipherStream.m2_bio_free">(M2Crypto.BIO.CipherStream method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.BIO.IOBuffer.m2_bio_free">(M2Crypto.BIO.IOBuffer method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.m2_bio_free">(M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.m2_bio_noclose">m2_bio_noclose (M2Crypto.SSL.Connection.Connection attribute)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.BIO.CipherStream.m2_bio_pop">m2_bio_pop() (M2Crypto.BIO.CipherStream method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.BIO.IOBuffer.m2_bio_pop">(M2Crypto.BIO.IOBuffer method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.html#M2Crypto.EVP.Cipher.m2_cipher_ctx_free">m2_cipher_ctx_free() (M2Crypto.EVP.Cipher method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.DH.DH.m2_dh_free">m2_dh_free() (M2Crypto.DH.DH method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.DSA.DSA.m2_dsa_free">m2_dsa_free() (M2Crypto.DSA.DSA method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EC.EC.m2_ec_key_free">m2_ec_key_free() (M2Crypto.EC.EC method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.Engine.Engine.m2_engine_free">m2_engine_free() (M2Crypto.Engine.Engine method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EVP.HMAC.m2_hmac_ctx_free">m2_hmac_ctx_free() (M2Crypto.EVP.HMAC method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EVP.MessageDigest.m2_md_ctx_free">m2_md_ctx_free() (M2Crypto.EVP.MessageDigest method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.EVP.PKey.m2_md_ctx_free">(M2Crypto.EVP.PKey method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.html#M2Crypto.SMIME.PKCS7.m2_pkcs7_free">m2_pkcs7_free() (M2Crypto.SMIME.PKCS7 method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EVP.PKey.m2_pkey_free">m2_pkey_free() (M2Crypto.EVP.PKey method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.RSA.RSA.m2_rsa_free">m2_rsa_free() (M2Crypto.RSA.RSA method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509_Extension_Stack.m2_sk_x509_extension_free">m2_sk_x509_extension_free() (M2Crypto.X509.X509_Extension_Stack method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509_Stack.m2_sk_x509_free">m2_sk_x509_free() (M2Crypto.X509.X509_Stack method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.m2_ssl_ctx_free">m2_ssl_ctx_free() (M2Crypto.SSL.Context.Context method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.m2_ssl_free">m2_ssl_free() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Session.Session.m2_ssl_session_free">m2_ssl_session_free() (M2Crypto.SSL.Session.Session method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.CRL.m2_x509_crl_free">m2_x509_crl_free() (M2Crypto.X509.CRL method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509_Extension.m2_x509_extension_free">m2_x509_extension_free() (M2Crypto.X509.X509_Extension method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509.m2_x509_free">m2_x509_free() (M2Crypto.X509.X509 method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509_Name_Entry.m2_x509_name_entry_free">m2_x509_name_entry_free() (M2Crypto.X509.X509_Name_Entry method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509_Name.m2_x509_name_free">m2_x509_name_free() (M2Crypto.X509.X509_Name method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.Request.m2_x509_req_free">m2_x509_req_free() (M2Crypto.X509.Request method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509_Store_Context.m2_x509_store_ctx_free">m2_x509_store_ctx_free() (M2Crypto.X509.X509_Store_Context method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509_Store.m2_x509_store_free">m2_x509_store_free() (M2Crypto.X509.X509_Store method)</a>
+</li>
+ <li><a href="M2Crypto.html#module-M2Crypto.__init__">M2Crypto.__init__ (module)</a>
+</li>
+ <li><a href="M2Crypto.html#module-M2Crypto.ASN1">M2Crypto.ASN1 (module)</a>
+</li>
+ <li><a href="M2Crypto.html#module-M2Crypto.AuthCookie">M2Crypto.AuthCookie (module)</a>
+</li>
+ <li><a href="M2Crypto.html#module-M2Crypto.BIO">M2Crypto.BIO (module)</a>
+</li>
+ <li><a href="M2Crypto.html#module-M2Crypto.BN">M2Crypto.BN (module)</a>
+</li>
+ </ul></td>
+ <td style="width: 33%; vertical-align: top;"><ul>
+ <li><a href="M2Crypto.html#module-M2Crypto.callback">M2Crypto.callback (module)</a>
+</li>
+ <li><a href="M2Crypto.html#module-M2Crypto.DH">M2Crypto.DH (module)</a>
+</li>
+ <li><a href="M2Crypto.html#module-M2Crypto.DSA">M2Crypto.DSA (module)</a>
+</li>
+ <li><a href="M2Crypto.html#module-M2Crypto.EC">M2Crypto.EC (module)</a>
+</li>
+ <li><a href="M2Crypto.html#module-M2Crypto.Engine">M2Crypto.Engine (module)</a>
+</li>
+ <li><a href="M2Crypto.html#module-M2Crypto.Err">M2Crypto.Err (module)</a>
+</li>
+ <li><a href="M2Crypto.html#module-M2Crypto.EVP">M2Crypto.EVP (module)</a>
+</li>
+ <li><a href="M2Crypto.html#module-M2Crypto.ftpslib">M2Crypto.ftpslib (module)</a>
+</li>
+ <li><a href="M2Crypto.html#module-M2Crypto.httpslib">M2Crypto.httpslib (module)</a>
+</li>
+ <li><a href="M2Crypto.html#module-M2Crypto.m2">M2Crypto.m2 (module)</a>
+</li>
+ <li><a href="M2Crypto.html#module-M2Crypto.m2crypto">M2Crypto.m2crypto (module)</a>
+</li>
+ <li><a href="M2Crypto.html#module-M2Crypto.m2urllib">M2Crypto.m2urllib (module)</a>
+</li>
+ <li><a href="M2Crypto.html#module-M2Crypto.m2urllib2">M2Crypto.m2urllib2 (module)</a>
+</li>
+ <li><a href="M2Crypto.html#module-M2Crypto.m2xmlrpclib">M2Crypto.m2xmlrpclib (module)</a>
+</li>
+ <li><a href="M2Crypto.html#module-M2Crypto.Rand">M2Crypto.Rand (module)</a>
+</li>
+ <li><a href="M2Crypto.html#module-M2Crypto.RC4">M2Crypto.RC4 (module)</a>
+</li>
+ <li><a href="M2Crypto.html#module-M2Crypto.RSA">M2Crypto.RSA (module)</a>
+</li>
+ <li><a href="M2Crypto.html#module-M2Crypto.SMIME">M2Crypto.SMIME (module)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#module-M2Crypto.SSL">M2Crypto.SSL (module)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#module-M2Crypto.SSL.cb">M2Crypto.SSL.cb (module)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#module-M2Crypto.SSL.Checker">M2Crypto.SSL.Checker (module)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#module-M2Crypto.SSL.Cipher">M2Crypto.SSL.Cipher (module)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#module-M2Crypto.SSL.Connection">M2Crypto.SSL.Connection (module)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#module-M2Crypto.SSL.Context">M2Crypto.SSL.Context (module)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#module-M2Crypto.SSL.Session">M2Crypto.SSL.Session (module)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#module-M2Crypto.SSL.ssl_dispatcher">M2Crypto.SSL.ssl_dispatcher (module)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#module-M2Crypto.SSL.SSLServer">M2Crypto.SSL.SSLServer (module)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#module-M2Crypto.SSL.timeout">M2Crypto.SSL.timeout (module)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#module-M2Crypto.SSL.TwistedProtocolWrapper">M2Crypto.SSL.TwistedProtocolWrapper (module)</a>
+</li>
+ <li><a href="M2Crypto.html#module-M2Crypto.threading">M2Crypto.threading (module)</a>
+</li>
+ <li><a href="M2Crypto.html#module-M2Crypto.util">M2Crypto.util (module)</a>
+</li>
+ <li><a href="M2Crypto.html#module-M2Crypto.X509">M2Crypto.X509 (module)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.Err.M2CryptoError">M2CryptoError</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.AuthCookie.AuthCookie.mac">mac() (M2Crypto.AuthCookie.AuthCookie method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.AuthCookie.AuthCookieJar.makeCookie">makeCookie() (M2Crypto.AuthCookie.AuthCookieJar method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.makefile">makefile() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Context.map">map() (in module M2Crypto.SSL.Context)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.BIO.MemoryBuffer">MemoryBuffer (class in M2Crypto.BIO)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EVP.MessageDigest">MessageDigest (class in M2Crypto.EVP)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.AuthCookie.mix">mix() (in module M2Crypto.AuthCookie)</a>
+</li>
+ </ul></td>
+</tr></table>
+
+<h2 id="N">N</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+ <td style="width: 33%; vertical-align: top;"><ul>
+ <li><a href="M2Crypto.html#M2Crypto.AuthCookie.AuthCookie.name">name() (M2Crypto.AuthCookie.AuthCookie method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Cipher.Cipher.name">(M2Crypto.SSL.Cipher.Cipher method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.new_extension">new_extension() (in module M2Crypto.X509)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.RSA.new_pub_key">new_pub_key() (in module M2Crypto.RSA)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.new_stack_from_der">new_stack_from_der() (in module M2Crypto.X509)</a>
+</li>
+ </ul></td>
+ <td style="width: 33%; vertical-align: top;"><ul>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509_Name.nid">nid (M2Crypto.X509.X509_Name attribute)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.util.no_passphrase_callback">no_passphrase_callback() (in module M2Crypto.util)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Checker.NoCertificate">NoCertificate</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.ftpslib.FTP_TLS.ntransfercmd">ntransfercmd() (M2Crypto.ftpslib.FTP_TLS method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Checker.Checker.numericIpMatch">numericIpMatch (M2Crypto.SSL.Checker.Checker attribute)</a>
+</li>
+ </ul></td>
+</tr></table>
+
+<h2 id="O">O</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+ <td style="width: 33%; vertical-align: top;"><ul>
+ <li><a href="M2Crypto.html#M2Crypto.util.octx_to_num">octx_to_num() (in module M2Crypto.util)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.m2urllib.open_https">open_https() (in module M2Crypto.m2urllib)</a>
+</li>
+ </ul></td>
+ <td style="width: 33%; vertical-align: top;"><ul>
+ <li><a href="M2Crypto.html#M2Crypto.BIO.openfile">openfile() (in module M2Crypto.BIO)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.AuthCookie.AuthCookie.output">output() (M2Crypto.AuthCookie.AuthCookie method)</a>
+</li>
+ </ul></td>
+</tr></table>
+
+<h2 id="P">P</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+ <td style="width: 33%; vertical-align: top;"><ul>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.timeout.timeout.pack">pack() (M2Crypto.SSL.timeout.timeout method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.util.passphrase_callback">passphrase_callback() (in module M2Crypto.util)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EVP.pbkdf2">pbkdf2() (in module M2Crypto.EVP)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.Err.peek_error_code">peek_error_code() (in module M2Crypto.Err)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.pending">pending() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.util.pkcs5_pad">pkcs5_pad() (in module M2Crypto.util)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.SMIME.PKCS7">PKCS7 (class in M2Crypto.SMIME)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.SMIME.PKCS7_Error">PKCS7_Error</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.util.pkcs7_pad">pkcs7_pad() (in module M2Crypto.util)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EVP.PKey">PKey (class in M2Crypto.EVP)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509_Extension_Stack.pop">pop() (M2Crypto.X509.X509_Extension_Stack method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509_Stack.pop">(M2Crypto.X509.X509_Stack method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.html#M2Crypto.DH.DH.print_params">print_params() (M2Crypto.DH.DH method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.RSA.RSA.private_decrypt">private_decrypt() (M2Crypto.RSA.RSA method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.RSA.RSA_pub.private_decrypt">(M2Crypto.RSA.RSA_pub method)</a>
+</li>
+ </ul></li>
+ </ul></td>
+ <td style="width: 33%; vertical-align: top;"><ul>
+ <li><a href="M2Crypto.html#M2Crypto.RSA.RSA.private_encrypt">private_encrypt() (M2Crypto.RSA.RSA method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.RSA.RSA_pub.private_encrypt">(M2Crypto.RSA.RSA_pub method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.html#M2Crypto.ftpslib.FTP_TLS.prot_c">prot_c() (M2Crypto.ftpslib.FTP_TLS method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.ftpslib.FTP_TLS.prot_p">prot_p() (M2Crypto.ftpslib.FTP_TLS method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.httpslib.ProxyHTTPSConnection">ProxyHTTPSConnection (class in M2Crypto.httpslib)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EC.EC.pub">pub() (M2Crypto.EC.EC method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.RSA.RSA.pub">(M2Crypto.RSA.RSA method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.html#M2Crypto.EC.pub_key_from_der">pub_key_from_der() (in module M2Crypto.EC)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.DSA.pub_key_from_params">pub_key_from_params() (in module M2Crypto.DSA)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.EC.pub_key_from_params">(in module M2Crypto.EC)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.html#M2Crypto.RSA.RSA.public_decrypt">public_decrypt() (M2Crypto.RSA.RSA method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.RSA.RSA.public_encrypt">public_encrypt() (M2Crypto.RSA.RSA method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509_Extension_Stack.push">push() (M2Crypto.X509.X509_Extension_Stack method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509_Stack.push">(M2Crypto.X509.X509_Stack method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.html#M2Crypto.httpslib.ProxyHTTPSConnection.putheader">putheader() (M2Crypto.httpslib.ProxyHTTPSConnection method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.httpslib.ProxyHTTPSConnection.putrequest">putrequest() (M2Crypto.httpslib.ProxyHTTPSConnection method)</a>
+</li>
+ </ul></td>
+</tr></table>
+
+<h2 id="Q">Q</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+ <td style="width: 33%; vertical-align: top;"><ul>
+ <li><a href="M2Crypto.html#M2Crypto.util.quiet_genparam_callback">quiet_genparam_callback() (in module M2Crypto.util)</a>
+</li>
+ </ul></td>
+</tr></table>
+
+<h2 id="R">R</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+ <td style="width: 33%; vertical-align: top;"><ul>
+ <li><a href="M2Crypto.html#M2Crypto.BN.rand">rand() (in module M2Crypto.BN)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.Rand.rand_add">rand_add() (in module M2Crypto.Rand)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.Rand.rand_bytes">rand_bytes() (in module M2Crypto.Rand)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.Rand.rand_file_name">rand_file_name() (in module M2Crypto.Rand)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.Rand.rand_pseudo_bytes">rand_pseudo_bytes() (in module M2Crypto.Rand)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.BN.rand_range">rand_range() (in module M2Crypto.BN)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.Rand.rand_seed">rand_seed() (in module M2Crypto.Rand)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.Rand.rand_status">rand_status() (in module M2Crypto.Rand)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.BN.randfname">randfname() (in module M2Crypto.BN)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.RC4.RC4">RC4 (class in M2Crypto.RC4)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.RC4.RC4.rc4_free">rc4_free() (M2Crypto.RC4.RC4 method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.BIO.BIO.read">read() (M2Crypto.BIO.BIO method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.BIO.MemoryBuffer.read">(M2Crypto.BIO.MemoryBuffer method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.read">(M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.html#M2Crypto.BIO.MemoryBuffer.read_all">read_all() (M2Crypto.BIO.MemoryBuffer method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.BIO.BIO.readable">readable() (M2Crypto.BIO.BIO method)</a>
+</li>
+ </ul></td>
+ <td style="width: 33%; vertical-align: top;"><ul>
+ <li><a href="M2Crypto.html#M2Crypto.BIO.BIO.readline">readline() (M2Crypto.BIO.BIO method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.BIO.BIO.readlines">readlines() (M2Crypto.BIO.BIO method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.recv">recv() (M2Crypto.SSL.Connection.Connection method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.ssl_dispatcher.ssl_dispatcher.recv">(M2Crypto.SSL.ssl_dispatcher.ssl_dispatcher method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.recv_into">recv_into() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.remove_session">remove_session() (M2Crypto.SSL.Context.Context method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.renegotiate">renegotiate() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.Request">Request (class in M2Crypto.X509)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.m2xmlrpclib.SSL_Transport.request">request() (M2Crypto.m2xmlrpclib.SSL_Transport method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.BIO.BIO.reset">reset() (M2Crypto.BIO.BIO method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.BIO.File.reset">(M2Crypto.BIO.File method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EVP.HMAC.reset">(M2Crypto.EVP.HMAC method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.html#M2Crypto.EVP.PKey.reset_context">reset_context() (M2Crypto.EVP.PKey method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.RSA.RSA">RSA (class in M2Crypto.RSA)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.RSA.rsa_error">rsa_error() (in module M2Crypto.RSA)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.RSA.RSA_pub">RSA_pub (class in M2Crypto.RSA)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.RSA.RSAError">RSAError</a>
+</li>
+ </ul></td>
+</tr></table>
+
+<h2 id="S">S</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+ <td style="width: 33%; vertical-align: top;"><ul>
+ <li><a href="M2Crypto.html#M2Crypto.BIO.CipherStream.SALT_LEN">SALT_LEN (M2Crypto.BIO.CipherStream attribute)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.Request.save">save() (M2Crypto.X509.Request method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509.save">(M2Crypto.X509.X509 method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.html#M2Crypto.Rand.save_file">save_file() (in module M2Crypto.Rand)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.DSA.DSA.save_key">save_key() (M2Crypto.DSA.DSA method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.DSA.DSA_pub.save_key">(M2Crypto.DSA.DSA_pub method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EC.EC.save_key">(M2Crypto.EC.EC method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EC.EC_pub.save_key">(M2Crypto.EC.EC_pub method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EVP.PKey.save_key">(M2Crypto.EVP.PKey method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.RSA.RSA.save_key">(M2Crypto.RSA.RSA method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.RSA.RSA_pub.save_key">(M2Crypto.RSA.RSA_pub method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.html#M2Crypto.DSA.DSA.save_key_bio">save_key_bio() (M2Crypto.DSA.DSA method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.DSA.DSA_pub.save_key_bio">(M2Crypto.DSA.DSA_pub method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EC.EC.save_key_bio">(M2Crypto.EC.EC method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EC.EC_pub.save_key_bio">(M2Crypto.EC.EC_pub method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EVP.PKey.save_key_bio">(M2Crypto.EVP.PKey method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.RSA.RSA.save_key_bio">(M2Crypto.RSA.RSA method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.RSA.RSA_pub.save_key_bio">(M2Crypto.RSA.RSA_pub method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.html#M2Crypto.RSA.RSA.save_key_der">save_key_der() (M2Crypto.RSA.RSA method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.RSA.RSA.save_key_der_bio">save_key_der_bio() (M2Crypto.RSA.RSA method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.DSA.DSA.save_params">save_params() (M2Crypto.DSA.DSA method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.DSA.DSA.save_params_bio">save_params_bio() (M2Crypto.DSA.DSA method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.RSA.RSA.save_pem">save_pem() (M2Crypto.RSA.RSA method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.X509.Request.save_pem">(M2Crypto.X509.Request method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509.save_pem">(M2Crypto.X509.X509 method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.html#M2Crypto.DSA.DSA.save_pub_key">save_pub_key() (M2Crypto.DSA.DSA method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.EC.EC.save_pub_key">(M2Crypto.EC.EC method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.RSA.RSA.save_pub_key">(M2Crypto.RSA.RSA method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.html#M2Crypto.DSA.DSA.save_pub_key_bio">save_pub_key_bio() (M2Crypto.DSA.DSA method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.EC.EC.save_pub_key_bio">(M2Crypto.EC.EC method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.RSA.RSA.save_pub_key_bio">(M2Crypto.RSA.RSA method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.html#M2Crypto.BIO.BIO.seek">seek() (M2Crypto.BIO.BIO method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.send">send() (M2Crypto.SSL.Connection.Connection method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.ssl_dispatcher.ssl_dispatcher.send">(M2Crypto.SSL.ssl_dispatcher.ssl_dispatcher method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.sendall">sendall() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.serverPostConnectionCheck">serverPostConnectionCheck() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Session.Session">Session (class in M2Crypto.SSL.Session)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.set1_host">set1_host() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.set_accept_state">set_accept_state() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.set_allow_unknown_ca">set_allow_unknown_ca() (M2Crypto.SSL.Context.Context method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.set_bio">set_bio() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.BIO.CipherStream.set_cipher">set_cipher() (M2Crypto.BIO.CipherStream method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.SMIME.SMIME.set_cipher">(M2Crypto.SMIME.SMIME method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.set_cipher_list">set_cipher_list() (M2Crypto.SSL.Connection.Connection method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.set_cipher_list">(M2Crypto.SSL.Context.Context method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.set_client_CA_list_from_context">set_client_CA_list_from_context() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.set_client_CA_list_from_file">set_client_CA_list_from_file() (M2Crypto.SSL.Connection.Connection method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.set_client_CA_list_from_file">(M2Crypto.SSL.Context.Context method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.set_connect_state">set_connect_state() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509_Extension.set_critical">set_critical() (M2Crypto.X509.X509_Extension method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509_Name_Entry.set_data">set_data() (M2Crypto.X509.X509_Name_Entry method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.ASN1.ASN1_TIME.set_datetime">set_datetime() (M2Crypto.ASN1.ASN1_TIME method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.Engine.Engine.set_default">set_default() (M2Crypto.Engine.Engine method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.set_default_verify_paths">set_default_verify_paths() (M2Crypto.SSL.Context.Context method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.set_info_callback">set_info_callback() (M2Crypto.SSL.Context.Context method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509.set_issuer">set_issuer() (M2Crypto.X509.X509 method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509.set_issuer_name">set_issuer_name() (M2Crypto.X509.X509 method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.RC4.RC4.set_key">set_key() (M2Crypto.RC4.RC4 method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509.set_not_after">set_not_after() (M2Crypto.X509.X509 method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509.set_not_before">set_not_before() (M2Crypto.X509.X509 method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509_Name_Entry.set_object">set_object() (M2Crypto.X509.X509_Name_Entry method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.set_options">set_options() (M2Crypto.SSL.Context.Context method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EVP.Cipher.set_padding">set_padding() (M2Crypto.EVP.Cipher method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.DH.set_params">set_params() (in module M2Crypto.DH)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.DSA.DSA.set_params">(M2Crypto.DSA.DSA method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.DSA.set_params">(in module M2Crypto.DSA)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.set_post_connection_check_callback">set_post_connection_check_callback() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.Request.set_pubkey">set_pubkey() (M2Crypto.X509.Request method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509.set_pubkey">(M2Crypto.X509.X509 method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509.set_serial_number">set_serial_number() (M2Crypto.X509.X509 method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.httpslib.HTTPSConnection.set_session">set_session() (M2Crypto.httpslib.HTTPSConnection method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.set_session">(M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ </ul></li>
+ </ul></td>
+ <td style="width: 33%; vertical-align: top;"><ul>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.set_session_cache_mode">set_session_cache_mode() (M2Crypto.SSL.Context.Context method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.set_session_id_ctx">set_session_id_ctx() (M2Crypto.SSL.Connection.Connection method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.set_session_id_ctx">(M2Crypto.SSL.Context.Context method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.set_session_timeout">set_session_timeout() (M2Crypto.SSL.Context.Context method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.set_shutdown">set_shutdown() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.set_socket_read_timeout">set_socket_read_timeout() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.set_socket_write_timeout">set_socket_write_timeout() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.BIO.SSLBio.set_ssl">set_ssl() (M2Crypto.BIO.SSLBio method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.set_ssl_close_flag">set_ssl_close_flag() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.ASN1.ASN1_TIME.set_string">set_string() (M2Crypto.ASN1.ASN1_TIME method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.Request.set_subject">set_subject() (M2Crypto.X509.Request method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509.set_subject">(M2Crypto.X509.X509 method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.Request.set_subject_name">set_subject_name() (M2Crypto.X509.Request method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509.set_subject_name">(M2Crypto.X509.X509 method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.html#M2Crypto.ASN1.ASN1_TIME.set_time">set_time() (M2Crypto.ASN1.ASN1_TIME method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Session.Session.set_time">(M2Crypto.SSL.Session.Session method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Session.Session.set_timeout">set_timeout() (M2Crypto.SSL.Session.Session method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.set_tlsext_host_name">set_tlsext_host_name() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.set_tmp_dh">set_tmp_dh() (M2Crypto.SSL.Context.Context method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.set_tmp_dh_callback">set_tmp_dh_callback() (M2Crypto.SSL.Context.Context method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.set_tmp_rsa">set_tmp_rsa() (M2Crypto.SSL.Context.Context method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.set_tmp_rsa_callback">set_tmp_rsa_callback() (M2Crypto.SSL.Context.Context method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Context.Context.set_verify">set_verify() (M2Crypto.SSL.Context.Context method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509_Store.set_verify_cb">set_verify_cb() (M2Crypto.X509.X509_Store method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.Request.set_version">set_version() (M2Crypto.X509.Request method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509.set_version">(M2Crypto.X509.X509 method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.html#M2Crypto.SMIME.SMIME.set_x509_stack">set_x509_stack() (M2Crypto.SMIME.SMIME method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.SMIME.SMIME.set_x509_store">set_x509_store() (M2Crypto.SMIME.SMIME method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.setblocking">setblocking() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.setsockopt">setsockopt() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.settimeout">settimeout() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.setup_addr">setup_addr() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.setup_ssl">setup_ssl() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.BIO.BIO.should_read">should_read() (M2Crypto.BIO.BIO method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.BIO.BIO.should_retry">should_retry() (M2Crypto.BIO.BIO method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.BIO.BIO.should_write">should_write() (M2Crypto.BIO.BIO method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.shutdown">shutdown() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.DSA.DSA.sign">sign() (M2Crypto.DSA.DSA method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.DSA.DSA_pub.sign">(M2Crypto.DSA.DSA_pub method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.RSA.RSA.sign">(M2Crypto.RSA.RSA method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.SMIME.SMIME.sign">(M2Crypto.SMIME.SMIME method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.Request.sign">(M2Crypto.X509.Request method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509.sign">(M2Crypto.X509.X509 method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.html#M2Crypto.DSA.DSA.sign_asn1">sign_asn1() (M2Crypto.DSA.DSA method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.DSA.DSA_pub.sign_asn1">(M2Crypto.DSA.DSA_pub method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.html#M2Crypto.EC.EC.sign_dsa">sign_dsa() (M2Crypto.EC.EC method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EC.EC.sign_dsa_asn1">sign_dsa_asn1() (M2Crypto.EC.EC method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EVP.PKey.sign_final">sign_final() (M2Crypto.EVP.PKey method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EVP.PKey.sign_init">sign_init() (M2Crypto.EVP.PKey method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.RSA.RSA.sign_rsassa_pss">sign_rsassa_pss() (M2Crypto.RSA.RSA method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EVP.PKey.sign_update">sign_update() (M2Crypto.EVP.PKey method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EVP.PKey.size">size() (M2Crypto.EVP.PKey method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.SMIME.SMIME">SMIME (class in M2Crypto.SMIME)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.SMIME.SMIME_Error">SMIME_Error</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.SMIME.smime_load_pkcs7">smime_load_pkcs7() (in module M2Crypto.SMIME)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.SMIME.smime_load_pkcs7_bio">smime_load_pkcs7_bio() (in module M2Crypto.SMIME)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.ssl_dispatcher.ssl_dispatcher">ssl_dispatcher (class in M2Crypto.SSL.ssl_dispatcher)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.ssl_get_error">ssl_get_error() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.cb.ssl_info_callback">ssl_info_callback() (in module M2Crypto.SSL.cb)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.m2xmlrpclib.SSL_Transport">SSL_Transport (class in M2Crypto.m2xmlrpclib)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.cb.ssl_verify_callback">ssl_verify_callback() (in module M2Crypto.SSL.cb)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.cb.ssl_verify_callback_allow_unknown_ca">ssl_verify_callback_allow_unknown_ca() (in module M2Crypto.SSL.cb)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.cb.ssl_verify_callback_stub">ssl_verify_callback_stub() (in module M2Crypto.SSL.cb)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.BIO.SSLBio">SSLBio (class in M2Crypto.BIO)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.SSLError">SSLError</a>, <a href="M2Crypto.html#M2Crypto.Err.SSLError">[1]</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.SSLServer.SSLServer">SSLServer (class in M2Crypto.SSL.SSLServer)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.SSLTimeoutError">SSLTimeoutError</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Checker.SSLVerificationError">SSLVerificationError</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper.startTLS">startTLS() (M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.timeout.struct_size">struct_size() (in module M2Crypto.SSL.timeout)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.timeout.struct_to_timeout">struct_to_timeout() (in module M2Crypto.SSL.timeout)</a>
+</li>
+ </ul></td>
+</tr></table>
+
+<h2 id="T">T</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+ <td style="width: 33%; vertical-align: top;"><ul>
+ <li><a href="M2Crypto.html#M2Crypto.BIO.BIO.tell">tell() (M2Crypto.BIO.BIO method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.SMIME.text_crlf">text_crlf() (in module M2Crypto.SMIME)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.SMIME.text_crlf_bio">text_crlf_bio() (in module M2Crypto.SMIME)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.SSLServer.ThreadingSSLServer">ThreadingSSLServer (class in M2Crypto.SSL.SSLServer)</a>
+</li>
+ </ul></td>
+ <td style="width: 33%; vertical-align: top;"><ul>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.timeout.timeout">timeout (class in M2Crypto.SSL.timeout)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper">TLSProtocolWrapper (class in M2Crypto.SSL.TwistedProtocolWrapper)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.SMIME.PKCS7.type">type() (M2Crypto.SMIME.PKCS7 method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.ASN1.LocalTimezone.tzname">tzname() (M2Crypto.ASN1.LocalTimezone method)</a>
+</li>
+ </ul></td>
+</tr></table>
+
+<h2 id="U">U</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+ <td style="width: 33%; vertical-align: top;"><ul>
+ <li><a href="M2Crypto.html#M2Crypto.AuthCookie.unmix">unmix() (in module M2Crypto.AuthCookie)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.AuthCookie.unmix3">unmix3() (in module M2Crypto.AuthCookie)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.SMIME.SMIME.unset_cipher">unset_cipher() (M2Crypto.SMIME.SMIME method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.SMIME.SMIME.unset_key">unset_key() (M2Crypto.SMIME.SMIME method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.SMIME.SMIME.unset_x509_stack">unset_x509_stack() (M2Crypto.SMIME.SMIME method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.SMIME.SMIME.unset_x509_store">unset_x509_store() (M2Crypto.SMIME.SMIME method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EVP.Cipher.update">update() (M2Crypto.EVP.Cipher method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.EVP.HMAC.update">(M2Crypto.EVP.HMAC method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EVP.MessageDigest.update">(M2Crypto.EVP.MessageDigest method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EVP.PKey.update">(M2Crypto.EVP.PKey method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.RC4.RC4.update">(M2Crypto.RC4.RC4 method)</a>
+</li>
+ </ul></li>
+ </ul></td>
+ <td style="width: 33%; vertical-align: top;"><ul>
+ <li><a href="M2Crypto.html#M2Crypto.m2xmlrpclib.SSL_Transport.user_agent">user_agent (M2Crypto.m2xmlrpclib.SSL_Transport attribute)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.ASN1.LocalTimezone.utcoffset">utcoffset() (M2Crypto.ASN1.LocalTimezone method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.util.UtilError">UtilError</a>
+</li>
+ </ul></td>
+</tr></table>
+
+<h2 id="V">V</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+ <td style="width: 33%; vertical-align: top;"><ul>
+ <li><a href="M2Crypto.html#M2Crypto.AuthCookie.AuthCookie.value">value() (M2Crypto.AuthCookie.AuthCookie method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.DSA.DSA.verify">verify() (M2Crypto.DSA.DSA method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.RSA.RSA.verify">(M2Crypto.RSA.RSA method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.SMIME.SMIME.verify">(M2Crypto.SMIME.SMIME method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.Request.verify">(M2Crypto.X509.Request method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509.verify">(M2Crypto.X509.X509 method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.html#M2Crypto.DSA.DSA.verify_asn1">verify_asn1() (M2Crypto.DSA.DSA method)</a>
+</li>
+ </ul></td>
+ <td style="width: 33%; vertical-align: top;"><ul>
+ <li><a href="M2Crypto.html#M2Crypto.EC.EC.verify_dsa">verify_dsa() (M2Crypto.EC.EC method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EC.EC.verify_dsa_asn1">verify_dsa_asn1() (M2Crypto.EC.EC method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EVP.PKey.verify_final">verify_final() (M2Crypto.EVP.PKey method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EVP.PKey.verify_init">verify_init() (M2Crypto.EVP.PKey method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.verify_ok">verify_ok() (M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.RSA.RSA.verify_rsassa_pss">verify_rsassa_pss() (M2Crypto.RSA.RSA method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.EVP.PKey.verify_update">verify_update() (M2Crypto.EVP.PKey method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Cipher.Cipher.version">version() (M2Crypto.SSL.Cipher.Cipher method)</a>
+</li>
+ </ul></td>
+</tr></table>
+
+<h2 id="W">W</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+ <td style="width: 33%; vertical-align: top;"><ul>
+ <li><a href="M2Crypto.html#M2Crypto.BIO.BIO.write">write() (M2Crypto.BIO.BIO method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.SMIME.PKCS7.write">(M2Crypto.SMIME.PKCS7 method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.SMIME.SMIME.write">(M2Crypto.SMIME.SMIME method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Connection.Connection.write">(M2Crypto.SSL.Connection.Connection method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper.write">(M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper method)</a>
+</li>
+ </ul></li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Session.Session.write_bio">write_bio() (M2Crypto.SSL.Session.Session method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.BIO.BIO.write_close">write_close() (M2Crypto.BIO.BIO method)</a>
+
+ <ul>
+ <li><a href="M2Crypto.html#M2Crypto.BIO.CipherStream.write_close">(M2Crypto.BIO.CipherStream method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.BIO.MemoryBuffer.write_close">(M2Crypto.BIO.MemoryBuffer method)</a>
+</li>
+ </ul></li>
+ </ul></td>
+ <td style="width: 33%; vertical-align: top;"><ul>
+ <li><a href="M2Crypto.html#M2Crypto.SMIME.PKCS7.write_der">write_der() (M2Crypto.SMIME.PKCS7 method)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.BIO.BIO.writeable">writeable() (M2Crypto.BIO.BIO method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper.writeSequence">writeSequence() (M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper method)</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Checker.WrongCertificate">WrongCertificate</a>
+</li>
+ <li><a href="M2Crypto.SSL.html#M2Crypto.SSL.Checker.WrongHost">WrongHost</a>
+</li>
+ </ul></td>
+</tr></table>
+
+<h2 id="X">X</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+ <td style="width: 33%; vertical-align: top;"><ul>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509">X509 (class in M2Crypto.X509)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509_Extension">X509_Extension (class in M2Crypto.X509)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509_Extension_Stack">X509_Extension_Stack (class in M2Crypto.X509)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509_Name">X509_Name (class in M2Crypto.X509)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509_Name_Entry">X509_Name_Entry (class in M2Crypto.X509)</a>
+</li>
+ </ul></td>
+ <td style="width: 33%; vertical-align: top;"><ul>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509_Stack">X509_Stack (class in M2Crypto.X509)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509_Store">X509_Store (class in M2Crypto.X509)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509_Store_Context">X509_Store_Context (class in M2Crypto.X509)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.x509_store_default_cb">x509_store_default_cb() (in module M2Crypto.X509)</a>
+</li>
+ <li><a href="M2Crypto.html#M2Crypto.X509.X509Error">X509Error</a>
+</li>
+ </ul></td>
+</tr></table>
+
+
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="index.html">M2Crypto</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="M2Crypto.html">M2Crypto Package</a></li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="index.html">Documentation overview</a><ul>
+ </ul></li>
+</ul>
+</div>
+<div id="searchbox" style="display: none" role="search">
+ <h3>Quick search</h3>
+ <div class="searchformwrapper">
+ <form class="search" action="search.html" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ </div>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer">
+ &copy;2017, Matej Cepl <mcepl@cepl.eu>.
+
+ |
+ Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
+ &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
+
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/howto.ca.html b/doc/html/howto.ca.html
new file mode 100644
index 0000000..7f5bd21
--- /dev/null
+++ b/doc/html/howto.ca.html
@@ -0,0 +1,478 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>HOWTO: Creating your own CA with OpenSSL &#8212; M2Crypto documentation</title>
+ <link rel="stylesheet" href="_static/alabaster.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <script type="text/javascript" src="_static/language_data.js"></script>
+ <link rel="index" title="Index" href="genindex.html" />
+ <link rel="search" title="Search" href="search.html" />
+
+ <link rel="stylesheet" href="_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+ <div class="section" id="howto-creating-your-own-ca-with-openssl">
+<span id="howto-ca"></span><h1>HOWTO: Creating your own CA with OpenSSL<a class="headerlink" href="#howto-creating-your-own-ca-with-openssl" title="Permalink to this headline">¶</a></h1>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">author:</th><td class="field-body">Pheng Siong Ng &lt;<a class="reference external" href="mailto:ngps&#37;&#52;&#48;post1&#46;com">ngps<span>&#64;</span>post1<span>&#46;</span>com</a>&gt;</td>
+</tr>
+<tr class="field-even field"><th class="field-name">copyright:</th><td class="field-body">© 2000, 2001 by Ng Pheng Siong.</td>
+</tr>
+</tbody>
+</table>
+<div class="section" id="introduction">
+<h2>Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline">¶</a></h2>
+<p>This is a HOWTO on creating your own <em>certification authority</em> (<em>CA</em>)
+with OpenSSL.</p>
+<p>I last created a CA about a year ago, when I began work on
+<a class="reference external" href="https://gitlab.com/m2crypto/m2crypto/">M2Crypto</a> and needed
+certificates for the SSL bits. I accepted the tools’ default
+settings then, e.g., certificate validity of 365 days; this meant
+that my certificates, including my CA’s certificate, have now
+expired.</p>
+<p>Since I am using these certificates for M2Crypto’s demonstration
+programs (and I have forgotten the passphrase to the CA’s private
+key), I decided to discard the old CA and start afresh. I also
+decided to document the process, hence this HOWTO.</p>
+</div>
+<div class="section" id="the-procedure">
+<h2>The Procedure<a class="headerlink" href="#the-procedure" title="Permalink to this headline">¶</a></h2>
+<p>I use <code class="docutils literal notranslate"><span class="pre">CA.pl</span></code>, a Perl program written by Steve Hanson and bundled with
+OpenSSL.</p>
+<p>The following are the steps to create a CA:</p>
+<ol class="arabic">
+<li><p class="first">Choose a directory to do your CA work. All commands are executed
+within this directory. Let’s call the directory <code class="docutils literal notranslate"><span class="pre">demo</span></code>.</p>
+</li>
+<li><p class="first">Copy <code class="docutils literal notranslate"><span class="pre">CA.pl</span></code> and <code class="docutils literal notranslate"><span class="pre">openssl.cnf</span></code> into <code class="docutils literal notranslate"><span class="pre">demo</span></code>.</p>
+</li>
+<li><p class="first">Apply the following patch to <code class="docutils literal notranslate"><span class="pre">CA.pl</span></code>, which allows it to generate a
+CA certificate with a validity period of 1095 days, i.e.,
+3 years:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>--- CA.pl.org Sat Mar 31 12:40:13 2001
++++ CA.pl Sat Mar 31 12:41:15 2001
+@@ -97,7 +97,7 @@
+ } else {
+ print &quot;Making CA certificate ...\n&quot;;
+ system (&quot;$REQ -new -x509 -keyout &quot; .
+- &quot;${CATOP}/private/$CAKEY -out ${CATOP}/$CACERT $DAYS&quot;);
++ &quot;${CATOP}/private/$CAKEY -out ${CATOP}/$CACERT -days 1095&quot;);
+ $RET=$?;
+ }
+ }
+</pre></div>
+</div>
+</li>
+<li><p class="first">Create a new CA like this:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">./</span><span class="n">CA</span><span class="o">.</span><span class="n">pl</span> <span class="o">-</span><span class="n">newca</span>
+
+<span class="n">A</span> <span class="n">certificate</span> <span class="n">filename</span> <span class="p">(</span><span class="ow">or</span> <span class="n">enter</span> <span class="n">to</span> <span class="n">create</span><span class="p">)</span> <span class="o">&lt;</span><span class="n">enter</span><span class="o">&gt;</span>
+
+<span class="n">Making</span> <span class="n">CA</span> <span class="n">certificate</span> <span class="o">...</span>
+<span class="n">Using</span> <span class="n">configuration</span> <span class="kn">from</span> <span class="nn">openssl.cnf</span>
+<span class="n">Generating</span> <span class="n">a</span> <span class="mi">1024</span> <span class="n">bit</span> <span class="n">RSA</span> <span class="n">private</span> <span class="n">key</span>
+<span class="o">............++++++</span>
+<span class="o">......................++++++</span>
+<span class="n">writing</span> <span class="n">new</span> <span class="n">private</span> <span class="n">key</span> <span class="n">to</span> <span class="s1">&#39;./demoCA/private/cakey.pem&#39;</span>
+<span class="n">Enter</span> <span class="n">PEM</span> <span class="k">pass</span> <span class="n">phrase</span><span class="p">:</span> <span class="o">&lt;</span><span class="n">secret</span> <span class="n">passphrase</span> <span class="n">here</span><span class="o">&gt;</span>
+<span class="n">Verifying</span> <span class="n">password</span> <span class="o">-</span> <span class="n">Enter</span> <span class="n">PEM</span> <span class="k">pass</span> <span class="n">phrase</span><span class="p">:</span> <span class="o">&lt;</span><span class="n">secret</span> <span class="n">passphrase</span> <span class="n">again</span><span class="o">&gt;</span>
+<span class="o">-----</span>
+<span class="n">You</span> <span class="n">are</span> <span class="n">about</span> <span class="n">to</span> <span class="n">be</span> <span class="n">asked</span> <span class="n">to</span> <span class="n">enter</span> <span class="n">information</span> <span class="n">that</span> <span class="n">will</span> <span class="n">be</span> <span class="n">incorporated</span>
+<span class="n">into</span> <span class="n">your</span> <span class="n">certificate</span> <span class="n">request</span><span class="o">.</span>
+<span class="n">What</span> <span class="n">you</span> <span class="n">are</span> <span class="n">about</span> <span class="n">to</span> <span class="n">enter</span> <span class="ow">is</span> <span class="n">what</span> <span class="ow">is</span> <span class="n">called</span> <span class="n">a</span> <span class="n">Distinguished</span> <span class="n">Name</span> <span class="ow">or</span> <span class="n">a</span> <span class="n">DN</span><span class="o">.</span>
+<span class="n">There</span> <span class="n">are</span> <span class="n">quite</span> <span class="n">a</span> <span class="n">few</span> <span class="n">fields</span> <span class="n">but</span> <span class="n">you</span> <span class="n">can</span> <span class="n">leave</span> <span class="n">some</span> <span class="n">blank</span>
+<span class="n">For</span> <span class="n">some</span> <span class="n">fields</span> <span class="n">there</span> <span class="n">will</span> <span class="n">be</span> <span class="n">a</span> <span class="n">default</span> <span class="n">value</span><span class="p">,</span>
+<span class="n">If</span> <span class="n">you</span> <span class="n">enter</span> <span class="s1">&#39;.&#39;</span><span class="p">,</span> <span class="n">the</span> <span class="n">field</span> <span class="n">will</span> <span class="n">be</span> <span class="n">left</span> <span class="n">blank</span><span class="o">.</span>
+<span class="o">-----</span>
+<span class="n">Country</span> <span class="n">Name</span> <span class="p">(</span><span class="mi">2</span> <span class="n">letter</span> <span class="n">code</span><span class="p">)</span> <span class="p">[</span><span class="n">AU</span><span class="p">]:</span><span class="n">SG</span>
+<span class="n">State</span> <span class="ow">or</span> <span class="n">Province</span> <span class="n">Name</span> <span class="p">(</span><span class="n">full</span> <span class="n">name</span><span class="p">)</span> <span class="p">[</span><span class="n">Some</span><span class="o">-</span><span class="n">State</span><span class="p">]:</span><span class="o">.</span>
+<span class="n">Locality</span> <span class="n">Name</span> <span class="p">(</span><span class="n">eg</span><span class="p">,</span> <span class="n">city</span><span class="p">)</span> <span class="p">[]:</span><span class="o">..</span>
+<span class="n">Organization</span> <span class="n">Name</span> <span class="p">(</span><span class="n">eg</span><span class="p">,</span> <span class="n">company</span><span class="p">)</span> <span class="p">[</span><span class="n">Internet</span> <span class="n">Widgits</span> <span class="n">Pty</span> <span class="n">Ltd</span><span class="p">]:</span><span class="n">DemoCA</span>
+<span class="n">Organizational</span> <span class="n">Unit</span> <span class="n">Name</span> <span class="p">(</span><span class="n">eg</span><span class="p">,</span> <span class="n">section</span><span class="p">)</span> <span class="p">[]:</span><span class="o">.</span>
+<span class="n">Common</span> <span class="n">Name</span> <span class="p">(</span><span class="n">eg</span><span class="p">,</span> <span class="n">YOUR</span> <span class="n">name</span><span class="p">)</span> <span class="p">[]:</span><span class="n">DemoCA</span> <span class="n">Certificate</span> <span class="n">Master</span>
+<span class="n">Email</span> <span class="n">Address</span> <span class="p">[]:</span><span class="n">certmaster</span><span class="nd">@democa</span><span class="o">.</span><span class="n">dom</span>
+</pre></div>
+</div>
+<p>This creates a new CA in the directory <code class="docutils literal notranslate"><span class="pre">demoCA</span></code>. The CA’s
+self-signed certificate is in <code class="docutils literal notranslate"><span class="pre">demoCA/cacert.pem</span></code> and its RSA key
+pair is in <code class="docutils literal notranslate"><span class="pre">demoCA/private/cakey.pem</span></code>.</p>
+<p><code class="docutils literal notranslate"><span class="pre">demoCA/private/cakey.pem</span></code> looks like this:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">cat</span> <span class="n">demoCA</span><span class="o">/</span><span class="n">private</span><span class="o">/</span><span class="n">cakey</span><span class="o">.</span><span class="n">pem</span>
+
+<span class="o">-----</span><span class="n">BEGIN</span> <span class="n">RSA</span> <span class="n">PRIVATE</span> <span class="n">KEY</span><span class="o">-----</span>
+<span class="n">Proc</span><span class="o">-</span><span class="n">Type</span><span class="p">:</span> <span class="mi">4</span><span class="p">,</span><span class="n">ENCRYPTED</span>
+<span class="n">DEK</span><span class="o">-</span><span class="n">Info</span><span class="p">:</span> <span class="n">DES</span><span class="o">-</span><span class="n">EDE3</span><span class="o">-</span><span class="n">CBC</span><span class="p">,</span><span class="mi">19973</span><span class="n">A9DBBB601BA</span>
+
+<span class="n">eOq9WFScNiI4</span><span class="o">/</span><span class="n">UWEUaSnGTKpJv2JYuMD3HwQox2Q3Cd4zGqVjJ6gF3exa5126cKf</span>
+<span class="n">X</span><span class="o">/</span><span class="n">bMVnwbPpuFZPiAIvaLyCjT6pYeXTBbSzs7</span><span class="o">/</span><span class="n">GQnvEOv</span><span class="o">+</span><span class="n">nYnDUFWi0Qm92qLk0uy</span>
+<span class="n">pFi</span><span class="o">/</span><span class="n">M1aWheN3vir2ZlAw</span><span class="o">+</span><span class="n">DW0bOOZhj8tC7Co7lMYb0YE271b6</span><span class="o">/</span><span class="n">YRPZCwQ3GXAHUJ</span>
+<span class="o">+</span><span class="n">aMYxlUDrK45aCUa</span><span class="o">/</span><span class="mi">1</span><span class="n">CZDzTgk7h9cDgx2QJSIvYMYytCfI3zsuZMJS8</span><span class="o">/</span><span class="mi">4</span><span class="n">OXLL0bI</span>
+<span class="n">lKmAc1dwB3DqGJt5XK4WJesiNfdxeCNEgAcYtEAgYZTPIApU</span><span class="o">+</span><span class="n">kTgTCIxJl2nMW7j</span>
+<span class="n">ax</span><span class="o">+</span><span class="n">Q1z7g</span><span class="o">+</span><span class="mi">4</span><span class="n">MpgG20WD633D4z4dTlDdz</span><span class="o">+</span><span class="n">dnLi0rvuvxiwt</span><span class="o">+</span><span class="n">dUhrqiML1tyi</span><span class="o">+</span><span class="n">Z6EBH</span>
+<span class="n">jU4</span><span class="o">/</span><span class="n">cLBWev3rYfrlp4x8J9mDte0YKOk3t0wQOHqRetTsIfdtjnFp</span><span class="o">/</span><span class="n">Hu3qDmTCWjD</span>
+<span class="n">z</span><span class="o">/</span><span class="n">g7PPoO</span><span class="o">/</span><span class="n">bg</span><span class="o">/</span><span class="n">B877J9WBPbL</span><span class="o">/</span><span class="mi">1</span><span class="n">hXXFYo88M</span><span class="o">+</span><span class="mi">2</span><span class="n">aGlPOgDcFdiOqbLb2DCscohMbbVr</span>
+<span class="n">A4mgiy2kwWfIE73qiyV7yyG8FlRvr1iib</span><span class="o">+</span><span class="n">jbT3LTGf743utYAAs7HNGuOUObhoyt</span>
+<span class="n">jYvBD7ACn35P5YX7KTqvqErwdijxYCaNBCnvmRtmYSaNw9Kv1UJTxc5Vx7YLwIPk</span>
+<span class="n">E9KyBgKI7vPOjWBZ27</span><span class="o">+</span><span class="n">zOvNycmv1ciNtpALAw4bWtXnhCDVTHaVDy34OkheMzNCg</span>
+<span class="mi">2</span><span class="n">cjcBFzOkMIjcI03KbTQXOFIQGlsTWXGzkNf</span><span class="o">/</span><span class="n">zBQ</span><span class="o">+</span><span class="n">KksT1MCj</span><span class="o">+</span><span class="n">zBXSCvlDASMckg</span>
+<span class="n">kef21pGgUqPF14gKGfWX3sV4bjc1vbrRwq6zlG3nMuYqR5MtJJY9eQ</span><span class="o">==</span>
+<span class="o">-----</span><span class="n">END</span> <span class="n">RSA</span> <span class="n">PRIVATE</span> <span class="n">KEY</span><span class="o">-----</span>
+</pre></div>
+</div>
+</li>
+<li><p class="first">Next, generate a certificate request:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">./</span><span class="n">CA</span><span class="o">.</span><span class="n">pl</span> <span class="o">-</span><span class="n">newreq</span>
+
+<span class="n">Using</span> <span class="n">configuration</span> <span class="kn">from</span> <span class="nn">openssl.cnf</span>
+<span class="n">Generating</span> <span class="n">a</span> <span class="mi">1024</span> <span class="n">bit</span> <span class="n">RSA</span> <span class="n">private</span> <span class="n">key</span>
+<span class="o">..........++++++</span>
+<span class="o">..............++++++</span>
+<span class="n">writing</span> <span class="n">new</span> <span class="n">private</span> <span class="n">key</span> <span class="n">to</span> <span class="s1">&#39;newreq.pem&#39;</span>
+<span class="n">Enter</span> <span class="n">PEM</span> <span class="k">pass</span> <span class="n">phrase</span><span class="p">:</span> <span class="o">&lt;</span><span class="n">another</span> <span class="n">secret</span> <span class="n">passphrase</span> <span class="n">here</span><span class="o">&gt;</span>
+<span class="n">Verifying</span> <span class="n">password</span> <span class="o">-</span> <span class="n">Enter</span> <span class="n">PEM</span> <span class="k">pass</span> <span class="n">phrase</span><span class="p">:</span> <span class="o">&lt;</span><span class="n">another</span> <span class="n">secret</span> <span class="n">passphrase</span> <span class="n">again</span><span class="o">&gt;</span>
+<span class="o">-----</span>
+<span class="n">You</span> <span class="n">are</span> <span class="n">about</span> <span class="n">to</span> <span class="n">be</span> <span class="n">asked</span> <span class="n">to</span> <span class="n">enter</span> <span class="n">information</span> <span class="n">that</span> <span class="n">will</span> <span class="n">be</span> <span class="n">incorporated</span>
+<span class="n">into</span> <span class="n">your</span> <span class="n">certificate</span> <span class="n">request</span><span class="o">.</span>
+<span class="n">What</span> <span class="n">you</span> <span class="n">are</span> <span class="n">about</span> <span class="n">to</span> <span class="n">enter</span> <span class="ow">is</span> <span class="n">what</span> <span class="ow">is</span> <span class="n">called</span> <span class="n">a</span> <span class="n">Distinguished</span> <span class="n">Name</span> <span class="ow">or</span> <span class="n">a</span> <span class="n">DN</span><span class="o">.</span>
+<span class="n">There</span> <span class="n">are</span> <span class="n">quite</span> <span class="n">a</span> <span class="n">few</span> <span class="n">fields</span> <span class="n">but</span> <span class="n">you</span> <span class="n">can</span> <span class="n">leave</span> <span class="n">some</span> <span class="n">blank</span>
+<span class="n">For</span> <span class="n">some</span> <span class="n">fields</span> <span class="n">there</span> <span class="n">will</span> <span class="n">be</span> <span class="n">a</span> <span class="n">default</span> <span class="n">value</span><span class="p">,</span>
+<span class="n">If</span> <span class="n">you</span> <span class="n">enter</span> <span class="s1">&#39;.&#39;</span><span class="p">,</span> <span class="n">the</span> <span class="n">field</span> <span class="n">will</span> <span class="n">be</span> <span class="n">left</span> <span class="n">blank</span><span class="o">.</span>
+<span class="o">-----</span>
+<span class="n">Country</span> <span class="n">Name</span> <span class="p">(</span><span class="mi">2</span> <span class="n">letter</span> <span class="n">code</span><span class="p">)</span> <span class="p">[</span><span class="n">AU</span><span class="p">]:</span><span class="n">SG</span>
+<span class="n">State</span> <span class="ow">or</span> <span class="n">Province</span> <span class="n">Name</span> <span class="p">(</span><span class="n">full</span> <span class="n">name</span><span class="p">)</span> <span class="p">[</span><span class="n">Some</span><span class="o">-</span><span class="n">State</span><span class="p">]:</span><span class="o">..</span>
+<span class="n">Locality</span> <span class="n">Name</span> <span class="p">(</span><span class="n">eg</span><span class="p">,</span> <span class="n">city</span><span class="p">)</span> <span class="p">[]:</span><span class="o">.</span>
+<span class="n">Organization</span> <span class="n">Name</span> <span class="p">(</span><span class="n">eg</span><span class="p">,</span> <span class="n">company</span><span class="p">)</span> <span class="p">[</span><span class="n">Internet</span> <span class="n">Widgits</span> <span class="n">Pty</span> <span class="n">Ltd</span><span class="p">]:</span><span class="n">M2Crypto</span>
+<span class="n">Organizational</span> <span class="n">Unit</span> <span class="n">Name</span> <span class="p">(</span><span class="n">eg</span><span class="p">,</span> <span class="n">section</span><span class="p">)</span> <span class="p">[]:</span><span class="o">.</span>
+<span class="n">Common</span> <span class="n">Name</span> <span class="p">(</span><span class="n">eg</span><span class="p">,</span> <span class="n">YOUR</span> <span class="n">name</span><span class="p">)</span> <span class="p">[]:</span><span class="n">localhost</span>
+<span class="n">Email</span> <span class="n">Address</span> <span class="p">[]:</span><span class="n">admin</span><span class="nd">@server</span><span class="o">.</span><span class="n">example</span><span class="o">.</span><span class="n">dom</span>
+
+<span class="n">Please</span> <span class="n">enter</span> <span class="n">the</span> <span class="n">following</span> <span class="s1">&#39;extra&#39;</span> <span class="n">attributes</span>
+<span class="n">to</span> <span class="n">be</span> <span class="n">sent</span> <span class="k">with</span> <span class="n">your</span> <span class="n">certificate</span> <span class="n">request</span>
+<span class="n">A</span> <span class="n">challenge</span> <span class="n">password</span> <span class="p">[]:</span><span class="o">&lt;</span><span class="n">enter</span><span class="o">&gt;</span>
+<span class="n">An</span> <span class="n">optional</span> <span class="n">company</span> <span class="n">name</span> <span class="p">[]:</span><span class="o">&lt;</span><span class="n">enter</span><span class="o">&gt;</span>
+<span class="n">Request</span> <span class="p">(</span><span class="ow">and</span> <span class="n">private</span> <span class="n">key</span><span class="p">)</span> <span class="ow">is</span> <span class="ow">in</span> <span class="n">newreq</span><span class="o">.</span><span class="n">pem</span>
+</pre></div>
+</div>
+</li>
+</ol>
+<p></p>
+<blockquote>
+<div><p>The certificate request and private key in <code class="docutils literal notranslate"><span class="pre">newreq.pem</span></code> looks like
+this:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">cat</span> <span class="n">newreq</span><span class="o">.</span><span class="n">pem</span>
+
+<span class="o">-----</span><span class="n">BEGIN</span> <span class="n">RSA</span> <span class="n">PRIVATE</span> <span class="n">KEY</span><span class="o">-----</span>
+<span class="n">Proc</span><span class="o">-</span><span class="n">Type</span><span class="p">:</span> <span class="mi">4</span><span class="p">,</span><span class="n">ENCRYPTED</span>
+<span class="n">DEK</span><span class="o">-</span><span class="n">Info</span><span class="p">:</span> <span class="n">DES</span><span class="o">-</span><span class="n">EDE3</span><span class="o">-</span><span class="n">CBC</span><span class="p">,</span><span class="mi">41</span><span class="n">B2874DF3D02DD4</span>
+
+<span class="n">mg611EoVkLEooSTv</span><span class="o">+</span><span class="n">qTM0Ddmm</span><span class="o">/</span><span class="n">M1jE</span><span class="o">/</span><span class="n">Jy5RD</span><span class="o">/</span><span class="n">sc3LSMhuGu9xc26OgsTJmkQuIAh</span>
+<span class="n">J</span><span class="o">/</span><span class="n">B4lAw8G59VTG6DykeEtrG0rUBx4bggc7PKbFuiN423YjJODWcHvVgnPOzXMQt</span><span class="o">+</span>
+<span class="n">lY4tPl5</span><span class="o">+</span><span class="mi">217</span><span class="n">MRHyx2NsWGrpkQNdu3GeSPOVMl3jeQiaXupONbwQ7rj42</span><span class="o">+</span><span class="n">X</span><span class="o">/</span><span class="n">VtAJP</span>
+<span class="n">W4D1NNwu8aGCPyShsEXHc</span><span class="o">/</span><span class="n">fI1WDpphYWke97pOjIZVQESFZOPty5HjIYZux4U</span><span class="o">+</span><span class="n">td</span>
+<span class="n">W81xODtq2ecJXc8fn2Wpa9y5VD1LT7oJksOuL1</span><span class="o">+</span><span class="n">Z04OVaeUe4x0swM17HlBm2kVt</span>
+<span class="n">fe</span><span class="o">/</span><span class="n">C</span><span class="o">/</span><span class="n">L6kN27MwZhE331VjtTjSGl4</span><span class="o">/</span><span class="n">gknqQDbLOtqT06f3OISsDJETm2itllyhgzv</span>
+<span class="n">C6Fi3N03rGFmKectijC</span><span class="o">+</span><span class="n">tws5k</span><span class="o">+</span><span class="n">P</span><span class="o">+</span><span class="n">HRG6sai33usk8xPokJqA</span><span class="o">+</span><span class="n">HYSWPz1XVlpRmv4</span>
+<span class="n">kdjQOdST7ovU62mOTgf3ARcduPPwuzTfxOlYONe5NioO1APVHBrInQwcpLkpOTQR</span>
+<span class="n">vI4roIN</span><span class="o">+</span><span class="n">b75</span><span class="o">/</span><span class="n">nihUWGUJn</span><span class="o">/</span><span class="n">nbbBa2Yl0N5Gs1Tyiy9Z</span><span class="o">+</span><span class="n">CcRT2TfWKBBFlEUIFl7Mb</span>
+<span class="n">J9fTV3DI</span><span class="o">+</span><span class="n">k</span><span class="o">+</span><span class="n">akbR4il1NkQ8EcSmCr3WpA0I9n0EHI7ZVpVaHxc0sqaPFl8YGdFHq</span>
+<span class="mi">1</span><span class="n">Qk53C</span><span class="o">/</span><span class="n">w6</span><span class="o">+</span><span class="n">qPpDzT3yKFmG2LZytAAM1czvb6RbNRJJP2ZrpBwn</span><span class="o">/</span><span class="n">h99sUTo</span><span class="o">/</span><span class="n">yPfxY</span>
+<span class="n">nueYmFJDm0uVNtG0icXGNUfSfnjKNTtHPAgyKGetRIC3kgJz</span><span class="o">/</span><span class="n">bo2w7EI6iEjBAzK</span>
+<span class="n">l5TRm4x6ZJxwuXXMiJCehMMd8TC8ybwWO4AO19B3ebFFeTVsUgxSGA</span><span class="o">==</span>
+<span class="o">-----</span><span class="n">END</span> <span class="n">RSA</span> <span class="n">PRIVATE</span> <span class="n">KEY</span><span class="o">-----</span>
+<span class="o">-----</span><span class="n">BEGIN</span> <span class="n">CERTIFICATE</span> <span class="n">REQUEST</span><span class="o">-----</span>
+<span class="n">MIIBnTCCAQYCAQAwXTELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRIw</span>
+<span class="n">EAYDVQQDEwlsb2NhbGhvc3QxJzAlBgkqhkiG9w0BCQEWGGFkbWluQHNlcnZlci5l</span>
+<span class="n">eGFtcGxlLmRvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAr1nYY1Qrll1r</span>
+<span class="n">uB</span><span class="o">/</span><span class="n">FqlCRrr5nvupdIN</span><span class="o">+</span><span class="mi">3</span><span class="n">wF7q915tvEQoc74bnu6b8IbbGRMhzdzmvQ4SzFfVEAuM</span>
+<span class="n">MuTHeybPq5th7YDrTNizKKxOBnqE2KYuX9X22A1Kh49soJJFg6kPb9MUgiZBiMlv</span>
+<span class="n">tb7K3CHfgw5WagWnLl8Lb</span><span class="o">+</span><span class="n">ccvKZZl</span><span class="o">+</span><span class="mi">8</span><span class="n">CAwEAAaAAMA0GCSqGSIb3DQEBBAUAA4GB</span>
+<span class="n">AHpoRp5YS55CZpy</span><span class="o">+</span><span class="n">wdigQEwjL</span><span class="o">/</span><span class="n">wSluvo</span><span class="o">+</span><span class="n">WjtpvP0YoBMJu4VMKeZi405R7o8oEwi</span>
+<span class="n">PdlrrliKNknFmHKIaCKTLRcU59ScA6ADEIWUzqmUzP5Cs6jrSRo3NKfg1bd09D1K</span>
+<span class="mi">9</span><span class="n">rsQkRc9Urv9mRBIsredGnYECNeRaK5R1yzpOowninXC</span>
+<span class="o">-----</span><span class="n">END</span> <span class="n">CERTIFICATE</span> <span class="n">REQUEST</span><span class="o">-----</span>
+</pre></div>
+</div>
+</div></blockquote>
+<p></p>
+<blockquote>
+<div><p>Decoding the certificate request gives the following:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">openssl</span> <span class="n">req</span> <span class="o">-</span><span class="n">text</span> <span class="o">-</span><span class="n">noout</span> <span class="o">&lt;</span> <span class="n">newreq</span><span class="o">.</span><span class="n">pem</span>
+
+<span class="n">Using</span> <span class="n">configuration</span> <span class="kn">from</span> <span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="n">local</span><span class="o">/</span><span class="n">pkg</span><span class="o">/</span><span class="n">openssl</span><span class="o">/</span><span class="n">openssl</span><span class="o">.</span><span class="n">cnf</span>
+<span class="n">Certificate</span> <span class="n">Request</span><span class="p">:</span>
+ <span class="n">Data</span><span class="p">:</span>
+ <span class="n">Version</span><span class="p">:</span> <span class="mi">0</span> <span class="p">(</span><span class="mh">0x0</span><span class="p">)</span>
+ <span class="n">Subject</span><span class="p">:</span> <span class="n">C</span><span class="o">=</span><span class="n">SG</span><span class="p">,</span> <span class="n">O</span><span class="o">=</span><span class="n">M2Crypto</span><span class="p">,</span> <span class="n">CN</span><span class="o">=</span><span class="n">localhost</span><span class="o">/</span><span class="n">Email</span><span class="o">=</span><span class="n">admin</span><span class="nd">@server</span><span class="o">.</span><span class="n">example</span><span class="o">.</span><span class="n">dom</span>
+ <span class="n">Subject</span> <span class="n">Public</span> <span class="n">Key</span> <span class="n">Info</span><span class="p">:</span>
+ <span class="n">Public</span> <span class="n">Key</span> <span class="n">Algorithm</span><span class="p">:</span> <span class="n">rsaEncryption</span>
+ <span class="n">RSA</span> <span class="n">Public</span> <span class="n">Key</span><span class="p">:</span> <span class="p">(</span><span class="mi">1024</span> <span class="n">bit</span><span class="p">)</span>
+ <span class="n">Modulus</span> <span class="p">(</span><span class="mi">1024</span> <span class="n">bit</span><span class="p">):</span>
+ <span class="mi">00</span><span class="p">:</span><span class="n">af</span><span class="p">:</span><span class="mi">59</span><span class="p">:</span><span class="n">d8</span><span class="p">:</span><span class="mi">63</span><span class="p">:</span><span class="mi">54</span><span class="p">:</span><span class="mi">2</span><span class="n">b</span><span class="p">:</span><span class="mi">96</span><span class="p">:</span><span class="mi">5</span><span class="n">d</span><span class="p">:</span><span class="mi">6</span><span class="n">b</span><span class="p">:</span><span class="n">b8</span><span class="p">:</span><span class="mi">1</span><span class="n">f</span><span class="p">:</span><span class="n">c5</span><span class="p">:</span><span class="n">aa</span><span class="p">:</span><span class="mi">50</span><span class="p">:</span>
+ <span class="mi">91</span><span class="p">:</span><span class="n">ae</span><span class="p">:</span><span class="n">be</span><span class="p">:</span><span class="mi">67</span><span class="p">:</span><span class="n">be</span><span class="p">:</span><span class="n">ea</span><span class="p">:</span><span class="mi">5</span><span class="n">d</span><span class="p">:</span><span class="mi">20</span><span class="p">:</span><span class="n">df</span><span class="p">:</span><span class="n">b7</span><span class="p">:</span><span class="n">c0</span><span class="p">:</span><span class="mi">5</span><span class="n">e</span><span class="p">:</span><span class="n">ea</span><span class="p">:</span><span class="n">f7</span><span class="p">:</span><span class="mi">5</span><span class="n">e</span><span class="p">:</span>
+ <span class="mi">6</span><span class="n">d</span><span class="p">:</span><span class="n">bc</span><span class="p">:</span><span class="mi">44</span><span class="p">:</span><span class="mi">28</span><span class="p">:</span><span class="mi">73</span><span class="p">:</span><span class="n">be</span><span class="p">:</span><span class="mi">1</span><span class="n">b</span><span class="p">:</span><span class="mi">9</span><span class="n">e</span><span class="p">:</span><span class="n">ee</span><span class="p">:</span><span class="mi">9</span><span class="n">b</span><span class="p">:</span><span class="n">f0</span><span class="p">:</span><span class="mi">86</span><span class="p">:</span><span class="n">db</span><span class="p">:</span><span class="mi">19</span><span class="p">:</span><span class="mi">13</span><span class="p">:</span>
+ <span class="mi">21</span><span class="p">:</span><span class="n">cd</span><span class="p">:</span><span class="n">dc</span><span class="p">:</span><span class="n">e6</span><span class="p">:</span><span class="n">bd</span><span class="p">:</span><span class="mi">0</span><span class="n">e</span><span class="p">:</span><span class="mi">12</span><span class="p">:</span><span class="n">cc</span><span class="p">:</span><span class="mi">57</span><span class="p">:</span><span class="n">d5</span><span class="p">:</span><span class="mi">10</span><span class="p">:</span><span class="mi">0</span><span class="n">b</span><span class="p">:</span><span class="mi">8</span><span class="n">c</span><span class="p">:</span><span class="mi">32</span><span class="p">:</span><span class="n">e4</span><span class="p">:</span>
+ <span class="n">c7</span><span class="p">:</span><span class="mi">7</span><span class="n">b</span><span class="p">:</span><span class="mi">26</span><span class="p">:</span><span class="n">cf</span><span class="p">:</span><span class="n">ab</span><span class="p">:</span><span class="mi">9</span><span class="n">b</span><span class="p">:</span><span class="mi">61</span><span class="p">:</span><span class="n">ed</span><span class="p">:</span><span class="mi">80</span><span class="p">:</span><span class="n">eb</span><span class="p">:</span><span class="mi">4</span><span class="n">c</span><span class="p">:</span><span class="n">d8</span><span class="p">:</span><span class="n">b3</span><span class="p">:</span><span class="mi">28</span><span class="p">:</span><span class="n">ac</span><span class="p">:</span>
+ <span class="mi">4</span><span class="n">e</span><span class="p">:</span><span class="mi">06</span><span class="p">:</span><span class="mi">7</span><span class="n">a</span><span class="p">:</span><span class="mi">84</span><span class="p">:</span><span class="n">d8</span><span class="p">:</span><span class="n">a6</span><span class="p">:</span><span class="mi">2</span><span class="n">e</span><span class="p">:</span><span class="mi">5</span><span class="n">f</span><span class="p">:</span><span class="n">d5</span><span class="p">:</span><span class="n">f6</span><span class="p">:</span><span class="n">d8</span><span class="p">:</span><span class="mi">0</span><span class="n">d</span><span class="p">:</span><span class="mi">4</span><span class="n">a</span><span class="p">:</span><span class="mi">87</span><span class="p">:</span><span class="mi">8</span><span class="n">f</span><span class="p">:</span>
+ <span class="mi">6</span><span class="n">c</span><span class="p">:</span><span class="n">a0</span><span class="p">:</span><span class="mi">92</span><span class="p">:</span><span class="mi">45</span><span class="p">:</span><span class="mi">83</span><span class="p">:</span><span class="n">a9</span><span class="p">:</span><span class="mi">0</span><span class="n">f</span><span class="p">:</span><span class="mi">6</span><span class="n">f</span><span class="p">:</span><span class="n">d3</span><span class="p">:</span><span class="mi">14</span><span class="p">:</span><span class="mi">82</span><span class="p">:</span><span class="mi">26</span><span class="p">:</span><span class="mi">41</span><span class="p">:</span><span class="mi">88</span><span class="p">:</span><span class="n">c9</span><span class="p">:</span>
+ <span class="mi">6</span><span class="n">f</span><span class="p">:</span><span class="n">b5</span><span class="p">:</span><span class="n">be</span><span class="p">:</span><span class="n">ca</span><span class="p">:</span><span class="n">dc</span><span class="p">:</span><span class="mi">21</span><span class="p">:</span><span class="n">df</span><span class="p">:</span><span class="mi">83</span><span class="p">:</span><span class="mi">0</span><span class="n">e</span><span class="p">:</span><span class="mi">56</span><span class="p">:</span><span class="mi">6</span><span class="n">a</span><span class="p">:</span><span class="mi">05</span><span class="p">:</span><span class="n">a7</span><span class="p">:</span><span class="mi">2</span><span class="n">e</span><span class="p">:</span><span class="mi">5</span><span class="n">f</span><span class="p">:</span>
+ <span class="mi">0</span><span class="n">b</span><span class="p">:</span><span class="mi">6</span><span class="n">f</span><span class="p">:</span><span class="n">e7</span><span class="p">:</span><span class="mi">1</span><span class="n">c</span><span class="p">:</span><span class="n">bc</span><span class="p">:</span><span class="n">a6</span><span class="p">:</span><span class="mi">59</span><span class="p">:</span><span class="mi">97</span><span class="p">:</span><span class="n">ef</span>
+ <span class="n">Exponent</span><span class="p">:</span> <span class="mi">65537</span> <span class="p">(</span><span class="mh">0x10001</span><span class="p">)</span>
+ <span class="n">Attributes</span><span class="p">:</span>
+ <span class="n">a0</span><span class="p">:</span><span class="mi">00</span>
+ <span class="n">Signature</span> <span class="n">Algorithm</span><span class="p">:</span> <span class="n">md5WithRSAEncryption</span>
+ <span class="mi">7</span><span class="n">a</span><span class="p">:</span><span class="mi">68</span><span class="p">:</span><span class="mi">46</span><span class="p">:</span><span class="mi">9</span><span class="n">e</span><span class="p">:</span><span class="mi">58</span><span class="p">:</span><span class="mi">4</span><span class="n">b</span><span class="p">:</span><span class="mi">9</span><span class="n">e</span><span class="p">:</span><span class="mi">42</span><span class="p">:</span><span class="mi">66</span><span class="p">:</span><span class="mi">9</span><span class="n">c</span><span class="p">:</span><span class="n">be</span><span class="p">:</span><span class="n">c1</span><span class="p">:</span><span class="n">d8</span><span class="p">:</span><span class="n">a0</span><span class="p">:</span><span class="mi">40</span><span class="p">:</span><span class="mi">4</span><span class="n">c</span><span class="p">:</span><span class="mi">23</span><span class="p">:</span><span class="mi">2</span><span class="n">f</span><span class="p">:</span>
+ <span class="n">fc</span><span class="p">:</span><span class="mi">12</span><span class="p">:</span><span class="mi">96</span><span class="p">:</span><span class="n">eb</span><span class="p">:</span><span class="n">e8</span><span class="p">:</span><span class="n">f9</span><span class="p">:</span><span class="mi">68</span><span class="p">:</span><span class="n">ed</span><span class="p">:</span><span class="n">a6</span><span class="p">:</span><span class="n">f3</span><span class="p">:</span><span class="n">f4</span><span class="p">:</span><span class="mi">62</span><span class="p">:</span><span class="mi">80</span><span class="p">:</span><span class="mi">4</span><span class="n">c</span><span class="p">:</span><span class="mi">26</span><span class="p">:</span><span class="n">ee</span><span class="p">:</span><span class="mi">15</span><span class="p">:</span><span class="mi">30</span><span class="p">:</span>
+ <span class="n">a7</span><span class="p">:</span><span class="mi">99</span><span class="p">:</span><span class="mi">8</span><span class="n">b</span><span class="p">:</span><span class="mi">8</span><span class="n">d</span><span class="p">:</span><span class="mi">39</span><span class="p">:</span><span class="mi">47</span><span class="p">:</span><span class="n">ba</span><span class="p">:</span><span class="mi">3</span><span class="n">c</span><span class="p">:</span><span class="n">a0</span><span class="p">:</span><span class="mi">4</span><span class="n">c</span><span class="p">:</span><span class="mi">22</span><span class="p">:</span><span class="mi">3</span><span class="n">d</span><span class="p">:</span><span class="n">d9</span><span class="p">:</span><span class="mi">6</span><span class="n">b</span><span class="p">:</span><span class="n">ae</span><span class="p">:</span><span class="mi">58</span><span class="p">:</span><span class="mi">8</span><span class="n">a</span><span class="p">:</span><span class="mi">36</span><span class="p">:</span>
+ <span class="mi">49</span><span class="p">:</span><span class="n">c5</span><span class="p">:</span><span class="mi">98</span><span class="p">:</span><span class="mi">72</span><span class="p">:</span><span class="mi">88</span><span class="p">:</span><span class="mi">68</span><span class="p">:</span><span class="mi">22</span><span class="p">:</span><span class="mi">93</span><span class="p">:</span><span class="mi">2</span><span class="n">d</span><span class="p">:</span><span class="mi">17</span><span class="p">:</span><span class="mi">14</span><span class="p">:</span><span class="n">e7</span><span class="p">:</span><span class="n">d4</span><span class="p">:</span><span class="mi">9</span><span class="n">c</span><span class="p">:</span><span class="mi">03</span><span class="p">:</span><span class="n">a0</span><span class="p">:</span><span class="mi">03</span><span class="p">:</span><span class="mi">10</span><span class="p">:</span>
+ <span class="mi">85</span><span class="p">:</span><span class="mi">94</span><span class="p">:</span><span class="n">ce</span><span class="p">:</span><span class="n">a9</span><span class="p">:</span><span class="mi">94</span><span class="p">:</span><span class="n">cc</span><span class="p">:</span><span class="n">fe</span><span class="p">:</span><span class="mi">42</span><span class="p">:</span><span class="n">b3</span><span class="p">:</span><span class="n">a8</span><span class="p">:</span><span class="n">eb</span><span class="p">:</span><span class="mi">49</span><span class="p">:</span><span class="mi">1</span><span class="n">a</span><span class="p">:</span><span class="mi">37</span><span class="p">:</span><span class="mi">34</span><span class="p">:</span><span class="n">a7</span><span class="p">:</span><span class="n">e0</span><span class="p">:</span><span class="n">d5</span><span class="p">:</span>
+ <span class="n">b7</span><span class="p">:</span><span class="mi">74</span><span class="p">:</span><span class="n">f4</span><span class="p">:</span><span class="mi">3</span><span class="n">d</span><span class="p">:</span><span class="mi">4</span><span class="n">a</span><span class="p">:</span><span class="n">f6</span><span class="p">:</span><span class="n">bb</span><span class="p">:</span><span class="mi">10</span><span class="p">:</span><span class="mi">91</span><span class="p">:</span><span class="mi">17</span><span class="p">:</span><span class="mi">3</span><span class="n">d</span><span class="p">:</span><span class="mi">52</span><span class="p">:</span><span class="n">bb</span><span class="p">:</span><span class="n">fd</span><span class="p">:</span><span class="mi">99</span><span class="p">:</span><span class="mi">10</span><span class="p">:</span><span class="mi">48</span><span class="p">:</span><span class="n">b2</span><span class="p">:</span>
+ <span class="n">b7</span><span class="p">:</span><span class="mi">9</span><span class="n">d</span><span class="p">:</span><span class="mi">1</span><span class="n">a</span><span class="p">:</span><span class="mi">76</span><span class="p">:</span><span class="mi">04</span><span class="p">:</span><span class="mi">08</span><span class="p">:</span><span class="n">d7</span><span class="p">:</span><span class="mi">91</span><span class="p">:</span><span class="mi">68</span><span class="p">:</span><span class="n">ae</span><span class="p">:</span><span class="mi">51</span><span class="p">:</span><span class="n">d7</span><span class="p">:</span><span class="mi">2</span><span class="n">c</span><span class="p">:</span><span class="n">e9</span><span class="p">:</span><span class="mi">3</span><span class="n">a</span><span class="p">:</span><span class="mi">8</span><span class="n">c</span><span class="p">:</span><span class="mi">27</span><span class="p">:</span><span class="mi">8</span><span class="n">a</span><span class="p">:</span>
+ <span class="mi">75</span><span class="p">:</span><span class="n">c2</span>
+</pre></div>
+</div>
+</div></blockquote>
+<ol class="arabic" start="6">
+<li><p class="first">Now, sign the certificate request:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>./CA.pl -sign
+
+Using configuration from openssl.cnf
+Enter PEM pass phrase: &lt;CA&#39;s passphrase&gt;
+Check that the request matches the signature
+Signature ok
+The Subjects Distinguished Name is as follows
+countryName :PRINTABLE:&#39;SG&#39;
+organizationName :PRINTABLE:&#39;M2Crypto&#39;
+commonName :PRINTABLE:&#39;localhost&#39;
+emailAddress :IA5STRING:&#39;admin@server.example.dom&#39;
+Certificate is to be certified until Mar 31 02:57:30 2002 GMT (365 days)
+Sign the certificate? [y/n]:y
+
+
+1 out of 1 certificate requests certified, commit? [y/n]y
+Write out database with 1 new entries
+Data Base Updated
+Signed certificate is in newcert.pem
+</pre></div>
+</div>
+</li>
+</ol>
+<p></p>
+<blockquote>
+<div><p><code class="docutils literal notranslate"><span class="pre">newcert.pem</span></code> looks like this:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">cat</span> <span class="n">newcert</span><span class="o">.</span><span class="n">pem</span>
+
+<span class="n">Certificate</span><span class="p">:</span>
+<span class="n">Data</span><span class="p">:</span>
+ <span class="n">Version</span><span class="p">:</span> <span class="mi">3</span> <span class="p">(</span><span class="mh">0x2</span><span class="p">)</span>
+ <span class="n">Serial</span> <span class="n">Number</span><span class="p">:</span> <span class="mi">1</span> <span class="p">(</span><span class="mh">0x1</span><span class="p">)</span>
+ <span class="n">Signature</span> <span class="n">Algorithm</span><span class="p">:</span> <span class="n">md5WithRSAEncryption</span>
+ <span class="n">Issuer</span><span class="p">:</span> <span class="n">C</span><span class="o">=</span><span class="n">SG</span><span class="p">,</span> <span class="n">O</span><span class="o">=</span><span class="n">DemoCA</span><span class="p">,</span> <span class="n">CN</span><span class="o">=</span><span class="n">DemoCA</span> <span class="n">Certificate</span> <span class="n">Master</span><span class="o">/</span><span class="n">Email</span><span class="o">=</span><span class="n">certmaster</span><span class="nd">@democa</span><span class="o">.</span><span class="n">dom</span>
+ <span class="n">Validity</span>
+ <span class="n">Not</span> <span class="n">Before</span><span class="p">:</span> <span class="n">Mar</span> <span class="mi">31</span> <span class="mi">02</span><span class="p">:</span><span class="mi">57</span><span class="p">:</span><span class="mi">30</span> <span class="mi">2001</span> <span class="n">GMT</span>
+ <span class="n">Not</span> <span class="n">After</span> <span class="p">:</span> <span class="n">Mar</span> <span class="mi">31</span> <span class="mi">02</span><span class="p">:</span><span class="mi">57</span><span class="p">:</span><span class="mi">30</span> <span class="mi">2002</span> <span class="n">GMT</span>
+ <span class="n">Subject</span><span class="p">:</span> <span class="n">C</span><span class="o">=</span><span class="n">SG</span><span class="p">,</span> <span class="n">O</span><span class="o">=</span><span class="n">M2Crypto</span><span class="p">,</span> <span class="n">CN</span><span class="o">=</span><span class="n">localhost</span><span class="o">/</span><span class="n">Email</span><span class="o">=</span><span class="n">admin</span><span class="nd">@server</span><span class="o">.</span><span class="n">example</span><span class="o">.</span><span class="n">dom</span>
+ <span class="n">Subject</span> <span class="n">Public</span> <span class="n">Key</span> <span class="n">Info</span><span class="p">:</span>
+ <span class="n">Public</span> <span class="n">Key</span> <span class="n">Algorithm</span><span class="p">:</span> <span class="n">rsaEncryption</span>
+ <span class="n">RSA</span> <span class="n">Public</span> <span class="n">Key</span><span class="p">:</span> <span class="p">(</span><span class="mi">1024</span> <span class="n">bit</span><span class="p">)</span>
+ <span class="n">Modulus</span> <span class="p">(</span><span class="mi">1024</span> <span class="n">bit</span><span class="p">):</span>
+ <span class="mi">00</span><span class="p">:</span><span class="n">af</span><span class="p">:</span><span class="mi">59</span><span class="p">:</span><span class="n">d8</span><span class="p">:</span><span class="mi">63</span><span class="p">:</span><span class="mi">54</span><span class="p">:</span><span class="mi">2</span><span class="n">b</span><span class="p">:</span><span class="mi">96</span><span class="p">:</span><span class="mi">5</span><span class="n">d</span><span class="p">:</span><span class="mi">6</span><span class="n">b</span><span class="p">:</span><span class="n">b8</span><span class="p">:</span><span class="mi">1</span><span class="n">f</span><span class="p">:</span><span class="n">c5</span><span class="p">:</span><span class="n">aa</span><span class="p">:</span><span class="mi">50</span><span class="p">:</span>
+ <span class="mi">91</span><span class="p">:</span><span class="n">ae</span><span class="p">:</span><span class="n">be</span><span class="p">:</span><span class="mi">67</span><span class="p">:</span><span class="n">be</span><span class="p">:</span><span class="n">ea</span><span class="p">:</span><span class="mi">5</span><span class="n">d</span><span class="p">:</span><span class="mi">20</span><span class="p">:</span><span class="n">df</span><span class="p">:</span><span class="n">b7</span><span class="p">:</span><span class="n">c0</span><span class="p">:</span><span class="mi">5</span><span class="n">e</span><span class="p">:</span><span class="n">ea</span><span class="p">:</span><span class="n">f7</span><span class="p">:</span><span class="mi">5</span><span class="n">e</span><span class="p">:</span>
+ <span class="mi">6</span><span class="n">d</span><span class="p">:</span><span class="n">bc</span><span class="p">:</span><span class="mi">44</span><span class="p">:</span><span class="mi">28</span><span class="p">:</span><span class="mi">73</span><span class="p">:</span><span class="n">be</span><span class="p">:</span><span class="mi">1</span><span class="n">b</span><span class="p">:</span><span class="mi">9</span><span class="n">e</span><span class="p">:</span><span class="n">ee</span><span class="p">:</span><span class="mi">9</span><span class="n">b</span><span class="p">:</span><span class="n">f0</span><span class="p">:</span><span class="mi">86</span><span class="p">:</span><span class="n">db</span><span class="p">:</span><span class="mi">19</span><span class="p">:</span><span class="mi">13</span><span class="p">:</span>
+ <span class="mi">21</span><span class="p">:</span><span class="n">cd</span><span class="p">:</span><span class="n">dc</span><span class="p">:</span><span class="n">e6</span><span class="p">:</span><span class="n">bd</span><span class="p">:</span><span class="mi">0</span><span class="n">e</span><span class="p">:</span><span class="mi">12</span><span class="p">:</span><span class="n">cc</span><span class="p">:</span><span class="mi">57</span><span class="p">:</span><span class="n">d5</span><span class="p">:</span><span class="mi">10</span><span class="p">:</span><span class="mi">0</span><span class="n">b</span><span class="p">:</span><span class="mi">8</span><span class="n">c</span><span class="p">:</span><span class="mi">32</span><span class="p">:</span><span class="n">e4</span><span class="p">:</span>
+ <span class="n">c7</span><span class="p">:</span><span class="mi">7</span><span class="n">b</span><span class="p">:</span><span class="mi">26</span><span class="p">:</span><span class="n">cf</span><span class="p">:</span><span class="n">ab</span><span class="p">:</span><span class="mi">9</span><span class="n">b</span><span class="p">:</span><span class="mi">61</span><span class="p">:</span><span class="n">ed</span><span class="p">:</span><span class="mi">80</span><span class="p">:</span><span class="n">eb</span><span class="p">:</span><span class="mi">4</span><span class="n">c</span><span class="p">:</span><span class="n">d8</span><span class="p">:</span><span class="n">b3</span><span class="p">:</span><span class="mi">28</span><span class="p">:</span><span class="n">ac</span><span class="p">:</span>
+ <span class="mi">4</span><span class="n">e</span><span class="p">:</span><span class="mi">06</span><span class="p">:</span><span class="mi">7</span><span class="n">a</span><span class="p">:</span><span class="mi">84</span><span class="p">:</span><span class="n">d8</span><span class="p">:</span><span class="n">a6</span><span class="p">:</span><span class="mi">2</span><span class="n">e</span><span class="p">:</span><span class="mi">5</span><span class="n">f</span><span class="p">:</span><span class="n">d5</span><span class="p">:</span><span class="n">f6</span><span class="p">:</span><span class="n">d8</span><span class="p">:</span><span class="mi">0</span><span class="n">d</span><span class="p">:</span><span class="mi">4</span><span class="n">a</span><span class="p">:</span><span class="mi">87</span><span class="p">:</span><span class="mi">8</span><span class="n">f</span><span class="p">:</span>
+ <span class="mi">6</span><span class="n">c</span><span class="p">:</span><span class="n">a0</span><span class="p">:</span><span class="mi">92</span><span class="p">:</span><span class="mi">45</span><span class="p">:</span><span class="mi">83</span><span class="p">:</span><span class="n">a9</span><span class="p">:</span><span class="mi">0</span><span class="n">f</span><span class="p">:</span><span class="mi">6</span><span class="n">f</span><span class="p">:</span><span class="n">d3</span><span class="p">:</span><span class="mi">14</span><span class="p">:</span><span class="mi">82</span><span class="p">:</span><span class="mi">26</span><span class="p">:</span><span class="mi">41</span><span class="p">:</span><span class="mi">88</span><span class="p">:</span><span class="n">c9</span><span class="p">:</span>
+ <span class="mi">6</span><span class="n">f</span><span class="p">:</span><span class="n">b5</span><span class="p">:</span><span class="n">be</span><span class="p">:</span><span class="n">ca</span><span class="p">:</span><span class="n">dc</span><span class="p">:</span><span class="mi">21</span><span class="p">:</span><span class="n">df</span><span class="p">:</span><span class="mi">83</span><span class="p">:</span><span class="mi">0</span><span class="n">e</span><span class="p">:</span><span class="mi">56</span><span class="p">:</span><span class="mi">6</span><span class="n">a</span><span class="p">:</span><span class="mi">05</span><span class="p">:</span><span class="n">a7</span><span class="p">:</span><span class="mi">2</span><span class="n">e</span><span class="p">:</span><span class="mi">5</span><span class="n">f</span><span class="p">:</span>
+ <span class="mi">0</span><span class="n">b</span><span class="p">:</span><span class="mi">6</span><span class="n">f</span><span class="p">:</span><span class="n">e7</span><span class="p">:</span><span class="mi">1</span><span class="n">c</span><span class="p">:</span><span class="n">bc</span><span class="p">:</span><span class="n">a6</span><span class="p">:</span><span class="mi">59</span><span class="p">:</span><span class="mi">97</span><span class="p">:</span><span class="n">ef</span>
+ <span class="n">Exponent</span><span class="p">:</span> <span class="mi">65537</span> <span class="p">(</span><span class="mh">0x10001</span><span class="p">)</span>
+ <span class="n">X509v3</span> <span class="n">extensions</span><span class="p">:</span>
+ <span class="n">X509v3</span> <span class="n">Basic</span> <span class="n">Constraints</span><span class="p">:</span>
+<span class="n">Certificate</span><span class="p">:</span>
+<span class="n">Data</span><span class="p">:</span>
+ <span class="n">Version</span><span class="p">:</span> <span class="mi">3</span> <span class="p">(</span><span class="mh">0x2</span><span class="p">)</span>
+ <span class="n">Serial</span> <span class="n">Number</span><span class="p">:</span> <span class="mi">1</span> <span class="p">(</span><span class="mh">0x1</span><span class="p">)</span>
+ <span class="n">Signature</span> <span class="n">Algorithm</span><span class="p">:</span> <span class="n">md5WithRSAEncryption</span>
+ <span class="n">Issuer</span><span class="p">:</span> <span class="n">C</span><span class="o">=</span><span class="n">SG</span><span class="p">,</span> <span class="n">O</span><span class="o">=</span><span class="n">DemoCA</span><span class="p">,</span> <span class="n">CN</span><span class="o">=</span><span class="n">DemoCA</span> <span class="n">Certificate</span> <span class="n">Master</span><span class="o">/</span><span class="n">Email</span><span class="o">=</span><span class="n">certmaster</span><span class="nd">@democa</span><span class="o">.</span><span class="n">dom</span>
+ <span class="n">Validity</span>
+ <span class="n">Not</span> <span class="n">Before</span><span class="p">:</span> <span class="n">Mar</span> <span class="mi">31</span> <span class="mi">02</span><span class="p">:</span><span class="mi">57</span><span class="p">:</span><span class="mi">30</span> <span class="mi">2001</span> <span class="n">GMT</span>
+ <span class="n">Not</span> <span class="n">After</span> <span class="p">:</span> <span class="n">Mar</span> <span class="mi">31</span> <span class="mi">02</span><span class="p">:</span><span class="mi">57</span><span class="p">:</span><span class="mi">30</span> <span class="mi">2002</span> <span class="n">GMT</span>
+ <span class="n">Subject</span><span class="p">:</span> <span class="n">C</span><span class="o">=</span><span class="n">SG</span><span class="p">,</span> <span class="n">O</span><span class="o">=</span><span class="n">M2Crypto</span><span class="p">,</span> <span class="n">CN</span><span class="o">=</span><span class="n">localhost</span><span class="o">/</span><span class="n">Email</span><span class="o">=</span><span class="n">admin</span><span class="nd">@server</span><span class="o">.</span><span class="n">example</span><span class="o">.</span><span class="n">dom</span>
+ <span class="n">Subject</span> <span class="n">Public</span> <span class="n">Key</span> <span class="n">Info</span><span class="p">:</span>
+ <span class="n">Public</span> <span class="n">Key</span> <span class="n">Algorithm</span><span class="p">:</span> <span class="n">rsaEncryption</span>
+ <span class="n">RSA</span> <span class="n">Public</span> <span class="n">Key</span><span class="p">:</span> <span class="p">(</span><span class="mi">1024</span> <span class="n">bit</span><span class="p">)</span>
+ <span class="n">Modulus</span> <span class="p">(</span><span class="mi">1024</span> <span class="n">bit</span><span class="p">):</span>
+ <span class="mi">00</span><span class="p">:</span><span class="n">af</span><span class="p">:</span><span class="mi">59</span><span class="p">:</span><span class="n">d8</span><span class="p">:</span><span class="mi">63</span><span class="p">:</span><span class="mi">54</span><span class="p">:</span><span class="mi">2</span><span class="n">b</span><span class="p">:</span><span class="mi">96</span><span class="p">:</span><span class="mi">5</span><span class="n">d</span><span class="p">:</span><span class="mi">6</span><span class="n">b</span><span class="p">:</span><span class="n">b8</span><span class="p">:</span><span class="mi">1</span><span class="n">f</span><span class="p">:</span><span class="n">c5</span><span class="p">:</span><span class="n">aa</span><span class="p">:</span><span class="mi">50</span><span class="p">:</span>
+ <span class="mi">91</span><span class="p">:</span><span class="n">ae</span><span class="p">:</span><span class="n">be</span><span class="p">:</span><span class="mi">67</span><span class="p">:</span><span class="n">be</span><span class="p">:</span><span class="n">ea</span><span class="p">:</span><span class="mi">5</span><span class="n">d</span><span class="p">:</span><span class="mi">20</span><span class="p">:</span><span class="n">df</span><span class="p">:</span><span class="n">b7</span><span class="p">:</span><span class="n">c0</span><span class="p">:</span><span class="mi">5</span><span class="n">e</span><span class="p">:</span><span class="n">ea</span><span class="p">:</span><span class="n">f7</span><span class="p">:</span><span class="mi">5</span><span class="n">e</span><span class="p">:</span>
+ <span class="mi">6</span><span class="n">d</span><span class="p">:</span><span class="n">bc</span><span class="p">:</span><span class="mi">44</span><span class="p">:</span><span class="mi">28</span><span class="p">:</span><span class="mi">73</span><span class="p">:</span><span class="n">be</span><span class="p">:</span><span class="mi">1</span><span class="n">b</span><span class="p">:</span><span class="mi">9</span><span class="n">e</span><span class="p">:</span><span class="n">ee</span><span class="p">:</span><span class="mi">9</span><span class="n">b</span><span class="p">:</span><span class="n">f0</span><span class="p">:</span><span class="mi">86</span><span class="p">:</span><span class="n">db</span><span class="p">:</span><span class="mi">19</span><span class="p">:</span><span class="mi">13</span><span class="p">:</span>
+ <span class="mi">21</span><span class="p">:</span><span class="n">cd</span><span class="p">:</span><span class="n">dc</span><span class="p">:</span><span class="n">e6</span><span class="p">:</span><span class="n">bd</span><span class="p">:</span><span class="mi">0</span><span class="n">e</span><span class="p">:</span><span class="mi">12</span><span class="p">:</span><span class="n">cc</span><span class="p">:</span><span class="mi">57</span><span class="p">:</span><span class="n">d5</span><span class="p">:</span><span class="mi">10</span><span class="p">:</span><span class="mi">0</span><span class="n">b</span><span class="p">:</span><span class="mi">8</span><span class="n">c</span><span class="p">:</span><span class="mi">32</span><span class="p">:</span><span class="n">e4</span><span class="p">:</span>
+ <span class="n">c7</span><span class="p">:</span><span class="mi">7</span><span class="n">b</span><span class="p">:</span><span class="mi">26</span><span class="p">:</span><span class="n">cf</span><span class="p">:</span><span class="n">ab</span><span class="p">:</span><span class="mi">9</span><span class="n">b</span><span class="p">:</span><span class="mi">61</span><span class="p">:</span><span class="n">ed</span><span class="p">:</span><span class="mi">80</span><span class="p">:</span><span class="n">eb</span><span class="p">:</span><span class="mi">4</span><span class="n">c</span><span class="p">:</span><span class="n">d8</span><span class="p">:</span><span class="n">b3</span><span class="p">:</span><span class="mi">28</span><span class="p">:</span><span class="n">ac</span><span class="p">:</span>
+ <span class="mi">4</span><span class="n">e</span><span class="p">:</span><span class="mi">06</span><span class="p">:</span><span class="mi">7</span><span class="n">a</span><span class="p">:</span><span class="mi">84</span><span class="p">:</span><span class="n">d8</span><span class="p">:</span><span class="n">a6</span><span class="p">:</span><span class="mi">2</span><span class="n">e</span><span class="p">:</span><span class="mi">5</span><span class="n">f</span><span class="p">:</span><span class="n">d5</span><span class="p">:</span><span class="n">f6</span><span class="p">:</span><span class="n">d8</span><span class="p">:</span><span class="mi">0</span><span class="n">d</span><span class="p">:</span><span class="mi">4</span><span class="n">a</span><span class="p">:</span><span class="mi">87</span><span class="p">:</span><span class="mi">8</span><span class="n">f</span><span class="p">:</span>
+ <span class="mi">6</span><span class="n">c</span><span class="p">:</span><span class="n">a0</span><span class="p">:</span><span class="mi">92</span><span class="p">:</span><span class="mi">45</span><span class="p">:</span><span class="mi">83</span><span class="p">:</span><span class="n">a9</span><span class="p">:</span><span class="mi">0</span><span class="n">f</span><span class="p">:</span><span class="mi">6</span><span class="n">f</span><span class="p">:</span><span class="n">d3</span><span class="p">:</span><span class="mi">14</span><span class="p">:</span><span class="mi">82</span><span class="p">:</span><span class="mi">26</span><span class="p">:</span><span class="mi">41</span><span class="p">:</span><span class="mi">88</span><span class="p">:</span><span class="n">c9</span><span class="p">:</span>
+ <span class="mi">6</span><span class="n">f</span><span class="p">:</span><span class="n">b5</span><span class="p">:</span><span class="n">be</span><span class="p">:</span><span class="n">ca</span><span class="p">:</span><span class="n">dc</span><span class="p">:</span><span class="mi">21</span><span class="p">:</span><span class="n">df</span><span class="p">:</span><span class="mi">83</span><span class="p">:</span><span class="mi">0</span><span class="n">e</span><span class="p">:</span><span class="mi">56</span><span class="p">:</span><span class="mi">6</span><span class="n">a</span><span class="p">:</span><span class="mi">05</span><span class="p">:</span><span class="n">a7</span><span class="p">:</span><span class="mi">2</span><span class="n">e</span><span class="p">:</span><span class="mi">5</span><span class="n">f</span><span class="p">:</span>
+ <span class="mi">0</span><span class="n">b</span><span class="p">:</span><span class="mi">6</span><span class="n">f</span><span class="p">:</span><span class="n">e7</span><span class="p">:</span><span class="mi">1</span><span class="n">c</span><span class="p">:</span><span class="n">bc</span><span class="p">:</span><span class="n">a6</span><span class="p">:</span><span class="mi">59</span><span class="p">:</span><span class="mi">97</span><span class="p">:</span><span class="n">ef</span>
+ <span class="n">Exponent</span><span class="p">:</span> <span class="mi">65537</span> <span class="p">(</span><span class="mh">0x10001</span><span class="p">)</span>
+ <span class="n">X509v3</span> <span class="n">extensions</span><span class="p">:</span>
+ <span class="n">X509v3</span> <span class="n">Basic</span> <span class="n">Constraints</span><span class="p">:</span>
+ <span class="n">CA</span><span class="p">:</span><span class="n">FALSE</span>
+ <span class="n">Netscape</span> <span class="n">Comment</span><span class="p">:</span>
+ <span class="n">OpenSSL</span> <span class="n">Generated</span> <span class="n">Certificate</span>
+ <span class="n">X509v3</span> <span class="n">Subject</span> <span class="n">Key</span> <span class="n">Identifier</span><span class="p">:</span>
+ <span class="n">B3</span><span class="p">:</span><span class="n">D6</span><span class="p">:</span><span class="mi">89</span><span class="p">:</span><span class="mi">88</span><span class="p">:</span><span class="mi">2</span><span class="n">F</span><span class="p">:</span><span class="n">B1</span><span class="p">:</span><span class="mi">15</span><span class="p">:</span><span class="mi">40</span><span class="p">:</span><span class="n">EC</span><span class="p">:</span><span class="mi">0</span><span class="n">A</span><span class="p">:</span><span class="n">C0</span><span class="p">:</span><span class="mi">30</span><span class="p">:</span><span class="mi">35</span><span class="p">:</span><span class="mi">3</span><span class="n">A</span><span class="p">:</span><span class="n">B7</span><span class="p">:</span><span class="n">DA</span><span class="p">:</span><span class="mi">72</span><span class="p">:</span><span class="mi">73</span><span class="p">:</span><span class="mi">1</span><span class="n">B</span><span class="p">:</span><span class="mi">4</span><span class="n">D</span>
+ <span class="n">X509v3</span> <span class="n">Authority</span> <span class="n">Key</span> <span class="n">Identifier</span><span class="p">:</span>
+ <span class="n">keyid</span><span class="p">:</span><span class="n">F9</span><span class="p">:</span><span class="mi">6</span><span class="n">A</span><span class="p">:</span><span class="n">A6</span><span class="p">:</span><span class="mi">34</span><span class="p">:</span><span class="mi">97</span><span class="p">:</span><span class="mi">6</span><span class="n">B</span><span class="p">:</span><span class="n">BC</span><span class="p">:</span><span class="n">BB</span><span class="p">:</span><span class="mi">5</span><span class="n">A</span><span class="p">:</span><span class="mi">17</span><span class="p">:</span><span class="mi">0</span><span class="n">D</span><span class="p">:</span><span class="mi">19</span><span class="p">:</span><span class="n">FC</span><span class="p">:</span><span class="mi">62</span><span class="p">:</span><span class="mi">21</span><span class="p">:</span><span class="mi">0</span><span class="n">B</span><span class="p">:</span><span class="mi">00</span><span class="p">:</span><span class="n">B5</span><span class="p">:</span><span class="mi">0</span><span class="n">E</span><span class="p">:</span><span class="mi">29</span>
+ <span class="n">DirName</span><span class="p">:</span><span class="o">/</span><span class="n">C</span><span class="o">=</span><span class="n">SG</span><span class="o">/</span><span class="n">O</span><span class="o">=</span><span class="n">DemoCA</span><span class="o">/</span><span class="n">CN</span><span class="o">=</span><span class="n">DemoCA</span> <span class="n">Certificate</span> <span class="n">Master</span><span class="o">/</span><span class="n">Email</span><span class="o">=</span><span class="n">certmaster</span><span class="nd">@democa</span><span class="o">.</span><span class="n">dom</span>
+ <span class="n">serial</span><span class="p">:</span><span class="mi">00</span>
+
+<span class="n">Signature</span> <span class="n">Algorithm</span><span class="p">:</span> <span class="n">md5WithRSAEncryption</span>
+</pre></div>
+</div>
+</div></blockquote>
+<ol class="arabic" start="7">
+<li><p class="first">In certain situations, e.g., where your certificate and private key
+are to be used in an unattended SSL server, you may wish to not
+encrypt the private key, i.e., leave the key in the clear. This
+decision should be governed by your site’s security policy and threat
+model, of course:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">openssl</span> <span class="n">rsa</span> <span class="o">&lt;</span> <span class="n">newkey</span><span class="o">.</span><span class="n">pem</span> <span class="o">&gt;</span> <span class="n">newkey2</span><span class="o">.</span><span class="n">pem</span>
+
+<span class="n">read</span> <span class="n">RSA</span> <span class="n">key</span>
+<span class="n">Enter</span> <span class="n">PEM</span> <span class="k">pass</span> <span class="n">phrase</span><span class="p">:</span><span class="o">&lt;</span><span class="n">secret</span> <span class="n">passphrase</span> <span class="n">here</span><span class="o">&gt;</span>
+<span class="n">writing</span> <span class="n">RSA</span> <span class="n">key</span>
+</pre></div>
+</div>
+<p><code class="docutils literal notranslate"><span class="pre">newkey2.pem</span></code> looks like this:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">cat</span> <span class="n">newkey2</span><span class="o">.</span><span class="n">pem</span>
+
+<span class="o">-----</span><span class="n">BEGIN</span> <span class="n">RSA</span> <span class="n">PRIVATE</span> <span class="n">KEY</span><span class="o">-----</span>
+<span class="n">MIICXgIBAAKBgQCvWdhjVCuWXWu4H8WqUJGuvme</span><span class="o">+</span><span class="mi">6</span><span class="n">l0g37fAXur3Xm28RChzvhue</span>
+<span class="mi">7</span><span class="n">pvwhtsZEyHN3Oa9DhLMV9UQC4wy5Md7Js</span><span class="o">+</span><span class="n">rm2HtgOtM2LMorE4GeoTYpi5f1fbY</span>
+<span class="n">DUqHj2ygkkWDqQ9v0xSCJkGIyW</span><span class="o">+</span><span class="mi">1</span><span class="n">vsrcId</span><span class="o">+</span><span class="n">DDlZqBacuXwtv5xy8plmX7wIDAQAB</span>
+<span class="n">AoGAbAkU8w3W1Qu15Hle1bJSL7GMReoreqeblOBmMAZz4by0l6sXZXJpjWXo86f</span><span class="o">/</span>
+<span class="o">+</span><span class="n">dASMYTMPC4ZTYtv06N07AFbjL</span><span class="o">+</span><span class="n">kDfqDMTfzQkYMHp1LAq1Ihbq1rHWSBH5n3ekq</span>
+<span class="n">KiY8JKpv8DR5Po1iKaXJFuDByGDENJwYbSRSpSK3P</span><span class="o">+</span><span class="n">vkWWECQQDkEUE</span><span class="o">/</span><span class="n">ZPqqqZkQ</span>
+<span class="mi">2</span><span class="n">iWRPAsCbEID8SAraQl3DdCLYs</span><span class="o">/</span><span class="n">GgARfmmj4yUHEwkys9Jo1H8k4BdxugmaUwNi5</span>
+<span class="n">YQ</span><span class="o">/</span><span class="n">CVzrXAkEAxNO80ArbGxPUmr11GHG</span><span class="o">/</span><span class="n">bGBYj1DUBkHZSc7dgxZdtUCLGNxQnNsg</span>
+<span class="n">Iwq3n6j1sUzS3UW6abQ8bivYNOUcMKJAqQJBANQxFaLU4b</span><span class="o">/</span><span class="n">NQaODQ3aoBZpAfP9L</span>
+<span class="mi">5</span><span class="n">eFdvbet</span><span class="o">+</span><span class="mi">7</span><span class="n">zjt2r5CpikgkwOfAmDuXEltx</span><span class="o">/</span><span class="mi">8</span><span class="n">LevY0CllW</span><span class="o">+</span><span class="n">nErx9zJgVrwUsCQQCu</span>
+<span class="mi">76</span><span class="n">H5JiznPBDSF2FjgHWqVVdgyW4owY3mU739LHvNBLicN</span><span class="o">/</span><span class="n">RN9VPy0Suy8</span><span class="o">/</span><span class="n">CqzKT9</span>
+<span class="n">lWPBXzf2k3FuUdNkRlFBAkEAmpXoybuiFR2S5Bma</span><span class="o">/</span><span class="n">ax96lVs0</span><span class="o">/</span><span class="n">VihhfC1zZP</span><span class="o">/</span><span class="n">X</span><span class="o">/</span><span class="n">F</span>
+<span class="n">Br77</span><span class="o">+</span><span class="n">h9dIul</span><span class="o">+</span><span class="mi">2</span><span class="n">DnyOl50zu0Sdzst1</span><span class="o">/</span><span class="mi">7</span><span class="n">ay4JSDHyiBCMGSQ</span><span class="o">==</span>
+<span class="o">-----</span><span class="n">END</span> <span class="n">RSA</span> <span class="n">PRIVATE</span> <span class="n">KEY</span><span class="o">-----</span>
+</pre></div>
+</div>
+</li>
+</ol>
+<p>That’s it! The certificate, <code class="docutils literal notranslate"><span class="pre">newcert.pem</span></code>, and the private key -
+<code class="docutils literal notranslate"><span class="pre">newkey.pem</span></code> (encrypted) or <code class="docutils literal notranslate"><span class="pre">newkey2.pem</span></code> (unencrypted) - are now
+ready to be used. You may wish to rename the files to more intuitive
+names.</p>
+<p>You should also keep the CA’s certificate <code class="docutils literal notranslate"><span class="pre">demo/cacert.pem</span></code> handy
+for use when developing and deploying SSL or S/MIME applications.</p>
+</div>
+<div class="section" id="conclusion">
+<h2>Conclusion<a class="headerlink" href="#conclusion" title="Permalink to this headline">¶</a></h2>
+<p>We’ve walked through the basic steps in the creation of a CA and
+certificates using the tools that come with OpenSSL. We did not cover
+more advanced topics such as constraining a certificate to be SSL-only
+or S/MIME-only.</p>
+<p>There exist several HOWTOs similar to this one on the net. This one is
+written specifically to facilitate discussions in my other HOWTOs on
+developing SSL and S/MIME applications in
+<a class="reference external" href="http://www.python.org">Python</a> using
+<a class="reference external" href="https://gitlab.com/m2crypto/m2crypto/">M2Crypto</a>.</p>
+</div>
+</div>
+
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="index.html">M2Crypto</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="M2Crypto.html">M2Crypto Package</a></li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="index.html">Documentation overview</a><ul>
+ </ul></li>
+</ul>
+</div>
+<div id="searchbox" style="display: none" role="search">
+ <h3>Quick search</h3>
+ <div class="searchformwrapper">
+ <form class="search" action="search.html" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ </div>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer">
+ &copy;2017, Matej Cepl <mcepl@cepl.eu>.
+
+ |
+ Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
+ &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
+
+ |
+ <a href="_sources/howto.ca.rst.txt"
+ rel="nofollow">Page source</a>
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/howto.smime.html b/doc/html/howto.smime.html
new file mode 100644
index 0000000..7f77e00
--- /dev/null
+++ b/doc/html/howto.smime.html
@@ -0,0 +1,849 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>HOWTO: Programming S/MIME in Python with M2Crypto &#8212; M2Crypto documentation</title>
+ <link rel="stylesheet" href="_static/alabaster.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <script type="text/javascript" src="_static/language_data.js"></script>
+ <link rel="index" title="Index" href="genindex.html" />
+ <link rel="search" title="Search" href="search.html" />
+
+ <link rel="stylesheet" href="_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+ <div class="section" id="howto-programming-s-mime-in-python-with-m2crypto">
+<span id="howto-smime"></span><h1>HOWTO: Programming S/MIME in Python with M2Crypto<a class="headerlink" href="#howto-programming-s-mime-in-python-with-m2crypto" title="Permalink to this headline">¶</a></h1>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">author:</th><td class="field-body">Pheng Siong Ng &lt;<a class="reference external" href="mailto:ngps&#37;&#52;&#48;post1&#46;com">ngps<span>&#64;</span>post1<span>&#46;</span>com</a>&gt;</td>
+</tr>
+<tr class="field-even field"><th class="field-name">copyright:</th><td class="field-body">© 2000, 2001 by Ng Pheng Siong.</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="introduction">
+<h1>Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline">¶</a></h1>
+<p><a class="reference external" href="https://gitlab.com/m2crypto/m2crypto/">M2Crypto</a> is a
+<a class="reference external" href="http://www.python.org">Python</a> interface to
+<a class="reference external" href="http://www.openssl.org">OpenSSL</a>. It makes available to the Python
+programmer SSL functionality to implement clients and servers, S/MIME
+v2, RSA, DSA, DH, symmetric ciphers, message digests and HMACs.</p>
+<p>This document demonstrates programming S/MIME with M2Crypto.</p>
+</div>
+<div class="section" id="s-mime">
+<h1>S/MIME<a class="headerlink" href="#s-mime" title="Permalink to this headline">¶</a></h1>
+<p>S/MIME - Secure Multipurpose Internet Mail Extensions [RFC 2311, RFC
+2312] - provides a consistent way to send and receive secure MIME data.
+Based on the popular Internet MIME standard, S/MIME provides the
+following cryptographic security services for electronic messaging
+applications - <em>authentication</em>, <em>message integrity</em> and
+<em>non-repudiation of origin</em> (using <em>digital signatures</em>), and <em>privacy</em>
+and <em>data security</em> (using <em>encryption</em>).</p>
+</div>
+<div class="section" id="keys-and-certificates">
+<h1>Keys and Certificates<a class="headerlink" href="#keys-and-certificates" title="Permalink to this headline">¶</a></h1>
+<p>To create an S/MIME-signed message, you need an RSA key pair (this
+consists of a public key and a private key) and an X.509 certificate of
+said public key.</p>
+<p>To create an S/MIME-encrypted message, you need an X.509 certificate for
+each recipient.</p>
+<p>To create an S/MIME-signed <em>and</em> -encrypted message, first create a
+signed message, then encrypt the signed message with the recipients’
+certificates.</p>
+<p>You may generate key pairs and obtain certificates by using a commercial
+<em>certification authority</em> service.</p>
+<p>You can also do so using freely-available software. For many purposes,
+e.g., automated S/MIME messaging by system administration processes,
+this approach is cheap and effective.</p>
+<p>We now work through using OpenSSL to generate key pairs and
+certificates. This assumes you have OpenSSL installed properly on your
+system.</p>
+<p>First, we generate an X.509 certificate to be used for signing:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">openssl</span> <span class="n">req</span> <span class="o">-</span><span class="n">newkey</span> <span class="n">rsa</span><span class="p">:</span><span class="mi">1024</span> <span class="o">-</span><span class="n">nodes</span> <span class="o">-</span><span class="n">x509</span> <span class="o">-</span><span class="n">days</span> <span class="mi">365</span> <span class="o">-</span><span class="n">out</span> <span class="n">signer</span><span class="o">.</span><span class="n">pem</span>
+
+<span class="n">Using</span> <span class="n">configuration</span> <span class="kn">from</span> <span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="n">local</span><span class="o">/</span><span class="n">pkg</span><span class="o">/</span><span class="n">openssl</span><span class="o">/</span><span class="n">openssl</span><span class="o">.</span><span class="n">cnf</span>
+<span class="n">Generating</span> <span class="n">a</span> <span class="mi">1024</span> <span class="n">bit</span> <span class="n">RSA</span> <span class="n">private</span> <span class="n">key</span>
+<span class="o">..++++++</span>
+<span class="o">....................++++++</span>
+<span class="n">writing</span> <span class="n">new</span> <span class="n">private</span> <span class="n">key</span> <span class="n">to</span> <span class="s1">&#39;privkey.pem&#39;</span>
+<span class="o">-----</span>
+<span class="n">You</span> <span class="n">are</span> <span class="n">about</span> <span class="n">to</span> <span class="n">be</span> <span class="n">asked</span> <span class="n">to</span> <span class="n">enter</span> <span class="n">information</span> <span class="n">that</span> <span class="n">will</span> <span class="n">be</span> <span class="n">incorporated</span>
+<span class="n">into</span> <span class="n">your</span> <span class="n">certificate</span> <span class="n">request</span><span class="o">.</span>
+<span class="n">What</span> <span class="n">you</span> <span class="n">are</span> <span class="n">about</span> <span class="n">to</span> <span class="n">enter</span> <span class="ow">is</span> <span class="n">what</span> <span class="ow">is</span> <span class="n">called</span> <span class="n">a</span> <span class="n">Distinguished</span> <span class="n">Name</span> <span class="ow">or</span> <span class="n">a</span> <span class="n">DN</span><span class="o">.</span>
+<span class="n">There</span> <span class="n">are</span> <span class="n">quite</span> <span class="n">a</span> <span class="n">few</span> <span class="n">fields</span> <span class="n">but</span> <span class="n">you</span> <span class="n">can</span> <span class="n">leave</span> <span class="n">some</span> <span class="n">blank</span>
+<span class="n">For</span> <span class="n">some</span> <span class="n">fields</span> <span class="n">there</span> <span class="n">will</span> <span class="n">be</span> <span class="n">a</span> <span class="n">default</span> <span class="n">value</span><span class="p">,</span>
+<span class="n">If</span> <span class="n">you</span> <span class="n">enter</span> <span class="s1">&#39;.&#39;</span><span class="p">,</span> <span class="n">the</span> <span class="n">field</span> <span class="n">will</span> <span class="n">be</span> <span class="n">left</span> <span class="n">blank</span><span class="o">.</span>
+<span class="o">-----</span>
+<span class="n">Country</span> <span class="n">Name</span> <span class="p">(</span><span class="mi">2</span> <span class="n">letter</span> <span class="n">code</span><span class="p">)</span> <span class="p">[</span><span class="n">AU</span><span class="p">]:</span><span class="n">SG</span>
+<span class="n">State</span> <span class="ow">or</span> <span class="n">Province</span> <span class="n">Name</span> <span class="p">(</span><span class="n">full</span> <span class="n">name</span><span class="p">)</span> <span class="p">[</span><span class="n">Some</span><span class="o">-</span><span class="n">State</span><span class="p">]:</span><span class="o">.</span>
+<span class="n">Locality</span> <span class="n">Name</span> <span class="p">(</span><span class="n">eg</span><span class="p">,</span> <span class="n">city</span><span class="p">)</span> <span class="p">[]:</span><span class="o">.</span>
+<span class="n">Organization</span> <span class="n">Name</span> <span class="p">(</span><span class="n">eg</span><span class="p">,</span> <span class="n">company</span><span class="p">)</span> <span class="p">[</span><span class="n">Internet</span> <span class="n">Widgits</span> <span class="n">Pty</span> <span class="n">Ltd</span><span class="p">]:</span><span class="n">M2Crypto</span>
+<span class="n">Organizational</span> <span class="n">Unit</span> <span class="n">Name</span> <span class="p">(</span><span class="n">eg</span><span class="p">,</span> <span class="n">section</span><span class="p">)</span> <span class="p">[]:</span><span class="o">.</span>
+<span class="n">Common</span> <span class="n">Name</span> <span class="p">(</span><span class="n">eg</span><span class="p">,</span> <span class="n">YOUR</span> <span class="n">name</span><span class="p">)</span> <span class="p">[]:</span><span class="n">S</span><span class="o">/</span><span class="n">MIME</span> <span class="n">Sender</span>
+<span class="n">Email</span> <span class="n">Address</span> <span class="p">[]:</span><span class="n">sender</span><span class="nd">@example</span><span class="o">.</span><span class="n">dom</span>
+</pre></div>
+</div>
+<p>This generates a 1024-bit RSA key pair, unencrypted, into
+<code class="docutils literal notranslate"><span class="pre">privkey.pem</span></code>; it also generates a self-signed X.509 certificate for
+the public key into <code class="docutils literal notranslate"><span class="pre">signer.pem</span></code>. The certificate is valid for 365
+days, i.e., a year.</p>
+<p>Let’s rename <code class="docutils literal notranslate"><span class="pre">privkey.pem</span></code> so that we know it is a companion of
+<code class="docutils literal notranslate"><span class="pre">signer.pem</span></code>’s:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">mv</span> <span class="n">privkey</span><span class="o">.</span><span class="n">pem</span> <span class="n">signer_key</span><span class="o">.</span><span class="n">pem</span>
+</pre></div>
+</div>
+<p>To verify the content of <code class="docutils literal notranslate"><span class="pre">signer.pem</span></code>, execute the following:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">openssl</span> <span class="n">x509</span> <span class="o">-</span><span class="n">noout</span> <span class="o">-</span><span class="n">text</span> <span class="o">-</span><span class="ow">in</span> <span class="n">signer</span><span class="o">.</span><span class="n">pem</span>
+
+<span class="n">Certificate</span><span class="p">:</span>
+ <span class="n">Data</span><span class="p">:</span>
+ <span class="n">Version</span><span class="p">:</span> <span class="mi">3</span> <span class="p">(</span><span class="mh">0x2</span><span class="p">)</span>
+ <span class="n">Serial</span> <span class="n">Number</span><span class="p">:</span> <span class="mi">0</span> <span class="p">(</span><span class="mh">0x0</span><span class="p">)</span>
+ <span class="n">Signature</span> <span class="n">Algorithm</span><span class="p">:</span> <span class="n">md5WithRSAEncryption</span>
+ <span class="n">Issuer</span><span class="p">:</span> <span class="n">C</span><span class="o">=</span><span class="n">SG</span><span class="p">,</span> <span class="n">O</span><span class="o">=</span><span class="n">M2Crypto</span><span class="p">,</span> <span class="n">CN</span><span class="o">=</span><span class="n">S</span><span class="o">/</span><span class="n">MIME</span> <span class="n">Sender</span><span class="o">/</span><span class="n">Email</span><span class="o">=</span><span class="n">sender</span><span class="nd">@example</span><span class="o">.</span><span class="n">dom</span>
+ <span class="n">Validity</span>
+ <span class="n">Not</span> <span class="n">Before</span><span class="p">:</span> <span class="n">Mar</span> <span class="mi">24</span> <span class="mi">12</span><span class="p">:</span><span class="mi">56</span><span class="p">:</span><span class="mi">16</span> <span class="mi">2001</span> <span class="n">GMT</span>
+ <span class="n">Not</span> <span class="n">After</span> <span class="p">:</span> <span class="n">Mar</span> <span class="mi">24</span> <span class="mi">12</span><span class="p">:</span><span class="mi">56</span><span class="p">:</span><span class="mi">16</span> <span class="mi">2002</span> <span class="n">GMT</span>
+ <span class="n">Subject</span><span class="p">:</span> <span class="n">C</span><span class="o">=</span><span class="n">SG</span><span class="p">,</span> <span class="n">O</span><span class="o">=</span><span class="n">M2Crypto</span><span class="p">,</span> <span class="n">CN</span><span class="o">=</span><span class="n">S</span><span class="o">/</span><span class="n">MIME</span> <span class="n">Sender</span><span class="o">/</span><span class="n">Email</span><span class="o">=</span><span class="n">sender</span><span class="nd">@example</span><span class="o">.</span><span class="n">dom</span>
+ <span class="n">Subject</span> <span class="n">Public</span> <span class="n">Key</span> <span class="n">Info</span><span class="p">:</span>
+ <span class="n">Public</span> <span class="n">Key</span> <span class="n">Algorithm</span><span class="p">:</span> <span class="n">rsaEncryption</span>
+ <span class="n">RSA</span> <span class="n">Public</span> <span class="n">Key</span><span class="p">:</span> <span class="p">(</span><span class="mi">1024</span> <span class="n">bit</span><span class="p">)</span>
+ <span class="n">Modulus</span> <span class="p">(</span><span class="mi">1024</span> <span class="n">bit</span><span class="p">):</span>
+ <span class="mi">00</span><span class="p">:</span><span class="n">a9</span><span class="p">:</span><span class="n">d6</span><span class="p">:</span><span class="n">e2</span><span class="p">:</span><span class="n">b5</span><span class="p">:</span><span class="mi">11</span><span class="p">:</span><span class="mi">3</span><span class="n">b</span><span class="p">:</span><span class="n">ae</span><span class="p">:</span><span class="mi">3</span><span class="n">c</span><span class="p">:</span><span class="n">e2</span><span class="p">:</span><span class="mi">17</span><span class="p">:</span><span class="mi">31</span><span class="p">:</span><span class="mi">70</span><span class="p">:</span><span class="n">e1</span><span class="p">:</span><span class="mi">6</span><span class="n">e</span><span class="p">:</span>
+ <span class="mi">01</span><span class="p">:</span><span class="n">f4</span><span class="p">:</span><span class="mi">19</span><span class="p">:</span><span class="mi">6</span><span class="n">d</span><span class="p">:</span><span class="n">bd</span><span class="p">:</span><span class="mi">2</span><span class="n">a</span><span class="p">:</span><span class="mi">42</span><span class="p">:</span><span class="mi">36</span><span class="p">:</span><span class="mi">2</span><span class="n">b</span><span class="p">:</span><span class="mi">37</span><span class="p">:</span><span class="mi">34</span><span class="p">:</span><span class="n">e2</span><span class="p">:</span><span class="mi">83</span><span class="p">:</span><span class="mi">1</span><span class="n">d</span><span class="p">:</span><span class="mi">0</span><span class="n">d</span><span class="p">:</span>
+ <span class="mi">11</span><span class="p">:</span><span class="mi">2</span><span class="n">e</span><span class="p">:</span><span class="n">b4</span><span class="p">:</span><span class="mi">99</span><span class="p">:</span><span class="mi">44</span><span class="p">:</span><span class="n">db</span><span class="p">:</span><span class="mi">10</span><span class="p">:</span><span class="mi">67</span><span class="p">:</span><span class="n">be</span><span class="p">:</span><span class="mi">97</span><span class="p">:</span><span class="mi">5</span><span class="n">f</span><span class="p">:</span><span class="mi">5</span><span class="n">b</span><span class="p">:</span><span class="mi">1</span><span class="n">a</span><span class="p">:</span><span class="mi">26</span><span class="p">:</span><span class="mi">33</span><span class="p">:</span>
+ <span class="mi">46</span><span class="p">:</span><span class="mi">23</span><span class="p">:</span><span class="mi">2</span><span class="n">f</span><span class="p">:</span><span class="mi">95</span><span class="p">:</span><span class="mi">04</span><span class="p">:</span><span class="mi">7</span><span class="n">a</span><span class="p">:</span><span class="mi">35</span><span class="p">:</span><span class="n">da</span><span class="p">:</span><span class="mi">9</span><span class="n">d</span><span class="p">:</span><span class="n">f9</span><span class="p">:</span><span class="mi">26</span><span class="p">:</span><span class="mi">88</span><span class="p">:</span><span class="mi">39</span><span class="p">:</span><span class="mi">9</span><span class="n">e</span><span class="p">:</span><span class="mi">17</span><span class="p">:</span>
+ <span class="n">cd</span><span class="p">:</span><span class="mi">3</span><span class="n">e</span><span class="p">:</span><span class="n">eb</span><span class="p">:</span><span class="n">a8</span><span class="p">:</span><span class="mi">19</span><span class="p">:</span><span class="mi">8</span><span class="n">d</span><span class="p">:</span><span class="n">a8</span><span class="p">:</span><span class="mi">2</span><span class="n">a</span><span class="p">:</span><span class="n">f1</span><span class="p">:</span><span class="mi">43</span><span class="p">:</span><span class="n">da</span><span class="p">:</span><span class="mi">55</span><span class="p">:</span><span class="n">a9</span><span class="p">:</span><span class="mi">2</span><span class="n">e</span><span class="p">:</span><span class="mi">2</span><span class="n">c</span><span class="p">:</span>
+ <span class="mi">65</span><span class="p">:</span><span class="n">ed</span><span class="p">:</span><span class="mi">04</span><span class="p">:</span><span class="mi">71</span><span class="p">:</span><span class="mi">42</span><span class="p">:</span><span class="n">ce</span><span class="p">:</span><span class="mi">73</span><span class="p">:</span><span class="mi">53</span><span class="p">:</span><span class="n">b8</span><span class="p">:</span><span class="n">ea</span><span class="p">:</span><span class="mi">7</span><span class="n">e</span><span class="p">:</span><span class="n">c7</span><span class="p">:</span><span class="n">f0</span><span class="p">:</span><span class="mi">23</span><span class="p">:</span><span class="n">c6</span><span class="p">:</span>
+ <span class="mi">63</span><span class="p">:</span><span class="n">c5</span><span class="p">:</span><span class="mi">5</span><span class="n">e</span><span class="p">:</span><span class="mi">68</span><span class="p">:</span><span class="mi">96</span><span class="p">:</span><span class="mi">64</span><span class="p">:</span><span class="n">a7</span><span class="p">:</span><span class="n">b4</span><span class="p">:</span><span class="mi">2</span><span class="n">a</span><span class="p">:</span><span class="mi">94</span><span class="p">:</span><span class="mi">26</span><span class="p">:</span><span class="mi">76</span><span class="p">:</span><span class="n">eb</span><span class="p">:</span><span class="mi">79</span><span class="p">:</span><span class="n">ea</span><span class="p">:</span>
+ <span class="n">e3</span><span class="p">:</span><span class="mi">4</span><span class="n">e</span><span class="p">:</span><span class="n">aa</span><span class="p">:</span><span class="mi">82</span><span class="p">:</span><span class="mi">09</span><span class="p">:</span><span class="mi">4</span><span class="n">f</span><span class="p">:</span><span class="mi">44</span><span class="p">:</span><span class="mi">87</span><span class="p">:</span><span class="mi">4</span><span class="n">a</span><span class="p">:</span><span class="mi">12</span><span class="p">:</span><span class="mi">62</span><span class="p">:</span><span class="n">b5</span><span class="p">:</span><span class="n">d7</span><span class="p">:</span><span class="mi">1</span><span class="n">f</span><span class="p">:</span><span class="n">ca</span><span class="p">:</span>
+ <span class="n">f2</span><span class="p">:</span><span class="n">ce</span><span class="p">:</span><span class="n">d5</span><span class="p">:</span><span class="n">ba</span><span class="p">:</span><span class="mi">7</span><span class="n">e</span><span class="p">:</span><span class="mi">1</span><span class="n">f</span><span class="p">:</span><span class="mi">48</span><span class="p">:</span><span class="n">fd</span><span class="p">:</span><span class="n">b9</span>
+ <span class="n">Exponent</span><span class="p">:</span> <span class="mi">65537</span> <span class="p">(</span><span class="mh">0x10001</span><span class="p">)</span>
+ <span class="n">X509v3</span> <span class="n">extensions</span><span class="p">:</span>
+ <span class="n">X509v3</span> <span class="n">Subject</span> <span class="n">Key</span> <span class="n">Identifier</span><span class="p">:</span>
+ <span class="mi">29</span><span class="p">:</span><span class="n">FB</span><span class="p">:</span><span class="mi">38</span><span class="p">:</span><span class="n">B6</span><span class="p">:</span><span class="n">BF</span><span class="p">:</span><span class="n">E2</span><span class="p">:</span><span class="mi">40</span><span class="p">:</span><span class="n">BB</span><span class="p">:</span><span class="n">FF</span><span class="p">:</span><span class="n">D5</span><span class="p">:</span><span class="mi">71</span><span class="p">:</span><span class="n">D7</span><span class="p">:</span><span class="n">D5</span><span class="p">:</span><span class="n">C4</span><span class="p">:</span><span class="n">F0</span><span class="p">:</span><span class="mi">83</span><span class="p">:</span><span class="mi">1</span><span class="n">A</span><span class="p">:</span><span class="mi">2</span><span class="n">B</span><span class="p">:</span><span class="n">C7</span><span class="p">:</span><span class="mi">99</span>
+ <span class="n">X509v3</span> <span class="n">Authority</span> <span class="n">Key</span> <span class="n">Identifier</span><span class="p">:</span>
+ <span class="n">keyid</span><span class="p">:</span><span class="mi">29</span><span class="p">:</span><span class="n">FB</span><span class="p">:</span><span class="mi">38</span><span class="p">:</span><span class="n">B6</span><span class="p">:</span><span class="n">BF</span><span class="p">:</span><span class="n">E2</span><span class="p">:</span><span class="mi">40</span><span class="p">:</span><span class="n">BB</span><span class="p">:</span><span class="n">FF</span><span class="p">:</span><span class="n">D5</span><span class="p">:</span><span class="mi">71</span><span class="p">:</span><span class="n">D7</span><span class="p">:</span><span class="n">D5</span><span class="p">:</span><span class="n">C4</span><span class="p">:</span><span class="n">F0</span><span class="p">:</span><span class="mi">83</span><span class="p">:</span><span class="mi">1</span><span class="n">A</span><span class="p">:</span><span class="mi">2</span><span class="n">B</span><span class="p">:</span><span class="n">C7</span><span class="p">:</span><span class="mi">99</span>
+ <span class="n">DirName</span><span class="p">:</span><span class="o">/</span><span class="n">C</span><span class="o">=</span><span class="n">SG</span><span class="o">/</span><span class="n">O</span><span class="o">=</span><span class="n">M2Crypto</span><span class="o">/</span><span class="n">CN</span><span class="o">=</span><span class="n">S</span><span class="o">/</span><span class="n">MIME</span> <span class="n">Sender</span><span class="o">/</span><span class="n">Email</span><span class="o">=</span><span class="n">sender</span><span class="nd">@example</span><span class="o">.</span><span class="n">dom</span>
+ <span class="n">serial</span><span class="p">:</span><span class="mi">00</span>
+
+ <span class="n">X509v3</span> <span class="n">Basic</span> <span class="n">Constraints</span><span class="p">:</span>
+ <span class="n">CA</span><span class="p">:</span><span class="n">TRUE</span>
+ <span class="n">Signature</span> <span class="n">Algorithm</span><span class="p">:</span> <span class="n">md5WithRSAEncryption</span>
+ <span class="mi">68</span><span class="p">:</span><span class="n">c8</span><span class="p">:</span><span class="mi">6</span><span class="n">b</span><span class="p">:</span><span class="mi">1</span><span class="n">b</span><span class="p">:</span><span class="n">fa</span><span class="p">:</span><span class="mi">7</span><span class="n">c</span><span class="p">:</span><span class="mi">9</span><span class="n">a</span><span class="p">:</span><span class="mi">39</span><span class="p">:</span><span class="mi">35</span><span class="p">:</span><span class="mi">76</span><span class="p">:</span><span class="mi">18</span><span class="p">:</span><span class="mi">15</span><span class="p">:</span><span class="n">c9</span><span class="p">:</span><span class="n">fd</span><span class="p">:</span><span class="mi">89</span><span class="p">:</span><span class="mi">97</span><span class="p">:</span><span class="mi">62</span><span class="p">:</span><span class="n">db</span><span class="p">:</span>
+ <span class="mi">7</span><span class="n">a</span><span class="p">:</span><span class="n">b0</span><span class="p">:</span><span class="mi">2</span><span class="n">d</span><span class="p">:</span><span class="mi">13</span><span class="p">:</span><span class="n">dd</span><span class="p">:</span><span class="mi">97</span><span class="p">:</span><span class="n">e8</span><span class="p">:</span><span class="mi">1</span><span class="n">b</span><span class="p">:</span><span class="mi">7</span><span class="n">a</span><span class="p">:</span><span class="mi">9</span><span class="n">f</span><span class="p">:</span><span class="mi">22</span><span class="p">:</span><span class="mi">27</span><span class="p">:</span><span class="mi">83</span><span class="p">:</span><span class="mi">24</span><span class="p">:</span><span class="mi">9</span><span class="n">d</span><span class="p">:</span><span class="mi">2</span><span class="n">e</span><span class="p">:</span><span class="mi">56</span><span class="p">:</span><span class="n">ec</span><span class="p">:</span>
+ <span class="mi">97</span><span class="p">:</span><span class="mi">89</span><span class="p">:</span><span class="mi">3</span><span class="n">c</span><span class="p">:</span><span class="n">ef</span><span class="p">:</span><span class="mi">16</span><span class="p">:</span><span class="mi">55</span><span class="p">:</span><span class="mi">80</span><span class="p">:</span><span class="mi">5</span><span class="n">a</span><span class="p">:</span><span class="mi">18</span><span class="p">:</span><span class="mi">7</span><span class="n">c</span><span class="p">:</span><span class="mi">22</span><span class="p">:</span><span class="n">d0</span><span class="p">:</span><span class="n">f6</span><span class="p">:</span><span class="n">bb</span><span class="p">:</span><span class="n">e3</span><span class="p">:</span><span class="n">a4</span><span class="p">:</span><span class="n">e8</span><span class="p">:</span><span class="mi">59</span><span class="p">:</span>
+ <span class="mi">30</span><span class="p">:</span><span class="n">ff</span><span class="p">:</span><span class="mi">99</span><span class="p">:</span><span class="mi">5</span><span class="n">a</span><span class="p">:</span><span class="mi">93</span><span class="p">:</span><span class="mi">3</span><span class="n">e</span><span class="p">:</span><span class="n">ea</span><span class="p">:</span><span class="n">bc</span><span class="p">:</span><span class="n">ee</span><span class="p">:</span><span class="mi">7</span><span class="n">f</span><span class="p">:</span><span class="mi">8</span><span class="n">d</span><span class="p">:</span><span class="n">d6</span><span class="p">:</span><span class="mi">7</span><span class="n">d</span><span class="p">:</span><span class="mi">37</span><span class="p">:</span><span class="mi">8</span><span class="n">c</span><span class="p">:</span><span class="n">ac</span><span class="p">:</span><span class="mi">3</span><span class="n">d</span><span class="p">:</span><span class="mi">74</span><span class="p">:</span>
+ <span class="mi">80</span><span class="p">:</span><span class="n">ce</span><span class="p">:</span><span class="mi">7</span><span class="n">a</span><span class="p">:</span><span class="mi">99</span><span class="p">:</span><span class="n">ba</span><span class="p">:</span><span class="mi">27</span><span class="p">:</span><span class="n">b9</span><span class="p">:</span><span class="mi">2</span><span class="n">a</span><span class="p">:</span><span class="n">a3</span><span class="p">:</span><span class="mi">71</span><span class="p">:</span><span class="n">fa</span><span class="p">:</span><span class="n">a5</span><span class="p">:</span><span class="mi">25</span><span class="p">:</span><span class="n">ba</span><span class="p">:</span><span class="mi">47</span><span class="p">:</span><span class="mi">17</span><span class="p">:</span><span class="n">df</span><span class="p">:</span><span class="mi">07</span><span class="p">:</span>
+ <span class="mi">56</span><span class="p">:</span><span class="mi">96</span><span class="p">:</span><span class="mi">36</span><span class="p">:</span><span class="n">fd</span><span class="p">:</span><span class="mi">60</span><span class="p">:</span><span class="n">b9</span><span class="p">:</span><span class="mi">6</span><span class="n">c</span><span class="p">:</span><span class="mi">96</span><span class="p">:</span><span class="mi">06</span><span class="p">:</span><span class="n">e8</span><span class="p">:</span><span class="n">e3</span><span class="p">:</span><span class="mi">7</span><span class="n">b</span><span class="p">:</span><span class="mi">9</span><span class="n">f</span><span class="p">:</span><span class="mi">4</span><span class="n">b</span><span class="p">:</span><span class="mi">6</span><span class="n">a</span><span class="p">:</span><span class="mi">95</span><span class="p">:</span><span class="mi">71</span><span class="p">:</span><span class="n">a8</span><span class="p">:</span>
+ <span class="mi">34</span><span class="p">:</span><span class="n">fc</span><span class="p">:</span><span class="n">fc</span><span class="p">:</span><span class="n">b5</span><span class="p">:</span><span class="mi">88</span><span class="p">:</span><span class="mi">8</span><span class="n">b</span><span class="p">:</span><span class="n">c4</span><span class="p">:</span><span class="mi">3</span><span class="n">f</span><span class="p">:</span><span class="mi">1</span><span class="n">e</span><span class="p">:</span><span class="mi">24</span><span class="p">:</span><span class="n">f6</span><span class="p">:</span><span class="mi">52</span><span class="p">:</span><span class="mi">47</span><span class="p">:</span><span class="n">b2</span><span class="p">:</span><span class="mi">7</span><span class="n">d</span><span class="p">:</span><span class="mi">44</span><span class="p">:</span><span class="mi">67</span><span class="p">:</span><span class="n">d9</span><span class="p">:</span>
+ <span class="mi">83</span><span class="p">:</span><span class="n">e8</span>
+</pre></div>
+</div>
+<p>Next, we generate a self-signed X.509 certificate for the recipient.
+Note that <code class="docutils literal notranslate"><span class="pre">privkey.pem</span></code> will be recreated:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">openssl</span> <span class="n">req</span> <span class="o">-</span><span class="n">newkey</span> <span class="n">rsa</span><span class="p">:</span><span class="mi">1024</span> <span class="o">-</span><span class="n">nodes</span> <span class="o">-</span><span class="n">x509</span> <span class="o">-</span><span class="n">days</span> <span class="mi">365</span> <span class="o">-</span><span class="n">out</span> <span class="n">recipient</span><span class="o">.</span><span class="n">pem</span>
+
+<span class="n">Using</span> <span class="n">configuration</span> <span class="kn">from</span> <span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="n">local</span><span class="o">/</span><span class="n">pkg</span><span class="o">/</span><span class="n">openssl</span><span class="o">/</span><span class="n">openssl</span><span class="o">.</span><span class="n">cnf</span>
+<span class="n">Generating</span> <span class="n">a</span> <span class="mi">1024</span> <span class="n">bit</span> <span class="n">RSA</span> <span class="n">private</span> <span class="n">key</span>
+<span class="o">.....................................++++++</span>
+<span class="o">.................++++++</span>
+<span class="n">writing</span> <span class="n">new</span> <span class="n">private</span> <span class="n">key</span> <span class="n">to</span> <span class="s1">&#39;privkey.pem&#39;</span>
+<span class="o">-----</span>
+<span class="n">You</span> <span class="n">are</span> <span class="n">about</span> <span class="n">to</span> <span class="n">be</span> <span class="n">asked</span> <span class="n">to</span> <span class="n">enter</span> <span class="n">information</span> <span class="n">that</span> <span class="n">will</span> <span class="n">be</span> <span class="n">incorporated</span>
+<span class="n">into</span> <span class="n">your</span> <span class="n">certificate</span> <span class="n">request</span><span class="o">.</span>
+<span class="n">What</span> <span class="n">you</span> <span class="n">are</span> <span class="n">about</span> <span class="n">to</span> <span class="n">enter</span> <span class="ow">is</span> <span class="n">what</span> <span class="ow">is</span> <span class="n">called</span> <span class="n">a</span> <span class="n">Distinguished</span> <span class="n">Name</span> <span class="ow">or</span> <span class="n">a</span> <span class="n">DN</span><span class="o">.</span>
+<span class="n">There</span> <span class="n">are</span> <span class="n">quite</span> <span class="n">a</span> <span class="n">few</span> <span class="n">fields</span> <span class="n">but</span> <span class="n">you</span> <span class="n">can</span> <span class="n">leave</span> <span class="n">some</span> <span class="n">blank</span>
+<span class="n">For</span> <span class="n">some</span> <span class="n">fields</span> <span class="n">there</span> <span class="n">will</span> <span class="n">be</span> <span class="n">a</span> <span class="n">default</span> <span class="n">value</span><span class="p">,</span>
+<span class="n">If</span> <span class="n">you</span> <span class="n">enter</span> <span class="s1">&#39;.&#39;</span><span class="p">,</span> <span class="n">the</span> <span class="n">field</span> <span class="n">will</span> <span class="n">be</span> <span class="n">left</span> <span class="n">blank</span><span class="o">.</span>
+<span class="o">-----</span>
+<span class="n">Country</span> <span class="n">Name</span> <span class="p">(</span><span class="mi">2</span> <span class="n">letter</span> <span class="n">code</span><span class="p">)</span> <span class="p">[</span><span class="n">AU</span><span class="p">]:</span><span class="n">SG</span>
+<span class="n">State</span> <span class="ow">or</span> <span class="n">Province</span> <span class="n">Name</span> <span class="p">(</span><span class="n">full</span> <span class="n">name</span><span class="p">)</span> <span class="p">[</span><span class="n">Some</span><span class="o">-</span><span class="n">State</span><span class="p">]:</span><span class="o">.</span>
+<span class="n">Locality</span> <span class="n">Name</span> <span class="p">(</span><span class="n">eg</span><span class="p">,</span> <span class="n">city</span><span class="p">)</span> <span class="p">[]:</span><span class="o">.</span>
+<span class="n">Organization</span> <span class="n">Name</span> <span class="p">(</span><span class="n">eg</span><span class="p">,</span> <span class="n">company</span><span class="p">)</span> <span class="p">[</span><span class="n">Internet</span> <span class="n">Widgits</span> <span class="n">Pty</span> <span class="n">Ltd</span><span class="p">]:</span><span class="n">M2Crypto</span>
+<span class="n">Organizational</span> <span class="n">Unit</span> <span class="n">Name</span> <span class="p">(</span><span class="n">eg</span><span class="p">,</span> <span class="n">section</span><span class="p">)</span> <span class="p">[]:</span><span class="o">.</span>
+<span class="n">Common</span> <span class="n">Name</span> <span class="p">(</span><span class="n">eg</span><span class="p">,</span> <span class="n">YOUR</span> <span class="n">name</span><span class="p">)</span> <span class="p">[]:</span><span class="n">S</span><span class="o">/</span><span class="n">MIME</span> <span class="n">Recipient</span>
+<span class="n">Email</span> <span class="n">Address</span> <span class="p">[]:</span><span class="n">recipient</span><span class="nd">@example</span><span class="o">.</span><span class="n">dom</span>
+</pre></div>
+</div>
+<p>Again, rename <code class="docutils literal notranslate"><span class="pre">privkey.pem</span></code>:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">mv</span> <span class="n">privkey</span><span class="o">.</span><span class="n">pem</span> <span class="n">recipient_key</span><span class="o">.</span><span class="n">pem</span>
+</pre></div>
+</div>
+<p>In the examples to follow, S/MIME Sender, <code class="docutils literal notranslate"><span class="pre">&lt;sender&#64;example.dom&gt;</span></code>,
+shall be the sender of S/MIME messages, while S/MIME Recipient,
+<code class="docutils literal notranslate"><span class="pre">&lt;recipient&#64;example.dom&gt;</span></code>, shall be the recipient of S/MIME messages.</p>
+<p>Armed with the key pairs and certificates, we are now ready to begin
+programming S/MIME in Python.</p>
+<blockquote>
+<div><p><strong>Note:</strong> The private keys generated above are <em>not
+passphrase-protected</em>, i.e., they are <em>in the clear</em>. Anyone who has
+access to such a key can generate S/MIME-signed messages with it,
+and decrypt S/MIME messages encrypted to it’s corresponding public
+key.</p>
+<p>We may passphrase-protect the keys, if we so choose. M2Crypto will
+prompt the user for the passphrase when such a key is being loaded.</p>
+</div></blockquote>
+</div>
+<div class="section" id="m2crypto-smime">
+<h1>M2Crypto.SMIME<a class="headerlink" href="#m2crypto-smime" title="Permalink to this headline">¶</a></h1>
+<p>The Python programmer accesses M2Crypto’s S/MIME functionality through
+class <code class="docutils literal notranslate"><span class="pre">SMIME</span></code> in the module <code class="docutils literal notranslate"><span class="pre">M2Crypto.SMIME</span></code>. Typically, an
+<code class="docutils literal notranslate"><span class="pre">SMIME</span></code> object is instantiated; the object is then set up for the
+intended operation: sign, encrypt, decrypt or verify; finally, the
+operation is invoked on the object.</p>
+<p><code class="docutils literal notranslate"><span class="pre">M2Crypto.SMIME</span></code> makes extensive use of <code class="docutils literal notranslate"><span class="pre">M2Crypto.BIO</span></code>:
+<code class="docutils literal notranslate"><span class="pre">M2Crypto.BIO</span></code> is a Python abstraction of the <code class="docutils literal notranslate"><span class="pre">BIO</span></code> abstraction in
+OpenSSL. A commonly used <code class="docutils literal notranslate"><span class="pre">BIO</span></code> abstraction in M2Crypto is
+<code class="docutils literal notranslate"><span class="pre">M2Crypto.BIO.MemoryBuffer</span></code>, which implements a memory-based file-like
+object, similar to Python’s own <code class="docutils literal notranslate"><span class="pre">StringIO</span></code>.</p>
+</div>
+<div class="section" id="sign">
+<h1>Sign<a class="headerlink" href="#sign" title="Permalink to this headline">¶</a></h1>
+<p>The following code demonstrates how to generate an S/MIME-signed
+message. <code class="docutils literal notranslate"><span class="pre">randpool.dat</span></code> contains random data which is used to seed
+OpenSSL’s pseudo-random number generator via M2Crypto:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">M2Crypto</span> <span class="k">import</span> <span class="n">BIO</span><span class="p">,</span> <span class="n">Rand</span><span class="p">,</span> <span class="n">SMIME</span>
+
+<span class="k">def</span> <span class="nf">makebuf</span><span class="p">(</span><span class="n">text</span><span class="p">):</span>
+ <span class="k">return</span> <span class="n">BIO</span><span class="o">.</span><span class="n">MemoryBuffer</span><span class="p">(</span><span class="n">text</span><span class="p">)</span>
+
+<span class="c1"># Make a MemoryBuffer of the message.</span>
+<span class="n">buf</span> <span class="o">=</span> <span class="n">makebuf</span><span class="p">(</span><span class="s1">&#39;a sign of our times&#39;</span><span class="p">)</span>
+
+<span class="c1"># Seed the PRNG.</span>
+<span class="n">Rand</span><span class="o">.</span><span class="n">load_file</span><span class="p">(</span><span class="s1">&#39;randpool.dat&#39;</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span>
+
+<span class="c1"># Instantiate an SMIME object; set it up; sign the buffer.</span>
+<span class="n">s</span> <span class="o">=</span> <span class="n">SMIME</span><span class="o">.</span><span class="n">SMIME</span><span class="p">()</span>
+<span class="n">s</span><span class="o">.</span><span class="n">load_key</span><span class="p">(</span><span class="s1">&#39;signer_key.pem&#39;</span><span class="p">,</span> <span class="s1">&#39;signer.pem&#39;</span><span class="p">)</span>
+<span class="n">p7</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">sign</span><span class="p">(</span><span class="n">buf</span><span class="p">,</span> <span class="n">SMIME</span><span class="o">.</span><span class="n">PKCS7_DETACHED</span><span class="p">)</span>
+</pre></div>
+</div>
+<p><code class="docutils literal notranslate"><span class="pre">p7</span></code> now contains a <em>PKCS #7 signature blob</em> wrapped in an
+<code class="docutils literal notranslate"><span class="pre">M2Crypto.SMIME.PKCS7</span></code> object. Note that <code class="docutils literal notranslate"><span class="pre">buf</span></code> has been consumed by
+<code class="docutils literal notranslate"><span class="pre">sign()</span></code> and has to be recreated if it is to be used again.</p>
+<p>We may now send the signed message via SMTP. In these examples, we shall
+not do so; instead, we’ll render the S/MIME output in mail-friendly
+format, and pretend that our messages are sent and received
+correctly:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># Recreate buf.</span>
+<span class="n">buf</span> <span class="o">=</span> <span class="n">makebuf</span><span class="p">(</span><span class="s1">&#39;a sign of our times&#39;</span><span class="p">)</span>
+
+<span class="c1"># Output p7 in mail-friendly format.</span>
+<span class="n">out</span> <span class="o">=</span> <span class="n">BIO</span><span class="o">.</span><span class="n">MemoryBuffer</span><span class="p">()</span>
+<span class="n">out</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;From: sender@example.dom</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">)</span>
+<span class="n">out</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;To: recipient@example.dom</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">)</span>
+<span class="n">out</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;Subject: M2Crypto S/MIME testing</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">)</span>
+<span class="n">s</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">out</span><span class="p">,</span> <span class="n">p7</span><span class="p">,</span> <span class="n">buf</span><span class="p">)</span>
+
+<span class="nb">print</span><span class="p">(</span><span class="n">out</span><span class="o">.</span><span class="n">read</span><span class="p">())</span>
+
+<span class="c1"># Save the PRNG&#39;s state.</span>
+<span class="n">Rand</span><span class="o">.</span><span class="n">save_file</span><span class="p">(</span><span class="s1">&#39;randpool.dat&#39;</span><span class="p">)</span>
+</pre></div>
+</div>
+<p>Here’s the output:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">From</span><span class="p">:</span> <span class="n">sender</span><span class="nd">@example</span><span class="o">.</span><span class="n">dom</span>
+<span class="n">To</span><span class="p">:</span> <span class="n">recipient</span><span class="nd">@example</span><span class="o">.</span><span class="n">dom</span>
+<span class="n">Subject</span><span class="p">:</span> <span class="n">M2Crypto</span> <span class="n">S</span><span class="o">/</span><span class="n">MIME</span> <span class="n">testing</span>
+<span class="n">MIME</span><span class="o">-</span><span class="n">Version</span><span class="p">:</span> <span class="mf">1.0</span>
+<span class="n">Content</span><span class="o">-</span><span class="n">Type</span><span class="p">:</span> <span class="n">multipart</span><span class="o">/</span><span class="n">signed</span> <span class="p">;</span> <span class="n">protocol</span><span class="o">=</span><span class="s2">&quot;application/x-pkcs7-signature&quot;</span> <span class="p">;</span> <span class="n">micalg</span><span class="o">=</span><span class="n">sha1</span> <span class="p">;</span> <span class="n">boundary</span><span class="o">=</span><span class="s2">&quot;----3C93156FC7B4EBF49FE9C7DB7F503087&quot;</span>
+
+<span class="n">This</span> <span class="ow">is</span> <span class="n">an</span> <span class="n">S</span><span class="o">/</span><span class="n">MIME</span> <span class="n">signed</span> <span class="n">message</span>
+
+<span class="o">------</span><span class="mi">3</span><span class="n">C93156FC7B4EBF49FE9C7DB7F503087</span>
+<span class="n">a</span> <span class="n">sign</span> <span class="n">of</span> <span class="n">our</span> <span class="n">times</span>
+<span class="o">------</span><span class="mi">3</span><span class="n">C93156FC7B4EBF49FE9C7DB7F503087</span>
+<span class="n">Content</span><span class="o">-</span><span class="n">Type</span><span class="p">:</span> <span class="n">application</span><span class="o">/</span><span class="n">x</span><span class="o">-</span><span class="n">pkcs7</span><span class="o">-</span><span class="n">signature</span><span class="p">;</span> <span class="n">name</span><span class="o">=</span><span class="s2">&quot;smime.p7s&quot;</span>
+<span class="n">Content</span><span class="o">-</span><span class="n">Transfer</span><span class="o">-</span><span class="n">Encoding</span><span class="p">:</span> <span class="n">base64</span>
+<span class="n">Content</span><span class="o">-</span><span class="n">Disposition</span><span class="p">:</span> <span class="n">attachment</span><span class="p">;</span> <span class="n">filename</span><span class="o">=</span><span class="s2">&quot;smime.p7s&quot;</span>
+
+<span class="n">MIIE8AYJKoZIhvcNAQcCoIIE4TCCBN0CAQExCzAJBgUrDgMCGgUAMCIGCSqGSIb3</span>
+<span class="n">DQEHAaAVBBNhIHNpZ24gb2Ygb3VyIHRpbWVzoIIC5zCCAuMwggJMoAMCAQICAQAw</span>
+<span class="n">DQYJKoZIhvcNAQEEBQAwWzELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRv</span>
+<span class="n">MRYwFAYDVQQDEw1TL01JTUUgU2VuZGVyMSEwHwYJKoZIhvcNAQkBFhJzZW5kZXJA</span>
+<span class="n">ZXhhbXBsZS5kb20wHhcNMDEwMzMxMTE0MDMzWhcNMDIwMzMxMTE0MDMzWjBbMQsw</span>
+<span class="n">CQYDVQQGEwJTRzERMA8GA1UEChMITTJDcnlwdG8xFjAUBgNVBAMTDVMvTUlNRSBT</span>
+<span class="n">ZW5kZXIxITAfBgkqhkiG9w0BCQEWEnNlbmRlckBleGFtcGxlLmRvbTCBnzANBgkq</span>
+<span class="n">hkiG9w0BAQEFAAOBjQAwgYkCgYEA5c5Tj1CHTSOxa1q2q0FYiwMWYHptJpJcvtZm</span>
+<span class="n">UwrgU5sHrA8OnCM0cDXEj0KPf3cfNjHffB8HWMzI4UEgNmFXQNsxoGZ</span><span class="o">+</span><span class="n">iqwxLlNj</span>
+<span class="n">y9Mh7eFW</span><span class="o">/</span><span class="n">Bjq5hNXbouSlQ0rWBRkoxV64y</span><span class="o">+</span><span class="n">t6lQehb32WfYXQbKFxFJSXzSxOx3R</span>
+<span class="mi">8</span><span class="n">YhSPd0CAwEAAaOBtjCBszAdBgNVHQ4EFgQUXOyolL1t4jaBwZFRM7MS8nBLzUow</span>
+<span class="n">gYMGA1UdIwR8MHqAFFzsqJS9beI2gcGRUTOzEvJwS81KoV</span><span class="o">+</span><span class="n">kXTBbMQswCQYDVQQG</span>
+<span class="n">EwJTRzERMA8GA1UEChMITTJDcnlwdG8xFjAUBgNVBAMTDVMvTUlNRSBTZW5kZXIx</span>
+<span class="n">ITAfBgkqhkiG9w0BCQEWEnNlbmRlckBleGFtcGxlLmRvbYIBADAMBgNVHRMEBTAD</span>
+<span class="n">AQH</span><span class="o">/</span><span class="n">MA0GCSqGSIb3DQEBBAUAA4GBAHo3DrCHR86fSTVAvfiXdSswWqKtCEhUHRdC</span>
+<span class="n">TLFGl4hDk2GyZxaFuqZwiURz</span><span class="o">/</span><span class="n">H7nMicymI2wkz8H</span><span class="o">/</span><span class="n">wyHFg8G3BIehURpj2v</span><span class="o">/</span><span class="n">ZWXY</span>
+<span class="n">eovbgS7EZALVVkDj4hNl</span><span class="o">/</span><span class="n">IIHWd6Gtv1UODf7URbxtl3hQ9</span><span class="o">/</span><span class="n">eTWITrefT1heuPnar</span>
+<span class="mi">8</span><span class="n">czydsOLMYIBujCCAbYCAQEwYDBbMQswCQYDVQQGEwJTRzERMA8GA1UEChMITTJD</span>
+<span class="n">cnlwdG8xFjAUBgNVBAMTDVMvTUlNRSBTZW5kZXIxITAfBgkqhkiG9w0BCQEWEnNl</span>
+<span class="n">bmRlckBleGFtcGxlLmRvbQIBADAJBgUrDgMCGgUAoIGxMBgGCSqGSIb3DQEJAzEL</span>
+<span class="n">BgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTAxMDMzMTExNDUwMlowIwYJKoZI</span>
+<span class="n">hvcNAQkEMRYEFOoeRUd8ExIYXfQq8BTFuKWrSP3iMFIGCSqGSIb3DQEJDzFFMEMw</span>
+<span class="n">CgYIKoZIhvcNAwcwDgYIKoZIhvcNAwICAgCAMA0GCCqGSIb3DQMCAgFAMAcGBSsO</span>
+<span class="n">AwIHMA0GCCqGSIb3DQMCAgEoMA0GCSqGSIb3DQEBAQUABIGAQpU8hFUtLCF6hO2t</span>
+<span class="n">ec9EYJ</span><span class="o">/</span><span class="n">Imqqiiw</span><span class="o">+</span><span class="n">BxWxkUUVT81Vbjwdn9JST6</span><span class="o">+</span><span class="n">sztM5JRP2ZW</span><span class="o">+</span><span class="n">b4txEjZriYC8f3</span>
+<span class="n">kv95YMTGbIsuWkJ93GrbvqoJ</span><span class="o">/</span><span class="n">CxO23r9WWRnZEm</span><span class="o">/</span><span class="mi">1</span><span class="n">EZN9ZmlrYqzBTxnNRmP3Dhj</span>
+<span class="n">cW8kzZwH</span><span class="o">+</span><span class="mi">2</span><span class="o">/</span><span class="mi">2</span><span class="n">zz2G7x1HxRWH95A</span><span class="o">=</span>
+
+<span class="o">------</span><span class="mi">3</span><span class="n">C93156FC7B4EBF49FE9C7DB7F503087</span><span class="o">--</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="verify">
+<h1>Verify<a class="headerlink" href="#verify" title="Permalink to this headline">¶</a></h1>
+<p>Assume the above output has been saved into <code class="docutils literal notranslate"><span class="pre">sign.p7</span></code>. Let’s now
+verify the signature:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">M2Crypto</span> <span class="k">import</span> <span class="n">SMIME</span><span class="p">,</span> <span class="n">X509</span>
+
+<span class="c1"># Instantiate an SMIME object.</span>
+<span class="n">s</span> <span class="o">=</span> <span class="n">SMIME</span><span class="o">.</span><span class="n">SMIME</span><span class="p">()</span>
+
+<span class="c1"># Load the signer&#39;s cert.</span>
+<span class="n">x509</span> <span class="o">=</span> <span class="n">X509</span><span class="o">.</span><span class="n">load_cert</span><span class="p">(</span><span class="s1">&#39;signer.pem&#39;</span><span class="p">)</span>
+<span class="n">sk</span> <span class="o">=</span> <span class="n">X509</span><span class="o">.</span><span class="n">X509_Stack</span><span class="p">()</span>
+<span class="n">sk</span><span class="o">.</span><span class="n">push</span><span class="p">(</span><span class="n">x509</span><span class="p">)</span>
+<span class="n">s</span><span class="o">.</span><span class="n">set_x509_stack</span><span class="p">(</span><span class="n">sk</span><span class="p">)</span>
+
+<span class="c1"># Load the signer&#39;s CA cert. In this case, because the signer&#39;s</span>
+<span class="c1"># cert is self-signed, it is the signer&#39;s cert itself.</span>
+<span class="n">st</span> <span class="o">=</span> <span class="n">X509</span><span class="o">.</span><span class="n">X509_Store</span><span class="p">()</span>
+<span class="n">st</span><span class="o">.</span><span class="n">load_info</span><span class="p">(</span><span class="s1">&#39;signer.pem&#39;</span><span class="p">)</span>
+<span class="n">s</span><span class="o">.</span><span class="n">set_x509_store</span><span class="p">(</span><span class="n">st</span><span class="p">)</span>
+
+<span class="c1"># Load the data, verify it.</span>
+<span class="n">p7</span><span class="p">,</span> <span class="n">data</span> <span class="o">=</span> <span class="n">SMIME</span><span class="o">.</span><span class="n">smime_load_pkcs7</span><span class="p">(</span><span class="s1">&#39;sign.p7&#39;</span><span class="p">)</span>
+<span class="n">v</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">verify</span><span class="p">(</span><span class="n">p7</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span>
+<span class="nb">print</span><span class="p">(</span><span class="n">v</span><span class="p">)</span>
+<span class="nb">print</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
+<span class="nb">print</span><span class="p">(</span><span class="n">data</span><span class="o">.</span><span class="n">read</span><span class="p">())</span>
+</pre></div>
+</div>
+<p>Here’s the output of the above program:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">a</span> <span class="n">sign</span> <span class="n">of</span> <span class="n">our</span> <span class="n">times</span>
+<span class="o">&lt;</span><span class="n">M2Crypto</span><span class="o">.</span><span class="n">BIO</span><span class="o">.</span><span class="n">BIO</span> <span class="n">instance</span> <span class="n">at</span> <span class="mh">0x822012c</span><span class="o">&gt;</span>
+<span class="n">a</span> <span class="n">sign</span> <span class="n">of</span> <span class="n">our</span> <span class="n">times</span>
+</pre></div>
+</div>
+<p>Suppose, instead of loading <code class="docutils literal notranslate"><span class="pre">signer.pem</span></code> above, we load
+<code class="docutils literal notranslate"><span class="pre">recipient.pem</span></code>. That is, we do a global substitution of
+<code class="docutils literal notranslate"><span class="pre">recipient.pem</span></code> for <code class="docutils literal notranslate"><span class="pre">signer.pem</span></code> in the above program. Here’s the
+modified program’s output:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>Traceback (most recent call last):
+ File &quot;./verify.py&quot;, line 22, in ?
+ v = s.verify(p7)
+ File &quot;/usr/local/home/ngps/prog/m2/M2Crypto/SMIME.py&quot;, line 205, in verify
+ raise SMIME_Error, Err.get_error()
+M2Crypto.SMIME.SMIME_Error: 312:error:21075075:PKCS7 routines:PKCS7_verify:certificate verify error:pk7_smime.c:213:Verify error:self signed certificate
+</pre></div>
+</div>
+<p>As displayed, the error is generated by line 213 of OpenSSL’s
+<code class="docutils literal notranslate"><span class="pre">pk7_smime.c</span></code> (as of OpenSSL 0.9.6); if you are a C programmer, you
+may wish to look up the C source to explore OpenSSL’s S/MIME
+implementation and understand why the error message is worded thus.</p>
+</div>
+<div class="section" id="encrypt">
+<h1>Encrypt<a class="headerlink" href="#encrypt" title="Permalink to this headline">¶</a></h1>
+<p>We now demonstrate how to generate an S/MIME-encrypted message:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">M2Crypto</span> <span class="k">import</span> <span class="n">BIO</span><span class="p">,</span> <span class="n">Rand</span><span class="p">,</span> <span class="n">SMIME</span><span class="p">,</span> <span class="n">X509</span>
+
+<span class="k">def</span> <span class="nf">makebuf</span><span class="p">(</span><span class="n">text</span><span class="p">):</span>
+ <span class="k">return</span> <span class="n">BIO</span><span class="o">.</span><span class="n">MemoryBuffer</span><span class="p">(</span><span class="n">text</span><span class="p">)</span>
+
+<span class="c1"># Make a MemoryBuffer of the message.</span>
+<span class="n">buf</span> <span class="o">=</span> <span class="n">makebuf</span><span class="p">(</span><span class="s1">&#39;a sign of our times&#39;</span><span class="p">)</span>
+
+<span class="c1"># Seed the PRNG.</span>
+<span class="n">Rand</span><span class="o">.</span><span class="n">load_file</span><span class="p">(</span><span class="s1">&#39;randpool.dat&#39;</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span>
+
+<span class="c1"># Instantiate an SMIME object.</span>
+<span class="n">s</span> <span class="o">=</span> <span class="n">SMIME</span><span class="o">.</span><span class="n">SMIME</span><span class="p">()</span>
+
+<span class="c1"># Load target cert to encrypt to.</span>
+<span class="n">x509</span> <span class="o">=</span> <span class="n">X509</span><span class="o">.</span><span class="n">load_cert</span><span class="p">(</span><span class="s1">&#39;recipient.pem&#39;</span><span class="p">)</span>
+<span class="n">sk</span> <span class="o">=</span> <span class="n">X509</span><span class="o">.</span><span class="n">X509_Stack</span><span class="p">()</span>
+<span class="n">sk</span><span class="o">.</span><span class="n">push</span><span class="p">(</span><span class="n">x509</span><span class="p">)</span>
+<span class="n">s</span><span class="o">.</span><span class="n">set_x509_stack</span><span class="p">(</span><span class="n">sk</span><span class="p">)</span>
+
+<span class="c1"># Set cipher: 3-key triple-DES in CBC mode.</span>
+<span class="n">s</span><span class="o">.</span><span class="n">set_cipher</span><span class="p">(</span><span class="n">SMIME</span><span class="o">.</span><span class="n">Cipher</span><span class="p">(</span><span class="s1">&#39;des_ede3_cbc&#39;</span><span class="p">))</span>
+
+<span class="c1"># Encrypt the buffer.</span>
+<span class="n">p7</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">encrypt</span><span class="p">(</span><span class="n">buf</span><span class="p">)</span>
+
+<span class="c1"># Output p7 in mail-friendly format.</span>
+<span class="n">out</span> <span class="o">=</span> <span class="n">BIO</span><span class="o">.</span><span class="n">MemoryBuffer</span><span class="p">()</span>
+<span class="n">out</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;From: sender@example.dom</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">)</span>
+<span class="n">out</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;To: recipient@example.dom</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">)</span>
+<span class="n">out</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;Subject: M2Crypto S/MIME testing</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">)</span>
+<span class="n">s</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">out</span><span class="p">,</span> <span class="n">p7</span><span class="p">)</span>
+
+<span class="nb">print</span><span class="p">(</span><span class="n">out</span><span class="o">.</span><span class="n">read</span><span class="p">())</span>
+
+<span class="c1"># Save the PRNG&#39;s state.</span>
+<span class="n">Rand</span><span class="o">.</span><span class="n">save_file</span><span class="p">(</span><span class="s1">&#39;randpool.dat&#39;</span><span class="p">)</span>
+</pre></div>
+</div>
+<p>Here’s the output of the above program:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">From</span><span class="p">:</span> <span class="n">sender</span><span class="nd">@example</span><span class="o">.</span><span class="n">dom</span>
+<span class="n">To</span><span class="p">:</span> <span class="n">recipient</span><span class="nd">@example</span><span class="o">.</span><span class="n">dom</span>
+<span class="n">Subject</span><span class="p">:</span> <span class="n">M2Crypto</span> <span class="n">S</span><span class="o">/</span><span class="n">MIME</span> <span class="n">testing</span>
+<span class="n">MIME</span><span class="o">-</span><span class="n">Version</span><span class="p">:</span> <span class="mf">1.0</span>
+<span class="n">Content</span><span class="o">-</span><span class="n">Disposition</span><span class="p">:</span> <span class="n">attachment</span><span class="p">;</span> <span class="n">filename</span><span class="o">=</span><span class="s2">&quot;smime.p7m&quot;</span>
+<span class="n">Content</span><span class="o">-</span><span class="n">Type</span><span class="p">:</span> <span class="n">application</span><span class="o">/</span><span class="n">x</span><span class="o">-</span><span class="n">pkcs7</span><span class="o">-</span><span class="n">mime</span><span class="p">;</span> <span class="n">name</span><span class="o">=</span><span class="s2">&quot;smime.p7m&quot;</span>
+<span class="n">Content</span><span class="o">-</span><span class="n">Transfer</span><span class="o">-</span><span class="n">Encoding</span><span class="p">:</span> <span class="n">base64</span>
+
+<span class="n">MIIBVwYJKoZIhvcNAQcDoIIBSDCCAUQCAQAxggEAMIH9AgEAMGYwYTELMAkGA1UE</span>
+<span class="n">BhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRkwFwYDVQQDExBTL01JTUUgUmVjaXBp</span>
+<span class="n">ZW50MSQwIgYJKoZIhvcNAQkBFhVyZWNpcGllbnRAZXhhbXBsZS5kb20CAQAwDQYJ</span>
+<span class="n">KoZIhvcNAQEBBQAEgYCBaXZ</span><span class="o">+</span><span class="n">qjpBEZwdP7gjfzfAtQitESyMwo3i</span><span class="o">+</span><span class="n">LBOw6sSDir6</span>
+<span class="n">FlNDPCnkrTvqDX3Rt6X6vBtTCYOm</span><span class="o">+</span><span class="n">qiN7ujPkOU61cN7h8dvHR8YW9</span><span class="o">+</span><span class="mi">0</span><span class="n">IPY80</span><span class="o">/</span><span class="n">W0</span>
+<span class="n">lZ</span><span class="o">/</span><span class="n">HihSRgwTNd7LnxUUcPx8YV1id0dlmP0Hz</span><span class="o">+</span><span class="n">Lg</span><span class="o">+</span><span class="n">mHf6rqaR</span><span class="o">//</span><span class="n">JcYhX9vW4XvjA7</span>
+<span class="n">BgkqhkiG9w0BBwEwFAYIKoZIhvcNAwcECMN</span><span class="o">+</span><span class="n">qya6ADywgBgHr9Jkhwn5Gsdu7BwX</span>
+<span class="n">nIQfYTYcdL9I5Sk</span><span class="o">=</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="decrypt">
+<h1>Decrypt<a class="headerlink" href="#decrypt" title="Permalink to this headline">¶</a></h1>
+<p>Assume the above output has been saved into <code class="docutils literal notranslate"><span class="pre">encrypt.p7</span></code>. Decrypt the
+message thusly:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">M2Crypto</span> <span class="k">import</span> <span class="n">BIO</span><span class="p">,</span> <span class="n">SMIME</span><span class="p">,</span> <span class="n">X509</span>
+
+<span class="c1"># Instantiate an SMIME object.</span>
+<span class="n">s</span> <span class="o">=</span> <span class="n">SMIME</span><span class="o">.</span><span class="n">SMIME</span><span class="p">()</span>
+
+<span class="c1"># Load private key and cert.</span>
+<span class="n">s</span><span class="o">.</span><span class="n">load_key</span><span class="p">(</span><span class="s1">&#39;recipient_key.pem&#39;</span><span class="p">,</span> <span class="s1">&#39;recipient.pem&#39;</span><span class="p">)</span>
+
+<span class="c1"># Load the encrypted data.</span>
+<span class="n">p7</span><span class="p">,</span> <span class="n">data</span> <span class="o">=</span> <span class="n">SMIME</span><span class="o">.</span><span class="n">smime_load_pkcs7</span><span class="p">(</span><span class="s1">&#39;encrypt.p7&#39;</span><span class="p">)</span>
+
+<span class="c1"># Decrypt p7.</span>
+<span class="n">out</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">decrypt</span><span class="p">(</span><span class="n">p7</span><span class="p">)</span>
+
+<span class="nb">print</span><span class="p">(</span><span class="n">out</span><span class="p">)</span>
+</pre></div>
+</div>
+<p>Here’s the output:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">a</span> <span class="n">sign</span> <span class="n">of</span> <span class="n">our</span> <span class="n">times</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="sign-and-encrypt">
+<h1>Sign and Encrypt<a class="headerlink" href="#sign-and-encrypt" title="Permalink to this headline">¶</a></h1>
+<p>Here’s how to generate an S/MIME-signed/encrypted message:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">M2Crypto</span> <span class="k">import</span> <span class="n">BIO</span><span class="p">,</span> <span class="n">Rand</span><span class="p">,</span> <span class="n">SMIME</span><span class="p">,</span> <span class="n">X509</span>
+
+<span class="k">def</span> <span class="nf">makebuf</span><span class="p">(</span><span class="n">text</span><span class="p">):</span>
+ <span class="k">return</span> <span class="n">BIO</span><span class="o">.</span><span class="n">MemoryBuffer</span><span class="p">(</span><span class="n">text</span><span class="p">)</span>
+
+<span class="c1"># Make a MemoryBuffer of the message.</span>
+<span class="n">buf</span> <span class="o">=</span> <span class="n">makebuf</span><span class="p">(</span><span class="s1">&#39;a sign of our times&#39;</span><span class="p">)</span>
+
+<span class="c1"># Seed the PRNG.</span>
+<span class="n">Rand</span><span class="o">.</span><span class="n">load_file</span><span class="p">(</span><span class="s1">&#39;randpool.dat&#39;</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span>
+
+<span class="c1"># Instantiate an SMIME object.</span>
+<span class="n">s</span> <span class="o">=</span> <span class="n">SMIME</span><span class="o">.</span><span class="n">SMIME</span><span class="p">()</span>
+
+<span class="c1"># Load signer&#39;s key and cert. Sign the buffer.</span>
+<span class="n">s</span><span class="o">.</span><span class="n">load_key</span><span class="p">(</span><span class="s1">&#39;signer_key.pem&#39;</span><span class="p">,</span> <span class="s1">&#39;signer.pem&#39;</span><span class="p">)</span>
+<span class="n">p7</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">sign</span><span class="p">(</span><span class="n">buf</span><span class="p">)</span>
+
+<span class="c1"># Load target cert to encrypt the signed message to.</span>
+<span class="n">x509</span> <span class="o">=</span> <span class="n">X509</span><span class="o">.</span><span class="n">load_cert</span><span class="p">(</span><span class="s1">&#39;recipient.pem&#39;</span><span class="p">)</span>
+<span class="n">sk</span> <span class="o">=</span> <span class="n">X509</span><span class="o">.</span><span class="n">X509_Stack</span><span class="p">()</span>
+<span class="n">sk</span><span class="o">.</span><span class="n">push</span><span class="p">(</span><span class="n">x509</span><span class="p">)</span>
+<span class="n">s</span><span class="o">.</span><span class="n">set_x509_stack</span><span class="p">(</span><span class="n">sk</span><span class="p">)</span>
+
+<span class="c1"># Set cipher: 3-key triple-DES in CBC mode.</span>
+<span class="n">s</span><span class="o">.</span><span class="n">set_cipher</span><span class="p">(</span><span class="n">SMIME</span><span class="o">.</span><span class="n">Cipher</span><span class="p">(</span><span class="s1">&#39;des_ede3_cbc&#39;</span><span class="p">))</span>
+
+<span class="c1"># Create a temporary buffer.</span>
+<span class="n">tmp</span> <span class="o">=</span> <span class="n">BIO</span><span class="o">.</span><span class="n">MemoryBuffer</span><span class="p">()</span>
+
+<span class="c1"># Write the signed message into the temporary buffer.</span>
+<span class="n">s</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">tmp</span><span class="p">,</span> <span class="n">p7</span><span class="p">)</span>
+
+<span class="c1"># Encrypt the temporary buffer.</span>
+<span class="n">p7</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">encrypt</span><span class="p">(</span><span class="n">tmp</span><span class="p">)</span>
+
+<span class="c1"># Output p7 in mail-friendly format.</span>
+<span class="n">out</span> <span class="o">=</span> <span class="n">BIO</span><span class="o">.</span><span class="n">MemoryBuffer</span><span class="p">()</span>
+<span class="n">out</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;From: sender@example.dom</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">)</span>
+<span class="n">out</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;To: recipient@example.dom</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">)</span>
+<span class="n">out</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;Subject: M2Crypto S/MIME testing</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">)</span>
+<span class="n">s</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">out</span><span class="p">,</span> <span class="n">p7</span><span class="p">)</span>
+
+<span class="nb">print</span><span class="p">(</span><span class="n">out</span><span class="o">.</span><span class="n">read</span><span class="p">())</span>
+
+<span class="c1"># Save the PRNG&#39;s state.</span>
+<span class="n">Rand</span><span class="o">.</span><span class="n">save_file</span><span class="p">(</span><span class="s1">&#39;randpool.dat&#39;</span><span class="p">)</span>
+</pre></div>
+</div>
+<p>Here’s the output of the above program:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">From</span><span class="p">:</span> <span class="n">sender</span><span class="nd">@example</span><span class="o">.</span><span class="n">dom</span>
+<span class="n">To</span><span class="p">:</span> <span class="n">recipient</span><span class="nd">@example</span><span class="o">.</span><span class="n">dom</span>
+<span class="n">Subject</span><span class="p">:</span> <span class="n">M2Crypto</span> <span class="n">S</span><span class="o">/</span><span class="n">MIME</span> <span class="n">testing</span>
+<span class="n">MIME</span><span class="o">-</span><span class="n">Version</span><span class="p">:</span> <span class="mf">1.0</span>
+<span class="n">Content</span><span class="o">-</span><span class="n">Disposition</span><span class="p">:</span> <span class="n">attachment</span><span class="p">;</span> <span class="n">filename</span><span class="o">=</span><span class="s2">&quot;smime.p7m&quot;</span>
+<span class="n">Content</span><span class="o">-</span><span class="n">Type</span><span class="p">:</span> <span class="n">application</span><span class="o">/</span><span class="n">x</span><span class="o">-</span><span class="n">pkcs7</span><span class="o">-</span><span class="n">mime</span><span class="p">;</span> <span class="n">name</span><span class="o">=</span><span class="s2">&quot;smime.p7m&quot;</span>
+<span class="n">Content</span><span class="o">-</span><span class="n">Transfer</span><span class="o">-</span><span class="n">Encoding</span><span class="p">:</span> <span class="n">base64</span>
+
+<span class="n">MIIIwwYJKoZIhvcNAQcDoIIItDCCCLACAQAxggEAMIH9AgEAMGYwYTELMAkGA1UE</span>
+<span class="n">BhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRkwFwYDVQQDExBTL01JTUUgUmVjaXBp</span>
+<span class="n">ZW50MSQwIgYJKoZIhvcNAQkBFhVyZWNpcGllbnRAZXhhbXBsZS5kb20CAQAwDQYJ</span>
+<span class="n">KoZIhvcNAQEBBQAEgYBlZlGupFphwhsGtIAPvDExN61qisz3oem88xoXkUW0SzoR</span>
+<span class="n">B9zJFFAuQTWzdNJgrKKYikhWjDojaAc</span><span class="o">/</span><span class="n">PFl1K5dYxRgtZLB36ULJD</span><span class="o">/</span><span class="n">v</span><span class="o">/</span><span class="n">yWmxnjz8</span>
+<span class="n">TvtK</span><span class="o">+</span><span class="n">Wbal2P</span><span class="o">/</span><span class="n">MH2pZ4LVERXa</span><span class="o">/</span><span class="n">snTElhCawUlwtiFz</span><span class="o">/</span><span class="n">JvY5CiF</span><span class="o">/</span><span class="n">dcwd</span><span class="o">+</span><span class="n">AwFQq4jCC</span>
+<span class="n">B6UGCSqGSIb3DQEHATAUBggqhkiG9w0DBwQIRF525UfwszaAggeA85RmX6AXQMxb</span>
+<span class="n">eBDz</span><span class="o">/</span><span class="n">LJeCgc3RqU1UwIsbKMquIs1S46Ebbm5nP75izPnujOkJ2hv</span><span class="o">+</span><span class="n">LNzqOWADmOl</span>
+<span class="o">+</span><span class="n">CnGEq1qxTyduIgUDA2nBgCL</span><span class="o">/</span><span class="n">gVyVy</span><span class="o">+/</span><span class="n">XC9dtImUUTxtxLgYtB0ujkBNsOaENOlM</span>
+<span class="n">fv4SGM3jkR</span><span class="o">+</span><span class="n">K</span><span class="o">/</span><span class="n">xlYG6HHzZGbfYyNGj2Y7yMZ1rL1m8SnRNmkCysKGTrudeNf6wT9</span>
+<span class="n">J6wO9DzLTioz3ZnVr3LjsSKIb4tIp4ugqNJaLuW7m3FtZ3MAgxN68hBbJs8TZ8tL</span>
+<span class="n">V</span><span class="o">/</span><span class="mi">0</span><span class="n">jwUqS</span><span class="o">+</span><span class="n">grcgZEb9ymfcedxahtDUfHjRkpDpsxZzVVGkSBNcbQu92oByQVnRQ8m</span>
+<span class="n">wrYLp3</span><span class="o">/</span><span class="n">eawM5AvuV7HNpTT5ZR</span><span class="o">+</span><span class="mi">1</span><span class="n">t8luishHN9899IMP2Vyg0Ub67FqFypYmM2cm2</span>
+<span class="n">sjAI4KpfvT00XFNvgLuYwYEKs9syGTO7hiHNQKcF44F5LYv6nTFwmFQB11dAtY9V</span>
+<span class="n">ull4D2CLDx9OvyNyKwdEZB5dyV0r</span><span class="o">/</span><span class="n">uKIdkhST60V2Q9KegpzgFpoZtSKM</span><span class="o">/</span><span class="n">HPYSVH</span>
+<span class="mi">1</span><span class="n">Bc9f3Q</span><span class="o">/</span><span class="n">GqZCvNZZCMx8UvRjQR8dRWDSmPJ0VXG1</span><span class="o">+</span><span class="n">wJ</span><span class="o">+</span><span class="n">fCmSPP3AuQ1</span><span class="o">/</span><span class="n">VsgPRqx2</span>
+<span class="mi">56</span><span class="n">VrpGPpGut40hV8xQFbWIZ2whwWLKPFAHj8B79ZtFUzUrU6Z2rNpvv8inHc</span><span class="o">/+</span><span class="n">S</span><span class="o">/</span>
+<span class="n">b6GR5s8</span><span class="o">/</span><span class="n">gucRblvd7n3OFNX5UJmPmcw9zWbu</span><span class="o">/</span><span class="mi">1</span><span class="n">Dr9DY8l0nAQh21y5FGSS8B1wdE</span>
+<span class="n">oD2M3Lp7JbwjQbRtnDhImqul2S4yu</span><span class="o">+</span><span class="n">m</span><span class="o">+</span><span class="n">wDD1aR2K4k3GAI7KKgOBWT0</span><span class="o">+</span><span class="n">BDClcn8A</span>
+<span class="mi">4</span><span class="n">Ju6</span><span class="o">/</span><span class="n">YUbj33YlMPJgnGijLnolFy0hNW7TmWqR</span><span class="o">+</span><span class="mi">8</span><span class="n">tSI3wO5eNKg4qwBnarqc3vgCV</span>
+<span class="n">quVxINAXyGQCO9lzdw6hudk8</span><span class="o">/+</span><span class="n">BlweGdqhONaIWbK5z1L</span><span class="o">/</span><span class="n">SfQo6LC9MTsj7FJydq</span>
+<span class="n">bc</span><span class="o">+</span><span class="n">kEbfZS8aSq7uc9axW6Ti0eAPJ8EVHtwhSBgZQRweKFBXs6HbbhMIdc4N0M7Oq</span>
+<span class="n">UiFXaF6s4n2uihVP6TqXtHEjTpZoC7pC</span><span class="o">+</span><span class="n">HCYiuKXUJtaqtXBOh</span><span class="o">+</span><span class="n">y3KLvHk09YL6D</span>
+<span class="n">XmTDg</span><span class="o">+</span><span class="n">UTiFsh4jKKm</span><span class="o">/</span><span class="n">BhdelbR5JbpJcj5AId76Mfr8</span><span class="o">+</span><span class="n">F</span><span class="o">/</span><span class="mi">1</span><span class="n">g9ePOvsWHpQr</span><span class="o">/</span><span class="n">oIQTo</span>
+<span class="n">xEkaxCmzEgP0b6caMWfMUQrbVGxBBNcqKc</span><span class="o">/</span><span class="n">ir9fGGOPHATzzq</span><span class="o">/</span><span class="n">xLcQYvK1tZhd</span><span class="o">/</span><span class="n">D</span>
+<span class="n">ah</span><span class="o">/</span><span class="n">gpMPndsyvVCEuFPluWyDiM0VkwHgC2</span><span class="o">/</span><span class="mi">3</span><span class="n">pJIYFHaxK64IutmPsy393rHMEB4kN</span>
+<span class="n">AHau6kWK</span><span class="o">+</span><span class="n">yL9qEVH1pP2zvswQ12P7gjt3T</span><span class="o">/</span><span class="n">G3bGsmvlXkEfztfjkXo6XnjcBNf5y</span>
+<span class="n">G</span><span class="o">+</span><span class="mi">974</span><span class="n">AKLcjnk1gzIgarz</span><span class="o">+</span><span class="n">lAMY57Gkw4oNDMrTqVQ2OJQlvOSbllPXzH</span><span class="o">+</span><span class="n">aAiavB8W</span>
+<span class="n">ZPECLLwHxD4B1AuaiAArgKl935u</span><span class="o">/</span><span class="n">TOB</span><span class="o">+</span><span class="n">yQOR8JgGsUzROyJqHJ</span><span class="o">/</span><span class="n">SC51HkebgCkL1</span>
+<span class="n">aggtjgPlIBEXLZAlhpWLZ9lAQyrQpvCVJYwaOvfMmvRav4NAFNoZ2</span><span class="o">/</span><span class="n">Q7S4Tn1z</span><span class="o">+</span><span class="n">U</span>
+<span class="n">XX</span><span class="o">+</span><span class="n">f</span><span class="o">+</span><span class="n">GD58P4MPMhU5IKnz4yH4nlHnAiTEvcs85TZUAXze9g</span><span class="o">/</span><span class="n">uBOwZITeGtyLi52S</span>
+<span class="n">aETIr4v7SgXMepX7ThQ1Pv</span><span class="o">/</span><span class="n">jddsK</span><span class="o">/</span><span class="n">u4j2F34u0XktwCP</span><span class="o">+</span><span class="n">UrbfkE2mocdXvdzxbmd</span>
+<span class="n">tZSznK2qwgVSsPOs9MhUaepbnjmNBFFBrULhrUtSglM</span><span class="o">/</span><span class="n">VX</span><span class="o">/</span><span class="n">rWNiyh0aw4XYyHhIt</span>
+<span class="mi">9</span><span class="n">ZNlfEjKjJ67VEMBxBJ</span><span class="o">/</span><span class="n">ieUCouRGCxPYD1j65VT7oB3ZiyPu2F2nlUIcYNqPg1Sd</span>
+<span class="n">QBCrdaOXdJ0uLwyTAUeVE</span><span class="o">+</span><span class="n">wMbgscLvWsfZcCCJHAvw9NHFMUcnrdWxAYMVETNUOn</span>
+<span class="n">uryVAK7VfOldaz6z3NOSOi6nonNeHpR</span><span class="o">/</span><span class="n">sipBa4ik5xCRLT9e0S2QJgRvO9GyfAqz</span>
+<span class="mi">3</span><span class="n">DIzHtxIGePFzTiUYUTxS3i2gnMX2PEe3ChTLlYWD3jNeAKz0iOzpDphIF2xHLLQ</span>
+<span class="mi">1</span><span class="n">tCAqBmq</span><span class="o">/</span><span class="n">vUzALyDFFdFuTIqQZys4z</span><span class="o">/</span><span class="n">u4Dmyq9uXs421eN3v2hkVHvDy8uT2Ot29</span>
+<span class="n">lg4Q5YezR1EjaW</span><span class="o">//</span><span class="mi">9</span><span class="n">guL1BXbcKrTEdtxeNqtem7SpZOMTSwD2lhB8z65GrX90Cyt</span>
+<span class="n">EMmaRSGYEdf5h1afL1SmKOMskbqxe1D2jG</span><span class="o">/</span><span class="n">vsXC7XX7xO</span><span class="o">/</span><span class="n">ioy0BdiJcYN1JiMOHJ</span>
+<span class="n">EOzFol5I20YkiV6j</span><span class="o">+</span><span class="n">cenfQFwc</span><span class="o">/</span><span class="n">NkaSxEkR8AUHJSbvUmRQRl6r0nnsFpZdR1w7pv</span>
+<span class="n">wkaT</span><span class="o">+</span><span class="n">eOpZynO4mY</span><span class="o">/</span><span class="n">ZtF6MpXJsixi6L4ZYXEbS6yHf</span><span class="o">+</span><span class="n">XGFfB0okILylmwv2bf6</span><span class="o">+</span><span class="n">Mq</span>
+<span class="n">nqXlmGj3Jwq7X9</span><span class="o">/+</span><span class="mi">2</span><span class="n">BDqvfpFFX5lSmItKZAobLdssjFR6roJxOqRsGia2aZ</span><span class="o">+</span><span class="mi">0</span><span class="o">+</span><span class="n">U5</span>
+<span class="n">VhgdITtnElgtHBaeZU5rHDswgdeLVBP</span><span class="o">+</span><span class="n">rGWnKxpJ</span><span class="o">+</span><span class="n">pLtNNi25sPYRcWFL6Erd25u</span>
+<span class="n">eXiY8GEIr</span><span class="o">+</span><span class="n">u7rqBWpc9HR34sAPRs3ubbCUleT748keCbx247ImBtiDctZxcc1O86</span>
+<span class="o">+</span><span class="mi">0</span><span class="n">QjHP6HUT7FSo</span><span class="o">/</span><span class="n">FmT7a120S3Gd2jixGh06l</span><span class="o">/</span><span class="mi">9</span><span class="n">ij5Z6mJa7Rm7TTbSjup</span><span class="o">/</span><span class="n">XISnOT</span>
+<span class="n">MKWcbI1nfVOhCv3xDq2eLae</span><span class="o">+</span><span class="n">s0oVoc041ceRazqFM2TL</span><span class="o">/</span><span class="n">Z6UXRME</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="decrypt-and-verify">
+<h1>Decrypt and Verify<a class="headerlink" href="#decrypt-and-verify" title="Permalink to this headline">¶</a></h1>
+<p>Suppose the above output has been saved into <code class="docutils literal notranslate"><span class="pre">se.p7</span></code>. The following
+demonstrates how to decrypt and verify it:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">M2Crypto</span> <span class="k">import</span> <span class="n">BIO</span><span class="p">,</span> <span class="n">SMIME</span><span class="p">,</span> <span class="n">X509</span>
+
+<span class="c1"># Instantiate an SMIME object.</span>
+<span class="n">s</span> <span class="o">=</span> <span class="n">SMIME</span><span class="o">.</span><span class="n">SMIME</span><span class="p">()</span>
+
+<span class="c1"># Load private key and cert.</span>
+<span class="n">s</span><span class="o">.</span><span class="n">load_key</span><span class="p">(</span><span class="s1">&#39;recipient_key.pem&#39;</span><span class="p">,</span> <span class="s1">&#39;recipient.pem&#39;</span><span class="p">)</span>
+
+<span class="c1"># Load the signed/encrypted data.</span>
+<span class="n">p7</span><span class="p">,</span> <span class="n">data</span> <span class="o">=</span> <span class="n">SMIME</span><span class="o">.</span><span class="n">smime_load_pkcs7</span><span class="p">(</span><span class="s1">&#39;se.p7&#39;</span><span class="p">)</span>
+
+<span class="c1"># After the above step, &#39;data&#39; == None.</span>
+<span class="c1"># Decrypt p7. &#39;out&#39; now contains a PKCS #7 signed blob.</span>
+<span class="n">out</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">decrypt</span><span class="p">(</span><span class="n">p7</span><span class="p">)</span>
+
+<span class="c1"># Load the signer&#39;s cert.</span>
+<span class="n">x509</span> <span class="o">=</span> <span class="n">X509</span><span class="o">.</span><span class="n">load_cert</span><span class="p">(</span><span class="s1">&#39;signer.pem&#39;</span><span class="p">)</span>
+<span class="n">sk</span> <span class="o">=</span> <span class="n">X509</span><span class="o">.</span><span class="n">X509_Stack</span><span class="p">()</span>
+<span class="n">sk</span><span class="o">.</span><span class="n">push</span><span class="p">(</span><span class="n">x509</span><span class="p">)</span>
+<span class="n">s</span><span class="o">.</span><span class="n">set_x509_stack</span><span class="p">(</span><span class="n">sk</span><span class="p">)</span>
+
+<span class="c1"># Load the signer&#39;s CA cert. In this case, because the signer&#39;s</span>
+<span class="c1"># cert is self-signed, it is the signer&#39;s cert itself.</span>
+<span class="n">st</span> <span class="o">=</span> <span class="n">X509</span><span class="o">.</span><span class="n">X509_Store</span><span class="p">()</span>
+<span class="n">st</span><span class="o">.</span><span class="n">load_info</span><span class="p">(</span><span class="s1">&#39;signer.pem&#39;</span><span class="p">)</span>
+<span class="n">s</span><span class="o">.</span><span class="n">set_x509_store</span><span class="p">(</span><span class="n">st</span><span class="p">)</span>
+
+<span class="c1"># Recall &#39;out&#39; contains a PKCS #7 blob.</span>
+<span class="c1"># Transform &#39;out&#39;; verify the resulting PKCS #7 blob.</span>
+<span class="n">p7_bio</span> <span class="o">=</span> <span class="n">BIO</span><span class="o">.</span><span class="n">MemoryBuffer</span><span class="p">(</span><span class="n">out</span><span class="p">)</span>
+<span class="n">p7</span><span class="p">,</span> <span class="n">data</span> <span class="o">=</span> <span class="n">SMIME</span><span class="o">.</span><span class="n">smime_load_pkcs7_bio</span><span class="p">(</span><span class="n">p7_bio</span><span class="p">)</span>
+<span class="n">v</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">verify</span><span class="p">(</span><span class="n">p7</span><span class="p">)</span>
+
+<span class="nb">print</span><span class="p">(</span><span class="n">v</span><span class="p">)</span>
+</pre></div>
+</div>
+<p>The output is as follows:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">a</span> <span class="n">sign</span> <span class="n">of</span> <span class="n">our</span> <span class="n">times</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="sending-s-mime-messages-via-smtp">
+<h1>Sending S/MIME messages via SMTP<a class="headerlink" href="#sending-s-mime-messages-via-smtp" title="Permalink to this headline">¶</a></h1>
+<p>In the above examples, we’ve assumed that our S/MIME messages are sent
+and received automagically. The following is a Python function that
+generates S/MIME-signed/encrypted messages and sends them via
+SMTP:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">M2Crypto</span> <span class="k">import</span> <span class="n">BIO</span><span class="p">,</span> <span class="n">SMIME</span><span class="p">,</span> <span class="n">X509</span>
+<span class="kn">import</span> <span class="nn">smtplib</span><span class="o">,</span> <span class="nn">string</span><span class="o">,</span> <span class="nn">sys</span>
+
+<span class="k">def</span> <span class="nf">sendsmime</span><span class="p">(</span><span class="n">from_addr</span><span class="p">,</span> <span class="n">to_addrs</span><span class="p">,</span> <span class="n">subject</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="n">from_key</span><span class="p">,</span> <span class="n">from_cert</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">to_certs</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">smtpd</span><span class="o">=</span><span class="s1">&#39;localhost&#39;</span><span class="p">):</span>
+
+ <span class="n">msg_bio</span> <span class="o">=</span> <span class="n">BIO</span><span class="o">.</span><span class="n">MemoryBuffer</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
+ <span class="n">sign</span> <span class="o">=</span> <span class="n">from_key</span>
+ <span class="n">encrypt</span> <span class="o">=</span> <span class="n">to_certs</span>
+
+ <span class="n">s</span> <span class="o">=</span> <span class="n">SMIME</span><span class="o">.</span><span class="n">SMIME</span><span class="p">()</span>
+ <span class="k">if</span> <span class="n">sign</span><span class="p">:</span>
+ <span class="n">s</span><span class="o">.</span><span class="n">load_key</span><span class="p">(</span><span class="n">from_key</span><span class="p">,</span> <span class="n">from_cert</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">encrypt</span><span class="p">:</span>
+ <span class="n">p7</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">sign</span><span class="p">(</span><span class="n">msg_bio</span><span class="p">,</span> <span class="n">flags</span><span class="o">=</span><span class="n">SMIME</span><span class="o">.</span><span class="n">PKCS7_TEXT</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">p7</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">sign</span><span class="p">(</span><span class="n">msg_bio</span><span class="p">,</span> <span class="n">flags</span><span class="o">=</span><span class="n">SMIME</span><span class="o">.</span><span class="n">PKCS7_TEXT</span><span class="o">|</span><span class="n">SMIME</span><span class="o">.</span><span class="n">PKCS7_DETACHED</span><span class="p">)</span>
+ <span class="n">msg_bio</span> <span class="o">=</span> <span class="n">BIO</span><span class="o">.</span><span class="n">MemoryBuffer</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span> <span class="c1"># Recreate coz sign() has consumed it.</span>
+
+ <span class="k">if</span> <span class="n">encrypt</span><span class="p">:</span>
+ <span class="n">sk</span> <span class="o">=</span> <span class="n">X509</span><span class="o">.</span><span class="n">X509_Stack</span><span class="p">()</span>
+ <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">to_certs</span><span class="p">:</span>
+ <span class="n">sk</span><span class="o">.</span><span class="n">push</span><span class="p">(</span><span class="n">X509</span><span class="o">.</span><span class="n">load_cert</span><span class="p">(</span><span class="n">x</span><span class="p">))</span>
+ <span class="n">s</span><span class="o">.</span><span class="n">set_x509_stack</span><span class="p">(</span><span class="n">sk</span><span class="p">)</span>
+ <span class="n">s</span><span class="o">.</span><span class="n">set_cipher</span><span class="p">(</span><span class="n">SMIME</span><span class="o">.</span><span class="n">Cipher</span><span class="p">(</span><span class="s1">&#39;des_ede3_cbc&#39;</span><span class="p">))</span>
+ <span class="n">tmp_bio</span> <span class="o">=</span> <span class="n">BIO</span><span class="o">.</span><span class="n">MemoryBuffer</span><span class="p">()</span>
+ <span class="k">if</span> <span class="n">sign</span><span class="p">:</span>
+ <span class="n">s</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">tmp_bio</span><span class="p">,</span> <span class="n">p7</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">tmp_bio</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
+ <span class="n">p7</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">encrypt</span><span class="p">(</span><span class="n">tmp_bio</span><span class="p">)</span>
+
+ <span class="n">out</span> <span class="o">=</span> <span class="n">BIO</span><span class="o">.</span><span class="n">MemoryBuffer</span><span class="p">()</span>
+ <span class="n">out</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;From: </span><span class="si">%s</span><span class="se">\r\n</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">from_addr</span><span class="p">)</span>
+ <span class="n">out</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;To: </span><span class="si">%s</span><span class="se">\r\n</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">string</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">to_addrs</span><span class="p">,</span> <span class="s2">&quot;, &quot;</span><span class="p">))</span>
+ <span class="n">out</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;Subject: </span><span class="si">%s</span><span class="se">\r\n</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">subject</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">encrypt</span><span class="p">:</span>
+ <span class="n">s</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">out</span><span class="p">,</span> <span class="n">p7</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="k">if</span> <span class="n">sign</span><span class="p">:</span>
+ <span class="n">s</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">out</span><span class="p">,</span> <span class="n">p7</span><span class="p">,</span> <span class="n">msg_bio</span><span class="p">,</span> <span class="n">SMIME</span><span class="o">.</span><span class="n">PKCS7_TEXT</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">out</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;</span><span class="se">\r\n</span><span class="s1">&#39;</span><span class="p">)</span>
+ <span class="n">out</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
+ <span class="n">out</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
+
+ <span class="n">smtp</span> <span class="o">=</span> <span class="n">smtplib</span><span class="o">.</span><span class="n">SMTP</span><span class="p">()</span>
+ <span class="n">smtp</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">smtpd</span><span class="p">)</span>
+ <span class="n">smtp</span><span class="o">.</span><span class="n">sendmail</span><span class="p">(</span><span class="n">from_addr</span><span class="p">,</span> <span class="n">to_addrs</span><span class="p">,</span> <span class="n">out</span><span class="o">.</span><span class="n">read</span><span class="p">())</span>
+ <span class="n">smtp</span><span class="o">.</span><span class="n">quit</span><span class="p">()</span>
+</pre></div>
+</div>
+<p>This function sends plain, S/MIME-signed, S/MIME-encrypted, and
+S/MIME-signed/encrypted messages, depending on the parameters
+<code class="docutils literal notranslate"><span class="pre">from_key</span></code> and <code class="docutils literal notranslate"><span class="pre">to_certs</span></code>. The function’s output interoperates with
+Netscape Messenger.</p>
+</div>
+<div class="section" id="verifying-origin-of-s-mime-messages">
+<h1>Verifying origin of S/MIME messages<a class="headerlink" href="#verifying-origin-of-s-mime-messages" title="Permalink to this headline">¶</a></h1>
+<p>In our examples above that decrypt or verify messages, we skipped a
+step: verifying that the <code class="docutils literal notranslate"><span class="pre">from</span></code> address of the message matches the
+<code class="docutils literal notranslate"><span class="pre">email</span> <span class="pre">address</span></code> attribute in the sender’s certificate.</p>
+<p>The premise of current X.509 certification practice is that the CA is
+supposed to verify your identity, and to issue a certificate with
+<code class="docutils literal notranslate"><span class="pre">email</span> <span class="pre">address</span></code> that matches your actual mail address. (Verisign’s
+March 2001 failure in identity verification resulting in Microsoft
+certificates being issued to spoofers notwithstanding.)</p>
+<p>If you run your own CA, your certification practice is up to you, of
+course, and it would probably be part of your security policy.</p>
+<p>Whether your S/MIME messaging application needs to verify the <code class="docutils literal notranslate"><span class="pre">from</span></code>
+addresses of S/MIME messages depends on your security policy and your
+system’s threat model, as always.</p>
+</div>
+<div class="section" id="interoperating-with-netscape-messenger">
+<h1>Interoperating with Netscape Messenger<a class="headerlink" href="#interoperating-with-netscape-messenger" title="Permalink to this headline">¶</a></h1>
+<p>Suppose S/MIME Recipient uses Netscape Messenger. To enable Messenger to
+handle S/MIME messages from S/MIME Sender, S/MIME Recipient needs to
+configure Messenger with his private key and certificate, as well as
+S/MIME Sender’s certificate.</p>
+<blockquote>
+<div><strong>Note:</strong> Configuring Messenger’s POP or IMAP settings so that it
+retrieves mail correctly is beyond the scope of this HOWTO.</div></blockquote>
+<p>The following steps demonstrate how to import S/MIME Recipient’s private
+key and certificate for Messenger:</p>
+<ol class="arabic">
+<li><p class="first">Transform S/MIME Recipient’s private key and certificate into <em>PKCS
+#12</em> format:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">openssl</span> <span class="n">pkcs12</span> <span class="o">-</span><span class="n">export</span> <span class="o">-</span><span class="ow">in</span> <span class="n">recipient</span><span class="o">.</span><span class="n">pem</span> <span class="o">-</span><span class="n">inkey</span> <span class="n">recipient_key</span><span class="o">.</span><span class="n">pem</span> \
+ <span class="o">-</span><span class="n">name</span> <span class="s2">&quot;S/MIME Recipient&quot;</span> <span class="o">-</span><span class="n">out</span> <span class="n">recipient</span><span class="o">.</span><span class="n">p12</span>
+
+<span class="n">Enter</span> <span class="n">Export</span> <span class="n">Password</span><span class="p">:</span><span class="o">&lt;</span><span class="n">enter</span><span class="o">&gt;</span>
+<span class="n">Verifying</span> <span class="n">password</span> <span class="o">-</span> <span class="n">Enter</span> <span class="n">Export</span> <span class="n">Password</span><span class="p">:</span><span class="o">&lt;</span><span class="n">enter</span><span class="o">&gt;</span>
+</pre></div>
+</div>
+</li>
+<li><p class="first">Start Messenger.</p>
+</li>
+<li><p class="first">Click on the (open) “lock†icon at the bottom left corner of
+Messenger’s window. This brings up the “Security Info†dialog box.</p>
+</li>
+<li><p class="first">Click on “Yours†under “Certificatesâ€.</p>
+</li>
+<li><p class="first">Select “Import a certificateâ€, then pick <code class="docutils literal notranslate"><span class="pre">recipient.p12</span></code> from the
+ensuing file selection dialog box.</p>
+</li>
+</ol>
+<p>Next, you need to import <code class="docutils literal notranslate"><span class="pre">signer.pem</span></code> as a CA certificate, so that
+Messenger will mark messages signed by S/MIME Sender as “trustedâ€:</p>
+<ol class="arabic">
+<li><p class="first">Create a DER encoding of <code class="docutils literal notranslate"><span class="pre">signer.pem</span></code>:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">openssl</span> <span class="n">x509</span> <span class="o">-</span><span class="n">inform</span> <span class="n">pem</span> <span class="o">-</span><span class="n">outform</span> <span class="n">der</span> <span class="o">-</span><span class="ow">in</span> <span class="n">signer</span><span class="o">.</span><span class="n">pem</span> <span class="o">-</span><span class="n">out</span> <span class="n">signer</span><span class="o">.</span><span class="n">der</span>
+</pre></div>
+</div>
+</li>
+<li><p class="first">Install <code class="docutils literal notranslate"><span class="pre">signer.der</span></code> into Messenger as MIME type
+<code class="docutils literal notranslate"><span class="pre">application/x-x509-ca-cert</span></code>. You do this by downloading
+<code class="docutils literal notranslate"><span class="pre">signer.der</span></code> via Navigator from a HTTP or HTTPS server, with the
+correct MIME type mapping. (You may use <code class="docutils literal notranslate"><span class="pre">demo/ssl/https_srv.py</span></code>,
+bundled with M2Crypto, for this purpose.) Follow the series of dialog
+boxes to accept <code class="docutils literal notranslate"><span class="pre">signer.der</span></code> as a CA for certifying email users.</p>
+</li>
+</ol>
+<p>S/MIME Recipient is now able to decrypt and read S/MIME Sender’s
+messages with Messenger. Messenger will indicate that S/MIME Sender’s
+messages are signed, encrypted, or encrypted <em>and</em> signed, as the case
+may be, via the “stamp†icon on the message window’s top right corner.</p>
+<p>Clicking on the “stamp†icon brings you to the Security Info dialog box.
+Messenger informs you that the message is, say, encrypted with 168-bit
+DES-EDE3-CBC and that it is digitally signed by the private key
+corresponding to the public key contained in the certificate
+<code class="docutils literal notranslate"><span class="pre">signer.pem</span></code>.</p>
+</div>
+<div class="section" id="interoperating-with-microsoft-outlook">
+<h1>Interoperating with Microsoft Outlook<a class="headerlink" href="#interoperating-with-microsoft-outlook" title="Permalink to this headline">¶</a></h1>
+<p>I do not know how to do this, as I do not use Outlook. (Nor do I use
+Netscape Messenger, actually. I use Mutt, top dog of MUAs. ;-)
+Information on how to configure Outlook with keys and certificates so
+that it handles S/MIME mail is gratefully accepted.</p>
+</div>
+<div class="section" id="zsmime">
+<h1>ZSmime<a class="headerlink" href="#zsmime" title="Permalink to this headline">¶</a></h1>
+<p>ZSmime is a <a class="reference external" href="http://www.zope.org">Zope</a> <em>product</em> that enables Zope
+to generate S/MIME-signed/encrypted messages. ZSmime demonstrates how to
+invoke M2Crypto in a web application server extension.</p>
+<p>ZSmime has its own
+<a class="reference external" href="http://sandbox.rulemaker.net/ngps/zope/zsmime/howto.html">HOWTO</a>
+explaining its usage. (That HOWTO has some overlap in content with this
+document.)</p>
+</div>
+<div class="section" id="resources">
+<h1>Resources<a class="headerlink" href="#resources" title="Permalink to this headline">¶</a></h1>
+<ul class="simple">
+<li>IETF S/MIME Working Group - <a class="reference external" href="http://www.imc.org/ietf-smime">http://www.imc.org/ietf-smime</a></li>
+<li>S/MIME and OpenPGP - <a class="reference external" href="http://www.imc.org/smime-pgpmime.html">http://www.imc.org/smime-pgpmime.html</a></li>
+<li>S/MIME Freeware Library -
+<a class="reference external" href="http://www.getronicsgov.com/hot/sfl_home.htm">http://www.getronicsgov.com/hot/sfl_home.htm</a></li>
+<li>Mozilla Network Security Services -
+<a class="reference external" href="http://www.mozilla.org/projects/security/pkg/nss">http://www.mozilla.org/projects/security/pkg/nss</a></li>
+<li>S/MIME Cracking Screen Saver - <a class="reference external" href="http://www.counterpane.com/smime.html">http://www.counterpane.com/smime.html</a></li>
+</ul>
+</div>
+
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="index.html">M2Crypto</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="M2Crypto.html">M2Crypto Package</a></li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="index.html">Documentation overview</a><ul>
+ </ul></li>
+</ul>
+</div>
+<div id="searchbox" style="display: none" role="search">
+ <h3>Quick search</h3>
+ <div class="searchformwrapper">
+ <form class="search" action="search.html" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ </div>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer">
+ &copy;2017, Matej Cepl <mcepl@cepl.eu>.
+
+ |
+ Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
+ &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
+
+ |
+ <a href="_sources/howto.smime.rst.txt"
+ rel="nofollow">Page source</a>
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/howto.ssl.html b/doc/html/howto.ssl.html
new file mode 100644
index 0000000..759cb85
--- /dev/null
+++ b/doc/html/howto.ssl.html
@@ -0,0 +1,219 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>HOWTO: Programming SSL in Python with M2Crypto &#8212; M2Crypto documentation</title>
+ <link rel="stylesheet" href="_static/alabaster.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <script type="text/javascript" src="_static/language_data.js"></script>
+ <link rel="index" title="Index" href="genindex.html" />
+ <link rel="search" title="Search" href="search.html" />
+
+ <link rel="stylesheet" href="_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+ <div class="section" id="howto-programming-ssl-in-python-with-m2crypto">
+<span id="howto-ssl"></span><h1>HOWTO: Programming SSL in Python with M2Crypto<a class="headerlink" href="#howto-programming-ssl-in-python-with-m2crypto" title="Permalink to this headline">¶</a></h1>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">author:</th><td class="field-body">Pheng Siong Ng &lt;<a class="reference external" href="mailto:ngps&#37;&#52;&#48;netmemetic&#46;com">ngps<span>&#64;</span>netmemetic<span>&#46;</span>com</a>&gt; and Heikki Toivonen (<a class="reference external" href="mailto:heikki&#37;&#52;&#48;osafoundation&#46;org">heikki<span>&#64;</span>osafoundation<span>&#46;</span>org</a>)</td>
+</tr>
+<tr class="field-even field"><th class="field-name">copyright:</th><td class="field-body">© 2000, 2001 by Ng Pheng Siong,
+portions © 2006 by Open Source Applications Foundation</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="introduction">
+<h1>Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline">¶</a></h1>
+<p><a class="reference external" href="https://gitlab.com/m2crypto/m2crypto/">M2Crypto</a> is a
+<a class="reference external" href="http://www.python.org">Python</a> interface to
+<a class="reference external" href="http://www.openssl.org">OpenSSL</a>. It makes available to the Python
+programmer SSL functionality to implement clients and servers, S/MIME
+v2, RSA, DSA, DH, symmetric ciphers, message digests and HMACs.</p>
+<p>This document demonstrates programming HTTPS with M2Crypto.</p>
+</div>
+<div class="section" id="a-bit-of-history">
+<h1>A bit of history<a class="headerlink" href="#a-bit-of-history" title="Permalink to this headline">¶</a></h1>
+<p>M2Crypto was created during the time of Python 1.5, which features a
+module httplib providing client-side HTTP functionality. M2Crypto sports
+a httpslib based on httplib.</p>
+<p>Beginning with version 2.0, Python’s socket module provided
+(rudimentary) SSL support. Also in the same version, httplib was
+enhanced with class HTTPConnection, which is more sophisticated than the
+old class HTTP, and HTTPSConnection, which does HTTPS.</p>
+<p>Subsequently, M2Crypto.httpslib grew a compatible (but not identical)
+class HTTPSConnection.</p>
+<p>The primary interface difference between the two HTTPSConnection classes
+is that M2Crypto’s version accepts an M2Crypto.SSL.Context instance as a
+parameter, whereas Python 2.x’s SSL support does not permit Pythonic
+control of the SSL context.</p>
+<p>Within the implementations, Python’s <code class="docutils literal notranslate"><span class="pre">HTTPSConnection</span></code> employs a
+<code class="docutils literal notranslate"><span class="pre">FakeSocket</span></code> object, which collects all input from the SSL connection
+before returning it to the application as a <code class="docutils literal notranslate"><span class="pre">StringIO</span></code> buffer, whereas
+M2Crypto’s <code class="docutils literal notranslate"><span class="pre">HTTPSConnection</span></code> uses a buffering
+<code class="docutils literal notranslate"><span class="pre">M2Crypto.BIO.IOBuffer</span></code> object that works over the underlying
+M2Crypto.SSL.Connection directly.</p>
+<p>Since then M2Crypto has gained a Twisted wrapper that allows securing
+Twisted SSL connections with M2Crypto.</p>
+</div>
+<div class="section" id="secure-ssl">
+<h1>Secure SSL<a class="headerlink" href="#secure-ssl" title="Permalink to this headline">¶</a></h1>
+<p>It is recommended that you read the book Network Security with OpenSSL
+by John Viega, Matt Messier and Pravir Chandra, ISBN 059600270X.</p>
+<p>Using M2Crypto does not automatically make an SSL connection secure.
+There are various steps that need to be made before we can make that
+claim. Let’s see how a simple client can establish a secure
+connection:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">ctx</span> <span class="o">=</span> <span class="n">SSL</span><span class="o">.</span><span class="n">Context</span><span class="p">()</span>
+<span class="n">ctx</span><span class="o">.</span><span class="n">set_verify</span><span class="p">(</span><span class="n">SSL</span><span class="o">.</span><span class="n">verify_peer</span> <span class="o">|</span> <span class="n">SSL</span><span class="o">.</span><span class="n">verify_fail_if_no_peer_cert</span><span class="p">,</span> <span class="n">depth</span><span class="o">=</span><span class="mi">9</span><span class="p">)</span>
+<span class="k">if</span> <span class="n">ctx</span><span class="o">.</span><span class="n">load_verify_locations</span><span class="p">(</span><span class="s1">&#39;ca.pem&#39;</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">1</span><span class="p">:</span> <span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s1">&#39;No CA certs&#39;</span><span class="p">)</span>
+<span class="n">s</span> <span class="o">=</span> <span class="n">SSL</span><span class="o">.</span><span class="n">Connection</span><span class="p">(</span><span class="n">ctx</span><span class="p">)</span>
+<span class="n">s</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">server_address</span><span class="p">)</span>
+<span class="c1"># Normal protocol (for example HTTP) commands follow</span>
+</pre></div>
+</div>
+<p>The first line creates an SSL context. The defaults allow any SSL
+version (except SSL version 2 which has known weaknesses) and sets the
+allowed ciphers to secure ones.</p>
+<p>The second line tells M2Crypto to perform certificate validation. The
+flags shown above are typical for clients, and requires the server to
+send a certificate. The depth parameter tells how long certificate
+chains are allowed - 9 is pretty common default, although probably too
+long in practice.</p>
+<p>The third line loads the allowed root (certificate authority or CA)
+certificates. Most Linux distributions come with CA certificates in
+suitable format. You could also download the
+<a class="reference external" href="http://mxr.mozilla.org/seamonkey/source//security/nss/lib/ckfw/builtins/certdata.txt?raw=1">certdata.txt</a>
+file from the
+<a class="reference external" href="http://www.mozilla.org/projects/security/pki/nss/">NSS</a> project and
+convert it with the little M2Crypto utility script
+<a class="reference external" href="http://svn.osafoundation.org/m2crypto/trunk/demo/x509/certdata2pem.py">demo/x509/certdata2pem.py</a>.</p>
+<p>The fourth line creates an SSL connection object with the secure
+context.</p>
+<p>The fifth line connects to the server. During this time we perform the
+last security step: just after connection, but before exchanging any
+data, we compare the commonName (or subjectAltName DNS field) field in
+the certificate the server returned to the server address we tried to
+connect to. This happens automatically with SSL.Connection and the
+Twisted wrapper class, and anything that uses those. In all other cases
+you must do the check manually. It is recommended you call the
+SSL.Checker to do the actual check.</p>
+<p>SSL servers are different in that they typically do not require the
+client to send a certificate, so there is usually no certificate
+checking. Also, it is typically useless to perform host name checking.</p>
+</div>
+<div class="section" id="code-samples">
+<h1>Code Samples<a class="headerlink" href="#code-samples" title="Permalink to this headline">¶</a></h1>
+<p>The best samples of how to use the various SSL objects are in the tests
+directory, and the test_ssl.py file specifically. There are additional
+samples in the demo directory, but they are not quaranteed to be up to
+date.</p>
+<p>NOTE: The tests and demos may not be secure as is. Use the information
+above on how to make them secure.</p>
+</div>
+<div class="section" id="ssldump">
+<h1>ssldump<a class="headerlink" href="#ssldump" title="Permalink to this headline">¶</a></h1>
+<p>ssldump “is an SSLv3/TLS network protocol analyser. It identifies TCP
+connections on the chosen network interface and attempts to interpret
+them as SSLv3/TLS traffic. When it identifies SSLv3/TLS traffic, it
+decodes the records and displays them in a textual form to stdout. If
+provided with the appropriate keying material, it will also decrypt the
+connections and display the application data traffic.</p>
+<p>If linked with OpenSSL, ssldump can display certificates in decoded form
+and decrypt traffic (provided that it has the appropriate keying
+material).â€</p>
+<p>ssldump is written by Eric Rescorla.</p>
+</div>
+
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="index.html">M2Crypto</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="M2Crypto.html">M2Crypto Package</a></li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="index.html">Documentation overview</a><ul>
+ </ul></li>
+</ul>
+</div>
+<div id="searchbox" style="display: none" role="search">
+ <h3>Quick search</h3>
+ <div class="searchformwrapper">
+ <form class="search" action="search.html" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ </div>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer">
+ &copy;2017, Matej Cepl <mcepl@cepl.eu>.
+
+ |
+ Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
+ &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
+
+ |
+ <a href="_sources/howto.ssl.rst.txt"
+ rel="nofollow">Page source</a>
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/index.html b/doc/html/index.html
new file mode 100644
index 0000000..6116ded
--- /dev/null
+++ b/doc/html/index.html
@@ -0,0 +1,177 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>Welcome to M2Crypto’s documentation! &#8212; M2Crypto documentation</title>
+ <link rel="stylesheet" href="_static/alabaster.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <script type="text/javascript" src="_static/language_data.js"></script>
+ <link rel="index" title="Index" href="genindex.html" />
+ <link rel="search" title="Search" href="search.html" />
+ <link rel="next" title="M2Crypto Package" href="M2Crypto.html" />
+
+ <link rel="stylesheet" href="_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+ <div class="section" id="welcome-to-m2crypto-s-documentation">
+<h1>Welcome to M2Crypto’s documentation!<a class="headerlink" href="#welcome-to-m2crypto-s-documentation" title="Permalink to this headline">¶</a></h1>
+<p>Contents:</p>
+<div class="toctree-wrapper compound">
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="M2Crypto.html">M2Crypto Package</a><ul>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#id1"><code class="docutils literal notranslate"><span class="pre">M2Crypto</span></code> Package</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.ASN1"><code class="docutils literal notranslate"><span class="pre">ASN1</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.AuthCookie"><code class="docutils literal notranslate"><span class="pre">AuthCookie</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.BIO"><code class="docutils literal notranslate"><span class="pre">BIO</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.BN"><code class="docutils literal notranslate"><span class="pre">BN</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.DH"><code class="docutils literal notranslate"><span class="pre">DH</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.DSA"><code class="docutils literal notranslate"><span class="pre">DSA</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.EC"><code class="docutils literal notranslate"><span class="pre">EC</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.EVP"><code class="docutils literal notranslate"><span class="pre">EVP</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.Engine"><code class="docutils literal notranslate"><span class="pre">Engine</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.Err"><code class="docutils literal notranslate"><span class="pre">Err</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.RC4"><code class="docutils literal notranslate"><span class="pre">RC4</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.RSA"><code class="docutils literal notranslate"><span class="pre">RSA</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.Rand"><code class="docutils literal notranslate"><span class="pre">Rand</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.SMIME"><code class="docutils literal notranslate"><span class="pre">SMIME</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.X509"><code class="docutils literal notranslate"><span class="pre">X509</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.callback"><code class="docutils literal notranslate"><span class="pre">callback</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.ftpslib"><code class="docutils literal notranslate"><span class="pre">ftpslib</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.httpslib"><code class="docutils literal notranslate"><span class="pre">httpslib</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.m2"><code class="docutils literal notranslate"><span class="pre">m2</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.m2crypto"><code class="docutils literal notranslate"><span class="pre">m2crypto</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.m2urllib"><code class="docutils literal notranslate"><span class="pre">m2urllib</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.m2urllib2"><code class="docutils literal notranslate"><span class="pre">m2urllib2</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.m2xmlrpclib"><code class="docutils literal notranslate"><span class="pre">m2xmlrpclib</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.threading"><code class="docutils literal notranslate"><span class="pre">threading</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#module-M2Crypto.util"><code class="docutils literal notranslate"><span class="pre">util</span></code> Module</a></li>
+<li class="toctree-l2"><a class="reference internal" href="M2Crypto.html#subpackages">Subpackages</a><ul>
+<li class="toctree-l3"><a class="reference internal" href="M2Crypto.SSL.html">SSL Package</a><ul>
+<li class="toctree-l4"><a class="reference internal" href="M2Crypto.SSL.html#id1"><code class="docutils literal notranslate"><span class="pre">SSL</span></code> Package</a></li>
+<li class="toctree-l4"><a class="reference internal" href="M2Crypto.SSL.html#module-M2Crypto.SSL.Checker"><code class="docutils literal notranslate"><span class="pre">Checker</span></code> Module</a></li>
+<li class="toctree-l4"><a class="reference internal" href="M2Crypto.SSL.html#module-M2Crypto.SSL.Cipher"><code class="docutils literal notranslate"><span class="pre">Cipher</span></code> Module</a></li>
+<li class="toctree-l4"><a class="reference internal" href="M2Crypto.SSL.html#module-M2Crypto.SSL.Connection"><code class="docutils literal notranslate"><span class="pre">Connection</span></code> Module</a></li>
+<li class="toctree-l4"><a class="reference internal" href="M2Crypto.SSL.html#module-M2Crypto.SSL.Context"><code class="docutils literal notranslate"><span class="pre">Context</span></code> Module</a></li>
+<li class="toctree-l4"><a class="reference internal" href="M2Crypto.SSL.html#module-M2Crypto.SSL.SSLServer"><code class="docutils literal notranslate"><span class="pre">SSLServer</span></code> Module</a></li>
+<li class="toctree-l4"><a class="reference internal" href="M2Crypto.SSL.html#module-M2Crypto.SSL.Session"><code class="docutils literal notranslate"><span class="pre">Session</span></code> Module</a></li>
+<li class="toctree-l4"><a class="reference internal" href="M2Crypto.SSL.html#module-M2Crypto.SSL.TwistedProtocolWrapper"><code class="docutils literal notranslate"><span class="pre">TwistedProtocolWrapper</span></code> Module</a></li>
+<li class="toctree-l4"><a class="reference internal" href="M2Crypto.SSL.html#module-M2Crypto.SSL.cb"><code class="docutils literal notranslate"><span class="pre">cb</span></code> Module</a></li>
+<li class="toctree-l4"><a class="reference internal" href="M2Crypto.SSL.html#module-M2Crypto.SSL.ssl_dispatcher"><code class="docutils literal notranslate"><span class="pre">ssl_dispatcher</span></code> Module</a></li>
+<li class="toctree-l4"><a class="reference internal" href="M2Crypto.SSL.html#module-M2Crypto.SSL.timeout"><code class="docutils literal notranslate"><span class="pre">timeout</span></code> Module</a></li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+</div>
+<div class="section" id="howtos">
+<h1>HOWTOs<a class="headerlink" href="#howtos" title="Permalink to this headline">¶</a></h1>
+<ul class="simple">
+<li><a class="reference internal" href="howto.ca.html#howto-ca"><span class="std std-ref">HOWTO: Creating your own CA with OpenSSL</span></a></li>
+<li><a class="reference internal" href="howto.ssl.html#howto-ssl"><span class="std std-ref">HOWTO: Programming SSL in Python with M2Crypto</span></a></li>
+<li><a class="reference internal" href="howto.smime.html#howto-smime"><span class="std std-ref">HOWTO: Programming S/MIME in Python with M2Crypto</span></a></li>
+<li><a class="reference internal" href="ZServerSSL-HOWTO.html#zserverssl-howto"><span class="std std-ref">1.&nbsp;&nbsp;&nbsp;ZServerSSL-HOWTO</span></a></li>
+</ul>
+</div>
+<div class="section" id="indices-and-tables">
+<h1>Indices and tables<a class="headerlink" href="#indices-and-tables" title="Permalink to this headline">¶</a></h1>
+<ul class="simple">
+<li><a class="reference internal" href="genindex.html"><span class="std std-ref">Index</span></a></li>
+<li><a class="reference internal" href="py-modindex.html"><span class="std std-ref">Module Index</span></a></li>
+<li><a class="reference internal" href="search.html"><span class="std std-ref">Search Page</span></a></li>
+</ul>
+</div>
+
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="#">M2Crypto</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="M2Crypto.html">M2Crypto Package</a></li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="#">Documentation overview</a><ul>
+ <li>Next: <a href="M2Crypto.html" title="next chapter">M2Crypto Package</a></li>
+ </ul></li>
+</ul>
+</div>
+<div id="searchbox" style="display: none" role="search">
+ <h3>Quick search</h3>
+ <div class="searchformwrapper">
+ <form class="search" action="search.html" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ </div>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer">
+ &copy;2017, Matej Cepl <mcepl@cepl.eu>.
+
+ |
+ Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
+ &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
+
+ |
+ <a href="_sources/index.rst.txt"
+ rel="nofollow">Page source</a>
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/objects.inv b/doc/html/objects.inv
new file mode 100644
index 0000000..8955897
--- /dev/null
+++ b/doc/html/objects.inv
Binary files differ
diff --git a/doc/html/py-modindex.html b/doc/html/py-modindex.html
new file mode 100644
index 0000000..628e2c5
--- /dev/null
+++ b/doc/html/py-modindex.html
@@ -0,0 +1,307 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>Python Module Index &#8212; M2Crypto documentation</title>
+ <link rel="stylesheet" href="_static/alabaster.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <script type="text/javascript" src="_static/language_data.js"></script>
+ <link rel="index" title="Index" href="genindex.html" />
+ <link rel="search" title="Search" href="search.html" />
+
+
+ <link rel="stylesheet" href="_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+
+ <h1>Python Module Index</h1>
+
+ <div class="modindex-jumpbox">
+ <a href="#cap-m"><strong>m</strong></a>
+ </div>
+
+ <table class="indextable modindextable">
+ <tr class="pcap"><td></td><td>&#160;</td><td></td></tr>
+ <tr class="cap" id="cap-m"><td></td><td>
+ <strong>m</strong></td><td></td></tr>
+ <tr>
+ <td><img src="_static/minus.png" class="toggler"
+ id="toggle-1" style="display: none" alt="-" /></td>
+ <td>
+ <code class="xref">M2Crypto</code></td><td>
+ <em></em></td></tr>
+ <tr class="cg-1">
+ <td></td>
+ <td>&#160;&#160;&#160;
+ <a href="M2Crypto.html#module-M2Crypto.__init__"><code class="xref">M2Crypto.__init__</code></a></td><td>
+ <em></em></td></tr>
+ <tr class="cg-1">
+ <td></td>
+ <td>&#160;&#160;&#160;
+ <a href="M2Crypto.html#module-M2Crypto.ASN1"><code class="xref">M2Crypto.ASN1</code></a></td><td>
+ <em></em></td></tr>
+ <tr class="cg-1">
+ <td></td>
+ <td>&#160;&#160;&#160;
+ <a href="M2Crypto.html#module-M2Crypto.AuthCookie"><code class="xref">M2Crypto.AuthCookie</code></a></td><td>
+ <em></em></td></tr>
+ <tr class="cg-1">
+ <td></td>
+ <td>&#160;&#160;&#160;
+ <a href="M2Crypto.html#module-M2Crypto.BIO"><code class="xref">M2Crypto.BIO</code></a></td><td>
+ <em></em></td></tr>
+ <tr class="cg-1">
+ <td></td>
+ <td>&#160;&#160;&#160;
+ <a href="M2Crypto.html#module-M2Crypto.BN"><code class="xref">M2Crypto.BN</code></a></td><td>
+ <em></em></td></tr>
+ <tr class="cg-1">
+ <td></td>
+ <td>&#160;&#160;&#160;
+ <a href="M2Crypto.html#module-M2Crypto.callback"><code class="xref">M2Crypto.callback</code></a></td><td>
+ <em></em></td></tr>
+ <tr class="cg-1">
+ <td></td>
+ <td>&#160;&#160;&#160;
+ <a href="M2Crypto.html#module-M2Crypto.DH"><code class="xref">M2Crypto.DH</code></a></td><td>
+ <em></em></td></tr>
+ <tr class="cg-1">
+ <td></td>
+ <td>&#160;&#160;&#160;
+ <a href="M2Crypto.html#module-M2Crypto.DSA"><code class="xref">M2Crypto.DSA</code></a></td><td>
+ <em></em></td></tr>
+ <tr class="cg-1">
+ <td></td>
+ <td>&#160;&#160;&#160;
+ <a href="M2Crypto.html#module-M2Crypto.EC"><code class="xref">M2Crypto.EC</code></a></td><td>
+ <em></em></td></tr>
+ <tr class="cg-1">
+ <td></td>
+ <td>&#160;&#160;&#160;
+ <a href="M2Crypto.html#module-M2Crypto.Engine"><code class="xref">M2Crypto.Engine</code></a></td><td>
+ <em></em></td></tr>
+ <tr class="cg-1">
+ <td></td>
+ <td>&#160;&#160;&#160;
+ <a href="M2Crypto.html#module-M2Crypto.Err"><code class="xref">M2Crypto.Err</code></a></td><td>
+ <em></em></td></tr>
+ <tr class="cg-1">
+ <td></td>
+ <td>&#160;&#160;&#160;
+ <a href="M2Crypto.html#module-M2Crypto.EVP"><code class="xref">M2Crypto.EVP</code></a></td><td>
+ <em></em></td></tr>
+ <tr class="cg-1">
+ <td></td>
+ <td>&#160;&#160;&#160;
+ <a href="M2Crypto.html#module-M2Crypto.ftpslib"><code class="xref">M2Crypto.ftpslib</code></a></td><td>
+ <em></em></td></tr>
+ <tr class="cg-1">
+ <td></td>
+ <td>&#160;&#160;&#160;
+ <a href="M2Crypto.html#module-M2Crypto.httpslib"><code class="xref">M2Crypto.httpslib</code></a></td><td>
+ <em></em></td></tr>
+ <tr class="cg-1">
+ <td></td>
+ <td>&#160;&#160;&#160;
+ <a href="M2Crypto.html#module-M2Crypto.m2"><code class="xref">M2Crypto.m2</code></a></td><td>
+ <em></em></td></tr>
+ <tr class="cg-1">
+ <td></td>
+ <td>&#160;&#160;&#160;
+ <a href="M2Crypto.html#module-M2Crypto.m2crypto"><code class="xref">M2Crypto.m2crypto</code></a></td><td>
+ <em></em></td></tr>
+ <tr class="cg-1">
+ <td></td>
+ <td>&#160;&#160;&#160;
+ <a href="M2Crypto.html#module-M2Crypto.m2urllib"><code class="xref">M2Crypto.m2urllib</code></a></td><td>
+ <em></em></td></tr>
+ <tr class="cg-1">
+ <td></td>
+ <td>&#160;&#160;&#160;
+ <a href="M2Crypto.html#module-M2Crypto.m2urllib2"><code class="xref">M2Crypto.m2urllib2</code></a></td><td>
+ <em></em></td></tr>
+ <tr class="cg-1">
+ <td></td>
+ <td>&#160;&#160;&#160;
+ <a href="M2Crypto.html#module-M2Crypto.m2xmlrpclib"><code class="xref">M2Crypto.m2xmlrpclib</code></a></td><td>
+ <em></em></td></tr>
+ <tr class="cg-1">
+ <td></td>
+ <td>&#160;&#160;&#160;
+ <a href="M2Crypto.html#module-M2Crypto.Rand"><code class="xref">M2Crypto.Rand</code></a></td><td>
+ <em></em></td></tr>
+ <tr class="cg-1">
+ <td></td>
+ <td>&#160;&#160;&#160;
+ <a href="M2Crypto.html#module-M2Crypto.RC4"><code class="xref">M2Crypto.RC4</code></a></td><td>
+ <em></em></td></tr>
+ <tr class="cg-1">
+ <td></td>
+ <td>&#160;&#160;&#160;
+ <a href="M2Crypto.html#module-M2Crypto.RSA"><code class="xref">M2Crypto.RSA</code></a></td><td>
+ <em></em></td></tr>
+ <tr class="cg-1">
+ <td></td>
+ <td>&#160;&#160;&#160;
+ <a href="M2Crypto.html#module-M2Crypto.SMIME"><code class="xref">M2Crypto.SMIME</code></a></td><td>
+ <em></em></td></tr>
+ <tr class="cg-1">
+ <td></td>
+ <td>&#160;&#160;&#160;
+ <a href="M2Crypto.SSL.html#module-M2Crypto.SSL"><code class="xref">M2Crypto.SSL</code></a></td><td>
+ <em></em></td></tr>
+ <tr class="cg-1">
+ <td></td>
+ <td>&#160;&#160;&#160;
+ <a href="M2Crypto.SSL.html#module-M2Crypto.SSL.cb"><code class="xref">M2Crypto.SSL.cb</code></a></td><td>
+ <em></em></td></tr>
+ <tr class="cg-1">
+ <td></td>
+ <td>&#160;&#160;&#160;
+ <a href="M2Crypto.SSL.html#module-M2Crypto.SSL.Checker"><code class="xref">M2Crypto.SSL.Checker</code></a></td><td>
+ <em></em></td></tr>
+ <tr class="cg-1">
+ <td></td>
+ <td>&#160;&#160;&#160;
+ <a href="M2Crypto.SSL.html#module-M2Crypto.SSL.Cipher"><code class="xref">M2Crypto.SSL.Cipher</code></a></td><td>
+ <em></em></td></tr>
+ <tr class="cg-1">
+ <td></td>
+ <td>&#160;&#160;&#160;
+ <a href="M2Crypto.SSL.html#module-M2Crypto.SSL.Connection"><code class="xref">M2Crypto.SSL.Connection</code></a></td><td>
+ <em></em></td></tr>
+ <tr class="cg-1">
+ <td></td>
+ <td>&#160;&#160;&#160;
+ <a href="M2Crypto.SSL.html#module-M2Crypto.SSL.Context"><code class="xref">M2Crypto.SSL.Context</code></a></td><td>
+ <em></em></td></tr>
+ <tr class="cg-1">
+ <td></td>
+ <td>&#160;&#160;&#160;
+ <a href="M2Crypto.SSL.html#module-M2Crypto.SSL.Session"><code class="xref">M2Crypto.SSL.Session</code></a></td><td>
+ <em></em></td></tr>
+ <tr class="cg-1">
+ <td></td>
+ <td>&#160;&#160;&#160;
+ <a href="M2Crypto.SSL.html#module-M2Crypto.SSL.ssl_dispatcher"><code class="xref">M2Crypto.SSL.ssl_dispatcher</code></a></td><td>
+ <em></em></td></tr>
+ <tr class="cg-1">
+ <td></td>
+ <td>&#160;&#160;&#160;
+ <a href="M2Crypto.SSL.html#module-M2Crypto.SSL.SSLServer"><code class="xref">M2Crypto.SSL.SSLServer</code></a></td><td>
+ <em></em></td></tr>
+ <tr class="cg-1">
+ <td></td>
+ <td>&#160;&#160;&#160;
+ <a href="M2Crypto.SSL.html#module-M2Crypto.SSL.timeout"><code class="xref">M2Crypto.SSL.timeout</code></a></td><td>
+ <em></em></td></tr>
+ <tr class="cg-1">
+ <td></td>
+ <td>&#160;&#160;&#160;
+ <a href="M2Crypto.SSL.html#module-M2Crypto.SSL.TwistedProtocolWrapper"><code class="xref">M2Crypto.SSL.TwistedProtocolWrapper</code></a></td><td>
+ <em></em></td></tr>
+ <tr class="cg-1">
+ <td></td>
+ <td>&#160;&#160;&#160;
+ <a href="M2Crypto.html#module-M2Crypto.threading"><code class="xref">M2Crypto.threading</code></a></td><td>
+ <em></em></td></tr>
+ <tr class="cg-1">
+ <td></td>
+ <td>&#160;&#160;&#160;
+ <a href="M2Crypto.html#module-M2Crypto.util"><code class="xref">M2Crypto.util</code></a></td><td>
+ <em></em></td></tr>
+ <tr class="cg-1">
+ <td></td>
+ <td>&#160;&#160;&#160;
+ <a href="M2Crypto.html#module-M2Crypto.X509"><code class="xref">M2Crypto.X509</code></a></td><td>
+ <em></em></td></tr>
+ </table>
+
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="index.html">M2Crypto</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="M2Crypto.html">M2Crypto Package</a></li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="index.html">Documentation overview</a><ul>
+ </ul></li>
+</ul>
+</div>
+<div id="searchbox" style="display: none" role="search">
+ <h3>Quick search</h3>
+ <div class="searchformwrapper">
+ <form class="search" action="search.html" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ </div>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer">
+ &copy;2017, Matej Cepl <mcepl@cepl.eu>.
+
+ |
+ Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
+ &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
+
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/search.html b/doc/html/search.html
new file mode 100644
index 0000000..5e59920
--- /dev/null
+++ b/doc/html/search.html
@@ -0,0 +1,120 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>Search &#8212; M2Crypto documentation</title>
+ <link rel="stylesheet" href="_static/alabaster.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+
+ <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <script type="text/javascript" src="_static/language_data.js"></script>
+ <script type="text/javascript" src="_static/searchtools.js"></script>
+ <link rel="index" title="Index" href="genindex.html" />
+ <link rel="search" title="Search" href="#" />
+ <script type="text/javascript">
+ jQuery(function() { Search.loadIndex("searchindex.js"); });
+ </script>
+
+ <script type="text/javascript" id="searchindexloader"></script>
+
+
+ <link rel="stylesheet" href="_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+ <h1 id="search-documentation">Search</h1>
+ <div id="fallback" class="admonition warning">
+ <script type="text/javascript">$('#fallback').hide();</script>
+ <p>
+ Please activate JavaScript to enable the search
+ functionality.
+ </p>
+ </div>
+ <p>
+ From here you can search these documents. Enter your search
+ words into the box below and click "search". Note that the search
+ function will automatically search for all of the words. Pages
+ containing fewer words won't appear in the result list.
+ </p>
+ <form action="" method="get">
+ <input type="text" name="q" value="" />
+ <input type="submit" value="search" />
+ <span id="search-progress" style="padding-left: 10px"></span>
+ </form>
+
+ <div id="search-results">
+
+ </div>
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="index.html">M2Crypto</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="M2Crypto.html">M2Crypto Package</a></li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="index.html">Documentation overview</a><ul>
+ </ul></li>
+</ul>
+</div>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer">
+ &copy;2017, Matej Cepl <mcepl@cepl.eu>.
+
+ |
+ Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a>
+ &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
+
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/searchindex.js b/doc/html/searchindex.js
new file mode 100644
index 0000000..d376536
--- /dev/null
+++ b/doc/html/searchindex.js
@@ -0,0 +1 @@
+Search.setIndex({docnames:["M2Crypto","M2Crypto.SSL","ZServerSSL-HOWTO","howto.ca","howto.smime","howto.ssl","index"],envversion:{"sphinx.domains.c":1,"sphinx.domains.changeset":1,"sphinx.domains.cpp":1,"sphinx.domains.javascript":1,"sphinx.domains.math":2,"sphinx.domains.python":1,"sphinx.domains.rst":1,"sphinx.domains.std":1,"sphinx.ext.viewcode":1,sphinx:55},filenames:["M2Crypto.rst","M2Crypto.SSL.rst","ZServerSSL-HOWTO.rst","howto.ca.rst","howto.smime.rst","howto.ssl.rst","index.rst"],objects:{"M2Crypto.ASN1":{ASN1_Integer:[0,1,1,""],ASN1_Object:[0,1,1,""],ASN1_String:[0,1,1,""],ASN1_TIME:[0,1,1,""],ASN1_UTCTIME:[0,3,1,""],LocalTimezone:[0,1,1,""]},"M2Crypto.ASN1.ASN1_Integer":{m2_asn1_integer_free:[0,2,1,""]},"M2Crypto.ASN1.ASN1_Object":{m2_asn1_object_free:[0,2,1,""]},"M2Crypto.ASN1.ASN1_String":{as_text:[0,2,1,""],m2_asn1_string_free:[0,2,1,""]},"M2Crypto.ASN1.ASN1_TIME":{get_datetime:[0,2,1,""],m2_asn1_time_free:[0,2,1,""],set_datetime:[0,2,1,""],set_string:[0,2,1,""],set_time:[0,2,1,""]},"M2Crypto.ASN1.LocalTimezone":{dst:[0,2,1,""],tzname:[0,2,1,""],utcoffset:[0,2,1,""]},"M2Crypto.AuthCookie":{AuthCookie:[0,1,1,""],AuthCookieJar:[0,1,1,""],mix:[0,4,1,""],unmix3:[0,4,1,""],unmix:[0,4,1,""]},"M2Crypto.AuthCookie.AuthCookie":{data:[0,2,1,""],expiry:[0,2,1,""],headerValue:[0,2,1,""],isExpired:[0,2,1,""],mac:[0,2,1,""],name:[0,2,1,""],output:[0,2,1,""],value:[0,2,1,""]},"M2Crypto.AuthCookie.AuthCookieJar":{isGoodCookie:[0,2,1,""],isGoodCookieString:[0,2,1,""],makeCookie:[0,2,1,""]},"M2Crypto.BIO":{BIO:[0,1,1,""],BIOError:[0,5,1,""],CipherStream:[0,1,1,""],File:[0,1,1,""],IOBuffer:[0,1,1,""],MemoryBuffer:[0,1,1,""],SSLBio:[0,1,1,""],openfile:[0,4,1,""]},"M2Crypto.BIO.BIO":{bio_ptr:[0,2,1,""],close:[0,2,1,""],fileno:[0,2,1,""],flush:[0,2,1,""],m2_bio_free:[0,2,1,""],read:[0,2,1,""],readable:[0,2,1,""],readline:[0,2,1,""],readlines:[0,2,1,""],reset:[0,2,1,""],seek:[0,2,1,""],should_read:[0,2,1,""],should_retry:[0,2,1,""],should_write:[0,2,1,""],tell:[0,2,1,""],write:[0,2,1,""],write_close:[0,2,1,""],writeable:[0,2,1,""]},"M2Crypto.BIO.CipherStream":{SALT_LEN:[0,3,1,""],close:[0,2,1,""],m2_bio_free:[0,2,1,""],m2_bio_pop:[0,2,1,""],set_cipher:[0,2,1,""],write_close:[0,2,1,""]},"M2Crypto.BIO.File":{close:[0,2,1,""],flush:[0,2,1,""],reset:[0,2,1,""]},"M2Crypto.BIO.IOBuffer":{close:[0,2,1,""],m2_bio_free:[0,2,1,""],m2_bio_pop:[0,2,1,""]},"M2Crypto.BIO.MemoryBuffer":{close:[0,2,1,""],getvalue:[0,2,1,""],read:[0,2,1,""],read_all:[0,2,1,""],write_close:[0,2,1,""]},"M2Crypto.BIO.SSLBio":{do_handshake:[0,2,1,""],set_ssl:[0,2,1,""]},"M2Crypto.BN":{rand:[0,4,1,""],rand_range:[0,4,1,""],randfname:[0,4,1,""]},"M2Crypto.DH":{DH:[0,1,1,""],DHError:[0,5,1,""],gen_params:[0,4,1,""],load_params:[0,4,1,""],load_params_bio:[0,4,1,""],set_params:[0,4,1,""]},"M2Crypto.DH.DH":{check_params:[0,2,1,""],compute_key:[0,2,1,""],gen_key:[0,2,1,""],m2_dh_free:[0,2,1,""],print_params:[0,2,1,""]},"M2Crypto.DSA":{DSA:[0,1,1,""],DSAError:[0,5,1,""],DSA_pub:[0,1,1,""],gen_params:[0,4,1,""],load_key:[0,4,1,""],load_key_bio:[0,4,1,""],load_params:[0,4,1,""],load_params_bio:[0,4,1,""],load_pub_key:[0,4,1,""],load_pub_key_bio:[0,4,1,""],pub_key_from_params:[0,4,1,""],set_params:[0,4,1,""]},"M2Crypto.DSA.DSA":{check_key:[0,2,1,""],gen_key:[0,2,1,""],m2_dsa_free:[0,2,1,""],save_key:[0,2,1,""],save_key_bio:[0,2,1,""],save_params:[0,2,1,""],save_params_bio:[0,2,1,""],save_pub_key:[0,2,1,""],save_pub_key_bio:[0,2,1,""],set_params:[0,2,1,""],sign:[0,2,1,""],sign_asn1:[0,2,1,""],verify:[0,2,1,""],verify_asn1:[0,2,1,""]},"M2Crypto.DSA.DSA_pub":{check_key:[0,2,1,""],save_key:[0,2,1,""],save_key_bio:[0,2,1,""],sign:[0,2,1,""],sign_asn1:[0,2,1,""]},"M2Crypto.EC":{EC:[0,1,1,""],ECError:[0,5,1,""],EC_pub:[0,1,1,""],ec_error:[0,4,1,""],gen_params:[0,4,1,""],get_builtin_curves:[0,4,1,""],load_key:[0,4,1,""],load_key_bio:[0,4,1,""],load_key_string:[0,4,1,""],load_key_string_pubkey:[0,4,1,""],load_pub_key:[0,4,1,""],load_pub_key_bio:[0,4,1,""],pub_key_from_der:[0,4,1,""],pub_key_from_params:[0,4,1,""]},"M2Crypto.EC.EC":{as_pem:[0,2,1,""],check_key:[0,2,1,""],compute_dh_key:[0,2,1,""],gen_key:[0,2,1,""],m2_ec_key_free:[0,2,1,""],pub:[0,2,1,""],save_key:[0,2,1,""],save_key_bio:[0,2,1,""],save_pub_key:[0,2,1,""],save_pub_key_bio:[0,2,1,""],sign_dsa:[0,2,1,""],sign_dsa_asn1:[0,2,1,""],verify_dsa:[0,2,1,""],verify_dsa_asn1:[0,2,1,""]},"M2Crypto.EC.EC_pub":{get_der:[0,2,1,""],get_key:[0,2,1,""],save_key:[0,2,1,""],save_key_bio:[0,2,1,""]},"M2Crypto.EVP":{Cipher:[0,1,1,""],EVPError:[0,5,1,""],HMAC:[0,1,1,""],MessageDigest:[0,1,1,""],PKey:[0,1,1,""],hmac:[0,4,1,""],load_key:[0,4,1,""],load_key_bio:[0,4,1,""],load_key_bio_pubkey:[0,4,1,""],load_key_string:[0,4,1,""],load_key_string_pubkey:[0,4,1,""],pbkdf2:[0,4,1,""]},"M2Crypto.EVP.Cipher":{"final":[0,2,1,""],m2_cipher_ctx_free:[0,2,1,""],set_padding:[0,2,1,""],update:[0,2,1,""]},"M2Crypto.EVP.HMAC":{"final":[0,2,1,""],digest:[0,2,1,""],m2_hmac_ctx_free:[0,2,1,""],reset:[0,2,1,""],update:[0,2,1,""]},"M2Crypto.EVP.MessageDigest":{"final":[0,2,1,""],digest:[0,2,1,""],m2_md_ctx_free:[0,2,1,""],update:[0,2,1,""]},"M2Crypto.EVP.PKey":{"final":[0,2,1,""],as_der:[0,2,1,""],as_pem:[0,2,1,""],assign_rsa:[0,2,1,""],get_modulus:[0,2,1,""],get_rsa:[0,2,1,""],m2_md_ctx_free:[0,2,1,""],m2_pkey_free:[0,2,1,""],reset_context:[0,2,1,""],save_key:[0,2,1,""],save_key_bio:[0,2,1,""],sign_final:[0,2,1,""],sign_init:[0,2,1,""],sign_update:[0,2,1,""],size:[0,2,1,""],update:[0,2,1,""],verify_final:[0,2,1,""],verify_init:[0,2,1,""],verify_update:[0,2,1,""]},"M2Crypto.Engine":{Engine:[0,1,1,""],EngineError:[0,5,1,""],cleanup:[0,4,1,""],load_dynamic:[0,4,1,""],load_dynamic_engine:[0,4,1,""],load_openssl:[0,4,1,""]},"M2Crypto.Engine.Engine":{ctrl_cmd_string:[0,2,1,""],finish:[0,2,1,""],get_id:[0,2,1,""],get_name:[0,2,1,""],init:[0,2,1,""],load_certificate:[0,2,1,""],load_private_key:[0,2,1,""],load_public_key:[0,2,1,""],m2_engine_free:[0,2,1,""],set_default:[0,2,1,""]},"M2Crypto.Err":{M2CryptoError:[0,5,1,""],SSLError:[0,5,1,""],get_error:[0,4,1,""],get_error_code:[0,4,1,""],get_error_func:[0,4,1,""],get_error_lib:[0,4,1,""],get_error_message:[0,4,1,""],get_error_reason:[0,4,1,""],get_x509_verify_error:[0,4,1,""],peek_error_code:[0,4,1,""]},"M2Crypto.RC4":{RC4:[0,1,1,""]},"M2Crypto.RC4.RC4":{"final":[0,2,1,""],rc4_free:[0,2,1,""],set_key:[0,2,1,""],update:[0,2,1,""]},"M2Crypto.RSA":{RSA:[0,1,1,""],RSAError:[0,5,1,""],RSA_pub:[0,1,1,""],gen_key:[0,4,1,""],keygen_callback:[0,4,1,""],load_key:[0,4,1,""],load_key_bio:[0,4,1,""],load_key_string:[0,4,1,""],load_pub_key:[0,4,1,""],load_pub_key_bio:[0,4,1,""],new_pub_key:[0,4,1,""],rsa_error:[0,4,1,""]},"M2Crypto.RSA.RSA":{as_pem:[0,2,1,""],check_key:[0,2,1,""],m2_rsa_free:[0,2,1,""],private_decrypt:[0,2,1,""],private_encrypt:[0,2,1,""],pub:[0,2,1,""],public_decrypt:[0,2,1,""],public_encrypt:[0,2,1,""],save_key:[0,2,1,""],save_key_bio:[0,2,1,""],save_key_der:[0,2,1,""],save_key_der_bio:[0,2,1,""],save_pem:[0,2,1,""],save_pub_key:[0,2,1,""],save_pub_key_bio:[0,2,1,""],sign:[0,2,1,""],sign_rsassa_pss:[0,2,1,""],verify:[0,2,1,""],verify_rsassa_pss:[0,2,1,""]},"M2Crypto.RSA.RSA_pub":{check_key:[0,2,1,""],private_decrypt:[0,2,1,""],private_encrypt:[0,2,1,""],save_key:[0,2,1,""],save_key_bio:[0,2,1,""]},"M2Crypto.Rand":{load_file:[0,4,1,""],rand_add:[0,4,1,""],rand_bytes:[0,4,1,""],rand_file_name:[0,4,1,""],rand_pseudo_bytes:[0,4,1,""],rand_seed:[0,4,1,""],rand_status:[0,4,1,""],save_file:[0,4,1,""]},"M2Crypto.SMIME":{Cipher:[0,1,1,""],PKCS7:[0,1,1,""],PKCS7_Error:[0,5,1,""],SMIME:[0,1,1,""],SMIME_Error:[0,5,1,""],load_pkcs7:[0,4,1,""],load_pkcs7_bio:[0,4,1,""],load_pkcs7_bio_der:[0,4,1,""],load_pkcs7_der:[0,4,1,""],smime_load_pkcs7:[0,4,1,""],smime_load_pkcs7_bio:[0,4,1,""],text_crlf:[0,4,1,""],text_crlf_bio:[0,4,1,""]},"M2Crypto.SMIME.PKCS7":{get0_signers:[0,2,1,""],m2_pkcs7_free:[0,2,1,""],type:[0,2,1,""],write:[0,2,1,""],write_der:[0,2,1,""]},"M2Crypto.SMIME.SMIME":{decrypt:[0,2,1,""],encrypt:[0,2,1,""],load_key:[0,2,1,""],load_key_bio:[0,2,1,""],set_cipher:[0,2,1,""],set_x509_stack:[0,2,1,""],set_x509_store:[0,2,1,""],sign:[0,2,1,""],unset_cipher:[0,2,1,""],unset_key:[0,2,1,""],unset_x509_stack:[0,2,1,""],unset_x509_store:[0,2,1,""],verify:[0,2,1,""],write:[0,2,1,""]},"M2Crypto.SSL":{Checker:[1,0,0,"-"],Cipher:[1,0,0,"-"],Connection:[1,0,0,"-"],Context:[1,0,0,"-"],SSLError:[1,5,1,""],SSLServer:[1,0,0,"-"],SSLTimeoutError:[1,5,1,""],Session:[1,0,0,"-"],TwistedProtocolWrapper:[1,0,0,"-"],cb:[1,0,0,"-"],ssl_dispatcher:[1,0,0,"-"],timeout:[1,0,0,"-"]},"M2Crypto.SSL.Checker":{Checker:[1,1,1,""],NoCertificate:[1,5,1,""],SSLVerificationError:[1,5,1,""],WrongCertificate:[1,5,1,""],WrongHost:[1,5,1,""]},"M2Crypto.SSL.Checker.Checker":{numericIpMatch:[1,3,1,""]},"M2Crypto.SSL.Cipher":{Cipher:[1,1,1,""],Cipher_Stack:[1,1,1,""]},"M2Crypto.SSL.Cipher.Cipher":{name:[1,2,1,""],version:[1,2,1,""]},"M2Crypto.SSL.Connection":{Connection:[1,1,1,""]},"M2Crypto.SSL.Connection.Connection":{accept:[1,2,1,""],accept_ssl:[1,2,1,""],bind:[1,2,1,""],clear:[1,2,1,""],clientPostConnectionCheck:[1,3,1,""],close:[1,2,1,""],connect:[1,2,1,""],connect_ssl:[1,2,1,""],fileno:[1,2,1,""],get_cipher:[1,2,1,""],get_cipher_list:[1,2,1,""],get_ciphers:[1,2,1,""],get_context:[1,2,1,""],get_default_session_timeout:[1,2,1,""],get_peer_cert:[1,2,1,""],get_peer_cert_chain:[1,2,1,""],get_session:[1,2,1,""],get_shutdown:[1,2,1,""],get_socket_read_timeout:[1,2,1,""],get_socket_write_timeout:[1,2,1,""],get_state:[1,2,1,""],get_verify_depth:[1,2,1,""],get_verify_mode:[1,2,1,""],get_verify_result:[1,2,1,""],get_version:[1,2,1,""],getpeername:[1,2,1,""],getsockname:[1,2,1,""],getsockopt:[1,2,1,""],listen:[1,2,1,""],m2_bio_free:[1,2,1,""],m2_bio_noclose:[1,3,1,""],m2_ssl_free:[1,2,1,""],makefile:[1,2,1,""],pending:[1,2,1,""],read:[1,2,1,""],recv:[1,2,1,""],recv_into:[1,2,1,""],renegotiate:[1,2,1,""],send:[1,2,1,""],sendall:[1,2,1,""],serverPostConnectionCheck:[1,2,1,""],set1_host:[1,2,1,""],set_accept_state:[1,2,1,""],set_bio:[1,2,1,""],set_cipher_list:[1,2,1,""],set_client_CA_list_from_context:[1,2,1,""],set_client_CA_list_from_file:[1,2,1,""],set_connect_state:[1,2,1,""],set_post_connection_check_callback:[1,2,1,""],set_session:[1,2,1,""],set_session_id_ctx:[1,2,1,""],set_shutdown:[1,2,1,""],set_socket_read_timeout:[1,2,1,""],set_socket_write_timeout:[1,2,1,""],set_ssl_close_flag:[1,2,1,""],set_tlsext_host_name:[1,2,1,""],setblocking:[1,2,1,""],setsockopt:[1,2,1,""],settimeout:[1,2,1,""],setup_addr:[1,2,1,""],setup_ssl:[1,2,1,""],shutdown:[1,2,1,""],ssl_get_error:[1,2,1,""],verify_ok:[1,2,1,""],write:[1,2,1,""]},"M2Crypto.SSL.Context":{Context:[1,1,1,""],ctxmap:[1,4,1,""],map:[1,4,1,""]},"M2Crypto.SSL.Context.Context":{add_session:[1,2,1,""],close:[1,2,1,""],get_allow_unknown_ca:[1,2,1,""],get_cert_store:[1,2,1,""],get_session_cache_mode:[1,2,1,""],get_session_timeout:[1,2,1,""],get_verify_depth:[1,2,1,""],get_verify_mode:[1,2,1,""],load_cert:[1,2,1,""],load_cert_chain:[1,2,1,""],load_client_CA:[1,2,1,""],load_client_ca:[1,2,1,""],load_verify_info:[1,2,1,""],load_verify_locations:[1,2,1,""],m2_ssl_ctx_free:[1,2,1,""],remove_session:[1,2,1,""],set_allow_unknown_ca:[1,2,1,""],set_cipher_list:[1,2,1,""],set_client_CA_list_from_file:[1,2,1,""],set_default_verify_paths:[1,2,1,""],set_info_callback:[1,2,1,""],set_options:[1,2,1,""],set_session_cache_mode:[1,2,1,""],set_session_id_ctx:[1,2,1,""],set_session_timeout:[1,2,1,""],set_tmp_dh:[1,2,1,""],set_tmp_dh_callback:[1,2,1,""],set_tmp_rsa:[1,2,1,""],set_tmp_rsa_callback:[1,2,1,""],set_verify:[1,2,1,""]},"M2Crypto.SSL.SSLServer":{ForkingSSLServer:[1,1,1,""],SSLServer:[1,1,1,""],ThreadingSSLServer:[1,1,1,""]},"M2Crypto.SSL.SSLServer.SSLServer":{handle_error:[1,2,1,""],handle_request:[1,2,1,""]},"M2Crypto.SSL.Session":{Session:[1,1,1,""],load_session:[1,4,1,""]},"M2Crypto.SSL.Session.Session":{as_der:[1,2,1,""],as_text:[1,2,1,""],get_time:[1,2,1,""],get_timeout:[1,2,1,""],m2_ssl_session_free:[1,2,1,""],set_time:[1,2,1,""],set_timeout:[1,2,1,""],write_bio:[1,2,1,""]},"M2Crypto.SSL.TwistedProtocolWrapper":{TLSProtocolWrapper:[1,1,1,""],connectSSL:[1,4,1,""],connectTCP:[1,4,1,""],listenSSL:[1,4,1,""],listenTCP:[1,4,1,""]},"M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper":{clear:[1,2,1,""],connectionLost:[1,2,1,""],connectionMade:[1,2,1,""],dataReceived:[1,2,1,""],loseConnection:[1,2,1,""],startTLS:[1,2,1,""],write:[1,2,1,""],writeSequence:[1,2,1,""]},"M2Crypto.SSL.cb":{ssl_info_callback:[1,4,1,""],ssl_verify_callback:[1,4,1,""],ssl_verify_callback_allow_unknown_ca:[1,4,1,""],ssl_verify_callback_stub:[1,4,1,""]},"M2Crypto.SSL.ssl_dispatcher":{ssl_dispatcher:[1,1,1,""]},"M2Crypto.SSL.ssl_dispatcher.ssl_dispatcher":{connect:[1,2,1,""],create_socket:[1,2,1,""],recv:[1,2,1,""],send:[1,2,1,""]},"M2Crypto.SSL.timeout":{struct_size:[1,4,1,""],struct_to_timeout:[1,4,1,""],timeout:[1,1,1,""]},"M2Crypto.SSL.timeout.timeout":{pack:[1,2,1,""]},"M2Crypto.X509":{CRL:[0,1,1,""],Request:[0,1,1,""],X509:[0,1,1,""],X509Error:[0,5,1,""],X509_Extension:[0,1,1,""],X509_Extension_Stack:[0,1,1,""],X509_Name:[0,1,1,""],X509_Name_Entry:[0,1,1,""],X509_Stack:[0,1,1,""],X509_Store:[0,1,1,""],X509_Store_Context:[0,1,1,""],load_cert:[0,4,1,""],load_cert_bio:[0,4,1,""],load_cert_der_string:[0,4,1,""],load_cert_string:[0,4,1,""],load_crl:[0,4,1,""],load_request:[0,4,1,""],load_request_bio:[0,4,1,""],load_request_der_string:[0,4,1,""],load_request_string:[0,4,1,""],new_extension:[0,4,1,""],new_stack_from_der:[0,4,1,""],x509_store_default_cb:[0,4,1,""]},"M2Crypto.X509.CRL":{as_text:[0,2,1,""],m2_x509_crl_free:[0,2,1,""]},"M2Crypto.X509.Request":{add_extensions:[0,2,1,""],as_der:[0,2,1,""],as_pem:[0,2,1,""],as_text:[0,2,1,""],get_pubkey:[0,2,1,""],get_subject:[0,2,1,""],get_version:[0,2,1,""],m2_x509_req_free:[0,2,1,""],save:[0,2,1,""],save_pem:[0,2,1,""],set_pubkey:[0,2,1,""],set_subject:[0,2,1,""],set_subject_name:[0,2,1,""],set_version:[0,2,1,""],sign:[0,2,1,""],verify:[0,2,1,""]},"M2Crypto.X509.X509":{add_ext:[0,2,1,""],as_der:[0,2,1,""],as_pem:[0,2,1,""],as_text:[0,2,1,""],check_ca:[0,2,1,""],check_purpose:[0,2,1,""],get_ext:[0,2,1,""],get_ext_at:[0,2,1,""],get_ext_count:[0,2,1,""],get_fingerprint:[0,2,1,""],get_issuer:[0,2,1,""],get_not_after:[0,2,1,""],get_not_before:[0,2,1,""],get_pubkey:[0,2,1,""],get_serial_number:[0,2,1,""],get_subject:[0,2,1,""],get_version:[0,2,1,""],m2_x509_free:[0,2,1,""],save:[0,2,1,""],save_pem:[0,2,1,""],set_issuer:[0,2,1,""],set_issuer_name:[0,2,1,""],set_not_after:[0,2,1,""],set_not_before:[0,2,1,""],set_pubkey:[0,2,1,""],set_serial_number:[0,2,1,""],set_subject:[0,2,1,""],set_subject_name:[0,2,1,""],set_version:[0,2,1,""],sign:[0,2,1,""],verify:[0,2,1,""]},"M2Crypto.X509.X509_Extension":{get_critical:[0,2,1,""],get_name:[0,2,1,""],get_value:[0,2,1,""],m2_x509_extension_free:[0,2,1,""],set_critical:[0,2,1,""]},"M2Crypto.X509.X509_Extension_Stack":{m2_sk_x509_extension_free:[0,2,1,""],pop:[0,2,1,""],push:[0,2,1,""]},"M2Crypto.X509.X509_Name":{add_entry_by_txt:[0,2,1,""],as_der:[0,2,1,""],as_hash:[0,2,1,""],as_text:[0,2,1,""],entry_count:[0,2,1,""],get_entries_by_nid:[0,2,1,""],m2_x509_name_free:[0,2,1,""],nid:[0,3,1,""]},"M2Crypto.X509.X509_Name_Entry":{create_by_txt:[0,2,1,""],get_data:[0,2,1,""],get_object:[0,2,1,""],m2_x509_name_entry_free:[0,2,1,""],set_data:[0,2,1,""],set_object:[0,2,1,""]},"M2Crypto.X509.X509_Stack":{as_der:[0,2,1,""],m2_sk_x509_free:[0,2,1,""],pop:[0,2,1,""],push:[0,2,1,""]},"M2Crypto.X509.X509_Store":{add_cert:[0,2,1,""],add_x509:[0,2,1,""],load_info:[0,2,1,""],load_locations:[0,2,1,""],m2_x509_store_free:[0,2,1,""],set_verify_cb:[0,2,1,""]},"M2Crypto.X509.X509_Store_Context":{get1_chain:[0,2,1,""],get_current_cert:[0,2,1,""],get_error:[0,2,1,""],get_error_depth:[0,2,1,""],m2_x509_store_ctx_free:[0,2,1,""]},"M2Crypto.ftpslib":{FTP_TLS:[0,1,1,""]},"M2Crypto.ftpslib.FTP_TLS":{auth_ssl:[0,2,1,""],auth_tls:[0,2,1,""],ntransfercmd:[0,2,1,""],prot_c:[0,2,1,""],prot_p:[0,2,1,""]},"M2Crypto.httpslib":{HTTPSConnection:[0,1,1,""],ProxyHTTPSConnection:[0,1,1,""]},"M2Crypto.httpslib.HTTPSConnection":{close:[0,2,1,""],connect:[0,2,1,""],default_port:[0,3,1,""],get_session:[0,2,1,""],set_session:[0,2,1,""]},"M2Crypto.httpslib.ProxyHTTPSConnection":{connect:[0,2,1,""],endheaders:[0,2,1,""],putheader:[0,2,1,""],putrequest:[0,2,1,""]},"M2Crypto.m2urllib":{open_https:[0,4,1,""]},"M2Crypto.m2urllib2":{HTTPSHandler:[0,1,1,""],build_opener:[0,4,1,""]},"M2Crypto.m2urllib2.HTTPSHandler":{https_open:[0,2,1,""],https_request:[0,2,1,""]},"M2Crypto.m2xmlrpclib":{SSL_Transport:[0,1,1,""]},"M2Crypto.m2xmlrpclib.SSL_Transport":{request:[0,2,1,""],user_agent:[0,3,1,""]},"M2Crypto.threading":{cleanup:[0,4,1,""],init:[0,4,1,""]},"M2Crypto.util":{UtilError:[0,5,1,""],bin_to_hex:[0,4,1,""],genparam_callback:[0,4,1,""],no_passphrase_callback:[0,4,1,""],octx_to_num:[0,4,1,""],passphrase_callback:[0,4,1,""],pkcs5_pad:[0,4,1,""],pkcs7_pad:[0,4,1,""],quiet_genparam_callback:[0,4,1,""]},M2Crypto:{ASN1:[0,0,0,"-"],AuthCookie:[0,0,0,"-"],BIO:[0,0,0,"-"],BN:[0,0,0,"-"],DH:[0,0,0,"-"],DSA:[0,0,0,"-"],EC:[0,0,0,"-"],EVP:[0,0,0,"-"],Engine:[0,0,0,"-"],Err:[0,0,0,"-"],RC4:[0,0,0,"-"],RSA:[0,0,0,"-"],Rand:[0,0,0,"-"],SMIME:[0,0,0,"-"],SSL:[1,0,0,"-"],X509:[0,0,0,"-"],__init__:[0,0,0,"-"],callback:[0,0,0,"-"],ftpslib:[0,0,0,"-"],httpslib:[0,0,0,"-"],m2:[0,0,0,"-"],m2crypto:[0,0,0,"-"],m2urllib2:[0,0,0,"-"],m2urllib:[0,0,0,"-"],m2xmlrpclib:[0,0,0,"-"],threading:[0,0,0,"-"],util:[0,0,0,"-"]}},objnames:{"0":["py","module","Python module"],"1":["py","class","Python class"],"2":["py","method","Python method"],"3":["py","attribute","Python attribute"],"4":["py","function","Python function"],"5":["py","exception","Python exception"]},objtypes:{"0":"py:module","1":"py:class","2":"py:method","3":"py:attribute","4":"py:function","5":"py:exception"},terms:{"059600270x":5,"0ipy80":4,"0jwuq":4,"0qjhp6hut7fso":4,"0x0":[3,4],"0x1":3,"0x10001":[3,4],"0x2":[3,4],"0x822012c":4,"19973a9dbbb601ba":3,"1bc9f3q":4,"1czdztgk7h9cdgx2qjsivymyytcfi3zsuzmjs8":3,"1dr9dy8l0naqh21y5fgss8b1wd":4,"1ezn9zmlryqzbtxnnrmp3dhj":4,"1g9epovswhpqr":4,"1hxxfyo88m":3,"1qk53c":3,"1t8luishhn9899imp2vyg0ub67fqfypymm2cm2":4,"1tcaqbmq":4,"1vsrcid":3,"217mrhyx2nswgrpkqndu3gespovml3jeqiaxuponbwq7rj42":3,"2aglpogdcfdioqblb2dcscohmbbvr":3,"2bconvert":1,"2bdqvfpffx5lsmitkzaobldssjfr6rojxoqrsgia2az":4,"2cjcbfzokmijci03kbtqxofiqglstwxgzknf":3,"2dnyol50zu0sdzst1":3,"2iwrpascbeid8saraql3ddcli":3,"2zz2g7x1hxrwh95a":4,"3c93156fc7b4ebf49fe9c7db7f503087":4,"3dizhtxigepfztiuyutxs3i2gnmx2pee3chtllywd3jneakz0iozpdphif2xhllq":4,"3pjiyfhaxk64iutmpsy393rhmeb4kn":4,"3wf7q915tveqoc74bnu6b8ibbgrmhzdzmvq4szffveaum":3,"41b2874df3d02dd4":3,"4ju6":4,"4mpgg20wd633d4z4dtlddz":3,"4oxll0bi":3,"509v3":2,"56vrpgppgut40hv8xqfbwiz2whwwlkpfahj8b79ztfuzuru6z2rnpvv8inhc":4,"5efdvbet":3,"6l0g37faxur3xm28rchzvhu":3,"76h5jiznpbdsf2fjghwqvvdgyw4owy3mu739lhvnblicn":3,"7ay4jsdhyibcmgsq":3,"7pvwhtszeyhn3oa9dhlmv9uqc4wy5md7j":3,"7zjt2r5cpikgkwofamduxeltx":3,"8caweaaaaama0gcsqgsib3dqebbauaa4gb":3,"8czydsolmyibujccabycaqewydbbmqswcqydvqqgewjtrzerma8ga1uechmittjd":4,"8levy0cllw":3,"8tsi3wo5enkg4qwbnarqc3vgcv":4,"8yhspd0caweaaaobtjcbszadbgnvhq4efgquxoyoll1t4jabwzfrm7ms8nblzuow":4,"974aklcjnk1gzigarz":4,"9gul1bxbckrtedtxenqtem7spzomtswd2lhb8z65grx90cyt":4,"9ij5z6mja7rm7ttbsjup":4,"9rsqkrc9urv9mrbisredgnyecnerak5r1yzpoowninxc":3,"9znlfejkjj67vembxbj":4,"abstract":[0,4],"break":2,"byte":[0,1],"case":[1,4,5],"class":[0,1,4,5],"default":[0,1,2,3,4,5],"export":[1,4],"final":[0,4],"float":0,"function":[0,1,2,4,5],"import":[0,1,2,4],"int":[0,1],"long":[1,5],"new":[0,1,2,3,4],"null":[0,1],"public":[0,3,4],"return":[0,1,4,5],"true":[0,1,4],"while":[0,1,2,4],AND:1,CAs:1,DES:[3,4],DNS:[0,5],Doing:0,For:[0,1,2,3,4],HAS:1,Its:0,NOT:[0,1],Not:[3,4],THE:1,TLS:[0,1,5],That:[3,4],The:[0,1,2,4,5],There:[1,3,4,5],These:[1,2],Use:[0,1,5],Using:[3,4,5],WILL:1,With:2,__del__:1,__init__:[0,2],_alwayssucceedspostconnectioncheck:1,_close_cb:0,_debug:0,_io:0,_mode_:1,_ptr:0,_pyfre:[0,1],_pyfree_x509:0,_timeout_:1,_top:2,a4mgiy2kwwfie73qiyv7yyg8flrvr1iib:3,aaiavb8w:4,abl:4,about:[0,1,3,4],abov:[0,1,2,4,5],absent:1,absolut:0,abstracthttphandl:0,accept:[0,1,2,3,4,5],accept_ssl:1,access:[2,4],accord:[0,1],acl_us:2,acquir:0,action:1,actual:[0,1,4,5],actualhost:1,add:[0,1,2],add_cert:0,add_entry_by_txt:0,add_ext:0,add_extens:0,add_sess:1,add_x509:0,added:[0,1],addhead:2,addinfourl:0,adding:1,addit:[0,1,5],addr:1,address:[1,3,4,5],addressfamili:1,admin:3,administr:4,advanc:3,adversari:0,aes_128_cbc:0,aetir4v7sgxmepx7thq1pv:4,af_inet:1,affect:1,afresh:3,after:[0,1,3,4,5],again:[0,3,4],against:0,agent:2,aggtjgplibexlzalhpwlz9laqyrqpvcvjywaovfmmvrav4nafnoz2:4,ago:3,ahau6kwk:4,ahporp5ys55czpi:3,aka:0,akbr4il1nkq8ecsmcr3wpa0i9n0ehi7zvpvahxc0sqapfl8ygdfhq:3,alert:1,alg:0,algo:0,algorigthm:0,algorithm:[0,3,4],alia:0,aliv:1,all:[0,1,3,5],allow:[0,1,3,5],almost:0,along:0,alreadi:1,also:[0,1,2,3,4,5],alt:2,altern:[1,2],although:5,alwai:[0,4],amyxludrk45acua:3,analys:5,ani:[0,1,5],anoth:[1,3],anyon:4,anyth:5,aogabaku8w3w1qu15hle1bjsl7gmreoreqeblobmmazz4by0l6sxzxjpjwxo86f:3,apach:2,api:[0,1],appear:2,append:0,appli:[0,2,3],applic:[0,1,3,4,5],approach:4,appropri:[0,1,5],aqh:4,arg:0,argument:0,argv:0,arm:4,around:2,as_der:[0,1],as_hash:0,as_pem:0,as_text:[0,1],ask:[0,3,4],asn1:6,asn1_integ:0,asn1_object:0,asn1_str:0,asn1_string_print_ex:0,asn1_tim:0,asn1_utctim:0,asn1int:0,asn1obj:0,asn1str:0,assign:[0,1],assign_rsa:0,associ:[0,1],assum:[1,2,4],asyncio:1,asyncor:[1,2],attach:4,attempt:[0,5],attribut:[0,3,4],auth:0,auth_ssl:0,auth_tl:0,authcooki:6,authcookiejar:0,authent:4,author:[0,2,3,4,5],autom:4,automag:[0,4],automat:[1,5],avail:[1,2,4,5],avoid:2,awai:[0,1],awfqq4jcc:4,awihma0gccqgsib3dqmcageoma0gcsqgsib3dqebaquabigaqpu8hfutlcf6ho2t:4,ax96lvs0:3,b4law8g59vtg6dykeetrg0rubx4bggc7pkbfuin423yjjodwchvvgnpozxmqt:3,b4txejzriyc8f3:4,b6gr5s8:4,b6ugcsqgsib3dqehataubggqhkig9w0dbwqirf525ufwszaaggea85rmx6axqmxb:4,b75:3,b877j9wbpbl:3,b9zjffauqtwzdnjgrkkyikhwjdojaac:4,backlog:1,bad:1,base64:4,base:[0,1,2,3,4,5],basi:1,basic:[3,4],bat:2,bdclcn8a:4,becaus:[0,1,4],been:[0,1,4],befor:[0,1,3,4,5],began:3,begin:[3,4,5],behav:1,behaviour:1,being:[0,1,4],below:2,best:5,better:0,between:5,beyond:4,bgbyj1dubkhzsc7dgxzdtuclgnxqnnsg:3,bgcolor:2,bgkqhkig9w0bbwewfayikozihvcnawcecmn:4,bgkqhkig9w0bbwewhayjkozihvcnaqkfmq8xdtaxmdmzmtexnduwmlowiwyjkozi:4,bhdelbr5jbpjcj5aid76mfr8:4,bhmcu0cxetapbgnvbaotce0yq3j5chrvmrkwfwydvqqdexbtl01jtuugumvjaxbp:4,big:0,bin_to_hex:0,binari:[0,1],bind:1,bind_and_activ:1,bindaddress:1,binstr:1,bio:[1,4,5,6],bio_clos:1,bio_f_buff:0,bio_f_ciph:0,bio_f_ssl:0,bio_fre:1,bio_in:0,bio_noclos:1,bio_ptr:0,bio_push:0,bio_s_mem:0,bio_s_pyfd:0,bioerror:0,bit:[0,1,3,4],bitmask:1,bitwis:0,bjq5hnxbouslq0rwbrkoxv64i:4,blank:[3,4],blklen:0,blob:[0,4],block:1,blwegdqhonaiwbk5z1l:4,bmrlckblegftcgxllmrvbqibadajbgurdgmcgguaoigxmbggcsqgsib3dqejazel:4,bmvnwbppufzpiaivalycjt6pyextbbszs7:3,bo2w7ei6iejbazk:3,bodi:[0,2],book:5,bool:1,border:2,both:[0,1,2],bottom:[0,4],bound:[0,1],boundari:4,box:[2,4],br77:3,bring:4,brows:2,browser:2,browser_id_manag:2,buf:[0,4],buf_len:0,buff:1,buffer:[0,1,4,5],buffer_s:1,buffers:1,buflen:1,bufsiz:1,build_open:0,built:1,builtin:0,bundl:[2,3,4],bxwxkuuvt81vbjwdn9jst6:4,bytearrai:1,c6fi3n03rgfmkectijc:3,cacert:[1,3],cach:1,cadav:2,cafil:1,cakei:3,calcul:0,call:[0,1,3,4,5],callabl:[0,1],callback:[1,6],caller:1,can:[0,1,2,3,4,5],cannot:1,capath:1,captur:0,cat:3,catalog:2,catop:3,cbc:[3,4],ccrt2tfwkbbfleuifl7mb:3,ccvkzzl:3,cenfqfwc:4,cepl:0,cert:[0,1,4,5],certain:[0,1,3],certbio:0,certchainfil:1,certdata2pem:5,certdata:5,certfil:[0,1],certif:[0,1,2,3,5],certifi:[3,4],certmast:3,cgyikozihvcnawcwdgyikozihvcnawicagcama0gccqgsib3dqmcagfamacgbsso:4,chain:[0,1,5],challeng:3,chandra:5,chang:[0,1],channel:[1,2],charact:0,cheap:4,check:[0,1,2,3,5],check_ca:0,check_kei:0,check_param:0,check_purpos:0,checker:[0,5,6],choos:[3,4],chosen:5,chunk:1,cipher:[0,4,5,6],cipher_list:1,cipher_stack:1,cipherstream:0,circular:1,citi:[3,4],claim:5,clbwev3ryfrlp4x8j9mdte0ykok3t0wqohqrettsifdtjnfp:3,clean:[0,1],cleanup:0,clear:[0,1,3,4],click:[2,4],client:[0,1,4,5],client_addr:0,client_address:1,clientpostconnectioncheck:1,close:[0,1,2,4],close_flag:0,close_pyfil:0,clutter:2,cmd:0,cnf:[3,4],cngeq1qxtyduiguda2nbgcl:4,cnlwdg8xfjaubgnvbamtdvmvtulnrsbtzw5kzxixitafbgkqhkig9w0bcqewennl:4,code:[0,1,3,4],coll:2,collect:[2,5],com:[0,2,3,4,5],combin:1,come:[0,3,5],command:[3,5],comment:3,commerci:4,commit:3,common:[3,4,5],commonli:4,commonnam:[0,1,3,5],commun:[0,1],compani:[3,4],companion:4,compar:5,compat:5,compil:[0,1],complet:[0,1],compos:2,composit:0,comput:0,compute_dh_kei:0,compute_kei:0,concaten:1,configur:[3,4],conn:0,connect:[0,2,4,5,6],connect_ssl:1,connectionlost:1,connectionmad:1,connectssl:1,connecttcp:1,consid:1,consist:[0,4],constant:[0,1],constrain:3,constraint:[3,4],consum:4,contain:[0,1,2,4],content:[0,1,4,6],context:[0,5,6],contextfactori:1,continu:1,control:[0,1,5],control_panel:2,conveni:1,convert:[0,5],cooki:0,cookie_str:0,copi:[1,2,3],copyright:[0,1,2,3,4,5],corner:4,correct:[1,4],correctli:4,correspond:4,could:[0,1,5],count:[0,2],counterpan:4,countri:[3,4],countrynam:3,cours:[3,4],cover:3,coz:4,cqydvqqgewjtrzerma8ga1uechmittjdcnlwdg8xfjaubgnvbamtdvmvtulnrsbt:4,cqzkt9:3,crack:4,crash:0,creat:[0,1,2,4,5,6],create_by_txt:0,create_socket:1,creation:[1,3],credit:2,critic:0,crl:0,cryptograph:[0,4],css:2,cstringio:0,ctrl_cmd_string:0,ctx:[0,1,5],ctxmap:1,current:[0,1,4],curv:0,custom:1,cvzrxakeaxno80arbgxpumr11ghg:3,cw8kzzwh:4,cxo23r9wwrnzem:4,d2i_ssl_sess:1,dai:[3,4],dasmytmpc4ztytv06n07afbjl:3,dat:[2,4],data:[0,1,2,3,4,5],data_bio:0,databas:3,datareceiv:1,date:[0,2,5],datetim:0,dav:2,dcwd:4,ddlzqbacuxwtv5xy8plmx7widaqab:3,dec:2,decid:[1,3],decis:3,decod:[1,3,5],decrypt:[0,5],def:4,default_port:0,defin:1,dek:3,delet:0,demo:[2,3,4,5],democa:3,demonstr:[3,4,5],depend:[0,1,2,4],deploi:3,depth:[0,1,5],der:[0,4],der_str:0,deriv:0,des_ede3_cbc:4,describ:[0,1],descript:0,desktop:2,detail:0,determin:0,dev:2,develop:3,dh1024:2,dherror:0,dhpfile:1,dialog:[2,4],did:[1,3],differ:[1,5],diffi:[0,2],digest:[0,4,5],digit:4,directli:[1,5],directori:[1,2,3,5],dirnam:[3,4],disabl:[0,1],discard:3,discuss:3,dispatch:1,displai:[4,5],dispos:1,disposit:4,distinguish:[1,3,4],distribut:[2,5],ditto:0,dnli0rvuvxiwt:3,do_handshak:0,document:[1,2,3,4,5],doe:[0,1,5],doesn:1,dog:4,dom:[3,4],don:0,done:[1,2],dough:0,down:1,download:[2,4,5],dqehaaavbbnhihnpz24gb2ygb3vyihrpbwvzoiic5zccaumwggjmoamcaqicaqaw:4,dqyjkozihvcnaqeebqawwzelmakga1uebhmcu0cxetapbgnvbaotce0yq3j5chrv:4,dsa:[4,5,6],dsa_pub:0,dsaerror:0,dst:0,due:1,duhrqiml1tyi:3,duqhj2ygkkwdqq9v0xscjkgiyw:3,dure:[0,1,5],dw0boozhj8tc7co7lmyb0ye271b6:3,dyman:0,dynam:0,e9kybgki7vpojwbz27:3,e_n:0,each:[0,1,4],east:0,eawm5avuv7hnptt5zr:4,eaydvqqdewlsb2nhbghvc3qxjzalbgkqhkig9w0bcqewggfkbwluqhnlcnzlci5l:3,ebdz:4,ec9eyj:4,ec_error:0,ec_pub:0,ecdh:0,ecdsa:0,ecerror:0,ede3:[3,4],effect:4,egftcgxllmrvbtcbnzanbgkqhkig9w0baqefaaobjqawgykcgyear1nyy1qrll1r:3,either:[0,1],electron:4,els:[0,1,3,4],email:[0,3,4],emailaddress:[0,3],emmarsgyedf5h1afl1smkomskbqxe1d2jg:4,empir:0,emploi:5,enabl:[1,4],encod:[0,1,2,4],encrypt:[0,1,3],end:[0,1,3],endhead:0,endian:0,engin:[1,6],engine_ctrl_cmd_str:0,engine_method_:0,engineerror:0,enhanc:5,enough:0,ensu:4,ensur:[0,1],enter:[0,2,3,4],entri:[0,3],entropi:0,entry_count:0,environ:[0,1],eopzyno4mi:4,eoq9wfscnii4:3,eovbgs7ezalvvkdj4hnl:4,eozfol5i20ykiv6j:4,ephemer:1,epoch:0,epollreactor:1,equival:[0,1],eric:5,err:[4,6],err_get_error:0,errdepth:1,errnum:1,error:[0,1,4],error_log:2,establish:[0,1,5],estim:0,etag:2,etc:[0,1],etwitreft1heupnar:4,even:0,event:0,evp:6,evp_ciph:0,evperror:0,ewjtrzerma8ga1uechmittjdcnlwdg8xfjaubgnvbamtdvmvtulnrsbtzw5kzxix:4,exampl:[0,1,2,3,4,5],except:[0,1,5],exchang:[0,5],execut:[3,4],exist:[2,3],exit:0,exiy8geir:4,exp:0,expect:0,expectedhost:1,expir:[0,1,3],expiri:0,explain:4,explan:1,explicitli:1,explor:4,expon:[0,3,4],ext:0,ext_stack:0,extens:[0,1,3,4],extern:1,extra:3,extract:1,facilit:3,fact:0,factori:[0,1],fail:[0,1],failur:[0,1,4],fakesocket:5,fals:[0,1,3],famili:1,fancyurlopen:2,faq:0,farm:2,fashion:2,fatal:1,fcgiserv:2,fcmspp3auq1:4,featur:5,feed:0,feedback:0,few:[3,4],ffffff:2,fi1wdpphywke97pojizvqesfzopty5hjiyzux4u:3,field:[0,3,4,5],fieldnam:1,fifth:5,file:[0,1,2,3,4,5],filenam:[0,1,3,4],fileno:[0,1],find:1,fingerprint:0,finish:[0,1],first:[0,4,5],fixm:1,flag:[0,1,4,5],flndpcnkrtvqdx3rt6x6vbttcyom:4,flowinfo:1,flush:0,fmt7a120s3gd2jixgh06l:4,follow:[0,2,3,4,5],forgotten:3,forkingmixin:1,forkingsslserv:1,form:[0,1,5],format:[0,1,4,5],format_d:0,format_format_d:0,format_pem:0,found:[0,1],foundat:[1,5],four:1,fourth:5,fqlcrrr5nvupdin:3,freebsd:2,freed:1,freeli:4,freewar:4,friendli:4,frill:0,from:[0,1,2,3,4,5],from_addr:4,from_cert:4,from_kei:4,ftp:[0,2],ftp_tl:0,ftplib:0,ftpserver:2,ftpslib:6,full:[3,4],further:1,fv4sgm3jkr:4,g3bgsmvlxkefztfjkxo6xnjcbnf5i:4,g7ppoo:3,gain:5,gd58p4mpmhu5iknz4yh4nlhnaitevcs85tzuaxze9g:4,gen_kei:0,gen_param:0,gener:[0,1,3,4],genparam_callback:0,get0_sign:0,get1_chain:0,get:[0,1,2],get_allow_unknown_ca:1,get_builtin_curv:0,get_cert_stor:1,get_ciph:1,get_cipher_list:1,get_context:1,get_crit:0,get_current_cert:0,get_data:0,get_datetim:0,get_default_session_timeout:1,get_der:0,get_entries_by_nid:0,get_error:[0,1,4],get_error_cod:0,get_error_depth:0,get_error_func:0,get_error_lib:0,get_error_messag:0,get_error_reason:0,get_ext:0,get_ext_at:0,get_ext_count:0,get_fingerprint:0,get_id:0,get_issu:0,get_kei:0,get_modulu:0,get_nam:0,get_not_aft:0,get_not_befor:0,get_object:0,get_peer_cert:1,get_peer_cert_chain:1,get_pubkei:0,get_rsa:0,get_serial_numb:0,get_sess:[0,1],get_session_cache_mod:1,get_session_timeout:1,get_shutdown:1,get_socket_read_timeout:1,get_socket_write_timeout:1,get_stat:1,get_subject:0,get_tim:1,get_timeout:1,get_valu:0,get_verify_depth:1,get_verify_mod:1,get_verify_result:1,get_vers:[0,1],get_x509_verify_error:0,getpeernam:1,getproto:1,getronicsgov:4,getsocknam:1,getsockopt:1,geturl:0,getvalu:0,ggarfmmj4yuhewkys9jo1h8k4bdxugmauwni5:3,give:3,given:[0,1],givennam:0,gknqqdblotqt06f3oissdjetm2itllyhgzv:3,global:4,gmt:[2,3,4],goe:[0,1],good:0,govern:3,gpmpndsyvvceufpluwydim0vkwhgc2:4,gqnveov:3,gqzcvnzzcmx8uvrjqr8drwdsmpj0vxg1:4,gracefulli:1,gratefulli:4,grcgzeb9ymfcedxahtdufhjrkpdpsxzzvvgksbncbqu92obyqvnrq8m:4,greet:1,grew:5,group:4,gucrblvd7n3ofnx5ujmpmcw9zwbu:4,gvyvi:4,gymga1udiwr8mhqaffzsqjs9bei2gcgrutozevjws81kov:4,h7nmicymi2wkz8h:4,h99suto:3,h9diul:3,hack:2,handi:3,handl:[1,4],handle_error:1,handle_request:1,handler:[0,1],handshak:[0,1],hanson:3,happen:5,hard:0,hardwar:0,has:[0,1,4,5],hash:0,have:[1,3,4],hcyiukxujtaqtxboh:4,head:2,header:[0,2],headervalu:0,height:2,heikki:[1,5],hellman:[0,2],henc:3,henceforth:2,here:[0,1,3,4],hex:0,higher:1,hihsrgwtnd7lnxuucpx8yv1id0dlmp0hz:4,his:4,hkig9w0baqefaaobjqawgykcgyea5c5tj1chtsoxa1q2q0fyiwmwyhptjpjcvtzm:4,hmac:[0,4,5],hold:0,home:[0,2,4],hook:1,host:[0,1,5],hostnam:1,hot:4,how:[0,1,4,5],howev:1,hpysvh:4,href:2,hrg6sai33usk8xpokjqa:3,htm:4,html:[0,2,4],http:[0,4,5],http_class:0,httpconnect:[0,5],httplib:[0,5],https_open:0,https_request:0,https_server:2,https_srv:4,httpsconnect:[0,5],httpserver:2,httpshandler:0,httpslib:[5,6],hu3qdmtcwjd:3,hvcnaqkemryefooerud8exiyxfqq8btfukwrsp3imfigcsqgsib3dqejdzffmemw:4,hyswpz1xvlprmv4:3,i2d_ssl_sess:1,ia5str:3,icon:4,ident:[1,2,4,5],identifi:[0,3,4,5],idx:1,ietf:4,ieucourgcxpyd1j65vt7ob3ziypu2f2nluicynqpg1sd:4,ignor:0,iihwd6gtv1uodf7urbxtl3hq9:4,imap:4,imc:4,img:2,immedi:1,implement:[0,4,5],imqqiiw:4,includ:[0,3],incorpor:[3,4],increas:0,indent:0,indetermin:1,index:[0,6],index_html:2,indic:[0,1,4],indirectli:0,info:[0,3,4],inform:[0,1,2,3,4,5],inherit:[0,1],init:0,initi:[0,1],initialis:[0,1],inkei:4,input:[0,1,5],insert:0,instal:4,instanc:[0,1,4,5],instanti:[0,4],instead:[2,4],instruct:2,integ:1,integr:4,intend:4,interact:0,interest:1,interfac:[0,1,4,5],intern:[0,1],internet:[1,3,4],interpret:[0,1,5],intuit:3,invalid:0,invok:[0,1,2,4],iobuff:[0,5],ioy0bdijcyn1jimohj:4,ipv4:1,ipv6:1,iqwxllnj:4,ir9fggophatzzq:4,ireactorssl:1,ireactortcp:1,isbn:5,isexpir:0,isgoodcooki:0,isgoodcookiestr:0,issu:[1,2,4],issuer:[0,3,4],itafbgkqhkig9w0bcqewennlbmrlckblegftcgxllmrvbyibadambgnvhrmebtad:4,item:0,iter:0,its:[0,1,2,3,4],itself:[0,4],iwq3n6j1suzs3uw6abq8bivynoucmkjaqqjbanqxfalu4b:3,j6wo9dzltioz3znvr3ljsskib4tip4ugqnjaluw7m3ftz3magxn68hbbjs8tz8tl:4,j9ftv3di:3,jan:2,jbt3ltgf743utyaas7hnguouobhoyt:3,jcyhx9vw4xvja7:4,jddsk:4,john:5,join:4,ju4:3,jun:2,just:[1,5],jvy5cif:4,jy5rd:3,jyvbd7acn35p5yx7ktqvqerwdijxycanbcnvmrtmysanw9kv1ujtxc5vx7ylwipk:3,kdfqdmtfzqkymhp1laq1ihbq1rhwsbh5n3ekq:3,kdjqodst7ovu62motgf3arcduppwuztfxolyone5nioo1apvhbrinqwcplkpotqr:3,kebfzs8asq7uc9axw6ti0eapj8evhtwhsbgzqrwekfbxs6hbbhmidc4n0m7oq:4,keep:[1,3],kef21pgguqpf14gkgfwx3sv4bjc1vbrrwq6zlg3nmuyqr5mtjjy9eq:3,kei:[0,1,2,3,5],key_as_byt:0,keybio:0,keyfil:[0,1],keygen_callback:0,keyid:[3,4],keylen:0,keyout:3,keypair:0,kilroi:0,kind:1,kiy8jkpv8dr5po1ikaxjfudbygdenjwybsrspsk3p:3,kkst1mcj:3,know:4,known:5,kozihvcnaqebbqaegyblzlgupfphwhsgtiapvdexn61qisz3oem88xoxkuw0szor:4,kozihvcnaqebbqaegycbaxz:4,ktgtcixjl2nmw7j:3,kv95ymtgbisuwkj93grbvqoj:4,kwarg:0,kxtbbmqswcqydvqqg:4,l5trm4x6zjxwuxxmijcehmmd8tc8ybwwo4ao19b3ebffetvsugxsga:3,l6kn27mwzhe331vjttjsgl4:3,lamy57gkw4ondmrtqvq2ojqlvosbllpxzh:4,last:[0,1,3,4,5],later:[0,1],latter:1,lbow6ssdir6:4,lead:[0,1],leak:0,least:1,leav:[3,4],left:[3,4],legal:0,len:0,length:[0,1,2],less:0,let:[3,4,5],letter:[1,3,4],level:[1,2],lg4q5yezr1ejaw:4,librari:[1,4],licenc:0,licens:0,lifetim:1,like:[0,3,4],limit:0,line:[0,4,5],link:[2,5],linux:5,list:[0,1,2],listen:1,listenssl:1,listentcp:1,literatur:0,littl:[2,5],ljecgc3rqu1uwisbkmquis1s46ebbm5np75izpnujokj2hv:4,lkmac1dwb3dqgjt5xk4wjesinfdxecnegacyteagyztpiapu:3,lnzqowadmol:4,load:[0,1,2,4,5],load_cert:[0,1,4],load_cert_bio:0,load_cert_chain:1,load_cert_der_str:0,load_cert_str:0,load_certif:0,load_client_ca:1,load_crl:0,load_dynam:0,load_dynamic_engin:0,load_fil:[0,4],load_info:[0,4],load_kei:[0,4],load_key_bio:0,load_key_bio_pubkei:0,load_key_str:0,load_key_string_pubkei:0,load_loc:0,load_openssl:0,load_param:0,load_params_bio:0,load_pkcs7:0,load_pkcs7_bio:0,load_pkcs7_bio_d:0,load_pkcs7_der:0,load_private_kei:0,load_pub_kei:0,load_pub_key_bio:0,load_public_kei:0,load_request:0,load_request_bio:0,load_request_der_str:0,load_request_str:0,load_sess:1,load_verify_info:1,load_verify_loc:[1,5],loc:0,local:[2,3,4],localhost:[2,3,4],localitynam:0,localtimezon:0,locat:[1,2],lock:4,logger:2,logic:1,longer:0,look:[3,4],loseconnect:1,lower:0,ltd:[3,4],lwpbxzf2k3fuudnkrlfbakeampxoybuifr2s5bma:3,ly4tpl5:3,m1awhen3vir2zlaw:3,m1je:3,m2_asn1_integer_fre:0,m2_asn1_object_fre:0,m2_asn1_string_fre:0,m2_asn1_time_fre:0,m2_bio_fre:[0,1],m2_bio_noclos:1,m2_bio_pop:0,m2_cipher_ctx_fre:0,m2_dh_free:0,m2_dsa_fre:0,m2_ec_key_fre:0,m2_engine_fre:0,m2_hmac_ctx_fre:0,m2_md_ctx_free:0,m2_pkcs7_free:0,m2_pkey_fre:0,m2_rsa_fre:0,m2_sk_x509_extension_fre:0,m2_sk_x509_free:0,m2_ssl_ctx_free:1,m2_ssl_free:1,m2_ssl_session_fre:1,m2_x509_crl_free:0,m2_x509_extension_fre:0,m2_x509_free:0,m2_x509_name_entry_fre:0,m2_x509_name_fre:0,m2_x509_req_fre:0,m2_x509_store_ctx_fre:0,m2_x509_store_fre:0,m2crypto:[1,3],m2crypto_xmlrpc:0,m2cryptoerror:0,m2urllib2:6,m2urllib:[2,6],m2xmlrpclib:[2,6],ma0gcsqgsib3dqebbauaa4gbaho3drchr86fstvavfixdsswwqktcehuhrdc:4,mac:0,made:[1,5],mai:[0,1,2,3,4,5],mail:4,maintain:1,make:[0,1,3,4,5],makebuf:4,makecooki:0,makefil:[0,1],malfunct:1,man:1,manag:2,mani:[0,2,4],manipul:[0,1],manpag:[0,1],manual:[0,5],map:[1,4],mar:[3,4],march:4,mark:[0,4],master:3,match:[0,3,4],matej:0,materi:[2,5],matt:5,max_byt:0,maximum:1,mbstring_asc:0,mbstring_utf8:0,md5:0,md5withrsaencrypt:[3,4],mean:0,meant:3,measur:0,medusa:2,memori:[0,4],memorybuff:[0,4],memoryview:1,messag:[0,1,5],message_bodi:0,messagedigest:0,messier:5,method:[0,1],mg611eovkleoostv:3,mh2pz4lverxa:4,mhf6rqar:4,micalg:4,microsec:1,might:1,miibntccaqycaqawxtelmakga1uebhmcu0cxetapbgnvbaotce0yq3j5chrvmriw:3,miibvwyjkozihvcnaqcdoiibsdccauqcaqaxggeamih9ageamgywytelmakga1u:4,miicxgibaakbgqcvwdhjvcuwxwu4h8wqujguvm:3,miie8ayjkozihvcnaqccoiie4tccbn0caqexczajbgurdgmcgguamcigcsqgsib3:4,miiiwwyjkozihvcnaqcdoiiitdccclacaqaxggeamih9ageamgywytelmakga1u:4,mime:[3,5,6],mimetool:0,mind:1,minu:0,miss:1,mix:0,mkwcbi1nfvohcv3xdq2ela:4,mode:[0,1,2,4],model:[3,4],modifi:[0,2,4],modul:[4,5,6],modulu:[0,3,4],more:[0,1,3,5],most:[0,1,4,5],mous:0,movement:0,mozilla:[2,4],mpi:0,mpint:0,mrywfaydvqqdew1tl01jtuugu2vuzgvymsewhwyjkozihvcnaqkbfhjzzw5kzxja:4,msb:0,msg:4,msg_bio:4,mua:4,much:0,multilin:0,multipart:4,multipl:1,multipurpos:4,multivalu:0,must:[0,1,5],mutheybpq5th7ydrtnizkkxobnqe2kyux9x22a1kh49sojjfg6kpb9mugizbimlv:3,mutt:4,mysteri:0,naccept:2,name:[0,1,3,4,5],navig:4,nbbba2yl0n5gs1tyiy9z:3,nbsp:2,nbyte:1,nconnect:2,necessari:0,necessarili:0,need:[0,1,3,4,5],neg:0,negoti:1,neither:1,nerx9zjgvrwuscqqcu:3,net:3,netmemet:5,netscap:3,network:[4,5],new_extens:0,new_pub_kei:0,new_stack_from_d:0,newca:3,newcert:3,newer:0,newkei:[3,4],newkey2:3,newli:0,newreq:3,next:[0,3,4],ngp:[2,3,4,5],nhost:2,nid:0,nihuwgujn:3,niqfytycdl9i5sk:4,nkasxekr8auhjsbvumrqrl6r0nnsfpzdr1w7pv:4,no_passphrase_callback:0,nocertif:1,node:4,non:[0,1,4],noncrit:0,none:[0,1,4],nonzero:0,noout:[3,4],nor:[1,4],normal:[1,5],note:[0,1,4,5],noth:0,notifi:1,notwithstand:4,now:[3,4],nqaodq3aobzpafp9l:3,nqxlmgj3jwq7x9:4,nss:[4,5],ntransfercmd:0,nueymfjdm0uvntg0icxgnufsfnjkntthpagykgetric3kgjz:3,num:0,number:[0,1,3,4],numer:2,numericipmatch:1,nuser:2,nyndufwi0qm92qlk0ui:3,obio:0,object:[0,1,4,5],obtain:[0,4],occur:[0,1],octet:[0,1],octx_to_num:0,od2m3lp7jbwjqbrtndhimqul2s4yu:4,odd:0,off:0,offset:0,oiqto:4,old:[3,5],onc:[0,1],one:[1,2,3],ones:5,onli:[0,1,3],onto:0,open:[0,1,2,4,5],open_http:0,openfil:0,openpgp:4,openssl:[0,1,2,4,5,6],oper:[0,1,2,4],option:[0,1,3],optnam:1,org:[2,3,4,5],organ:[3,4],organiz:[3,4],organizationnam:[0,3],organizationunitnam:0,origin:0,osafound:5,other:[0,1,3,5],otherwis:0,our:4,out:[0,1,2,3,4],out_bio:0,outform:4,output:[0,4],over:[0,1,5],overlap:4,overload:1,overrid:1,overridden:1,overwrit:2,own:[0,1,2,4,6],p12:4,p7_bio:[0,4],p7file:0,p7m:4,p7s:4,pack:1,packag:6,pad:0,page:[1,2,6],pair:[0,1,2,3,4],param:[0,1],paramet:[0,1,2,4,5],part:4,partial:1,pass:[0,1,3],passphras:[0,1,3,4],passphrase_callback:[0,1],password:[0,3,4],patch:[2,3],path:0,pathnam:2,pbkdf2:0,pcgiserv:2,pdlrrliknknfmhkiacktlrcu59sca6adeiwuzqmuzp5cs6jrsro3nkfg1bd09d1k:3,peek_error_cod:0,peer:1,peercertdigest:1,peercerthash:1,pem:[0,1,2,3,4,5],pemfil:1,pend:1,pep484:1,per:[0,1,2],perform:[0,5],period:3,perl:3,permit:5,pfi:3,pfl1k5dyxrgtzlb36uljd:4,pgpmime:4,pheng:[0,1,2,3,4,5],phrase:3,pick:4,pin:0,pk7_smime:4,pkc:4,pkcs12:4,pkcs5_pad:0,pkcs7:[0,4],pkcs7_detach:4,pkcs7_error:0,pkcs7_pad:0,pkcs7_text:4,pkcs7_verifi:4,pkei:0,pkg:[3,4],plain:4,pleas:[1,3],plen:0,pltnni25spyrcwfl6erd25u:4,plu:1,point:0,pointer:0,polici:[1,3,4],pool:0,pop:[0,4],popular:4,port:[0,1,2],portal0:2,portal:2,portion:[0,5],posit:0,possibl:[0,1],post1:[2,3,4],post:0,post_connection_check:1,postconnectioncheck:1,power:2,practic:[0,4,5],pravir:5,predetermin:0,predict:0,prefix:0,premis:4,present:[1,2],press:0,pretend:4,pretti:5,previou:0,previous:1,primari:5,prime:0,princip:0,print:[0,1,2,3,4],print_param:0,printabl:3,privaci:4,privat:[0,1,3,4],private_decrypt:0,private_encrypt:0,privkei:4,prng:[0,2,4],probabl:[1,4,5],problem:0,proc:3,proce:1,process:[1,3,4],produc:0,product:4,prog:4,program:[3,6],programm:[4,5],project:[4,5],prompt1:0,prompt2:0,prompt:4,propag:0,proper:1,properli:4,propertymap:2,prot_c:0,prot_p:0,protect:[0,1,4],protocol:[0,1,2,4,5],protocolwrapp:1,provid:[0,1,2,4,5],provinc:[3,4],proxi:0,proxyhttpsconnect:0,pseudo:[0,4],pss:0,pty:[3,4],pub:0,pub_kei:0,pub_key_from_d:0,pub_key_from_param:0,pubkei:0,public_decrypt:0,public_encrypt:0,purpos:[0,4],push:[0,4],puthead:0,putrequest:0,pyfil:0,pystack:0,python3:1,python:[0,1,3,6],q1z7g:3,q7s4tn1z:4,qbcrdaoxdj0ulwytauev:4,qin7ujpkou61cn7h8dvhr8yw9:4,qjpbezwdp7gjfzfatqitesymwo3i:4,qlen:1,qppdzt3ykfmg2lzytaam1czvb6rbnrjjp2zrpbwn:3,qtm0ddmm:3,quarante:5,queri:1,quiet_genparam_callback:0,quit:[2,3,4],quvxinaxygqco9lzdw6hudk8:4,qya6adywgbghr9jkhwn5gsdu7bwx:4,rais:[0,1,4,5],rand:[2,4,6],rand_add:0,rand_byt:0,rand_file_nam:0,rand_pseudo_byt:0,rand_rang:0,rand_se:0,rand_statu:0,randfil:0,randfnam:0,random:[0,4],randpool:[2,4],rang:0,rather:1,rc4:6,rc4_free:0,rdn:0,reactor:1,read:[0,1,2,3,4,5],read_al:0,readabl:0,readbio:1,readi:[1,3,4],readlin:0,real:0,realiz:1,reason:[0,1],recal:4,receipt:1,receiv:[1,4],recent:4,recipi:4,recipient_kei:4,recommend:[0,1,5],record:5,recreat:4,recv:1,recv_into:1,refcount:[0,1],refer:[0,1,2],regex:0,regular:0,reject:1,relativedistinguishednam:0,releas:0,reli:[0,1],remot:1,remov:1,remove_sess:1,renam:[3,4],render:4,renegoti:1,repli:2,repres:[0,1],represent:0,repudi:4,req:[0,3,4],request:[0,1,3,4],request_bodi:0,requesthandlerclass:1,requir:[0,1,5],rescorla:5,reserv:[0,1],reset:0,reset_context:0,resid:1,resolv:2,respect:[0,1],rest:0,result:[0,1,4],ret:[1,3],retriev:[0,4],reus:1,revoc:0,rfc:[0,4],rgwnkxpj:4,right:[0,1,4],ripemd160:0,rm2htgotm2lmore4geotypi5f1fbi:3,rn9vpy0suy8:3,rnd:0,root:5,routin:[1,4],rsa:[1,2,3,4,5,6],rsa_error:0,rsa_pub:0,rsaencrypt:[3,4],rsaerror:0,rsassa:0,rudimentari:5,run:[0,2,4],rwb:0,rwniyh0aw4xyyhhit:4,s0ovoc041cerazqfm2tl:4,safe:0,sai:4,said:[0,4],salt:0,salt_len:0,salt_length:0,same:[0,1,5],sat:[2,3],save:[0,4],save_fil:[0,4],save_kei:0,save_key_bio:0,save_key_d:0,save_key_der_bio:0,save_param:0,save_params_bio:0,save_pem:0,save_pub_kei:0,save_pub_key_bio:0,saver:4,sc3lsmhugu9xc26ogstjmkquiah:3,sc51hkebgckl1:4,scope:4,scopeid:1,screen:[2,4],script:5,search:6,sec:1,second:[0,1,5],secret:3,section:[3,4],secur:[0,1,3,4],see:[0,1,2,5],seed:[0,2,4],seek:0,seldom:0,select:[1,2,4],self:[0,1,3,4],send:[0,1,2,5],sendal:1,sender:4,sendmail:4,sendsmim:4,sens:1,sent:[0,1,3,4],sequenc:0,seri:4,serial:[0,3,4],serialnumb:0,serv:2,server:[0,1,2,3,4,5],server_address:[1,5],serverpostconnectioncheck:1,servic:[1,4],session:[0,6],session_data_manag:2,set1_host:1,set:[0,1,3,4,5],set_accept_st:1,set_allow_unknown_ca:1,set_bio:1,set_ciph:[0,4],set_cipher_list:1,set_client_ca_list_from_context:1,set_client_ca_list_from_fil:1,set_connect_st:1,set_crit:0,set_data:0,set_datetim:0,set_default:0,set_default_verify_path:1,set_info_callback:1,set_issu:0,set_issuer_nam:0,set_kei:0,set_mod:1,set_not_aft:0,set_not_befor:0,set_object:0,set_opt:1,set_pad:0,set_param:0,set_post_connection_check_callback:1,set_pubkei:0,set_serial_numb:0,set_sess:[0,1],set_session_cache_mod:1,set_session_id_ctx:1,set_session_timeout:1,set_shutdown:1,set_socket_read_timeout:1,set_socket_write_timeout:1,set_ssl:0,set_ssl_close_flag:1,set_str:0,set_subject:0,set_subject_nam:0,set_tim:[0,1],set_timeout:1,set_tlsext_host_nam:1,set_tmp_dh:1,set_tmp_dh_callback:1,set_tmp_rsa:1,set_tmp_rsa_callback:1,set_verifi:[1,5],set_verify_cb:0,set_vers:0,set_x509_stack:[0,4],set_x509_stor:[0,4],setblock:1,setsockopt:1,settimeout:1,setup_addr:1,setup_ssl:1,sever:[0,1,3],sfl_home:4,sfqo6lc9mtsj7fjydq:4,sha1:[0,1,4],sha224:0,sha256:0,sha:0,shall:[2,4],share:0,should:[0,1,3],should_read:0,should_retri:0,should_writ:0,show:0,shown:[2,5],shut:1,shutdown:1,sid_ctx:1,side:[0,1,5],sign:[0,3],sign_asn1:0,sign_dsa:0,sign_dsa_asn1:0,sign_fin:0,sign_init:0,sign_rsassa_pss:0,sign_upd:0,signal:0,signatur:[0,3,4],signer:4,signer_kei:4,signific:[0,1],similar:[1,2,3,4],simpl:[0,1,5],simpli:0,sinc:[0,3,5],singl:0,siong:[0,1,2,3,4,5],sipba4ik5xcrlt9e0s2qjgrvo9gyfaqz:4,site:3,situat:3,size:[0,1],sizehint:0,sjai4kpfvt00xfnvgluywyeks9sygto7hihnqkcf44f5lyv6ntfwmfqb11daty9v:4,skip:4,skip_accept_encod:0,skip_host:0,skunk:2,smartcard:0,smime:6,smime_error:[0,4],smime_load_pkcs7:[0,4],smime_load_pkcs7_bio:[0,4],smtpd:4,smtplib:4,sni:1,sntelhcawulwtifz:4,so_:1,sock:1,socket:[0,1,5],socketserv:1,softwar:4,sol_socket:1,sol_tcp:1,some:[1,3,4],sopath:0,sophist:5,sourc:[0,1,4,5],space:0,specif:[1,3,5],specifi:[0,1],spoofer:4,sport:5,src:2,ssl:[0,2,3,4,6],ssl_:1,ssl_cert_dir:1,ssl_cert_fil:1,ssl_connect:1,ssl_context:[0,1],ssl_ctx:0,ssl_ctx_flush_sess:1,ssl_ctx_ptr:1,ssl_ctx_set_opt:1,ssl_ctx_set_session_cache_mod:1,ssl_ctx_set_timeout:1,ssl_dispatch:[0,6],ssl_get_default_timeout:1,ssl_get_error:1,ssl_info_callback:1,ssl_ptr:1,ssl_received_shutdown:1,ssl_sent_shutdown:1,ssl_sess_cache_:1,ssl_transport:[0,2],ssl_verify_callback:1,ssl_verify_callback_allow_unknown_ca:1,ssl_verify_callback_stub:1,sslbio:0,sslerror:[0,1],sslserver:[0,6],ssltimeouterror:1,sslv3:[1,5],sslverificationerror:1,stack:[0,1],stack_of:1,stamp:4,standard:[0,4],standard_error_messag:2,standard_html_foot:2,standard_html_head:2,standard_templ:2,start:[0,1,2,3,4],startpassthrough:1,starttl:1,state:[0,1,3,4],stateorprovincenam:0,statu:[0,1],stderr:1,stdout:[0,5],step:[3,4,5],steve:3,still:1,stop:[1,2],store:[0,1],str:1,stream:0,strict:0,string:[0,1,2,4],stringio:[4,5],strong:0,struct:1,struct_siz:1,struct_to_timeout:1,structur:[0,1],style:1,subclass:0,subject:[0,3,4],subjectaltnam:[0,5],subjectnam:0,subpackag:6,subsequ:5,substitut:4,succeed:[0,1,2],success:[0,1],successfulli:1,suffici:0,suggest:0,suit:1,suitabl:[0,5],sun:2,suppli:[0,1],support:[0,1,5],suppos:4,sure:0,surnam:0,symbol:1,symmetr:[0,4,5],sync:0,sys:4,system:[1,2,3,4],sztm5jrp2zw:4,t6lqehb32wfyxqbkfxfjsxzsxox3r:4,take:1,target:[0,2,4],tb7k3chfgw5wagwnll8lb:3,tcp:[1,5],tcpserver:1,tell:[0,5],temp_fold:2,temporari:[1,4],termin:1,test:[0,1,4,5],test_ssl:5,text:[0,2,3,4],text_crlf:0,text_crlf_bio:0,text_nam:0,textiowrapp:0,textual:5,than:[0,1,5],thei:[0,1,4,5],them:[0,4,5],therefor:1,thi:[0,1,2,3,4,5],third:5,those:5,thread:6,threadingmixin:1,threadingsslserv:1,threat:[3,4],through:[0,1,3,4],thu:[0,4],thusli:[2,4],time:[0,1,2,4,5],timedelta:0,timeo:1,timeout:[0,6],titl:2,tlfgl4hdk2gyzxafuqzwiurz:4,tls:1,tlsprotocolwrapp:1,tmp:4,tmp_bio:4,to_addr:4,to_cert:4,tob:4,togeth:1,toivonen:[1,5],too:5,tool:3,top:[0,2,4],topic:3,trace:0,traceback:[1,4],traffic:5,transfer:[0,4],transform:4,translat:1,transport:0,treat:1,tri:[1,5],tripl:4,trust:4,tue:2,tunnel:0,tupl:[0,1],tvtk:4,twice:1,twist:[1,5],twistedprotocolwrapp:[0,6],two:[0,1,5],tws5k:3,txt:5,type:[0,1,2,3,4],typic:[1,4,5],tzinfo:0,tzname:0,tzsznk2qwgvsspos9mhuaepbnjmnbffbrulhrutsglm:4,u4dmyq9uxs421en3v2hkvhvdy8ut2ot29:4,u4j2f34u0xktwcp:4,u7rqbwpc9hr34saprs3ubbculet748kecbx247imbtidctzxcc1o86:4,ubowzitegtyli52:4,uifxaf6s4n2uihvp6tqxthejtpzoc7pc:4,ukidkhst60v2q9kegpzgfpoztskm:4,ull4d2cldx9ovynykwdezb5dyv0r:4,unattend:3,uncertainti:0,under:4,under_bio:0,underli:[0,1,5],understand:4,unencrypt:[3,4],uniqu:0,unit:[1,3,4],unix:1,unknow:0,unknown:[0,1],unless:0,unlock:0,unmix3:0,unmix:0,unpack:2,unpredict:0,unsaf:0,unset_ciph:0,unset_kei:0,unset_x509_stack:0,unset_x509_stor:0,until:[1,3],untouch:1,untrust:2,updat:[0,3],upon:1,upper:0,urandom:2,urbfke2mocdxvdzxbmd:4,url:[0,2],urllib:[0,2],uryvak7vfoldaz6z3nosoi6nonnehpr:4,usag:4,use:[0,1,2,3,4,5],used:[0,1,3,4],useful:1,useless:5,user:[0,4],user_ag:0,usernam:0,uses:[0,4,5],using:[0,1,3,4],usr:[3,4],usual:[0,1,5],utc:0,utcoffset:0,utf:0,utifsh4jkkm:4,util:[5,6],utilerror:0,uweuasngtkpjv2jyumd3hwqox2q3cd4zgqvjj6gf3exa5126ckf:3,uwrgu5shra8oncm0cdxej0kpf3cfnjhffb8hwmzi4uegnmfxqnsxogz:4,v_asn1_ia5str:0,valid:[0,1,3,4,5],valu:[0,1,3,4],valueerror:0,variabl:[0,1],variou:[1,5],verbos:0,veri:[0,1],verif:[0,1,4],verifi:[0,1,2,3],verify_asn1:0,verify_dsa:0,verify_dsa_asn1:0,verify_fail_if_no_peer_cert:[1,5],verify_fin:0,verify_init:0,verify_ok:1,verify_p:[1,5],verify_rsassa_pss:0,verify_upd:0,verisign:4,version:[0,1,3,4,5],vhgdittnelgthbaezu5rhdswgdelvbp:4,vi4roin:3,via:[0,1],viega:5,vihhfc1zzp:3,visual:0,vkwwecqqdkeu:3,vsgprqx2:4,vsxc7xx7xo:4,vtajp:3,vuzalydffdfutiqqzys4z:4,w4d1nnwu8agcpyshsexhc:3,w81xodtq2ecjxc8fn2wpa9y5vd1lt7ojksoul1:3,wai:[1,4],wait:1,walk:3,warn:[0,1,2],wbal2p:4,wdd1ar2k4k3gai7kkgobwt0:4,wdigqewjl:3,weak:5,weak_crypto:1,web:[2,4],well:[0,1,2,4],were:[0,1],west:0,what:[0,3,4],when:[0,1,3,4,5],whenev:1,where:[0,1,3],wherea:[0,5],whether:[0,4],which:[0,1,3,4,5],who:4,whose:0,why:4,widgit:[3,4],width:2,window:[2,4],wish:[2,3,4],within:[1,3,5],without:0,wjtpvp0yobmju4vmkezi405r7o8oewi:3,wkat:4,wmbgsclvwsfzcccjhavw9nhfmucnrdwxaymvetnuon:4,won:1,word:4,work:[0,1,2,3,4,5],world:1,would:[0,1,4],wrap:4,wrappedprotocol:1,wrapper:[0,1,5],write:[0,1,3,4],write_bio:1,write_clos:0,write_d:0,writeabl:0,writebio:1,writesequ:1,written:[0,3,5],wrongcertif:1,wronghost:1,wrylp3:4,wsluvo:3,www:[0,2,4],wyhfg8g3biehurpj2v:4,x509:[3,4,5,6],x509_ext:0,x509_ext_ptr:0,x509_extens:0,x509_extension_stack:0,x509_name:[0,1],x509_name_entri:0,x509_ptr:1,x509_purpose_:0,x509_stack:[0,4],x509_store:[0,4],x509_store_context:0,x509_store_ctx:0,x509_store_default_cb:0,x509_store_set_verify_cb:0,x509error:0,x509v3:[3,4],xc9dtimuutxtxlgytb0ujkbnsoaenolm:4,xekaxcmzegp0b6camwfmuqrbvgxbbncqkc:4,xgffb0okilylmwv2bf6:4,xisnot:4,xlcqyvk1tzhd:4,xlyg6hhzzgbfyyngj2y7ymz1rl1m8snrnmkcyskgtrudenf6wt9:4,xmlrpc:0,xmtdg:4,y3klvhk09yl6d:4,y9mh7efw:4,year:[3,4],yet:1,yl9qevh1pp2zvswq12p7gjt3t:4,you:[0,1,2,3,4,5],your:[0,2,4,6],ypfxy:3,yqor8jggsuzroyjqhj:4,yrpzcwq3gxahuj:3,yubj33ylmpjgngijlnolfy0hnw7tmwqr:4,ywmxnjz8:4,z04ovaeue4x0swm17hlbm2kvt:3,z2s:2,z6ebh:3,z6uxrm:4,zbq:3,zbxscvldasmckg:3,zero:0,zhttp_handler:2,zhttp_server:2,zhttps_handler:2,zhttps_server:2,zip:2,zone:0,zope:[2,4],zopebutton:2,zovnycmv1cintpalaw4bwtxnhcdvthavdy34okhemzncg:3,zpecllwhxd4b1auaiaargkl935u:4,zpqqqzkq:3,zserver:2,zserverssl:6,zssl:2,zsyncer:2,ztf6mpxjsixi6l4zyxebs6yhf:4,zw50msqwigyjkozihvcnaqkbfhvyzwnpcgllbnrazxhhbxbszs5kb20caqawdqyj:4,zw5kzxixitafbgkqhkig9w0bcqewennlbmrlckblegftcgxllmrvbtcbnzanbgkq:4,zwxy:4,zxhhbxbszs5kb20whhcnmdewmzmxmte0mdmzwhcnmdiwmzmxmte0mdmzwjbbmqsw:4},titles:["M2Crypto Package","SSL Package","1.&nbsp;&nbsp;&nbsp;ZServerSSL-HOWTO","HOWTO: Creating your own CA with OpenSSL","HOWTO: Programming S/MIME in Python with M2Crypto","HOWTO: Programming SSL in Python with M2Crypto","Welcome to M2Crypto\u2019s documentation!"],titleterms:{The:3,asn1:0,authcooki:0,bio:0,bit:5,callback:0,certif:4,checker:1,cipher:1,code:5,conclus:[2,3],connect:1,content:2,context:1,creat:3,decrypt:4,document:6,dsa:0,encrypt:4,engin:0,err:0,evp:0,ftpslib:0,histori:5,howto:[2,3,4,5,6],http:2,httpslib:0,indic:6,instal:2,interoper:4,introduct:[2,3,4,5],kei:4,m2crypto:[0,2,4,5,6],m2urllib2:0,m2urllib:0,m2xmlrpclib:0,messag:4,messeng:4,microsoft:4,mime:4,modul:[0,1],netscap:4,openssl:3,origin:4,outlook:4,over:2,own:3,packag:[0,1],prepar:2,procedur:3,program:[4,5],python:[2,4,5],rand:0,rc4:0,resourc:4,rsa:0,sampl:5,secur:5,send:4,session:1,sign:4,smime:[0,4],smtp:4,sourc:2,ssl:[1,5],ssl_dispatch:1,ssldump:5,sslserver:1,subpackag:0,tabl:6,test:2,thread:0,timeout:1,twistedprotocolwrapp:1,util:0,verifi:4,via:4,webdav:2,welcom:6,x509:0,xmlrpc:2,your:3,zserverssl:2,zsmime:4}}) \ No newline at end of file
diff --git a/doc/index.rst b/doc/index.rst
new file mode 100644
index 0000000..a472668
--- /dev/null
+++ b/doc/index.rst
@@ -0,0 +1,30 @@
+Welcome to M2Crypto's documentation!
+====================================
+
+Contents:
+
+.. toctree::
+ :maxdepth: 4
+
+ M2Crypto
+
+
+HOWTOs
+======
+
+* :ref:`howto-ca`
+
+* :ref:`howto-ssl`
+
+* :ref:`howto-smime`
+
+* :ref:`zserverssl-howto`
+
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
+
diff --git a/doc/make.bat b/doc/make.bat
new file mode 100644
index 0000000..8c9f7cc
--- /dev/null
+++ b/doc/make.bat
@@ -0,0 +1,190 @@
+@ECHO OFF
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+ set SPHINXBUILD=sphinx-build
+)
+set BUILDDIR=_build
+set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
+set I18NSPHINXOPTS=%SPHINXOPTS% .
+if NOT "%PAPER%" == "" (
+ set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
+ set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
+)
+
+if "%1" == "" goto help
+
+if "%1" == "help" (
+ :help
+ echo.Please use `make ^<target^>` where ^<target^> is one of
+ echo. html to make standalone HTML files
+ echo. dirhtml to make HTML files named index.html in directories
+ echo. singlehtml to make a single large HTML file
+ echo. pickle to make pickle files
+ echo. json to make JSON files
+ echo. htmlhelp to make HTML files and a HTML help project
+ echo. qthelp to make HTML files and a qthelp project
+ echo. devhelp to make HTML files and a Devhelp project
+ echo. epub to make an epub
+ echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
+ echo. text to make text files
+ echo. man to make manual pages
+ echo. texinfo to make Texinfo files
+ echo. gettext to make PO message catalogs
+ echo. changes to make an overview over all changed/added/deprecated items
+ echo. linkcheck to check all external links for integrity
+ echo. doctest to run all doctests embedded in the documentation if enabled
+ goto end
+)
+
+if "%1" == "clean" (
+ for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
+ del /q /s %BUILDDIR%\*
+ goto end
+)
+
+if "%1" == "html" (
+ %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The HTML pages are in %BUILDDIR%/html.
+ goto end
+)
+
+if "%1" == "dirhtml" (
+ %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
+ goto end
+)
+
+if "%1" == "singlehtml" (
+ %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
+ goto end
+)
+
+if "%1" == "pickle" (
+ %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can process the pickle files.
+ goto end
+)
+
+if "%1" == "json" (
+ %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can process the JSON files.
+ goto end
+)
+
+if "%1" == "htmlhelp" (
+ %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can run HTML Help Workshop with the ^
+.hhp project file in %BUILDDIR%/htmlhelp.
+ goto end
+)
+
+if "%1" == "qthelp" (
+ %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can run "qcollectiongenerator" with the ^
+.qhcp project file in %BUILDDIR%/qthelp, like this:
+ echo.^> qcollectiongenerator %BUILDDIR%\qthelp\M2Crypto.qhcp
+ echo.To view the help file:
+ echo.^> assistant -collectionFile %BUILDDIR%\qthelp\M2Crypto.ghc
+ goto end
+)
+
+if "%1" == "devhelp" (
+ %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished.
+ goto end
+)
+
+if "%1" == "epub" (
+ %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The epub file is in %BUILDDIR%/epub.
+ goto end
+)
+
+if "%1" == "latex" (
+ %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
+ goto end
+)
+
+if "%1" == "text" (
+ %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The text files are in %BUILDDIR%/text.
+ goto end
+)
+
+if "%1" == "man" (
+ %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The manual pages are in %BUILDDIR%/man.
+ goto end
+)
+
+if "%1" == "texinfo" (
+ %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
+ goto end
+)
+
+if "%1" == "gettext" (
+ %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
+ goto end
+)
+
+if "%1" == "changes" (
+ %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.The overview file is in %BUILDDIR%/changes.
+ goto end
+)
+
+if "%1" == "linkcheck" (
+ %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Link check complete; look for any errors in the above output ^
+or in %BUILDDIR%/linkcheck/output.txt.
+ goto end
+)
+
+if "%1" == "doctest" (
+ %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Testing of doctests in the sources finished, look at the ^
+results in %BUILDDIR%/doctest/output.txt.
+ goto end
+)
+
+:end
diff --git a/epydoc.conf b/epydoc.conf
index 2afa556..d2c1826 100644
--- a/epydoc.conf
+++ b/epydoc.conf
@@ -18,9 +18,6 @@ exclude-introspect = M2Crypto.__m2crypto
# Variable shadows module, which causes the module to double in the doc
# with second instance showing '. Exclude so we only get one (with ').
-exclude = M2Crypto.PGP.PublicKey
-exclude = M2Crypto.PGP.PublicKeyRing
-exclude = M2Crypto.PGP.packet
exclude = M2Crypto.SSL.Cipher
exclude = M2Crypto.SSL.Connection
exclude = M2Crypto.SSL.Context
diff --git a/fedora_setup.sh b/fedora_setup.sh
deleted file mode 100755
index 76d1f59..0000000
--- a/fedora_setup.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/sh
-# This script is meant to work around the differences on Fedora Core-based
-# distributions (Redhat, CentOS, ...) compared to other common Linux
-# distributions.
-#
-# Usage: ./fedora_setup.sh [setup.py options]
-#
-
-arch=`uname -m`
-for i in SWIG/_{ec,evp}.i; do
- sed -i -e "s/opensslconf\./opensslconf-${arch}\./" "$i"
-done
-
-SWIG_FEATURES=-cpperraswarn python setup.py $*
-
diff --git a/pack.py b/pack.py
deleted file mode 100644
index 0005026..0000000
--- a/pack.py
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/usr/bin/env python
-
-# Clean up M2Crypto source base.
-
-import glob, os, os.path, sys
-
-def zap(arg, dirname, names):
- for f in glob.glob(dirname + arg):
- try:
- os.remove(f)
- except:
- pass
-
-if __name__ == "__main__":
- start = sys.argv[1]
-
- os.path.walk(start, zap, "/*.pyc")
-
- if os.name == 'nt':
- zap_m2 = ("__m2cryptoc.pyd","_m2crypto.py")
- elif os.name == 'posix':
- zap_m2 = ("__m2crypto.so","_m2crypto.py")
- for x in zap_m2:
- try:
- os.remove("%s/M2Crypto/%s" % (start, x))
- except:
- pass
-
- zap_swig = ("_m2crypto_wrap*", "_m2crypto.c", "_m2crypto.py", "vc60.pdb")
- for x in zap_swig:
- for z in glob.glob("%s/SWIG/%s" % (start, x)):
- try:
- os.remove(z)
- except:
- pass
-
-
diff --git a/packaging/python-M2Crypto.spec b/packaging/python-M2Crypto.spec
index f8aa0f3..f77bcf0 100644
--- a/packaging/python-M2Crypto.spec
+++ b/packaging/python-M2Crypto.spec
@@ -13,7 +13,7 @@
# published by the Open Source Initiative.
Name: python-M2Crypto
-Version: 0.21.1
+Version: 0.35.1.1
Release: 0
Url: http://chandlerproject.org/bin/view/Projects/MeTooCrypto
Summary: Crypto and SSL toolkit for Python
diff --git a/pylintrc b/pylintrc
new file mode 100644
index 0000000..0f2393b
--- /dev/null
+++ b/pylintrc
@@ -0,0 +1,272 @@
+# -*- coding: utf-8; mode: conf -*-
+# lint Python modules using external checkers.
+#
+# This is the main checker controlling the other ones and the reports
+# generation. It is itself both a raw checker and an astng checker in order
+# to:
+# * handle message activation / deactivation at the module level
+# * handle some basic but necessary stats'data (number of classes, methods...)
+#
+[MASTER]
+
+# Specify a configuration file.
+#rcfile=
+
+# Python code to execute, usually for sys.path manipulation such as
+# pygtk.require().
+#init-hook=
+
+# Add <file or directory> to the black list. It should be a base name, not a
+# path. You may set this option multiple times.
+ignore=CVS, .git, .svn
+
+# Pickle collected data for later comparisons.
+persistent=yes
+
+# Set the cache size for astng objects.
+cache-size=500
+
+# List of plugins (as comma separated values of python modules names) to load,
+# usually to register additional checkers.
+load-plugins=
+
+[MESSAGES CONTROL]
+
+# Enable the message, report, category or checker with the given id(s). You can
+# either give multiple identifier separated by comma (,) or put this option
+# multiple time. See also the "--disable" option for examples.
+#enable=
+
+# Disable the message, report, category or checker with the given id(s). You
+# can either give multiple identifiers separated by comma (,) or put this
+# option multiple times (only on the command line, not in the configuration
+# file where it should appear only once).You can also use "--disable=all" to
+# disable everything first and then reenable specific checks. For example, if
+# you want to run only the similarities checker, you can use "--disable=all
+# --enable=similarities". If you want to run only the classes checker, but have
+# no Warning level messages displayed, use"--disable=all --enable=classes
+# --disable=W"
+disable=C0330, C0103, C0111, C0326, R0901, R0903, R0201, I0011
+
+
+[REPORTS]
+
+# Set the output format. Available formats are text, parseable, colorized, msvs
+# (visual studio) and html. You can also give a reporter class, eg
+# mypackage.mymodule.MyReporterClass.
+output-format=text
+
+# Put messages in a separate file for each module / package specified on the
+# command line instead of printing them on stdout. Reports (if any) will be
+# written in a file name "pylint_global.[txt|html]".
+files-output=no
+
+# Tells whether to display a full report or only the messages
+reports=yes
+
+# Python expression which should return a note less than 10 (10 is the highest
+# note). You have access to the variables errors warning, statement which
+# respectively contain the number of errors / warnings messages and the total
+# number of statements analyzed. This is used by the global evaluation report
+# (RP0004).
+evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
+
+# Template used to display messages. This is a python new-style format string
+# used to format the message information. See doc for all details
+msg-template={path}:{line}:[{msg_id}({symbol}),{obj}] {msg}
+
+
+[TYPECHECK]
+
+# Tells whether missing members accessed in mixin class should be ignored. A
+# mixin class is detected if its name ends with "mixin" (case insensitive).
+ignore-mixin-members=yes
+
+# List of classes names for which member attributes should not be checked
+# (useful for classes with attributes dynamically set).
+ignored-classes=SQLObject
+
+# List of members which are set dynamically and missed by pylint inference
+# system, and so shouldn't trigger E0201 when accessed. Python regular
+# expressions are accepted.
+generated-members=REQUEST,acl_users,aq_parent
+
+
+[VARIABLES]
+
+# Tells whether we should check for unused import in __init__ files.
+init-import=no
+
+# A regular expression matching the beginning of the name of dummy variables
+# (i.e. not used).
+dummy-variables-rgx=_|dummy
+
+# List of additional names supposed to be defined in builtins. Remember that
+# you should avoid to define new builtins when possible.
+additional-builtins=
+
+
+[FORMAT]
+
+# Maximum number of characters on a single line.
+max-line-length=120
+
+# Regexp for a line that is allowed to be longer than the limit.
+ignore-long-lines=^\s*(# )?<?https?://\S+>?$
+
+# Allow the body of an if to be on the same line as the test if there is no
+# else.
+single-line-if-stmt=no
+
+# List of optional constructs for which whitespace checking is disabled
+no-space-check=trailing-comma,dict-separator
+
+# Maximum number of lines in a module
+max-module-lines=2000
+
+# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
+# tab).
+indent-string=' '
+
+
+[BASIC]
+
+# List of builtins function names that should not be used, separated by a comma
+bad-functions=map,filter,apply,input
+
+# Regular expression which should only match correct module names
+# module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
+module-rgx=(([a-z_][a-z0-9_]*)|([a-zA-Z0-9]+))$
+
+# Regular expression which should only match correct module level names
+const-rgx=[f]?[A-Z_][a-zA-Z0-9_]{2,30}$
+
+# Regular expression which should only match correct class names
+class-rgx=[A-Z_]+[a-zA-Z0-9]+$
+
+# Regular expression which should only match correct function names
+function-rgx=[a-z_][a-zA-Z0-9_]{2,30}$
+
+# Regular expression which should only match correct method names
+method-rgx=[a-zA-Z0-9_]{2,30}$
+
+# Regular expression which should only match correct instance attribute names
+attr-rgx=([a-z_][a-zA-Z0-9_]{2,30}|[A-Z0-9_]{2,30})$
+
+# Regular expression which should only match correct argument names
+argument-rgx=[a-z_][a-zA-Z0-9_]{2,30}$
+
+# Regular expression which should only match correct variable names
+variable-rgx=[a-z_][a-zA-Z0-9_]{0,30}$
+
+# Regular expression which should only match correct attribute names in class
+# bodies
+class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
+
+# Regular expression which should only match correct list comprehension /
+# generator expression variable names
+inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$
+
+# Good variable names which should always be accepted, separated by a comma
+good-names=i,j,k,ex,Run,_
+
+# Bad variable names which should always be refused, separated by a comma
+bad-names=foo,bar,baz,toto,tutu,tata
+
+# Regular expression which should only match function or class names that do
+# not require a docstring.
+no-docstring-rgx=__.*__
+
+# Minimum line length for functions/classes that require docstrings, shorter
+# ones are exempt.
+docstring-min-length=-1
+
+
+[MISCELLANEOUS]
+
+# List of note tags to take in consideration, separated by a comma.
+notes=FIXME,XXX,TODO
+
+
+[SIMILARITIES]
+
+# Minimum lines number of a similarity.
+min-similarity-lines=4
+
+# Ignore comments when computing similarities.
+ignore-comments=yes
+
+# Ignore docstrings when computing similarities.
+ignore-docstrings=yes
+
+# Ignore imports when computing similarities.
+ignore-imports=no
+
+
+[CLASSES]
+
+# List of method names used to declare (i.e. assign) instance attributes.
+defining-attr-methods=__init__,__new__,setUp
+
+# List of valid names for the first argument in a class method.
+valid-classmethod-first-arg=cls
+
+# List of valid names for the first argument in a metaclass class method.
+valid-metaclass-classmethod-first-arg=mcs
+
+
+[DESIGN]
+
+# Maximum number of arguments for function / method
+max-args=8
+
+# Argument names that match this expression will be ignored. Default to name
+# with leading underscore
+ignored-argument-names=_.*
+
+# Maximum number of locals for function / method body
+max-locals=15
+
+# Maximum number of return / yield for function / method body
+max-returns=6
+
+# Maximum number of branch for function / method body
+max-branches=12
+
+# Maximum number of statements in function / method body
+max-statements=50
+
+# Maximum number of parents for a class (see R0901).
+max-parents=7
+
+# Maximum number of attributes for a class (see R0902).
+max-attributes=50
+
+# Minimum number of public methods for a class (see R0903).
+min-public-methods=2
+
+# Maximum number of public methods for a class (see R0904).
+max-public-methods=100
+
+[IMPORTS]
+
+# Deprecated modules which should not be used, separated by a comma
+deprecated-modules=regsub,string,TERMIOS,Bastion,rexec
+
+# Create a graph of every (i.e. internal and external) dependencies in the
+# given file (report RP0402 must not be disabled)
+import-graph=
+
+# Create a graph of external dependencies in the given file (report RP0402 must
+# not be disabled)
+ext-import-graph=
+
+# Create a graph of internal dependencies in the given file (report RP0402 must
+# not be disabled)
+int-import-graph=
+
+[EXCEPTIONS]
+
+# Exceptions that will emit a warning when being caught. Defaults to
+# "Exception"
+overgeneral-exceptions=Exception
diff --git a/setup.cfg b/setup.cfg
index 861a9f5..a21020e 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,5 +1,10 @@
[egg_info]
-tag_build =
-tag_date = 0
+tag_build =
tag_svn_revision = 0
+[flake8]
+; ignore = E402,E501,E731,N806,N803,N802,E265
+ignore = E402,N806,N803,N802,E501
+
+[pydocstyle]
+ignore = D10,D203,D213
diff --git a/setup.py b/setup.py
index e7c49eb..d503577 100644
--- a/setup.py
+++ b/setup.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
-Distutils/setuptools installer for M2Crypto.
+setuptools based installer for M2Crypto.
Copyright (c) 1999-2004, Ng Pheng Siong. All rights reserved.
@@ -9,160 +9,388 @@ Portions created by Open Source Applications Foundation (OSAF) are
Copyright (C) 2004-2007 OSAF. All Rights Reserved.
Copyright 2008-2011 Heikki Toivonen. All rights reserved.
+
+Copyright 2018 Daniel Wozniak. All rights reserved.
"""
+import glob
+import logging
+import os
+import platform
+import re
+import shlex
+import shutil
+import string
+import subprocess
+import sys
+
+from distutils.command import build, sdist
+from distutils.command.clean import clean
+from distutils.dir_util import mkpath
+from distutils.version import StrictVersion
+
+import setuptools
+from setuptools.command import build_ext
+
+logging.basicConfig(format='%(levelname)s:%(funcName)s:%(message)s',
+ stream=sys.stdout, level=logging.INFO)
+log = logging.getLogger('setup')
+
+REQUIRED_SWIG_VERSION = '2.0.4'
+
+if (2, 6) < sys.version_info[:2] < (3, 5):
+ requires_list = ['typing']
+else:
+ requires_list = []
+package_data = {}
+if sys.platform == 'win32':
+ package_data.update(M2Crypto=["*.dll"])
+
+
+def _get_additional_includes():
+ if os.name == 'nt':
+ globmask = os.path.join('C:', os.sep, 'Program Files*',
+ '*Visual*', 'VC', 'include')
+ err = glob.glob(globmask)
+ else:
+ cpp = shlex.split(os.environ.get('CPP', 'cpp'))
+ pid = subprocess.Popen(cpp + ['-Wp,-v', '-'],
+ stdin=open(os.devnull, 'r'),
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ _, err = pid.communicate()
+ err = [line.lstrip() for line in err.decode('utf8').split('\n')
+ if line and line.startswith(' /')]
+
+ log.debug('additional includes:\n%s', err)
+ return err
+
+
+def openssl_version(ossldir, req_ver, required=False):
+ # type: (str, int, bool) -> bool
+ """
+ Compare version of the installed OpenSSL with the maximum required version.
+
+ :param ossldir: the directory where OpenSSL is installed
+ :param req_ver: required version as integer (e.g. 0x10100000)
+ :param required: whether we want bigger-or-equal or less-than
+ :return: Boolean indicating whether the satisfying version of
+ OpenSSL has been installed.
+ """
+ ver = None
+ file = os.path.join(ossldir, 'include', 'openssl', 'opensslv.h')
+
+ with open(file) as origin_file:
+ for line in origin_file:
+ m = re.match(r'^# *define *OPENSSL_VERSION_NUMBER *(0x[0-9a-fA-F]*)', line)
+ if m:
+ log.debug('found version number: %s\n' % m.group(1))
+ ver = int(m.group(1), base=16)
+ break
+
+ if ver is None:
+ raise OSError('Unknown format of file %s\n' % file)
+
+ if required:
+ return ver >= req_ver
+ else:
+ return ver < req_ver
-import os, sys
-try:
- from setuptools import setup
- from setuptools.command import build_ext
-except ImportError:
- from distutils.core import setup
- from distutils.command import build_ext
-from distutils.core import Extension
+class _M2CryptoBuild(build.build):
+ """Enable swig_opts to inherit any include_dirs settings made elsewhere."""
+
+ user_options = build.build.user_options + \
+ [('openssl=', 'o', 'Prefix for openssl installation location')] + \
+ [('bundledlls', 'b', 'Bundle DLLs (win32 only)')]
+
+ def initialize_options(self):
+ """Overload to enable custom openssl settings to be picked up."""
+ build.build.initialize_options(self)
+ self.openssl = None
+ self.bundledlls = None
class _M2CryptoBuildExt(build_ext.build_ext):
- '''Specialization of build_ext to enable swig_opts to inherit any
- include_dirs settings made at the command line or in a setup.cfg file'''
+ """Enable swig_opts to inherit any include_dirs settings made elsewhere."""
+
user_options = build_ext.build_ext.user_options + \
- [('openssl=', 'o', 'Prefix for openssl installation location')]
+ [('openssl=', 'o', 'Prefix for openssl installation location')] + \
+ [('bundledlls', 'b', 'Bundle DLLs (win32 only)')]
def initialize_options(self):
- '''Overload to enable custom openssl settings to be picked up'''
-
+ """Overload to enable custom openssl settings to be picked up."""
build_ext.build_ext.initialize_options(self)
-
- # openssl is the attribute corresponding to openssl directory prefix
- # command line option
- if os.name == 'nt':
- self.libraries = ['ssleay32', 'libeay32']
- self.openssl = 'c:\\pkg'
- else:
- self.libraries = ['ssl', 'crypto']
- self.openssl = '/usr'
-
-
- def finalize_options(self):
- '''Overloaded build_ext implementation to append custom openssl
- include file and library linking options'''
+ self.openssl = None
+ self.bundledlls = None
+ def finalize_options(self):
+ # type: (None) -> None
+ """Append custom openssl include file and library linking options."""
build_ext.build_ext.finalize_options(self)
+ self.openssl_default = None
+ self.set_undefined_options('build', ('openssl', 'openssl'))
+ if self.openssl is None:
+ self.openssl = self.openssl_default
+ self.set_undefined_options('build', ('bundledlls', 'bundledlls'))
+
+ self.libraries = ['ssl', 'crypto']
+ if sys.platform == 'win32':
+ self.libraries = ['ssleay32', 'libeay32']
+ if self.openssl and openssl_version(self.openssl, 0x10100000, True):
+ self.libraries = ['libssl', 'libcrypto']
+ self.swig_opts.append('-D_WIN32')
+ # Swig doesn't know the version of MSVC, which causes errors in e_os2.h
+ # trying to import stdint.h. Since python 2.7 is intimately tied to
+ # MSVC 2008, it's harmless for now to define this. Will come back to
+ # this shortly to come up with a better fix.
+ self.swig_opts.append('-D_MSC_VER=1500')
+
+
+ if sys.version_info[:1] >= (3,):
+ self.swig_opts.append('-py3')
+
+ log.debug('self.include_dirs = %s', self.include_dirs)
+ log.debug('self.library_dirs = %s', self.library_dirs)
- opensslIncludeDir = os.path.join(self.openssl, 'include')
- opensslLibraryDir = os.path.join(self.openssl, 'lib')
-
- self.swig_opts = ['-I%s' % i for i in self.include_dirs + \
- [opensslIncludeDir]]
+ if self.openssl is not None:
+ log.debug('self.openssl = %s', self.openssl)
+ openssl_library_dir = os.path.join(self.openssl, 'lib')
+ openssl_include_dir = os.path.join(self.openssl, 'include')
+
+ self.library_dirs.append(openssl_library_dir)
+ self.include_dirs.append(openssl_include_dir)
+
+ log.debug('self.include_dirs = %s', self.include_dirs)
+ log.debug('self.library_dirs = %s', self.library_dirs)
+
+ if platform.system() == "Linux":
+ # For RedHat-based distros, the '-D__{arch}__' option for
+ # Swig needs to be normalized, particularly on i386.
+ mach = platform.machine().lower()
+ if mach in ('i386', 'i486', 'i586', 'i686'):
+ arch = '__i386__'
+ elif mach in ('ppc64', 'powerpc64', 'ppc64le', 'ppc64el'):
+ arch = '__powerpc64__'
+ elif mach in ('ppc', 'powerpc'):
+ arch = '__powerpc__'
+ else:
+ arch = '__%s__' % mach
+ self.swig_opts.append('-D%s' % arch)
+ if mach in ('ppc64le', 'ppc64el'):
+ self.swig_opts.append('-D_CALL_ELF=2')
+
+ self.swig_opts.extend(['-I%s' % i for i in self.include_dirs])
+
+ # Some Linux distributor has added the following line in
+ # /usr/include/openssl/opensslconf.h:
+ #
+ # #include "openssl-x85_64.h"
+ #
+ # This is fine with C compilers, because they are smart enough to
+ # handle 'local inclusion' correctly. Swig, on the other hand, is
+ # not as smart, and needs to be told where to find this file...
+ #
+ # Note that this is risky workaround, since it takes away the
+ # namespace that OpenSSL uses. If someone else has similarly
+ # named header files in /usr/include, there will be clashes.
+ if self.openssl is None:
+ self.swig_opts.append('-I/usr/include/openssl')
+ else:
+ self.swig_opts.append('-I' + os.path.join(openssl_include_dir, 'openssl'))
+
+ # swig seems to need the default header file directories
+ self.swig_opts.extend(['-I%s' % i for i in _get_additional_includes()])
self.swig_opts.append('-includeall')
- #self.swig_opts.append('-D__i386__') # Uncomment for early OpenSSL 0.9.7 versions, or on Fedora Core if build fails
- #self.swig_opts.append('-DOPENSSL_NO_EC') # Try uncommenting if you can't build with EC disabled
-
- self.include_dirs += [os.path.join(self.openssl, opensslIncludeDir),
- os.path.join(os.getcwd(), 'SWIG')]
-
- if sys.platform == 'cygwin':
+ self.swig_opts.append('-modern')
+ self.swig_opts.append('-builtin')
+
+ # These two lines are a workaround for
+ # http://bugs.python.org/issue2624 , hard-coding that we are only
+ # building a single extension with a known path; a proper patch to
+ # distutils would be in the run phase, when extension name and path are
+ # known.
+ self.swig_opts.extend(['-outdir',
+ os.path.join(os.getcwd(), 'M2Crypto')])
+ self.include_dirs.append(os.path.join(os.getcwd(), 'SWIG'))
+
+ if sys.platform == 'cygwin' and self.openssl is not None:
# Cygwin SHOULD work (there's code in distutils), but
# if one first starts a Windows command prompt, then bash,
# the distutils code does not seem to work. If you start
# Cygwin directly, then it would work even without this change.
# Someday distutils will be fixed and this won't be needed.
self.library_dirs += [os.path.join(self.openssl, 'bin')]
-
- self.library_dirs += [os.path.join(self.openssl, opensslLibraryDir)]
+ mkpath(os.path.join(self.build_lib, 'M2Crypto'))
-if sys.version_info < (2,4):
+ def run(self):
+ """
+ On Win32 platforms include the openssl dll's in the binary packages
+ """
- # This copy of swig_sources is from Python 2.2.
+ # Win32 bdist builds must use --openssl in the builds step.
+ if not self.bundledlls:
+ build_ext.build_ext.run(self)
+ return
- def swig_sources (self, sources):
+ if sys.platform == 'win32':
+ ver_part = ''
+ if self.openssl and openssl_version(self.openssl, 0x10100000, True):
+ ver_part += '-1_1'
+ if sys.maxsize > 2**32:
+ ver_part += '-x64'
+ search = list(self.library_dirs)
+ if self.openssl:
+ search = search + [self.openssl, os.path.join(self.openssl, 'bin')]
+ libs = list(self.libraries)
+ for libname in list(libs):
+ for search_path in search:
+ dll_name = '{0}{1}.dll'.format(libname, ver_part)
+ dll_path = os.path.join(search_path, dll_name)
+ if os.path.exists(dll_path):
+ shutil.copy(dll_path, 'M2Crypto')
+ libs.remove(libname)
+ break
+ if libs:
+ raise Exception("Libs not found {}".format(','.join(libs)))
+ build_ext.build_ext.run(self)
- """Walk the list of source files in 'sources', looking for SWIG
- interface (.i) files. Run SWIG on all that are found, and
- return a modified 'sources' list with SWIG source files replaced
- by the generated C (or C++) files.
- """
- new_sources = []
- swig_sources = []
- swig_targets = {}
+def swig_version(req_ver):
+ # type: (str) -> bool
+ """
+ Compare version of the swig with the required version.
- # XXX this drops generated C/C++ files into the source tree, which
- # is fine for developers who want to distribute the generated
- # source -- but there should be an option to put SWIG output in
- # the temp dir.
+ :param req_ver: required version as a str (e.g., '2.0.4')
+ :return: Boolean indicating whether the satisfying version of swig
+ has been installed.
+ """
+ ver_str = None
+ IND_VER_LINE = 'SWIG Version '
- if self.swig_cpp:
- target_ext = '.cpp'
- else:
- target_ext = '.c'
-
- for source in sources:
- (base, ext) = os.path.splitext(source)
- if ext == ".i": # SWIG interface file
- new_sources.append(base + target_ext)
- swig_sources.append(source)
- swig_targets[source] = new_sources[-1]
- else:
- new_sources.append(source)
+ try:
+ pid = subprocess.Popen(['swig', '-version'], stdout=subprocess.PIPE)
+ except OSError:
+ return False
+
+ out, _ = pid.communicate()
+ if hasattr(out, 'decode'):
+ out = out.decode('utf8')
+
+ for line in out.split('\n'):
+ line = line.strip()
+ if line.startswith(IND_VER_LINE):
+ ver_str = line.strip()[len(IND_VER_LINE):]
+ break
+
+ if not ver_str:
+ raise OSError('Unknown format of swig -version output:\n%s' % out)
+
+ return StrictVersion(ver_str) >= StrictVersion(req_ver)
+
+
+x_comp_args = set()
- if not swig_sources:
- return new_sources
+# We take care of deprecated functions in OpenSSL with our code, no need
+# to spam compiler output with it.
+if sys.platform == 'win32':
+ x_comp_args.update(['-DTHREADING', '-D_CRT_SECURE_NO_WARNINGS'])
+else:
+ x_comp_args.update(['-DTHREADING', '-Wno-deprecated-declarations'])
- swig = self.find_swig()
- swig_cmd = [swig, "-python", "-ISWIG"]
- if self.swig_cpp:
- swig_cmd.append("-c++")
+# Don't try to run swig on the ancient platforms
+if swig_version(REQUIRED_SWIG_VERSION):
+ lib_sources = ['SWIG/_m2crypto.i']
+else:
+ lib_sources = ['SWIG/_m2crypto_wrap.c']
- swig_cmd += self.swig_opts
- for source in swig_sources:
- target = swig_targets[source]
- self.announce("swigging %s to %s" % (source, target))
- self.spawn(swig_cmd + ["-o", target, source])
+m2crypto = setuptools.Extension(name='M2Crypto._m2crypto',
+ sources=lib_sources,
+ extra_compile_args=list(x_comp_args),
+ # Uncomment to build Universal Mac binaries
+ # extra_link_args =
+ # ['-Wl,-search_paths_first'],
+ )
- return new_sources
-
- build_ext.build_ext.swig_sources = swig_sources
+class Clean(clean):
+ def __init__(self, dist):
+ clean.__init__(self, dist)
-m2crypto = Extension(name = 'M2Crypto.__m2crypto',
- sources = ['SWIG/_m2crypto.i'],
- extra_compile_args = ['-DTHREADING'],
- #extra_link_args = ['-Wl,-search_paths_first'], # Uncomment to build Universal Mac binaries
- )
+ def initialize_options(self):
+ clean.initialize_options(self)
+ self.all = True
+
+ def finalize_options(self):
+ clean.finalize_options(self)
+
+ def run(self):
+ clean.run(self)
+ garbage_list = [
+ os.path.join('M2Crypto', '*.so'),
+ os.path.join('M2Crypto', '*.pyd'),
+ os.path.join('M2Crypto', '*.dll')
+ ]
+ for p in garbage_list:
+ for f in glob.glob(p):
+ if os.path.exists(f):
+ os.unlink(f)
-setup(name = 'M2Crypto',
- version = '0.21.1',
- description = 'M2Crypto: A Python crypto and SSL toolkit',
- long_description = '''\
+def __get_version(): # noqa
+ with open('M2Crypto/__init__.py') as init_file:
+ for line in init_file:
+ if line.startswith('__version__ ='):
+ return line.split('=')[1].strip(string.whitespace + "'")
+
+
+long_description_text = '''\
M2Crypto is the most complete Python wrapper for OpenSSL featuring RSA, DSA,
DH, EC, HMACs, message digests, symmetric ciphers (including AES); SSL
functionality to implement clients and servers; HTTPS extensions to Python's
httplib, urllib, and xmlrpclib; unforgeable HMAC'ing AuthCookies for web
-session management; FTP/TLS client and server; S/MIME; ZServerSSL: A HTTPS
-server for Zope and ZSmime: An S/MIME messenger for Zope. M2Crypto can also be
-used to provide SSL for Twisted.''',
- license = 'BSD-style license',
- platforms = ['any'],
- author = 'Ng Pheng Siong',
- author_email = 'ngps at sandbox rulemaker net',
- maintainer = 'Heikki Toivonen',
- maintainer_email = 'heikki@osafoundation.org',
- url = 'http://chandlerproject.org/Projects/MeTooCrypto',
- packages = ['M2Crypto', 'M2Crypto.SSL', 'M2Crypto.PGP'],
- classifiers = [
- 'Development Status :: 5 - Production/Stable',
- 'Intended Audience :: Developers',
- 'Operating System :: OS Independent',
- 'Programming Language :: C',
- 'Programming Language :: Python',
- 'Topic :: Security :: Cryptography',
- 'Topic :: Software Development :: Libraries :: Python Modules',
- ],
-
- ext_modules = [m2crypto],
- test_suite='tests.alltests.suite',
- cmdclass = {'build_ext': _M2CryptoBuildExt}
- )
+session management; FTP/TLS client and server; S/MIME; M2Crypto can also be
+used to provide SSL for Twisted. Smartcards supported through the Engine
+interface.'''
+
+setuptools.setup(
+ name='M2Crypto',
+ version=__get_version(),
+ description='M2Crypto: A Python crypto and SSL toolkit',
+ long_description=long_description_text,
+ license='MIT',
+ platforms=['any'],
+ author='Ng Pheng Siong',
+ author_email='ngps@sandbox.rulemaker.net',
+ maintainer='Matej Cepl',
+ maintainer_email='mcepl@cepl.eu',
+ url='https://gitlab.com/m2crypto/m2crypto',
+ classifiers=[
+ 'Development Status :: 5 - Production/Stable',
+ 'Intended Audience :: Developers',
+ 'License :: OSI Approved :: MIT License',
+ 'Operating System :: OS Independent',
+ 'Programming Language :: C',
+ 'Programming Language :: Python',
+ 'Topic :: Security :: Cryptography',
+ 'Topic :: Software Development :: Libraries :: Python Modules',
+ 'Programming Language :: Python :: 2',
+ 'Programming Language :: Python :: 2.6',
+ 'Programming Language :: Python :: 2.7',
+ 'Programming Language :: Python :: 3',
+ 'Programming Language :: Python :: 3.5',
+ 'Programming Language :: Python :: 3.6',
+ 'Programming Language :: Python :: 3.7',
+ ],
+ keywords='cryptography openssl',
+ packages=setuptools.find_packages(exclude=['contrib', 'docs', 'tests']),
+ ext_modules=[m2crypto],
+ test_suite='tests.alltests.suite',
+ install_requires=requires_list,
+ package_data=package_data,
+ cmdclass={
+ 'build_ext': _M2CryptoBuildExt,
+ 'build': _M2CryptoBuild,
+ 'clean': Clean
+ }
+)
diff --git a/tests/__init__.py b/tests/__init__.py
index e69de29..688264f 100644
--- a/tests/__init__.py
+++ b/tests/__init__.py
@@ -0,0 +1,16 @@
+import logging
+import os.path
+import sys
+
+if sys.version_info[:2] <= (2, 6):
+ sys.path.insert(0, os.path.join(os.path.abspath(os.path.dirname(__file__)),
+ 'vendor'))
+
+try:
+ import unittest2 as unittest
+except ImportError:
+ import unittest
+
+
+logging.basicConfig(format='%(levelname)s:%(funcName)s:%(message)s',
+ level=logging.DEBUG)
diff --git a/tests/alltests.py b/tests/alltests.py
index b35e58f..141cd88 100644
--- a/tests/alltests.py
+++ b/tests/alltests.py
@@ -1,10 +1,11 @@
-#!/usr/bin/env python
+from __future__ import absolute_import, print_function
+
def suite():
- from M2Crypto import m2
+ from M2Crypto import m2 # noqa
import os
import unittest
-
+
def my_import(name):
# See http://docs.python.org/lib/built-in-funcs.html#l2h-6
components = name.split('.')
@@ -19,6 +20,7 @@ def suite():
return mod
modules_to_test = [
+ 'tests.test_aes',
'tests.test_asn1',
'tests.test_bio',
'tests.test_bio_membuf',
@@ -30,16 +32,18 @@ def suite():
'tests.test_dh',
'tests.test_dsa',
'tests.test_engine',
+ 'tests.test_err',
'tests.test_evp',
'tests.test_obj',
- 'tests.test_pgp',
'tests.test_rand',
'tests.test_rc4',
'tests.test_rsa',
'tests.test_smime',
'tests.test_ssl_offline',
'tests.test_threading',
- 'tests.test_x509']
+ 'tests.test_util',
+ 'tests.test_x509',
+ 'tests.test_timeout']
if os.name == 'posix':
modules_to_test.append('tests.test_ssl')
elif os.name == 'nt':
@@ -51,50 +55,52 @@ def suite():
alltests = unittest.TestSuite()
for module in map(my_import, modules_to_test):
alltests.addTest(module.suite())
+
+ print('Version of OpenSSL is {0:x} ({1:s})'.format(m2.OPENSSL_VERSION_NUMBER,
+ m2.OPENSSL_VERSION_TEXT))
+
return alltests
def dump_garbage():
import gc
- print '\nGarbage:'
+ print('\nGarbage:')
gc.collect()
if len(gc.garbage):
-
- print '\nLeaked objects:'
+
+ print('\nLeaked objects:')
for x in gc.garbage:
s = str(x)
- if len(s) > 77: s = s[:73]+'...'
- print type(x), '\n ', s
-
- print 'There were %d leaks.' % len(gc.garbage)
+ if len(s) > 77:
+ s = s[:73] + '...'
+ print(type(x), '\n ', s)
+
+ print('There were %d leaks.' % len(gc.garbage))
else:
- print 'Python garbage collector did not detect any leaks.'
- print 'However, it is still possible there are leaks in the C code.'
+ print('Python garbage collector did not detect any leaks.')
+ print('However, it is still possible there are leaks in the C code.')
def runall(report_leaks=0):
report_leaks = report_leaks
-
+
if report_leaks:
import gc
gc.enable()
gc.set_debug(gc.DEBUG_LEAK & ~gc.DEBUG_SAVEALL)
-
- import os, unittest
+
+ import os
+ import unittest
from M2Crypto import Rand
-
+
try:
- Rand.load_file('tests/randpool.dat', -1)
+ Rand.load_file('tests/randpool.dat', -1)
unittest.TextTestRunner(verbosity=2).run(suite())
Rand.save_file('tests/randpool.dat')
finally:
if os.name == 'posix':
- from test_ssl import zap_servers
+ from .test_ssl import zap_servers
zap_servers()
if report_leaks:
dump_garbage()
-
-
-if __name__ == '__main__':
- runall(0)
diff --git a/tests/bad_date_cert.crt b/tests/bad_date_cert.crt
new file mode 100644
index 0000000..649f2e1
--- /dev/null
+++ b/tests/bad_date_cert.crt
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIC/TCCAeWgAwIBAgIJAPd8QvAqguI9MA0GCSqGSIb3DQEBCwUAMBQxEjAQBgNV
+BAMMCWxvY2FsaG9zdDAgFw0xNjAzMDQxNDU3NDZaGA8yMTE2MDIwOTE0NTc0Nlow
+FDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
+CgKCAQEAsyy/9CI++wVV22U3xor0Hi1nUUusa8Or/a/ppTpgAH0UREcvKrfSCQU0
+cCPbYg2M3Jn+tQlcs3eAfUFnyz4XCDlMnns8iKse6kkzQQpx+budUwAamP21bHa6
+8dMwDFT3+z9LxDstqdbsvW+KzQwyuYCsWnp6l2KRNy1P4wt7gVvnm5+GCGRMo89L
+yWJ6iz21XZt6wsafPArKclxVzkzW6Li7JvMaJWyJstSlDaGMlAORUbbO78/VYVYD
+idhqtgN+s1rnHZEMKU0io2pTkVTYVVU6hkGvx7OxChVd8ZYQdptYu1jqB4DS9Ima
+tNLZZMnBh9aAwZAEWLku8N1EV/pfyQIDAQABo1AwTjAdBgNVHQ4EFgQUWc4wUp+0
+e1cC0gY3DCtCx1ECCgswHwYDVR0jBBgwFoAUWc4wUp+0e1cC0gY3DCtCx1ECCgsw
+DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEABmFTO2Q+6VqzQ3Td4Xp4
+TwJ25WJWf/n5E/sY96Z4iG5ABzPEo4jzsx6DQzcxQ445nu62/OHtmF8y8abZWk0/
+KTmTMEl0+z9ab48zHIjp7WkXcUGxHfbIApI8tmYXn/y1+zEtG5+bRXcAODce0pRL
+CqWvlchiwLhlao0Pe8Gz1DV7feS/or9XojE8+sokSiuRFGIcwIzpYX/hja4Xtsmc
+Z/PUfodHmpKW+c559cn9pnVjJjhjXpKqDrgE2l9jtTwRVLQOGMxcISvfoNwu833z
+OJJ1gyor9okGBpmackBUpwpWD7s6tBwkcMo2sJZGD/Kfv1ncYuRXqa6+tQaHxJRS
+LA==
+-----END CERTIFICATE-----
diff --git a/tests/ca.pem b/tests/ca.pem
index 5450a68..a1ec319 100644
--- a/tests/ca.pem
+++ b/tests/ca.pem
@@ -1,62 +1,101 @@
Certificate:
Data:
Version: 3 (0x2)
- Serial Number:
- d1:b6:bf:af:06:17:8c:bd
- Signature Algorithm: sha1WithRSAEncryption
+ Serial Number: 0 (0x0)
+ Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, ST=California, O=M2Crypto, CN=Heikki Toivonen
Validity
- Not Before: Jul 28 04:30:50 2009 GMT
- Not After : Jul 27 04:30:50 2012 GMT
+ Not Before: Oct 7 15:12:02 2018 GMT
+ Not After : Oct 4 15:12:02 2028 GMT
Subject: C=US, ST=California, O=M2Crypto, CN=Heikki Toivonen
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
- RSA Public Key: (1024 bit)
- Modulus (1024 bit):
- 00:c8:9b:59:18:c2:bf:21:68:dc:d4:62:30:1f:43:
- 29:52:85:8d:36:fc:20:7f:11:1b:c6:f3:e6:c2:7a:
- d0:17:0e:6e:78:43:21:e9:e2:df:9f:31:87:e8:7a:
- 37:88:1f:a4:56:a1:e9:cb:13:7b:1b:c0:28:cf:5a:
- db:a3:e7:50:6c:c6:55:76:e3:61:e8:73:4b:c2:8c:
- ee:1c:29:c1:ee:2d:fd:e2:30:34:69:06:ea:d0:af:
- bd:c5:db:86:70:92:26:0a:33:1b:70:a9:e7:6e:a4:
- 2e:ee:4a:8a:f3:b2:6c:c9:97:28:39:28:28:3f:c5:
- 90:4d:4e:83:0a:0e:cd:98:93
+ RSA Public-Key: (2048 bit)
+ Modulus:
+ 00:b8:14:c3:7e:10:d4:0e:55:5e:8c:5c:14:07:14:
+ da:a6:32:d4:35:37:23:7c:27:bd:29:69:4a:dd:ee:
+ a7:9f:f3:7f:1b:f4:73:3d:0b:89:6a:a1:f7:35:ac:
+ b0:20:42:b8:e6:f5:36:9f:83:d9:d6:d0:45:b9:60:
+ 0c:a9:dd:f6:28:b9:c4:b7:02:ee:63:cc:ba:3a:70:
+ 0c:34:75:46:9d:f1:7b:d5:5f:46:17:84:94:fc:00:
+ f6:21:c3:e2:cd:6c:d1:33:bf:d9:c2:1c:5f:c8:af:
+ 91:20:0b:ed:c9:68:44:00:45:ec:9e:82:5a:62:c2:
+ a7:53:de:58:db:7d:d5:2c:9e:8f:7c:15:b4:34:30:
+ ab:b7:3d:ed:72:a2:5c:4a:51:d1:85:33:ad:e0:23:
+ e9:12:02:b9:64:0b:d8:de:61:f8:d9:18:4e:43:32:
+ 73:d0:f2:df:c6:de:28:cf:f5:48:7e:46:7c:85:c6:
+ 1e:96:a2:32:b8:16:ff:96:71:81:a7:d1:87:d2:d9:
+ 0e:b8:9f:ad:45:14:a1:d3:b9:52:c8:59:63:77:17:
+ fe:22:ac:f9:c1:97:12:97:98:99:ae:ac:48:1b:97:
+ 83:fa:88:e0:63:9b:bc:55:ea:e0:c7:ec:55:28:e9:
+ 28:2a:b4:be:08:e1:50:43:4e:41:df:10:b7:98:1e:
+ dd:37
Exponent: 65537 (0x10001)
X509v3 extensions:
- X509v3 Subject Key Identifier:
- AD:64:45:74:8F:83:C7:2C:D5:D7:A0:85:91:10:40:9A:9C:96:CF:EE
- X509v3 Authority Key Identifier:
- keyid:AD:64:45:74:8F:83:C7:2C:D5:D7:A0:85:91:10:40:9A:9C:96:CF:EE
- DirName:/C=US/ST=California/O=M2Crypto/CN=Heikki Toivonen
- serial:D1:B6:BF:AF:06:17:8C:BD
-
X509v3 Basic Constraints:
CA:TRUE
- Signature Algorithm: sha1WithRSAEncryption
- c8:11:af:7d:6d:fb:1c:82:0d:c0:e7:41:f4:b2:a5:b0:69:6d:
- 18:e3:04:aa:49:e6:4a:69:6d:c3:e3:8b:ab:d1:18:ac:72:ef:
- 48:9e:49:c7:57:75:2d:00:1e:08:9f:c3:dc:ca:5f:91:38:0d:
- ac:f8:1f:cc:fc:f7:c2:5b:ce:d7:0c:cf:b2:fe:c9:a9:ce:b8:
- 07:45:17:1c:cf:b3:07:f9:1f:69:6a:94:03:be:62:62:9c:af:
- a2:24:25:2d:1f:63:0a:91:6b:bb:e3:6c:ec:20:de:80:d3:04:
- b4:5e:42:1f:27:bc:1f:79:98:18:ba:fb:8a:34:24:a9:40:1e:
- b9:7b
+ X509v3 Subject Key Identifier:
+ 49:6E:7E:9B:16:48:9F:E9:B8:A7:DC:7C:0E:73:F6:26:2A:9C:9D:7C
+ Signature Algorithm: sha256WithRSAEncryption
+ a5:88:b0:1a:e3:fc:89:21:8f:d2:3f:39:5d:bd:84:1c:c9:1b:
+ 58:16:8d:cc:f7:9d:6d:f1:19:29:05:51:c6:20:c5:cc:00:d5:
+ 61:5f:8f:de:64:3a:43:81:eb:b2:21:7a:ec:19:6b:21:30:33:
+ bc:a3:7b:f7:2a:49:f5:8b:d3:48:dc:65:f0:29:f2:fd:3c:f5:
+ 03:37:19:a3:56:d5:3c:42:60:29:df:ab:aa:36:95:16:eb:6c:
+ f2:2d:22:ca:5c:0d:e7:14:6e:f3:10:70:b9:d2:82:59:68:9e:
+ 31:9d:39:f2:8a:6e:00:c3:2c:b5:ed:f9:fa:6f:f4:43:f1:98:
+ 81:f3:89:ef:23:6d:fc:f1:33:2f:d7:fc:cc:28:2a:dd:3e:da:
+ 27:8a:1f:5e:a9:7a:df:2e:c1:e5:c6:db:a9:74:c2:e2:9c:3e:
+ 9b:2c:22:b1:2e:5d:90:09:c9:45:95:35:21:ca:08:12:19:4c:
+ 8d:ca:a5:1d:2b:55:b3:44:d5:43:5d:86:bc:36:4c:e6:7a:29:
+ b6:21:ab:e8:a2:23:ec:e4:00:a0:6b:0f:bd:d5:77:64:64:30:
+ ed:d7:31:88:18:91:24:08:7b:9b:0f:62:8f:31:5c:11:f1:df:
+ d3:2d:e6:52:27:11:a0:8a:f9:5e:a9:a3:ea:e3:0c:83:56:2b:
+ 95:6b:b9:f6
-----BEGIN CERTIFICATE-----
-MIICzjCCAjegAwIBAgIJANG2v68GF4y9MA0GCSqGSIb3DQEBBQUAME8xCzAJBgNV
-BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMREwDwYDVQQKEwhNMkNyeXB0bzEY
-MBYGA1UEAxMPSGVpa2tpIFRvaXZvbmVuMB4XDTA5MDcyODA0MzA1MFoXDTEyMDcy
-NzA0MzA1MFowTzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExETAP
-BgNVBAoTCE0yQ3J5cHRvMRgwFgYDVQQDEw9IZWlra2kgVG9pdm9uZW4wgZ8wDQYJ
-KoZIhvcNAQEBBQADgY0AMIGJAoGBAMibWRjCvyFo3NRiMB9DKVKFjTb8IH8RG8bz
-5sJ60BcObnhDIeni358xh+h6N4gfpFah6csTexvAKM9a26PnUGzGVXbjYehzS8KM
-7hwpwe4t/eIwNGkG6tCvvcXbhnCSJgozG3Cp526kLu5KivOybMmXKDkoKD/FkE1O
-gwoOzZiTAgMBAAGjgbEwga4wHQYDVR0OBBYEFK1kRXSPg8cs1deghZEQQJqcls/u
-MH8GA1UdIwR4MHaAFK1kRXSPg8cs1deghZEQQJqcls/uoVOkUTBPMQswCQYDVQQG
-EwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTERMA8GA1UEChMITTJDcnlwdG8xGDAW
-BgNVBAMTD0hlaWtraSBUb2l2b25lboIJANG2v68GF4y9MAwGA1UdEwQFMAMBAf8w
-DQYJKoZIhvcNAQEFBQADgYEAyBGvfW37HIINwOdB9LKlsGltGOMEqknmSmltw+OL
-q9EYrHLvSJ5Jx1d1LQAeCJ/D3MpfkTgNrPgfzPz3wlvO1wzPsv7Jqc64B0UXHM+z
-B/kfaWqUA75iYpyvoiQlLR9jCpFru+Ns7CDegNMEtF5CHye8H3mYGLr7ijQkqUAe
-uXs=
+MIIDSDCCAjCgAwIBAgIBADANBgkqhkiG9w0BAQsFADBPMQswCQYDVQQGEwJVUzET
+MBEGA1UECAwKQ2FsaWZvcm5pYTERMA8GA1UECgwITTJDcnlwdG8xGDAWBgNVBAMM
+D0hlaWtraSBUb2l2b25lbjAeFw0xODEwMDcxNTEyMDJaFw0yODEwMDQxNTEyMDJa
+ME8xCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMREwDwYDVQQKDAhN
+MkNyeXB0bzEYMBYGA1UEAwwPSGVpa2tpIFRvaXZvbmVuMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEAuBTDfhDUDlVejFwUBxTapjLUNTcjfCe9KWlK3e6n
+n/N/G/RzPQuJaqH3NaywIEK45vU2n4PZ1tBFuWAMqd32KLnEtwLuY8y6OnAMNHVG
+nfF71V9GF4SU/AD2IcPizWzRM7/ZwhxfyK+RIAvtyWhEAEXsnoJaYsKnU95Y233V
+LJ6PfBW0NDCrtz3tcqJcSlHRhTOt4CPpEgK5ZAvY3mH42RhOQzJz0PLfxt4oz/VI
+fkZ8hcYelqIyuBb/lnGBp9GH0tkOuJ+tRRSh07lSyFljdxf+Iqz5wZcSl5iZrqxI
+G5eD+ojgY5u8Vergx+xVKOkoKrS+COFQQ05B3xC3mB7dNwIDAQABoy8wLTAMBgNV
+HRMEBTADAQH/MB0GA1UdDgQWBBRJbn6bFkif6bin3HwOc/YmKpydfDANBgkqhkiG
+9w0BAQsFAAOCAQEApYiwGuP8iSGP0j85Xb2EHMkbWBaNzPedbfEZKQVRxiDFzADV
+YV+P3mQ6Q4HrsiF67BlrITAzvKN79ypJ9YvTSNxl8Cny/Tz1AzcZo1bVPEJgKd+r
+qjaVFuts8i0iylwN5xRu8xBwudKCWWieMZ058opuAMMste35+m/0Q/GYgfOJ7yNt
+/PEzL9f8zCgq3T7aJ4ofXql63y7B5cbbqXTC4pw+mywisS5dkAnJRZU1IcoIEhlM
+jcqlHStVs0TVQ12GvDZM5noptiGr6KIj7OQAoGsPvdV3ZGQw7dcxiBiRJAh7mw9i
+jzFcEfHf0y3mUicRoIr5Xqmj6uMMg1YrlWu59g==
-----END CERTIFICATE-----
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpQIBAAKCAQEAuBTDfhDUDlVejFwUBxTapjLUNTcjfCe9KWlK3e6nn/N/G/Rz
+PQuJaqH3NaywIEK45vU2n4PZ1tBFuWAMqd32KLnEtwLuY8y6OnAMNHVGnfF71V9G
+F4SU/AD2IcPizWzRM7/ZwhxfyK+RIAvtyWhEAEXsnoJaYsKnU95Y233VLJ6PfBW0
+NDCrtz3tcqJcSlHRhTOt4CPpEgK5ZAvY3mH42RhOQzJz0PLfxt4oz/VIfkZ8hcYe
+lqIyuBb/lnGBp9GH0tkOuJ+tRRSh07lSyFljdxf+Iqz5wZcSl5iZrqxIG5eD+ojg
+Y5u8Vergx+xVKOkoKrS+COFQQ05B3xC3mB7dNwIDAQABAoIBAQCISU8nYbwuVIQo
+tO9bAtSS4eT89TK/dAh3xW3ZfBz8rmF4R/adxpHZscp+IblQWTXeQMRNO2gnw5Er
+mvIlPaFHK6p5uKDYoLVsGJLgr8c1npkJM32IYe+P2AJio02iu6LzhmHpdepwgZOX
+v10wlZJrBVoXTPkwT19lF6R/9NzEJ+qyceixwIUFlqKzFv+LavFL4elP03OVF5Wu
+TN2DTaVJzNdpBVGdYKkJX7GhX28/gaDRZw6B2wJoJhl56uhzibNe9Lc0S9nyt+0Y
+ARodv5KVTaM07z4LkFQxIliVFJmR8Bin3CHC36K9ike57srkR/BOR13Vxw9EtUHx
+tNe11jy5AoGBAOVo1NHwHT7EH06F3O2MvKYJAa5rm8EU9Eq6d70ylVDKHCu2NA9V
+KeeUbXxGK9Bk3RhLVevZv870AgZqtD4sUEg3qMrW3ZQHyyAlZq57AAw9GlL8REZv
+aWvDE4/fmpNYVyUrpQ9KIyaZa96VZtqUJbLgzcvQsRhiwo2zQAP9UqL9AoGBAM1q
+7DJtTqU1Muk5UWc8XS6HxRf0D5c1240UXP1xkRDCfI2lI3AM3sCQ5iKQP/SsOrvK
+KgxQDVykdbTqD5F7QDX8BmYTdALzRm/XyqqY52WljDAwNEsdTLPewffDMRhjSBSw
+sjPiHMnmXJH+0uKKUrSdvDsElBQASKQ81Ojg+ZlDAoGAS2HiJMYQ5hIN84B7Mze+
+uZRWEBleCdk32OJi/DGF7REsppRtkOg8J9OXEnIAba7nE9eVeTWJGJkHnVIsvg1T
+qBdaCKUIFF9nOL3xer4CKwNdBg3M5ZQwgO+OGwWvxmEN6bHowBhtan6Zen9/V628
+oYXLOgDuYIP7SBKxo133bIUCgYEAj4hTrFSmbFfE0CQF1k3eimHB/R/DORQf6e89
+nrYY+A39e/fU0Dmd+A4HUEVc+vjRPWBgiyPwgjhEKvqVkED/t/j2+6JCIMGeCQ5O
+hW+72FGZqB42m/nIG7Ld8+KGzpSozBQ/IHOxS/5T1oupDTQ74AqLeO2VDni4SVJc
+LrDslwMCgYEArxtk6NGesCUgdCTHEueubcY8VoXn/DOHi1QpqV/Fq93Fs5AkDwle
+yI11+KVvXad2UAZI2LcQsN3P12Wdco0ayfHOSpOf8zv1w+/DyDkrcT10ZxgL9EDJ
+eBEgQ+XmPoteMubMr6EQrzfXxzKqK/DN+2mq0s7PAFgHOr31g6feLYI=
+-----END RSA PRIVATE KEY-----
diff --git a/tests/ca_key.pem b/tests/ca_key.pem
new file mode 100644
index 0000000..a5525db
--- /dev/null
+++ b/tests/ca_key.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpQIBAAKCAQEAuBTDfhDUDlVejFwUBxTapjLUNTcjfCe9KWlK3e6nn/N/G/Rz
+PQuJaqH3NaywIEK45vU2n4PZ1tBFuWAMqd32KLnEtwLuY8y6OnAMNHVGnfF71V9G
+F4SU/AD2IcPizWzRM7/ZwhxfyK+RIAvtyWhEAEXsnoJaYsKnU95Y233VLJ6PfBW0
+NDCrtz3tcqJcSlHRhTOt4CPpEgK5ZAvY3mH42RhOQzJz0PLfxt4oz/VIfkZ8hcYe
+lqIyuBb/lnGBp9GH0tkOuJ+tRRSh07lSyFljdxf+Iqz5wZcSl5iZrqxIG5eD+ojg
+Y5u8Vergx+xVKOkoKrS+COFQQ05B3xC3mB7dNwIDAQABAoIBAQCISU8nYbwuVIQo
+tO9bAtSS4eT89TK/dAh3xW3ZfBz8rmF4R/adxpHZscp+IblQWTXeQMRNO2gnw5Er
+mvIlPaFHK6p5uKDYoLVsGJLgr8c1npkJM32IYe+P2AJio02iu6LzhmHpdepwgZOX
+v10wlZJrBVoXTPkwT19lF6R/9NzEJ+qyceixwIUFlqKzFv+LavFL4elP03OVF5Wu
+TN2DTaVJzNdpBVGdYKkJX7GhX28/gaDRZw6B2wJoJhl56uhzibNe9Lc0S9nyt+0Y
+ARodv5KVTaM07z4LkFQxIliVFJmR8Bin3CHC36K9ike57srkR/BOR13Vxw9EtUHx
+tNe11jy5AoGBAOVo1NHwHT7EH06F3O2MvKYJAa5rm8EU9Eq6d70ylVDKHCu2NA9V
+KeeUbXxGK9Bk3RhLVevZv870AgZqtD4sUEg3qMrW3ZQHyyAlZq57AAw9GlL8REZv
+aWvDE4/fmpNYVyUrpQ9KIyaZa96VZtqUJbLgzcvQsRhiwo2zQAP9UqL9AoGBAM1q
+7DJtTqU1Muk5UWc8XS6HxRf0D5c1240UXP1xkRDCfI2lI3AM3sCQ5iKQP/SsOrvK
+KgxQDVykdbTqD5F7QDX8BmYTdALzRm/XyqqY52WljDAwNEsdTLPewffDMRhjSBSw
+sjPiHMnmXJH+0uKKUrSdvDsElBQASKQ81Ojg+ZlDAoGAS2HiJMYQ5hIN84B7Mze+
+uZRWEBleCdk32OJi/DGF7REsppRtkOg8J9OXEnIAba7nE9eVeTWJGJkHnVIsvg1T
+qBdaCKUIFF9nOL3xer4CKwNdBg3M5ZQwgO+OGwWvxmEN6bHowBhtan6Zen9/V628
+oYXLOgDuYIP7SBKxo133bIUCgYEAj4hTrFSmbFfE0CQF1k3eimHB/R/DORQf6e89
+nrYY+A39e/fU0Dmd+A4HUEVc+vjRPWBgiyPwgjhEKvqVkED/t/j2+6JCIMGeCQ5O
+hW+72FGZqB42m/nIG7Ld8+KGzpSozBQ/IHOxS/5T1oupDTQ74AqLeO2VDni4SVJc
+LrDslwMCgYEArxtk6NGesCUgdCTHEueubcY8VoXn/DOHi1QpqV/Fq93Fs5AkDwle
+yI11+KVvXad2UAZI2LcQsN3P12Wdco0ayfHOSpOf8zv1w+/DyDkrcT10ZxgL9EDJ
+eBEgQ+XmPoteMubMr6EQrzfXxzKqK/DN+2mq0s7PAFgHOr31g6feLYI=
+-----END RSA PRIVATE KEY-----
diff --git a/tests/easy_rsa.pem b/tests/easy_rsa.pem
new file mode 100644
index 0000000..0028c63
--- /dev/null
+++ b/tests/easy_rsa.pem
@@ -0,0 +1,74 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 3 (0x3)
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=US, ST=NC, L=Raleigh, O=Fedora Project, OU=fedmsg, CN=fedmsg/name=fedmsg/emailAddress=admin@fedoraproject.org
+ Validity
+ Not Before: Jul 15 21:18:52 2012 GMT
+ Not After : Jul 13 21:18:52 2022 GMT
+ Subject: C=US, ST=NC, L=Raleigh, O=Fedora Project, OU=fedmsg, CN=shell-app01.phx2.fedoraproject.org/name=shell-app01.phx2.fedoraproject.org/emailAddress=admin@fedoraproject.org
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (1024 bit)
+ Modulus:
+ 00:c9:5d:32:76:f9:e8:a4:84:e6:16:cd:24:7e:99:
+ 68:2a:3e:a7:5b:4f:c2:3b:3a:74:ac:3c:30:be:e5:
+ 99:17:62:83:76:5d:40:79:15:b3:7e:ca:4e:40:e5:
+ 88:2b:95:7e:a3:6a:b1:60:0e:ad:6a:22:b8:6c:f7:
+ f2:95:82:f5:20:62:30:95:53:fd:99:ae:73:c2:44:
+ 6f:5a:47:ad:5a:31:8e:46:9e:41:ee:0e:e8:10:24:
+ 0e:06:8d:e0:9d:0b:74:51:fe:53:58:04:35:e9:69:
+ f4:6c:2a:c8:41:2a:8e:59:52:92:70:af:6f:52:4f:
+ e8:a2:65:25:01:96:e4:b0:47
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints:
+ CA:FALSE
+ Netscape Comment:
+ Easy-RSA Generated Certificate
+ X509v3 Subject Key Identifier:
+ 77:71:57:05:B0:F6:25:6D:EA:72:6A:BE:E5:53:FB:19:CB:B1:1C:5E
+ X509v3 Authority Key Identifier:
+ keyid:00:98:A5:D5:E7:C4:55:0E:84:A3:67:FE:66:4A:16:E0:04:15:DD:21
+ DirName:/C=US/ST=NC/L=Raleigh/O=Fedora Project/OU=fedmsg/CN=fedmsg/name=fedmsg/emailAddress=admin@fedoraproject.org
+ serial:8E:EB:28:D8:A9:13:9D:7C
+
+ X509v3 Extended Key Usage:
+ TLS Web Client Authentication
+ X509v3 Key Usage:
+ Digital Signature
+ Signature Algorithm: sha1WithRSAEncryption
+ 11:b5:cc:6f:e5:cd:8c:b3:fe:98:61:44:ea:ba:9f:39:37:41:
+ 45:5e:34:6c:b1:15:dc:71:a0:1e:7b:8f:8c:43:8b:ad:32:cf:
+ 2d:b2:01:87:bd:b3:0a:a5:2f:51:a4:f6:38:c0:e3:f6:5f:fe:
+ 52:cf:17:13:8c:f8:d8:a7:4c:e8:7f:a3:ac:f4:6c:40:41:0a:
+ e7:f0:14:a8:92:fa:e8:3f:a6:3b:08:a3:af:6f:0b:4d:c5:db:
+ 54:b4:a6:ab:8c:f1:b4:23:71:da:00:e6:ae:69:76:26:3f:06:
+ ae:47:50:b9:a8:b3:20:3e:10:db:ba:f6:8b:d0:19:96:54:88:
+ 96:ff
+-----BEGIN CERTIFICATE-----
+MIIESTCCA7KgAwIBAgIBAzANBgkqhkiG9w0BAQUFADCBoDELMAkGA1UEBhMCVVMx
+CzAJBgNVBAgTAk5DMRAwDgYDVQQHEwdSYWxlaWdoMRcwFQYDVQQKEw5GZWRvcmEg
+UHJvamVjdDEPMA0GA1UECxMGZmVkbXNnMQ8wDQYDVQQDEwZmZWRtc2cxDzANBgNV
+BCkTBmZlZG1zZzEmMCQGCSqGSIb3DQEJARYXYWRtaW5AZmVkb3JhcHJvamVjdC5v
+cmcwHhcNMTIwNzE1MjExODUyWhcNMjIwNzEzMjExODUyWjCB2DELMAkGA1UEBhMC
+VVMxCzAJBgNVBAgTAk5DMRAwDgYDVQQHEwdSYWxlaWdoMRcwFQYDVQQKEw5GZWRv
+cmEgUHJvamVjdDEPMA0GA1UECxMGZmVkbXNnMSswKQYDVQQDEyJzaGVsbC1hcHAw
+MS5waHgyLmZlZG9yYXByb2plY3Qub3JnMSswKQYDVQQpEyJzaGVsbC1hcHAwMS5w
+aHgyLmZlZG9yYXByb2plY3Qub3JnMSYwJAYJKoZIhvcNAQkBFhdhZG1pbkBmZWRv
+cmFwcm9qZWN0Lm9yZzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAyV0ydvno
+pITmFs0kfploKj6nW0/COzp0rDwwvuWZF2KDdl1AeRWzfspOQOWIK5V+o2qxYA6t
+aiK4bPfylYL1IGIwlVP9ma5zwkRvWketWjGORp5B7g7oECQOBo3gnQt0Uf5TWAQ1
+6Wn0bCrIQSqOWVKScK9vUk/oomUlAZbksEcCAwEAAaOCAVcwggFTMAkGA1UdEwQC
+MAAwLQYJYIZIAYb4QgENBCAWHkVhc3ktUlNBIEdlbmVyYXRlZCBDZXJ0aWZpY2F0
+ZTAdBgNVHQ4EFgQUd3FXBbD2JW3qcmq+5VP7GcuxHF4wgdUGA1UdIwSBzTCByoAU
+AJil1efEVQ6Eo2f+ZkoW4AQV3SGhgaakgaMwgaAxCzAJBgNVBAYTAlVTMQswCQYD
+VQQIEwJOQzEQMA4GA1UEBxMHUmFsZWlnaDEXMBUGA1UEChMORmVkb3JhIFByb2pl
+Y3QxDzANBgNVBAsTBmZlZG1zZzEPMA0GA1UEAxMGZmVkbXNnMQ8wDQYDVQQpEwZm
+ZWRtc2cxJjAkBgkqhkiG9w0BCQEWF2FkbWluQGZlZG9yYXByb2plY3Qub3JnggkA
+juso2KkTnXwwEwYDVR0lBAwwCgYIKwYBBQUHAwIwCwYDVR0PBAQDAgeAMA0GCSqG
+SIb3DQEBBQUAA4GBABG1zG/lzYyz/phhROq6nzk3QUVeNGyxFdxxoB57j4xDi60y
+zy2yAYe9swqlL1Gk9jjA4/Zf/lLPFxOM+NinTOh/o6z0bEBBCufwFKiS+ug/pjsI
+o69vC03F21S0pquM8bQjcdoA5q5pdiY/Bq5HULmosyA+ENu69ovQGZZUiJb/
+-----END CERTIFICATE-----
diff --git a/tests/ec.priv.pem b/tests/ec.priv.pem
index 2147d67..cddd1d7 100644
--- a/tests/ec.priv.pem
+++ b/tests/ec.priv.pem
@@ -1,5 +1,6 @@
-----BEGIN EC PRIVATE KEY-----
-MG0CAQEEHXXhxMbflWHSfCjfxsqHTsIR+BVbREI6JFYGaUs0oAcGBSuBBAAaoUAD
-PgAEAdJXSN/xnRiDqc4wSiYbWB7LGabs71Y9zzIE1ZbzAcvb7uxtoyUxrmRQC8xD
-EO2qZX16mtpmgoNz3EeT
+MIGkAgEBBDDYZmLKVOPc34hDebkYt5vGMQBcX+WtHbXxnncL6ptQtzgkWN1ePGA6
+x2HU8NFFpwigBwYFK4EEACKhZANiAASkekXfdAy+vfwcOvO0rwsVDWpil6EKYMlo
+kdhqz1/kp7hiv5ppw3/LCwsst9CJUUvfAIsRI4qFvTBE0JR8FxLHKFJgasPRHZo9
+x5i2EG07MzSevyODOjtVBrklq6nQCao=
-----END EC PRIVATE KEY-----
diff --git a/tests/ec.pub.pem b/tests/ec.pub.pem
index 4a08b59..288e181 100644
--- a/tests/ec.pub.pem
+++ b/tests/ec.pub.pem
@@ -1,4 +1,5 @@
-----BEGIN PUBLIC KEY-----
-MFIwEAYHKoZIzj0CAQYFK4EEABoDPgAEAdJXSN/xnRiDqc4wSiYbWB7LGabs71Y9
-zzIE1ZbzAcvb7uxtoyUxrmRQC8xDEO2qZX16mtpmgoNz3EeT
+MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEpHpF33QMvr38HDrztK8LFQ1qYpehCmDJ
+aJHYas9f5Ke4Yr+aacN/ywsLLLfQiVFL3wCLESOKhb0wRNCUfBcSxyhSYGrD0R2a
+PceYthBtOzM0nr8jgzo7VQa5Jaup0Amq
-----END PUBLIC KEY-----
diff --git a/tests/fips.py b/tests/fips.py
index 32eb75b..6b2ba3e 100644
--- a/tests/fips.py
+++ b/tests/fips.py
@@ -1,8 +1,5 @@
try:
- f = open('/proc/sys/crypto/fips_enabled')
- try:
+ with open('/proc/sys/crypto/fips_enabled') as f:
fips_mode = int(f.read())
- finally:
- f.close()
-except Exception, e:
+except (IOError, OSError):
fips_mode = 0
diff --git a/tests/makecerts.py b/tests/makecerts.py
new file mode 100755
index 0000000..e25a07b
--- /dev/null
+++ b/tests/makecerts.py
@@ -0,0 +1,213 @@
+#!/usr/bin/env python
+#
+# Create test certificates:
+#
+# ca.pem
+# server.pem
+# recipient.pem
+# signer.pem
+# x509.pem
+#
+from __future__ import print_function
+
+import hashlib
+import os
+import os.path
+import sys
+import time
+
+from M2Crypto import ASN1, EC, EVP, RSA, X509, m2, util
+
+t = int(time.time() + time.timezone)
+before = ASN1.ASN1_TIME()
+before.set_time(t)
+after = ASN1.ASN1_TIME()
+after.set_time(t + 60 * 60 * 24 * 365 * 10) # 10 years
+
+serial = 1
+
+
+def callback(self, *args):
+ return ' '
+
+
+def gen_identifier(cert, dig='sha256'):
+ instr = cert.get_pubkey().get_rsa().as_pem()
+ h = hashlib.new(dig)
+ h.update(instr)
+ digest = h.hexdigest().upper()
+
+ return ":".join(digest[pos: pos + 2] for pos in range(0, 40, 2))
+
+
+def make_subject(cn=None, email=None):
+ sub = X509.X509_Name()
+ sub.C = 'US'
+ sub.ST = 'California'
+ sub.O = 'M2Crypto'
+ if cn is not None:
+ sub.CN = cn
+ else:
+ sub.CN = 'Heikki Toivonen'
+ if email is not None:
+ sub.Email = email
+ return sub
+
+
+def req(name):
+ rsa = RSA.load_key(name + '_key.pem')
+ pk = EVP.PKey()
+ pk.assign_rsa(rsa)
+ reqqed = X509.Request()
+ reqqed.set_pubkey(pk)
+ reqqed.set_subject(make_subject())
+ reqqed.sign(pk, 'sha256')
+ return reqqed, pk
+
+
+def save_text_pem_key(cert, name, with_key=True):
+ with open(name + '.pem', 'wb') as f:
+ for line in cert.as_text():
+ f.write(line.encode("ascii"))
+ f.write(cert.as_pem())
+ if with_key:
+ with open(name + '_key.pem', 'rb') as key_f:
+ for line in key_f:
+ f.write(line)
+
+
+def issue(request, ca, capk):
+ global serial
+
+ pkey = request.get_pubkey()
+ sub = request.get_subject()
+
+ cert = X509.X509()
+ cert.set_version(2)
+ cert.set_subject(sub)
+ cert.set_serial_number(serial)
+ serial += 1
+
+ issuer = ca.get_subject()
+ cert.set_issuer(issuer)
+
+ cert.set_pubkey(pkey)
+
+ cert.set_not_before(before)
+ cert.set_not_after(after)
+
+ ext = X509.new_extension('basicConstraints', 'CA:FALSE')
+ cert.add_ext(ext)
+
+ ext = X509.new_extension('subjectKeyIdentifier',
+ gen_identifier(cert))
+ cert.add_ext(ext)
+
+ # auth = X509.load_cert('ca.pem')
+ # auth_id = auth.get_ext('subjectKeyIdentifier').get_value()
+ # ext = X509.new_extension('authorityKeyIdentifier', 'keyid:%s' % auth_id)
+ # # cert.add_ext(ext)
+
+ cert.sign(capk, 'sha256')
+
+ assert cert.verify(capk)
+
+ return cert
+
+
+def mk_ca():
+ r, pk = req('ca')
+ pkey = r.get_pubkey()
+ sub = r.get_subject()
+
+ cert = X509.X509()
+ cert.set_version(2)
+ cert.set_subject(sub)
+ cert.set_serial_number(0)
+
+ issuer = X509.X509_Name()
+ issuer.C = sub.C
+ issuer.ST = sub.ST
+ issuer.O = sub.O
+ issuer.CN = sub.CN
+ cert.set_issuer(issuer)
+
+ cert.set_pubkey(pkey)
+
+ cert.set_not_before(before)
+ cert.set_not_after(after)
+
+ ext = X509.new_extension('basicConstraints', 'CA:TRUE')
+ cert.add_ext(ext)
+
+ ski = gen_identifier(cert)
+ ext = X509.new_extension('subjectKeyIdentifier', ski)
+ cert.add_ext(ext)
+
+ # ext = X509.new_extension('authorityKeyIdentifier', 'keyid:%s' % ski)
+ # cert.add_ext(ext)
+
+ cert.sign(pk, 'sha256')
+
+ save_text_pem_key(cert, 'ca')
+
+ return cert, pk
+
+
+def mk_server(ca, capk):
+ r, _ = req('server')
+ r.set_subject(make_subject(cn='localhost'))
+ cert = issue(r, ca, capk)
+ save_text_pem_key(cert, 'server')
+
+
+def mk_x509(ca, capk):
+ r, _ = req('x509')
+ r.set_subject(make_subject(cn='X509'))
+ cert = issue(r, ca, capk)
+ save_text_pem_key(cert, 'x509')
+
+ with open('x509.der', 'wb') as derf:
+ derf.write(cert.as_der())
+
+
+def mk_signer(ca, capk):
+ r, _ = req('signer')
+ r.set_subject(make_subject(cn='Signer', email='signer@example.com'))
+ cert = issue(r, ca, capk)
+
+ save_text_pem_key(cert, 'signer', with_key=False)
+
+
+def mk_recipient(ca, capk):
+ r, _ = req('recipient')
+ r.set_subject(make_subject(cn='Recipient', email='recipient@example.com'))
+ cert = issue(r, ca, capk)
+ save_text_pem_key(cert, 'recipient')
+
+
+def mk_ec_pair():
+ priv_key = EC.gen_params(EC.NID_secp384r1)
+ priv_key.gen_key()
+ priv_key.save_key('ec.priv.pem',
+ callback=util.no_passphrase_callback)
+ pub_key = priv_key.pub()
+ pub_key.save_pub_key('ec.pub.pem')
+
+if __name__ == '__main__':
+ names = ['ca', 'server', 'recipient', 'signer', 'x509']
+
+ os.chdir(os.path.dirname(sys.argv[0]))
+
+ for key_name in names:
+ genned_key = RSA.gen_key(2048, m2.RSA_F4)
+ genned_key.save_key('%s_key.pem' % key_name, None)
+
+ ca_bits, pk_bits = mk_ca()
+ mk_server(ca_bits, pk_bits)
+ mk_x509(ca_bits, pk_bits)
+ mk_signer(ca_bits, pk_bits)
+ mk_recipient(ca_bits, pk_bits)
+
+ # FIXME This doesn't work well.
+ # mk_ec_pair()
diff --git a/tests/recipient.pem b/tests/recipient.pem
index d766266..0a03e4d 100644
--- a/tests/recipient.pem
+++ b/tests/recipient.pem
@@ -1,61 +1,102 @@
Certificate:
Data:
Version: 3 (0x2)
- Serial Number:
- d1:b6:bf:af:06:17:8c:c1
- Signature Algorithm: sha1WithRSAEncryption
+ Serial Number: 4 (0x4)
+ Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, ST=California, O=M2Crypto, CN=Heikki Toivonen
Validity
- Not Before: Jul 28 04:39:19 2009 GMT
- Not After : Jul 26 04:39:19 2019 GMT
+ Not Before: Oct 7 15:12:02 2018 GMT
+ Not After : Oct 4 15:12:02 2028 GMT
Subject: C=US, ST=California, O=M2Crypto, CN=Recipient/emailAddress=recipient@example.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
- RSA Public Key: (1024 bit)
- Modulus (1024 bit):
- 00:c2:21:a3:4f:64:59:9c:21:39:21:d2:3c:e7:0a:
- 60:72:c8:39:b3:c3:27:4a:6d:56:8f:a0:5d:1b:c6:
- e4:3e:26:61:09:a9:ae:04:83:69:3f:9d:2b:12:7e:
- d4:f7:8e:d0:6e:a9:8c:9b:d1:bf:17:0c:bd:d0:73:
- 99:02:6e:7e:cb:7a:80:2d:cf:b1:29:c0:30:36:3f:
- 68:12:3e:4e:bf:f9:8b:3d:1d:56:af:24:94:ae:d5:
- 59:b4:00:50:0c:c0:2b:59:c3:99:b3:8a:19:f1:86:
- 14:bd:ee:e9:c4:f1:d7:6a:0c:e9:67:8a:94:9a:2d:
- 2d:60:25:22:c6:72:68:c2:0d
+ RSA Public-Key: (2048 bit)
+ Modulus:
+ 00:cf:c6:83:2b:8c:ea:4e:10:7c:5a:c6:45:07:45:
+ f2:a6:17:55:33:f4:e8:24:df:4e:55:de:3d:0c:e6:
+ a0:a5:e0:b0:eb:bd:0e:55:2f:4e:f3:69:38:f0:31:
+ 1d:0d:54:0c:39:d6:da:37:89:4c:ab:c1:9c:10:9f:
+ 8d:e1:e6:c1:eb:ad:97:c0:8a:a2:4f:6f:e6:10:a0:
+ ad:f2:a0:11:4e:58:16:25:81:3a:5b:7d:6c:b4:e0:
+ 76:83:f2:67:eb:17:be:44:d9:5a:38:2c:2c:b6:f5:
+ 1a:d3:f5:48:85:6a:50:81:f1:74:0b:b1:22:92:cd:
+ e9:1f:fb:a3:1d:ec:03:be:1b:66:05:e9:24:4e:0a:
+ d7:7f:35:a3:92:d8:00:99:06:e9:ad:32:a0:df:7f:
+ 72:d0:de:82:f8:a7:7c:d7:41:73:68:97:7e:f3:de:
+ ea:73:e6:7e:0b:d8:eb:a6:4e:eb:a2:20:e0:2e:5a:
+ 8a:5e:79:b1:dd:e1:a6:64:3e:a2:7a:70:be:6a:5b:
+ 65:e8:bb:a0:d0:4c:00:b3:a4:aa:2f:c3:0a:30:4d:
+ 9e:d1:89:c2:c0:67:51:a0:13:a1:d3:0a:a4:db:82:
+ 85:96:dd:c9:06:49:68:c7:36:e6:ba:60:2a:de:71:
+ 36:5c:3b:16:a9:fe:c8:e3:91:48:6a:62:05:c1:b8:
+ 11:ef
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
- Netscape Comment:
- OpenSSL Generated Certificate
X509v3 Subject Key Identifier:
- 11:CB:60:AC:55:85:52:84:C5:C8:20:5A:50:13:D0:89:C7:7A:B7:81
- X509v3 Authority Key Identifier:
- keyid:AD:64:45:74:8F:83:C7:2C:D5:D7:A0:85:91:10:40:9A:9C:96:CF:EE
-
- Signature Algorithm: sha1WithRSAEncryption
- 87:56:17:6d:ba:3b:a6:c4:22:af:20:f1:a0:e5:9d:27:c4:50:
- bd:79:eb:d2:84:e5:9a:00:5f:5d:5a:c3:34:58:77:f5:a9:00:
- f9:76:e9:2d:89:b4:3f:9d:e3:cf:15:0c:64:1b:0a:03:db:e4:
- 6f:2b:ff:1c:82:89:1a:0f:7e:83:58:0f:e6:da:af:26:97:49:
- 4a:59:d7:61:3f:4b:ed:1d:5b:51:00:3b:83:96:c7:1e:3d:84:
- f4:91:1f:70:69:12:b9:a7:2c:5b:1b:05:cd:74:90:2b:a0:ba:
- e7:70:cd:6b:7d:ac:be:d7:92:50:e9:f5:c0:42:29:04:ef:8f:
- a1:68
+ 24:C1:B1:83:79:31:5E:54:5E:60:65:04:17:FB:76:D3:21:85:3B:68
+ Signature Algorithm: sha256WithRSAEncryption
+ 11:54:e9:1d:b4:5b:36:d8:40:63:45:58:f9:e8:29:53:ff:3e:
+ c9:3a:2a:89:b7:98:99:50:d4:29:96:03:e2:7e:16:1c:f7:86:
+ 2d:a3:92:2a:d8:60:16:d1:48:25:5d:9a:65:3e:27:16:c2:ca:
+ d9:20:62:88:d7:41:7a:9e:cc:bc:d3:a6:0a:af:d4:ea:14:72:
+ f1:00:13:ff:5a:a1:a1:d4:2e:89:76:98:23:28:60:1e:7f:6b:
+ 0c:a7:41:f6:56:d3:48:60:7a:63:9d:11:19:b7:57:60:b2:2a:
+ 23:a4:16:42:2f:9a:41:f3:3d:51:69:fc:30:c1:b2:34:26:89:
+ c3:b6:13:19:b9:ee:10:2c:52:36:b5:89:37:4b:ae:5a:76:b0:
+ ec:2c:c7:0f:8b:88:51:61:06:b7:9e:3b:df:d4:8e:2f:43:2d:
+ 34:79:51:5f:19:4c:21:b4:fc:db:99:c4:08:11:a1:5c:80:31:
+ 84:74:b5:0d:e2:3d:a4:e9:59:8d:f6:98:53:34:f1:df:18:0f:
+ c8:ce:42:47:fd:7d:3a:8b:c3:65:4e:e6:a1:40:0b:8b:0b:b4:
+ 5c:dd:1b:d2:56:c2:52:ab:08:c1:36:e4:e9:f4:b8:63:4f:f6:
+ 98:20:95:07:e5:d0:b3:f7:99:b4:ed:c7:ce:6a:3b:bb:19:94:
+ df:a5:ef:ce
-----BEGIN CERTIFICATE-----
-MIICtzCCAiCgAwIBAgIJANG2v68GF4zBMA0GCSqGSIb3DQEBBQUAME8xCzAJBgNV
-BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMREwDwYDVQQKEwhNMkNyeXB0bzEY
-MBYGA1UEAxMPSGVpa2tpIFRvaXZvbmVuMB4XDTA5MDcyODA0MzkxOVoXDTE5MDcy
-NjA0MzkxOVowbzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExETAP
-BgNVBAoTCE0yQ3J5cHRvMRIwEAYDVQQDEwlSZWNpcGllbnQxJDAiBgkqhkiG9w0B
-CQEWFXJlY2lwaWVudEBleGFtcGxlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAw
-gYkCgYEAwiGjT2RZnCE5IdI85wpgcsg5s8MnSm1Wj6BdG8bkPiZhCamuBINpP50r
-En7U947QbqmMm9G/Fwy90HOZAm5+y3qALc+xKcAwNj9oEj5Ov/mLPR1WrySUrtVZ
-tABQDMArWcOZs4oZ8YYUve7pxPHXagzpZ4qUmi0tYCUixnJowg0CAwEAAaN7MHkw
-CQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2Vy
-dGlmaWNhdGUwHQYDVR0OBBYEFBHLYKxVhVKExcggWlAT0InHereBMB8GA1UdIwQY
-MBaAFK1kRXSPg8cs1deghZEQQJqcls/uMA0GCSqGSIb3DQEBBQUAA4GBAIdWF226
-O6bEIq8g8aDlnSfEUL1569KE5ZoAX11awzRYd/WpAPl26S2JtD+d488VDGQbCgPb
-5G8r/xyCiRoPfoNYD+baryaXSUpZ12E/S+0dW1EAO4OWxx49hPSRH3BpErmnLFsb
-Bc10kCuguudwzWt9rL7XklDp9cBCKQTvj6Fo
+MIIDZTCCAk2gAwIBAgIBBDANBgkqhkiG9w0BAQsFADBPMQswCQYDVQQGEwJVUzET
+MBEGA1UECAwKQ2FsaWZvcm5pYTERMA8GA1UECgwITTJDcnlwdG8xGDAWBgNVBAMM
+D0hlaWtraSBUb2l2b25lbjAeFw0xODEwMDcxNTEyMDJaFw0yODEwMDQxNTEyMDJa
+MG8xCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMREwDwYDVQQKDAhN
+MkNyeXB0bzESMBAGA1UEAwwJUmVjaXBpZW50MSQwIgYJKoZIhvcNAQkBFhVyZWNp
+cGllbnRAZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
+AQDPxoMrjOpOEHxaxkUHRfKmF1Uz9Ogk305V3j0M5qCl4LDrvQ5VL07zaTjwMR0N
+VAw51to3iUyrwZwQn43h5sHrrZfAiqJPb+YQoK3yoBFOWBYlgTpbfWy04HaD8mfr
+F75E2Vo4LCy29RrT9UiFalCB8XQLsSKSzekf+6Md7AO+G2YF6SROCtd/NaOS2ACZ
+BumtMqDff3LQ3oL4p3zXQXNol37z3upz5n4L2OumTuuiIOAuWopeebHd4aZkPqJ6
+cL5qW2Xou6DQTACzpKovwwowTZ7RicLAZ1GgE6HTCqTbgoWW3ckGSWjHNua6YCre
+cTZcOxap/sjjkUhqYgXBuBHvAgMBAAGjLDAqMAkGA1UdEwQCMAAwHQYDVR0OBBYE
+FCTBsYN5MV5UXmBlBBf7dtMhhTtoMA0GCSqGSIb3DQEBCwUAA4IBAQARVOkdtFs2
+2EBjRVj56ClT/z7JOiqJt5iZUNQplgPifhYc94Yto5Iq2GAW0UglXZplPicWwsrZ
+IGKI10F6nsy806YKr9TqFHLxABP/WqGh1C6JdpgjKGAef2sMp0H2VtNIYHpjnREZ
+t1dgsiojpBZCL5pB8z1RafwwwbI0JonDthMZue4QLFI2tYk3S65adrDsLMcPi4hR
+YQa3njvf1I4vQy00eVFfGUwhtPzbmcQIEaFcgDGEdLUN4j2k6VmN9phTNPHfGA/I
+zkJH/X06i8NlTuahQAuLC7Rc3RvSVsJSqwjBNuTp9LhjT/aYIJUH5dCz95m07cfO
+aju7GZTfpe/O
-----END CERTIFICATE-----
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpQIBAAKCAQEAz8aDK4zqThB8WsZFB0XyphdVM/ToJN9OVd49DOagpeCw670O
+VS9O82k48DEdDVQMOdbaN4lMq8GcEJ+N4ebB662XwIqiT2/mEKCt8qARTlgWJYE6
+W31stOB2g/Jn6xe+RNlaOCwstvUa0/VIhWpQgfF0C7Eiks3pH/ujHewDvhtmBekk
+TgrXfzWjktgAmQbprTKg339y0N6C+Kd810FzaJd+897qc+Z+C9jrpk7roiDgLlqK
+Xnmx3eGmZD6ienC+altl6Lug0EwAs6SqL8MKME2e0YnCwGdRoBOh0wqk24KFlt3J
+BkloxzbmumAq3nE2XDsWqf7I45FIamIFwbgR7wIDAQABAoIBAQC2CdvkrSqfyKvb
+MDlMXQlyYaEBy4IUxB0y+GqOwgVgL9NyRwqmsbM/aiI7txwYEFpB1q8L11x4Y0Hk
+ApbhpDak0UvSouQAKy7rxIuCtqFS/bQxmd5SSDqU4tCTXC+V9xB56+CytGlcxrSB
+njayxWnR34VntQNwkb29is/oKF9DD9MAGv16B6l8sNCO5tCEKVR0YxLdrkVzWlgm
+unyZqUmdN+n4YdPNYYxm5IcJHR++X+0evXiQO3sPOz8IlFgPj7NZB8DFUjQh1ToH
+srwQihg2T7eusasLL7g9dv2m5yySAjmkfN1L3T8T/WIQRYu8xLaFHGpOa3NukQ6o
+CurR314JAoGBAPhQYlzzTnimrmfFcOxMdpIoRtW9b0YB8u/hY/TBrCHzciO31hJS
+HRJuqgHLhdu52ke8sJlWsQ3+vv4osyVBPe+vodwFJu+c1OJ5PXPp58oD8TboGgGX
+qCEKh96BOZ7MZoiRs9smmKDc/5S17Qsppq3tuAqMSlDEXNbxtVZC5L0bAoGBANY0
+55G10SUDfRN9govEly/zorEIy+gWW+PEKzIkeZpsIzKZTUa5F4CTX/4TSD/FZPAB
+TJo4nfQdvVi1OlDQLRnjAsq7f9sWiq2MyZx0eSy5RCpSKNyft6BX6mt+M4EdssQT
+/GMVU+qAprXNuC5J1dRR4CNT1g0MLa7oj7Xs6a+9AoGAfpVz31CFI0pNREdJjpxY
+IZ/4pENCs1yQ/KpYq1ADsPcKq5yuu34ypc/WSL34yg9PcByHplOkRK8lrCkRUh+V
+NFfDWoch1yqK97y4kBugdsJVuBjQERm/ssBMjSgxOHuYlWw5VLGzQuYGQEgRxAwC
+lU3G8VGdHNlNPqHPQF8vfhsCgYEAvquY9TrCUBAq5Y5zBbaYXTahOrR5zL0aTkPv
+r1KIa8yWCBQtlSZspSaJ679+MEWk8340kZKUBxfx02R95DFp9AD+GzeLN5l5F8Ka
+M4n50rWW15UKilghO7kGEWjkr6mf1qlznz7802BxBKN5rrpKfBPlT4zwm+ybPXYF
+dgrMeIECgYEAgbmkN4rxUEb9FFteSG0avH5CxY4iBqQSyxmi7XASgHjlkD8n9yRR
+IrLlSK01XNKTtZ3ZGxWSUvLIJsfTaBDXpZGMpi53blLbXf9jUaU/DaXXS2pLNHdJ
+h0qLNRt9bkQ/1tHUwhptkkI5P6U7ErkWbcB9YCg8LXm8SlgebZUJvHQ=
+-----END RSA PRIVATE KEY-----
diff --git a/tests/recipient_key.pem b/tests/recipient_key.pem
index 5bf0f70..70ef775 100644
--- a/tests/recipient_key.pem
+++ b/tests/recipient_key.pem
@@ -1,15 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
-MIICXAIBAAKBgQDCIaNPZFmcITkh0jznCmByyDmzwydKbVaPoF0bxuQ+JmEJqa4E
-g2k/nSsSftT3jtBuqYyb0b8XDL3Qc5kCbn7LeoAtz7EpwDA2P2gSPk6/+Ys9HVav
-JJSu1Vm0AFAMwCtZw5mzihnxhhS97unE8ddqDOlnipSaLS1gJSLGcmjCDQIDAQAB
-AoGAZlrJ+kAUpyc1Mkng5ogoFhzPn6ITg0Bm1U9eCBkzmjkuDKQ0JhkLUwkQ/q10
-qBnad55ZjoZmVEbZhaCNWiTcIIy0nKAMWNKRcg3vTgrnbmbjco1HECDStfJKogZl
-7egoIImHnU1f/IeKQDUYUfs/INonmnnZ1d2jrU7QsdTz84ECQQDzhT0UwP8S1oma
-0IBgeUOt5ptZs7nFdZnbIKCd+ADra6NiQznokCHe5K0WZHqPKvN9asKx1u0h+97H
-Wmk6Fw7RAkEAzBR1+mTRSrlJT8/NTCsIDPtCK/+OhmGbNy1pfsOWq1lN58Za5HV7
-fmtaH2No+MP+DlfNigsg557GzAYl2ZumfQJAHQj33W+dehuGUKUniVksDqH+R9W8
-AqUg8RWU0QDu6yLsWhz13JrCzxao5JCaZFOUsJF4IUglAfZL+6z1+u0g4QJAH5aL
-LFaujoJfdpsTi9adSGUbuPO1e9dfzwqYaaaci6knBdkN+I62rrqvGGyqstajXFT6
-24MddLx+yNWqxiPxgQJBAKF8YiR4eLqLSnq4ftqCqVCC1XbA2H9b7G5RBWi00WFq
-3Nx+B/wjLzbqsMamTCIDUCEW+MzFx6otCxduDZRMKH8=
+MIIEpQIBAAKCAQEAz8aDK4zqThB8WsZFB0XyphdVM/ToJN9OVd49DOagpeCw670O
+VS9O82k48DEdDVQMOdbaN4lMq8GcEJ+N4ebB662XwIqiT2/mEKCt8qARTlgWJYE6
+W31stOB2g/Jn6xe+RNlaOCwstvUa0/VIhWpQgfF0C7Eiks3pH/ujHewDvhtmBekk
+TgrXfzWjktgAmQbprTKg339y0N6C+Kd810FzaJd+897qc+Z+C9jrpk7roiDgLlqK
+Xnmx3eGmZD6ienC+altl6Lug0EwAs6SqL8MKME2e0YnCwGdRoBOh0wqk24KFlt3J
+BkloxzbmumAq3nE2XDsWqf7I45FIamIFwbgR7wIDAQABAoIBAQC2CdvkrSqfyKvb
+MDlMXQlyYaEBy4IUxB0y+GqOwgVgL9NyRwqmsbM/aiI7txwYEFpB1q8L11x4Y0Hk
+ApbhpDak0UvSouQAKy7rxIuCtqFS/bQxmd5SSDqU4tCTXC+V9xB56+CytGlcxrSB
+njayxWnR34VntQNwkb29is/oKF9DD9MAGv16B6l8sNCO5tCEKVR0YxLdrkVzWlgm
+unyZqUmdN+n4YdPNYYxm5IcJHR++X+0evXiQO3sPOz8IlFgPj7NZB8DFUjQh1ToH
+srwQihg2T7eusasLL7g9dv2m5yySAjmkfN1L3T8T/WIQRYu8xLaFHGpOa3NukQ6o
+CurR314JAoGBAPhQYlzzTnimrmfFcOxMdpIoRtW9b0YB8u/hY/TBrCHzciO31hJS
+HRJuqgHLhdu52ke8sJlWsQ3+vv4osyVBPe+vodwFJu+c1OJ5PXPp58oD8TboGgGX
+qCEKh96BOZ7MZoiRs9smmKDc/5S17Qsppq3tuAqMSlDEXNbxtVZC5L0bAoGBANY0
+55G10SUDfRN9govEly/zorEIy+gWW+PEKzIkeZpsIzKZTUa5F4CTX/4TSD/FZPAB
+TJo4nfQdvVi1OlDQLRnjAsq7f9sWiq2MyZx0eSy5RCpSKNyft6BX6mt+M4EdssQT
+/GMVU+qAprXNuC5J1dRR4CNT1g0MLa7oj7Xs6a+9AoGAfpVz31CFI0pNREdJjpxY
+IZ/4pENCs1yQ/KpYq1ADsPcKq5yuu34ypc/WSL34yg9PcByHplOkRK8lrCkRUh+V
+NFfDWoch1yqK97y4kBugdsJVuBjQERm/ssBMjSgxOHuYlWw5VLGzQuYGQEgRxAwC
+lU3G8VGdHNlNPqHPQF8vfhsCgYEAvquY9TrCUBAq5Y5zBbaYXTahOrR5zL0aTkPv
+r1KIa8yWCBQtlSZspSaJ679+MEWk8340kZKUBxfx02R95DFp9AD+GzeLN5l5F8Ka
+M4n50rWW15UKilghO7kGEWjkr6mf1qlznz7802BxBKN5rrpKfBPlT4zwm+ybPXYF
+dgrMeIECgYEAgbmkN4rxUEb9FFteSG0avH5CxY4iBqQSyxmi7XASgHjlkD8n9yRR
+IrLlSK01XNKTtZ3ZGxWSUvLIJsfTaBDXpZGMpi53blLbXf9jUaU/DaXXS2pLNHdJ
+h0qLNRt9bkQ/1tHUwhptkkI5P6U7ErkWbcB9YCg8LXm8SlgebZUJvHQ=
-----END RSA PRIVATE KEY-----
diff --git a/tests/sample-p7.pem b/tests/sample-p7.pem
new file mode 100644
index 0000000..46034f0
--- /dev/null
+++ b/tests/sample-p7.pem
@@ -0,0 +1,102 @@
+MIME-Version: 1.0
+Content-Type: multipart/signed; protocol="application/x-pkcs7-signature"; micalg="sha-256"; boundary="----38FBD2321B4A76C8BE88AFD029CDED23"
+
+This is an S/MIME signed message
+
+------38FBD2321B4A76C8BE88AFD029CDED23
+This directory contains unit tests for M2Crypto.
+
+To run all tests, make sure you have installed setuptools and then issue the
+following command from the M2Crypto root directory:
+
+python setup.py test
+
+To run tests in a single file, for example test_ssl.py, do this:
+
+python setup.py test --test-suite=tests.test_ssl
+
+
+Look also in the demo directory for other samples.
+
+
+To create new test certificates:
+
+mkdir certs
+cd certs
+
+Making the CA. You may want to use a locally edited openssl.cnf to
+make sure that X509v3 Basic Constraints CA:TRUE gets set (by default
+it may be false). By default duration may only be just one year; should
+set this for at least 3 years.
+
+CA.sh -newca
+cp demoCA/cacert.pem ../ca.pem
+
+Making the server certificate and private key. make sure commonName
+field is localhost.
+
+CA.sh -newreq
+CA.sh -signreq
+cp newcert.pem ../server.pem
+openssl rsa <newkey.pem >>../server.pem
+
+Making the x509 certificate and key.
+
+CA.sh -newreq
+CA.sh -signreq
+cp newcert.pem ../x509.pem
+openssl rsa <newkey.pem >>../x509.pem
+openssl x509 -in ../x509.pem -out ../x509.der -outform DER
+
+Making the signer certificate. Make sure the email address is
+signer@example.com.
+
+CA.sh -newreq
+CA.sh -signreq
+cp newcert.pem ../signer.pem
+openssl rsa <newkey.pem >../signer_key.pem
+
+Making the recipient certificate. Make sure the email address is
+recipient@example.com.
+
+CA.sh -newreq
+CA.sh -signreq
+cp newcert.pem ../recipient.pem
+openssl rsa <newkey.pem >../recipient_key.pem
+
+
+Finally run the tests and edit for new values.
+
+------38FBD2321B4A76C8BE88AFD029CDED23
+Content-Type: application/x-pkcs7-signature; name="smime.p7s"
+Content-Transfer-Encoding: base64
+Content-Disposition: attachment; filename="smime.p7s"
+
+MIIEhQYJKoZIhvcNAQcCoIIEdjCCBHICAQExDzANBglghkgBZQMEAgEFADALBgkq
+hkiG9w0BBwGgggJkMIICYDCCAcmgAwIBAgIBBDANBgkqhkiG9w0BAQUFADBPMQsw
+CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTERMA8GA1UEChMITTJDcnlw
+dG8xGDAWBgNVBAMTD0hlaWtraSBUb2l2b25lbjAeFw0xNTExMjYyMTMzMTJaFw0y
+NTExMjMyMTMzMTJaMG8xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh
+MREwDwYDVQQKEwhNMkNyeXB0bzESMBAGA1UEAxMJUmVjaXBpZW50MSQwIgYJKoZI
+hvcNAQkBFhVyZWNpcGllbnRAZXhhbXBsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQAD
+gY0AMIGJAoGBAJaMhIx8GBrTwmJdDwilmD2LkUw0b80Vr1Ycffk2pgE8nGPPIGT6
+dySl4cv+j1rAqJAbmaMCakPv+TGseQH5zEYRfKrRh9+V1PGkesv8TC6LMyL1M/hT
+augiSBiW8kk5/zOZA+U9wiJS8TOWILzRyCG7S3U9Kz1RTqoP1XNdZkS/AgMBAAGj
+LDAqMAkGA1UdEwQCMAAwHQYDVR0OBBYEFFON3U+KXkkZq9wvnavqx8PK9vXUMA0G
+CSqGSIb3DQEBBQUAA4GBABCx3TS7lz4+2ODeapnJvoy3gMcdMNs6aNWk2QJ2K3Zi
+AIYwWgYDZZK5AKRClF90xpRELowHVfPBbnoKF2ZW71Cvo1/x95dmKdO0FBM0eZaY
+rVjbIOb8+nCsHCKQv3vD6uOKCr26SP/lyVCDGNkeYTDAx2zqM/7Q/Kga8Zuj3JEQ
+MYIB5TCCAeECAQEwVDBPMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5p
+YTERMA8GA1UEChMITTJDcnlwdG8xGDAWBgNVBAMTD0hlaWtraSBUb2l2b25lbgIB
+BDANBglghkgBZQMEAgEFAKCB5DAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwG
+CSqGSIb3DQEJBTEPFw0xODA3MjMxODExNTNaMC8GCSqGSIb3DQEJBDEiBCAFNpRM
+82d8yvtEyK+nEYuCf5KuyfnooeJYkzIbqUb2yDB5BgkqhkiG9w0BCQ8xbDBqMAsG
+CWCGSAFlAwQBKjALBglghkgBZQMEARYwCwYJYIZIAWUDBAECMAoGCCqGSIb3DQMH
+MA4GCCqGSIb3DQMCAgIAgDANBggqhkiG9w0DAgIBQDAHBgUrDgMCBzANBggqhkiG
+9w0DAgIBKDANBgkqhkiG9w0BAQEFAASBgEEVB6XZeD44cN+6qmj1LR5Jh6JLGnIQ
+eQPGrI8Ygymc1dVDWC72872Xp3UTidhMnCyN36QNBZ7GL63tc2mCZ9rgWE24mvqx
+cj5hCyXF240ty20igJe5BDaXHgzO0JGJPUtoOxNWrM40IhGxh9MSGlfioMOsuRD4
+gDf9hUfjCkvG
+
+------38FBD2321B4A76C8BE88AFD029CDED23--
+
diff --git a/tests/server.pem b/tests/server.pem
index 825abc6..681528d 100644
--- a/tests/server.pem
+++ b/tests/server.pem
@@ -1,75 +1,101 @@
Certificate:
Data:
Version: 3 (0x2)
- Serial Number:
- d1:b6:bf:af:06:17:8c:be
- Signature Algorithm: sha1WithRSAEncryption
+ Serial Number: 1 (0x1)
+ Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, ST=California, O=M2Crypto, CN=Heikki Toivonen
Validity
- Not Before: Jul 28 04:31:41 2009 GMT
- Not After : Jul 26 04:31:41 2019 GMT
+ Not Before: Oct 7 15:12:02 2018 GMT
+ Not After : Oct 4 15:12:02 2028 GMT
Subject: C=US, ST=California, O=M2Crypto, CN=localhost
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
- RSA Public Key: (1024 bit)
- Modulus (1024 bit):
- 00:d4:99:6f:33:3f:e6:ac:0a:34:d8:0e:45:97:f3:
- 2b:6a:50:2a:84:30:0a:52:9c:15:30:9f:05:29:3a:
- 21:f4:c1:c3:01:9e:2f:55:56:4e:35:ac:f1:16:1e:
- 26:8d:b5:26:b7:99:78:92:ea:1c:74:46:ab:41:12:
- ef:cc:53:62:cc:59:5c:9e:c4:86:df:d9:25:35:55:
- 05:4b:16:ff:d9:90:e3:f4:51:b4:b4:fa:c5:98:4b:
- 60:f0:60:7f:14:4e:1e:dd:61:9b:22:a2:9c:21:17:
- 43:a3:cb:07:80:f5:75:59:9c:55:1c:fe:e0:66:d4:
- 70:77:5e:13:06:0c:05:c7:1f
+ RSA Public-Key: (2048 bit)
+ Modulus:
+ 00:f4:f3:38:31:09:92:0d:5d:8b:06:f0:43:e0:62:
+ 62:e1:71:eb:30:ba:d7:b9:57:db:8c:10:9b:9e:1e:
+ 76:45:ab:14:92:54:d4:47:34:ab:0f:95:f3:83:c5:
+ f1:45:75:58:72:0a:e1:67:77:d0:d3:7e:6a:6f:5d:
+ 1a:a4:df:aa:96:c0:0f:8d:0a:95:9e:aa:e5:bc:7a:
+ 6f:ab:61:41:75:31:0c:da:a6:d5:0d:b3:42:f0:20:
+ f6:2c:74:69:39:79:90:a0:c9:c2:23:ba:5a:c5:9c:
+ 8f:fa:4f:06:bb:04:8e:2d:a1:36:82:c4:23:99:18:
+ 1a:b7:56:0f:8a:ef:ff:57:22:51:96:ca:69:8f:a3:
+ ae:91:b7:84:02:07:be:4d:55:f2:1c:f9:11:2a:ff:
+ 20:ab:0f:27:fb:79:75:6c:b2:53:e3:04:ea:4f:e5:
+ 51:3f:1e:b0:b5:7f:fa:de:0f:f6:e8:e6:85:a3:17:
+ 8c:b1:a6:dd:fc:e9:b8:92:d5:1c:73:d7:82:6e:60:
+ 6c:10:b3:22:ca:a5:d8:c5:d2:41:93:b3:57:3f:1b:
+ cf:cf:78:4c:15:85:b1:ca:b6:84:13:1b:8f:42:ed:
+ 21:bb:90:a2:b7:39:9d:68:bf:4d:da:31:06:53:98:
+ e3:de:8f:f8:3e:7d:25:f2:75:7e:d3:09:e4:eb:4d:
+ 59:c9
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
- Netscape Comment:
- OpenSSL Generated Certificate
X509v3 Subject Key Identifier:
- 04:05:3D:6A:A7:E8:D7:52:BD:2F:C4:52:30:7C:2C:BD:D3:81:46:C6
- X509v3 Authority Key Identifier:
- keyid:AD:64:45:74:8F:83:C7:2C:D5:D7:A0:85:91:10:40:9A:9C:96:CF:EE
-
- Signature Algorithm: sha1WithRSAEncryption
- ac:2b:ad:86:36:96:5c:fb:34:2c:02:ca:d9:5f:a7:8e:b6:58:
- 24:1d:27:b6:8e:81:aa:69:0e:60:26:64:2e:72:a1:ff:d8:ba:
- bb:7e:5d:46:c7:07:2d:a8:c8:4c:df:1e:ba:c8:bc:21:5b:f2:
- b3:01:4c:d6:3b:10:fd:49:70:e6:83:01:f3:24:e2:a9:97:d7:
- c3:9c:5b:2d:d7:64:2b:e5:e2:0e:3e:d9:8c:e6:93:86:39:32:
- 50:43:5f:36:4a:3b:b0:05:e7:65:a3:b3:ef:50:56:7f:7e:dc:
- f0:65:83:ac:42:7e:97:a0:c0:7e:63:c6:c8:c6:35:d3:60:d1:
- 4f:51
+ 56:FF:B6:FD:ED:A3:76:04:AA:CB:1F:25:FB:A5:8D:9D:9A:D5:85:D3
+ Signature Algorithm: sha256WithRSAEncryption
+ 53:99:54:2e:26:26:0c:81:b2:c6:5c:61:6f:1c:60:28:ed:f3:
+ 1b:74:8e:e8:c1:3c:b5:35:e3:db:51:07:38:43:b0:57:0b:e5:
+ 7e:fa:0a:9e:bd:bd:82:5a:ed:9b:67:0d:2b:61:4d:44:58:64:
+ a2:fe:bc:fb:90:80:d2:6b:e4:25:09:ea:ca:a1:17:e6:33:31:
+ 09:62:b6:db:4c:21:f3:52:02:7d:ca:9a:f9:42:04:50:b4:d8:
+ a6:49:ea:bd:c0:13:05:c6:c4:d2:59:d6:30:87:80:c6:a3:92:
+ 45:49:02:43:9c:4a:aa:c1:84:d0:ea:01:29:40:73:87:cd:8e:
+ aa:93:d3:33:7e:01:cf:b5:c1:4b:35:e7:20:1f:6d:7a:c5:d4:
+ a9:4a:c1:e2:26:f5:b7:a2:f5:04:31:45:74:30:9a:51:e7:19:
+ 62:e4:d1:ab:f9:36:29:58:ec:90:f9:8c:3b:28:39:28:d7:8a:
+ a0:c3:ae:aa:a9:c2:05:6e:a9:f4:b6:62:1b:01:db:f9:3e:b9:
+ a4:d7:05:ac:76:b8:8a:12:57:b3:66:de:b0:d2:78:0d:07:9c:
+ 15:1b:85:84:76:31:23:64:ce:1e:7f:be:1e:cc:d9:9f:c0:0c:
+ 9c:20:b9:f0:2e:09:04:ca:d0:61:fc:ce:ba:df:28:c8:20:c8:
+ fb:63:1d:52
-----BEGIN CERTIFICATE-----
-MIICkTCCAfqgAwIBAgIJANG2v68GF4y+MA0GCSqGSIb3DQEBBQUAME8xCzAJBgNV
-BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMREwDwYDVQQKEwhNMkNyeXB0bzEY
-MBYGA1UEAxMPSGVpa2tpIFRvaXZvbmVuMB4XDTA5MDcyODA0MzE0MVoXDTE5MDcy
-NjA0MzE0MVowSTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExETAP
-BgNVBAoTCE0yQ3J5cHRvMRIwEAYDVQQDEwlsb2NhbGhvc3QwgZ8wDQYJKoZIhvcN
-AQEBBQADgY0AMIGJAoGBANSZbzM/5qwKNNgORZfzK2pQKoQwClKcFTCfBSk6IfTB
-wwGeL1VWTjWs8RYeJo21JreZeJLqHHRGq0ES78xTYsxZXJ7Eht/ZJTVVBUsW/9mQ
-4/RRtLT6xZhLYPBgfxROHt1hmyKinCEXQ6PLB4D1dVmcVRz+4GbUcHdeEwYMBccf
-AgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2Vu
-ZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBQEBT1qp+jXUr0vxFIwfCy904FG
-xjAfBgNVHSMEGDAWgBStZEV0j4PHLNXXoIWREECanJbP7jANBgkqhkiG9w0BAQUF
-AAOBgQCsK62GNpZc+zQsAsrZX6eOtlgkHSe2joGqaQ5gJmQucqH/2Lq7fl1Gxwct
-qMhM3x66yLwhW/KzAUzWOxD9SXDmgwHzJOKpl9fDnFst12Qr5eIOPtmM5pOGOTJQ
-Q182SjuwBedlo7PvUFZ/ftzwZYOsQn6XoMB+Y8bIxjXTYNFPUQ==
+MIIDPzCCAiegAwIBAgIBATANBgkqhkiG9w0BAQsFADBPMQswCQYDVQQGEwJVUzET
+MBEGA1UECAwKQ2FsaWZvcm5pYTERMA8GA1UECgwITTJDcnlwdG8xGDAWBgNVBAMM
+D0hlaWtraSBUb2l2b25lbjAeFw0xODEwMDcxNTEyMDJaFw0yODEwMDQxNTEyMDJa
+MEkxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMREwDwYDVQQKDAhN
+MkNyeXB0bzESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOC
+AQ8AMIIBCgKCAQEA9PM4MQmSDV2LBvBD4GJi4XHrMLrXuVfbjBCbnh52RasUklTU
+RzSrD5Xzg8XxRXVYcgrhZ3fQ035qb10apN+qlsAPjQqVnqrlvHpvq2FBdTEM2qbV
+DbNC8CD2LHRpOXmQoMnCI7paxZyP+k8GuwSOLaE2gsQjmRgat1YPiu//VyJRlspp
+j6OukbeEAge+TVXyHPkRKv8gqw8n+3l1bLJT4wTqT+VRPx6wtX/63g/26OaFoxeM
+sabd/Om4ktUcc9eCbmBsELMiyqXYxdJBk7NXPxvPz3hMFYWxyraEExuPQu0hu5Ci
+tzmdaL9N2jEGU5jj3o/4Pn0l8nV+0wnk601ZyQIDAQABoywwKjAJBgNVHRMEAjAA
+MB0GA1UdDgQWBBRW/7b97aN2BKrLHyX7pY2dmtWF0zANBgkqhkiG9w0BAQsFAAOC
+AQEAU5lULiYmDIGyxlxhbxxgKO3zG3SO6ME8tTXj21EHOEOwVwvlfvoKnr29glrt
+m2cNK2FNRFhkov68+5CA0mvkJQnqyqEX5jMxCWK220wh81ICfcqa+UIEULTYpknq
+vcATBcbE0lnWMIeAxqOSRUkCQ5xKqsGE0OoBKUBzh82OqpPTM34Bz7XBSzXnIB9t
+esXUqUrB4ib1t6L1BDFFdDCaUecZYuTRq/k2KVjskPmMOyg5KNeKoMOuqqnCBW6p
+9LZiGwHb+T65pNcFrHa4ihJXs2besNJ4DQecFRuFhHYxI2TOHn++HszZn8AMnCC5
+8C4JBMrQYfzOut8oyCDI+2MdUg==
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
-MIICXgIBAAKBgQDUmW8zP+asCjTYDkWX8ytqUCqEMApSnBUwnwUpOiH0wcMBni9V
-Vk41rPEWHiaNtSa3mXiS6hx0RqtBEu/MU2LMWVyexIbf2SU1VQVLFv/ZkOP0UbS0
-+sWYS2DwYH8UTh7dYZsiopwhF0OjyweA9XVZnFUc/uBm1HB3XhMGDAXHHwIDAQAB
-AoGBALBHrSm8kYMTT2/anZ/5tIUJhcdnohePbg6LvJbLqf4tb4l25V6IGn9tL9Yc
-F/GmRD02VwDSd9d+BWAG2Kj+d0rfdCLfKY9O8PVVm0DF6grLZ7ugItYqUHRDYOdV
-MOVOQrx+mCIzHtoEtQ6HLqmqt2rIX731L1TA7OLNm3XHyISJAkEA/mgNNNg0e23G
-64z83yxxwPEnBrnKd1+xjH9QJ0Z9SJJuF4sNXRIFA4YUNvv2MNe3gMS4Hg9w78HL
-PwcEzLnO9QJBANXuWAZGV58CdkM2w7H9+ukxMbQeLSnmgjpdddo31qqbfgFAYZMK
-LppRqyosj+a2qQ6vua0ndstTImSi7KPmCUMCQQDbwr5Fu836ISYIK830aswIw0fX
-A37mB3+zwfZXNwjaO8NmCvQMRZiXJqcnqBdOsckOLuBs9yGzuk/7rfBzeL5RAkA2
-uBcly7o/vsZ3HLvjfB5ApUecVZehvwcSXLN3VI8A5nLNaSVMEe+nozoPuIQ6NAB7
-9DCe/JgjG6mRaibzKTS3AkEAjTl5MTKkYR78+2u3NRU/ypa1iKCicSvI/Ryw7p/z
-Q8XmVA0CmNRvltf9gA1gJ04ZijBPtl+s09uppaCw9L3vuA==
+MIIEpAIBAAKCAQEA9PM4MQmSDV2LBvBD4GJi4XHrMLrXuVfbjBCbnh52RasUklTU
+RzSrD5Xzg8XxRXVYcgrhZ3fQ035qb10apN+qlsAPjQqVnqrlvHpvq2FBdTEM2qbV
+DbNC8CD2LHRpOXmQoMnCI7paxZyP+k8GuwSOLaE2gsQjmRgat1YPiu//VyJRlspp
+j6OukbeEAge+TVXyHPkRKv8gqw8n+3l1bLJT4wTqT+VRPx6wtX/63g/26OaFoxeM
+sabd/Om4ktUcc9eCbmBsELMiyqXYxdJBk7NXPxvPz3hMFYWxyraEExuPQu0hu5Ci
+tzmdaL9N2jEGU5jj3o/4Pn0l8nV+0wnk601ZyQIDAQABAoIBAQCgFpWS9v5NXeWP
+E1hJPgQB88IShwqWR6VlVTVfkekaf0Vina5fGzzxYr9UT/nvu1Gitxm51cTVdLl7
+Lw5K0yNagwum0lQW7vpWxG5XQ6jUPsp33LFB0vbcma5KP4rF1X2AmFwZnaHVpQ00
+OpHbiI6jo8lMjYP2epp7V/OwikoHV0873HTmuq2Y+jUvRM3o01moDtuF5mKofNEd
+ft9lArRG8yjLgC5G1C9cmiATGoMGyHBRkEv+UrUWLHVxrpXviUd+/iJmhrwXcpvj
+rTrZWbUkSA3i4JMml/qYqNQYeVUFVgV/slD331iIwlWP8RipXF5YqN+YGjGeqL0+
+yQ4KWtABAoGBAP7XvGBUWNBSBrqioTzqYMTbwz/YjXJkvlO09wwc/UkraYlSihi0
+2J1dKBePIfOk6gFbuiJNYMJvAt1hBCsN0Z6o/bH7CiOh/55nkTaL0R4zB38uuDDx
+4qf6+9HT1eC9yW3UJVPwBBwI4WZmmq4peQoipBtKwpY2Q+yoUU3gp4KhAoGBAPYP
++6uv3gQYoIpkUD2ZdX8kFoaC6rJMP3Z/N75NfsOz1Tx3nNwexYM6EVVQrvTRWpLZ
+rJyCgCJi9HY4lPASKSKM1cLCT/M3SdR8OiqlEjziZtSH/di6wq8/Hfqhf75nC7sK
+wV7Ic0eQ3Bjg2hggPpjeBJTv8NIlCYbWbxHnsK4pAoGAY0I39vUjWpB4Wn05e/Z2
+FnbaR6XbAfFHSGc1yhwIc1VbV8c0Tocxz6kXEoYHXVSgaEMH7pBg3ZpLbVp6OyK4
+wKlllssGmfZhD5ubLbmri62of9r8luO/ulnBd2qg5VZGfGai21yi3SCAWlggazFw
+GYiAjrjBrawZLLYqZMDZvcECgYBoi6/taWKWMPR8+FQTaBFA/M9JRXR8XuMT8Md5
+Zqm2csDl2Rhfef+HWvOkYQyE3jJydGPfd58DfTHKzQ2S1tR9ZoMoJbEccGBBFKsO
+FWajUbpJEKKtI+S12sZdB6Mj/dpBFTfFkrtQK98n/tkLKSAPiT0/HpceYjgi/xbf
+76XkyQKBgQCkAuuTYi/9vlqYBcUH+23f0XmzQ6NNCqi0JxrnUmPv0Mc/ci7QfBZ6
+BkjPxfllpAsDihfTFpfp6p1PCMpASq1J+w1yR+lnKgw9BlbBLT4SqSVVDiju0cfw
+njm6zQu7IR6Ts/vi+YbVqn3yeP8U5W9as7QL5y6KeYfAhwuPqWhvog==
-----END RSA PRIVATE KEY-----
diff --git a/tests/server_key.pem b/tests/server_key.pem
new file mode 100644
index 0000000..5994dc4
--- /dev/null
+++ b/tests/server_key.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEA9PM4MQmSDV2LBvBD4GJi4XHrMLrXuVfbjBCbnh52RasUklTU
+RzSrD5Xzg8XxRXVYcgrhZ3fQ035qb10apN+qlsAPjQqVnqrlvHpvq2FBdTEM2qbV
+DbNC8CD2LHRpOXmQoMnCI7paxZyP+k8GuwSOLaE2gsQjmRgat1YPiu//VyJRlspp
+j6OukbeEAge+TVXyHPkRKv8gqw8n+3l1bLJT4wTqT+VRPx6wtX/63g/26OaFoxeM
+sabd/Om4ktUcc9eCbmBsELMiyqXYxdJBk7NXPxvPz3hMFYWxyraEExuPQu0hu5Ci
+tzmdaL9N2jEGU5jj3o/4Pn0l8nV+0wnk601ZyQIDAQABAoIBAQCgFpWS9v5NXeWP
+E1hJPgQB88IShwqWR6VlVTVfkekaf0Vina5fGzzxYr9UT/nvu1Gitxm51cTVdLl7
+Lw5K0yNagwum0lQW7vpWxG5XQ6jUPsp33LFB0vbcma5KP4rF1X2AmFwZnaHVpQ00
+OpHbiI6jo8lMjYP2epp7V/OwikoHV0873HTmuq2Y+jUvRM3o01moDtuF5mKofNEd
+ft9lArRG8yjLgC5G1C9cmiATGoMGyHBRkEv+UrUWLHVxrpXviUd+/iJmhrwXcpvj
+rTrZWbUkSA3i4JMml/qYqNQYeVUFVgV/slD331iIwlWP8RipXF5YqN+YGjGeqL0+
+yQ4KWtABAoGBAP7XvGBUWNBSBrqioTzqYMTbwz/YjXJkvlO09wwc/UkraYlSihi0
+2J1dKBePIfOk6gFbuiJNYMJvAt1hBCsN0Z6o/bH7CiOh/55nkTaL0R4zB38uuDDx
+4qf6+9HT1eC9yW3UJVPwBBwI4WZmmq4peQoipBtKwpY2Q+yoUU3gp4KhAoGBAPYP
++6uv3gQYoIpkUD2ZdX8kFoaC6rJMP3Z/N75NfsOz1Tx3nNwexYM6EVVQrvTRWpLZ
+rJyCgCJi9HY4lPASKSKM1cLCT/M3SdR8OiqlEjziZtSH/di6wq8/Hfqhf75nC7sK
+wV7Ic0eQ3Bjg2hggPpjeBJTv8NIlCYbWbxHnsK4pAoGAY0I39vUjWpB4Wn05e/Z2
+FnbaR6XbAfFHSGc1yhwIc1VbV8c0Tocxz6kXEoYHXVSgaEMH7pBg3ZpLbVp6OyK4
+wKlllssGmfZhD5ubLbmri62of9r8luO/ulnBd2qg5VZGfGai21yi3SCAWlggazFw
+GYiAjrjBrawZLLYqZMDZvcECgYBoi6/taWKWMPR8+FQTaBFA/M9JRXR8XuMT8Md5
+Zqm2csDl2Rhfef+HWvOkYQyE3jJydGPfd58DfTHKzQ2S1tR9ZoMoJbEccGBBFKsO
+FWajUbpJEKKtI+S12sZdB6Mj/dpBFTfFkrtQK98n/tkLKSAPiT0/HpceYjgi/xbf
+76XkyQKBgQCkAuuTYi/9vlqYBcUH+23f0XmzQ6NNCqi0JxrnUmPv0Mc/ci7QfBZ6
+BkjPxfllpAsDihfTFpfp6p1PCMpASq1J+w1yR+lnKgw9BlbBLT4SqSVVDiju0cfw
+njm6zQu7IR6Ts/vi+YbVqn3yeP8U5W9as7QL5y6KeYfAhwuPqWhvog==
+-----END RSA PRIVATE KEY-----
diff --git a/tests/signer.pem b/tests/signer.pem
index 816f5fa..a7e2fb9 100644
--- a/tests/signer.pem
+++ b/tests/signer.pem
@@ -1,61 +1,75 @@
Certificate:
Data:
Version: 3 (0x2)
- Serial Number:
- d1:b6:bf:af:06:17:8c:c0
- Signature Algorithm: sha1WithRSAEncryption
+ Serial Number: 3 (0x3)
+ Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, ST=California, O=M2Crypto, CN=Heikki Toivonen
Validity
- Not Before: Jul 28 04:37:25 2009 GMT
- Not After : Jul 26 04:37:25 2019 GMT
+ Not Before: Oct 7 15:12:02 2018 GMT
+ Not After : Oct 4 15:12:02 2028 GMT
Subject: C=US, ST=California, O=M2Crypto, CN=Signer/emailAddress=signer@example.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
- RSA Public Key: (1024 bit)
- Modulus (1024 bit):
- 00:c3:9c:76:f3:21:aa:10:19:9f:77:e3:82:1d:9d:
- c3:4a:da:bc:c3:83:71:d1:89:78:8b:82:a4:b9:c5:
- 70:bb:e3:00:bf:49:b8:99:96:67:0b:bf:fe:72:cb:
- d9:b6:63:85:f4:fb:86:55:32:22:1e:6e:ce:fd:88:
- 5c:75:9d:77:3c:92:17:c5:b2:70:04:59:02:33:ef:
- be:33:26:f1:e4:72:41:45:72:f1:bf:c4:21:b1:fe:
- de:92:b9:f3:25:3e:1a:15:4b:26:47:29:cc:38:7f:
- 58:3b:ae:b7:c5:69:e7:48:81:b6:55:61:45:c3:3f:
- b6:9d:06:e5:17:41:f6:f2:e9
+ RSA Public-Key: (2048 bit)
+ Modulus:
+ 00:c8:85:86:3d:72:aa:91:d8:7b:11:02:05:92:b7:
+ 1b:bf:9f:35:be:88:56:db:96:f2:70:3e:98:3c:c3:
+ 62:42:ff:54:74:7a:63:e7:a9:4c:ae:52:48:a2:4f:
+ ab:c5:6b:1d:de:39:b8:f0:89:36:15:f7:70:3d:a8:
+ a6:c3:49:3e:10:d8:ae:ba:cf:1a:e6:dd:0b:d8:cd:
+ d9:00:ea:57:f2:7c:2e:6d:89:80:95:68:b1:fd:06:
+ bc:ea:ba:44:c1:fa:20:87:57:d3:ac:e5:b4:5d:ba:
+ 4f:10:20:82:5b:1b:27:75:b3:0c:ce:4f:79:3f:49:
+ 8e:e3:ba:14:30:cf:8a:82:11:65:59:78:7b:41:16:
+ 43:e8:ea:7f:a4:60:52:46:93:53:4e:de:87:3f:50:
+ 8a:56:c5:d3:04:5c:3c:a2:d3:b0:64:d8:ce:1e:75:
+ ad:ce:cd:91:b1:58:cc:2d:a6:dc:da:b5:b2:c2:0e:
+ 2f:68:74:a7:a5:6e:61:4c:01:f2:d0:7d:83:66:78:
+ 66:9f:b9:87:33:cc:59:dc:03:82:6f:bb:98:0c:e9:
+ 10:63:12:ee:e9:05:c1:5b:98:7e:94:65:98:df:31:
+ bf:59:90:f0:1c:6c:ac:2c:1b:dd:90:71:ab:11:95:
+ 8b:9c:f7:2a:2f:c0:0f:2d:b1:c8:5a:65:d6:a9:34:
+ 44:81
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
- Netscape Comment:
- OpenSSL Generated Certificate
X509v3 Subject Key Identifier:
- 22:CA:29:B7:D7:39:B4:BF:35:F9:36:5E:EE:2B:E4:17:4E:F9:6E:EE
- X509v3 Authority Key Identifier:
- keyid:AD:64:45:74:8F:83:C7:2C:D5:D7:A0:85:91:10:40:9A:9C:96:CF:EE
-
- Signature Algorithm: sha1WithRSAEncryption
- 5f:a0:da:6b:37:b4:bb:25:34:a7:ed:f3:f7:2e:f2:85:aa:91:
- 01:8f:c3:80:e5:44:87:df:9e:64:5e:5f:3e:5c:7f:c1:07:12:
- 2a:46:cc:bb:9f:a4:a5:c8:3f:84:9a:a4:9e:d5:26:33:af:b4:
- 5f:eb:8e:7d:81:65:f6:44:18:78:89:17:74:fb:07:dc:04:65:
- fa:15:0c:b2:f3:e7:e7:af:1f:d9:02:c4:c4:44:b7:95:91:47:
- fe:c0:2a:e1:7a:ae:dd:5f:f8:a9:fa:bb:dd:89:2d:0b:05:b6:
- ce:ba:12:37:7f:97:4c:48:a9:fb:d4:b7:a5:d1:61:f6:85:ea:
- 30:8c
+ 68:03:33:27:D9:87:9A:EA:7D:41:D8:2D:EB:F9:EE:AB:C9:6A:C5:FA
+ Signature Algorithm: sha256WithRSAEncryption
+ 47:27:62:6d:43:f3:f6:87:0a:8f:1f:f1:4b:2b:67:05:11:85:
+ b1:13:69:ca:de:1e:6f:8f:78:ae:b5:b7:75:ca:84:f3:58:26:
+ 9d:c5:0b:0e:4c:e9:ce:1c:5d:69:03:6e:d7:2e:88:28:75:78:
+ c5:54:37:e6:70:4f:8f:92:fb:5f:ce:c2:b3:a3:74:77:e6:c3:
+ 94:ab:c6:d2:69:bb:dd:d8:16:9d:36:2a:d1:c1:e1:0d:81:da:
+ 96:9f:f1:ae:a4:b9:73:16:b1:98:b5:f9:6a:4c:8b:08:30:c3:
+ d6:31:3a:79:e2:ef:7f:db:4f:6f:13:f8:98:d6:b2:04:72:c3:
+ 03:b2:ff:63:ad:ce:4e:8d:95:37:a6:dc:52:5e:5c:26:35:9f:
+ 14:7e:9d:a0:04:46:00:ff:52:94:f1:2b:75:1c:52:f0:79:eb:
+ 41:a8:39:a2:5a:63:cc:de:70:cd:82:72:77:1d:77:e1:3d:ff:
+ 38:86:2d:12:4f:ab:4c:72:35:69:4f:ad:55:1d:da:ae:9d:0a:
+ 23:4a:cc:2a:40:d8:4e:f5:bd:33:4c:eb:b7:47:41:82:2a:c9:
+ fc:64:0d:33:76:00:61:ba:b6:40:ca:24:96:5e:84:d5:4f:d2:
+ 4d:2e:7a:31:a5:50:53:ba:eb:31:7b:78:9f:f4:43:f1:e5:54:
+ 4f:59:dc:ba
-----BEGIN CERTIFICATE-----
-MIICsTCCAhqgAwIBAgIJANG2v68GF4zAMA0GCSqGSIb3DQEBBQUAME8xCzAJBgNV
-BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMREwDwYDVQQKEwhNMkNyeXB0bzEY
-MBYGA1UEAxMPSGVpa2tpIFRvaXZvbmVuMB4XDTA5MDcyODA0MzcyNVoXDTE5MDcy
-NjA0MzcyNVowaTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExETAP
-BgNVBAoTCE0yQ3J5cHRvMQ8wDQYDVQQDEwZTaWduZXIxITAfBgkqhkiG9w0BCQEW
-EnNpZ25lckBleGFtcGxlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
-w5x28yGqEBmfd+OCHZ3DStq8w4Nx0Yl4i4KkucVwu+MAv0m4mZZnC7/+csvZtmOF
-9PuGVTIiHm7O/YhcdZ13PJIXxbJwBFkCM+++Mybx5HJBRXLxv8Qhsf7ekrnzJT4a
-FUsmRynMOH9YO663xWnnSIG2VWFFwz+2nQblF0H28ukCAwEAAaN7MHkwCQYDVR0T
-BAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNh
-dGUwHQYDVR0OBBYEFCLKKbfXObS/Nfk2Xu4r5BdO+W7uMB8GA1UdIwQYMBaAFK1k
-RXSPg8cs1deghZEQQJqcls/uMA0GCSqGSIb3DQEBBQUAA4GBAF+g2ms3tLslNKft
-8/cu8oWqkQGPw4DlRIffnmReXz5cf8EHEipGzLufpKXIP4SapJ7VJjOvtF/rjn2B
-ZfZEGHiJF3T7B9wEZfoVDLLz5+evH9kCxMREt5WRR/7AKuF6rt1f+Kn6u92JLQsF
-ts66Ejd/l0xIqfvUt6XRYfaF6jCM
+MIIDXzCCAkegAwIBAgIBAzANBgkqhkiG9w0BAQsFADBPMQswCQYDVQQGEwJVUzET
+MBEGA1UECAwKQ2FsaWZvcm5pYTERMA8GA1UECgwITTJDcnlwdG8xGDAWBgNVBAMM
+D0hlaWtraSBUb2l2b25lbjAeFw0xODEwMDcxNTEyMDJaFw0yODEwMDQxNTEyMDJa
+MGkxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMREwDwYDVQQKDAhN
+MkNyeXB0bzEPMA0GA1UEAwwGU2lnbmVyMSEwHwYJKoZIhvcNAQkBFhJzaWduZXJA
+ZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIhYY9
+cqqR2HsRAgWStxu/nzW+iFbblvJwPpg8w2JC/1R0emPnqUyuUkiiT6vFax3eObjw
+iTYV93A9qKbDST4Q2K66zxrm3QvYzdkA6lfyfC5tiYCVaLH9BrzqukTB+iCHV9Os
+5bRduk8QIIJbGyd1swzOT3k/SY7juhQwz4qCEWVZeHtBFkPo6n+kYFJGk1NO3oc/
+UIpWxdMEXDyi07Bk2M4eda3OzZGxWMwtptzatbLCDi9odKelbmFMAfLQfYNmeGaf
+uYczzFncA4Jvu5gM6RBjEu7pBcFbmH6UZZjfMb9ZkPAcbKwsG92QcasRlYuc9yov
+wA8tschaZdapNESBAgMBAAGjLDAqMAkGA1UdEwQCMAAwHQYDVR0OBBYEFGgDMyfZ
+h5rqfUHYLev57qvJasX6MA0GCSqGSIb3DQEBCwUAA4IBAQBHJ2JtQ/P2hwqPH/FL
+K2cFEYWxE2nK3h5vj3iutbd1yoTzWCadxQsOTOnOHF1pA27XLogodXjFVDfmcE+P
+kvtfzsKzo3R35sOUq8bSabvd2BadNirRweENgdqWn/GupLlzFrGYtflqTIsIMMPW
+MTp54u9/209vE/iY1rIEcsMDsv9jrc5OjZU3ptxSXlwmNZ8Ufp2gBEYA/1KU8St1
+HFLweetBqDmiWmPM3nDNgnJ3HXfhPf84hi0ST6tMcjVpT61VHdqunQojSswqQNhO
+9b0zTOu3R0GCKsn8ZA0zdgBhurZAyiSWXoTVT9JNLnoxpVBTuusxe3if9EPx5VRP
+Wdy6
-----END CERTIFICATE-----
diff --git a/tests/signer_key.pem b/tests/signer_key.pem
index 39abda1..dda4f85 100644
--- a/tests/signer_key.pem
+++ b/tests/signer_key.pem
@@ -1,15 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
-MIICXAIBAAKBgQDDnHbzIaoQGZ9344IdncNK2rzDg3HRiXiLgqS5xXC74wC/SbiZ
-lmcLv/5yy9m2Y4X0+4ZVMiIebs79iFx1nXc8khfFsnAEWQIz774zJvHkckFFcvG/
-xCGx/t6SufMlPhoVSyZHKcw4f1g7rrfFaedIgbZVYUXDP7adBuUXQfby6QIDAQAB
-AoGAZL24JQ85XoFTt5Lb+BS/91Uf0jFn9Nov0um9nE8q+Bi40ctN3wuulkaS7Nw/
-i8dFvh2r2USwfavjvn7z3z7xoMG8V2c1ZFJCI2CKjocuWVkGwNnIsbO7/BOG03nu
-vir/i7TXN0YbN8zMhfuFC9APmR8bdmMa2KgHXzQcLuAmI4ECQQDhDIkC97l6rMKG
-QWbYrbc7GoMZNwCsPb/fasUknGmtPmq+s818i335u1yyhAk5pwKV7HF+WyZ76S2A
-P1bZf9+FAkEA3oN98qoklVmWSK0qV+CKHjZHSqtt32q2eu6+eAO5fVZOWHwXhS/B
-MkTtfKJbIDTLyUnwhKyht/hXOniVqHE5FQJAf99VgoArvc6oAQzsWTXrpQOddhhQ
-o426lkHenrzZNvz+PjmACsJf5CRXuX9Ylo+U4ockvb0hEssddX+H47HK2QJBAIYr
-aV1SJH79pvWpnLeiSAYRmok2tyiZMvELVkQNkuI1kUYfhRslAWxrTXvyddoEm8CC
-2glWAqlokEhMf4kyxEUCQCIQbV+XFoEqkECchik34PPmcPi2ends32dv/sW+AKjQ
-pxKpWbxVB4sEOPZzpmujP0LLxvCY4HOUJDlhENGQ8MM=
+MIIEowIBAAKCAQEAyIWGPXKqkdh7EQIFkrcbv581vohW25bycD6YPMNiQv9UdHpj
+56lMrlJIok+rxWsd3jm48Ik2FfdwPaimw0k+ENiuus8a5t0L2M3ZAOpX8nwubYmA
+lWix/Qa86rpEwfogh1fTrOW0XbpPECCCWxsndbMMzk95P0mO47oUMM+KghFlWXh7
+QRZD6Op/pGBSRpNTTt6HP1CKVsXTBFw8otOwZNjOHnWtzs2RsVjMLabc2rWywg4v
+aHSnpW5hTAHy0H2DZnhmn7mHM8xZ3AOCb7uYDOkQYxLu6QXBW5h+lGWY3zG/WZDw
+HGysLBvdkHGrEZWLnPcqL8APLbHIWmXWqTREgQIDAQABAoIBAFniSI9I1B62PEwe
+bOMcQ0r9EflLYivimOApntI1/tjrXS8tIZVZdW76oWZociX3YxcXJshjqSPlm6F3
+9PC65yBkEMbaSUPNOB9B/pEDetLOSX1+Um4m1QoHuC07u9B7z5L7kn4BJX2SIxim
+iehO3rxKu2XLiB0PWwbHhX9vuLWeTTnozC5BjCpLe1/bj7j9L8llbyO+XyAwthJ6
+ZdfF/pv7ERT3JUfGqhIm9u4aXTWC/6brVlXSUvrJ+9gKJtxUyz5i5+BD/xPU9Lvb
+H8/3CqSpEmoCtCXxTfs7MD1b9UTzJhldJZmTu7KWTLd+sARNmkaA729tUB+N4usd
+tbQSlAUCgYEA7sgYTl14iAvEkPjsd3ytH7BkizZr0w7/RQMilR8afyQENoNjkPx6
+kYrjgPuuM9oWeIRbn0FruCKrc3lTS+ilym8k+UxUo3m8Fb662Rw+R6Alrrh1E2Y5
+Ugic9U6kFvZmlf8tsdjVKCM6EqO0jvPDIrTbMyOwNbQDvNESXFBXDv8CgYEA1vsm
+T8Wh8qknLDCSoOUP/1QCyR/OvVczisvYlT054/vXluHWbRtrlcAOXlBUUrtgV/vP
+DETVAkEXPjiNbNsANENf0QZKhGBd8L8Orer0O6Bc8bsGTkFVMp/XWbAIpUFe7fOy
+Ot4sA4WpfuK0fKdRyBwG9s8FOw8n+usRpJiQLH8CgYAZ8uDBU2MP1ceMwaBg88mU
+kgS7JDTfgNe41jhh4Dlu66kRi4G8ddOUEXXbxH4P4Hlkq22Rhvh/0DS1nc+xhhzO
+PPnVpbfk9Au+iTWg9nLGMd8md6ExdIByK8Fy3xLx8+D+F/cNRrUTYZCkCepLRq5E
+DUds7Unu7Bsj38yQ/6IWXQKBgDbVYHRAaIpIcuFmkj/PrUDm4L8ECetpbpAcZmXK
+dBWeiuLFP7gcolhT4FZWDuv7Nxu58pmihOJKT+9i5U+6nFa4SJw8Co2xNsTNNqVN
+pHYA9TQDDByxtVVwR7FsoQfloJz456D0Qi2zzgO7N2YEF2v/GhehvifOOdhaVOmy
+sDNpAoGBAM/b+jI8eQGtNGbdRWkuHH2gRgmm1n900brEYlTWCHBSGePyghWJj3Uu
+oiuxsHV22CAUuOlDpOWeZUsNlpa+8dOBYAxZUvkH99y4jukNCCAKvFwI0MS+FUoW
+DKida/MnaVqE6+1KDC/l6LjXDAP1JcwS0PimBXMqVNYScb2q7eAl
-----END RSA PRIVATE KEY-----
diff --git a/tests/te_chunked_response.txt b/tests/te_chunked_response.txt
new file mode 100644
index 0000000..f7eaadd
--- /dev/null
+++ b/tests/te_chunked_response.txt
@@ -0,0 +1,11 @@
+HTTP/1.1 200 ok
+Content-Type: text/plain
+Transfer-Encoding: chunked
+
+4
+foo
+
+7
+foobar
+
+0
diff --git a/tests/test_aes.py b/tests/test_aes.py
new file mode 100644
index 0000000..1da122d
--- /dev/null
+++ b/tests/test_aes.py
@@ -0,0 +1,80 @@
+#!/usr/bin/env python
+from __future__ import absolute_import, print_function
+"""Unit tests for _aes.i.
+
+Copyright (c) 2018 Matej Cepl. All rights reserved.
+"""
+import logging
+
+from M2Crypto import m2
+from tests import unittest
+
+log = logging.getLogger('test_AES')
+
+KEY_TEXT = (b'blabulka' * 3)[:16] # 128/8 == 16
+
+
+class AESTestCase(unittest.TestCase):
+ """
+ Functions in AES module are very low level, and you are HIGHLY
+ encouraged NOT to use them. Use functions from EVP module instead.
+
+ These tests are here only for checking regressions, not as an
+ illustration for the real world use.
+ """
+
+ def test_existing_methods(self):
+ missing = []
+ exp_mtds = ('aes_128_cbc', 'aes_128_cfb', 'aes_128_ctr',
+ 'aes_128_ecb', 'aes_128_ofb', 'aes_192_cbc',
+ 'aes_192_cfb', 'aes_192_ctr', 'aes_192_ecb',
+ 'aes_192_ofb', 'aes_256_cbc', 'aes_256_cfb',
+ 'aes_256_ctr', 'aes_256_ecb', 'aes_256_ofb')
+ for name in exp_mtds:
+ if not hasattr(m2, name):
+ missing.append(name)
+
+ self.assertEqual(missing, [])
+
+ def test_set_key(self):
+ key = m2.aes_new()
+ m2.AES_set_key(key, KEY_TEXT, 128, 1)
+ m2.AES_free(key)
+
+ key2 = m2.aes_new()
+ m2.AES_set_key(key2, KEY_TEXT, 128, 0)
+ m2.AES_free(key2)
+ # Just to make sure nothing crashed
+
+ def test_type_check(self):
+ key = m2.aes_new()
+ m2.AES_set_key(key, KEY_TEXT, 128, 1)
+ res = m2.AES_type_check(key)
+ m2.AES_free(key)
+ self.assertEqual(res, 1) # Just to make sure nothing crashed
+
+ def test_crypt(self):
+ padded = b'zezulicka ' # len(padded) % 16 == 0
+ key = m2.aes_new()
+ # op == 0: encrypt
+ # otherwise: decrypt (Python code will supply the value 1.)
+ m2.AES_set_key(key, KEY_TEXT, 128, 0)
+ enc = m2.AES_crypt(key, padded, len(padded), 0)
+ m2.AES_free(key)
+
+ key2 = m2.aes_new()
+ m2.AES_set_key(key2, KEY_TEXT, 128, 1)
+ observed = m2.AES_crypt(key2, enc, len(enc), 1)
+ m2.AES_free(key2)
+
+ self.assertEqual(padded, observed)
+
+
+def suite():
+ t_suite = unittest.TestSuite()
+ t_suite.addTest(unittest.makeSuite(AESTestCase))
+ return t_suite
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/test_asn1.py b/tests/test_asn1.py
index 30ef759..0f5274f 100644
--- a/tests/test_asn1.py
+++ b/tests/test_asn1.py
@@ -4,58 +4,117 @@
Copyright (c) 2005 Open Source Applications Foundation. All rights reserved."""
-import unittest, time, datetime
+import datetime
+import time
+
from M2Crypto import ASN1, m2
+from tests import unittest
+
class ASN1TestCase(unittest.TestCase):
def test_Integer(self):
- pass # XXX Dunno how to test
+ pass # XXX Dunno how to test
def test_BitSTring(self):
- pass # XXX Dunno how to test
+ pass # XXX Dunno how to test
def test_String(self):
asn1ptr = m2.asn1_string_new()
- text = 'hello there'
+ # FIXME this is probably wrong ... asn1_string_set should have
+ # Python string as its parameter.
+ text = b'hello there'
# In RFC2253 format:
# #040B68656C6C6F207468657265
- # h e l l o t h e r e
+ # h e l l o t h e r e
m2.asn1_string_set(asn1ptr, text)
a = ASN1.ASN1_String(asn1ptr, 1)
- assert a.as_text() == 'hello there', a.as_text()
- assert a.as_text(flags=m2.ASN1_STRFLGS_RFC2253) == '#040B68656C6C6F207468657265', a.as_text(flags=m2.ASN1_STRFLGS_RFC2253)
+ self.assertEqual(a.as_text(), 'hello there', a.as_text())
+ self.assertEqual(a.as_text(flags=m2.ASN1_STRFLGS_RFC2253),
+ '#040B68656C6C6F207468657265',
+ a.as_text(flags=m2.ASN1_STRFLGS_RFC2253))
self.assertEqual(a.as_text(), str(a))
def test_Object(self):
- pass # XXX Dunno how to test
+ pass # XXX Dunno how to test
+
+ def test_TIME(self):
+ asn1 = ASN1.ASN1_TIME()
+ self.assertEqual(str(asn1), 'Bad time value')
+
+ format = '%b %d %H:%M:%S %Y GMT'
+ utcformat = '%y%m%d%H%M%SZ'
+
+ s = '990807053011Z'
+ asn1.set_string(s)
+ # assert str(asn1) == 'Aug 7 05:30:11 1999 GMT'
+ t1 = time.strptime(str(asn1), format)
+ t2 = time.strptime(s, utcformat)
+ self.assertEqual(t1, t2)
+
+ asn1.set_time(500)
+ # assert str(asn1) == 'Jan 1 00:08:20 1970 GMT'
+ t1 = time.strftime(format, time.strptime(str(asn1), format))
+ t2 = time.strftime(format, time.gmtime(500))
+ self.assertEqual(t1, t2)
+
+ t = int(time.time()) + time.timezone
+ asn1.set_time(t)
+ t1 = time.strftime(format, time.strptime(str(asn1), format))
+ t2 = time.strftime(format, time.gmtime(t))
+ self.assertEqual(t1, t2)
def test_UTCTIME(self):
asn1 = ASN1.ASN1_UTCTIME()
- assert str(asn1) == 'Bad time value'
-
+ self.assertEqual(str(asn1), 'Bad time value')
+
format = '%b %d %H:%M:%S %Y GMT'
utcformat = '%y%m%d%H%M%SZ'
s = '990807053011Z'
asn1.set_string(s)
- #assert str(asn1) == 'Aug 7 05:30:11 1999 GMT'
+ # assert str(asn1) == 'Aug 7 05:30:11 1999 GMT'
t1 = time.strptime(str(asn1), format)
t2 = time.strptime(s, utcformat)
self.assertEqual(t1, t2)
-
+
asn1.set_time(500)
- #assert str(asn1) == 'Jan 1 00:08:20 1970 GMT'
+ # assert str(asn1) == 'Jan 1 00:08:20 1970 GMT'
t1 = time.strftime(format, time.strptime(str(asn1), format))
t2 = time.strftime(format, time.gmtime(500))
self.assertEqual(t1, t2)
-
- t = long(time.time()) + time.timezone
+
+ t = int(time.time()) + time.timezone
asn1.set_time(t)
t1 = time.strftime(format, time.strptime(str(asn1), format))
t2 = time.strftime(format, time.gmtime(t))
self.assertEqual(t1, t2)
+ def test_TIME_datetime(self):
+ asn1 = ASN1.ASN1_TIME()
+ # Test get_datetime and set_datetime
+ t = time.time()
+ dt = datetime.datetime.fromtimestamp(int(t))
+ udt = dt.replace(tzinfo=ASN1.LocalTimezone()).astimezone(ASN1.UTC)
+ asn1.set_time(int(t))
+ t1 = str(asn1)
+ asn1.set_datetime(dt)
+ t2 = str(asn1)
+ self.assertEqual(t1, t2)
+ self.assertEqual(str(udt), str(asn1.get_datetime()))
+
+ dt = dt.replace(tzinfo=ASN1.LocalTimezone())
+ asn1.set_datetime(dt)
+ t2 = str(asn1)
+ self.assertEqual(t1, t2)
+ self.assertEqual(str(udt), str(asn1.get_datetime()))
+
+ dt = dt.astimezone(ASN1.UTC)
+ asn1.set_datetime(dt)
+ t2 = str(asn1)
+ self.assertEqual(t1, t2)
+ self.assertEqual(str(udt), str(asn1.get_datetime()))
+
def test_UTCTIME_datetime(self):
asn1 = ASN1.ASN1_UTCTIME()
# Test get_datetime and set_datetime
@@ -74,13 +133,13 @@ class ASN1TestCase(unittest.TestCase):
t2 = str(asn1)
self.assertEqual(t1, t2)
self.assertEqual(str(udt), str(asn1.get_datetime()))
-
+
dt = dt.astimezone(ASN1.UTC)
asn1.set_datetime(dt)
t2 = str(asn1)
self.assertEqual(t1, t2)
self.assertEqual(str(udt), str(asn1.get_datetime()))
-
+
def suite():
return unittest.makeSuite(ASN1TestCase)
diff --git a/tests/test_authcookie.py b/tests/test_authcookie.py
index 9ce0eb8..006571f 100644..100755
--- a/tests/test_authcookie.py
+++ b/tests/test_authcookie.py
@@ -4,15 +4,20 @@
Copyright (c) 1999-2002 Ng Pheng Siong. All rights reserved."""
-import Cookie, binascii, time, unittest, sys
+import logging
+import time
+
+from M2Crypto import EVP, Rand, six, util
from M2Crypto.AuthCookie import AuthCookie, AuthCookieJar, mix, unmix, unmix3
-from M2Crypto import Rand, EVP
+from M2Crypto.six.moves.http_cookies import SimpleCookie # pylint: disable=no-name-in-module,import-error
+from tests import unittest
+
+log = logging.getLogger(__name__)
+
class AuthCookieTestCase(unittest.TestCase):
- _format = 'Set-Cookie: _M2AUTH_="exp=%s&data=%s&digest=%s"'
- if sys.version_info < (2,5):
- _format += ';'
+ _format = 'Set-Cookie: _M2AUTH_="exp=%f&data=%s&digest=%s"'
_token = '_M2AUTH_'
def setUp(self):
@@ -23,117 +28,137 @@ class AuthCookieTestCase(unittest.TestCase):
def tearDown(self):
pass
+ def _corrupt_part_str(self, s, fr, to):
+ # type: (str, int, int) -> str
+ out = s[:fr] + ''.join([chr(ord(x) + 13) for x in s[fr:to]]) + s[to:]
+ self.assertNotEqual(s, out)
+ return out
+
+ def test_encode_part_str(self):
+ a_str = 'a1b2c3d4e5f6h7i8j9'
+ self.assertEqual(self._corrupt_part_str(a_str, 3, 5),
+ 'a1b?p3d4e5f6h7i8j9')
+
def test_mix_unmix(self):
dough = mix(self.exp, self.data)
exp, data = unmix(dough)
- self.failUnlessEqual(data, self.data)
- self.failUnlessEqual(exp, self.exp)
+ self.assertEqual(data, self.data)
+ # we are comparing seconds here, ten-thousandth
+ # second should be enough.
+ self.assertAlmostEqual(exp, self.exp, places=4)
def test_make_cookie(self):
c = self.jar.makeCookie(self.exp, self.data)
- self.failUnless(isinstance(c, AuthCookie))
- self.failUnlessEqual(c.expiry(), self.exp)
- self.failUnlessEqual(c.data(), self.data)
+ self.assertTrue(isinstance(c, AuthCookie))
+ self.assertEqual(c.expiry(), self.exp)
+ self.assertEqual(c.data(), self.data)
# Peek inside the cookie jar...
- key = self.jar._key
- mac = binascii.b2a_base64(EVP.hmac(key, mix(self.exp, self.data), 'sha1'))[:-1]
- self.failUnlessEqual(c.mac(), mac)
+ key = self.jar._key # pylint: disable=protected-access
+ mac = util.bin_to_hex(
+ EVP.hmac(key, six.ensure_binary(mix(self.exp, self.data)), 'sha1'))
+ self.assertEqual(c.mac(), mac)
# Ok, stop peeking now.
- cookie_str = self._format % (repr(self.exp), self.data, mac)
- self.failUnlessEqual(c.output(), cookie_str)
+ cookie_str = self._format % (self.exp, self.data, mac)
+ self.assertEqual(c.output(), cookie_str)
+
+ def test_make_cookie_invalid(self):
+ with self.assertRaises(ValueError):
+ self.jar.makeCookie("complete nonsense", self.data)
def test_expired(self):
t = self.exp - 7200
c = self.jar.makeCookie(t, self.data)
- self.failUnless(c.isExpired())
+ self.assertTrue(c.isExpired())
def test_not_expired(self):
c = self.jar.makeCookie(self.exp, self.data)
- self.failIf(c.isExpired())
+ self.assertFalse(c.isExpired())
def test_is_valid(self):
c = self.jar.makeCookie(self.exp, self.data)
- self.failUnless(self.jar.isGoodCookie(c))
-
+ self.assertTrue(self.jar.isGoodCookie(c))
+
def test_is_invalid_expired(self):
t = self.exp - 7200
c = self.jar.makeCookie(t, self.data)
- self.failIf(self.jar.isGoodCookie(c))
+ self.assertFalse(self.jar.isGoodCookie(c))
def test_is_invalid_changed_exp(self):
c = self.jar.makeCookie(self.exp, self.data)
- c._expiry = 'this is bad'
- self.failIf(self.jar.isGoodCookie(c))
+ c._expiry = 0 # pylint: disable=protected-access
+ self.assertFalse(self.jar.isGoodCookie(c))
def test_is_invalid_changed_data(self):
c = self.jar.makeCookie(self.exp, self.data)
- c._data = 'this is bad'
- self.failIf(self.jar.isGoodCookie(c))
+ c._data = 'this is bad' # pylint: disable=protected-access
+ self.assertFalse(self.jar.isGoodCookie(c))
def test_is_invalid_changed_mac(self):
c = self.jar.makeCookie(self.exp, self.data)
- c._mac = 'this is bad'
- self.failIf(self.jar.isGoodCookie(c))
+ c._mac = 'this is bad' # pylint: disable=protected-access
+ self.assertFalse(self.jar.isGoodCookie(c))
def test_mix_unmix3(self):
c = self.jar.makeCookie(self.exp, self.data)
- s = Cookie.SmartCookie()
- s.load(c.output())
+ s = SimpleCookie()
+ s.load(c.output(header=""))
exp, data, digest = unmix3(s[self._token].value)
- self.failUnlessEqual(data, self.data)
- self.failUnlessEqual(float(exp), self.exp)
- key = self.jar._key # Peeking...
- mac = binascii.b2a_base64(EVP.hmac(key, mix(self.exp, self.data), 'sha1'))[:-1]
- self.failUnlessEqual(digest, mac)
+ self.assertEqual(data, self.data)
+ # see comment in test_mix_unmix
+ self.assertAlmostEqual(exp, self.exp, places=4)
+ key = self.jar._key # pylint: disable=protected-access
+ mac = util.bin_to_hex(
+ EVP.hmac(key, six.ensure_binary(mix(self.exp, self.data)), 'sha1'))
+ self.assertEqual(digest, mac)
def test_cookie_str(self):
c = self.jar.makeCookie(self.exp, self.data)
- self.failUnless(self.jar.isGoodCookieString(c.output()))
+ self.assertTrue(self.jar.isGoodCookieString(c.output(header="")))
def test_cookie_str2(self):
c = self.jar.makeCookie(self.exp, self.data)
- s = Cookie.SmartCookie()
- s.load(c.output())
- self.failUnless(self.jar.isGoodCookieString(s.output()))
+ s = SimpleCookie()
+ s.load(c.output(header=""))
+ self.assertTrue(self.jar.isGoodCookieString(s.output(header="")))
def test_cookie_str_expired(self):
t = self.exp - 7200
c = self.jar.makeCookie(t, self.data)
- s = Cookie.SmartCookie()
- s.load(c.output())
- self.failIf(self.jar.isGoodCookieString(s.output()))
+ s = SimpleCookie()
+ s.load(c.output(header=""))
+ self.assertFalse(self.jar.isGoodCookieString(s.output(header="")))
def test_cookie_str_arbitrary_change(self):
c = self.jar.makeCookie(self.exp, self.data)
- cout = c.output()
- str = cout[:32] + 'this is bad' + cout[32:]
- s = Cookie.SmartCookie()
- s.load(str)
- self.failIf(self.jar.isGoodCookieString(s.output()))
+ cout = c.output(header="")
+ cout_str = cout[:20] + 'this is bad' + cout[20:]
+ s = SimpleCookie()
+ s.load(cout_str)
+ self.assertFalse(self.jar.isGoodCookieString(s.output(header="")))
def test_cookie_str_changed_exp(self):
c = self.jar.makeCookie(self.exp, self.data)
- cout = c.output()
- str = cout[:26] + '2' + cout[27:]
- s = Cookie.SmartCookie()
- s.load(str)
- self.failIf(self.jar.isGoodCookieString(s.output()))
+ cout = c.output(header="")
+ cout_str = self._corrupt_part_str(cout, 14, 16)
+ s = SimpleCookie()
+ s.load(cout_str)
+ self.assertFalse(self.jar.isGoodCookieString(s.output(header="")))
def test_cookie_str_changed_data(self):
c = self.jar.makeCookie(self.exp, self.data)
- cout = c.output()
- str = cout[:36] + 'X' + cout[37:]
- s = Cookie.SmartCookie()
- s.load(str)
- self.failIf(self.jar.isGoodCookieString(s.output()))
+ cout = c.output(header="")
+ cout_str = self._corrupt_part_str(cout, 24, 26)
+ s = SimpleCookie()
+ s.load(cout_str)
+ self.assertFalse(self.jar.isGoodCookieString(s.output(header="")))
def test_cookie_str_changed_mac(self):
c = self.jar.makeCookie(self.exp, self.data)
- cout = c.output()
- str = cout[:76] + 'X' + cout[77:]
- s = Cookie.SmartCookie()
- s.load(str)
- self.failIf(self.jar.isGoodCookieString(s.output()))
+ cout = c.output(header="")
+ cout_str = self._corrupt_part_str(cout, 64, 66)
+ s = SimpleCookie()
+ s.load(cout_str)
+ self.assertFalse(self.jar.isGoodCookieString(s.output(header="")))
def suite():
@@ -141,7 +166,6 @@ def suite():
if __name__ == '__main__':
- Rand.load_file('randpool.dat', -1)
+ Rand.load_file('randpool.dat', -1)
unittest.TextTestRunner().run(suite())
Rand.save_file('randpool.dat')
-
diff --git a/tests/test_bio.py b/tests/test_bio.py
index 1d7b0c3..d2b4fa4 100644
--- a/tests/test_bio.py
+++ b/tests/test_bio.py
@@ -1,4 +1,5 @@
#!/usr/bin/env python
+from __future__ import absolute_import
"""
Unit tests for M2Crypto.BIO.
@@ -8,69 +9,86 @@ Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved.
Copyright (c) 2006 Open Source Applications Foundation
Author: Heikki Toivonen
"""
+import logging
-import unittest
from M2Crypto import BIO, Rand
+from tests import unittest
+from tests.fips import fips_mode
+
+log = logging.getLogger('test_bio')
-from fips import fips_mode
class CipherStreamTestCase(unittest.TestCase):
def try_algo(self, algo):
- enc = 1
- dec = 0
- data = '123456789012345678901234'
+ data = b'123456789012345678901234'
+ my_key = 3 * 15 * b"key"
+ my_IV = 3 * 16 * b'IV'
# Encrypt.
mem = BIO.MemoryBuffer()
cf = BIO.CipherStream(mem)
- cf.set_cipher(algo, 'key', 'iv', 1)
+ cf.set_cipher(algo, my_key, my_IV, 1)
cf.write(data)
cf.flush()
cf.write_close()
cf.close()
- xxx = mem.read()
-
+ ciphertext = mem.read()
+
# Decrypt.
- mem = BIO.MemoryBuffer(xxx)
+ mem = BIO.MemoryBuffer(ciphertext)
cf = BIO.CipherStream(mem)
- cf.set_cipher(algo, 'key', 'iv', 0)
+ cf.set_cipher(algo, my_key, my_IV, 0)
cf.write_close()
data2 = cf.read()
cf.close()
- assert not cf.readable()
-
- self.assertRaises(IOError, cf.read)
- self.assertRaises(IOError, cf.readline)
- self.assertRaises(IOError, cf.readlines)
-
- assert data == data2, '%s algorithm cipher test failed' % algo
-
+ self.assertFalse(cf.readable())
+
+ with self.assertRaises(IOError):
+ cf.read()
+ with self.assertRaises(IOError):
+ cf.readline()
+ with self.assertRaises(IOError):
+ cf.readlines()
+
+ self.assertEqual(data, data2,
+ '%s algorithm cipher test failed' % algo)
+
def test_ciphers(self):
- ciphers=[
+ ciphers = [
'des_ede_ecb', 'des_ede_cbc', 'des_ede_cfb', 'des_ede_ofb',
'des_ede3_ecb', 'des_ede3_cbc', 'des_ede3_cfb', 'des_ede3_ofb',
'aes_128_ecb', 'aes_128_cbc', 'aes_128_cfb', 'aes_128_ofb',
'aes_192_ecb', 'aes_192_cbc', 'aes_192_cfb', 'aes_192_ofb',
'aes_256_ecb', 'aes_256_cbc', 'aes_256_cfb', 'aes_256_ofb']
- nonfips_ciphers=['bf_ecb', 'bf_cbc', 'bf_cfb', 'bf_ofb',
- #'idea_ecb', 'idea_cbc', 'idea_cfb', 'idea_ofb',
- 'cast5_ecb', 'cast5_cbc', 'cast5_cfb', 'cast5_ofb',
- #'rc5_ecb', 'rc5_cbc', 'rc5_cfb', 'rc5_ofb',
- 'des_ecb', 'des_cbc', 'des_cfb', 'des_ofb',
- 'rc4', 'rc2_40_cbc']
- if not fips_mode: # Forbidden ciphers
+ nonfips_ciphers = ['bf_ecb', 'bf_cbc', 'bf_cfb', 'bf_ofb',
+ # 'idea_ecb', 'idea_cbc', 'idea_cfb', 'idea_ofb',
+ 'cast5_ecb', 'cast5_cbc', 'cast5_cfb', 'cast5_ofb',
+ # 'rc5_ecb', 'rc5_cbc', 'rc5_cfb', 'rc5_ofb',
+ 'des_ecb', 'des_cbc', 'des_cfb', 'des_ofb',
+ 'rc4', 'rc2_40_cbc']
+ if not fips_mode: # Forbidden ciphers
ciphers += nonfips_ciphers
+
+ failed_ciphers = []
+ log.debug('ciphers:\n%s', ciphers)
for i in ciphers:
- self.try_algo(i)
+ try:
+ self.try_algo(i)
+ except AssertionError:
+ failed_ciphers.append(i)
+
+ self.assertEqual(len(failed_ciphers), 0,
+ "failed ciphers: %s" % ', '.join(failed_ciphers))
+
+ with self.assertRaises(ValueError):
+ self.try_algo('nosuchalgo4567')
- self.assertRaises(ValueError, self.try_algo, 'nosuchalgo4567')
def suite():
- suite = unittest.TestSuite()
- suite.addTest(unittest.makeSuite(CipherStreamTestCase))
- return suite
+ t_suite = unittest.TestSuite()
+ t_suite.addTest(unittest.makeSuite(CipherStreamTestCase))
+ return t_suite
if __name__ == '__main__':
- Rand.load_file('randpool.dat', -1)
+ Rand.load_file('randpool.dat', -1)
unittest.TextTestRunner().run(suite())
Rand.save_file('randpool.dat')
-
diff --git a/tests/test_bio_file.py b/tests/test_bio_file.py
index e118386..fe0a8a7 100644
--- a/tests/test_bio_file.py
+++ b/tests/test_bio_file.py
@@ -4,75 +4,141 @@
Copyright (c) 1999-2002 Ng Pheng Siong. All rights reserved."""
-import unittest
-import M2Crypto
+import logging
+import os
+import platform
+import tempfile
+import ctypes
+if platform.system() == 'Windows':
+ import ctypes.wintypes
+
from M2Crypto.BIO import File, openfile
-import os, sys
+from tests import unittest
+
+log = logging.getLogger(__name__)
+
+
+def getCountProcHandles():
+ PROCESS_QUERY_INFORMATION = 0x400
+ handle = ctypes.windll.kernel32.OpenProcess(
+ PROCESS_QUERY_INFORMATION, 0, os.getpid())
+ hndcnt = ctypes.wintypes.DWORD()
+ ctypes.windll.kernel32.GetProcessHandleCount(
+ handle, ctypes.byref(hndcnt))
+ sys_value = hndcnt.value
+ ctypes.windll.kernel32.CloseHandle(handle)
+ return sys_value + 1
+
class FileTestCase(unittest.TestCase):
def setUp(self):
- self.data = 'abcdef' * 64
- if sys.platform != 'win32':
- self.fname = os.tmpnam()
+ self.data = b'abcdef' * 64
+ self.fd, self.fname = tempfile.mkstemp()
+
+ if platform.system() in ['Linux', 'Darwin', 'FreeBSD']:
+ self.__dev_fd = "/dev/fd/"
+
+ self.fd_count = self.__mfd()
+
+ def __mfd(self):
+ if hasattr(self, '__dev_fd'):
+ return len(os.listdir(self.__dev_fd))
+ elif platform.system() == 'Windows':
+ return getCountProcHandles()
else:
- import tempfile
- self.fname = tempfile.mktemp()
+ return None
def tearDown(self):
+
+ self.assertEqual(self.fd_count, self.__mfd(),
+ "last test did not close all file descriptors properly")
+
try:
- os.unlink(self.fname)
+ os.close(self.fd)
except OSError:
pass
def test_openfile_rb(self):
# First create the file using Python's open().
- f = open(self.fname, 'wb')
- f.write(self.data)
- f.close()
+ with open(self.fname, 'wb') as f:
+ f.write(self.data)
+
# Now open the file using M2Crypto.BIO.openfile().
- f = openfile(self.fname, 'rb')
- data = f.read(len(self.data))
- assert data == self.data
+ with openfile(self.fname, 'rb') as f:
+ data = f.read(len(self.data))
+
+ self.assertEqual(data, self.data)
def test_openfile_wb(self):
# First create the file using M2Crypto.BIO.openfile().
- f = openfile(self.fname, 'wb')
- f.write(self.data)
- f.close()
+ with openfile(self.fname, 'wb') as f:
+ f.write(self.data)
+
# Now open the file using Python's open().
- f = open(self.fname, 'rb')
- data = f.read(len(self.data))
- assert data == self.data
+ with open(self.fname, 'rb') as f:
+ data = f.read(len(self.data))
+
+ self.assertEqual(data, self.data)
def test_closed(self):
f = openfile(self.fname, 'wb')
f.write(self.data)
f.close()
- self.assertRaises(IOError, f.write, self.data)
+ with self.assertRaises(IOError):
+ f.write(self.data)
def test_use_pyfile(self):
# First create the file.
- f = open(self.fname, 'wb')
- f2 = File(f)
- f2.write(self.data)
- f2.close()
+ with open(self.fname, 'wb') as f:
+ f2 = File(f)
+ f2.write(self.data)
+ f2.close()
+
# Now read the file.
- f = open(self.fname, 'rb')
- data = f.read(len(self.data))
- assert data == self.data
+ with open(self.fname, 'rb') as f:
+ in_data = f.read(len(self.data))
+
+ self.assertEqual(len(in_data), len(self.data))
+ self.assertEqual(in_data, self.data)
+
+ def test_readline_bin(self):
+ with open(self.fname, 'wb') as f:
+ f.write(b'hello\nworld\n')
+ with openfile(self.fname, 'rb') as f:
+ self.assertTrue(f.readable())
+ self.assertEqual(f.readline(), b'hello\n')
+ self.assertEqual(f.readline(), b'world\n')
+ with openfile(self.fname, 'rb') as f:
+ self.assertEqual(
+ f.readlines(),
+ [b'hello\n', b'world\n'])
+
+ def test_readline(self):
+ sep = os.linesep.encode()
+ with open(self.fname, 'w') as f:
+ f.write('hello\nworld\n')
+ with openfile(self.fname, 'rb') as f:
+ self.assertTrue(f.readable())
+ self.assertEqual(f.readline(), b'hello' + sep)
+ self.assertEqual(f.readline(), b'world' + sep)
+ with openfile(self.fname, 'rb') as f:
+ self.assertEqual(
+ f.readlines(),
+ [b'hello' + sep, b'world' + sep])
+
+ def test_tell_seek(self):
+ with open(self.fname, 'w') as f:
+ f.write('hello world')
+ with openfile(self.fname, 'r') as f:
+ # Seek absolute
+ f.seek(6)
+ self.assertEqual(f.tell(), 6)
def suite():
- # Python 2.2 warns that os.tmpnam() is unsafe.
- try:
- import warnings
- warnings.filterwarnings('ignore')
- except ImportError:
- pass
return unittest.makeSuite(FileTestCase)
-
+
if __name__ == '__main__':
unittest.TextTestRunner().run(suite())
-
diff --git a/tests/test_bio_iobuf.py b/tests/test_bio_iobuf.py
index 358e5df..372fd04 100644
--- a/tests/test_bio_iobuf.py
+++ b/tests/test_bio_iobuf.py
@@ -4,16 +4,16 @@
Copyright (c) 2000 Ng Pheng Siong. All rights reserved."""
-from cStringIO import StringIO
+from io import BytesIO
-import unittest
-import M2Crypto
from M2Crypto.BIO import IOBuffer, MemoryBuffer
+from tests import unittest
+
class IOBufferTestCase(unittest.TestCase):
def setUp(self):
- self._data = 'abcdef\n'
+ self._data = b'abcdef\n'
self.data = self._data * 1024
def tearDown(self):
@@ -23,30 +23,30 @@ class IOBufferTestCase(unittest.TestCase):
mb = MemoryBuffer()
io = IOBuffer(mb)
out = io.read()
- assert out == ''
+ self.assertEqual(out, b'')
def test_init_something(self):
mb = MemoryBuffer(self.data)
io = IOBuffer(mb)
out = io.read(len(self.data))
- assert out == self.data
+ self.assertEqual(out, self.data)
def test_read_less_than(self):
chunk = len(self.data) - 7
mb = MemoryBuffer(self.data)
io = IOBuffer(mb)
out = io.read(chunk)
- assert out == self.data[:chunk]
-
+ self.assertEqual(out, self.data[:chunk])
+
def test_read_more_than(self):
chunk = len(self.data) + 8
mb = MemoryBuffer(self.data)
io = IOBuffer(mb)
out = io.read(chunk)
- assert out == self.data
+ self.assertEqual(out, self.data)
def test_readline(self):
- buf = StringIO()
+ buf = BytesIO()
mb = MemoryBuffer(self.data)
io = IOBuffer(mb)
while 1:
@@ -54,37 +54,38 @@ class IOBufferTestCase(unittest.TestCase):
if not out:
break
buf.write(out)
- assert out == self._data
- assert buf.getvalue() == self.data
+ self.assertEqual(out, self._data)
+ self.assertEqual(buf.getvalue(), self.data)
def test_readlines(self):
- buf = StringIO()
+ buf = BytesIO()
mb = MemoryBuffer(self.data)
io = IOBuffer(mb)
lines = io.readlines()
for line in lines:
- assert line == self._data
+ self.assertEqual(line, self._data)
buf.write(line)
- assert buf.getvalue() == self.data
+ self.assertEqual(buf.getvalue(), self.data)
def test_closed(self):
mb = MemoryBuffer(self.data)
io = IOBuffer(mb)
io.close()
- self.assertRaises(IOError, io.write, self.data)
+ with self.assertRaises(IOError):
+ io.write(self.data)
assert not io.readable() and not io.writeable()
def test_read_only(self):
mb = MemoryBuffer(self.data)
io = IOBuffer(mb, mode='r')
- self.assertRaises(IOError, io.write, self.data)
+ with self.assertRaises(IOError):
+ io.write(self.data)
assert not io.writeable()
def suite():
return unittest.makeSuite(IOBufferTestCase)
-
+
if __name__ == '__main__':
unittest.TextTestRunner().run(suite())
-
diff --git a/tests/test_bio_membuf.py b/tests/test_bio_membuf.py
index 7d719fd..49a0e24 100644
--- a/tests/test_bio_membuf.py
+++ b/tests/test_bio_membuf.py
@@ -4,61 +4,114 @@
Copyright (c) 2000 Ng Pheng Siong. All rights reserved."""
-import unittest
-import M2Crypto
+import os
+import multiprocessing
+
from M2Crypto.BIO import MemoryBuffer
+from tests import unittest
+
+
+class TimeLimitExpired(Exception):
+ pass
+
+
+def time_limit(timeout, func, exc_msg, *args, **kwargs):
+ p = multiprocessing.Process(target=func)
+ p.start()
+ p.join(timeout)
+ if p.is_alive():
+ p.terminate()
+ raise TimeLimitExpired(exc_msg)
+
class MemoryBufferTestCase(unittest.TestCase):
def setUp(self):
- self.data = 'abcdef' * 64
+ self.data = b'abcdef' * 64
def tearDown(self):
pass
def test_init_empty(self):
mb = MemoryBuffer()
- assert len(mb) == 0
+ self.assertEqual(len(mb), 0)
out = mb.read()
assert out is None
+ def test_init_empty_cm(self):
+ with MemoryBuffer() as mb:
+ self.assertEqual(len(mb), 0)
+ out = mb.read()
+ assert out is None
+
def test_init_something(self):
mb = MemoryBuffer(self.data)
- assert len(mb) == len(self.data)
+ self.assertEqual(len(mb), len(self.data))
out = mb.read()
- assert out == self.data
+ self.assertEqual(out, self.data)
+
+ def test_init_something_result_bytes(self):
+ mb = MemoryBuffer(self.data)
+ self.assertEqual(len(mb), len(self.data))
+ out = mb.read()
+ self.assertIsInstance(out, bytes)
+
+ def test_init_something_cm(self):
+ with MemoryBuffer(self.data) as mb:
+ self.assertEqual(len(mb), len(self.data))
+ out = mb.read()
+ self.assertEqual(out, self.data)
def test_read_less_than(self):
chunk = len(self.data) - 7
mb = MemoryBuffer(self.data)
out = mb.read(chunk)
- assert out == self.data[:chunk] and len(mb) == (len(self.data) - chunk)
-
+ self.assertEqual(out, self.data[:chunk])
+ self.assertEqual(len(mb), (len(self.data)) - chunk)
+
def test_read_more_than(self):
chunk = len(self.data) + 8
mb = MemoryBuffer(self.data)
out = mb.read(chunk)
- assert out == self.data and len(mb) == 0
+ self.assertEqual(out, self.data)
+ self.assertEqual(len(mb), 0)
def test_write_close(self):
mb = MemoryBuffer(self.data)
assert mb.writeable()
mb.write_close()
assert mb.readable()
- self.assertRaises(IOError, mb.write, self.data)
+ with self.assertRaises(IOError):
+ mb.write(self.data)
assert not mb.writeable()
def test_closed(self):
mb = MemoryBuffer(self.data)
mb.close()
- self.assertRaises(IOError, mb.write, self.data)
+ with self.assertRaises(IOError):
+ mb.write(self.data)
assert mb.readable() and not mb.writeable()
+ def test_readline(self):
+ # test against possible endless loop
+ # http://stackoverflow.com/questions/9280550/
+ timeout_secs = 10
+ time_limit(timeout_secs, run_test,
+ 'The readline() should not timeout!')
+
+
+def run_test(*args, **kwargs):
+ sep = os.linesep.encode()
+ with MemoryBuffer(b'hello\nworld\n') as mb:
+ assert mb.readable()
+ assert mb.readline() == b'hello' + sep
+ assert mb.readline() == b'world' + sep
+ with MemoryBuffer(b'hello\nworld\n') as mb:
+ assert mb.readlines() == [b'hello' + sep, b'world' + sep]
def suite():
return unittest.makeSuite(MemoryBufferTestCase)
-
+
if __name__ == '__main__':
unittest.TextTestRunner().run(suite())
-
diff --git a/tests/test_bio_ssl.py b/tests/test_bio_ssl.py
index 0dee9da..1f9ae89 100644
--- a/tests/test_bio_ssl.py
+++ b/tests/test_bio_ssl.py
@@ -1,28 +1,34 @@
#!/usr/bin/env python
+from __future__ import absolute_import, print_function
+
"""Unit tests for M2Crypto.BIO.File.
Copyright (c) 1999-2002 Ng Pheng Siong. All rights reserved."""
-import unittest, threading, sys, socket
+import socket
+import sys
+import threading
-from M2Crypto import BIO
-from M2Crypto import SSL
+from M2Crypto import BIO
+from M2Crypto import SSL
from M2Crypto import Err
from M2Crypto import Rand
from M2Crypto import threading as m2threading
-from test_ssl import srv_host, srv_port
+from tests import unittest
+from tests.test_ssl import srv_host, allocate_srv_port
+
class HandshakeClient(threading.Thread):
-
+
def __init__(self, host, port):
threading.Thread.__init__(self)
self.host = host
self.port = port
-
+
def run(self):
ctx = SSL.Context()
- ctx.load_cert_chain("tests/server.pem")
+ ctx.load_cert_chain("tests/server.pem")
conn = SSL.Connection(ctx)
cipher_list = conn.get_cipher_list()
sslbio = BIO.SSLBio()
@@ -33,92 +39,96 @@ class HandshakeClient(threading.Thread):
conn.set_connect_state()
sock = socket.socket()
sock.connect((self.host, self.port))
-
+
handshake_complete = False
while not handshake_complete:
ret = sslbio.do_handshake()
- if ret <= 0:
+ if ret <= 0:
if not sslbio.should_retry() or not sslbio.should_read():
- err_string = Err.get_error()
- print err_string
+ err_string = Err.get_error()
+ print(err_string)
sys.exit("unrecoverable error in handshake - client")
else:
- output_token = writebio.read()
- if output_token is not None:
- sock.sendall(output_token)
- else:
- input_token = sock.recv(1024)
- readbio.write(input_token)
+ output_token = writebio.read()
+ if output_token is not None:
+ sock.sendall(output_token)
+ else:
+ input_token = sock.recv(1024)
+ readbio.write(input_token)
else:
- handshake_complete = True
-
+ handshake_complete = True
+
+ output_token = writebio.read()
+ if output_token is not None:
+ sock.sendall(output_token)
sock.close()
class SSLTestCase(unittest.TestCase):
-
+
def setUp(self):
self.sslbio = BIO.SSLBio()
-
- def test_pass(self): # XXX leaks 64/24 bytes
+
+ def test_pass(self): # XXX leaks 64/24 bytes
pass
- def test_set_ssl(self): # XXX leaks 64/1312 bytes
+ def test_set_ssl(self): # XXX leaks 64/1312 bytes
ctx = SSL.Context()
conn = SSL.Connection(ctx)
self.sslbio.set_ssl(conn)
- def test_do_handshake_fail(self): # XXX leaks 64/42066 bytes
+ def test_do_handshake_fail(self): # XXX leaks 64/42066 bytes
ctx = SSL.Context()
conn = SSL.Connection(ctx)
conn.set_connect_state()
self.sslbio.set_ssl(conn)
- ret = self.sslbio.do_handshake()
- assert ret == 0
+ ret = self.sslbio.do_handshake()
+ self.assertIn(ret, (-1, 0))
- def test_should_retry_fail(self): # XXX leaks 64/1312 bytes
+ def test_should_retry_fail(self): # XXX leaks 64/1312 bytes
ctx = SSL.Context()
- conn = SSL.Connection(ctx)
+ conn = SSL.Connection(ctx)
self.sslbio.set_ssl(conn)
- ret = self.sslbio.do_handshake()
- assert ret == -1
- ret = self.sslbio.should_retry()
- assert ret == 0
-
- def test_should_write_fail(self): # XXX leaks 64/1312 bytes
+ ret = self.sslbio.do_handshake()
+ self.assertIn(ret, (-1, 0))
+ ret = self.sslbio.should_retry()
+ self.assertEqual(ret, 0)
+
+ def test_should_write_fail(self): # XXX leaks 64/1312 bytes
ctx = SSL.Context()
- conn = SSL.Connection(ctx)
+ conn = SSL.Connection(ctx)
self.sslbio.set_ssl(conn)
- ret = self.sslbio.do_handshake()
- assert ret == -1
- ret = self.sslbio.should_write()
- assert ret == 0
-
- def test_should_read_fail(self): # XXX leaks 64/1312 bytes
+ ret = self.sslbio.do_handshake()
+ self.assertIn(ret, (-1, 0))
+ ret = self.sslbio.should_write()
+ self.assertEqual(ret, 0)
+
+ def test_should_read_fail(self): # XXX leaks 64/1312 bytes
ctx = SSL.Context()
conn = SSL.Connection(ctx)
self.sslbio.set_ssl(conn)
- ret = self.sslbio.do_handshake()
- assert ret == -1
- ret = self.sslbio.should_read()
- assert ret == 0
-
- def test_do_handshake_succeed(self): # XXX leaks 196/26586 bytes
- ctx = SSL.Context()
+ ret = self.sslbio.do_handshake()
+ self.assertIn(ret, (-1, 0))
+ ret = self.sslbio.should_read()
+ self.assertEqual(ret, 0)
+
+ def test_do_handshake_succeed(self): # XXX leaks 196/26586 bytes
+ ctx = SSL.Context()
ctx.load_cert_chain("tests/server.pem")
- conn = SSL.Connection(ctx)
+ conn = SSL.Connection(ctx)
self.sslbio.set_ssl(conn)
readbio = BIO.MemoryBuffer()
writebio = BIO.MemoryBuffer()
conn.set_bio(readbio, writebio)
conn.set_accept_state()
handshake_complete = False
+ srv_port = allocate_srv_port()
sock = socket.socket()
sock.bind((srv_host, srv_port))
sock.listen(5)
handshake_client = HandshakeClient(srv_host, srv_port)
- handshake_client.start()
- new_sock, addr = sock.accept()
+ handshake_client.start()
+ new_sock, _ = sock.accept()
while not handshake_complete:
input_token = new_sock.recv(1024)
readbio.write(input_token)
@@ -130,17 +140,18 @@ class SSLTestCase(unittest.TestCase):
else:
handshake_complete = True
- output_token = writebio.read()
+ output_token = writebio.read()
if output_token is not None:
new_sock.sendall(output_token)
-
- handshake_client.join()
- sock.close()
- new_sock.close()
-def suite():
+ handshake_client.join()
+ sock.close()
+ new_sock.close()
+
+
+def suite():
return unittest.makeSuite(SSLTestCase)
-
+
if __name__ == '__main__':
Rand.load_file('randpool.dat', -1)
diff --git a/tests/test_bn.py b/tests/test_bn.py
index 62c83fe..410969a 100755..100644
--- a/tests/test_bn.py
+++ b/tests/test_bn.py
@@ -6,18 +6,22 @@ Unit tests for M2Crypto.BN.
Copyright (c) 2005 Open Source Applications Foundation. All rights reserved.
"""
-import unittest, re
+import re
+import warnings
+
from M2Crypto import BN, Rand
+from tests import unittest
loops = 16
+
class BNTestCase(unittest.TestCase):
def test_rand(self):
# defaults
for x in range(loops):
r8 = BN.rand(8)
-
+
# top
for x in range(loops):
r8 = BN.rand(8, top=0)
@@ -25,7 +29,7 @@ class BNTestCase(unittest.TestCase):
for x in range(loops):
r8 = BN.rand(8, top=1)
assert r8 & 192
-
+
# bottom
for x in range(loops):
r8 = BN.rand(8, bottom=1)
@@ -41,38 +45,37 @@ class BNTestCase(unittest.TestCase):
r256 = BN.rand(256, top=0)
r512 = BN.rand(512, top=0)
assert r8 < r16 < r32 < r64 < r128 < r256 < r512 < (r512 + 1)
-
def test_rand_range(self):
# small range
for x in range(loops):
r = BN.rand_range(1)
- assert r == 0
-
+ self.assertEqual(r, 0)
+
for x in range(loops):
r = BN.rand_range(4)
assert 0 <= r < 4
-
+
# large range
r512 = BN.rand(512, top=0)
for x in range(loops):
r = BN.rand_range(r512)
assert 0 <= r < r512
-
def test_randfname(self):
m = re.compile('^[a-zA-Z0-9]{8}$')
for x in range(loops):
- r = BN.randfname(8)
+ with warnings.catch_warnings():
+ warnings.simplefilter('ignore', DeprecationWarning)
+ r = BN.randfname(8)
assert m.match(r)
-
+
def suite():
return unittest.makeSuite(BNTestCase)
if __name__ == '__main__':
- Rand.load_file('randpool.dat', -1)
+ Rand.load_file('randpool.dat', -1)
unittest.TextTestRunner().run(suite())
Rand.save_file('randpool.dat')
-
diff --git a/tests/test_dh.py b/tests/test_dh.py
index 0e66c89..074f154 100644
--- a/tests/test_dh.py
+++ b/tests/test_dh.py
@@ -4,41 +4,43 @@
Copyright (c) 2000 Ng Pheng Siong. All rights reserved."""
-import unittest
-from M2Crypto import DH, BIO, Rand, m2
+from M2Crypto import DH, BIO, Rand
+from tests import unittest
+
class DHTestCase(unittest.TestCase):
params = 'tests/dhparam.pem'
def genparam_callback(self, *args):
- pass
+ pass
def genparam_callback2(self):
- pass
+ pass
def test_init_junk(self):
- self.assertRaises(TypeError, DH.DH, 'junk')
+ with self.assertRaises(TypeError):
+ DH.DH('junk')
def test_gen_params(self):
a = DH.gen_params(1024, 2, self.genparam_callback)
- assert a.check_params() == 0
+ self.assertEqual(a.check_params(), 0)
def test_gen_params_bad_cb(self):
a = DH.gen_params(1024, 2, self.genparam_callback2)
- assert a.check_params() == 0
+ self.assertEqual(a.check_params(), 0)
def test_print_params(self):
a = DH.gen_params(1024, 2, self.genparam_callback)
bio = BIO.MemoryBuffer()
a.print_params(bio)
params = bio.read()
- assert params.find('(1024 bit)')
- assert params.find('generator: 2 (0x2)')
+ self.assertTrue(params.find(b'(1024 bit)'))
+ self.assertTrue(params.find(b'generator: 2 (0x2)'))
def test_load_params(self):
a = DH.load_params('tests/dhparams.pem')
- assert a.check_params() == 0
+ self.assertEqual(a.check_params(), 0)
def test_compute_key(self):
a = DH.load_params('tests/dhparams.pem')
@@ -47,19 +49,20 @@ class DHTestCase(unittest.TestCase):
b.gen_key()
ak = a.compute_key(b.pub)
bk = b.compute_key(a.pub)
- assert ak == bk
+ self.assertEqual(ak, bk)
self.assertEqual(len(a), 128)
- self.assertRaises(DH.DHError, setattr, a, 'p', 1)
- self.assertRaises(DH.DHError, setattr, a, 'priv', 1)
+ with self.assertRaises(DH.DHError):
+ setattr(a, 'p', 1)
+ with self.assertRaises(DH.DHError):
+ setattr(a, 'priv', 1)
def suite():
return unittest.makeSuite(DHTestCase)
-if __name__=='__main__':
- Rand.load_file('randpool.dat', -1)
+if __name__ == '__main__':
+ Rand.load_file('randpool.dat', -1)
unittest.TextTestRunner().run(suite())
Rand.save_file('randpool.dat')
-
diff --git a/tests/test_dsa.py b/tests/test_dsa.py
index 7823f50..a9a940a 100644
--- a/tests/test_dsa.py
+++ b/tests/test_dsa.py
@@ -4,38 +4,44 @@
Copyright (c) 2000 Ng Pheng Siong. All rights reserved."""
-import unittest
-import sha
-from M2Crypto import DSA, BIO, Rand, m2
+import hashlib
+
+from M2Crypto import DSA, Rand
+from tests import unittest
+
class DSATestCase(unittest.TestCase):
- errkey = 'tests/rsa.priv.pem'
+ errkey = 'tests/rsa.priv.pem'
privkey = 'tests/dsa.priv.pem'
- pubkey = 'tests/dsa.pub.pem'
- param = 'tests/dsa.param.pem'
+ pubkey = 'tests/dsa.pub.pem'
+ param = 'tests/dsa.param.pem'
- data = sha.sha('Can you spell subliminal channel?').digest()
- different_data = sha.sha('I can spell.').digest()
+ data = hashlib.sha1(b'Can you spell subliminal channel?').digest()
+ different_data = hashlib.sha1(b'I can spell.').digest()
def callback(self, *args):
pass
def test_loadkey_junk(self):
- self.assertRaises(DSA.DSAError, DSA.load_key, self.errkey)
+ with self.assertRaises(DSA.DSAError):
+ DSA.load_key(self.errkey)
def test_loadkey(self):
dsa = DSA.load_key(self.privkey)
- assert len(dsa) == 1024
- self.assertRaises(AttributeError, getattr, dsa, 'foobar')
+ self.assertEqual(len(dsa), 1024)
+ with self.assertRaises(AttributeError):
+ getattr(dsa, 'foobar')
for k in ('p', 'q', 'g', 'priv', 'pub'):
- self.assertRaises(DSA.DSAError, setattr, dsa, k, 1)
+ with self.assertRaises(DSA.DSAError):
+ setattr(dsa, k, 1)
def test_loadparam(self):
- self.assertRaises(DSA.DSAError, DSA.load_key, self.param)
+ with self.assertRaises(DSA.DSAError):
+ DSA.load_key(self.param)
dsa = DSA.load_params(self.param)
assert not dsa.check_key()
- assert len(dsa) == 1024
+ self.assertEqual(len(dsa), 1024)
def test_sign(self):
dsa = DSA.load_key(self.privkey)
@@ -51,8 +57,10 @@ class DSATestCase(unittest.TestCase):
def test_sign_with_params_only(self):
dsa = DSA.load_params(self.param)
- self.assertRaises(AssertionError, dsa.sign, self.data)
- self.assertRaises(AssertionError, dsa.sign_asn1, self.data)
+ with self.assertRaises(AssertionError):
+ dsa.sign(self.data)
+ with self.assertRaises(AssertionError):
+ dsa.sign_asn1(self.data)
def test_pub_verify(self):
dsa = DSA.load_key(self.privkey)
@@ -60,7 +68,8 @@ class DSATestCase(unittest.TestCase):
dsapub = DSA.load_pub_key(self.pubkey)
assert dsapub.check_key()
assert dsapub.verify(self.data, r, s)
- self.assertRaises(DSA.DSAError, dsapub.sign)
+ with self.assertRaises(DSA.DSAError):
+ dsapub.sign()
def test_verify_fail(self):
dsa = DSA.load_key(self.privkey)
@@ -69,30 +78,44 @@ class DSATestCase(unittest.TestCase):
def test_verify_fail2(self):
dsa = DSA.load_key(self.privkey)
- r,s = dsa.sign(self.data)
+ r, s = dsa.sign(self.data)
dsa2 = DSA.load_params(self.param)
assert not dsa2.check_key()
- self.assertRaises(AssertionError, dsa2.verify, self.data, r, s)
+ with self.assertRaises(AssertionError):
+ dsa2.verify(self.data, r, s)
def test_genparam_setparam_genkey(self):
dsa = DSA.gen_params(1024, self.callback)
- assert len(dsa) == 1024
+ self.assertEqual(len(dsa), 1024)
p = dsa.p
q = dsa.q
g = dsa.g
- dsa2 = DSA.set_params(p,q,g)
+ dsa2 = DSA.set_params(p, q, g)
assert not dsa2.check_key()
dsa2.gen_key()
assert dsa2.check_key()
- r,s = dsa2.sign(self.data)
+ r, s = dsa2.sign(self.data)
+ assert dsa2.verify(self.data, r, s)
+
+ def test_pub_key_from_params(self):
+ dsa = DSA.gen_params(1024, self.callback)
+ dsa.gen_key()
+ assert len(dsa) == 1024
+ p = dsa.p
+ q = dsa.q
+ g = dsa.g
+ pub = dsa.pub
+ dsa2 = DSA.pub_key_from_params(p, q, g, pub)
+ assert dsa2.check_key()
+ r, s = dsa.sign(self.data)
assert dsa2.verify(self.data, r, s)
+
def suite():
return unittest.makeSuite(DSATestCase)
-
+
if __name__ == '__main__':
- Rand.load_file('randpool.dat', -1)
+ Rand.load_file('randpool.dat', -1)
unittest.TextTestRunner().run(suite())
Rand.save_file('randpool.dat')
-
diff --git a/tests/test_ec_curves.py b/tests/test_ec_curves.py
index d01f863..c15dcec 100644
--- a/tests/test_ec_curves.py
+++ b/tests/test_ec_curves.py
@@ -1,150 +1,163 @@
#!/usr/bin/env python
# XXX memory leaks
+from __future__ import absolute_import
+
"""
Unit tests for M2Crypto.EC, the curves
-
+
There are several ways one could unittest elliptical curves
- but we are going to only validate that we are using the
+ but we are going to only validate that we are using the
OpenSSL curve and that it works with ECDSA. We will assume
- OpenSSL has validated the curves themselves.
-
- Also, some curves are shorter than a SHA-1 digest of 160
+ OpenSSL has validated the curves themselves.
+
+ Also, some curves are shorter than a SHA-1 digest of 160
bits. To keep the testing simple, we will take advantage
- of ECDSA's ability to sign any digest length and create a
+ of ECDSA's ability to sign any digest length and create a
digset string of only 48 bits. Remember we are testing our
ability to access the curve, not ECDSA itself.
-
+
Copyright (c) 2006 Larry Bugbee. All rights reserved.
-
+
"""
+import logging
+
+from M2Crypto import EC, Rand, m2 # noqa
+from tests import unittest
+
+log = logging.getLogger(__name__)
+
+
+curves = {
+ 'secp112r1': 112,
+ 'secp112r2': 112,
+ 'secp128r1': 128,
+ 'secp128r2': 128,
+ 'secp160k1': 160,
+ 'secp160r1': 160,
+ 'secp160r2': 160,
+ 'secp192k1': 192,
+ 'secp224k1': 224,
+ 'secp224r1': 224,
+ 'secp256k1': 256,
+ 'secp384r1': 384,
+ 'secp521r1': 521,
+
+ 'sect113r1': 113,
+ 'sect113r2': 113,
+ 'sect131r1': 131,
+ 'sect131r2': 131,
+ 'sect163k1': 163,
+ 'sect163r1': 163,
+ 'sect163r2': 163,
+ 'sect193r1': 193,
+ 'sect193r2': 193,
+ 'sect233k1': 233,
+ 'sect233r1': 233,
+ 'sect239k1': 239,
+ 'sect283k1': 283,
+ 'sect283r1': 283,
+ 'sect409k1': 409,
+ 'sect409r1': 409,
+ 'sect571k1': 571,
+ 'sect571r1': 571,
+
+ 'X9_62_prime192v1': 192,
+ 'X9_62_prime192v2': 192,
+ 'X9_62_prime192v3': 192,
+ 'X9_62_prime239v1': 239,
+ 'X9_62_prime239v2': 239,
+ 'X9_62_prime239v3': 239,
+ 'X9_62_prime256v1': 256,
-import unittest
-#import sha
-from M2Crypto import EC, Rand
-from test_ecdsa import ECDSATestCase as ECDSATest
-
-
-curves = [
- ('secp112r1', 112),
- ('secp112r2', 112),
- ('secp128r1', 128),
- ('secp128r2', 128),
- ('secp160k1', 160),
- ('secp160r1', 160),
- ('secp160r2', 160),
- ('secp192k1', 192),
- ('secp224k1', 224),
- ('secp224r1', 224),
- ('secp256k1', 256),
- ('secp384r1', 384),
- ('secp521r1', 521),
-
- ('sect113r1', 113),
- ('sect113r2', 113),
- ('sect131r1', 131),
- ('sect131r2', 131),
- ('sect163k1', 163),
- ('sect163r1', 163),
- ('sect163r2', 163),
- ('sect193r1', 193),
- ('sect193r2', 193),
- ('sect233k1', 233),
- ('sect233r1', 233),
- ('sect239k1', 239),
- ('sect283k1', 283),
- ('sect283r1', 283),
- ('sect409k1', 409),
- ('sect409r1', 409),
- ('sect571k1', 571),
- ('sect571r1', 571),
-
- ('X9_62_prime192v1', 192),
- ('X9_62_prime192v2', 192),
- ('X9_62_prime192v3', 192),
- ('X9_62_prime239v1', 239),
- ('X9_62_prime239v2', 239),
- ('X9_62_prime239v3', 239),
- ('X9_62_prime256v1', 256),
-
- ('X9_62_c2pnb163v1', 163),
- ('X9_62_c2pnb163v2', 163),
- ('X9_62_c2pnb163v3', 163),
- ('X9_62_c2pnb176v1', 176),
- ('X9_62_c2tnb191v1', 191),
- ('X9_62_c2tnb191v2', 191),
- ('X9_62_c2tnb191v3', 191),
- ('X9_62_c2pnb208w1', 208),
- ('X9_62_c2tnb239v1', 239),
- ('X9_62_c2tnb239v2', 239),
- ('X9_62_c2tnb239v3', 239),
- ('X9_62_c2pnb272w1', 272),
- ('X9_62_c2pnb304w1', 304),
- ('X9_62_c2tnb359v1', 359),
- ('X9_62_c2pnb368w1', 368),
- ('X9_62_c2tnb431r1', 431),
-
- ('wap_wsg_idm_ecid_wtls1', 113),
- ('wap_wsg_idm_ecid_wtls3', 163),
- ('wap_wsg_idm_ecid_wtls4', 113),
- ('wap_wsg_idm_ecid_wtls5', 163),
- ('wap_wsg_idm_ecid_wtls6', 112),
- ('wap_wsg_idm_ecid_wtls7', 160),
- ('wap_wsg_idm_ecid_wtls8', 112),
- ('wap_wsg_idm_ecid_wtls9', 160),
- ('wap_wsg_idm_ecid_wtls10', 233),
- ('wap_wsg_idm_ecid_wtls11', 233),
- ('wap_wsg_idm_ecid_wtls12', 224),
-]
-
-# The following two curves, according to OpenSSL, have a
-# "Questionable extension field!" and are not supported by
+ 'X9_62_c2pnb163v1': 163,
+ 'X9_62_c2pnb163v2': 163,
+ 'X9_62_c2pnb163v3': 163,
+ 'X9_62_c2pnb176v1': 176,
+ 'X9_62_c2tnb191v1': 191,
+ 'X9_62_c2tnb191v2': 191,
+ 'X9_62_c2tnb191v3': 191,
+ 'X9_62_c2pnb208w1': 208,
+ 'X9_62_c2tnb239v1': 239,
+ 'X9_62_c2tnb239v2': 239,
+ 'X9_62_c2tnb239v3': 239,
+ 'X9_62_c2pnb272w1': 272,
+ 'X9_62_c2pnb304w1': 304,
+ 'X9_62_c2tnb359v1': 359,
+ 'X9_62_c2pnb368w1': 368,
+ 'X9_62_c2tnb431r1': 431,
+
+ 'wap_wsg_idm_ecid_wtls1': 113,
+ 'wap_wsg_idm_ecid_wtls3': 163,
+ 'wap_wsg_idm_ecid_wtls4': 113,
+ 'wap_wsg_idm_ecid_wtls5': 163,
+ 'wap_wsg_idm_ecid_wtls6': 112,
+ 'wap_wsg_idm_ecid_wtls7': 160,
+ 'wap_wsg_idm_ecid_wtls8': 112,
+ 'wap_wsg_idm_ecid_wtls9': 160,
+ 'wap_wsg_idm_ecid_wtls10': 233,
+ 'wap_wsg_idm_ecid_wtls11': 233,
+ 'wap_wsg_idm_ecid_wtls12': 224
+}
+
+# The following two curves, according to OpenSSL, have a
+# "Questionable extension field!" and are not supported by
# the OpenSSL inverse function. ECError: no inverse.
-# As such they cannot be used for signing. They might,
-# however, be usable for encryption but that has not
+# As such they cannot be used for signing. They might,
+# however, be usable for encryption but that has not
# been tested. Until thir usefulness can be established,
# they are not supported at this time.
-#curves2 = [
+# curves2 = [
# ('ipsec3', 155),
# ('ipsec4', 185),
-#]
+# ]
+
+
+def available_curves():
+ bc_dict = EC.get_builtin_curves()
+ bin_curves = set(x['sname'] for x in bc_dict)
+ out_curves = tuple((m2.obj_sn2nid(x[0]), x[1]) for x in curves
+ if x[0] in bin_curves)
+ return out_curves
+
+# Seems like one of the most widely supported curves.
+tested_curve = EC.NID_secp384r1, curves['secp384r1']
+
class ECCurveTests(unittest.TestCase):
- #data = sha.sha('Kilroy was here!').digest() # 160 bits
- data = "digest" # keep short (48 bits) so lesser curves
- # will work... ECDSA requires curve be
- # equal or longer than digest
-
- def genkey(self, curveName, curveLen):
- curve = getattr(EC, 'NID_'+curveName)
- ec = EC.gen_params(curve)
- assert len(ec) == curveLen
+ data = "digest"
+
+ def genkey(self, curve):
+ try:
+ curve_name = m2.obj_nid2sn(curve[0])
+ except TypeError:
+ # we have to throw different exception for compatibility
+ raise AttributeError('Unknown cipher %s', curve[0])
+ ec = EC.gen_params(curve[0])
+ self.assertEqual(len(ec), curve[1])
ec.gen_key()
- assert ec.check_key(), 'check_key() failure for "%s"' % curveName
+ self.assertTrue(ec.check_key(),
+ 'check_key() failure for "%s"' %
+ curve_name)
return ec
-# def check_ec_curves_genkey(self):
-# for curveName, curveLen in curves2:
-# self.genkey(curveName, curveLen)
-#
-# self.assertRaises(AttributeError, self.genkey,
-# 'nosuchcurve', 1)
-
- def sign_verify_ecdsa(self, curveName, curveLen):
- ec = self.genkey(curveName, curveLen)
+ def sign_verify_ecdsa(self, curve):
+ ec = self.genkey(curve)
r, s = ec.sign_dsa(self.data)
- assert ec.verify_dsa(self.data, r, s)
- assert not ec.verify_dsa(self.data, s, r)
+ self.assertTrue(ec.verify_dsa(self.data, r, s))
+ self.assertFalse(ec.verify_dsa(self.data, s, r))
- def test_ec_curves_ECDSA(self):
- for curveName, curveLen in curves:
- self.sign_verify_ecdsa(curveName, curveLen)
+ def test_ec_curves_ECDSA(self): # noqa
+ for curve in available_curves():
+ self.sign_verify_ecdsa(curve)
- self.assertRaises(AttributeError, self.sign_verify_ecdsa,
- 'nosuchcurve', 1)
+ with self.assertRaises(AttributeError):
+ self.sign_verify_ecdsa(('nosuchcurve', 1))
+
+ def test_ec_get_builtin_curves(self):
+ curves = EC.get_builtin_curves()
+ self.assertNotEqual(curves, [])
+ self.assertIsNotNone(curves)
-# for curveName, curveLen in curves2:
-# self.assertRaises(EC.ECError, self.sign_verify_ecdsa,
-# curveName, curveLen)
def suite():
suite = unittest.TestSuite()
@@ -153,7 +166,6 @@ def suite():
if __name__ == '__main__':
- Rand.load_file('randpool.dat', -1)
+ Rand.load_file('randpool.dat', -1)
unittest.TextTestRunner().run(suite())
Rand.save_file('randpool.dat')
-
diff --git a/tests/test_ecdh.py b/tests/test_ecdh.py
index 29581dc..0dc4600 100644
--- a/tests/test_ecdh.py
+++ b/tests/test_ecdh.py
@@ -3,47 +3,49 @@
"""Unit tests for M2Crypto.EC, ECDH part.
Copyright (c) 2000 Ng Pheng Siong. All rights reserved.
-Portions copyright (c) 2005-2006 Vrije Universiteit Amsterdam. All rights reserved.
+Portions copyright (c) 2005-2006 Vrije Universiteit Amsterdam. All
+rights reserved.
"""
+from M2Crypto import EC, Rand
+
+from tests import unittest
+from tests.test_ec_curves import tested_curve
-import unittest
-from M2Crypto import EC, BIO, Rand, m2
-import sys
class ECDHTestCase(unittest.TestCase):
privkey = 'tests/ec.priv.pem'
def test_init_junk(self):
- self.assertRaises(TypeError, EC.EC, 'junk')
+ with self.assertRaises(TypeError):
+ EC.EC('junk')
def test_compute_key(self):
a = EC.load_key(self.privkey)
- b = EC.gen_params(EC.NID_sect233k1)
+ b = EC.gen_params(tested_curve[0])
b.gen_key()
ak = a.compute_dh_key(b.pub())
bk = b.compute_dh_key(a.pub())
- assert ak == bk
+ self.assertEqual(ak, bk)
def test_pubkey_from_der(self):
- a = EC.gen_params(EC.NID_sect233k1)
+ a = EC.gen_params(tested_curve[0])
a.gen_key()
- b = EC.gen_params(EC.NID_sect233k1)
+ b = EC.gen_params(tested_curve[0])
b.gen_key()
a_pub_der = a.pub().get_der()
a_pub = EC.pub_key_from_der(a_pub_der)
ak = a.compute_dh_key(b.pub())
bk = b.compute_dh_key(a_pub)
- assert ak == bk
+ self.assertEqual(ak, bk)
def suite():
return unittest.makeSuite(ECDHTestCase)
-if __name__=='__main__':
- Rand.load_file('randpool.dat', -1)
+if __name__ == '__main__':
+ Rand.load_file('randpool.dat', -1)
unittest.TextTestRunner().run(suite())
Rand.save_file('randpool.dat')
-
diff --git a/tests/test_ecdsa.py b/tests/test_ecdsa.py
index 74d9a82..dea1209 100644
--- a/tests/test_ecdsa.py
+++ b/tests/test_ecdsa.py
@@ -3,12 +3,19 @@
"""Unit tests for M2Crypto.EC, ECDSA part.
Copyright (c) 2000 Ng Pheng Siong. All rights reserved.
-Portions copyright (c) 2005-2006 Vrije Universiteit Amsterdam. All rights reserved.
+Portions copyright (c) 2005-2006 Vrije Universiteit Amsterdam. All
+rights reserved.
"""
+import hashlib
+import logging
+
+from M2Crypto import EC, Rand
+
+from tests import unittest
+from tests.test_ec_curves import tested_curve
+
+log = logging.getLogger(__name__)
-import unittest
-import sha
-from M2Crypto import EC, BIO, Rand, m2
class ECDSATestCase(unittest.TestCase):
@@ -16,7 +23,7 @@ class ECDSATestCase(unittest.TestCase):
privkey = 'tests/ec.priv.pem'
pubkey = 'tests/ec.pub.pem'
- data = sha.sha('Can you spell subliminal channel?').digest()
+ data = hashlib.sha1(b'Can you spell subliminal channel?').digest()
def callback(self, *args):
pass
@@ -25,22 +32,25 @@ class ECDSATestCase(unittest.TestCase):
pass
def test_loadkey_junk(self):
- self.assertRaises(ValueError, EC.load_key, self.errkey)
+ with self.assertRaises(ValueError):
+ EC.load_key(self.errkey)
def test_loadkey(self):
ec = EC.load_key(self.privkey)
- assert len(ec) == 233
+ self.assertEqual(len(ec), tested_curve[1])
def test_loadpubkey(self):
# XXX more work needed
ec = EC.load_pub_key(self.pubkey)
- assert len(ec) == 233
- self.assertRaises(EC.ECError, EC.load_pub_key, self.errkey)
+ self.assertEqual(len(ec), tested_curve[1])
+ with self.assertRaises(EC.ECError):
+ EC.load_pub_key(self.errkey)
def _test_sign_dsa(self):
- ec = EC.gen_params(EC.NID_sect233k1)
+ ec = EC.gen_params(tested_curve[0])
# ec.gen_key()
- self.assertRaises(EC.ECError, ec.sign_dsa, self.data)
+ with self.assertRaises(EC.ECError):
+ ec.sign_dsa(self.data)
ec = EC.load_key(self.privkey)
r, s = ec.sign_dsa(self.data)
assert ec.verify_dsa(self.data, r, s)
@@ -50,7 +60,8 @@ class ECDSATestCase(unittest.TestCase):
ec = EC.load_key(self.privkey)
blob = ec.sign_dsa_asn1(self.data)
assert ec.verify_dsa_asn1(self.data, blob)
- self.assertRaises(EC.ECError, ec.verify_dsa_asn1, blob, self.data)
+ with self.assertRaises(EC.ECError):
+ ec.verify_dsa_asn1(blob, self.data)
def test_verify_dsa(self):
ec = EC.load_key(self.privkey)
@@ -58,18 +69,28 @@ class ECDSATestCase(unittest.TestCase):
ec2 = EC.load_pub_key(self.pubkey)
assert ec2.verify_dsa(self.data, r, s)
assert not ec2.verify_dsa(self.data, s, r)
-
+
def test_genparam(self):
- ec = EC.gen_params(EC.NID_sect233k1)
- assert len(ec) == 233
+ ec = EC.gen_params(tested_curve[0])
+ self.assertEqual(len(ec), tested_curve[1])
+
+ def test_pub_key_from_params(self):
+ curve = EC.NID_prime256v1
+ ec = EC.gen_params(curve)
+ ec.gen_key()
+ ec_pub = ec.pub()
+ k = ec_pub.get_key()
+ ec2 = EC.pub_key_from_params(curve, k)
+ assert ec2.check_key()
+ r, s = ec.sign_dsa(self.data)
+ assert ec2.verify_dsa(self.data, r, s)
def suite():
return unittest.makeSuite(ECDSATestCase)
-
+
if __name__ == '__main__':
- Rand.load_file('randpool.dat', -1)
+ Rand.load_file('randpool.dat', -1)
unittest.TextTestRunner().run(suite())
Rand.save_file('randpool.dat')
-
diff --git a/tests/test_engine.py b/tests/test_engine.py
index 91c2aa8..5439ee3 100644
--- a/tests/test_engine.py
+++ b/tests/test_engine.py
@@ -2,8 +2,9 @@
"""Unit tests for M2Crypto.Engine."""
-import unittest
-from M2Crypto import Engine, m2
+from M2Crypto import Engine
+from tests import unittest
+
class EngineTestCase(unittest.TestCase):
@@ -14,19 +15,26 @@ class EngineTestCase(unittest.TestCase):
Engine.cleanup()
def test_by_id_junk(self):
- self.assertRaises(ValueError, Engine.Engine, self.bad_id)
- self.assertRaises(ValueError, Engine.Engine)
+ with self.assertRaises(ValueError):
+ Engine.Engine(self.bad_id)
+ with self.assertRaises(ValueError):
+ Engine.Engine()
def test_by_id_openssl(self):
Engine.load_openssl()
e = Engine.Engine('openssl')
self.assertEqual(e.get_name(), 'Software engine support')
self.assertEqual(e.get_id(), 'openssl')
-
+
def test_by_id_dynamic(self):
Engine.load_dynamic()
Engine.Engine('dynamic')
-
+
+ def test_engine_ctrl_cmd_string(self):
+ Engine.load_dynamic()
+ e = Engine.Engine('dynamic')
+ e.ctrl_cmd_string('ID', 'TESTID')
+
def test_load_private(self):
Engine.load_openssl()
e = Engine.Engine('openssl')
@@ -37,12 +45,16 @@ class EngineTestCase(unittest.TestCase):
Engine.load_openssl()
e = Engine.Engine('openssl')
e.set_default()
- self.assertRaises(Engine.EngineError, e.load_certificate, '/dev/null')
+ try:
+ with self.assertRaises(Engine.EngineError):
+ e.load_certificate('/dev/null')
+ except SystemError:
+ pass
+
def suite():
return unittest.makeSuite(EngineTestCase)
-
+
if __name__ == '__main__':
unittest.TextTestRunner().run(suite())
-
diff --git a/tests/test_err.py b/tests/test_err.py
new file mode 100644
index 0000000..05fe425
--- /dev/null
+++ b/tests/test_err.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""Unit tests for M2Crypto.Err.
+
+Copyright (C) 2019 Matěj Cepl
+Released under the terms of MIT/X11 License,
+see the file LICENCE for more.
+"""
+from M2Crypto import Err
+from tests import unittest
+
+
+class ErrTestCase(unittest.TestCase):
+
+ def test_no_error(self):
+ # Protection against gl#m2crypto/m2crypto#258
+ self.assertEqual(Err.get_error_reason(0), '')
+
+
+
+def suite():
+ suite = unittest.TestSuite()
+ suite.addTest(unittest.makeSuite(ErrTestCase))
+ return suite
+
+
+if __name__ == '__main__':
+ unittest.TextTestRunner().run(suite())
diff --git a/tests/test_evp.py b/tests/test_evp.py
index ba09092..d133ed0 100644
--- a/tests/test_evp.py
+++ b/tests/test_evp.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+from __future__ import absolute_import, division
"""
Unit tests for M2Crypto.EVP.
@@ -7,183 +7,296 @@ Copyright (c) 2004-2007 Open Source Applications Foundation
Author: Heikki Toivonen
"""
-import unittest
-import cStringIO, sha
-from binascii import hexlify, unhexlify
-from M2Crypto import EVP, RSA, util, Rand, m2, BIO
-from M2Crypto.util import h2b
+import base64
+import hashlib
+import io
+import logging
+
+from binascii import a2b_hex, hexlify, unhexlify
+
+from M2Crypto import BIO, EVP, RSA, Rand, m2, util
+from tests import unittest
+from tests.fips import fips_mode
+
+log = logging.getLogger('test_EVP')
-from fips import fips_mode
class EVPTestCase(unittest.TestCase):
def _gen_callback(self, *args):
pass
-
+
def _pass_callback(self, *args):
- return 'foobar'
-
+ return b'foobar'
+
def _assign_rsa(self):
rsa = RSA.gen_key(1024, 3, callback=self._gen_callback)
pkey = EVP.PKey()
- pkey.assign_rsa(rsa, capture=0) # capture=1 should cause crash
+ pkey.assign_rsa(rsa, capture=0) # capture=1 should cause crash
return rsa
-
+
def test_assign(self):
rsa = self._assign_rsa()
rsa.check_key()
-
+
def test_pem(self):
rsa = RSA.gen_key(1024, 3, callback=self._gen_callback)
pkey = EVP.PKey()
pkey.assign_rsa(rsa)
- assert pkey.as_pem(callback=self._pass_callback) != pkey.as_pem(cipher=None)
- self.assertRaises(ValueError, pkey.as_pem, cipher='noXX$$%%suchcipher',
- callback=self._pass_callback)
-
+
+ result_w_callback = pkey.as_pem(callback=self._pass_callback)
+ result_wo_callback = pkey.as_pem(cipher=None)
+ self.assertNotEqual(result_w_callback, result_wo_callback)
+
+ with self.assertRaises(ValueError):
+ pkey.as_pem(cipher='noXX$$%%suchcipher',
+ callback=self._pass_callback)
+
def test_as_der(self):
"""
- Test DER encoding the PKey instance after assigning
+ Test DER encoding the PKey instance after assigning
a RSA key to it.
"""
rsa = RSA.gen_key(1024, 3, callback=self._gen_callback)
pkey = EVP.PKey()
pkey.assign_rsa(rsa)
- der_blob = pkey.as_der()
- #A quick but not thorough sanity check
- assert len(der_blob) == 160
-
-
- def test_MessageDigest(self):
- self.assertRaises(ValueError, EVP.MessageDigest, 'sha513')
+ der_blob = pkey.as_der()
+ # A quick but not thorough sanity check
+ self.assertEqual(len(der_blob), 160)
+
+ def test_get_digestbyname(self):
+ with self.assertRaises(EVP.EVPError):
+ m2.get_digestbyname('sha513')
+ self.assertNotEqual(m2.get_digestbyname('sha1'), None)
+
+ def test_MessageDigest(self): # noqa
+ with self.assertRaises(ValueError):
+ EVP.MessageDigest('sha513')
+ md = EVP.MessageDigest('sha1')
+ self.assertEqual(md.update(b'Hello'), 1)
+ self.assertEqual(util.octx_to_num(md.final()),
+ 1415821221623963719413415453263690387336440359920)
+
+ # temporarily remove sha1 from m2
+ old_sha1 = m2.sha1
+ del m2.sha1
+
+ # now run the same test again, relying on EVP.MessageDigest() to call
+ # get_digestbyname() under the hood
md = EVP.MessageDigest('sha1')
- assert md.update('Hello') == 1
- assert util.octx_to_num(md.final()) == 1415821221623963719413415453263690387336440359920
+ self.assertEqual(md.update(b'Hello'), 1)
+ self.assertEqual(util.octx_to_num(md.final()),
+ 1415821221623963719413415453263690387336440359920)
+
+ # put sha1 back in place
+ m2.sha1 = old_sha1
def test_as_der_capture_key(self):
"""
- Test DER encoding the PKey instance after assigning
+ Test DER encoding the PKey instance after assigning
a RSA key to it. Have the PKey instance capture the RSA key.
"""
rsa = RSA.gen_key(1024, 3, callback=self._gen_callback)
pkey = EVP.PKey()
pkey.assign_rsa(rsa, 1)
der_blob = pkey.as_der()
- #A quick but not thorough sanity check
- assert len(der_blob) == 160
+ # A quick but not thorough sanity check
+ self.assertEqual(len(der_blob), 160)
def test_size(self):
rsa = RSA.gen_key(1024, 3, callback=self._gen_callback)
pkey = EVP.PKey()
pkey.assign_rsa(rsa)
- size = pkey.size()
- assert size == 128
-
+ size = pkey.size()
+ self.assertEqual(size, 128)
+
def test_hmac(self):
- assert util.octx_to_num(EVP.hmac('key', 'data')) == 92800611269186718152770431077867383126636491933, util.octx_to_num(EVP.hmac('key', 'data'))
- if not fips_mode: # Disabled algorithms
- assert util.octx_to_num(EVP.hmac('key', 'data', algo='md5')) == 209168838103121722341657216703105225176, util.octx_to_num(EVP.hmac('key', 'data', algo='md5'))
- assert util.octx_to_num(EVP.hmac('key', 'data', algo='ripemd160')) == 1176807136224664126629105846386432860355826868536, util.octx_to_num(EVP.hmac('key', 'data', algo='ripemd160'))
-
- if m2.OPENSSL_VERSION_NUMBER >= 0x90800F:
- assert util.octx_to_num(EVP.hmac('key', 'data', algo='sha224')) == 2660082265842109788381286338540662430962855478412025487066970872635, util.octx_to_num(EVP.hmac('key', 'data', algo='sha224'))
- assert util.octx_to_num(EVP.hmac('key', 'data', algo='sha256')) == 36273358097036101702192658888336808701031275731906771612800928188662823394256, util.octx_to_num(EVP.hmac('key', 'data', algo='sha256'))
- assert util.octx_to_num(EVP.hmac('key', 'data', algo='sha384')) == 30471069101236165765942696708481556386452105164815350204559050657318908408184002707969468421951222432574647369766282, util.octx_to_num(EVP.hmac('key', 'data', algo='sha384'))
- assert util.octx_to_num(EVP.hmac('key', 'data', algo='sha512')) == 3160730054100700080556942280820129108466291087966635156623014063982211353635774277148932854680195471287740489442390820077884317620321797003323909388868696, util.octx_to_num(EVP.hmac('key', 'data', algo='sha512'))
-
- self.assertRaises(ValueError, EVP.hmac, 'key', 'data', algo='sha513')
+ self.assertEqual(util.octx_to_num(EVP.hmac(b'key', b'data')),
+ 92800611269186718152770431077867383126636491933,
+ util.octx_to_num(EVP.hmac(b'key', b'data')))
+ if not fips_mode: # Disabled algorithms
+ self.assertEqual(util.octx_to_num(EVP.hmac(b'key', b'data',
+ algo='md5')),
+ 209168838103121722341657216703105225176,
+ util.octx_to_num(EVP.hmac(b'key', b'data',
+ algo='md5')))
+ self.assertEqual(util.octx_to_num(EVP.hmac(b'key', b'data',
+ algo='ripemd160')),
+ 1176807136224664126629105846386432860355826868536,
+ util.octx_to_num(EVP.hmac(b'key', b'data',
+ algo='ripemd160')))
+ if m2.OPENSSL_VERSION_NUMBER >= 0x90800F:
+ self.assertEqual(util.octx_to_num(EVP.hmac(b'key', b'data',
+ algo='sha224')),
+ 2660082265842109788381286338540662430962855478412025487066970872635,
+ util.octx_to_num(EVP.hmac(b'key', b'data',
+ algo='sha224')))
+ self.assertEqual(util.octx_to_num(EVP.hmac(b'key', b'data',
+ algo='sha256')),
+ 36273358097036101702192658888336808701031275731906771612800928188662823394256,
+ util.octx_to_num(EVP.hmac(b'key', b'data',
+ algo='sha256')))
+ self.assertEqual(util.octx_to_num(EVP.hmac(b'key', b'data',
+ algo='sha384')),
+ 30471069101236165765942696708481556386452105164815350204559050657318908408184002707969468421951222432574647369766282,
+ util.octx_to_num(EVP.hmac(b'key', b'data',
+ algo='sha384')))
+ self.assertEqual(util.octx_to_num(EVP.hmac(b'key', b'data',
+ algo='sha512')),
+ 3160730054100700080556942280820129108466291087966635156623014063982211353635774277148932854680195471287740489442390820077884317620321797003323909388868696,
+ util.octx_to_num(EVP.hmac(b'key', b'data',
+ algo='sha512')))
+
+ with self.assertRaises(ValueError):
+ EVP.hmac(b'key', b'data', algo='sha513')
def test_get_rsa(self):
"""
Testing retrieving the RSA key from the PKey instance.
"""
- rsa = RSA.gen_key(512, 3, callback=self._gen_callback)
- assert isinstance(rsa, RSA.RSA)
+ rsa = RSA.gen_key(1024, 3, callback=self._gen_callback)
+ self.assertIsInstance(rsa, RSA.RSA)
pkey = EVP.PKey()
- pkey.assign_rsa(rsa)
+ pkey.assign_rsa(rsa)
rsa2 = pkey.get_rsa()
- assert isinstance(rsa2, RSA.RSA_pub)
- assert rsa.e == rsa2.e
- assert rsa.n == rsa2.n
+ self.assertIsInstance(rsa2, RSA.RSA_pub)
+ self.assertEqual(rsa.e, rsa2.e)
+ self.assertEqual(rsa.n, rsa2.n)
+ # FIXME
+ # hanging call is
+ # m2.rsa_write_key(self.rsa, bio._ptr(), ciph, callback)s
+ # from RSA.py/save_key_bio
+
pem = rsa.as_pem(callback=self._pass_callback)
pem2 = rsa2.as_pem()
assert pem
assert pem2
- assert pem != pem2
-
- message = "This is the message string"
- digest = sha.sha(message).digest()
- assert rsa.sign(digest) == rsa2.sign(digest)
-
+ self.assertNotEqual(pem, pem2)
+
+ message = b'This is the message string'
+ digest = hashlib.sha1(message).digest()
+ self.assertEqual(rsa.sign(digest), rsa2.sign(digest))
+
rsa3 = RSA.gen_key(1024, 3, callback=self._gen_callback)
- assert rsa.sign(digest) != rsa3.sign(digest)
-
+ self.assertNotEqual(rsa.sign(digest), rsa3.sign(digest))
+
+ def test_load_key_string_pubkey(self):
+ """
+ Testing creating a PKey instance from PEM string.
+ """
+ rsa = RSA.gen_key(1024, 3, callback=self._gen_callback)
+ self.assertIsInstance(rsa, RSA.RSA)
+
+ rsa_pem = BIO.MemoryBuffer()
+ rsa.save_pub_key_bio(rsa_pem)
+ pkey = EVP.load_key_string_pubkey(rsa_pem.read())
+ rsa2 = pkey.get_rsa()
+ self.assertIsInstance(rsa2, RSA.RSA_pub)
+ self.assertEqual(rsa.e, rsa2.e)
+ self.assertEqual(rsa.n, rsa2.n)
+ pem = rsa.as_pem(callback=self._pass_callback)
+ pem2 = rsa2.as_pem()
+ assert pem
+ assert pem2
+ self.assertNotEqual(pem, pem2)
+
def test_get_rsa_fail(self):
"""
Testing trying to retrieve the RSA key from the PKey instance
when it is not holding a RSA Key. Should raise a ValueError.
"""
pkey = EVP.PKey()
- self.assertRaises(ValueError, pkey.get_rsa)
+ with self.assertRaises(ValueError):
+ pkey.get_rsa()
def test_get_modulus(self):
pkey = EVP.PKey()
- self.assertRaises(ValueError, pkey.get_modulus)
+ with self.assertRaises(ValueError):
+ pkey.get_modulus()
- rsa = RSA.gen_key(512, 3, callback=self._gen_callback)
+ rsa = RSA.gen_key(1024, 3, callback=self._gen_callback)
pkey.assign_rsa(rsa)
mod = pkey.get_modulus()
- assert len(mod) > 0, mod
- assert len(mod.strip('0123456789ABCDEF')) == 0
-
+ self.assertGreater(len(mod), 0, mod)
+ self.assertEqual(len(mod.strip(b'0123456789ABCDEF')), 0)
+
def test_verify_final(self):
from M2Crypto import X509
pkey = EVP.load_key('tests/signer_key.pem')
pkey.sign_init()
- pkey.sign_update('test message')
+ pkey.sign_update(b'test message')
sig = pkey.sign_final()
-
+
# OK
x509 = X509.load_cert('tests/signer.pem')
pubkey = x509.get_pubkey()
pubkey.verify_init()
- pubkey.verify_update('test message')
- assert pubkey.verify_final(sig) == 1
-
+ pubkey.verify_update(b'test message')
+ self.assertEqual(pubkey.verify_final(sig), 1)
+
# wrong cert
x509 = X509.load_cert('tests/x509.pem')
pubkey = x509.get_pubkey()
pubkey.verify_init()
- pubkey.verify_update('test message')
- assert pubkey.verify_final(sig) == 0
-
+ pubkey.verify_update(b'test message')
+ self.assertEqual(pubkey.verify_final(sig), 0)
+
# wrong message
x509 = X509.load_cert('tests/signer.pem')
pubkey = x509.get_pubkey()
pubkey.verify_init()
- pubkey.verify_update('test message not')
- assert pubkey.verify_final(sig) == 0
+ pubkey.verify_update(b'test message not')
+ self.assertEqual(pubkey.verify_final(sig), 0)
def test_load_bad(self):
- self.assertRaises(BIO.BIOError, EVP.load_key,
- 'thisdoesnotexist-dfgh56789')
- self.assertRaises(EVP.EVPError, EVP.load_key,
- 'tests/signer.pem') # not a key
- self.assertRaises(EVP.EVPError, EVP.load_key_bio,
- BIO.MemoryBuffer('no a key'))
+ with self.assertRaises(BIO.BIOError):
+ EVP.load_key('thisdoesnotexist-dfgh56789')
+ with self.assertRaises(EVP.EVPError):
+ EVP.load_key('tests/signer.pem') # not a key
+ with self.assertRaises(EVP.EVPError):
+ EVP.load_key_bio(BIO.MemoryBuffer(b'no a key'))
def test_pad(self):
self.assertEqual(util.pkcs5_pad('Hello World'),
'Hello World\x05\x05\x05\x05\x05')
self.assertEqual(util.pkcs7_pad('Hello World', 15),
'Hello World\x04\x04\x04\x04')
- self.assertRaises(ValueError, util.pkcs7_pad, 'Hello', 256)
-
+ with self.assertRaises(ValueError):
+ util.pkcs7_pad('Hello', 256)
+
+ def test_pkey_verify_crash(self):
+ SIGN_PRIVATE = EVP.load_key('tests/rsa.priv.pem')
+ SIGN_PUBLIC = RSA.load_pub_key('tests/rsa.pub.pem')
+
+ def sign(data):
+ SIGN_PRIVATE.sign_init()
+ SIGN_PRIVATE.sign_update(data)
+ signed_data = SIGN_PRIVATE.sign_final()
+ return base64.b64encode(signed_data)
+
+ def verify(response):
+ signature = base64.b64decode(response['sign'])
+ data = response['data']
+ verify_evp = EVP.PKey()
+ # capture parameter on the following line is required by
+ # the documentation
+ verify_evp.assign_rsa(SIGN_PUBLIC, capture=False)
+ verify_evp.verify_init()
+ verify_evp.verify_update(data)
+ # m2.verify_final(self.ctx, sign, self.pkey)
+ fin_res = verify_evp.verify_final(signature)
+ return fin_res == 1
+
+ data = b"test message"
+ signature = sign(data)
+ res = {"data": data, "sign": signature}
+ self.assertTrue(verify(res)) # works fine
+ self.assertTrue(verify(res)) # segmentation fault in *verify_final*
class CipherTestCase(unittest.TestCase):
def cipher_filter(self, cipher, inf, outf):
while 1:
- buf=inf.read()
+ buf = inf.read()
if not buf:
break
outf.write(cipher.update(buf))
@@ -193,110 +306,120 @@ class CipherTestCase(unittest.TestCase):
def try_algo(self, algo):
enc = 1
dec = 0
- otxt='against stupidity the gods themselves contend in vain'
-
- k=EVP.Cipher(algo, 'goethe','12345678', enc, 1, 'sha1', 'saltsalt', 5)
- pbuf=cStringIO.StringIO(otxt)
- cbuf=cStringIO.StringIO()
- ctxt=self.cipher_filter(k, pbuf, cbuf)
+ otxt = b'against stupidity the gods themselves contend in vain'
+
+ k = EVP.Cipher(algo, b'goethe', b'12345678', enc,
+ 1, 'sha1', b'saltsalt', 5)
+ pbuf = io.BytesIO(otxt)
+ cbuf = io.BytesIO()
+ ctxt = self.cipher_filter(k, pbuf, cbuf)
pbuf.close()
cbuf.close()
-
- j=EVP.Cipher(algo, 'goethe','12345678', dec, 1, 'sha1', 'saltsalt', 5)
- pbuf=cStringIO.StringIO()
- cbuf=cStringIO.StringIO(ctxt)
- ptxt=self.cipher_filter(j, cbuf, pbuf)
+
+ j = EVP.Cipher(algo, b'goethe', b'12345678', dec,
+ 1, 'sha1', b'saltsalt', 5)
+ pbuf = io.BytesIO()
+ cbuf = io.BytesIO(ctxt)
+ ptxt = self.cipher_filter(j, cbuf, pbuf)
pbuf.close()
cbuf.close()
-
- assert otxt == ptxt, '%s algorithm cipher test failed' % algo
-
+
+ self.assertEqual(otxt, ptxt, '%s algorithm cipher test failed' % algo)
+
def test_ciphers(self):
- ciphers=[
+ ciphers = [
'des_ede_ecb', 'des_ede_cbc', 'des_ede_cfb', 'des_ede_ofb',
'des_ede3_ecb', 'des_ede3_cbc', 'des_ede3_cfb', 'des_ede3_ofb',
'aes_128_ecb', 'aes_128_cbc', 'aes_128_cfb', 'aes_128_ofb',
- 'aes_192_ecb', 'aes_192_cbc', 'aes_192_cfb', 'aes_192_ofb',
- 'aes_256_ecb', 'aes_256_cbc', 'aes_256_cfb', 'aes_256_ofb']
- nonfips_ciphers=['bf_ecb', 'bf_cbc', 'bf_cfb', 'bf_ofb',
- #'idea_ecb', 'idea_cbc', 'idea_cfb', 'idea_ofb',
- 'cast5_ecb', 'cast5_cbc', 'cast5_cfb', 'cast5_ofb',
- #'rc5_ecb', 'rc5_cbc', 'rc5_cfb', 'rc5_ofb',
- 'des_ecb', 'des_cbc', 'des_cfb', 'des_ofb',
- 'rc4', 'rc2_40_cbc']
- if not fips_mode: # Disabled algorithms
+ 'aes_128_ctr', 'aes_192_ecb', 'aes_192_cbc', 'aes_192_cfb',
+ 'aes_192_ofb', 'aes_192_ctr', 'aes_256_ecb', 'aes_256_cbc',
+ 'aes_256_cfb', 'aes_256_ofb', 'aes_256_ctr']
+ nonfips_ciphers = ['bf_ecb', 'bf_cbc', 'bf_cfb', 'bf_ofb',
+ # 'idea_ecb', 'idea_cbc', 'idea_cfb', 'idea_ofb',
+ 'cast5_ecb', 'cast5_cbc', 'cast5_cfb', 'cast5_ofb',
+ # 'rc5_ecb', 'rc5_cbc', 'rc5_cfb', 'rc5_ofb',
+ 'des_ecb', 'des_cbc', 'des_cfb', 'des_ofb',
+ 'rc4', 'rc2_40_cbc']
+ if not fips_mode: # Disabled algorithms
ciphers += nonfips_ciphers
for i in ciphers:
self.try_algo(i)
# idea might not be compiled in
- ciphers=['idea_ecb', 'idea_cbc', 'idea_cfb', 'idea_ofb']
+ ciphers = ['idea_ecb', 'idea_cbc', 'idea_cfb', 'idea_ofb']
try:
for i in ciphers:
self.try_algo(i)
- except ValueError, e:
+ except ValueError as e:
if str(e) != "('unknown cipher', 'idea_ecb')":
- raise
+ raise
# rc5 might not be compiled in
- ciphers=['rc5_ecb', 'rc5_cbc', 'rc5_cfb', 'rc5_ofb']
+ ciphers = ['rc5_ecb', 'rc5_cbc', 'rc5_cfb', 'rc5_ofb']
try:
for i in ciphers:
self.try_algo(i)
- except ValueError, e:
+ except ValueError as e:
if str(e) != "('unknown cipher', 'rc5_ecb')":
- raise
+ raise
+
+ with self.assertRaises(ValueError):
+ self.try_algo('nosuchalgo4567')
- self.assertRaises(ValueError, self.try_algo, 'nosuchalgo4567')
-
- def test_AES(self):
+ def test_AES(self): # noqa
enc = 1
dec = 0
tests = [
# test vectors from rfc 3602
- #Case #1: Encrypting 16 bytes (1 block) using AES-CBC with 128-bit key
+ # Case #1: Encrypting 16 bytes (1 block) using AES-CBC with
+ # 128-bit key
{
- 'KEY': '06a9214036b8a15b512e03d534120006',
- 'IV': '3dafba429d9eb430b422da802c9fac41',
- 'PT': 'Single block msg',
- 'CT': 'e353779c1079aeb82708942dbe77181a',
+ 'KEY': '06a9214036b8a15b512e03d534120006',
+ 'IV': '3dafba429d9eb430b422da802c9fac41',
+ 'PT': b'Single block msg',
+ 'CT': b'e353779c1079aeb82708942dbe77181a',
},
-
- #Case #2: Encrypting 32 bytes (2 blocks) using AES-CBC with 128-bit key
+
+ # Case #2: Encrypting 32 bytes (2 blocks) using AES-CBC with
+ # 128-bit key
{
- 'KEY': 'c286696d887c9aa0611bbb3e2025a45a',
- 'IV': '562e17996d093d28ddb3ba695a2e6f58',
- 'PT': unhexlify('000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f'),
- 'CT': 'd296cd94c2cccf8a3a863028b5e1dc0a7586602d253cfff91b8266bea6d61ab1',
+ 'KEY': 'c286696d887c9aa0611bbb3e2025a45a',
+ 'IV': '562e17996d093d28ddb3ba695a2e6f58',
+ 'PT': unhexlify(b'000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f'),
+ 'CT': b'd296cd94c2cccf8a3a863028b5e1dc0a7586602d253cfff91b8266bea6d61ab1',
},
-
- #Case #3: Encrypting 48 bytes (3 blocks) using AES-CBC with 128-bit key
+
+ # Case #3: Encrypting 48 bytes (3 blocks) using AES-CBC with
+ # 128-bit key
{
- 'KEY': '6c3ea0477630ce21a2ce334aa746c2cd',
- 'IV': 'c782dc4c098c66cbd9cd27d825682c81',
- 'PT': 'This is a 48-byte message (exactly 3 AES blocks)',
- 'CT': 'd0a02b3836451753d493665d33f0e8862dea54cdb293abc7506939276772f8d5021c19216bad525c8579695d83ba2684',
+ 'KEY': '6c3ea0477630ce21a2ce334aa746c2cd',
+ 'IV': 'c782dc4c098c66cbd9cd27d825682c81',
+ 'PT': b'This is a 48-byte message (exactly 3 AES blocks)',
+ 'CT': b'd0a02b3836451753d493665d33f0e8862dea54cdb293abc7506939276772f8d5021c19216bad525c8579695d83ba2684',
},
]
-
+
# Test with padding
for test in tests:
# encrypt
- k=EVP.Cipher(alg='aes_128_cbc', key=unhexlify(test['KEY']), iv=unhexlify(test['IV']), op=enc)
- pbuf=cStringIO.StringIO(test['PT'])
- cbuf=cStringIO.StringIO()
+ k = EVP.Cipher(alg='aes_128_cbc', key=unhexlify(test['KEY']),
+ iv=unhexlify(test['IV']), op=enc)
+ pbuf = io.BytesIO(test['PT'])
+ cbuf = io.BytesIO()
ciphertext = hexlify(self.cipher_filter(k, pbuf, cbuf))
cipherpadding = ciphertext[len(test['PT']) * 2:]
- ciphertext = ciphertext[:len(test['PT']) * 2] # Remove the padding from the end
+ # Remove the padding from the end
+ ciphertext = ciphertext[:len(test['PT']) * 2]
pbuf.close()
cbuf.close()
self.assertEqual(ciphertext, test['CT'])
# decrypt
- j=EVP.Cipher(alg='aes_128_cbc', key=unhexlify(test['KEY']), iv=unhexlify(test['IV']), op=dec)
- pbuf=cStringIO.StringIO()
- cbuf=cStringIO.StringIO(unhexlify(test['CT'] + cipherpadding))
- plaintext=self.cipher_filter(j, cbuf, pbuf)
+ j = EVP.Cipher(alg='aes_128_cbc', key=unhexlify(test['KEY']),
+ iv=unhexlify(test['IV']), op=dec)
+ pbuf = io.BytesIO()
+ cbuf = io.BytesIO(unhexlify(test['CT'] + cipherpadding))
+ plaintext = self.cipher_filter(j, cbuf, pbuf)
pbuf.close()
cbuf.close()
self.assertEqual(plaintext, test['PT'])
@@ -304,26 +427,67 @@ class CipherTestCase(unittest.TestCase):
# Test without padding
for test in tests:
# encrypt
- k=EVP.Cipher(alg='aes_128_cbc', key=unhexlify(test['KEY']), iv=unhexlify(test['IV']), op=enc, padding=False)
- pbuf=cStringIO.StringIO(test['PT'])
- cbuf=cStringIO.StringIO()
+ k = EVP.Cipher(alg='aes_128_cbc', key=unhexlify(test['KEY']),
+ iv=unhexlify(test['IV']), op=enc, padding=False)
+ pbuf = io.BytesIO(test['PT'])
+ cbuf = io.BytesIO()
ciphertext = hexlify(self.cipher_filter(k, pbuf, cbuf))
pbuf.close()
cbuf.close()
self.assertEqual(ciphertext, test['CT'])
# decrypt
- j=EVP.Cipher(alg='aes_128_cbc', key=unhexlify(test['KEY']), iv=unhexlify(test['IV']), op=dec, padding=False)
- pbuf=cStringIO.StringIO()
- cbuf=cStringIO.StringIO(unhexlify(test['CT']))
- plaintext=self.cipher_filter(j, cbuf, pbuf)
+ j = EVP.Cipher(alg='aes_128_cbc', key=unhexlify(test['KEY']),
+ iv=unhexlify(test['IV']), op=dec, padding=False)
+ pbuf = io.BytesIO()
+ cbuf = io.BytesIO(unhexlify(test['CT']))
+ plaintext = self.cipher_filter(j, cbuf, pbuf)
pbuf.close()
cbuf.close()
self.assertEqual(plaintext, test['PT'])
+ def test_AES_ctr(self): # noqa
+ # In CTR mode, encrypt and decrypt are actually the same
+ # operation because you encrypt the nonce value, then use the
+ # output of that to XOR the plaintext. So we set operation=0,
+ # even though this setting is ignored by OpenSSL.
+ op = 0
+
+ nonce = unhexlify('4a45a048a1e9f7c1bd17f2908222b964') # CTR nonce value, 16 bytes
+ key = unhexlify('8410ad66fe53a09addc0d041ae00bc6d70e8038ec17019f27e52eecd3846757e')
+ plaintext_value = b'This is three blocks of text with unicode char \x03'
+
+ ciphertext_values = {
+ '128': unhexlify('6098fb2e49b3f7ed34f841f43f825d84cf4834021511594b931c85f04662544bdb4f38232e9d87fda6280ab1ef450e27'), # noqa
+ '192': unhexlify('2299b1c5363824cb92b5851dedc73f49f30b23fb23f288492e840c951ce703292a5c6de6fc7f0625c403648f8ca4a582'), # noqa
+ '256': unhexlify('713e34bcd2c59affc9185a716c3c6aef5c9bf7b9914337dd96e9d7436344bcb9c35175afb54adb78aab322829ce9cb4a'), # noqa
+ }
+
+ for key_size in [128, 192, 256]:
+ alg = 'aes_%s_ctr' % str(key_size)
+
+ # Our key for this test is 256 bits in length (32 bytes).
+ # We will trim it to the appopriate length for testing AES-128
+ # and AES-192 as well (so 16 and 24 bytes, respectively).
+ key_truncated = key[0:(key_size // 8)]
+
+ # Test encrypt operations
+ cipher = EVP.Cipher(alg=alg, key=key_truncated, iv=nonce, op=op)
+ ciphertext = cipher.update(plaintext_value)
+ ciphertext = ciphertext + cipher.final()
+ self.assertEqual(ciphertext, ciphertext_values[str(key_size)])
+
+ # Test decrypt operations
+ cipher = EVP.Cipher(alg=alg, key=key_truncated, iv=nonce, op=op)
+ plaintext = cipher.update(ciphertext_values[str(key_size)])
+ plaintext = plaintext + cipher.final()
+ # XXX not quite sure this is the actual intention
+ # but for now let's be happy to find the same content even if with
+ # a different type - XXX
+ self.assertEqual(plaintext, plaintext_value)
def test_raises(self):
- def _cipherFilter(cipher, inf, outf):
+ def _cipherFilter(cipher, inf, outf): # noqa
while 1:
buf = inf.read()
if not buf:
@@ -334,126 +498,127 @@ class CipherTestCase(unittest.TestCase):
def decrypt(ciphertext, key, iv, alg='aes_256_cbc'):
cipher = EVP.Cipher(alg=alg, key=key, iv=iv, op=0)
- pbuf = cStringIO.StringIO()
- cbuf = cStringIO.StringIO(ciphertext)
+ pbuf = io.BytesIO()
+ cbuf = io.BytesIO(ciphertext)
plaintext = _cipherFilter(cipher, cbuf, pbuf)
pbuf.close()
cbuf.close()
return plaintext
-
- self.assertRaises(EVP.EVPError, decrypt,
- unhexlify('941d3647a642fab26d9f99a195098b91252c652d07235b9db35758c401627711724637648e45cad0f1121751a1240a4134998cfdf3c4a95c72de2a2444de3f9e40d881d7f205630b0d8ce142fdaebd8d7fbab2aea3dc47f5f29a0e9b55aae59222671d8e2877e1fb5cd8ef1c427027e0'),
- unhexlify('5f2cc54067f779f74d3cf1f78c735aec404c8c3a4aaaa02eb1946f595ea4cddb'),
- unhexlify('0001efa4bd154ee415b9413a421cedf04359fff945a30e7c115465b1c780a85b65c0e45c'))
- self.assertRaises(EVP.EVPError, decrypt,
- unhexlify('a78a510416c1a6f1b48077cc9eeb4287dcf8c5d3179ef80136c18876d774570d'),
- unhexlify('5cd148eeaf680d4ff933aed83009cad4110162f53ef89fd44fad09611b0524d4'),
- unhexlify(''))
+ with self.assertRaises(EVP.EVPError):
+ decrypt(
+ unhexlify('941d3647a642fab26d9f99a195098b91252c652d07235b9db35758c401627711724637648e45cad0f1121751a1240a4134998cfdf3c4a95c72de2a2444de3f9e40d881d7f205630b0d8ce142fdaebd8d7fbab2aea3dc47f5f29a0e9b55aae59222671d8e2877e1fb5cd8ef1c427027e0'),
+ unhexlify('5f2cc54067f779f74d3cf1f78c735aec404c8c3a4aaaa02eb1946f595ea4cddb'),
+ unhexlify('0001efa4bd154ee415b9413a421cedf04359fff945a30e7c115465b1c780a85b65c0e45c'))
+
+ with self.assertRaises(EVP.EVPError):
+ decrypt(
+ unhexlify('a78a510416c1a6f1b48077cc9eeb4287dcf8c5d3179ef80136c18876d774570d'),
+ unhexlify('5cd148eeaf680d4ff933aed83009cad4110162f53ef89fd44fad09611b0524d4'),
+ unhexlify(''))
class PBKDF2TestCase(unittest.TestCase):
def test_rfc3211_test_vectors(self):
- from binascii import hexlify, unhexlify
-
- password = 'password'
- salt = unhexlify('12 34 56 78 78 56 34 12'.replace(' ', ''))
+
+ password = b'password'
+ salt = unhexlify('1234567878563412')
iter = 5
keylen = 8
ret = EVP.pbkdf2(password, salt, iter, keylen)
- self.assertEqual(hexlify(ret), 'D1 DA A7 86 15 F2 87 E6'.replace(' ', '').lower())
-
- password = 'All n-entities must communicate with other n-entities via n-1 entiteeheehees'
- salt = unhexlify('12 34 56 78 78 56 34 12'.replace(' ', ''))
+ self.assertEqual(ret, unhexlify(b'd1daa78615f287e6'))
+
+ password = b'All n-entities must communicate with other n-entities' + \
+ b' via n-1 entiteeheehees'
+ salt = unhexlify('1234567878563412')
iter = 500
keylen = 16
ret = EVP.pbkdf2(password, salt, iter, keylen)
- self.assertEqual(hexlify(ret), '6A 89 70 BF 68 C9 2C AE A8 4A 8D F2 85 10 85 86'.replace(' ', '').lower())
-
+ self.assertEqual(ret, unhexlify(b'6a8970bf68c92caea84a8df285108586'))
+
class HMACTestCase(unittest.TestCase):
- data1=['', 'More text test vectors to stuff up EBCDIC machines :-)', \
- h2b("e9139d1e6ee064ef8cf514fc7dc83e86")]
+ data1 = [b'', b'More text test vectors to stuff up EBCDIC machines :-)',
+ a2b_hex("b760e92d6662d351eb3801057695ac0346295356")]
- data2=[h2b('0b'*16), "Hi There", \
- h2b("9294727a3638bb1c13f48ef8158bfc9d")]
+ data2 = [a2b_hex(b'0b' * 16), b"Hi There",
+ a2b_hex("675b0b3a1b4ddf4e124872da6c2f632bfed957e9")]
- data3=['Jefe', "what do ya want for nothing?", \
- h2b("750c783e6ab0b503eaa86e310a5db738")]
+ data3 = [b'Jefe', b"what do ya want for nothing?",
+ a2b_hex("effcdf6ae5eb2fa2d27416d5f184df9c259a7c79")]
- data4=[h2b('aa'*16), h2b('dd'*50), \
- h2b("0x56be34521d144c88dbb8c733f0e8b3f6")]
+ data4 = [a2b_hex(b'aa' * 16), a2b_hex(b'dd' * 50),
+ a2b_hex("d730594d167e35d5956fd8003d0db3d3f46dc7bb")]
- data=[data1, data2, data3, data4]
+ data = [data1, data2, data3, data4]
def test_simple(self):
- algo = 'md5'
+ algo = 'sha1'
for d in self.data:
h = EVP.HMAC(d[0], algo)
h.update(d[1])
ret = h.final()
self.assertEqual(ret, d[2])
- self.assertRaises(ValueError, EVP.HMAC, d[0], algo='nosuchalgo')
+ with self.assertRaises(ValueError):
+ EVP.HMAC(d[0], algo='nosuchalgo')
- def make_chain_HMAC(self, key, start, input, algo='sha1'):
+ def make_chain_HMAC(self, key, start, input, algo='sha1'): # noqa
chain = []
hmac = EVP.HMAC(key, algo)
- hmac.update(`start`)
+ hmac.update(repr(start))
digest = hmac.final()
chain.append((digest, start))
for i in input:
hmac.reset(digest)
- hmac.update(`i`)
+ hmac.update(repr(i))
digest = hmac.final()
chain.append((digest, i))
return chain
-
+
def make_chain_hmac(self, key, start, input, algo='sha1'):
- from M2Crypto.EVP import hmac
chain = []
- digest = hmac(key, `start`, algo)
+ digest = EVP.hmac(key, start, algo)
chain.append((digest, start))
for i in input:
- digest = hmac(digest, `i`, algo)
+ digest = EVP.hmac(digest, i, algo)
chain.append((digest, i))
return chain
-
+
def verify_chain_hmac(self, key, start, chain, algo='sha1'):
- from M2Crypto.EVP import hmac
- digest = hmac(key, `start`, algo)
+ digest = EVP.hmac(key, start, algo)
c = chain[0]
if c[0] != digest or c[1] != start:
return 0
for d, v in chain[1:]:
- digest = hmac(digest, `v`, algo)
+ digest = EVP.hmac(digest, v, algo)
if digest != d:
return 0
return 1
-
- def verify_chain_HMAC(self, key, start, chain, algo='sha1'):
+
+ def verify_chain_HMAC(self, key, start, chain, algo='sha1'): # noqa
hmac = EVP.HMAC(key, algo)
- hmac.update(`start`)
+ hmac.update(start)
digest = hmac.final()
c = chain[0]
if c[0] != digest or c[1] != start:
return 0
for d, v in chain[1:]:
hmac.reset(digest)
- hmac.update(`v`)
+ hmac.update(v)
digest = hmac.final()
if digest != d:
return 0
return 1
-
+
def test_complicated(self):
make_chain = self.make_chain_hmac
verify_chain = self.verify_chain_hmac
- key = 'numero uno'
- start = 'zeroth item'
- input = ['first item', 'go go go', 'fly fly fly']
+ key = b'numero uno'
+ start = b'zeroth item'
+ input = [b'first item', b'go go go', b'fly fly fly']
chain = make_chain(key, start, input)
- self.assertEquals(verify_chain('some key', start, chain), 0)
- self.assertEquals(verify_chain(key, start, chain), 1)
+ self.assertEqual(verify_chain(b'some key', start, chain), 0)
+ self.assertEqual(verify_chain(key, start, chain), 1)
def suite():
@@ -462,10 +627,9 @@ def suite():
suite.addTest(unittest.makeSuite(CipherTestCase))
suite.addTest(unittest.makeSuite(PBKDF2TestCase))
suite.addTest(unittest.makeSuite(HMACTestCase))
- return suite
+ return suite
if __name__ == '__main__':
- Rand.load_file('randpool.dat', -1)
+ Rand.load_file('randpool.dat', -1)
unittest.TextTestRunner().run(suite())
Rand.save_file('randpool.dat')
-
diff --git a/tests/test_obj.py b/tests/test_obj.py
index 9144135..7748492 100644
--- a/tests/test_obj.py
+++ b/tests/test_obj.py
@@ -2,30 +2,41 @@
"""Unit tests for M2Crypto.m2 obj_* functions.
"""
-
-import unittest
-from M2Crypto import X509, ASN1, BIO, Rand, m2
+from M2Crypto import ASN1, BIO, Rand, X509, m2, six
+from tests import unittest
"""
These functions must be cleaned up and moved to some python module
Taken from CA managment code
"""
+
def x509_name2list(name):
for i in range(0, name.entry_count()):
- yield X509.X509_Name_Entry(m2.x509_name_get_entry(name._ptr(), i), _pyfree = 0)
+ yield X509.X509_Name_Entry(m2.x509_name_get_entry(name._ptr(), i),
+ _pyfree=0)
+
def x509_name_entry2tuple(entry):
bio = BIO.MemoryBuffer()
m2.asn1_string_print(bio._ptr(), m2.x509_name_entry_get_data(entry._ptr()))
- return (m2.obj_obj2txt(m2.x509_name_entry_get_object(entry._ptr()), 0), bio.getvalue())
+ return (
+ six.ensure_text(m2.obj_obj2txt(
+ m2.x509_name_entry_get_object(entry._ptr()), 0)),
+ six.ensure_text(bio.getvalue()))
+
def tuple2x509_name_entry(tup):
obj, data = tup
- _x509_ne = m2.x509_name_entry_create_by_txt(None, obj, ASN1.MBSTRING_ASC, data, len(data))
+ # TODO This is evil, isn't it? Shouldn't we use only official API?
+ # Something like X509.X509_Name.add_entry_by_txt()
+ _x509_ne = m2.x509_name_entry_create_by_txt(None, six.ensure_str(obj),
+ ASN1.MBSTRING_ASC,
+ six.ensure_str(data), len(data))
if not _x509_ne:
raise ValueError("Invalid object indentifier: %s" % obj)
- return X509.X509_Name_Entry(_x509_ne, _pyfree = 1) # Prevent memory leaks
+ return X509.X509_Name_Entry(_x509_ne, _pyfree=1) # Prevent memory leaks
+
class ObjectsTestCase(unittest.TestCase):
@@ -33,57 +44,94 @@ class ObjectsTestCase(unittest.TestCase):
pass
def test_obj2txt(self):
- assert m2.obj_obj2txt(m2.obj_txt2obj("commonName", 0), 1) == "2.5.4.3", "2.5.4.3"
- assert m2.obj_obj2txt(m2.obj_txt2obj("commonName", 0), 0) == "commonName", "commonName"
+ self.assertEqual(m2.obj_obj2txt(m2.obj_txt2obj("commonName", 0), 1),
+ b"2.5.4.3", b"2.5.4.3")
+ self.assertEqual(m2.obj_obj2txt(m2.obj_txt2obj("commonName", 0), 0),
+ b"commonName", b"commonName")
def test_nid(self):
- assert m2.obj_ln2nid("commonName") == m2.obj_txt2nid("2.5.4.3"), "ln2nid and txt2nid mismatch"
- assert m2.obj_ln2nid("CN") == 0, "ln2nid on sn"
- assert m2.obj_sn2nid("CN") == m2.obj_ln2nid("commonName"), "ln2nid and sn2nid mismatch"
- assert m2.obj_sn2nid("CN") == m2.obj_obj2nid(m2.obj_txt2obj("CN", 0)), "obj2nid"
- assert m2.obj_txt2nid("__unknown") == 0, "__unknown"
-
+ self.assertEqual(m2.obj_ln2nid("commonName"),
+ m2.obj_txt2nid("2.5.4.3"),
+ "ln2nid and txt2nid mismatch")
+ self.assertEqual(m2.obj_ln2nid("CN"),
+ 0, "ln2nid on sn")
+ self.assertEqual(m2.obj_sn2nid("CN"),
+ m2.obj_ln2nid("commonName"),
+ "ln2nid and sn2nid mismatch")
+ self.assertEqual(m2.obj_sn2nid("CN"),
+ m2.obj_obj2nid(m2.obj_txt2obj("CN", 0)), "obj2nid")
+ self.assertEqual(m2.obj_txt2nid("__unknown"),
+ 0, "__unknown")
+
def test_tuple2tuple(self):
tup = ("CN", "someCommonName")
tup1 = x509_name_entry2tuple(tuple2x509_name_entry(tup))
- assert tup1[1] == tup[1], tup1 # tup1[0] is 'commonName', not 'CN'
- assert x509_name_entry2tuple(tuple2x509_name_entry(tup1)) == tup1, tup1
+ # tup1[0] is 'commonName', not 'CN'
+ self.assertEqual(tup1[1], tup[1], tup1)
+ self.assertEqual(x509_name_entry2tuple(tuple2x509_name_entry(tup1)),
+ tup1, tup1)
def test_unknown(self):
- self.assertRaises(ValueError, tuple2x509_name_entry, ("__unknown", "_"))
-
+ with self.assertRaises(ValueError):
+ tuple2x509_name_entry(("__unknown", "_"))
+
def test_x509_name(self):
n = X509.X509_Name()
- n.C = 'US' # It seems this actually needs to be a real 2 letter country code
- n.SP = 'State or Province'
- n.L = 'locality name'
- n.O = 'orhanization name'
- n.OU = 'org unit'
- n.CN = 'common name'
- n.Email = 'bob@example.com'
- n.serialNumber = '1234'
- n.SN = 'surname'
- n.GN = 'given name'
-
- n.givenName = 'name given'
- assert len(n) == 11, len(n)
-
- tl = map(x509_name_entry2tuple, x509_name2list(n))
-
- assert len(tl) == len(n), len(tl)
+ # It seems this actually needs to be a real 2 letter country code
+ n.C = b'US'
+ n.SP = b'State or Province'
+ n.L = b'locality name'
+ n.O = b'orhanization name'
+ n.OU = b'org unit'
+ n.CN = b'common name'
+ n.Email = b'bob@example.com'
+ n.serialNumber = b'1234'
+ n.SN = b'surname'
+ n.GN = b'given name'
+
+ n.givenName = b'name given'
+ self.assertEqual(len(n), 11, len(n))
+
+ # Thierry: this call to list seems extraneous...
+ tl = [x509_name_entry2tuple(x) for x in x509_name2list(n)]
+
+ self.assertEqual(len(tl), len(n), len(tl))
x509_n = m2.x509_name_new()
- for o in map(tuple2x509_name_entry, tl):
+ for o in [tuple2x509_name_entry(x) for x in tl]:
m2.x509_name_add_entry(x509_n, o._ptr(), -1, 0)
- o._pyfree = 0 # Take care of underlying object
+ o._pyfree = 0 # Take care of underlying object
n1 = X509.X509_Name(x509_n)
- assert n.as_text() == n1.as_text(), n1.as_text()
+ self.assertEqual(n.as_text(), n1.as_text(), n1.as_text())
+
+ # Detailed OpenSSL error message is visible in Python error message:
+ def test_detailed_error_message(self):
+ from M2Crypto import SMIME, X509
+ s = SMIME.SMIME()
+ x509 = X509.load_cert('tests/recipient.pem')
+ sk = X509.X509_Stack()
+ sk.push(x509)
+ s.set_x509_stack(sk)
+
+ st = X509.X509_Store()
+ st.load_info('tests/recipient.pem')
+ s.set_x509_store(st)
+
+ p7, data = SMIME.smime_load_pkcs7('tests/sample-p7.pem')
+ self.assertIsInstance(p7, SMIME.PKCS7, p7)
+
+ try:
+ s.verify(p7, data)
+ except SMIME.PKCS7_Error as e:
+ self.assertRegexpMatches(str(e),
+ "unable to get local issuer certificate",
+ "Not received expected error message")
def suite():
- suite = unittest.TestSuite()
- suite.addTest(unittest.makeSuite(ObjectsTestCase))
- return suite
+ t_suite = unittest.TestSuite()
+ t_suite.addTest(unittest.makeSuite(ObjectsTestCase))
+ return t_suite
if __name__ == '__main__':
diff --git a/tests/test_pgp.py b/tests/test_pgp.py
deleted file mode 100644
index c86d153..0000000
--- a/tests/test_pgp.py
+++ /dev/null
@@ -1,40 +0,0 @@
-#!/usr/bin/env python
-
-"""PGP test program.
-
-Copyright (c) 1999 Ng Pheng Siong. All rights reserved."""
-
-import unittest
-from M2Crypto import EVP, PGP
-from cStringIO import StringIO
-
-
-class PGPTestCase(unittest.TestCase):
-
- def test_simple(self):
- pkr = PGP.load_pubring('tests/pubring.pgp')
- daft = pkr['daft']
- daft_pkt = daft._pubkey_pkt.pack()
- s1 = EVP.MessageDigest('sha1')
- s1.update(daft_pkt)
- s1f = `s1.final()`
-
- buf = StringIO(daft_pkt)
- ps = PGP.packet_stream(buf)
- dift_pkt = ps.read()
- s2 = EVP.MessageDigest('sha1')
- s2.update(dift_pkt.pack())
- s2f = `s2.final()`
-
- self.assertEqual(s1f, s2f)
-
-def suite():
- suite = unittest.TestSuite()
- suite.addTest(unittest.makeSuite(PGPTestCase))
- return suite
-
-
-if __name__ == '__main__':
- Rand.load_file('randpool.dat', -1)
- unittest.TextTestRunner().run(suite())
- Rand.save_file('randpool.dat')
diff --git a/tests/test_rand.py b/tests/test_rand.py
index 3e4d65d..cd27a25 100644
--- a/tests/test_rand.py
+++ b/tests/test_rand.py
@@ -2,45 +2,78 @@
"""Unit tests for M2Crypto.Rand.
-Copyright (C) 2006 Open Source Applications Foundation (OSAF). All Rights Reserved.
+Copyright (C) 2006 Open Source Applications Foundation (OSAF).
+All Rights Reserved.
"""
-import unittest
-import os, sys
-from M2Crypto import Rand
+import os
+import ctypes
+import warnings
+
+from M2Crypto import Rand, m2
+from tests import unittest
+
class RandTestCase(unittest.TestCase):
def test_bytes(self):
- self.assertRaises(MemoryError, Rand.rand_bytes, -1)
- assert Rand.rand_bytes(0) == ''
- assert len(Rand.rand_bytes(1)) == 1
-
+ with self.assertRaises(MemoryError):
+ Rand.rand_bytes(-1)
+ self.assertEqual(Rand.rand_bytes(0), b'')
+ self.assertEqual(len(Rand.rand_bytes(1)), 1)
+
def test_pseudo_bytes(self):
- self.assertRaises(MemoryError, Rand.rand_pseudo_bytes, -1)
- assert Rand.rand_pseudo_bytes(0) == ('', 1)
- a, b = Rand.rand_pseudo_bytes(1)
- assert len(a) == 1
- assert b == 1
-
+ with warnings.catch_warnings():
+ warnings.simplefilter('ignore', DeprecationWarning)
+ with self.assertRaises(MemoryError):
+ Rand.rand_pseudo_bytes(-1)
+ self.assertEqual(Rand.rand_pseudo_bytes(0), (b'', 1))
+ a, b = Rand.rand_pseudo_bytes(1)
+ self.assertEqual(len(a), 1)
+ self.assertEqual(b, 1)
+
+ def test_file_name(self):
+ if os.name == 'nt':
+ is_admin = ctypes.windll.shell32.IsUserAnAdmin() != 0
+ rand_env = ('RANDFILE', 'HOME', 'USERPROFILE', 'SYSTEMROOT')
+ else:
+ rand_env = ('RANDFILE', 'HOME')
+ is_admin = False
+ key = next((k for k in rand_env if os.environ.get(k)), None)
+ if is_admin and m2.OPENSSL_VERSION_NUMBER < 0x1010000F:
+ path = 'C:\\'
+ else:
+ path = os.path.join(os.environ[key])
+ self.assertIsNotNone(key, "Could not find required environment")
+ rand_file = os.path.abspath(os.path.join(path, '.rnd'))
+ self.assertEqual(os.path.abspath(Rand.rand_file_name()), rand_file)
+
def test_load_save(self):
try:
os.remove('tests/randpool.dat')
except OSError:
pass
- assert Rand.load_file('tests/randpool.dat', -1) == 0
- assert Rand.save_file('tests/randpool.dat') == 1024
- assert Rand.load_file('tests/randpool.dat', -1) == 1024
-
+ self.assertIn(Rand.load_file('tests/randpool.dat', -1), [0, -1])
+ self.assertEqual(Rand.save_file('tests/randpool.dat'), 1024)
+ self.assertEqual(Rand.load_file('tests/randpool.dat', -1), 1024)
+
def test_seed_add(self):
- if sys.version_info >= (2, 4):
- assert Rand.rand_seed(os.urandom(1024)) is None
-
- # XXX Should there be limits on the entropy parameter?
- assert Rand.rand_add(os.urandom(2), 0.5) is None
- Rand.rand_add(os.urandom(2), -0.5)
- Rand.rand_add(os.urandom(2), 5000.0)
-
-
+ self.assertIsNone(Rand.rand_seed(os.urandom(1024)))
+
+ # XXX Should there be limits on the entropy parameter?
+ self.assertIsNone(Rand.rand_add(os.urandom(2), 0.5))
+ Rand.rand_add(os.urandom(2), -0.5)
+ Rand.rand_add(os.urandom(2), 5000.0)
+
+ def test_rand_status(self):
+ # Although it is hard to believe we would ever get 0 (i.e., PRNG
+ # hasn't enough entropy), it is a legitimate value.
+ status = Rand.rand_status()
+ self.assertIn(status, [0, 1],
+ 'Illegal value of RAND.rand_status {0}!'.format(status))
+ if status == 0:
+ warnings.warn('RAND_status reports insufficient seeding of PRNG!')
+
+
def suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(RandTestCase))
diff --git a/tests/test_rc4.py b/tests/test_rc4.py
index 5a2d239..b06406c 100644
--- a/tests/test_rc4.py
+++ b/tests/test_rc4.py
@@ -1,41 +1,52 @@
#!/usr/bin/env python
+from __future__ import absolute_import
"""Unit tests for M2Crypto.RC4.
Copyright (c) 2009 Heikki Toivonen. All rights reserved."""
-import unittest
+from M2Crypto import RC4, Rand
from binascii import hexlify
-from M2Crypto import RC4
+
+from tests import unittest
+from tests.fips import fips_mode
+
class RC4TestCase(unittest.TestCase):
+ @unittest.skipIf(fips_mode, "Can't be run in FIPS mode")
def test_vectors(self):
"""
Test with test vectors from Wikipedia: http://en.wikipedia.org/wiki/Rc4
"""
- vectors = (('Key', 'Plaintext', 'BBF316E8D940AF0AD3'),
- ('Wiki', 'pedia', '1021BF0420'),
- ('Secret', 'Attack at dawn', '45A01F645FC35B383552544B9BF5'))
-
+ if fips_mode:
+ return
+ vectors = ((b'Key', b'Plaintext', b'BBF316E8D940AF0AD3'),
+ (b'Wiki', b'pedia', b'1021BF0420'),
+ (b'Secret', b'Attack at dawn',
+ b'45A01F645FC35B383552544B9BF5'))
+
rc4 = RC4.RC4()
for key, plaintext, ciphertext in vectors:
rc4.set_key(key)
- self.assertEqual(hexlify(rc4.update(plaintext)).upper(), ciphertext)
+ self.assertEqual(hexlify(rc4.update(plaintext)).upper(),
+ ciphertext)
self.assertEqual(rc4.final(), '')
-
+
+ @unittest.skipIf(fips_mode, "Can't be run in FIPS mode")
def test_bad(self):
- rc4 = RC4.RC4('foo')
- self.assertNotEqual(hexlify(rc4.update('bar')).upper(), '45678')
-
-
+ if fips_mode:
+ return
+ rc4 = RC4.RC4(b'foo')
+ self.assertNotEqual(hexlify(rc4.update(b'bar')).upper(), b'45678')
+
+
def suite():
return unittest.makeSuite(RC4TestCase)
-
+
if __name__ == '__main__':
- Rand.load_file('randpool.dat', -1)
+ Rand.load_file('randpool.dat', -1)
unittest.TextTestRunner().run(suite())
Rand.save_file('randpool.dat')
-
diff --git a/tests/test_rsa.py b/tests/test_rsa.py
index 0bb986b..7028b60 100644
--- a/tests/test_rsa.py
+++ b/tests/test_rsa.py
@@ -1,12 +1,20 @@
#!/usr/bin/env python
+from __future__ import absolute_import
"""Unit tests for M2Crypto.RSA.
Copyright (c) 2000 Ng Pheng Siong. All rights reserved."""
-import unittest
-import sha, md5, os, sys
-from M2Crypto import RSA, BIO, Rand, m2, EVP, X509
+import hashlib
+import logging
+import os
+
+from M2Crypto import BIO, RSA, Rand, X509, m2, six
+from tests import unittest
+from tests.fips import fips_mode
+
+log = logging.getLogger('test_RSA')
+
class RSATestCase(unittest.TestCase):
@@ -15,7 +23,7 @@ class RSATestCase(unittest.TestCase):
privkey2 = 'tests/rsa.priv2.pem'
pubkey = 'tests/rsa.pub.pem'
- data = sha.sha('The magic words are squeamish ossifrage.').digest()
+ data = hashlib.sha1(b'The magic words are squeamish ossifrage.').digest()
e_padding_ok = ('pkcs1_padding', 'pkcs1_oaep_padding')
@@ -30,50 +38,63 @@ class RSATestCase(unittest.TestCase):
def pp_callback(self, *args):
# The passphrase for rsa.priv2.pem is 'qwerty'.
- return 'qwerty'
+ return b'qwerty'
def pp2_callback(self, *args):
# Misbehaving passphrase callback.
- pass
+ return b'blabla'
+
+ def test_rsa_exceptions(self):
+ with self.assertRaises(RSA.RSAError):
+ RSA.rsa_error()
def test_loadkey_junk(self):
- self.assertRaises(RSA.RSAError, RSA.load_key, self.errkey)
+ with self.assertRaises(RSA.RSAError):
+ RSA.load_key(self.errkey)
def test_loadkey_pp(self):
rsa = RSA.load_key(self.privkey2, self.pp_callback)
- assert len(rsa) == 1024
- assert rsa.e == '\000\000\000\003\001\000\001' # aka 65537 aka 0xf4
- assert rsa.check_key() == 1
+ self.assertEqual(len(rsa), 1024)
+ self.assertEqual(rsa.e,
+ b'\000\000\000\003\001\000\001') # aka 65537 aka 0xf4
+ self.assertEqual(rsa.check_key(), 1)
def test_loadkey_pp_bad_cb(self):
- self.assertRaises(RSA.RSAError, RSA.load_key, self.privkey2, self.pp2_callback)
+ with self.assertRaises(RSA.RSAError):
+ RSA.load_key(self.privkey2, self.pp2_callback)
def test_loadkey(self):
rsa = RSA.load_key(self.privkey)
- assert len(rsa) == 1024
- assert rsa.e == '\000\000\000\003\001\000\001' # aka 65537 aka 0xf4
- self.assertEqual(rsa.n, "\x00\x00\x00\x81\x00\xcde!\x15\xdah\xb5`\xce[\xd6\x17d\xba8\xc1I\xb1\xf1\xber\x86K\xc7\xda\xb3\x98\xd6\xf6\x80\xae\xaa\x8f!\x9a\xefQ\xdeh\xbb\xc5\x99\x01o\xebGO\x8e\x9b\x9a\x18\xfb6\xba\x12\xfc\xf2\x17\r$\x00\xa1\x1a \xfc/\x13iUm\x04\x13\x0f\x91D~\xbf\x08\x19C\x1a\xe2\xa3\x91&\x8f\xcf\xcc\xf3\xa4HRf\xaf\xf2\x19\xbd\x05\xe36\x9a\xbbQ\xc86|(\xad\x83\xf2Eu\xb2EL\xdf\xa4@\x7f\xeel|\xfcU\x03\xdb\x89'")
- self.assertRaises(AttributeError, getattr, rsa, 'nosuchprop')
- assert rsa.check_key() == 1
+ self.assertEqual(len(rsa), 1024)
+ self.assertEqual(rsa.e,
+ b'\000\000\000\003\001\000\001') # aka 65537 aka 0xf4
+ self.assertEqual(rsa.n, b"\x00\x00\x00\x81\x00\xcde!\x15\xdah\xb5`\xce[\xd6\x17d\xba8\xc1I\xb1\xf1\xber\x86K\xc7\xda\xb3\x98\xd6\xf6\x80\xae\xaa\x8f!\x9a\xefQ\xdeh\xbb\xc5\x99\x01o\xebGO\x8e\x9b\x9a\x18\xfb6\xba\x12\xfc\xf2\x17\r$\x00\xa1\x1a \xfc/\x13iUm\x04\x13\x0f\x91D~\xbf\x08\x19C\x1a\xe2\xa3\x91&\x8f\xcf\xcc\xf3\xa4HRf\xaf\xf2\x19\xbd\x05\xe36\x9a\xbbQ\xc86|(\xad\x83\xf2Eu\xb2EL\xdf\xa4@\x7f\xeel|\xfcU\x03\xdb\x89'")
+ with self.assertRaises(AttributeError):
+ getattr(rsa, 'nosuchprop')
+ self.assertEqual(rsa.check_key(), 1)
def test_loadkey_bio(self):
- keybio = BIO.MemoryBuffer(open(self.privkey).read())
+ with open(self.privkey, "rb") as f:
+ keybio = BIO.MemoryBuffer(f.read())
rsa = RSA.load_key_bio(keybio)
- assert len(rsa) == 1024
- assert rsa.e == '\000\000\000\003\001\000\001' # aka 65537 aka 0xf4
- assert rsa.check_key() == 1
+ self.assertEqual(len(rsa), 1024)
+ self.assertEqual(rsa.e,
+ b'\000\000\000\003\001\000\001') # aka 65537 aka 0xf4
+ self.assertEqual(rsa.check_key(), 1)
def test_keygen(self):
rsa = RSA.gen_key(1024, 65537, self.gen_callback)
- assert len(rsa) == 1024
- assert rsa.e == '\000\000\000\003\001\000\001' # aka 65537 aka 0xf4
- assert rsa.check_key() == 1
+ self.assertEqual(len(rsa), 1024)
+ self.assertEqual(rsa.e,
+ b'\000\000\000\003\001\000\001') # aka 65537 aka 0xf4
+ self.assertEqual(rsa.check_key(), 1)
def test_keygen_bad_cb(self):
rsa = RSA.gen_key(1024, 65537, self.gen2_callback)
- assert len(rsa) == 1024
- assert rsa.e == '\000\000\000\003\001\000\001' # aka 65537 aka 0xf4
- assert rsa.check_key() == 1
+ self.assertEqual(len(rsa), 1024)
+ self.assertEqual(rsa.e,
+ b'\000\000\000\003\001\000\001') # aka 65537 aka 0xf4
+ self.assertEqual(rsa.check_key(), 1)
def test_private_encrypt(self):
priv = RSA.load_key(self.privkey)
@@ -82,14 +103,18 @@ class RSATestCase(unittest.TestCase):
p = getattr(RSA, padding)
ctxt = priv.private_encrypt(self.data, p)
ptxt = priv.public_decrypt(ctxt, p)
- assert ptxt == self.data
+ self.assertEqual(ptxt, self.data)
# The other paddings.
for padding in self.s_padding_nok:
p = getattr(RSA, padding)
- self.assertRaises(RSA.RSAError, priv.private_encrypt, self.data, p)
+ with self.assertRaises(RSA.RSAError):
+ priv.private_encrypt(self.data, p)
# Type-check the data to be encrypted.
- self.assertRaises(TypeError, priv.private_encrypt, self.gen_callback, RSA.pkcs1_padding)
+ with self.assertRaises(TypeError):
+ priv.private_encrypt(self.gen_callback, RSA.pkcs1_padding)
+ @unittest.skipIf(m2.OPENSSL_VERSION_NUMBER < 0x1010103f,
+ 'Relies on fix which happened only in OpenSSL 1.1.1c')
def test_public_encrypt(self):
priv = RSA.load_key(self.privkey)
# pkcs1_padding, pkcs1_oaep_padding
@@ -97,38 +122,49 @@ class RSATestCase(unittest.TestCase):
p = getattr(RSA, padding)
ctxt = priv.public_encrypt(self.data, p)
ptxt = priv.private_decrypt(ctxt, p)
- assert ptxt == self.data
+ self.assertEqual(ptxt, self.data)
+
# sslv23_padding
ctxt = priv.public_encrypt(self.data, RSA.sslv23_padding)
- self.assertRaises(RSA.RSAError, priv.private_decrypt, ctxt, RSA.sslv23_padding)
+ res = priv.private_decrypt(ctxt, RSA.sslv23_padding)
+ self.assertEqual(res, self.data)
+
# no_padding
- self.assertRaises(RSA.RSAError, priv.public_encrypt, self.data, RSA.no_padding)
+ with six.assertRaisesRegex(self, TypeError, 'data too small'):
+ priv.public_encrypt(self.data, RSA.no_padding)
+
# Type-check the data to be encrypted.
- self.assertRaises(TypeError, priv.public_encrypt, self.gen_callback, RSA.pkcs1_padding)
+ with self.assertRaises(TypeError):
+ priv.public_encrypt(self.gen_callback, RSA.pkcs1_padding)
def test_x509_public_encrypt(self):
x509 = X509.load_cert("tests/recipient.pem")
rsa = x509.get_pubkey().get_rsa()
- rsa.public_encrypt("data", RSA.pkcs1_padding)
-
+ rsa.public_encrypt(b"data", RSA.pkcs1_padding)
+
def test_loadpub(self):
rsa = RSA.load_pub_key(self.pubkey)
- assert len(rsa) == 1024
- assert rsa.e == '\000\000\000\003\001\000\001' # aka 65537 aka 0xf4
- self.assertRaises(RSA.RSAError, setattr, rsa, 'e', '\000\000\000\003\001\000\001')
- self.assertRaises(RSA.RSAError, rsa.private_encrypt, 1)
- self.assertRaises(RSA.RSAError, rsa.private_decrypt, 1)
+ self.assertEqual(len(rsa), 1024)
+ self.assertEqual(rsa.e,
+ b'\000\000\000\003\001\000\001') # aka 65537 aka 0xf4
+ with self.assertRaises(RSA.RSAError):
+ setattr(rsa, 'e', '\000\000\000\003\001\000\001')
+ with self.assertRaises(RSA.RSAError):
+ rsa.private_encrypt(1)
+ with self.assertRaises(RSA.RSAError):
+ rsa.private_decrypt(1)
assert rsa.check_key()
def test_loadpub_bad(self):
- self.assertRaises(RSA.RSAError, RSA.load_pub_key, self.errkey)
+ with self.assertRaises(RSA.RSAError):
+ RSA.load_pub_key(self.errkey)
def test_savepub(self):
rsa = RSA.load_pub_key(self.pubkey)
- assert rsa.as_pem() # calls save_key_bio
+ assert rsa.as_pem() # calls save_key_bio
f = 'tests/rsa_test.pub'
try:
- self.assertEquals(rsa.save_key(f), 1)
+ self.assertEqual(rsa.save_key(f), 1)
finally:
try:
os.remove(f)
@@ -137,100 +173,134 @@ class RSATestCase(unittest.TestCase):
def test_set_bn(self):
rsa = RSA.load_pub_key(self.pubkey)
- assert m2.rsa_set_e(rsa.rsa, '\000\000\000\003\001\000\001') is None
- self.assertRaises(RSA.RSAError, m2.rsa_set_e, rsa.rsa, '\000\000\000\003\001')
+ with self.assertRaises(RSA.RSAError):
+ m2.rsa_set_en(rsa.rsa,
+ b'\000\000\000\003\001\000\001',
+ b'\000\000\000\003\001')
+
+ def test_set_n(self):
+ rsa = m2.rsa_new()
+ m2.rsa_set_n(rsa, b'\000\000\000\003\001\000\001')
+
+ n = m2.rsa_get_n(rsa)
+ e = m2.rsa_get_e(rsa)
+
+ self.assertEqual(n, b'\000\000\000\003\001\000\001')
+ self.assertEqual(e, b'\x00\x00\x00\x00')
+
+ def test_set_e(self):
+ rsa = m2.rsa_new()
+ m2.rsa_set_e(rsa, b'\000\000\000\003\001\000\001')
+
+ n = m2.rsa_get_n(rsa)
+ e = m2.rsa_get_e(rsa)
+
+ self.assertEqual(e, b'\000\000\000\003\001\000\001')
+ self.assertEqual(n, b'\x00\x00\x00\x00')
+
+ def test_set_n_then_set_e(self):
+ rsa = m2.rsa_new()
+ m2.rsa_set_n(rsa, b'\000\000\000\004\020\011\006\006')
+ m2.rsa_set_e(rsa, b'\000\000\000\003\001\000\001')
+
+ n = m2.rsa_get_n(rsa)
+ e = m2.rsa_get_e(rsa)
+
+ self.assertEqual(e, b'\000\000\000\003\001\000\001')
+ self.assertEqual(n, b'\000\000\000\004\020\011\006\006')
def test_newpub(self):
old = RSA.load_pub_key(self.pubkey)
new = RSA.new_pub_key(old.pub())
- assert new.check_key()
- assert len(new) == 1024
- assert new.e == '\000\000\000\003\001\000\001' # aka 65537 aka 0xf4
-
+ self.assertTrue(new.check_key())
+ self.assertEqual(len(new), 1024)
+ # aka 65537 aka 0xf4
+ self.assertEqual(new.e, b'\000\000\000\003\001\000\001')
+
def test_sign_and_verify(self):
"""
Testing signing and verifying digests
"""
- algos = {'sha1':'',
- 'ripemd160':'',
- 'md5':''}
+ algos = {'sha1': '',
+ 'ripemd160': '',
+ 'md5': ''}
if m2.OPENSSL_VERSION_NUMBER >= 0x90800F:
algos['sha224'] = ''
algos['sha256'] = ''
- algos['sha384'] = ''
- algos['sha512'] = ''
+ algos['sha384'] = ''
+ algos['sha512'] = ''
- message = "This is the message string"
- digest = sha.sha(message).digest()
+ message = b"This is the message string"
+ digest = hashlib.sha1(message).digest()
rsa = RSA.load_key(self.privkey)
rsa2 = RSA.load_pub_key(self.pubkey)
for algo in algos.keys():
signature = rsa.sign(digest, algo)
- #assert signature == algos[algo], 'mismatched signature with algorithm %s: signature=%s' % (algo, signature)
- verify = rsa2.verify(digest, signature, algo)
- assert verify == 1, 'verification failed with algorithm %s' % algo
-
+ # assert signature == algos[algo],
+ # 'mismatched signature with algorithm %s:
+ # signature=%s' % (algo, signature)
+ verify = rsa2.verify(digest, signature, algo)
+ self.assertEqual(verify, 1,
+ 'verification failed with algorithm %s' % algo)
+
if m2.OPENSSL_VERSION_NUMBER >= 0x90708F:
def test_sign_and_verify_rsassa_pss(self):
"""
Testing signing and verifying using rsassa_pss
-
+
The maximum size of the salt has to decrease as the
- size of the digest increases because of the size of
+ size of the digest increases because of the size of
our test key limits it.
"""
- message = "This is the message string"
- if sys.version_info < (2, 5):
- algos = {'sha1': (43, sha.sha(message).digest()),
- 'md5': (47, md5.md5(message).digest())}
-
- else:
- import hashlib
- algos = {'sha1': 43,
- 'ripemd160': 43,
- 'md5': 47}
-
- if m2.OPENSSL_VERSION_NUMBER >= 0x90800F:
- algos['sha224'] = 35
- algos['sha256'] = 31
- algos['sha384'] = 15
- algos['sha512'] = 0
-
- for algo, salt_max in algos.iteritems():
- h = hashlib.new(algo)
- h.update(message)
- digest = h.digest()
- algos[algo] = (salt_max, digest)
-
+ message = b"This is the message string"
+ import hashlib
+ algos = {'sha1': 43}
+ if not fips_mode:
+ algos['md5'] = 47
+ algos['ripemd160'] = 43
+
+ if m2.OPENSSL_VERSION_NUMBER >= 0x90800F:
+ algos['sha224'] = 35
+ algos['sha256'] = 31
+ algos['sha384'] = 15
+ algos['sha512'] = 0
+
+ for algo, salt_max in algos.items():
+ h = hashlib.new(algo)
+ h.update(message)
+ digest = h.digest()
+ algos[algo] = (salt_max, digest)
+
rsa = RSA.load_key(self.privkey)
rsa2 = RSA.load_pub_key(self.pubkey)
- for algo, (salt_max, digest) in algos.iteritems():
+ for algo, (salt_max, digest) in algos.items():
for salt_length in range(0, salt_max):
signature = rsa.sign_rsassa_pss(digest, algo, salt_length)
- verify = rsa2.verify_rsassa_pss(digest, signature, algo, salt_length)
- assert verify == 1, 'verification failed with algorithm %s salt length %d' % (algo, salt_length)
+ verify = rsa2.verify_rsassa_pss(digest, signature,
+ algo, salt_length)
+ self.assertEqual(verify, 1,
+ 'verification failed with algorithm '
+ '%s salt length %d' % (algo, salt_length))
def test_sign_bad_method(self):
"""
Testing calling sign with an unsupported message digest algorithm
"""
rsa = RSA.load_key(self.privkey)
- message = "This is the message string"
- digest = md5.md5(message).digest()
- self.assertRaises(ValueError, rsa.sign,
- digest, 'bad_digest_method')
-
+ digest = 'a' * 16
+ with self.assertRaises(ValueError):
+ rsa.sign(digest, 'bad_digest_method')
+
def test_verify_bad_method(self):
"""
Testing calling verify with an unsupported message digest algorithm
"""
rsa = RSA.load_key(self.privkey)
- message = "This is the message string"
- digest = md5.md5(message).digest()
+ digest = b'a' * 16
signature = rsa.sign(digest, 'sha1')
- self.assertRaises(ValueError, rsa.verify,
- digest, signature, 'bad_digest_method')
+ with self.assertRaises(ValueError):
+ rsa.verify(digest, signature, 'bad_digest_method')
def test_verify_mismatched_algo(self):
"""
@@ -238,13 +308,12 @@ class RSATestCase(unittest.TestCase):
message digest algorithm
"""
rsa = RSA.load_key(self.privkey)
- message = "This is the message string"
- digest = sha.sha(message).digest()
+ message = b"This is the message string"
+ digest = hashlib.sha1(message).digest()
signature = rsa.sign(digest, 'sha1')
- rsa2 = RSA.load_pub_key(self.pubkey)
- self.assertRaises(RSA.RSAError, rsa.verify,
- digest, signature, 'md5')
-
+ with self.assertRaises(RSA.RSAError):
+ rsa.verify(digest, signature, 'md5')
+
def test_sign_fail(self):
"""
Testing sign to make sure it fails when I give it
@@ -253,33 +322,33 @@ class RSATestCase(unittest.TestCase):
it has to be longer than a certain length.
"""
rsa = RSA.load_key(self.privkey)
- digest = """This string should be long enough to warrant an error in
+ digest = b"""This string should be long enough to warrant an error in
RSA_sign""" * 2
-
- self.assertRaises(RSA.RSAError, rsa.sign, digest)
-
+
+ with self.assertRaises(RSA.RSAError):
+ rsa.sign(digest)
+
def test_verify_bad_signature(self):
"""
Testing verify to make sure it fails when we use a bad signature
"""
rsa = RSA.load_key(self.privkey)
- message = "This is the message string"
- digest = sha.sha(message).digest()
+ message = b"This is the message string"
+ digest = hashlib.sha1(message).digest()
+
+ other_message = b"Abracadabra"
+ other_digest = hashlib.sha1(other_message).digest()
+ other_signature = rsa.sign(other_digest)
+
+ with self.assertRaises(RSA.RSAError):
+ rsa.verify(digest, other_signature)
- otherMessage = "Abracadabra"
- otherDigest = sha.sha(otherMessage).digest()
- otherSignature = rsa.sign(otherDigest)
- self.assertRaises(RSA.RSAError, rsa.verify,
- digest, otherSignature)
-
-
def suite():
return unittest.makeSuite(RSATestCase)
-
+
if __name__ == '__main__':
- Rand.load_file('randpool.dat', -1)
+ Rand.load_file('randpool.dat', -1)
unittest.TextTestRunner().run(suite())
Rand.save_file('randpool.dat')
-
diff --git a/tests/test_smime.py b/tests/test_smime.py
index f18c9db..a0edca8 100644
--- a/tests/test_smime.py
+++ b/tests/test_smime.py
@@ -5,97 +5,209 @@
Copyright (C) 2006 Open Source Applications Foundation. All Rights Reserved.
"""
-import unittest
-from M2Crypto import SMIME, BIO, Rand, X509, EVP
+import os.path
+
+from M2Crypto import BIO, EVP, Rand, SMIME, X509
+from tests import unittest
+
+
+# Various callbacks to set by X509_Store.set_verify_cb() for
+# testing with SMIME.verify() afterwards.
+# NOTE: if the Python callback function contains compile-time or run-time
+# errors, then SMIME.verify() can fail with a mysterious error which can be
+# hard to trace back.
+# Python exceptions in callbacks do *not* propagate to verify() call.
+def verify_cb_dummy_function(ok, ctx):
+ return ok
+
+
+def verify_cb_rejects_cert_from_heikki_toivonen(ok, ctx):
+ cert = ctx.get_current_cert()
+ return "Heikki Toivonen" not in cert.get_issuer().as_text()
+
class SMIMETestCase(unittest.TestCase):
- cleartext = 'some text to manipulate'
+ cleartext = b'some text to manipulate'
def setUp(self):
# XXX Ugly, but not sure what would be better
self.signed = self.test_sign()
self.encrypted = self.test_encrypt()
-
+
def test_load_bad(self):
s = SMIME.SMIME()
- self.assertRaises(EVP.EVPError, s.load_key,
- 'tests/signer.pem',
- 'tests/signer.pem')
-
- self.assertRaises(BIO.BIOError, SMIME.load_pkcs7, 'nosuchfile-dfg456')
- self.assertRaises(SMIME.PKCS7_Error, SMIME.load_pkcs7, 'tests/signer.pem')
- self.assertRaises(SMIME.PKCS7_Error, SMIME.load_pkcs7_bio, BIO.MemoryBuffer('no pkcs7'))
-
- self.assertRaises(SMIME.SMIME_Error, SMIME.smime_load_pkcs7, 'tests/signer.pem')
- self.assertRaises(SMIME.SMIME_Error, SMIME.smime_load_pkcs7_bio, BIO.MemoryBuffer('no pkcs7'))
+ with self.assertRaises(EVP.EVPError):
+ s.load_key('tests/signer.pem',
+ 'tests/signer.pem')
+
+ with self.assertRaises(BIO.BIOError):
+ SMIME.load_pkcs7('nosuchfile-dfg456')
+ with self.assertRaises(SMIME.PKCS7_Error):
+ SMIME.load_pkcs7('tests/signer.pem')
+ with self.assertRaises(SMIME.PKCS7_Error):
+ SMIME.load_pkcs7_bio(BIO.MemoryBuffer(b'no pkcs7'))
+
+ with self.assertRaises(BIO.BIOError):
+ SMIME.load_pkcs7_der('nosuchfile-dfg456')
+ with self.assertRaises(SMIME.PKCS7_Error):
+ SMIME.load_pkcs7_der('tests/signer.pem')
+ with self.assertRaises(SMIME.PKCS7_Error):
+ SMIME.load_pkcs7_bio_der(BIO.MemoryBuffer(b'no pkcs7'))
+
+ with self.assertRaises(SMIME.SMIME_Error):
+ SMIME.smime_load_pkcs7('tests/signer.pem')
+ with self.assertRaises(SMIME.SMIME_Error):
+ SMIME.smime_load_pkcs7_bio(BIO.MemoryBuffer(b'no pkcs7'))
def test_crlf(self):
- self.assertEqual(SMIME.text_crlf('foobar'), 'Content-Type: text/plain\r\n\r\nfoobar')
- self.assertEqual(SMIME.text_crlf_bio(BIO.MemoryBuffer('foobar')).read(), 'Content-Type: text/plain\r\n\r\nfoobar')
-
+ self.assertEqual(SMIME.text_crlf(b'foobar'), b'Content-Type: text/plain\r\n\r\nfoobar')
+ self.assertEqual(SMIME.text_crlf_bio(
+ BIO.MemoryBuffer(b'foobar')).read(), b'Content-Type: text/plain\r\n\r\nfoobar')
+
def test_sign(self):
buf = BIO.MemoryBuffer(self.cleartext)
s = SMIME.SMIME()
s.load_key('tests/signer_key.pem', 'tests/signer.pem')
p7 = s.sign(buf, SMIME.PKCS7_DETACHED)
- assert len(buf) == 0
- assert p7.type() == SMIME.PKCS7_SIGNED, p7.type()
- assert isinstance(p7, SMIME.PKCS7), p7
+ self.assertEqual(len(buf), 0)
+ self.assertEqual(p7.type(), SMIME.PKCS7_SIGNED, p7.type())
+ self.assertIsInstance(p7, SMIME.PKCS7, p7)
out = BIO.MemoryBuffer()
p7.write(out)
-
+
buf = out.read()
-
- assert buf[:len('-----BEGIN PKCS7-----')] == '-----BEGIN PKCS7-----'
+
+ self.assertTrue(buf.startswith(b'-----BEGIN PKCS7-----'),
+ b'-----BEGIN PKCS7-----')
buf = buf.strip()
- assert buf[-len('-----END PKCS7-----'):] == '-----END PKCS7-----', buf[-len('-----END PKCS7-----'):]
- assert len(buf) > len('-----END PKCS7-----') + len('-----BEGIN PKCS7-----')
-
+ self.assertTrue(buf.endswith(b'-----END PKCS7-----'),
+ buf[-len(b'-----END PKCS7-----'):])
+ self.assertGreater(len(buf),
+ len(b'-----END PKCS7-----') +
+ len(b'-----BEGIN PKCS7-----'))
+
s.write(out, p7, BIO.MemoryBuffer(self.cleartext))
return out
- def test_store_load_info(self):
+ def test_sign_unknown_digest(self):
+ buf = BIO.MemoryBuffer(self.cleartext)
+ s = SMIME.SMIME()
+ s.load_key('tests/signer_key.pem', 'tests/signer.pem')
+ self.assertRaises(SMIME.SMIME_Error, s.sign,
+ buf, SMIME.PKCS7_DETACHED, 'invalid digest name')
+
+ def test_sign_nondefault_digest(self):
+ buf = BIO.MemoryBuffer(self.cleartext)
+ s = SMIME.SMIME()
+ s.load_key('tests/signer_key.pem', 'tests/signer.pem')
+ p7 = s.sign(buf, flags=SMIME.PKCS7_DETACHED, algo='sha512')
+ self.assertEqual(p7.type(), SMIME.PKCS7_SIGNED)
+
+ def test_sign_with_stack(self):
+ buf = BIO.MemoryBuffer(self.cleartext)
+ s = SMIME.SMIME()
+ s.load_key('tests/signer_key.pem', 'tests/signer.pem')
+ cert = X509.load_cert('tests/server.pem')
+ stack = X509.X509_Stack()
+ stack.push(cert)
+ s.set_x509_stack(stack)
+ p7 = s.sign(buf, flags=SMIME.PKCS7_DETACHED, algo='sha512')
+ self.assertEqual(p7.type(), SMIME.PKCS7_SIGNED)
+
+ def test_store_load_info(self):
st = X509.X509_Store()
- self.assertRaises(X509.X509Error, st.load_info, 'tests/ca.pem-typoname')
- self.assertEqual(st.load_info('tests/ca.pem'), 1)
+ with self.assertRaises(X509.X509Error):
+ st.load_info('tests/ca.pem-typoname')
+ self.assertEqual(st.load_info('tests/ca.pem'), 1)
def test_verify(self):
s = SMIME.SMIME()
-
+
x509 = X509.load_cert('tests/signer.pem')
sk = X509.X509_Stack()
sk.push(x509)
s.set_x509_stack(sk)
-
+
st = X509.X509_Store()
st.load_info('tests/ca.pem')
s.set_x509_store(st)
-
+
p7, data = SMIME.smime_load_pkcs7_bio(self.signed)
-
- assert isinstance(p7, SMIME.PKCS7), p7
+ self.assertIsInstance(p7, SMIME.PKCS7, p7)
+
v = s.verify(p7, data)
- assert v == self.cleartext
-
+ self.assertEqual(v, self.cleartext)
+
t = p7.get0_signers(sk)
- assert len(t) == 1
- assert t[0].as_pem() == x509.as_pem(), t[0].as_text()
+ self.assertEqual(len(t), 1)
+ self.assertEqual(t[0].as_pem(), x509.as_pem(), t[0].as_text())
+
+ def test_verify_with_static_callback(self):
+ s = SMIME.SMIME()
+
+ x509 = X509.load_cert('tests/signer.pem')
+ sk = X509.X509_Stack()
+ sk.push(x509)
+ s.set_x509_stack(sk)
+
+ st = X509.X509_Store()
+ st.load_info('tests/ca.pem')
+ st.set_verify_cb(verify_cb_rejects_cert_from_heikki_toivonen)
+ s.set_x509_store(st)
+
+ p7, data = SMIME.smime_load_pkcs7_bio(self.signed)
+ self.assertIsInstance(p7, SMIME.PKCS7, p7)
+
+ # Should reject certificate issued by Heikki Toivonen:
+ with self.assertRaises(SMIME.PKCS7_Error):
+ s.verify(p7, data)
+
+ st.set_verify_cb(verify_cb_dummy_function)
+ v = s.verify(p7, data)
+ self.assertEqual(v, self.cleartext)
+
+ st.set_verify_cb()
+ v = s.verify(p7, data)
+ self.assertEqual(v, self.cleartext)
+
+ def verify_cb_dummy_method(self, ok, store):
+ return verify_cb_dummy_function(ok, store)
+
+ def test_verify_with_method_callback(self):
+ s = SMIME.SMIME()
+
+ x509 = X509.load_cert('tests/signer.pem')
+ sk = X509.X509_Stack()
+ sk.push(x509)
+ s.set_x509_stack(sk)
+
+ st = X509.X509_Store()
+ st.load_info('tests/ca.pem')
+ st.set_verify_cb(self.verify_cb_dummy_method)
+ s.set_x509_store(st)
+
+ p7, data = SMIME.smime_load_pkcs7_bio(self.signed)
+
+ self.assertIsInstance(p7, SMIME.PKCS7, p7)
+ v = s.verify(p7, data)
+ self.assertEqual(v, self.cleartext)
def test_verifyBad(self):
s = SMIME.SMIME()
-
+
x509 = X509.load_cert('tests/recipient.pem')
sk = X509.X509_Stack()
sk.push(x509)
s.set_x509_stack(sk)
-
+
st = X509.X509_Store()
st.load_info('tests/recipient.pem')
s.set_x509_store(st)
-
+
p7, data = SMIME.smime_load_pkcs7_bio(self.signed)
- assert isinstance(p7, SMIME.PKCS7), p7
- self.assertRaises(SMIME.PKCS7_Error, s.verify, p7) # Bad signer
+ self.assertIsInstance(p7, SMIME.PKCS7, p7)
+ with self.assertRaises(SMIME.PKCS7_Error):
+ s.verify(p7) # Bad signer
def test_encrypt(self):
buf = BIO.MemoryBuffer(self.cleartext)
@@ -106,146 +218,159 @@ class SMIMETestCase(unittest.TestCase):
sk.push(x509)
s.set_x509_stack(sk)
- self.assertRaises(ValueError, SMIME.Cipher, 'nosuchcipher')
+ with self.assertRaises(ValueError):
+ SMIME.Cipher('nosuchcipher')
s.set_cipher(SMIME.Cipher('des_ede3_cbc'))
p7 = s.encrypt(buf)
-
- assert len(buf) == 0
- assert p7.type() == SMIME.PKCS7_ENVELOPED, p7.type()
- assert isinstance(p7, SMIME.PKCS7), p7
+
+ self.assertEqual(len(buf), 0)
+ self.assertEqual(p7.type(), SMIME.PKCS7_ENVELOPED,
+ p7.type())
+ self.assertIsInstance(p7, SMIME.PKCS7, p7)
out = BIO.MemoryBuffer()
p7.write(out)
-
+
buf = out.read()
-
- assert buf[:len('-----BEGIN PKCS7-----')] == '-----BEGIN PKCS7-----'
+
+ self.assertTrue(buf.startswith(b'-----BEGIN PKCS7-----'))
buf = buf.strip()
- assert buf[-len('-----END PKCS7-----'):] == '-----END PKCS7-----'
- assert len(buf) > len('-----END PKCS7-----') + len('-----BEGIN PKCS7-----')
-
+ self.assertTrue(buf.endswith(b'-----END PKCS7-----'))
+ self.assertGreater(len(buf),
+ len(b'-----END PKCS7-----') +
+ len(b'-----BEGIN PKCS7-----'))
+
s.write(out, p7)
return out
-
+
def test_decrypt(self):
s = SMIME.SMIME()
s.load_key('tests/recipient_key.pem', 'tests/recipient.pem')
-
+
p7, data = SMIME.smime_load_pkcs7_bio(self.encrypted)
- assert isinstance(p7, SMIME.PKCS7), p7
- self.assertRaises(SMIME.SMIME_Error, s.verify, p7) # No signer
-
+ self.assertIsInstance(p7, SMIME.PKCS7, p7)
+ with self.assertRaises(SMIME.SMIME_Error):
+ s.verify(p7) # No signer
+
out = s.decrypt(p7)
- assert out == self.cleartext
+ self.assertEqual(out, self.cleartext)
def test_decryptBad(self):
s = SMIME.SMIME()
s.load_key('tests/signer_key.pem', 'tests/signer.pem')
-
+
p7, data = SMIME.smime_load_pkcs7_bio(self.encrypted)
- assert isinstance(p7, SMIME.PKCS7), p7
- self.assertRaises(SMIME.SMIME_Error, s.verify, p7) # No signer
+ self.assertIsInstance(p7, SMIME.PKCS7, p7)
+ with self.assertRaises(SMIME.SMIME_Error):
+ s.verify(p7) # No signer
# Cannot decrypt: no recipient matches certificate
- self.assertRaises(SMIME.PKCS7_Error, s.decrypt, p7)
+ with self.assertRaises(SMIME.PKCS7_Error):
+ s.decrypt(p7)
def test_signEncryptDecryptVerify(self):
# sign
buf = BIO.MemoryBuffer(self.cleartext)
- s = SMIME.SMIME()
+ s = SMIME.SMIME()
s.load_key('tests/signer_key.pem', 'tests/signer.pem')
p7 = s.sign(buf)
-
+
# encrypt
x509 = X509.load_cert('tests/recipient.pem')
sk = X509.X509_Stack()
sk.push(x509)
s.set_x509_stack(sk)
-
+
s.set_cipher(SMIME.Cipher('des_ede3_cbc'))
-
+
tmp = BIO.MemoryBuffer()
s.write(tmp, p7)
p7 = s.encrypt(tmp)
-
+
signedEncrypted = BIO.MemoryBuffer()
s.write(signedEncrypted, p7)
# decrypt
s = SMIME.SMIME()
-
+
s.load_key('tests/recipient_key.pem', 'tests/recipient.pem')
-
+
p7, data = SMIME.smime_load_pkcs7_bio(signedEncrypted)
-
+
out = s.decrypt(p7)
-
+
# verify
x509 = X509.load_cert('tests/signer.pem')
sk = X509.X509_Stack()
sk.push(x509)
s.set_x509_stack(sk)
-
+
st = X509.X509_Store()
st.load_info('tests/ca.pem')
s.set_x509_store(st)
-
+
p7_bio = BIO.MemoryBuffer(out)
p7, data = SMIME.smime_load_pkcs7_bio(p7_bio)
v = s.verify(p7)
- assert v == self.cleartext
+ self.assertEqual(v, self.cleartext)
class WriteLoadTestCase(unittest.TestCase):
def setUp(self):
s = SMIME.SMIME()
s.load_key('tests/signer_key.pem', 'tests/signer.pem')
- p7 = s.sign(BIO.MemoryBuffer('some text'))
+ p7 = s.sign(BIO.MemoryBuffer(b'some text'))
self.filename = 'tests/sig.p7'
- f = BIO.openfile(self.filename, 'wb')
- assert p7.write(f) == 1
- f.close()
+ with BIO.openfile(self.filename, 'wb') as f:
+ self.assertEqual(p7.write(f), 1)
+ self.filename_der = 'tests/sig.p7.der'
+ with BIO.openfile(self.filename_der, 'wb') as f:
+ self.assertEqual(p7.write_der(f), 1)
- p7 = s.sign(BIO.MemoryBuffer('some text'), SMIME.PKCS7_DETACHED)
+ p7 = s.sign(BIO.MemoryBuffer(b'some text'), SMIME.PKCS7_DETACHED)
self.filenameSmime = 'tests/sig.p7s'
- f = BIO.openfile(self.filenameSmime, 'wb')
- assert s.write(f, p7, BIO.MemoryBuffer('some text')) == 1
- f.close()
-
- def test_write_pkcs7_der(self):
- buf = BIO.MemoryBuffer()
- assert SMIME.load_pkcs7(self.filename).write_der(buf) == 1
- s = buf.read()
- assert len(s) in (1204, 1243), len(s)
-
+ with BIO.openfile(self.filenameSmime, 'wb') as f:
+ self.assertEqual(s.write(f, p7, BIO.MemoryBuffer(b'some text')), 1)
+
+ def tearDown(self):
+ if os.path.exists(self.filename_der):
+ os.unlink(self.filename_der)
+
def test_load_pkcs7(self):
- assert SMIME.load_pkcs7(self.filename).type() == SMIME.PKCS7_SIGNED
-
+ self.assertEqual(SMIME.load_pkcs7(self.filename).type(), SMIME.PKCS7_SIGNED)
+
def test_load_pkcs7_bio(self):
- f = open(self.filename, 'rb')
- buf = BIO.MemoryBuffer(f.read())
- f.close()
-
- assert SMIME.load_pkcs7_bio(buf).type() == SMIME.PKCS7_SIGNED
+ with open(self.filename, 'rb') as f:
+ buf = BIO.MemoryBuffer(f.read())
+
+ self.assertEqual(SMIME.load_pkcs7_bio(buf).type(), SMIME.PKCS7_SIGNED)
+
+ def test_load_pkcs7_der(self):
+ self.assertEqual(SMIME.load_pkcs7_der(self.filename_der).type(), SMIME.PKCS7_SIGNED)
+
+ def test_load_pkcs7_bio_der(self):
+ with open(self.filename_der, 'rb') as f:
+ buf = BIO.MemoryBuffer(f.read())
+
+ self.assertEqual(SMIME.load_pkcs7_bio_der(buf).type(), SMIME.PKCS7_SIGNED)
def test_load_smime(self):
a, b = SMIME.smime_load_pkcs7(self.filenameSmime)
- assert isinstance(a, SMIME.PKCS7), a
- assert isinstance(b, BIO.BIO), b
- assert a.type() == SMIME.PKCS7_SIGNED
-
+ self.assertIsInstance(a, SMIME.PKCS7, a)
+ self.assertIsInstance(b, BIO.BIO, b)
+ self.assertEqual(a.type(), SMIME.PKCS7_SIGNED)
+
def test_load_smime_bio(self):
- f = open(self.filenameSmime, 'rb')
- buf = BIO.MemoryBuffer(f.read())
- f.close()
+ with open(self.filenameSmime, 'rb') as f:
+ buf = BIO.MemoryBuffer(f.read())
a, b = SMIME.smime_load_pkcs7_bio(buf)
- assert isinstance(a, SMIME.PKCS7), a
- assert isinstance(b, BIO.BIO), b
- assert a.type() == SMIME.PKCS7_SIGNED
+ self.assertIsInstance(a, SMIME.PKCS7, a)
+ self.assertIsInstance(b, BIO.BIO, b)
+ self.assertEqual(a.type(), SMIME.PKCS7_SIGNED)
def suite():
@@ -259,4 +384,3 @@ if __name__ == '__main__':
Rand.load_file('randpool.dat', -1)
unittest.TextTestRunner().run(suite())
Rand.save_file('randpool.dat')
-
diff --git a/tests/test_ssl.py b/tests/test_ssl.py
index 701484d..925d365 100644
--- a/tests/test_ssl.py
+++ b/tests/test_ssl.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python
-
+from __future__ import absolute_import, print_function
"""Unit tests for M2Crypto.SSL.
Copyright (c) 2000-2004 Ng Pheng Siong. All rights reserved.
@@ -19,280 +19,320 @@ Others:
- ForkingSSLServer
- ThreadingSSLServer
"""
+import gc
+import logging
+import os
+import os.path
+import signal
+import socket
+import subprocess
+import sys
+import tempfile
+import time
+import warnings
+
+from M2Crypto import (Err, Rand, SSL, X509, ftpslib, httpslib, m2, m2urllib,
+ m2urllib2, m2xmlrpclib, py27plus, six)
+from M2Crypto.SSL.timeout import DEFAULT_TIMEOUT
+from tests import unittest
+from tests.fips import fips_mode
+
+log = logging.getLogger('test_SSL')
+
+OPENSSL111=m2.OPENSSL_VERSION_NUMBER > 0x10101000
+
+# FIXME
+# It would be probably better if the port was randomly selected.
+# https://fedorahosted.org/libuser/browser/tests/alloc_port.c
+srv_host = 'localhost'
-import os, socket, string, sys, tempfile, thread, time, unittest
-from M2Crypto import Rand, SSL, m2, Err
-from fips import fips_mode
+def allocate_srv_port():
+ s = socket.socket()
+ try:
+ s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+ s.bind((srv_host, 0))
+ (host, port) = s.getsockname()
+ finally:
+ s.close()
+ return port
-srv_host = 'localhost'
-srv_port = 64000
def verify_cb_new_function(ok, store):
- try:
- assert not ok
- err = store.get_error()
- assert err in [m2.X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT,
- m2.X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY,
- m2.X509_V_ERR_CERT_UNTRUSTED,
- m2.X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE]
- assert store.get_error_depth() == 0
- app_data = m2.x509_store_ctx_get_app_data(store.ctx)
- assert app_data
- x509 = store.get_current_cert()
- assert x509
- stack = store.get1_chain()
- assert len(stack) == 1
- assert stack[0].as_pem() == x509.as_pem()
- except AssertionError, e:
- # If we let exceptions propagate from here the
- # caller may see strange errors. This is cleaner.
- return 0
+ assert not ok
+ err = store.get_error()
+ assert err in [m2.X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT,
+ m2.X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY,
+ m2.X509_V_ERR_CERT_UNTRUSTED,
+ m2.X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE]
+ assert store.get_error_depth() == 0
+ app_data = m2.x509_store_ctx_get_ex_data(
+ store.ctx, m2.ssl_get_ex_data_x509_store_ctx_idx())
+ assert app_data
+ x509 = store.get_current_cert()
+ assert x509
+ stack = store.get1_chain()
+ assert len(stack) == 1
+ assert stack[0].as_pem() == x509.as_pem()
return 1
-class VerifyCB:
+
+class VerifyCB(object):
def __call__(self, ok, store):
return verify_cb_new_function(ok, store)
-sleepTime = float(os.getenv('M2CRYPTO_TEST_SSL_SLEEP', 0.5))
+sleepTime = float(os.getenv('M2CRYPTO_TEST_SSL_SLEEP', '1.5'))
-def find_openssl():
- if os.name == 'nt' or sys.platform == 'cygwin':
- openssl = 'openssl.exe'
- else:
- openssl = 'openssl'
-
- plist = os.environ['PATH'].split(os.pathsep)
- for p in plist:
- try:
- dir = os.listdir(p)
- if openssl in dir:
- return True
- except:
- pass
- return False
class BaseSSLClientTestCase(unittest.TestCase):
- openssl_in_path = find_openssl()
+ # I would like to make it into a staticmethod, but apparently it
+ # doesn't mesh with @property. Oh well.
+ @property
+ def _is_openssl_in_path(self):
+ if os.name == 'nt' or sys.platform == 'cygwin':
+ openssl = 'openssl.exe'
+ else:
+ openssl = 'openssl'
+
+ plist = os.environ['PATH'].split(os.pathsep)
+ for p in plist:
+ try:
+ dir = os.listdir(p)
+ if openssl in dir:
+ return True
+ except:
+ pass
+ return False
def start_server(self, args):
- if not self.openssl_in_path:
+ if not self._is_openssl_in_path:
raise Exception('openssl command not in PATH')
-
- pid = os.fork()
- if pid == 0:
- # openssl must be started in the tests directory for it
- # to find the .pem files
- os.chdir('tests')
- try:
- os.execvp('openssl', args)
- finally:
- os.chdir('..')
-
- else:
- time.sleep(sleepTime)
- return pid
+
+ pid = subprocess.Popen(['openssl'] + args,
+ cwd='tests',
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ time.sleep(sleepTime)
+ return pid
def stop_server(self, pid):
- os.kill(pid, 1)
- os.waitpid(pid, 0)
+ pid.terminate()
+ out, err = pid.communicate()
+ return six.ensure_text(out), six.ensure_text(err)
def http_get(self, s):
- s.send('GET / HTTP/1.0\n\n')
- resp = ''
+ s.send(b'GET / HTTP/1.0\n\n')
+ resp = b''
while 1:
try:
r = s.recv(4096)
if not r:
break
- except SSL.SSLError: # s_server throws an 'unexpected eof'...
+ except SSL.SSLError: # s_server throws an 'unexpected eof'...
break
- resp = resp + r
- return resp
+ resp = resp + r
+ return six.ensure_text(resp)
def setUp(self):
self.srv_host = srv_host
- self.srv_port = srv_port
- self.srv_addr = (srv_host, srv_port)
- self.srv_url = 'https://%s:%s/' % (srv_host, srv_port)
+ self.srv_port = allocate_srv_port()
+ self.srv_addr = (srv_host, self.srv_port)
+ self.srv_url = 'https://%s:%s/' % (srv_host, self.srv_port)
self.args = ['s_server', '-quiet', '-www',
- #'-cert', 'server.pem', Implicitly using this
+ # '-cert', 'server.pem', Implicitly using this
'-accept', str(self.srv_port)]
- def tearDown(self):
- global srv_port
- srv_port = srv_port - 1
-
class PassSSLClientTestCase(BaseSSLClientTestCase):
-
+
def test_pass(self):
pass
+
class HttpslibSSLClientTestCase(BaseSSLClientTestCase):
+ def setUp(self):
+ super(HttpslibSSLClientTestCase, self).setUp()
+ self.ctx = SSL.Context()
+
+ def tearDown(self):
+ self.ctx.close()
def test_HTTPSConnection(self):
pid = self.start_server(self.args)
try:
- from M2Crypto import httpslib
- c = httpslib.HTTPSConnection(srv_host, srv_port)
+ c = httpslib.HTTPSConnection(srv_host, self.srv_port)
c.request('GET', '/')
data = c.getresponse().read()
c.close()
finally:
self.stop_server(pid)
- self.failIf(string.find(data, 's_server -quiet -www') == -1)
+ self.assertIn('s_server -quiet -www', six.ensure_text(data))
+ @unittest.skipIf(OPENSSL111, "Doesn't work with OpenSSL 1.1.1")
def test_HTTPSConnection_resume_session(self):
pid = self.start_server(self.args)
try:
- from M2Crypto import httpslib
- ctx = SSL.Context()
- ctx.load_verify_locations(cafile='tests/ca.pem')
- ctx.load_cert('tests/x509.pem')
- ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, 1)
- ctx.set_session_cache_mode(m2.SSL_SESS_CACHE_CLIENT)
- c = httpslib.HTTPSConnection(srv_host, srv_port, ssl_context=ctx)
+ self.ctx.load_verify_locations(cafile='tests/ca.pem')
+ self.ctx.load_cert('tests/x509.pem')
+ self.ctx.set_verify(
+ SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, 1)
+ self.ctx.set_session_cache_mode(m2.SSL_SESS_CACHE_CLIENT)
+ c = httpslib.HTTPSConnection(srv_host, self.srv_port,
+ ssl_context=self.ctx)
c.request('GET', '/')
ses = c.get_session()
t = ses.as_text()
data = c.getresponse().read()
# Appearently closing connection here screws session; Ali Polatel?
# c.close()
-
+
ctx2 = SSL.Context()
ctx2.load_verify_locations(cafile='tests/ca.pem')
ctx2.load_cert('tests/x509.pem')
- ctx2.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, 1)
+ ctx2.set_verify(
+ SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, 1)
ctx2.set_session_cache_mode(m2.SSL_SESS_CACHE_CLIENT)
- c2 = httpslib.HTTPSConnection(srv_host, srv_port, ssl_context=ctx2)
+ c2 = httpslib.HTTPSConnection(srv_host, self.srv_port,
+ ssl_context=ctx2)
c2.set_session(ses)
c2.request('GET', '/')
ses2 = c2.get_session()
t2 = ses2.as_text()
- data = c2.getresponse().read()
+ data = six.ensure_text(c2.getresponse().read())
c.close()
c2.close()
- assert t == t2, "Sessions did not match"
+ self.assertEqual(t, t2,
+ "Sessions did not match: t = %s, t2 = %s" % (t, t2,))
finally:
self.stop_server(pid)
- self.failIf(string.find(data, 's_server -quiet -www') == -1)
+ self.assertIn('s_server -quiet -www', data)
def test_HTTPSConnection_secure_context(self):
pid = self.start_server(self.args)
try:
- from M2Crypto import httpslib
- ctx = SSL.Context()
- ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, 9)
- ctx.load_verify_locations('tests/ca.pem')
- c = httpslib.HTTPSConnection(srv_host, srv_port, ssl_context=ctx)
+ self.ctx.set_verify(
+ SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, 9)
+ self.ctx.load_verify_locations('tests/ca.pem')
+ c = httpslib.HTTPSConnection(srv_host, self.srv_port,
+ ssl_context=self.ctx)
c.request('GET', '/')
- data = c.getresponse().read()
+ data = six.ensure_text(c.getresponse().read())
c.close()
finally:
self.stop_server(pid)
- self.failIf(string.find(data, 's_server -quiet -www') == -1)
+ self.assertIn('s_server -quiet -www', data)
def test_HTTPSConnection_secure_context_fail(self):
pid = self.start_server(self.args)
try:
- from M2Crypto import httpslib
- ctx = SSL.Context()
- ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, 9)
- ctx.load_verify_locations('tests/server.pem')
- c = httpslib.HTTPSConnection(srv_host, srv_port, ssl_context=ctx)
- self.assertRaises(SSL.SSLError, c.request, 'GET', '/')
+ self.ctx.set_verify(
+ SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, 9)
+ self.ctx.load_verify_locations('tests/server.pem')
+ c = httpslib.HTTPSConnection(srv_host, self.srv_port,
+ ssl_context=self.ctx)
+ with self.assertRaises(SSL.SSLError):
+ c.request('GET', '/')
c.close()
finally:
self.stop_server(pid)
- def test_HTTPS(self):
- pid = self.start_server(self.args)
- try:
- from M2Crypto import httpslib
- c = httpslib.HTTPS(srv_host, srv_port)
- c.putrequest('GET', '/')
- c.putheader('Accept', 'text/html')
- c.putheader('Accept', 'text/plain')
- c.endheaders()
- err, msg, headers = c.getreply()
- assert err == 200, err
- f = c.getfile()
- data = f.read()
- c.close()
- finally:
- self.stop_server(pid)
- self.failIf(string.find(data, 's_server -quiet -www') == -1)
+ def test_HTTPSConnection_illegalkeywordarg(self):
+ with self.assertRaises(ValueError):
+ httpslib.HTTPSConnection('example.org', badKeyword=True)
+
+
+class HttpslibSSLSNIClientTestCase(BaseSSLClientTestCase):
+ def setUp(self):
+ super(HttpslibSSLSNIClientTestCase, self).setUp()
+ self.args = ['s_server', '-servername', srv_host, '-debug', '-www', '-msg',
+ '-cert', 'server.pem', '-key', 'server_key.pem',
+ '-cert2', 'server.pem', '-key2', 'server_key.pem',
+ '-accept', str(self.srv_port)]
+ self.ctx = SSL.Context()
- def test_HTTPS_secure_context(self):
+ def tearDown(self):
+ self.ctx.close()
+
+ def test_SNI_support(self):
pid = self.start_server(self.args)
try:
- from M2Crypto import httpslib
- ctx = SSL.Context()
- ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, 9)
- ctx.load_verify_locations('tests/ca.pem')
- c = httpslib.HTTPS(srv_host, srv_port, ssl_context=ctx)
- c.putrequest('GET', '/')
- c.putheader('Accept', 'text/html')
- c.putheader('Accept', 'text/plain')
- c.endheaders()
- err, msg, headers = c.getreply()
- assert err == 200, err
- f = c.getfile()
- data = f.read()
+ c = httpslib.HTTPSConnection(self.srv_host, self.srv_port,
+ ssl_context=self.ctx)
+ c.request('GET', '/')
c.close()
finally:
- self.stop_server(pid)
- self.failIf(string.find(data, 's_server -quiet -www') == -1)
+ # (openssl s_server) buffers its log output, and ends the TLS session
+ # with the client (allowing the client to terminate) before flushing
+ # the log; so, the client may get here and terminate the server
+ # before it manages to log the output.
+ # So, give the server hopefully enough time to flush the logs.
+ time.sleep(sleepTime)
+ out, _ = self.stop_server(pid)
+ self.assertIn('Hostname in TLS extension: "%s"' % srv_host, out)
- def test_HTTPS_secure_context_fail(self):
+ def test_IP_call(self):
+ no_exception = True
+ runs_counter = 0
pid = self.start_server(self.args)
- try:
- from M2Crypto import httpslib
- ctx = SSL.Context()
- ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, 9)
- ctx.load_verify_locations('tests/server.pem')
- c = httpslib.HTTPS(srv_host, srv_port, ssl_context=ctx)
- c.putrequest('GET', '/')
- c.putheader('Accept', 'text/html')
- c.putheader('Accept', 'text/plain')
- self.assertRaises(SSL.SSLError, c.endheaders)
- c.close()
- finally:
- self.stop_server(pid)
-
- def test_HTTPSConnection_illegalkeywordarg(self):
- from M2Crypto import httpslib
- self.assertRaises(ValueError, httpslib.HTTPSConnection, 'example.org',
- badKeyword=True)
+
+ for entry in socket.getaddrinfo(self.srv_host, self.srv_port,
+ socket.AF_INET,
+ socket.SOCK_STREAM,
+ socket.IPPROTO_TCP):
+ ipfamily, socktype, _, _, sockaddr = entry
+ ip = sockaddr[0]
+
+ sock = socket.socket(ipfamily, socktype)
+ conn = SSL.Connection(self.ctx, sock=sock)
+ conn.set_tlsext_host_name(self.srv_host)
+ conn.set1_host(self.srv_host)
+
+ runs_counter += 1
+ try:
+ conn.connect((ip, self.srv_port))
+ except (SSL.SSLError, socket.error):
+ log.exception("Failed to connect to %s:%s", ip, self.srv_port)
+ no_exception = False
+ finally:
+ conn.close()
+
+ out, _ = self.stop_server(pid)
+ self.assertEqual(
+ out.count('Hostname in TLS extension: "%s"' % self.srv_host),
+ runs_counter)
+
+ self.assertTrue(no_exception)
class MiscSSLClientTestCase(BaseSSLClientTestCase):
def test_no_connection(self):
ctx = SSL.Context()
- s = SSL.Connection(ctx)
-
+ SSL.Connection(ctx)
+
def test_server_simple(self):
pid = self.start_server(self.args)
try:
- self.assertRaises(ValueError, SSL.Context, 'tlsv5')
+ with self.assertRaises(ValueError):
+ SSL.Context('tlsv5')
ctx = SSL.Context()
s = SSL.Connection(ctx)
s.connect(self.srv_addr)
- self.assertRaises(ValueError, s.read, 0)
+ with self.assertRaises(ValueError):
+ s.read(0)
data = self.http_get(s)
s.close()
finally:
self.stop_server(pid)
- self.failIf(string.find(data, 's_server -quiet -www') == -1)
+ self.assertIn('s_server -quiet -www', data)
def test_server_simple_secure_context(self):
pid = self.start_server(self.args)
try:
ctx = SSL.Context()
- ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, 9)
+ ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert,
+ 9)
ctx.load_verify_locations('tests/ca.pem')
s = SSL.Connection(ctx)
s.connect(self.srv_addr)
@@ -300,62 +340,74 @@ class MiscSSLClientTestCase(BaseSSLClientTestCase):
s.close()
finally:
self.stop_server(pid)
- self.failIf(string.find(data, 's_server -quiet -www') == -1)
+ self.assertIn('s_server -quiet -www', data)
def test_server_simple_secure_context_fail(self):
pid = self.start_server(self.args)
try:
ctx = SSL.Context()
- ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, 9)
+ ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert,
+ 9)
ctx.load_verify_locations('tests/server.pem')
s = SSL.Connection(ctx)
- self.assertRaises(SSL.SSLError, s.connect, self.srv_addr)
+ with self.assertRaises(SSL.SSLError):
+ s.connect(self.srv_addr)
s.close()
finally:
self.stop_server(pid)
def test_server_simple_timeouts(self):
pid = self.start_server(self.args)
+ # Arbitrary value:
+ test_timeout_sec = 909
+ # Linux rounds microseconds in the timeouts up to the HZ kernel parameter.
+ # Windows rounds down to milliseconds.
+ # To avoid checking for rounded values, pick interval long enough
+ # so that it is a whole number of ms and HZ for any reasonable HZ value.
+ test_timeout_microsec = 500000
+
try:
- self.assertRaises(ValueError, SSL.Context, 'tlsv5')
+ with self.assertRaises(ValueError):
+ SSL.Context('tlsv5')
ctx = SSL.Context()
s = SSL.Connection(ctx)
-
+
r = s.get_socket_read_timeout()
w = s.get_socket_write_timeout()
- assert r.sec == 0, r.sec
- assert r.microsec == 0, r.microsec
- assert w.sec == 0, w.sec
- assert w.microsec == 0, w.microsec
+ self.assertEqual(r.sec, 0, r.sec)
+ self.assertEqual(r.microsec, 0, r.microsec)
+ self.assertEqual(w.sec, 0, w.sec)
+ self.assertEqual(w.microsec, 0, w.microsec)
s.set_socket_read_timeout(SSL.timeout())
- s.set_socket_write_timeout(SSL.timeout(909,9))
+ s.set_socket_write_timeout(SSL.timeout(test_timeout_sec, test_timeout_microsec))
r = s.get_socket_read_timeout()
w = s.get_socket_write_timeout()
- assert r.sec == 600, r.sec
- assert r.microsec == 0, r.microsec
- assert w.sec == 909, w.sec
- #assert w.microsec == 9, w.microsec XXX 4000
-
+ self.assertEqual(r.sec, DEFAULT_TIMEOUT, r.sec)
+ self.assertEqual(r.microsec, 0, r.microsec)
+ self.assertEqual(w.sec, test_timeout_sec, w.sec)
+ self.assertEqual(w.microsec, test_timeout_microsec, w.microsec)
+
s.connect(self.srv_addr)
data = self.http_get(s)
s.close()
finally:
self.stop_server(pid)
- self.failIf(string.find(data, 's_server -quiet -www') == -1)
+ self.assertIn('s_server -quiet -www', data)
+ # TLS is required in FIPS mode
+ @unittest.skipIf(fips_mode, "Can't be run in FIPS mode")
def test_tls1_nok(self):
- if fips_mode: # TLS is required in FIPS mode
- return
self.args.append('-no_tls1')
pid = self.start_server(self.args)
try:
- ctx = SSL.Context('tlsv1')
+ with warnings.catch_warnings():
+ warnings.simplefilter('ignore', DeprecationWarning)
+ ctx = SSL.Context('tlsv1')
s = SSL.Connection(ctx)
- try:
+ with six.assertRaisesRegex(self, SSL.SSLError,
+ r'version|unexpected eof'):
s.connect(self.srv_addr)
- except SSL.SSLError, e:
- self.failUnlessEqual(e[0], 'wrong version number')
s.close()
finally:
self.stop_server(pid)
@@ -364,58 +416,16 @@ class MiscSSLClientTestCase(BaseSSLClientTestCase):
self.args.append('-tls1')
pid = self.start_server(self.args)
try:
- ctx = SSL.Context('tlsv1')
+ with warnings.catch_warnings():
+ warnings.simplefilter('ignore', DeprecationWarning)
+ ctx = SSL.Context('tlsv1')
s = SSL.Connection(ctx)
s.connect(self.srv_addr)
data = self.http_get(s)
s.close()
finally:
self.stop_server(pid)
- self.failIf(string.find(data, 's_server -quiet -www') == -1)
-
- def test_sslv23_no_v2(self):
- if fips_mode: # TLS is required in FIPS mode
- return
- self.args.append('-no_tls1')
- pid = self.start_server(self.args)
- try:
- ctx = SSL.Context('sslv23')
- s = SSL.Connection(ctx)
- s.connect(self.srv_addr)
- self.failUnlessEqual(s.get_version(), 'SSLv3')
- s.close()
- finally:
- self.stop_server(pid)
-
- def test_sslv23_no_v2_no_service(self):
- if fips_mode: # TLS is required in FIPS mode
- return
- self.args = self.args + ['-no_tls1', '-no_ssl3']
- pid = self.start_server(self.args)
- try:
- ctx = SSL.Context('sslv23')
- s = SSL.Connection(ctx)
- self.assertRaises(SSL.SSLError, s.connect, self.srv_addr)
- s.close()
- finally:
- self.stop_server(pid)
-
- def test_sslv23_weak_crypto(self):
- if fips_mode: # TLS is required in FIPS mode
- return
- self.args = self.args + ['-no_tls1', '-no_ssl3']
- pid = self.start_server(self.args)
- try:
- ctx = SSL.Context('sslv23', weak_crypto=1)
- s = SSL.Connection(ctx)
- if m2.OPENSSL_VERSION_NUMBER < 0x10000000: # SSLv2 ciphers disabled by default in newer OpenSSL
- s.connect(self.srv_addr)
- self.failUnlessEqual(s.get_version(), 'SSLv2')
- else:
- self.assertRaises(SSL.SSLError, s.connect, self.srv_addr)
- s.close()
- finally:
- self.stop_server(pid)
+ self.assertIn('s_server -quiet -www', data)
def test_cipher_mismatch(self):
self.args = self.args + ['-cipher', 'AES256-SHA']
@@ -424,14 +434,14 @@ class MiscSSLClientTestCase(BaseSSLClientTestCase):
ctx = SSL.Context()
s = SSL.Connection(ctx)
s.set_cipher_list('AES128-SHA')
- try:
- s.connect(self.srv_addr)
- except SSL.SSLError, e:
- self.failUnlessEqual(e[0], 'sslv3 alert handshake failure')
+ if not OPENSSL111:
+ with six.assertRaisesRegex(self, SSL.SSLError,
+ 'sslv3 alert handshake failure'):
+ s.connect(self.srv_addr)
s.close()
finally:
self.stop_server(pid)
-
+
def test_no_such_cipher(self):
self.args = self.args + ['-cipher', 'AES128-SHA']
pid = self.start_server(self.args)
@@ -439,79 +449,64 @@ class MiscSSLClientTestCase(BaseSSLClientTestCase):
ctx = SSL.Context()
s = SSL.Connection(ctx)
s.set_cipher_list('EXP-RC2-MD5')
- try:
- s.connect(self.srv_addr)
- except SSL.SSLError, e:
- self.failUnlessEqual(e[0], 'no ciphers available')
- s.close()
- finally:
- self.stop_server(pid)
-
- def test_no_weak_cipher(self):
- if fips_mode: # Weak ciphers are prohibited
- return
- self.args = self.args + ['-cipher', 'EXP']
- pid = self.start_server(self.args)
- try:
- ctx = SSL.Context()
- s = SSL.Connection(ctx)
- try:
- s.connect(self.srv_addr)
- except SSL.SSLError, e:
- self.failUnlessEqual(e[0], 'sslv3 alert handshake failure')
- s.close()
- finally:
- self.stop_server(pid)
-
- def test_use_weak_cipher(self):
- if fips_mode: # Weak ciphers are prohibited
- return
- self.args = self.args + ['-cipher', 'EXP']
- pid = self.start_server(self.args)
- try:
- ctx = SSL.Context(weak_crypto=1)
- s = SSL.Connection(ctx)
- s.connect(self.srv_addr)
- data = self.http_get(s)
+ if not OPENSSL111:
+ with six.assertRaisesRegex(self, SSL.SSLError,
+ 'no ciphers available'):
+ s.connect(self.srv_addr)
s.close()
finally:
self.stop_server(pid)
- self.failIf(string.find(data, 's_server -quiet -www') == -1)
-
+
def test_cipher_ok(self):
- self.args = self.args + ['-cipher', 'AES128-SHA']
+ if OPENSSL111:
+ TCIPHER = 'TLS_AES_256_GCM_SHA384'
+ self.args = self.args + ['-ciphersuites', TCIPHER]
+ else:
+ TCIPHER = 'AES128-SHA'
+ self.args = self.args + ['-cipher', TCIPHER]
+
pid = self.start_server(self.args)
try:
ctx = SSL.Context()
s = SSL.Connection(ctx)
- s.set_cipher_list('AES128-SHA')
+ s.set_cipher_list(TCIPHER)
s.connect(self.srv_addr)
data = self.http_get(s)
-
- assert s.get_cipher().name() == 'AES128-SHA', s.get_cipher().name()
-
+
+ self.assertEqual(s.get_cipher().name(), TCIPHER,
+ s.get_cipher().name())
+
cipher_stack = s.get_ciphers()
- assert cipher_stack[0].name() == 'AES128-SHA', cipher_stack[0].name()
- self.assertRaises(IndexError, cipher_stack.__getitem__, 2)
+ self.assertEqual(cipher_stack[0].name(), TCIPHER,
+ cipher_stack[0].name())
+
+ if not OPENSSL111:
+ with self.assertRaises(IndexError):
+ cipher_stack.__getitem__(2)
+
# For some reason there are 2 entries in the stack
- #assert len(cipher_stack) == 1, len(cipher_stack)
- assert s.get_cipher_list() == 'AES128-SHA', s.get_cipher_list()
-
+ # self.assertEqual(len(cipher_stack), 1, len(cipher_stack))
+ self.assertEqual(s.get_cipher_list(), TCIPHER,
+ s.get_cipher_list())
+
# Test Cipher_Stack iterator
i = 0
for cipher in cipher_stack:
i += 1
- assert cipher.name() == 'AES128-SHA', '"%s"' % cipher.name()
- self.assertEqual('AES128-SHA-128', str(cipher))
+ if not OPENSSL111:
+ cipname = cipher.name()
+ self.assertEqual(cipname, 'AES128-SHA',
+ '"%s" (%s)' % (cipname, type(cipname)))
+ self.assertEqual('AES128-SHA-128', str(cipher))
# For some reason there are 2 entries in the stack
- #assert i == 1, i
+ # self.assertEqual(i, 1, i)
self.assertEqual(i, len(cipher_stack))
-
+
s.close()
finally:
self.stop_server(pid)
- self.failIf(string.find(data, 's_server -quiet -www') == -1)
-
+ self.assertIn('s_server -quiet -www', data)
+
def verify_cb_new(self, ok, store):
return verify_cb_new_function(ok, store)
@@ -519,115 +514,118 @@ class MiscSSLClientTestCase(BaseSSLClientTestCase):
pid = self.start_server(self.args)
try:
ctx = SSL.Context()
- ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, 9,
- self.verify_cb_new)
+ ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert,
+ 9, self.verify_cb_new)
s = SSL.Connection(ctx)
try:
s.connect(self.srv_addr)
- except SSL.SSLError, e:
- assert 0, e
+ except SSL.SSLError as e:
+ self.fail(e)
data = self.http_get(s)
s.close()
finally:
self.stop_server(pid)
- self.failIf(string.find(data, 's_server -quiet -www') == -1)
+ self.assertIn('s_server -quiet -www', data)
def test_verify_cb_new_class(self):
pid = self.start_server(self.args)
try:
ctx = SSL.Context()
- ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, 9,
- VerifyCB())
+ ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert,
+ 9, VerifyCB())
s = SSL.Connection(ctx)
try:
s.connect(self.srv_addr)
- except SSL.SSLError, e:
- assert 0, e
+ except SSL.SSLError as e:
+ log.exception(e)
+ self.fail(e)
data = self.http_get(s)
s.close()
finally:
self.stop_server(pid)
- self.failIf(string.find(data, 's_server -quiet -www') == -1)
+ self.assertIn('s_server -quiet -www', data)
def test_verify_cb_new_function(self):
pid = self.start_server(self.args)
try:
ctx = SSL.Context()
- ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, 9,
- verify_cb_new_function)
+ ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert,
+ 9, verify_cb_new_function)
s = SSL.Connection(ctx)
try:
s.connect(self.srv_addr)
- except SSL.SSLError, e:
- assert 0, e
+ except SSL.SSLError as e:
+ self.fail(e)
data = self.http_get(s)
s.close()
finally:
self.stop_server(pid)
- self.failIf(string.find(data, 's_server -quiet -www') == -1)
+ self.assertIn('s_server -quiet -www', data)
def test_verify_cb_lambda(self):
pid = self.start_server(self.args)
try:
ctx = SSL.Context()
- ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, 9,
- lambda ok, store: 1)
+ ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert,
+ 9, lambda ok, store: 1)
s = SSL.Connection(ctx)
try:
s.connect(self.srv_addr)
- except SSL.SSLError, e:
- assert 0, e
+ except SSL.SSLError as e:
+ self.fail(e)
data = self.http_get(s)
s.close()
finally:
self.stop_server(pid)
- self.failIf(string.find(data, 's_server -quiet -www') == -1)
+ self.assertIn('s_server -quiet -www', data)
def verify_cb_exception(self, ok, store):
- raise Exception, 'We should fail verification'
+ self.fail('We should fail verification')
def test_verify_cb_exception(self):
pid = self.start_server(self.args)
try:
ctx = SSL.Context()
- ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, 9,
- self.verify_cb_exception)
+ ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert,
+ 9, self.verify_cb_exception)
s = SSL.Connection(ctx)
- self.assertRaises(SSL.SSLError, s.connect, self.srv_addr)
+ with self.assertRaises(SSL.SSLError):
+ s.connect(self.srv_addr)
s.close()
finally:
self.stop_server(pid)
def test_verify_cb_not_callable(self):
ctx = SSL.Context()
- self.assertRaises(TypeError,
- ctx.set_verify,
- SSL.verify_peer | SSL.verify_fail_if_no_peer_cert,
- 9,
- 1)
+ with self.assertRaises(TypeError):
+ ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert,
+ 9, 1)
def test_verify_cb_wrong_callable(self):
pid = self.start_server(self.args)
try:
ctx = SSL.Context()
- ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, 9,
- lambda _: '')
+ ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert,
+ 9, lambda _: '')
s = SSL.Connection(ctx)
- self.assertRaises(SSL.SSLError, s.connect, self.srv_addr)
+ with self.assertRaises(SSL.SSLError):
+ with warnings.catch_warnings():
+ warnings.simplefilter('ignore', DeprecationWarning)
+ s.connect(self.srv_addr)
s.close()
finally:
self.stop_server(pid)
def verify_cb_old(self, ctx_ptr, x509_ptr, err, depth, ok):
try:
- from M2Crypto import X509
- assert not ok
- assert err == m2.X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT or \
- err == m2.X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY or \
- err == m2.X509_V_ERR_CERT_UNTRUSTED or \
- err == m2.X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE
- assert m2.ssl_ctx_get_cert_store(ctx_ptr)
- assert X509.X509(x509_ptr).as_pem()
+ self.assertFalse(ok)
+ self.assertIn(err,
+ [m2.X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT,
+ m2.X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY,
+ m2.X509_V_ERR_CERT_UNTRUSTED,
+ m2.X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE])
+ self.assertTrue(m2.ssl_ctx_get_cert_store(ctx_ptr))
+ self.assertTrue(X509.X509(x509_ptr).as_pem())
except AssertionError:
# If we let exceptions propagate from here the
# caller may see strange errors. This is cleaner.
@@ -635,146 +633,160 @@ class MiscSSLClientTestCase(BaseSSLClientTestCase):
return 1
def test_verify_cb_old(self):
- pid = self.start_server(self.args)
- try:
- ctx = SSL.Context()
- ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, 9,
- self.verify_cb_old)
- s = SSL.Connection(ctx)
+ with warnings.catch_warnings():
+ warnings.simplefilter("ignore", DeprecationWarning)
+ pid = self.start_server(self.args)
try:
- s.connect(self.srv_addr)
- except SSL.SSLError, e:
- assert 0, e
- data = self.http_get(s)
- s.close()
- finally:
- self.stop_server(pid)
- self.failIf(string.find(data, 's_server -quiet -www') == -1)
+ ctx = SSL.Context()
+ ctx.set_verify(
+ SSL.verify_peer | SSL.verify_fail_if_no_peer_cert,
+ 9, self.verify_cb_old)
+ s = SSL.Connection(ctx)
+ try:
+ s.connect(self.srv_addr)
+ except SSL.SSLError as e:
+ self.fail(e)
+ data = self.http_get(s)
+ s.close()
+ finally:
+ self.stop_server(pid)
+ self.assertIn('s_server -quiet -www', data)
def test_verify_allow_unknown_old(self):
pid = self.start_server(self.args)
try:
ctx = SSL.Context()
- ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, 9,
- SSL.cb.ssl_verify_callback)
+ ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert,
+ 9, SSL.cb.ssl_verify_callback_allow_unknown_ca)
ctx.set_allow_unknown_ca(1)
s = SSL.Connection(ctx)
try:
s.connect(self.srv_addr)
- except SSL.SSLError, e:
- assert 0, e
+ except SSL.SSLError:
+ log.error('Failed to connect to %s', self.srv_addr)
+ raise
data = self.http_get(s)
s.close()
finally:
self.stop_server(pid)
- self.failIf(string.find(data, 's_server -quiet -www') == -1)
+ self.assertIn('s_server -quiet -www', data)
def test_verify_allow_unknown_new(self):
pid = self.start_server(self.args)
try:
ctx = SSL.Context()
- ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, 9,
- SSL.cb.ssl_verify_callback_allow_unknown_ca)
+ ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert,
+ 9, SSL.cb.ssl_verify_callback_allow_unknown_ca)
s = SSL.Connection(ctx)
try:
s.connect(self.srv_addr)
- except SSL.SSLError, e:
- assert 0, e
+ except SSL.SSLError as e:
+ self.fail(e)
data = self.http_get(s)
s.close()
finally:
self.stop_server(pid)
- self.failIf(string.find(data, 's_server -quiet -www') == -1)
+ self.assertIn('s_server -quiet -www', data)
def test_verify_cert(self):
pid = self.start_server(self.args)
try:
ctx = SSL.Context()
- ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, 9)
+ ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert,
+ 9)
ctx.load_verify_locations('tests/ca.pem')
s = SSL.Connection(ctx)
try:
s.connect(self.srv_addr)
- except SSL.SSLError, e:
- assert 0, e
+ except SSL.SSLError as e:
+ self.fail(e)
data = self.http_get(s)
s.close()
finally:
self.stop_server(pid)
- self.failIf(string.find(data, 's_server -quiet -www') == -1)
+ self.assertIn('s_server -quiet -www', data)
def test_verify_cert_fail(self):
pid = self.start_server(self.args)
try:
ctx = SSL.Context()
- ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, 9)
+ ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert,
+ 9)
ctx.load_verify_locations('tests/server.pem')
s = SSL.Connection(ctx)
- self.assertRaises(SSL.SSLError, s.connect, self.srv_addr)
+ with self.assertRaises(SSL.SSLError):
+ s.connect(self.srv_addr)
s.close()
finally:
self.stop_server(pid)
def test_verify_cert_mutual_auth(self):
- self.args.extend(['-Verify', '2', '-CAfile', 'ca.pem'])
+ self.args.extend(['-Verify', '2', '-CAfile', 'ca.pem'])
pid = self.start_server(self.args)
try:
ctx = SSL.Context()
- ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, 9)
+ ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert,
+ 9)
ctx.load_verify_locations('tests/ca.pem')
ctx.load_cert('tests/x509.pem')
s = SSL.Connection(ctx)
try:
s.connect(self.srv_addr)
- except SSL.SSLError, e:
- assert 0, e
+ except SSL.SSLError as e:
+ self.fail(e)
data = self.http_get(s)
s.close()
finally:
self.stop_server(pid)
- self.failIf(string.find(data, 's_server -quiet -www') == -1)
+ self.assertIn('s_server -quiet -www', data)
def test_verify_cert_mutual_auth_servernbio(self):
self.args.extend(['-Verify', '2', '-CAfile', 'ca.pem', '-nbio'])
pid = self.start_server(self.args)
try:
ctx = SSL.Context()
- ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, 9)
+ ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert,
+ 9)
ctx.load_verify_locations('tests/ca.pem')
ctx.load_cert('tests/x509.pem')
s = SSL.Connection(ctx)
try:
s.connect(self.srv_addr)
- except SSL.SSLError, e:
- assert 0, e
+ except SSL.SSLError as e:
+ self.fail(e)
data = self.http_get(s)
s.close()
finally:
self.stop_server(pid)
- self.failIf(string.find(data, 's_server -quiet -www') == -1)
+ self.assertIn('s_server -quiet -www', data)
def test_verify_cert_mutual_auth_fail(self):
- self.args.extend(['-Verify', '2', '-CAfile', 'ca.pem'])
+ self.args.extend(['-Verify', '2', '-CAfile', 'ca.pem'])
pid = self.start_server(self.args)
try:
ctx = SSL.Context()
- ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, 9)
+ ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert,
+ 9)
ctx.load_verify_locations('tests/ca.pem')
s = SSL.Connection(ctx)
- self.assertRaises(SSL.SSLError, s.connect, self.srv_addr)
+ if not OPENSSL111:
+ with self.assertRaises(SSL.SSLError):
+ s.connect(self.srv_addr)
s.close()
finally:
self.stop_server(pid)
def test_verify_nocert_fail(self):
- self.args.extend(['-nocert'])
+ self.args.extend(['-nocert'])
pid = self.start_server(self.args)
try:
ctx = SSL.Context()
- ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, 9)
+ ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert,
+ 9)
ctx.load_verify_locations('tests/ca.pem')
s = SSL.Connection(ctx)
- self.assertRaises(SSL.SSLError, s.connect, self.srv_addr)
+ with self.assertRaises(SSL.SSLError):
+ s.connect(self.srv_addr)
s.close()
finally:
self.stop_server(pid)
@@ -785,7 +797,8 @@ class MiscSSLClientTestCase(BaseSSLClientTestCase):
ctx = SSL.Context()
s = SSL.Connection(ctx)
s.setblocking(0)
- self.assertRaises(Exception, s.connect, self.srv_addr)
+ with self.assertRaises(Exception):
+ s.connect(self.srv_addr)
s.close()
finally:
self.stop_server(pid)
@@ -798,13 +811,13 @@ class MiscSSLClientTestCase(BaseSSLClientTestCase):
s.setblocking(1)
try:
s.connect(self.srv_addr)
- except SSL.SSLError, e:
- assert 0, e
+ except SSL.SSLError as e:
+ self.fail(e)
data = self.http_get(s)
s.close()
finally:
self.stop_server(pid)
- self.failIf(string.find(data, 's_server -quiet -www') == -1)
+ self.assertIn('s_server -quiet -www', data)
def test_makefile(self):
pid = self.start_server(self.args)
@@ -813,18 +826,18 @@ class MiscSSLClientTestCase(BaseSSLClientTestCase):
s = SSL.Connection(ctx)
try:
s.connect(self.srv_addr)
- except SSL.SSLError, e:
- assert 0, e
- bio = s.makefile('rw')
- #s.close() # XXX bug 6628?
- bio.write('GET / HTTP/1.0\n\n')
+ except SSL.SSLError as e:
+ self.fail(e)
+ bio = s.makefile('rwb')
+ # s.close() # XXX bug 6628?
+ bio.write(b'GET / HTTP/1.0\n\n')
bio.flush()
data = bio.read()
bio.close()
s.close()
finally:
self.stop_server(pid)
- self.failIf(string.find(data, 's_server -quiet -www') == -1)
+ self.assertIn(b's_server -quiet -www', data)
def test_makefile_err(self):
pid = self.start_server(self.args)
@@ -833,20 +846,21 @@ class MiscSSLClientTestCase(BaseSSLClientTestCase):
s = SSL.Connection(ctx)
try:
s.connect(self.srv_addr)
- except SSL.SSLError, e:
- assert 0, e
+ except SSL.SSLError as e:
+ self.fail(e)
f = s.makefile()
data = self.http_get(s)
s.close()
del f
del s
err_code = Err.peek_error_code()
- assert not err_code, 'Unexpected error: %s' % err_code
+ self.assertEqual(err_code, 0,
+ 'Unexpected error: %s' % err_code)
err = Err.get_error()
- assert not err, 'Unexpected error: %s' % err
+ self.assertIsNone(err, 'Unexpected error: %s' % err)
finally:
self.stop_server(pid)
- self.failIf(string.find(data, 's_server -quiet -www') == -1)
+ self.assertIn('s_server -quiet -www', data)
def test_info_callback(self):
pid = self.start_server(self.args)
@@ -859,118 +873,260 @@ class MiscSSLClientTestCase(BaseSSLClientTestCase):
s.close()
finally:
self.stop_server(pid)
- self.failIf(string.find(data, 's_server -quiet -www') == -1)
+ self.assertIn('s_server -quiet -www', data)
+
+ def test_ssl_connection_free(self):
+ pid = self.start_server(self.args)
+ orig_m2_ssl_free = SSL.Connection.m2_ssl_free
+ def _m2_ssl_free(ssl):
+ orig_m2_ssl_free(ssl)
+ _m2_ssl_free.called = True
+
+ try:
+ ctx = SSL.Context()
+ s = SSL.Connection(ctx)
+ s.m2_ssl_free = _m2_ssl_free
+ s.connect(self.srv_addr)
+ data = self.http_get(s)
+ s.close()
+ self.assertFalse(hasattr(_m2_ssl_free, 'called'))
+ # keep fingers crossed that SSL.Connection.__del__ is called
+ # by the python interpreter
+ del s
+ finally:
+ self.stop_server(pid)
+ self.assertIn('s_server -quiet -www', data)
+ self.assertTrue(getattr(_m2_ssl_free, 'called', False))
+
+ def test_ssl_connection_no_free(self):
+ pid = self.start_server(self.args)
+ orig_m2_ssl_free = SSL.Connection.m2_ssl_free
+ def _m2_ssl_free(ssl):
+ _m2_ssl_free.called = True
+ orig_m2_ssl_free(ssl)
+
+ try:
+ ctx = SSL.Context()
+ s = SSL.Connection(ctx)
+ s.m2_ssl_free = _m2_ssl_free
+ s.set_ssl_close_flag(m2.bio_close)
+ s.connect(self.srv_addr)
+ data = self.http_get(s)
+ s.close()
+ self.assertFalse(hasattr(_m2_ssl_free, 'called'))
+ # keep fingers crossed that SSL.Connection.__del__ is called
+ # by the python interpreter
+ del s
+ finally:
+ self.stop_server(pid)
+ self.assertIn('s_server -quiet -www', data)
+ self.assertFalse(hasattr(_m2_ssl_free, 'called'))
class UrllibSSLClientTestCase(BaseSSLClientTestCase):
+ @unittest.skipIf(six.PY3, "urllib.URLOpener is deprecated in py3k")
def test_urllib(self):
pid = self.start_server(self.args)
try:
- from M2Crypto import m2urllib
url = m2urllib.FancyURLopener()
url.addheader('Connection', 'close')
- u = url.open('https://%s:%s/' % (srv_host, srv_port))
+ u = url.open('https://%s:%s/' % (srv_host, self.srv_port))
data = u.read()
u.close()
finally:
self.stop_server(pid)
- self.failIf(string.find(data, 's_server -quiet -www') == -1)
+ self.assertIn('s_server -quiet -www', data)
# XXX Don't actually know how to use m2urllib safely!
- #def test_urllib_secure_context(self):
- #def test_urllib_secure_context_fail(self):
-
- # XXX Don't actually know how to use m2urllib safely!
- #def test_urllib_safe_context(self):
- #def test_urllib_safe_context_fail(self):
+ # def test_urllib_safe_context(self):
+ # def test_urllib_safe_context_fail(self):
class Urllib2SSLClientTestCase(BaseSSLClientTestCase):
- if sys.version_info >= (2,4):
- def test_urllib2(self):
- pid = self.start_server(self.args)
- try:
- from M2Crypto import m2urllib2
- opener = m2urllib2.build_opener()
- opener.addheaders = [('Connection', 'close')]
- u = opener.open('https://%s:%s/' % (srv_host, srv_port))
- data = u.read()
- u.close()
- finally:
- self.stop_server(pid)
- self.failIf(string.find(data, 's_server -quiet -www') == -1)
-
- def test_urllib2_secure_context(self):
- pid = self.start_server(self.args)
- try:
- ctx = SSL.Context()
- ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, 9)
- ctx.load_verify_locations('tests/ca.pem')
-
- from M2Crypto import m2urllib2
- opener = m2urllib2.build_opener(ctx)
- opener.addheaders = [('Connection', 'close')]
- u = opener.open('https://%s:%s/' % (srv_host, srv_port))
- data = u.read()
- u.close()
- finally:
- self.stop_server(pid)
- self.failIf(string.find(data, 's_server -quiet -www') == -1)
-
- def test_urllib2_secure_context_fail(self):
- pid = self.start_server(self.args)
- try:
- ctx = SSL.Context()
- ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, 9)
- ctx.load_verify_locations('tests/server.pem')
-
- from M2Crypto import m2urllib2
- opener = m2urllib2.build_opener(ctx)
- opener.addheaders = [('Connection', 'close')]
- self.assertRaises(SSL.SSLError, opener.open, 'https://%s:%s/' % (srv_host, srv_port))
- finally:
- self.stop_server(pid)
+ def test_urllib2(self):
+ pid = self.start_server(self.args)
+ try:
+ opener = m2urllib2.build_opener()
+ opener.addheaders = [('Connection', 'close')]
+ u = opener.open('https://%s:%s/' % (srv_host, self.srv_port))
+ data = u.read()
+ u.close()
+ finally:
+ self.stop_server(pid)
+ self.assertIn(b's_server -quiet -www', data)
- def test_z_urllib2_opener(self):
- pid = self.start_server(self.args)
- try:
- ctx = SSL.Context()
+ def test_urllib2_secure_context(self):
+ pid = self.start_server(self.args)
+ try:
+ ctx = SSL.Context()
+ ctx.set_verify(
+ SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, 9)
+ ctx.load_verify_locations('tests/ca.pem')
+
+ opener = m2urllib2.build_opener(ctx)
+ opener.addheaders = [('Connection', 'close')]
+ u = opener.open('https://%s:%s/' % (srv_host, self.srv_port))
+ data = u.read()
+ u.close()
+ finally:
+ self.stop_server(pid)
+ self.assertIn(b's_server -quiet -www', data)
+
+ def test_urllib2_secure_context_fail(self):
+ pid = self.start_server(self.args)
+ try:
+ ctx = SSL.Context()
+ ctx.set_verify(
+ SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, 9)
+ ctx.load_verify_locations('tests/server.pem')
+
+ opener = m2urllib2.build_opener(ctx)
+ opener.addheaders = [('Connection', 'close')]
+ with self.assertRaises(SSL.SSLError):
+ opener.open('https://%s:%s/' % (srv_host, self.srv_port))
+ finally:
+ self.stop_server(pid)
+
+ def test_z_urllib2_opener(self):
+ pid = self.start_server(self.args)
+ try:
+ ctx = SSL.Context()
+
+ opener = m2urllib2.build_opener(
+ ctx, m2urllib2.HTTPBasicAuthHandler())
+ m2urllib2.install_opener(opener)
+ req = m2urllib2.Request('https://%s:%s/' %
+ (srv_host, self.srv_port))
+ u = m2urllib2.urlopen(req)
+ data = u.read()
+ u.close()
+ finally:
+ self.stop_server(pid)
+ self.assertIn(b's_server -quiet -www', data)
+
+ def test_urllib2_opener_handlers(self):
+ ctx = SSL.Context()
+
+ m2urllib2.build_opener(ctx, m2urllib2.HTTPBasicAuthHandler())
+
+ def test_urllib2_leak(self):
+ pid = self.start_server(self.args)
+ try:
+ o = m2urllib2.build_opener()
+ r = o.open('https://%s:%s/' % (srv_host, self.srv_port))
+ s = [r.fp._sock.fp]
+ r.close()
+ # TODO This should be assertEqual 1, but we leak sock
+ # somehwere. Not sure how to fix it.
+ log.debug('get_referrers = %d', len(gc.get_referrers(s[0])))
+ self.assertLessEqual(len(gc.get_referrers(s[0])), 2)
+ finally:
+ self.stop_server(pid)
+
+
+class Urllib2TEChunkedSSLClientTestCase(BaseSSLClientTestCase):
+ """Test a response with "Transfer-Encoding: chunked"."""
+
+ def setUp(self):
+ super(Urllib2TEChunkedSSLClientTestCase, self).setUp()
+ self.args = ['s_server', '-quiet', '-HTTP',
+ '-accept', str(self.srv_port)]
+
+ def test_transfer_encoding_chunked(self):
+ pid = self.start_server(self.args)
+ try:
+ url = 'https://%s:%s/te_chunked_response.txt' % (srv_host,
+ self.srv_port)
+ o = m2urllib2.build_opener()
+ u = o.open(url)
+ data = u.read()
+ self.assertEqual(b'foo\nfoobar\n', data)
+ finally:
+ self.stop_server(pid)
- from M2Crypto import m2urllib2
- opener = m2urllib2.build_opener(ctx, m2urllib2.HTTPBasicAuthHandler())
- m2urllib2.install_opener(opener)
- req = m2urllib2.Request('https://%s:%s/' % (srv_host, srv_port))
- u = m2urllib2.urlopen(req)
- data = u.read()
- u.close()
- finally:
- self.stop_server(pid)
- self.failIf(string.find(data, 's_server -quiet -www') == -1)
- def test_urllib2_opener_handlers(self):
+@unittest.skipUnless(py27plus,
+ "Twisted doesn't test well with Python 2.6")
+class TwistedSSLClientTestCase(BaseSSLClientTestCase):
+
+ def test_timeout(self):
+ pid = self.start_server(self.args)
+ try:
ctx = SSL.Context()
+ s = SSL.Connection(ctx)
+ # Just a really small number so we can timeout
+ s.settimeout(0.000000000000000000000000000001)
+
+ # TODO: Figure out which exception should be raised for timeout.
+ # The following assertion originally expected only a
+ # SSL.SSLTimeoutError exception, but what is raised is actually a
+ # socket.timeout exception. As a temporary circumvention to this
+ # issue, both exceptions are now tolerated. A final fix would need
+ # to figure out which of these two exceptions is supposed to be
+ # raised by SSL.Connection.connect() and possibly other methods
+ # to indicate a timeout.
+ with self.assertRaises((SSL.SSLTimeoutError, socket.timeout)):
+ s.connect(self.srv_addr)
- from M2Crypto import m2urllib2
- opener = m2urllib2.build_opener(ctx,
- m2urllib2.HTTPBasicAuthHandler())
+ s.close()
+ finally:
+ self.stop_server(pid)
- def test_urllib2_leak(self):
+ def test_makefile_timeout(self):
+ # httpslib uses makefile to read the response
+ pid = self.start_server(self.args)
+ try:
+ c = httpslib.HTTPSConnection(srv_host, self.srv_port)
+ c.putrequest('GET', '/')
+ c.putheader('Accept', 'text/html')
+ c.putheader('Accept', 'text/plain')
+ c.endheaders()
+ c.sock.settimeout(100)
+ resp = c.getresponse()
+ self.assertEqual(resp.status, 200, resp.reason)
+ data = resp.read()
+ c.close()
+ finally:
+ self.stop_server(pid)
+ self.assertIn(b's_server -quiet -www', data)
+
+ def test_makefile_timeout_fires(self):
+ # This is convoluted because (openssl s_server -www) starts
+ # writing the response as soon as it receives the first line of
+ # the request, so it's possible for it to send the response
+ # before the request is sent and there would be no timeout. So,
+ # let the server spend time reading from an empty pipe
+ FIFO_NAME = 'test_makefile_timeout_fires_fifo' # noqa
+ os.mkfifo('tests/' + FIFO_NAME)
+ pipe_pid = os.fork()
+ try:
+ if pipe_pid == 0:
+ try:
+ with open('tests/' + FIFO_NAME, 'w') as f:
+ time.sleep(sleepTime + 1)
+ f.write('Content\n')
+ finally:
+ os._exit(0)
+ self.args[self.args.index('-www')] = '-WWW'
pid = self.start_server(self.args)
try:
- import gc
- from M2Crypto import m2urllib2
- o = m2urllib2.build_opener()
- r = o.open('https://%s:%s/' % (srv_host, srv_port))
- s = [r.fp._sock.fp]
- r.close()
- self.assertEqual(len(gc.get_referrers(s[0])), 1)
+ c = httpslib.HTTPSConnection(srv_host, self.srv_port)
+ c.putrequest('GET', '/' + FIFO_NAME)
+ c.putheader('Accept', 'text/html')
+ c.putheader('Accept', 'text/plain')
+ c.endheaders()
+ c.sock.settimeout(0.0000000001)
+ with self.assertRaises(socket.timeout):
+ c.getresponse()
+ c.close()
finally:
self.stop_server(pid)
-
-
-class TwistedSSLClientTestCase(BaseSSLClientTestCase):
+ finally:
+ os.kill(pipe_pid, signal.SIGTERM)
+ os.waitpid(pipe_pid, 0)
+ os.unlink('tests/' + FIFO_NAME)
def test_twisted_wrapper(self):
# Test only when twisted and ZopeInterfaces are present
@@ -980,13 +1136,14 @@ class TwistedSSLClientTestCase(BaseSSLClientTestCase):
from twisted.internet import reactor
import M2Crypto.SSL.TwistedProtocolWrapper as wrapper
except ImportError:
- import warnings
- warnings.warn('Skipping twisted wrapper test because twisted not found')
+ warnings.warn(
+ 'Skipping twisted wrapper test because twisted not found')
return
-
+
+ # TODO Class must implement all abstract methods
class EchoClient(LineReceiver):
def connectionMade(self):
- self.sendLine('GET / HTTP/1.0\n\n')
+ self.sendLine(b'GET / HTTP/1.0\n\n')
def lineReceived(self, line):
global twisted_data
@@ -994,31 +1151,33 @@ class TwistedSSLClientTestCase(BaseSSLClientTestCase):
class EchoClientFactory(ClientFactory):
protocol = EchoClient
-
+
def clientConnectionFailed(self, connector, reason):
reactor.stop()
- assert 0, reason
-
+ self.fail(reason)
+
def clientConnectionLost(self, connector, reason):
reactor.stop()
-
+
pid = self.start_server(self.args)
- class ContextFactory:
+ class ContextFactory(object):
def getContext(self):
return SSL.Context()
try:
global twisted_data
- twisted_data = ''
-
- contextFactory = ContextFactory()
+ twisted_data = b''
+
+ context_factory = ContextFactory()
factory = EchoClientFactory()
- wrapper.connectSSL(srv_host, srv_port, factory, contextFactory)
- reactor.run() # This will block until reactor.stop() is called
+ wrapper.connectSSL(srv_host, self.srv_port, factory,
+ context_factory)
+ # This will block until reactor.stop() is called
+ reactor.run()
finally:
self.stop_server(pid)
- self.failIf(string.find(twisted_data, 's_server -quiet -www') == -1)
+ self.assertIn(b's_server -quiet -www', twisted_data)
twisted_data = ''
@@ -1026,29 +1185,28 @@ twisted_data = ''
class XmlRpcLibTestCase(unittest.TestCase):
def test_lib(self):
- from M2Crypto import m2xmlrpclib
m2xmlrpclib.SSL_Transport()
# XXX need server to test against
class FtpsLibTestCase(unittest.TestCase):
def test_lib(self):
- from M2Crypto import ftpslib
ftpslib.FTP_TLS()
# XXX need server to test against
class SessionTestCase(unittest.TestCase):
def test_session_load_bad(self):
- self.assertRaises(SSL.SSLError, SSL.Session.load_session,
- 'tests/signer.pem')
+ with self.assertRaises(SSL.SSLError):
+ SSL.Session.load_session('tests/signer.pem')
+
class FtpslibTestCase(unittest.TestCase):
def test_26_compat(self):
- from M2Crypto import ftpslib
f = ftpslib.FTP_TLS()
# 2.6 used to raise AttributeError:
- self.assertRaises(socket.gaierror, f.connect, 'no-such-host-dfgHJK56789', 990)
+ with self.assertRaises((socket.gaierror, socket.error,)):
+ f.connect('no-such-host-dfgHJK56789', 990)
def suite():
@@ -1058,51 +1216,52 @@ def suite():
suite.addTest(unittest.makeSuite(FtpsLibTestCase))
suite.addTest(unittest.makeSuite(PassSSLClientTestCase))
suite.addTest(unittest.makeSuite(HttpslibSSLClientTestCase))
+ suite.addTest(unittest.makeSuite(HttpslibSSLSNIClientTestCase))
suite.addTest(unittest.makeSuite(UrllibSSLClientTestCase))
suite.addTest(unittest.makeSuite(Urllib2SSLClientTestCase))
+ suite.addTest(unittest.makeSuite(Urllib2TEChunkedSSLClientTestCase))
suite.addTest(unittest.makeSuite(MiscSSLClientTestCase))
suite.addTest(unittest.makeSuite(FtpslibTestCase))
try:
- import M2Crypto.SSL.TwistedProtocolWrapper as wrapper
- suite.addTest(unittest.makeSuite(TwistedSSLClientTestCase))
+ if py27plus:
+ import M2Crypto.SSL.TwistedProtocolWrapper as wrapper # noqa
+ suite.addTest(unittest.makeSuite(TwistedSSLClientTestCase))
except ImportError:
pass
- return suite
-
+ return suite
+
def zap_servers():
s = 's_server'
- fn = tempfile.mktemp()
+ fn = tempfile.mktemp()
cmd = 'ps | egrep %s > %s' % (s, fn)
os.system(cmd)
- f = open(fn)
- while 1:
- ps = f.readline()
- if not ps:
- break
- chunk = string.split(ps)
- pid, cmd = chunk[0], chunk[4]
- if cmd == s:
- os.kill(int(pid), 1)
- f.close()
+ with open(fn) as f:
+ while 1:
+ ps = f.readline()
+ if not ps:
+ break
+ chunk = ps.split()
+ pid, cmd = chunk[0], chunk[4]
+ if cmd == s:
+ os.kill(int(pid), signal.SIGTERM)
os.unlink(fn)
if __name__ == '__main__':
report_leaks = 0
-
+
if report_leaks:
- import gc
gc.enable()
gc.set_debug(gc.DEBUG_LEAK & ~gc.DEBUG_SAVEALL)
-
+
try:
- Rand.load_file('randpool.dat', -1)
+ Rand.load_file('randpool.dat', -1)
unittest.TextTestRunner().run(suite())
Rand.save_file('randpool.dat')
finally:
zap_servers()
if report_leaks:
- import alltests
+ from tests import alltests
alltests.dump_garbage()
diff --git a/tests/test_ssl_offline.py b/tests/test_ssl_offline.py
index ba77434..3ffc1f1 100644
--- a/tests/test_ssl_offline.py
+++ b/tests/test_ssl_offline.py
@@ -1,3 +1,5 @@
+from __future__ import absolute_import
+
"""Unit tests for M2Crypto.SSL offline parts
Copyright (C) 2006 Open Source Applications Foundation. All Rights Reserved.
@@ -5,37 +7,45 @@ Copyright (C) 2006 Open Source Applications Foundation. All Rights Reserved.
Copyright (C) 2009-2010 Heikki Toivonen. All Rights Reserved.
"""
-import unittest, doctest
-from M2Crypto.SSL import Checker
-from M2Crypto import X509
-from M2Crypto import SSL
-from test_ssl import srv_host
+import doctest
+
+from M2Crypto import Rand, SSL, X509
+from tests import unittest
+from tests.test_ssl import srv_host
class CheckerTestCase(unittest.TestCase):
def test_checker(self):
- check = Checker.Checker(host=srv_host,
- peerCertHash='7B754EFA41A264AAD370D43460BC8229F9354ECE')
+ check = SSL.Checker.Checker(
+ host=srv_host,
+ peerCertHash='0305E329FF3C9F1931B8DD3F0CF9F8E350E29839')
x509 = X509.load_cert('tests/server.pem')
- assert check(x509, srv_host)
- self.assertRaises(Checker.WrongHost, check, x509, 'example.com')
-
- doctest.testmod(Checker)
+ self.assertTrue(check(x509, srv_host))
+ with self.assertRaises(SSL.Checker.WrongHost):
+ check(x509, 'example.com')
+
+ doctest.testmod(SSL.Checker)
+
-
class ContextTestCase(unittest.TestCase):
def test_ctx_load_verify_locations(self):
ctx = SSL.Context()
- self.assertRaises(ValueError, ctx.load_verify_locations, None, None)
-
+ with self.assertRaises(ValueError):
+ ctx.load_verify_locations(None, None)
+
+ def test_ctx_set_default_verify_paths(self):
+ ctx = SSL.Context()
+ ctx.set_default_verify_paths()
+ # test will get here only if the previous won't fail
+
def test_map(self):
- from M2Crypto.SSL.Context import map, _ctxmap
- assert isinstance(map(), _ctxmap)
+ from M2Crypto.SSL.Context import ctxmap, _ctxmap
+ self.assertIsInstance(ctxmap(), _ctxmap)
ctx = SSL.Context()
- assert map()
+ assert ctxmap()
ctx.close()
- assert map() is _ctxmap.singleton
+ self.assertIs(ctxmap(), _ctxmap.singleton)
def test_certstore(self):
ctx = SSL.Context()
@@ -44,14 +54,14 @@ class ContextTestCase(unittest.TestCase):
ctx.load_cert('tests/x509.pem')
store = ctx.get_cert_store()
- assert isinstance(store, X509.X509_Store)
+ self.assertIsInstance(store, X509.X509_Store)
def suite():
- suite = unittest.TestSuite()
- suite.addTest(unittest.makeSuite(CheckerTestCase))
- suite.addTest(unittest.makeSuite(ContextTestCase))
- return suite
+ t_suite = unittest.TestSuite()
+ t_suite.addTest(unittest.makeSuite(CheckerTestCase))
+ t_suite.addTest(unittest.makeSuite(ContextTestCase))
+ return t_suite
if __name__ == '__main__':
diff --git a/tests/test_ssl_win.py b/tests/test_ssl_win.py
index 0d13bd0..027c457 100644
--- a/tests/test_ssl_win.py
+++ b/tests/test_ssl_win.py
@@ -1,70 +1,73 @@
#!/usr/bin/env python
+from __future__ import absolute_import
-"""Unit tests for M2Crypto.SSL.
+"""Unit tests for M2Crypto.SSL.
-Win32 version - requires Mark Hammond's Win32 extensions and openssl.exe
+Win32 version - requires Mark Hammond's Win32 extensions and openssl.exe
on your PATH.
Copyright (c) 2000-2001 Ng Pheng Siong. All rights reserved."""
-import os, os.path, string, time, unittest
+import os
+import os.path
+import time
+
try:
import win32process
except ImportError:
win32process = None
+from tests import test_ssl, unittest
+
if win32process:
- from M2Crypto import Rand, SSL
- import test_ssl
-
+ from M2Crypto import Rand
+
def find_openssl():
plist = os.environ['PATH'].split(';')
for p in plist:
try:
- dir = os.listdir(p)
- if 'openssl.exe' in dir:
+ path_dir = os.listdir(p)
+ if 'openssl.exe' in path_dir:
return os.path.join(p, 'openssl.exe')
- except WindowsError:
+ except win32process.WindowsError:
pass
return None
-
-
+
srv_host = 'localhost'
srv_port = 64000
-
- class SSLWinClientTestCase(test_ssl.SSLClientTestCase):
-
+
+ class SSLWinClientTestCase(test_ssl.BaseSSLClientTestCase):
+
startupinfo = win32process.STARTUPINFO()
openssl = find_openssl()
-
+
def start_server(self, args):
# openssl must be started in the tests directory for it
# to find the .pem files
- os.chdir('tests')
+ os.chdir('tests')
try:
- hproc, hthread, pid, tid = win32process.CreateProcess(self.openssl,
- string.join(args), None, None, 0, win32process.DETACHED_PROCESS,
- None, None, self.startupinfo)
+ hproc, _, _, _ = win32process.CreateProcess(
+ self.openssl, ' '.join(args), None, None, 0,
+ win32process.DETACHED_PROCESS, None, None,
+ self.startupinfo)
finally:
- os.chdir('..')
+ os.chdir('..')
time.sleep(0.3)
return hproc
-
+
def stop_server(self, hproc):
win32process.TerminateProcess(hproc, 0)
-
-
+
def suite():
return unittest.makeSuite(SSLWinClientTestCase)
-
+
def zap_servers():
pass
-
-
+
if __name__ == '__main__':
try:
if find_openssl() is not None:
- Rand.load_file('randpool.dat', -1)
+ Rand.load_file('randpool.dat', -1)
unittest.TextTestRunner().run(suite())
Rand.save_file('randpool.dat')
finally:
diff --git a/tests/test_threading.py b/tests/test_threading.py
index 7912a61..ad1d111 100644
--- a/tests/test_threading.py
+++ b/tests/test_threading.py
@@ -4,9 +4,8 @@
Copyright (C) 2007 Open Source Applications Foundation. All Rights Reserved.
"""
-
-import unittest
from M2Crypto import threading as m2threading, Rand
+from tests import unittest
class ThreadingTestCase(unittest.TestCase):
diff --git a/tests/test_timeout.py b/tests/test_timeout.py
new file mode 100644
index 0000000..6d05449
--- /dev/null
+++ b/tests/test_timeout.py
@@ -0,0 +1,135 @@
+#!/usr/bin/env python
+
+"""Unit tests for M2Crypto.SSL.timeout.
+"""
+
+import sys
+from M2Crypto.SSL import timeout, struct_to_timeout, struct_size
+from tests import unittest
+
+# Max value for sec argument on Windows:
+# - needs to fit DWORD (signed 32-bit) when converted to millisec
+MAX_SEC_WIN32 = int((2**31 - 1) / 1000)
+
+# Max value for sec argument on other platforms:
+# Note: It may actually be 64-bit but we are happy with 32-bit.
+# We use the signed maximum, because the packing uses lower case "l".
+MAX_SEC_OTHER = 2**31 - 1
+
+# Enable this to test the Windows logic on a non-Windows platform:
+# sys.platform = 'win32'
+
+
+class TimeoutTestCase(unittest.TestCase):
+
+ def timeout_test(self, sec, microsec, exp_sec=None, exp_microsec=None):
+ """
+ Test that the timeout values (sec, microsec) are the same after
+ round tripping through a pack / unpack cycle.
+ """
+ if exp_sec is None:
+ exp_sec = sec
+ if exp_microsec is None:
+ exp_microsec = microsec
+
+ to = timeout(sec, microsec)
+
+ binstr = to.pack()
+
+ act_to = struct_to_timeout(binstr)
+
+ self.assertEqual(
+ (act_to.sec, act_to.microsec), (exp_sec, exp_microsec),
+ "Unexpected timeout(sec,microsec) after pack + unpack: "
+ "Got (%r,%r), expected (%r,%r), input was (%r,%r)" %
+ (act_to.sec, act_to.microsec, exp_sec, exp_microsec,
+ sec, microsec))
+
+ def test_timeout_0_0(self):
+ self.timeout_test(0, 0)
+
+ def test_timeout_123_0(self):
+ self.timeout_test(123, 0)
+
+ def test_timeout_max_0(self):
+ if sys.platform == 'win32':
+ self.timeout_test(MAX_SEC_WIN32, 0)
+ else:
+ self.timeout_test(MAX_SEC_OTHER, 0)
+
+ def test_timeout_0_456000(self):
+ self.timeout_test(0, 456000)
+
+ def test_timeout_123_456000(self):
+ self.timeout_test(123, 456000)
+
+ def test_timeout_2_3000000(self):
+ if sys.platform == 'win32':
+ self.timeout_test(2, 3000000, 5, 0)
+ else:
+ self.timeout_test(2, 3000000)
+
+ def test_timeout_2_2499000(self):
+ if sys.platform == 'win32':
+ self.timeout_test(2, 2499000, 4, 499000)
+ else:
+ self.timeout_test(2, 2499000)
+
+ def test_timeout_2_2999000(self):
+ if sys.platform == 'win32':
+ self.timeout_test(2, 2999000, 4, 999000)
+ else:
+ self.timeout_test(2, 2999000)
+
+ def test_timeout_max_456000(self):
+ if sys.platform == 'win32':
+ self.timeout_test(MAX_SEC_WIN32, 456000)
+ else:
+ self.timeout_test(MAX_SEC_OTHER, 456000)
+
+ def test_timeout_0_456(self):
+ if sys.platform == 'win32':
+ self.timeout_test(0, 456, None, 0)
+ else:
+ self.timeout_test(0, 456)
+
+ def test_timeout_123_456(self):
+ if sys.platform == 'win32':
+ self.timeout_test(123, 456, None, 0)
+ else:
+ self.timeout_test(123, 456)
+
+ def test_timeout_max_456(self):
+ if sys.platform == 'win32':
+ self.timeout_test(MAX_SEC_WIN32, 456, None, 0)
+ else:
+ self.timeout_test(MAX_SEC_OTHER, 456)
+
+ def test_timeout_1_499(self):
+ if sys.platform == 'win32':
+ self.timeout_test(123, 499, None, 0) # 499 us rounds down to 0
+ else:
+ self.timeout_test(123, 499)
+
+ def test_timeout_1_501(self):
+ # We use 501 for this test and not 500 because 0.5 is not exactly
+ # represented in binary floating point numbers, and because 0.5
+ # rounds differently between py2 and py3. See Python round() docs.
+ if sys.platform == 'win32':
+ self.timeout_test(123, 501, None, 1000) # 501 us rounds up to 1000
+ else:
+ self.timeout_test(123, 501)
+
+ def test_timeout_size(self):
+ exp_size = len(timeout(0, 0).pack())
+ self.assertEqual(struct_size(), exp_size)
+
+
+def suite():
+ suite = unittest.TestSuite()
+ suite.addTest(unittest.makeSuite(TimeoutTestCase))
+ return suite
+
+
+if __name__ == '__main__':
+ unittest.TextTestRunner().run(suite())
diff --git a/tests/test_util.py b/tests/test_util.py
new file mode 100644
index 0000000..f4c758e
--- /dev/null
+++ b/tests/test_util.py
@@ -0,0 +1,48 @@
+#!/usr/bin/env python
+
+"""Unit tests for M2Crypto.Rand.
+
+Copyright (C) 2006 Open Source Applications Foundation (OSAF).
+All Rights Reserved.
+"""
+
+from M2Crypto import six
+from tests import unittest
+
+
+class UtilTestCase(unittest.TestCase):
+ def test_py3bytes(self):
+ self.assertIsInstance(six.ensure_binary('test'), six.binary_type)
+
+ def test_py3str(self):
+ self.assertIsInstance(six.ensure_text('test'), six.text_type)
+
+ def test_py3bytes_str(self):
+ self.assertIsInstance(six.ensure_binary(u'test'), six.binary_type)
+
+ def test_py3str_str(self):
+ self.assertIsInstance(six.ensure_text(u'test'), six.string_types)
+
+ def test_py3bytes_bytes(self):
+ self.assertIsInstance(six.ensure_binary(b'test'), six.binary_type)
+
+ def test_py3str_bytes(self):
+ self.assertIsInstance(six.ensure_text(b'test'), six.text_type)
+
+ def test_py3bytes_None(self):
+ with self.assertRaises(TypeError):
+ six.ensure_binary(None)
+
+ def test_py3str_None(self):
+ with self.assertRaises(TypeError):
+ six.ensure_text(None)
+
+
+def suite():
+ suite = unittest.TestSuite()
+ suite.addTest(unittest.makeSuite(UtilTestCase))
+ return suite
+
+
+if __name__ == '__main__':
+ unittest.TextTestRunner().run(suite())
diff --git a/tests/test_x509.py b/tests/test_x509.py
index 7ea86df..057d7da 100644
--- a/tests/test_x509.py
+++ b/tests/test_x509.py
@@ -9,143 +9,203 @@ Copyright (C) 2004-2005 OSAF. All Rights Reserved.
Author: Heikki Toivonen
"""
-import unittest
-import os, time, base64, sys
-from M2Crypto import X509, EVP, RSA, Rand, ASN1, m2, util, BIO
+import base64
+import logging
+import os
+import time
+import warnings
+
+from M2Crypto import ASN1, BIO, EVP, RSA, Rand, X509, m2 # noqa
+from tests import unittest
+
+log = logging.getLogger(__name__)
+
class X509TestCase(unittest.TestCase):
def callback(self, *args):
pass
+ def setUp(self):
+ self.expected_hash = 'BA4212E8B55527570828E7F5A0005D17C64BDC4C'
+
def mkreq(self, bits, ca=0):
pk = EVP.PKey()
x = X509.Request()
rsa = RSA.gen_key(bits, 65537, self.callback)
pk.assign_rsa(rsa)
- rsa = None # should not be freed here
+ rsa = None # should not be freed here
x.set_pubkey(pk)
name = x.get_subject()
name.C = "UK"
name.CN = "OpenSSL Group"
if not ca:
- ext1 = X509.new_extension('subjectAltName', 'DNS:foobar.example.com')
+ ext1 = X509.new_extension('subjectAltName',
+ 'DNS:foobar.example.com')
ext2 = X509.new_extension('nsComment', 'Hello there')
extstack = X509.X509_Extension_Stack()
extstack.push(ext1)
extstack.push(ext2)
x.add_extensions(extstack)
- self.assertRaises(ValueError, x.sign, pk, 'sha513')
- x.sign(pk,'sha1')
- assert x.verify(pk)
+
+ with self.assertRaises(ValueError):
+ x.sign(pk, 'sha513')
+
+ x.sign(pk, 'sha1')
+ self.assertTrue(x.verify(pk))
pk2 = x.get_pubkey()
- assert x.verify(pk2)
+ self.assertTrue(x.verify(pk2))
return x, pk
def test_ext(self):
- self.assertRaises(ValueError, X509.new_extension,
- 'subjectKeyIdentifier', 'hash')
+ with self.assertRaises(ValueError):
+ X509.new_extension('subjectKeyIdentifier', 'hash')
+
ext = X509.new_extension('subjectAltName', 'DNS:foobar.example.com')
- assert ext.get_value() == 'DNS:foobar.example.com'
- assert ext.get_value(indent=2) == ' DNS:foobar.example.com'
- assert ext.get_value(flag=m2.X509V3_EXT_PARSE_UNKNOWN) == 'DNS:foobar.example.com'
+ self.assertEqual(ext.get_value(), 'DNS:foobar.example.com')
+ self.assertEqual(ext.get_value(indent=2),
+ ' DNS:foobar.example.com')
+ self.assertEqual(ext.get_value(flag=m2.X509V3_EXT_PARSE_UNKNOWN),
+ 'DNS:foobar.example.com')
+
+ def test_ext_error(self):
+ with self.assertRaises(X509.X509Error):
+ X509.new_extension('nonsensicalName', 'blabla')
def test_extstack(self):
# new
ext1 = X509.new_extension('subjectAltName', 'DNS:foobar.example.com')
ext2 = X509.new_extension('nsComment', 'Hello there')
extstack = X509.X509_Extension_Stack()
-
+
# push
extstack.push(ext1)
extstack.push(ext2)
- assert(extstack[1].get_name() == 'nsComment')
- assert len(extstack) == 2
-
+ self.assertEqual(extstack[1].get_name(), 'nsComment')
+ self.assertEqual(len(extstack), 2)
+
# iterator
i = 0
for e in extstack:
i += 1
- assert len(e.get_name()) > 0
- assert i == 2
-
+ self.assertGreater(len(e.get_name()), 0)
+ self.assertEqual(i, 2)
+
# pop
ext3 = extstack.pop()
- assert len(extstack) == 1
- assert(extstack[0].get_name() == 'subjectAltName')
+ self.assertEqual(len(extstack), 1)
+ self.assertEqual(extstack[0].get_name(), 'subjectAltName')
extstack.push(ext3)
- assert len(extstack) == 2
- assert(extstack[1].get_name() == 'nsComment')
-
- assert extstack.pop() is not None
- assert extstack.pop() is not None
- assert extstack.pop() is None
+ self.assertEqual(len(extstack), 2)
+ self.assertEqual(extstack[1].get_name(), 'nsComment')
+
+ self.assertIsNotNone(extstack.pop())
+ self.assertIsNotNone(extstack.pop())
+ self.assertIsNone(extstack.pop())
def test_x509_name(self):
n = X509.X509_Name()
- n.C = 'US' # It seems this actually needs to be a real 2 letter country code
- assert n.C == 'US'
+ # It seems this actually needs to be a real 2 letter country code
+ n.C = 'US'
+ self.assertEqual(n.C, 'US')
n.SP = 'State or Province'
- assert n.SP == 'State or Province'
+ self.assertEqual(n.SP, 'State or Province')
n.L = 'locality name'
- assert n.L == 'locality name'
+ self.assertEqual(n.L, 'locality name')
+ # Yes, 'orhanization' is a typo, I know it and you're smart.
+ # However, fixing this typo would break later hashes.
+ # I don't think it is worthy of troubles.
n.O = 'orhanization name'
- assert n.O == 'orhanization name'
+ self.assertEqual(n.O, 'orhanization name')
n.OU = 'org unit'
- assert n.OU == 'org unit'
+ self.assertEqual(n.OU, 'org unit')
n.CN = 'common name'
- assert n.CN == 'common name'
+ self.assertEqual(n.CN, 'common name')
n.Email = 'bob@example.com'
- assert n.Email == 'bob@example.com'
+ self.assertEqual(n.Email, 'bob@example.com')
n.serialNumber = '1234'
- assert n.serialNumber == '1234'
+ self.assertEqual(n.serialNumber, '1234')
n.SN = 'surname'
- assert n.SN == 'surname'
+ self.assertEqual(n.SN, 'surname')
n.GN = 'given name'
- assert n.GN == 'given name'
- assert n.as_text() == 'C=US, ST=State or Province, L=locality name, O=orhanization name, OU=org unit, CN=common name/emailAddress=bob@example.com/serialNumber=1234, SN=surname, GN=given name', '"%s"' % n.as_text()
- assert len(n) == 10, len(n)
+ self.assertEqual(n.GN, 'given name')
+ self.assertEqual(n.as_text(),
+ 'C=US, ST=State or Province, ' +
+ 'L=locality name, O=orhanization name, ' +
+ 'OU=org unit, CN=common ' +
+ 'name/emailAddress=bob@example.com' +
+ '/serialNumber=1234, ' +
+ 'SN=surname, GN=given name')
+ self.assertEqual(len(n), 10,
+ 'X509_Name has inappropriate length %d ' % len(n))
n.givenName = 'name given'
- assert n.GN == 'given name' # Just gets the first
- assert n.as_text() == 'C=US, ST=State or Province, L=locality name, O=orhanization name, OU=org unit, CN=common name/emailAddress=bob@example.com/serialNumber=1234, SN=surname, GN=given name, GN=name given', '"%s"' % n.as_text()
- assert len(n) == 11, len(n)
+ self.assertEqual(n.GN, 'given name') # Just gets the first
+ self.assertEqual(n.as_text(), 'C=US, ST=State or Province, ' +
+ 'L=locality name, O=orhanization name, ' +
+ 'OU=org unit, ' +
+ 'CN=common name/emailAddress=bob@example.com' +
+ '/serialNumber=1234, ' +
+ 'SN=surname, GN=given name, GN=name given')
+ self.assertEqual(len(n), 11,
+ 'After adding one more attribute X509_Name should ' +
+ 'have 11 and not %d attributes.' % len(n))
n.add_entry_by_txt(field="CN", type=ASN1.MBSTRING_ASC,
entry="Proxy", len=-1, loc=-1, set=0)
- assert len(n) == 12, len(n)
- assert n.entry_count() == 12, n.entry_count()
- assert n.as_text() == 'C=US, ST=State or Province, L=locality name, O=orhanization name, OU=org unit, CN=common name/emailAddress=bob@example.com/serialNumber=1234, SN=surname, GN=given name, GN=name given, CN=Proxy', '"%s"' % n.as_text()
-
- self.assertRaises(AttributeError, n.__getattr__, 'foobar')
+ self.assertEqual(len(n), 12,
+ 'After adding one more attribute X509_Name should ' +
+ 'have 12 and not %d attributes.' % len(n))
+ self.assertEqual(n.entry_count(), 12, n.entry_count())
+ self.assertEqual(n.as_text(), 'C=US, ST=State or Province, ' +
+ 'L=locality name, O=orhanization name, ' +
+ 'OU=org unit, ' +
+ 'CN=common name/emailAddress=bob@example.com' +
+ '/serialNumber=1234, ' +
+ 'SN=surname, GN=given name, GN=name given, ' +
+ 'CN=Proxy')
+
+ with self.assertRaises(AttributeError):
+ n.__getattr__('foobar')
n.foobar = 1
- assert n.foobar == 1, n.foobar
-
+ self.assertEqual(n.foobar, 1)
+
# X509_Name_Entry tests
l = 0
for entry in n:
- assert isinstance(entry, X509.X509_Name_Entry), entry
- assert isinstance(entry.get_object(), ASN1.ASN1_Object), entry
- assert isinstance(entry.get_data(), ASN1.ASN1_String), entry
+ self.assertIsInstance(entry, X509.X509_Name_Entry)
+ self.assertIsInstance(entry.get_object(), ASN1.ASN1_Object)
+ self.assertIsInstance(entry.get_data(), ASN1.ASN1_String)
l += 1
- assert l == 12, l
-
+ self.assertEqual(l, 12, l)
+
l = 0
for cn in n.get_entries_by_nid(m2.NID_commonName):
- assert isinstance(cn, X509.X509_Name_Entry), cn
- assert isinstance(cn.get_object(), ASN1.ASN1_Object), cn
+ self.assertIsInstance(cn, X509.X509_Name_Entry)
+ self.assertIsInstance(cn.get_object(), ASN1.ASN1_Object)
data = cn.get_data()
- assert isinstance(data, ASN1.ASN1_String), data
+ self.assertIsInstance(data, ASN1.ASN1_String)
t = data.as_text()
- assert t == "common name" or t == "Proxy", t
+ self.assertIn(t, ("common name", "Proxy",))
l += 1
- assert l == 2, l
+ self.assertEqual(l, 2,
+ 'X509_Name has %d commonName entries instead '
+ 'of expected 2' % l)
+
+ # The target list is not deleted when the loop is finished
+ # https://docs.python.org/2.7/reference\
+ # /compound_stmts.html#the-for-statement
+ # so this checks what are the attributes of the last value of
+ # ``cn`` variable.
+ cn.set_data(b"Hello There!")
+ self.assertEqual(cn.get_data().as_text(), "Hello There!")
+
+ # OpenSSL 1.0.1h switched from encoding strings as PRINTABLESTRING (the
+ # first hash value) to UTF8STRING (the second one)
+ self.assertIn(n.as_hash(), (1697185131, 1370641112),
+ 'Unexpected value of the X509_Name hash %s' %
+ n.as_hash())
- cn.set_data("Hello There!")
- assert cn.get_data().as_text() == "Hello There!", cn.get_data().as_text()
-
- assert n.as_hash() == 1697185131
-
self.assertRaises(IndexError, lambda: n[100])
- self.assert_(n[10])
+ self.assertIsNotNone(n[10])
def test_mkreq(self):
(req, _) = self.mkreq(1024)
@@ -157,78 +217,97 @@ class X509TestCase(unittest.TestCase):
os.remove('tests/tmp_request.pem')
req.save('tests/tmp_request.der', format=X509.FORMAT_DER)
req4 = X509.load_request('tests/tmp_request.der',
- format=X509.FORMAT_DER)
+ format=X509.FORMAT_DER)
os.remove('tests/tmp_request.der')
- assert req.as_pem() == req2.as_pem()
- assert req.as_text() == req2.as_text()
- assert req.as_der() == req2.as_der()
- assert req.as_pem() == req3.as_pem()
- assert req.as_text() == req3.as_text()
- assert req.as_der() == req3.as_der()
- assert req.as_pem() == req4.as_pem()
- assert req.as_text() == req4.as_text()
- assert req.as_der() == req4.as_der()
+ self.assertEqual(req.as_pem(), req2.as_pem())
+ self.assertEqual(req.as_text(), req2.as_text())
+ self.assertEqual(req.as_der(), req2.as_der())
+ self.assertEqual(req.as_pem(), req3.as_pem())
+ self.assertEqual(req.as_text(), req3.as_text())
+ self.assertEqual(req.as_der(), req3.as_der())
+ self.assertEqual(req.as_pem(), req4.as_pem())
+ self.assertEqual(req.as_text(), req4.as_text())
+ self.assertEqual(req.as_der(), req4.as_der())
self.assertEqual(req.get_version(), 0)
req.set_version(1)
self.assertEqual(req.get_version(), 1)
req.set_version(0)
self.assertEqual(req.get_version(), 0)
-
def test_mkcert(self):
- req, pk = self.mkreq(1024)
- pkey = req.get_pubkey()
- assert(req.verify(pkey))
- sub = req.get_subject()
- assert len(sub) == 2, len(sub)
- cert = X509.X509()
- cert.set_serial_number(1)
- cert.set_version(2)
- cert.set_subject(sub)
- t = long(time.time()) + time.timezone
- now = ASN1.ASN1_UTCTIME()
- now.set_time(t)
- nowPlusYear = ASN1.ASN1_UTCTIME()
- nowPlusYear.set_time(t + 60 * 60 * 24 * 365)
- cert.set_not_before(now)
- cert.set_not_after(nowPlusYear)
- assert str(cert.get_not_before()) == str(now)
- assert str(cert.get_not_after()) == str(nowPlusYear)
- issuer = X509.X509_Name()
- issuer.CN = 'The Issuer Monkey'
- issuer.O = 'The Organization Otherwise Known as My CA, Inc.'
- cert.set_issuer(issuer)
- cert.set_pubkey(pkey)
- cert.set_pubkey(cert.get_pubkey()) # Make sure get/set work
- ext = X509.new_extension('subjectAltName', 'DNS:foobar.example.com')
- ext.set_critical(0)
- assert ext.get_critical() == 0
- cert.add_ext(ext)
- cert.sign(pk, 'sha1')
- self.assertRaises(ValueError, cert.sign, pk, 'nosuchalgo')
- assert(cert.get_ext('subjectAltName').get_name() == 'subjectAltName')
- assert(cert.get_ext_at(0).get_name() == 'subjectAltName')
- assert(cert.get_ext_at(0).get_value() == 'DNS:foobar.example.com')
- assert cert.get_ext_count() == 1, cert.get_ext_count()
- self.assertRaises(IndexError, cert.get_ext_at, 1)
- assert cert.verify()
- assert cert.verify(pkey)
- assert cert.verify(cert.get_pubkey())
- assert cert.get_version() == 2
- assert cert.get_serial_number() == 1
- assert cert.get_issuer().CN == 'The Issuer Monkey'
-
- if m2.OPENSSL_VERSION_NUMBER >= 0x90800f:
- assert not cert.check_ca()
- assert not cert.check_purpose(m2.X509_PURPOSE_SSL_SERVER, 1)
- assert not cert.check_purpose(m2.X509_PURPOSE_NS_SSL_SERVER, 1)
- assert cert.check_purpose(m2.X509_PURPOSE_SSL_SERVER, 0)
- assert cert.check_purpose(m2.X509_PURPOSE_NS_SSL_SERVER, 0)
- assert cert.check_purpose(m2.X509_PURPOSE_ANY, 0)
- else:
- self.assertRaises(AttributeError, cert.check_ca)
-
- def mkcacert(self):
+ for utc in (True, False):
+ req, pk = self.mkreq(1024)
+ pkey = req.get_pubkey()
+ self.assertTrue(req.verify(pkey))
+ sub = req.get_subject()
+ self.assertEqual(len(sub), 2,
+ 'Subject should be long 2 items not %d' % len(sub))
+
+ cert = X509.X509()
+ cert.set_serial_number(1)
+ cert.set_version(2)
+ cert.set_subject(sub)
+ t = int(time.time()) + time.timezone
+ if utc:
+ now = ASN1.ASN1_UTCTIME()
+ else:
+ now = ASN1.ASN1_TIME()
+ now.set_time(t)
+ now_plus_year = ASN1.ASN1_TIME()
+ now_plus_year.set_time(t + 60 * 60 * 24 * 365)
+ cert.set_not_before(now)
+ cert.set_not_after(now_plus_year)
+ self.assertEqual(str(cert.get_not_before()), str(now))
+ self.assertEqual(str(cert.get_not_after()), str(now_plus_year))
+
+ issuer = X509.X509_Name()
+ issuer.CN = 'The Issuer Monkey'
+ issuer.O = 'The Organization Otherwise Known as My CA, Inc.'
+ cert.set_issuer(issuer)
+ cert.set_pubkey(pkey)
+ cert.set_pubkey(cert.get_pubkey()) # Make sure get/set work
+
+ ext = X509.new_extension('subjectAltName', 'DNS:foobar.example.com')
+ ext.set_critical(0)
+ self.assertEqual(ext.get_critical(), 0)
+ cert.add_ext(ext)
+
+ cert.sign(pk, 'sha1')
+ with self.assertRaises(ValueError):
+ cert.sign(pk, 'nosuchalgo')
+
+ self.assertTrue(cert.get_ext('subjectAltName').get_name(),
+ 'subjectAltName')
+ self.assertTrue(cert.get_ext_at(0).get_name(),
+ 'subjectAltName')
+ self.assertTrue(cert.get_ext_at(0).get_value(),
+ 'DNS:foobar.example.com')
+ self.assertEqual(cert.get_ext_count(), 1,
+ 'Certificate should have now 1 extension not %d' %
+ cert.get_ext_count())
+ with self.assertRaises(IndexError):
+ cert.get_ext_at(1)
+ self.assertTrue(cert.verify())
+ self.assertTrue(cert.verify(pkey))
+ self.assertTrue(cert.verify(cert.get_pubkey()))
+ self.assertEqual(cert.get_version(), 2)
+ self.assertEqual(cert.get_serial_number(), 1)
+ self.assertEqual(cert.get_issuer().CN, 'The Issuer Monkey')
+
+ if m2.OPENSSL_VERSION_NUMBER >= 0x90800f:
+ self.assertFalse(cert.check_ca())
+ self.assertFalse(cert.check_purpose(m2.X509_PURPOSE_SSL_SERVER, 1))
+ self.assertFalse(cert.check_purpose(m2.X509_PURPOSE_NS_SSL_SERVER,
+ 1))
+ self.assertTrue(cert.check_purpose(m2.X509_PURPOSE_SSL_SERVER, 0))
+ self.assertTrue(cert.check_purpose(m2.X509_PURPOSE_NS_SSL_SERVER,
+ 0))
+ self.assertTrue(cert.check_purpose(m2.X509_PURPOSE_ANY, 0))
+ else:
+ with self.assertRaises(AttributeError):
+ cert.check_ca()
+
+ def mkcacert(self, utc):
req, pk = self.mkreq(1024, ca=1)
pkey = req.get_pubkey()
sub = req.get_subject()
@@ -236,87 +315,111 @@ class X509TestCase(unittest.TestCase):
cert.set_serial_number(1)
cert.set_version(2)
cert.set_subject(sub)
- t = long(time.time()) + time.timezone
- now = ASN1.ASN1_UTCTIME()
+ t = int(time.time()) + time.timezone
+ if utc:
+ now = ASN1.ASN1_UTCTIME()
+ else:
+ now = ASN1.ASN1_TIME()
now.set_time(t)
- nowPlusYear = ASN1.ASN1_UTCTIME()
- nowPlusYear.set_time(t + 60 * 60 * 24 * 365)
+ now_plus_year = ASN1.ASN1_TIME()
+ now_plus_year.set_time(t + 60 * 60 * 24 * 365)
cert.set_not_before(now)
- cert.set_not_after(nowPlusYear)
+ cert.set_not_after(now_plus_year)
issuer = X509.X509_Name()
issuer.C = "UK"
issuer.CN = "OpenSSL Group"
cert.set_issuer(issuer)
- cert.set_pubkey(pkey)
+ cert.set_pubkey(pkey)
ext = X509.new_extension('basicConstraints', 'CA:TRUE')
cert.add_ext(ext)
cert.sign(pk, 'sha1')
- if m2.OPENSSL_VERSION_NUMBER >= 0x0090800fL:
- assert cert.check_ca()
- assert cert.check_purpose(m2.X509_PURPOSE_SSL_SERVER, 1)
- assert cert.check_purpose(m2.X509_PURPOSE_NS_SSL_SERVER, 1)
- assert cert.check_purpose(m2.X509_PURPOSE_ANY, 1)
- assert cert.check_purpose(m2.X509_PURPOSE_SSL_SERVER, 0)
- assert cert.check_purpose(m2.X509_PURPOSE_NS_SSL_SERVER, 0)
- assert cert.check_purpose(m2.X509_PURPOSE_ANY, 0)
+ if m2.OPENSSL_VERSION_NUMBER >= 0x0090800f:
+ self.assertTrue(cert.check_ca())
+ self.assertTrue(cert.check_purpose(m2.X509_PURPOSE_SSL_SERVER,
+ 1))
+ self.assertTrue(cert.check_purpose(m2.X509_PURPOSE_NS_SSL_SERVER,
+ 1))
+ self.assertTrue(cert.check_purpose(m2.X509_PURPOSE_ANY, 1))
+ self.assertTrue(cert.check_purpose(m2.X509_PURPOSE_SSL_SERVER,
+ 0))
+ self.assertTrue(cert.check_purpose(m2.X509_PURPOSE_NS_SSL_SERVER,
+ 0))
+ self.assertTrue(cert.check_purpose(m2.X509_PURPOSE_ANY, 0))
else:
- self.assertRaises(AttributeError, cert.check_ca)
-
+ with self.assertRaises(AttributeError):
+ cert.check_ca()
+
return cert, pk, pkey
- def test_mkcacert(self):
- cacert, pk, pkey = self.mkcacert()
- assert cacert.verify(pkey)
-
-
- def test_mkproxycert(self):
- cacert, pk1, pkey = self.mkcacert()
- end_entity_cert_req, pk2 = self.mkreq(1024)
- end_entity_cert = self.make_eecert(cacert)
- end_entity_cert.set_subject(end_entity_cert_req.get_subject())
- end_entity_cert.set_pubkey(end_entity_cert_req.get_pubkey())
- end_entity_cert.sign(pk1, 'sha1')
- proxycert = self.make_proxycert(end_entity_cert)
- proxycert.sign(pk2, 'sha1')
- assert proxycert.verify(pk2)
- assert proxycert.get_ext_at(0).get_name() == 'proxyCertInfo', proxycert.get_ext_at(0).get_name()
- assert proxycert.get_ext_at(0).get_value() == 'Path Length Constraint: infinite\nPolicy Language: Inherit all\n', '"%s"' % proxycert.get_ext_at(0).get_value()
- assert proxycert.get_ext_count() == 1, proxycert.get_ext_count()
- assert proxycert.get_subject().as_text() == 'C=UK, CN=OpenSSL Group, CN=Proxy', proxycert.get_subject().as_text()
- assert proxycert.get_subject().as_text(indent=2, flags=m2.XN_FLAG_RFC2253) == ' CN=Proxy,CN=OpenSSL Group,C=UK', '"%s"' % proxycert.get_subject().as_text(indent=2, flags=m2.XN_FLAG_RFC2253)
-
- def make_eecert(self, cacert):
+ def test_mkcacert(self):
+ for utc in (True, False):
+ cacert, _, pkey = self.mkcacert(utc)
+ self.assertTrue(cacert.verify(pkey))
+
+ def test_mkproxycert(self):
+ for utc in (True, False):
+ cacert, pk1, _ = self.mkcacert(utc)
+ end_entity_cert_req, pk2 = self.mkreq(1024)
+ end_entity_cert = self.make_eecert(cacert, utc)
+ end_entity_cert.set_subject(end_entity_cert_req.get_subject())
+ end_entity_cert.set_pubkey(end_entity_cert_req.get_pubkey())
+ end_entity_cert.sign(pk1, 'sha1')
+ proxycert = self.make_proxycert(end_entity_cert, utc)
+ proxycert.sign(pk2, 'sha1')
+ self.assertTrue(proxycert.verify(pk2))
+ self.assertEqual(proxycert.get_ext_at(0).get_name(),
+ 'proxyCertInfo')
+ self.assertEqual(proxycert.get_ext_at(0).get_value(),
+ 'Path Length Constraint: infinite\n' +
+ 'Policy Language: Inherit all\n')
+ self.assertEqual(proxycert.get_ext_count(), 1,
+ proxycert.get_ext_count())
+ self.assertEqual(proxycert.get_subject().as_text(),
+ 'C=UK, CN=OpenSSL Group, CN=Proxy')
+ self.assertEqual(
+ proxycert.get_subject().as_text(indent=2,
+ flags=m2.XN_FLAG_RFC2253),
+ ' CN=Proxy,CN=OpenSSL Group,C=UK')
+
+ @staticmethod
+ def make_eecert(cacert, utc):
eecert = X509.X509()
eecert.set_serial_number(2)
eecert.set_version(2)
- t = long(time.time()) + time.timezone
- now = ASN1.ASN1_UTCTIME()
+ t = int(time.time()) + time.timezone
+ if utc:
+ now = ASN1.ASN1_UTCTIME()
+ else:
+ now = ASN1.ASN1_TIME()
now.set_time(t)
- now_plus_year = ASN1.ASN1_UTCTIME()
+ now_plus_year = ASN1.ASN1_TIME()
now_plus_year.set_time(t + 60 * 60 * 24 * 365)
eecert.set_not_before(now)
eecert.set_not_after(now_plus_year)
eecert.set_issuer(cacert.get_subject())
return eecert
-
- def make_proxycert(self, eecert):
+
+ def make_proxycert(self, eecert, utc):
proxycert = X509.X509()
pk2 = EVP.PKey()
- proxykey = RSA.gen_key(1024, 65537, self.callback)
+ proxykey = RSA.gen_key(1024, 65537, self.callback)
pk2.assign_rsa(proxykey)
proxycert.set_pubkey(pk2)
proxycert.set_version(2)
- not_before = ASN1.ASN1_UTCTIME()
- not_after = ASN1.ASN1_UTCTIME()
+ if utc:
+ not_before = ASN1.ASN1_UTCTIME()
+ not_after = ASN1.ASN1_UTCTIME()
+ else:
+ not_before = ASN1.ASN1_TIME()
+ not_after = ASN1.ASN1_TIME()
not_before.set_time(int(time.time()))
offset = 12 * 3600
- not_after.set_time(int(time.time()) + offset )
+ not_after.set_time(int(time.time()) + offset)
proxycert.set_not_before(not_before)
proxycert.set_not_after(not_after)
proxycert.set_issuer_name(eecert.get_subject())
proxycert.set_serial_number(12345678)
- proxy_subject_name = X509.X509_Name()
issuer_name_string = eecert.get_subject().as_text()
seq = issuer_name_string.split(",")
@@ -330,153 +433,197 @@ class X509TestCase(unittest.TestCase):
subject_name.add_entry_by_txt(field="CN", type=ASN1.MBSTRING_ASC,
entry="Proxy", len=-1, loc=-1, set=0)
-
proxycert.set_subject_name(subject_name)
- pci_ext = X509.new_extension("proxyCertInfo",
- "critical,language:Inherit all", 1) # XXX leaks 8 bytes
+ # XXX leaks 8 bytes
+ pci_ext = X509.new_extension("proxyCertInfo",
+ "critical,language:Inherit all", 1)
proxycert.add_ext(pci_ext)
return proxycert
-
+
def test_fingerprint(self):
x509 = X509.load_cert('tests/x509.pem')
fp = x509.get_fingerprint('sha1')
- expected = '8D2EB9E203B5FFDC7F4FA7DC4103E852A55B808D'
- assert fp == expected, '%s != %s' % (fp, expected)
+ self.assertEqual(fp, self.expected_hash)
def test_load_der_string(self):
- f = open('tests/x509.der', 'rb')
- x509 = X509.load_cert_der_string(''.join(f.readlines()))
+ with open('tests/x509.der', 'rb') as f:
+ x509 = X509.load_cert_der_string(f.read())
+
fp = x509.get_fingerprint('sha1')
- expected = '8D2EB9E203B5FFDC7F4FA7DC4103E852A55B808D'
- assert fp == expected, '%s != %s' % (fp, expected)
+ self.assertEqual(fp, self.expected_hash)
def test_save_der_string(self):
x509 = X509.load_cert('tests/x509.pem')
s = x509.as_der()
- f = open('tests/x509.der', 'rb')
- s2 = f.read()
- f.close()
- assert s == s2
+ with open('tests/x509.der', 'rb') as f:
+ s2 = f.read()
+
+ self.assertEqual(s, s2)
def test_load(self):
x509 = X509.load_cert('tests/x509.pem')
x5092 = X509.load_cert('tests/x509.der', format=X509.FORMAT_DER)
- assert x509.as_text() == x5092.as_text()
- assert x509.as_pem() == x5092.as_pem()
- assert x509.as_der() == x5092.as_der()
+ self.assertEqual(x509.as_text(), x5092.as_text())
+ self.assertEqual(x509.as_pem(), x5092.as_pem())
+ self.assertEqual(x509.as_der(), x5092.as_der())
return
-
+
def test_load_bio(self):
- bio = BIO.openfile('tests/x509.pem')
- bio2 = BIO.openfile('tests/x509.der')
- x509 = X509.load_cert_bio(bio)
- x5092 = X509.load_cert_bio(bio2, format=X509.FORMAT_DER)
-
- self.assertRaises(ValueError, X509.load_cert_bio, bio2, format=45678)
-
- assert x509.as_text() == x5092.as_text()
- assert x509.as_pem() == x5092.as_pem()
- assert x509.as_der() == x5092.as_der()
- return
+ with BIO.openfile('tests/x509.pem') as bio:
+ with BIO.openfile('tests/x509.der') as bio2:
+ x509 = X509.load_cert_bio(bio)
+ x5092 = X509.load_cert_bio(bio2, format=X509.FORMAT_DER)
+
+ with self.assertRaises(ValueError):
+ X509.load_cert_bio(bio2, format=45678)
+
+ self.assertEqual(x509.as_text(), x5092.as_text())
+ self.assertEqual(x509.as_pem(), x5092.as_pem())
+ self.assertEqual(x509.as_der(), x5092.as_der())
def test_load_string(self):
- f = open('tests/x509.pem')
- s = f.read()
- f.close()
- f2 = open('tests/x509.der', 'rb')
- s2 = f2.read()
- f2.close()
+ with open('tests/x509.pem') as f:
+ s = f.read()
+
+ with open('tests/x509.der', 'rb') as f2:
+ s2 = f2.read()
+
x509 = X509.load_cert_string(s)
x5092 = X509.load_cert_string(s2, X509.FORMAT_DER)
- assert x509.as_text() == x5092.as_text()
- assert x509.as_pem() == x5092.as_pem()
- assert x509.as_der() == x5092.as_der()
- return
-
+ self.assertEqual(x509.as_text(), x5092.as_text())
+ self.assertEqual(x509.as_pem(), x5092.as_pem())
+ self.assertEqual(x509.as_der(), x5092.as_der())
+
def test_load_request_bio(self):
- (req, _) = self.mkreq(512)
+ (req, _) = self.mkreq(1024)
r1 = X509.load_request_der_string(req.as_der())
r2 = X509.load_request_string(req.as_der(), X509.FORMAT_DER)
r3 = X509.load_request_string(req.as_pem(), X509.FORMAT_PEM)
- r4 = X509.load_request_bio(BIO.MemoryBuffer(req.as_der()), X509.FORMAT_DER)
- r5 = X509.load_request_bio(BIO.MemoryBuffer(req.as_pem()), X509.FORMAT_PEM)
+ r4 = X509.load_request_bio(BIO.MemoryBuffer(req.as_der()),
+ X509.FORMAT_DER)
+ r5 = X509.load_request_bio(BIO.MemoryBuffer(req.as_pem()),
+ X509.FORMAT_PEM)
for r in [r1, r2, r3, r4, r5]:
- assert req.as_der() == r.as_der()
+ self.assertEqual(req.as_der(), r.as_der())
- self.assertRaises(ValueError, X509.load_request_bio, BIO.MemoryBuffer(req.as_pem()), 345678)
+ with self.assertRaises(ValueError):
+ X509.load_request_bio(BIO.MemoryBuffer(req.as_pem()), 345678)
def test_save(self):
x509 = X509.load_cert('tests/x509.pem')
- f = open('tests/x509.pem', 'r')
- lTmp = f.readlines()
- x509_pem = ''.join(lTmp[44:60]) # -----BEGIN CERTIFICATE----- : -----END CERTIFICATE-----
- f.close()
- f = open('tests/x509.der', 'rb')
- x509_der = f.read()
- f.close()
+ with open('tests/x509.pem', 'r') as f:
+ l_tmp = f.readlines()
+ # -----BEGIN CERTIFICATE----- : -----END CERTIFICATE-----
+ beg_idx = l_tmp.index('-----BEGIN CERTIFICATE-----\n')
+ end_idx = l_tmp.index('-----END CERTIFICATE-----\n')
+ x509_pem = ''.join(l_tmp[beg_idx:end_idx + 1])
+
+ with open('tests/x509.der', 'rb') as f:
+ x509_der = f.read()
+
x509.save('tests/tmpcert.pem')
- f = open('tests/tmpcert.pem')
- s = f.read()
- f.close()
- self.assertEquals(s, x509_pem)
+ with open('tests/tmpcert.pem') as f:
+ s = f.read()
+
+ self.assertEqual(s, x509_pem)
os.remove('tests/tmpcert.pem')
x509.save('tests/tmpcert.der', format=X509.FORMAT_DER)
- f = open('tests/tmpcert.der', 'rb')
- s = f.read()
- f.close()
- self.assertEquals(s, x509_der)
+ with open('tests/tmpcert.der', 'rb') as f:
+ s = f.read()
+
+ self.assertEqual(s, x509_der)
os.remove('tests/tmpcert.der')
def test_malformed_data(self):
- self.assertRaises(X509.X509Error, X509.load_cert_string, 'Hello')
- self.assertRaises(X509.X509Error, X509.load_cert_der_string, 'Hello')
- self.assertRaises(X509.X509Error, X509.new_stack_from_der, 'Hello')
- self.assertRaises(X509.X509Error, X509.load_cert, 'tests/alltests.py')
- self.assertRaises(X509.X509Error, X509.load_request, 'tests/alltests.py')
- self.assertRaises(X509.X509Error, X509.load_request_string, 'Hello')
- self.assertRaises(X509.X509Error, X509.load_request_der_string, 'Hello')
- self.assertRaises(X509.X509Error, X509.load_crl, 'tests/alltests.py')
-
+ try:
+ with self.assertRaises(X509.X509Error):
+ X509.load_cert_string('Hello')
+ with self.assertRaises(X509.X509Error):
+ X509.load_cert_der_string('Hello')
+ with self.assertRaises(X509.X509Error):
+ X509.new_stack_from_der(b'Hello')
+ with self.assertRaises(X509.X509Error):
+ X509.load_cert('tests/alltests.py')
+ with self.assertRaises(X509.X509Error):
+ X509.load_request('tests/alltests.py')
+ with self.assertRaises(X509.X509Error):
+ X509.load_request_string('Hello')
+ with self.assertRaises(X509.X509Error):
+ X509.load_request_der_string('Hello')
+ with self.assertRaises(X509.X509Error):
+ X509.load_crl('tests/alltests.py')
+ except SystemError:
+ pass
+
def test_long_serial(self):
- from M2Crypto import X509
cert = X509.load_cert('tests/long_serial_cert.pem')
- self.assertEquals(cert.get_serial_number(), 17616841808974579194)
+ self.assertEqual(cert.get_serial_number(), 17616841808974579194)
cert = X509.load_cert('tests/thawte.pem')
- self.assertEquals(cert.get_serial_number(), 127614157056681299805556476275995414779)
+ self.assertEqual(cert.get_serial_number(),
+ 127614157056681299805556476275995414779)
+
+ def test_set_long_serial(self):
+ cert = X509.X509()
+ cert.set_serial_number(127614157056681299805556476275995414779)
+ self.assertEqual(cert.get_serial_number(),
+ 127614157056681299805556476275995414779)
+
+ def test_date_after_2050_working(self):
+ cert = X509.load_cert('tests/bad_date_cert.crt')
+ self.assertEqual(str(cert.get_not_after()), 'Feb 9 14:57:46 2116 GMT')
+
+ def test_easy_rsa_generated(self):
+ """ Test loading a cert generated by easy RSA.
+ https://github.com/fedora-infra/fedmsg/pull/389
+ """
+ # Does this raise an exception?
+ X509.load_cert('tests/easy_rsa.pem')
-class X509_StackTestCase(unittest.TestCase):
-
+
+class X509StackTestCase(unittest.TestCase):
def test_make_stack_from_der(self):
- f = open("tests/der_encoded_seq.b64")
- b64 = f.read(1304)
- seq = base64.decodestring(b64)
+ with open("tests/der_encoded_seq.b64", 'rb') as f:
+ b64 = f.read()
+
+ with warnings.catch_warnings():
+ warnings.simplefilter('ignore', DeprecationWarning)
+ seq = base64.decodestring(b64)
+
stack = X509.new_stack_from_der(seq)
cert = stack.pop()
- assert stack.pop() is None
-
+ self.assertIsNone(stack.pop())
+
cert.foobar = 1
- assert cert.foobar == 1
-
- subject = cert.get_subject()
- assert str(subject) == "/DC=org/DC=doegrids/OU=Services/CN=host/bosshog.lbl.gov"
+ self.assertEqual(cert.foobar, 1)
+
+ subject = cert.get_subject()
+ self.assertEqual(
+ str(subject),
+ "/DC=org/DC=doegrids/OU=Services/CN=host/bosshog.lbl.gov")
def test_make_stack_check_num(self):
- f = open("tests/der_encoded_seq.b64")
- b64 = f.read(1304)
- seq = base64.decodestring(b64)
+ with open("tests/der_encoded_seq.b64", 'rb') as f:
+ b64 = f.read()
+
+ with warnings.catch_warnings():
+ warnings.simplefilter('ignore', DeprecationWarning)
+ seq = base64.decodestring(b64)
+
stack = X509.new_stack_from_der(seq)
num = len(stack)
- assert num == 1
- cert = stack.pop()
+ self.assertEqual(num, 1)
+ cert = stack.pop()
num = len(stack)
- assert num == 0
- subject = cert.get_subject()
- assert str(subject) == "/DC=org/DC=doegrids/OU=Services/CN=host/bosshog.lbl.gov"
+ self.assertEqual(num, 0)
+ subject = cert.get_subject()
+ self.assertEqual(
+ str(subject),
+ "/DC=org/DC=doegrids/OU=Services/CN=host/bosshog.lbl.gov")
def test_make_stack(self):
stack = X509.X509_Stack()
@@ -486,21 +633,21 @@ class X509_StackTestCase(unittest.TestCase):
issuer_subject1 = issuer.get_subject()
stack.push(cert)
stack.push(issuer)
-
+
# Test stack iterator
i = 0
for c in stack:
i += 1
- assert len(c.get_subject().CN) > 0
- assert i == 2
-
- issuer_pop = stack.pop()
- cert_pop = stack.pop()
- cert_subject2 = cert_pop.get_subject()
+ self.assertGreater(len(c.get_subject().CN), 0)
+ self.assertEqual(i, 2)
+
+ stack.pop()
+ cert_pop = stack.pop()
+ cert_subject2 = cert_pop.get_subject()
issuer_subject2 = issuer.get_subject()
- assert str(cert_subject1) == str(cert_subject2)
- assert str(issuer_subject1) == str(issuer_subject2)
-
+ self.assertEqual(str(cert_subject1), str(cert_subject2))
+ self.assertEqual(str(issuer_subject1), str(issuer_subject2))
+
def test_as_der(self):
stack = X509.X509_Stack()
cert = X509.load_cert("tests/x509.pem")
@@ -509,20 +656,19 @@ class X509_StackTestCase(unittest.TestCase):
issuer_subject1 = issuer.get_subject()
stack.push(cert)
stack.push(issuer)
- der_seq = stack.as_der()
+ der_seq = stack.as_der()
stack2 = X509.new_stack_from_der(der_seq)
- issuer_pop = stack2.pop()
- cert_pop = stack2.pop()
- cert_subject2 = cert_pop.get_subject()
+ stack2.pop()
+ cert_pop = stack2.pop()
+ cert_subject2 = cert_pop.get_subject()
issuer_subject2 = issuer.get_subject()
- assert str(cert_subject1) == str(cert_subject2)
- assert str(issuer_subject1) == str(issuer_subject2)
-
+ self.assertEqual(str(cert_subject1), str(cert_subject2))
+ self.assertEqual(str(issuer_subject1), str(issuer_subject2))
+
-class X509_ExtTestCase(unittest.TestCase):
-
+class X509ExtTestCase(unittest.TestCase):
def test_ext(self):
- if 0: # XXX
+ if 0: # XXX
# With this leaks 8 bytes:
name = "proxyCertInfo"
value = "critical,language:Inherit all"
@@ -530,11 +676,10 @@ class X509_ExtTestCase(unittest.TestCase):
# With this there are no leaks:
name = "nsComment"
value = "Hello"
-
- lhash = m2.x509v3_lhash()
- ctx = m2.x509v3_set_conf_lhash(lhash)
- x509_ext_ptr = m2.x509v3_ext_conf(lhash, ctx, name, value)
- x509_ext = X509.X509_Extension(x509_ext_ptr, 1)
+
+ ctx = m2.x509v3_set_nconf()
+ x509_ext_ptr = m2.x509v3_ext_conf(None, ctx, name, value)
+ X509.X509_Extension(x509_ext_ptr, 1)
class CRLTestCase(unittest.TestCase):
@@ -542,15 +687,15 @@ class CRLTestCase(unittest.TestCase):
crl = X509.CRL()
self.assertEqual(crl.as_text()[:34],
'Certificate Revocation List (CRL):')
-
+
def suite():
- suite = unittest.TestSuite()
- suite.addTest(unittest.makeSuite(X509TestCase))
- suite.addTest(unittest.makeSuite(X509_StackTestCase))
- suite.addTest(unittest.makeSuite(X509_ExtTestCase))
- suite.addTest(unittest.makeSuite(CRLTestCase))
- return suite
+ st = unittest.TestSuite()
+ st.addTest(unittest.makeSuite(X509TestCase))
+ st.addTest(unittest.makeSuite(X509StackTestCase))
+ st.addTest(unittest.makeSuite(X509ExtTestCase))
+ st.addTest(unittest.makeSuite(CRLTestCase))
+ return st
if __name__ == '__main__':
diff --git a/tests/vendor/unittest2/__init__.py b/tests/vendor/unittest2/__init__.py
new file mode 100644
index 0000000..11cbadc
--- /dev/null
+++ b/tests/vendor/unittest2/__init__.py
@@ -0,0 +1,68 @@
+"""
+unittest2
+
+unittest2 is a backport of the new features added to the unittest testing
+framework in Python 2.7. It is tested to run on Python 2.4 - 2.6.
+
+To use unittest2 instead of unittest simply replace ``import unittest`` with
+``import unittest2``.
+
+
+Copyright (c) 1999-2003 Steve Purcell
+Copyright (c) 2003-2010 Python Software Foundation
+This module is free software, and you may redistribute it and/or modify
+it under the same terms as Python itself, so long as this copyright message
+and disclaimer are retained in their original form.
+
+IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF
+THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
+
+THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS,
+AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
+SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+"""
+
+__all__ = ['TestResult', 'TestCase', 'TestSuite',
+ 'TextTestRunner', 'TestLoader', 'FunctionTestCase', 'main',
+ 'defaultTestLoader', 'SkipTest', 'skip', 'skipIf', 'skipUnless',
+ 'expectedFailure', 'TextTestResult', '__version__', 'collector']
+
+__version__ = '0.5.1'
+
+# Expose obsolete functions for backwards compatibility
+__all__.extend(['getTestCaseNames', 'makeSuite', 'findTestCases'])
+
+
+from unittest2.collector import collector
+from unittest2.result import TestResult
+from unittest2.case import (
+ TestCase, FunctionTestCase, SkipTest, skip, skipIf,
+ skipUnless, expectedFailure
+)
+from unittest2.suite import BaseTestSuite, TestSuite
+from unittest2.loader import (
+ TestLoader, defaultTestLoader, makeSuite, getTestCaseNames,
+ findTestCases
+)
+from unittest2.main import TestProgram, main, main_
+from unittest2.runner import TextTestRunner, TextTestResult
+
+try:
+ from unittest2.signals import (
+ installHandler, registerResult, removeResult, removeHandler
+ )
+except ImportError:
+ # Compatibility with platforms that don't have the signal module
+ pass
+else:
+ __all__.extend(['installHandler', 'registerResult', 'removeResult',
+ 'removeHandler'])
+
+# deprecated
+_TextTestResult = TextTestResult
+
+__unittest = True \ No newline at end of file
diff --git a/tests/vendor/unittest2/__main__.py b/tests/vendor/unittest2/__main__.py
new file mode 100644
index 0000000..04ed982
--- /dev/null
+++ b/tests/vendor/unittest2/__main__.py
@@ -0,0 +1,10 @@
+"""Main entry point"""
+
+import sys
+if sys.argv[0].endswith("__main__.py"):
+ sys.argv[0] = "unittest2"
+
+__unittest = True
+
+from unittest2.main import main_
+main_()
diff --git a/tests/vendor/unittest2/case.py b/tests/vendor/unittest2/case.py
new file mode 100644
index 0000000..105914b
--- /dev/null
+++ b/tests/vendor/unittest2/case.py
@@ -0,0 +1,1084 @@
+"""Test case implementation"""
+
+import sys
+import difflib
+import pprint
+import re
+import unittest
+import warnings
+
+from unittest2 import result
+from unittest2.util import (
+ safe_repr, safe_str, strclass,
+ unorderable_list_difference
+)
+
+from unittest2.compatibility import wraps
+
+__unittest = True
+
+
+DIFF_OMITTED = ('\nDiff is %s characters long. '
+ 'Set self.maxDiff to None to see it.')
+
+class SkipTest(Exception):
+ """
+ Raise this exception in a test to skip it.
+
+ Usually you can use TestResult.skip() or one of the skipping decorators
+ instead of raising this directly.
+ """
+
+class _ExpectedFailure(Exception):
+ """
+ Raise this when a test is expected to fail.
+
+ This is an implementation detail.
+ """
+
+ def __init__(self, exc_info):
+ # can't use super because Python 2.4 exceptions are old style
+ Exception.__init__(self)
+ self.exc_info = exc_info
+
+class _UnexpectedSuccess(Exception):
+ """
+ The test was supposed to fail, but it didn't!
+ """
+
+def _id(obj):
+ return obj
+
+def skip(reason):
+ """
+ Unconditionally skip a test.
+ """
+ def decorator(test_item):
+ if not (isinstance(test_item, type) and issubclass(test_item, TestCase)):
+ @wraps(test_item)
+ def skip_wrapper(*args, **kwargs):
+ raise SkipTest(reason)
+ test_item = skip_wrapper
+
+ test_item.__unittest_skip__ = True
+ test_item.__unittest_skip_why__ = reason
+ return test_item
+ return decorator
+
+def skipIf(condition, reason):
+ """
+ Skip a test if the condition is true.
+ """
+ if condition:
+ return skip(reason)
+ return _id
+
+def skipUnless(condition, reason):
+ """
+ Skip a test unless the condition is true.
+ """
+ if not condition:
+ return skip(reason)
+ return _id
+
+
+def expectedFailure(func):
+ @wraps(func)
+ def wrapper(*args, **kwargs):
+ try:
+ func(*args, **kwargs)
+ except Exception:
+ raise _ExpectedFailure(sys.exc_info())
+ raise _UnexpectedSuccess
+ return wrapper
+
+
+class _AssertRaisesContext(object):
+ """A context manager used to implement TestCase.assertRaises* methods."""
+
+ def __init__(self, expected, test_case, expected_regexp=None):
+ self.expected = expected
+ self.failureException = test_case.failureException
+ self.expected_regexp = expected_regexp
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, exc_type, exc_value, tb):
+ if exc_type is None:
+ try:
+ exc_name = self.expected.__name__
+ except AttributeError:
+ exc_name = str(self.expected)
+ raise self.failureException(
+ "%s not raised" % (exc_name,))
+ if not issubclass(exc_type, self.expected):
+ # let unexpected exceptions pass through
+ return False
+ self.exception = exc_value # store for later retrieval
+ if self.expected_regexp is None:
+ return True
+
+ expected_regexp = self.expected_regexp
+ if isinstance(expected_regexp, basestring):
+ expected_regexp = re.compile(expected_regexp)
+ if not expected_regexp.search(str(exc_value)):
+ raise self.failureException('"%s" does not match "%s"' %
+ (expected_regexp.pattern, str(exc_value)))
+ return True
+
+
+class _TypeEqualityDict(object):
+
+ def __init__(self, testcase):
+ self.testcase = testcase
+ self._store = {}
+
+ def __setitem__(self, key, value):
+ self._store[key] = value
+
+ def __getitem__(self, key):
+ value = self._store[key]
+ if isinstance(value, basestring):
+ return getattr(self.testcase, value)
+ return value
+
+ def get(self, key, default=None):
+ if key in self._store:
+ return self[key]
+ return default
+
+
+class TestCase(unittest.TestCase):
+ """A class whose instances are single test cases.
+
+ By default, the test code itself should be placed in a method named
+ 'runTest'.
+
+ If the fixture may be used for many test cases, create as
+ many test methods as are needed. When instantiating such a TestCase
+ subclass, specify in the constructor arguments the name of the test method
+ that the instance is to execute.
+
+ Test authors should subclass TestCase for their own tests. Construction
+ and deconstruction of the test's environment ('fixture') can be
+ implemented by overriding the 'setUp' and 'tearDown' methods respectively.
+
+ If it is necessary to override the __init__ method, the base class
+ __init__ method must always be called. It is important that subclasses
+ should not change the signature of their __init__ method, since instances
+ of the classes are instantiated automatically by parts of the framework
+ in order to be run.
+ """
+
+ # This attribute determines which exception will be raised when
+ # the instance's assertion methods fail; test methods raising this
+ # exception will be deemed to have 'failed' rather than 'errored'
+
+ failureException = AssertionError
+
+ # This attribute sets the maximum length of a diff in failure messages
+ # by assert methods using difflib. It is looked up as an instance attribute
+ # so can be configured by individual tests if required.
+
+ maxDiff = 80*8
+
+ # This attribute determines whether long messages (including repr of
+ # objects used in assert methods) will be printed on failure in *addition*
+ # to any explicit message passed.
+
+ longMessage = True
+
+ # Attribute used by TestSuite for classSetUp
+
+ _classSetupFailed = False
+
+ def __init__(self, methodName='runTest'):
+ """Create an instance of the class that will use the named test
+ method when executed. Raises a ValueError if the instance does
+ not have a method with the specified name.
+ """
+ self._testMethodName = methodName
+ self._resultForDoCleanups = None
+ try:
+ testMethod = getattr(self, methodName)
+ except AttributeError:
+ raise ValueError("no such test method in %s: %s" % \
+ (self.__class__, methodName))
+ self._testMethodDoc = testMethod.__doc__
+ self._cleanups = []
+
+ # Map types to custom assertEqual functions that will compare
+ # instances of said type in more detail to generate a more useful
+ # error message.
+ self._type_equality_funcs = _TypeEqualityDict(self)
+ self.addTypeEqualityFunc(dict, 'assertDictEqual')
+ self.addTypeEqualityFunc(list, 'assertListEqual')
+ self.addTypeEqualityFunc(tuple, 'assertTupleEqual')
+ self.addTypeEqualityFunc(set, 'assertSetEqual')
+ self.addTypeEqualityFunc(frozenset, 'assertSetEqual')
+ self.addTypeEqualityFunc(unicode, 'assertMultiLineEqual')
+
+ def addTypeEqualityFunc(self, typeobj, function):
+ """Add a type specific assertEqual style function to compare a type.
+
+ This method is for use by TestCase subclasses that need to register
+ their own type equality functions to provide nicer error messages.
+
+ Args:
+ typeobj: The data type to call this function on when both values
+ are of the same type in assertEqual().
+ function: The callable taking two arguments and an optional
+ msg= argument that raises self.failureException with a
+ useful error message when the two arguments are not equal.
+ """
+ self._type_equality_funcs[typeobj] = function
+
+ def addCleanup(self, function, *args, **kwargs):
+ """Add a function, with arguments, to be called when the test is
+ completed. Functions added are called on a LIFO basis and are
+ called after tearDown on test failure or success.
+
+ Cleanup items are called even if setUp fails (unlike tearDown)."""
+ self._cleanups.append((function, args, kwargs))
+
+ def setUp(self):
+ "Hook method for setting up the test fixture before exercising it."
+
+ @classmethod
+ def setUpClass(cls):
+ "Hook method for setting up class fixture before running tests in the class."
+
+ @classmethod
+ def tearDownClass(cls):
+ "Hook method for deconstructing the class fixture after running all tests in the class."
+
+ def tearDown(self):
+ "Hook method for deconstructing the test fixture after testing it."
+
+ def countTestCases(self):
+ return 1
+
+ def defaultTestResult(self):
+ return result.TestResult()
+
+ def shortDescription(self):
+ """Returns a one-line description of the test, or None if no
+ description has been provided.
+
+ The default implementation of this method returns the first line of
+ the specified test method's docstring.
+ """
+ doc = self._testMethodDoc
+ return doc and doc.split("\n")[0].strip() or None
+
+
+ def id(self):
+ return "%s.%s" % (strclass(self.__class__), self._testMethodName)
+
+ def __eq__(self, other):
+ if type(self) is not type(other):
+ return NotImplemented
+
+ return self._testMethodName == other._testMethodName
+
+ def __ne__(self, other):
+ return not self == other
+
+ def __hash__(self):
+ return hash((type(self), self._testMethodName))
+
+ def __str__(self):
+ return "%s (%s)" % (self._testMethodName, strclass(self.__class__))
+
+ def __repr__(self):
+ return "<%s testMethod=%s>" % \
+ (strclass(self.__class__), self._testMethodName)
+
+ def _addSkip(self, result, reason):
+ addSkip = getattr(result, 'addSkip', None)
+ if addSkip is not None:
+ addSkip(self, reason)
+ else:
+ warnings.warn("Use of a TestResult without an addSkip method is deprecated",
+ DeprecationWarning, 2)
+ result.addSuccess(self)
+
+ def run(self, result=None):
+ orig_result = result
+ if result is None:
+ result = self.defaultTestResult()
+ startTestRun = getattr(result, 'startTestRun', None)
+ if startTestRun is not None:
+ startTestRun()
+
+ self._resultForDoCleanups = result
+ result.startTest(self)
+
+ testMethod = getattr(self, self._testMethodName)
+
+ if (getattr(self.__class__, "__unittest_skip__", False) or
+ getattr(testMethod, "__unittest_skip__", False)):
+ # If the class or method was skipped.
+ try:
+ skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
+ or getattr(testMethod, '__unittest_skip_why__', ''))
+ self._addSkip(result, skip_why)
+ finally:
+ result.stopTest(self)
+ return
+ try:
+ success = False
+ try:
+ self.setUp()
+ except SkipTest, e:
+ self._addSkip(result, str(e))
+ except Exception:
+ result.addError(self, sys.exc_info())
+ else:
+ try:
+ testMethod()
+ except self.failureException:
+ result.addFailure(self, sys.exc_info())
+ except _ExpectedFailure, e:
+ addExpectedFailure = getattr(result, 'addExpectedFailure', None)
+ if addExpectedFailure is not None:
+ addExpectedFailure(self, e.exc_info)
+ else:
+ warnings.warn("Use of a TestResult without an addExpectedFailure method is deprecated",
+ DeprecationWarning)
+ result.addSuccess(self)
+ except _UnexpectedSuccess:
+ addUnexpectedSuccess = getattr(result, 'addUnexpectedSuccess', None)
+ if addUnexpectedSuccess is not None:
+ addUnexpectedSuccess(self)
+ else:
+ warnings.warn("Use of a TestResult without an addUnexpectedSuccess method is deprecated",
+ DeprecationWarning)
+ result.addFailure(self, sys.exc_info())
+ except SkipTest, e:
+ self._addSkip(result, str(e))
+ except Exception:
+ result.addError(self, sys.exc_info())
+ else:
+ success = True
+
+ try:
+ self.tearDown()
+ except Exception:
+ result.addError(self, sys.exc_info())
+ success = False
+
+ cleanUpSuccess = self.doCleanups()
+ success = success and cleanUpSuccess
+ if success:
+ result.addSuccess(self)
+ finally:
+ result.stopTest(self)
+ if orig_result is None:
+ stopTestRun = getattr(result, 'stopTestRun', None)
+ if stopTestRun is not None:
+ stopTestRun()
+
+ def doCleanups(self):
+ """Execute all cleanup functions. Normally called for you after
+ tearDown."""
+ result = self._resultForDoCleanups
+ ok = True
+ while self._cleanups:
+ function, args, kwargs = self._cleanups.pop(-1)
+ try:
+ function(*args, **kwargs)
+ except Exception:
+ ok = False
+ result.addError(self, sys.exc_info())
+ return ok
+
+ def __call__(self, *args, **kwds):
+ return self.run(*args, **kwds)
+
+ def debug(self):
+ """Run the test without collecting errors in a TestResult"""
+ self.setUp()
+ getattr(self, self._testMethodName)()
+ self.tearDown()
+ while self._cleanups:
+ function, args, kwargs = self._cleanups.pop(-1)
+ function(*args, **kwargs)
+
+ def skipTest(self, reason):
+ """Skip this test."""
+ raise SkipTest(reason)
+
+ def fail(self, msg=None):
+ """Fail immediately, with the given message."""
+ raise self.failureException(msg)
+
+ def assertFalse(self, expr, msg=None):
+ "Fail the test if the expression is true."
+ if expr:
+ msg = self._formatMessage(msg, "%s is not False" % safe_repr(expr))
+ raise self.failureException(msg)
+
+ def assertTrue(self, expr, msg=None):
+ """Fail the test unless the expression is true."""
+ if not expr:
+ msg = self._formatMessage(msg, "%s is not True" % safe_repr(expr))
+ raise self.failureException(msg)
+
+ def _formatMessage(self, msg, standardMsg):
+ """Honour the longMessage attribute when generating failure messages.
+ If longMessage is False this means:
+ * Use only an explicit message if it is provided
+ * Otherwise use the standard message for the assert
+
+ If longMessage is True:
+ * Use the standard message
+ * If an explicit message is provided, plus ' : ' and the explicit message
+ """
+ if not self.longMessage:
+ return msg or standardMsg
+ if msg is None:
+ return standardMsg
+ try:
+ return '%s : %s' % (standardMsg, msg)
+ except UnicodeDecodeError:
+ return '%s : %s' % (safe_str(standardMsg), safe_str(msg))
+
+
+ def assertRaises(self, excClass, callableObj=None, *args, **kwargs):
+ """Fail unless an exception of class excClass is thrown
+ by callableObj when invoked with arguments args and keyword
+ arguments kwargs. If a different type of exception is
+ thrown, it will not be caught, and the test case will be
+ deemed to have suffered an error, exactly as for an
+ unexpected exception.
+
+ If called with callableObj omitted or None, will return a
+ context object used like this::
+
+ with self.assertRaises(SomeException):
+ do_something()
+
+ The context manager keeps a reference to the exception as
+ the 'exception' attribute. This allows you to inspect the
+ exception after the assertion::
+
+ with self.assertRaises(SomeException) as cm:
+ do_something()
+ the_exception = cm.exception
+ self.assertEqual(the_exception.error_code, 3)
+ """
+ if callableObj is None:
+ return _AssertRaisesContext(excClass, self)
+ try:
+ callableObj(*args, **kwargs)
+ except excClass:
+ return
+
+ if hasattr(excClass,'__name__'):
+ excName = excClass.__name__
+ else:
+ excName = str(excClass)
+ raise self.failureException, "%s not raised" % excName
+
+ def _getAssertEqualityFunc(self, first, second):
+ """Get a detailed comparison function for the types of the two args.
+
+ Returns: A callable accepting (first, second, msg=None) that will
+ raise a failure exception if first != second with a useful human
+ readable error message for those types.
+ """
+ #
+ # NOTE(gregory.p.smith): I considered isinstance(first, type(second))
+ # and vice versa. I opted for the conservative approach in case
+ # subclasses are not intended to be compared in detail to their super
+ # class instances using a type equality func. This means testing
+ # subtypes won't automagically use the detailed comparison. Callers
+ # should use their type specific assertSpamEqual method to compare
+ # subclasses if the detailed comparison is desired and appropriate.
+ # See the discussion in http://bugs.python.org/issue2578.
+ #
+ if type(first) is type(second):
+ asserter = self._type_equality_funcs.get(type(first))
+ if asserter is not None:
+ return asserter
+
+ return self._baseAssertEqual
+
+ def _baseAssertEqual(self, first, second, msg=None):
+ """The default assertEqual implementation, not type specific."""
+ if not first == second:
+ standardMsg = '%s != %s' % (safe_repr(first), safe_repr(second))
+ msg = self._formatMessage(msg, standardMsg)
+ raise self.failureException(msg)
+
+ def assertEqual(self, first, second, msg=None):
+ """Fail if the two objects are unequal as determined by the '=='
+ operator.
+ """
+ assertion_func = self._getAssertEqualityFunc(first, second)
+ assertion_func(first, second, msg=msg)
+
+ def assertNotEqual(self, first, second, msg=None):
+ """Fail if the two objects are equal as determined by the '=='
+ operator.
+ """
+ if not first != second:
+ msg = self._formatMessage(msg, '%s == %s' % (safe_repr(first),
+ safe_repr(second)))
+ raise self.failureException(msg)
+
+ def assertAlmostEqual(self, first, second, places=None, msg=None, delta=None):
+ """Fail if the two objects are unequal as determined by their
+ difference rounded to the given number of decimal places
+ (default 7) and comparing to zero, or by comparing that the
+ between the two objects is more than the given delta.
+
+ Note that decimal places (from zero) are usually not the same
+ as significant digits (measured from the most signficant digit).
+
+ If the two objects compare equal then they will automatically
+ compare almost equal.
+ """
+ if first == second:
+ # shortcut
+ return
+ if delta is not None and places is not None:
+ raise TypeError("specify delta or places not both")
+
+ if delta is not None:
+ if abs(first - second) <= delta:
+ return
+
+ standardMsg = '%s != %s within %s delta' % (safe_repr(first),
+ safe_repr(second),
+ safe_repr(delta))
+ else:
+ if places is None:
+ places = 7
+
+ if round(abs(second-first), places) == 0:
+ return
+
+ standardMsg = '%s != %s within %r places' % (safe_repr(first),
+ safe_repr(second),
+ places)
+ msg = self._formatMessage(msg, standardMsg)
+ raise self.failureException(msg)
+
+ def assertNotAlmostEqual(self, first, second, places=None, msg=None, delta=None):
+ """Fail if the two objects are equal as determined by their
+ difference rounded to the given number of decimal places
+ (default 7) and comparing to zero, or by comparing that the
+ between the two objects is less than the given delta.
+
+ Note that decimal places (from zero) are usually not the same
+ as significant digits (measured from the most signficant digit).
+
+ Objects that are equal automatically fail.
+ """
+ if delta is not None and places is not None:
+ raise TypeError("specify delta or places not both")
+ if delta is not None:
+ if not (first == second) and abs(first - second) > delta:
+ return
+ standardMsg = '%s == %s within %s delta' % (safe_repr(first),
+ safe_repr(second),
+ safe_repr(delta))
+ else:
+ if places is None:
+ places = 7
+ if not (first == second) and round(abs(second-first), places) != 0:
+ return
+ standardMsg = '%s == %s within %r places' % (safe_repr(first),
+ safe_repr(second),
+ places)
+
+ msg = self._formatMessage(msg, standardMsg)
+ raise self.failureException(msg)
+
+ # Synonyms for assertion methods
+
+ # The plurals are undocumented. Keep them that way to discourage use.
+ # Do not add more. Do not remove.
+ # Going through a deprecation cycle on these would annoy many people.
+ assertEquals = assertEqual
+ assertNotEquals = assertNotEqual
+ assertAlmostEquals = assertAlmostEqual
+ assertNotAlmostEquals = assertNotAlmostEqual
+ assert_ = assertTrue
+
+ # These fail* assertion method names are pending deprecation and will
+ # be a DeprecationWarning in 3.2; http://bugs.python.org/issue2578
+ def _deprecate(original_func):
+ def deprecated_func(*args, **kwargs):
+ warnings.warn(
+ ('Please use %s instead.' % original_func.__name__),
+ PendingDeprecationWarning, 2)
+ return original_func(*args, **kwargs)
+ return deprecated_func
+
+ failUnlessEqual = _deprecate(assertEqual)
+ failIfEqual = _deprecate(assertNotEqual)
+ failUnlessAlmostEqual = _deprecate(assertAlmostEqual)
+ failIfAlmostEqual = _deprecate(assertNotAlmostEqual)
+ failUnless = _deprecate(assertTrue)
+ failUnlessRaises = _deprecate(assertRaises)
+ failIf = _deprecate(assertFalse)
+
+ def assertSequenceEqual(self, seq1, seq2,
+ msg=None, seq_type=None, max_diff=80*8):
+ """An equality assertion for ordered sequences (like lists and tuples).
+
+ For the purposes of this function, a valid ordered sequence type is one
+ which can be indexed, has a length, and has an equality operator.
+
+ Args:
+ seq1: The first sequence to compare.
+ seq2: The second sequence to compare.
+ seq_type: The expected datatype of the sequences, or None if no
+ datatype should be enforced.
+ msg: Optional message to use on failure instead of a list of
+ differences.
+ max_diff: Maximum size off the diff, larger diffs are not shown
+ """
+ if seq_type is not None:
+ seq_type_name = seq_type.__name__
+ if not isinstance(seq1, seq_type):
+ raise self.failureException('First sequence is not a %s: %s'
+ % (seq_type_name, safe_repr(seq1)))
+ if not isinstance(seq2, seq_type):
+ raise self.failureException('Second sequence is not a %s: %s'
+ % (seq_type_name, safe_repr(seq2)))
+ else:
+ seq_type_name = "sequence"
+
+ differing = None
+ try:
+ len1 = len(seq1)
+ except (TypeError, NotImplementedError):
+ differing = 'First %s has no length. Non-sequence?' % (
+ seq_type_name)
+
+ if differing is None:
+ try:
+ len2 = len(seq2)
+ except (TypeError, NotImplementedError):
+ differing = 'Second %s has no length. Non-sequence?' % (
+ seq_type_name)
+
+ if differing is None:
+ if seq1 == seq2:
+ return
+
+ seq1_repr = repr(seq1)
+ seq2_repr = repr(seq2)
+ if len(seq1_repr) > 30:
+ seq1_repr = seq1_repr[:30] + '...'
+ if len(seq2_repr) > 30:
+ seq2_repr = seq2_repr[:30] + '...'
+ elements = (seq_type_name.capitalize(), seq1_repr, seq2_repr)
+ differing = '%ss differ: %s != %s\n' % elements
+
+ for i in xrange(min(len1, len2)):
+ try:
+ item1 = seq1[i]
+ except (TypeError, IndexError, NotImplementedError):
+ differing += ('\nUnable to index element %d of first %s\n' %
+ (i, seq_type_name))
+ break
+
+ try:
+ item2 = seq2[i]
+ except (TypeError, IndexError, NotImplementedError):
+ differing += ('\nUnable to index element %d of second %s\n' %
+ (i, seq_type_name))
+ break
+
+ if item1 != item2:
+ differing += ('\nFirst differing element %d:\n%s\n%s\n' %
+ (i, item1, item2))
+ break
+ else:
+ if (len1 == len2 and seq_type is None and
+ type(seq1) != type(seq2)):
+ # The sequences are the same, but have differing types.
+ return
+
+ if len1 > len2:
+ differing += ('\nFirst %s contains %d additional '
+ 'elements.\n' % (seq_type_name, len1 - len2))
+ try:
+ differing += ('First extra element %d:\n%s\n' %
+ (len2, seq1[len2]))
+ except (TypeError, IndexError, NotImplementedError):
+ differing += ('Unable to index element %d '
+ 'of first %s\n' % (len2, seq_type_name))
+ elif len1 < len2:
+ differing += ('\nSecond %s contains %d additional '
+ 'elements.\n' % (seq_type_name, len2 - len1))
+ try:
+ differing += ('First extra element %d:\n%s\n' %
+ (len1, seq2[len1]))
+ except (TypeError, IndexError, NotImplementedError):
+ differing += ('Unable to index element %d '
+ 'of second %s\n' % (len1, seq_type_name))
+ standardMsg = differing
+ diffMsg = '\n' + '\n'.join(
+ difflib.ndiff(pprint.pformat(seq1).splitlines(),
+ pprint.pformat(seq2).splitlines()))
+
+ standardMsg = self._truncateMessage(standardMsg, diffMsg)
+ msg = self._formatMessage(msg, standardMsg)
+ self.fail(msg)
+
+ def _truncateMessage(self, message, diff):
+ max_diff = self.maxDiff
+ if max_diff is None or len(diff) <= max_diff:
+ return message + diff
+ return message + (DIFF_OMITTED % len(diff))
+
+ def assertListEqual(self, list1, list2, msg=None):
+ """A list-specific equality assertion.
+
+ Args:
+ list1: The first list to compare.
+ list2: The second list to compare.
+ msg: Optional message to use on failure instead of a list of
+ differences.
+
+ """
+ self.assertSequenceEqual(list1, list2, msg, seq_type=list)
+
+ def assertTupleEqual(self, tuple1, tuple2, msg=None):
+ """A tuple-specific equality assertion.
+
+ Args:
+ tuple1: The first tuple to compare.
+ tuple2: The second tuple to compare.
+ msg: Optional message to use on failure instead of a list of
+ differences.
+ """
+ self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
+
+ def assertSetEqual(self, set1, set2, msg=None):
+ """A set-specific equality assertion.
+
+ Args:
+ set1: The first set to compare.
+ set2: The second set to compare.
+ msg: Optional message to use on failure instead of a list of
+ differences.
+
+ assertSetEqual uses ducktyping to support
+ different types of sets, and is optimized for sets specifically
+ (parameters must support a difference method).
+ """
+ try:
+ difference1 = set1.difference(set2)
+ except TypeError, e:
+ self.fail('invalid type when attempting set difference: %s' % e)
+ except AttributeError, e:
+ self.fail('first argument does not support set difference: %s' % e)
+
+ try:
+ difference2 = set2.difference(set1)
+ except TypeError, e:
+ self.fail('invalid type when attempting set difference: %s' % e)
+ except AttributeError, e:
+ self.fail('second argument does not support set difference: %s' % e)
+
+ if not (difference1 or difference2):
+ return
+
+ lines = []
+ if difference1:
+ lines.append('Items in the first set but not the second:')
+ for item in difference1:
+ lines.append(repr(item))
+ if difference2:
+ lines.append('Items in the second set but not the first:')
+ for item in difference2:
+ lines.append(repr(item))
+
+ standardMsg = '\n'.join(lines)
+ self.fail(self._formatMessage(msg, standardMsg))
+
+ def assertIn(self, member, container, msg=None):
+ """Just like self.assertTrue(a in b), but with a nicer default message."""
+ if member not in container:
+ standardMsg = '%s not found in %s' % (safe_repr(member),
+ safe_repr(container))
+ self.fail(self._formatMessage(msg, standardMsg))
+
+ def assertNotIn(self, member, container, msg=None):
+ """Just like self.assertTrue(a not in b), but with a nicer default message."""
+ if member in container:
+ standardMsg = '%s unexpectedly found in %s' % (safe_repr(member),
+ safe_repr(container))
+ self.fail(self._formatMessage(msg, standardMsg))
+
+ def assertIs(self, expr1, expr2, msg=None):
+ """Just like self.assertTrue(a is b), but with a nicer default message."""
+ if expr1 is not expr2:
+ standardMsg = '%s is not %s' % (safe_repr(expr1), safe_repr(expr2))
+ self.fail(self._formatMessage(msg, standardMsg))
+
+ def assertIsNot(self, expr1, expr2, msg=None):
+ """Just like self.assertTrue(a is not b), but with a nicer default message."""
+ if expr1 is expr2:
+ standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),)
+ self.fail(self._formatMessage(msg, standardMsg))
+
+ def assertDictEqual(self, d1, d2, msg=None):
+ self.assert_(isinstance(d1, dict), 'First argument is not a dictionary')
+ self.assert_(isinstance(d2, dict), 'Second argument is not a dictionary')
+
+ if d1 != d2:
+ standardMsg = '%s != %s' % (safe_repr(d1, True), safe_repr(d2, True))
+ diff = ('\n' + '\n'.join(difflib.ndiff(
+ pprint.pformat(d1).splitlines(),
+ pprint.pformat(d2).splitlines())))
+ standardMsg = self._truncateMessage(standardMsg, diff)
+ self.fail(self._formatMessage(msg, standardMsg))
+
+ def assertDictContainsSubset(self, expected, actual, msg=None):
+ """Checks whether actual is a superset of expected."""
+ missing = []
+ mismatched = []
+ for key, value in expected.iteritems():
+ if key not in actual:
+ missing.append(key)
+ elif value != actual[key]:
+ mismatched.append('%s, expected: %s, actual: %s' %
+ (safe_repr(key), safe_repr(value),
+ safe_repr(actual[key])))
+
+ if not (missing or mismatched):
+ return
+
+ standardMsg = ''
+ if missing:
+ standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in
+ missing)
+ if mismatched:
+ if standardMsg:
+ standardMsg += '; '
+ standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
+
+ self.fail(self._formatMessage(msg, standardMsg))
+
+ def assertItemsEqual(self, expected_seq, actual_seq, msg=None):
+ """An unordered sequence specific comparison. It asserts that
+ expected_seq and actual_seq contain the same elements. It is
+ the equivalent of::
+
+ self.assertEqual(sorted(expected_seq), sorted(actual_seq))
+
+ Raises with an error message listing which elements of expected_seq
+ are missing from actual_seq and vice versa if any.
+
+ Asserts that each element has the same count in both sequences.
+ Example:
+ - [0, 1, 1] and [1, 0, 1] compare equal.
+ - [0, 0, 1] and [0, 1] compare unequal.
+ """
+ try:
+ expected = sorted(expected_seq)
+ actual = sorted(actual_seq)
+ except TypeError:
+ # Unsortable items (example: set(), complex(), ...)
+ expected = list(expected_seq)
+ actual = list(actual_seq)
+ missing, unexpected = unorderable_list_difference(
+ expected, actual, ignore_duplicate=False
+ )
+ else:
+ return self.assertSequenceEqual(expected, actual, msg=msg)
+
+ errors = []
+ if missing:
+ errors.append('Expected, but missing:\n %s' %
+ safe_repr(missing))
+ if unexpected:
+ errors.append('Unexpected, but present:\n %s' %
+ safe_repr(unexpected))
+ if errors:
+ standardMsg = '\n'.join(errors)
+ self.fail(self._formatMessage(msg, standardMsg))
+
+ def assertMultiLineEqual(self, first, second, msg=None):
+ """Assert that two multi-line strings are equal."""
+ self.assert_(isinstance(first, basestring), (
+ 'First argument is not a string'))
+ self.assert_(isinstance(second, basestring), (
+ 'Second argument is not a string'))
+
+ if first != second:
+ standardMsg = '%s != %s' % (safe_repr(first, True), safe_repr(second, True))
+ diff = '\n' + ''.join(difflib.ndiff(first.splitlines(True),
+ second.splitlines(True)))
+ standardMsg = self._truncateMessage(standardMsg, diff)
+ self.fail(self._formatMessage(msg, standardMsg))
+
+ def assertLess(self, a, b, msg=None):
+ """Just like self.assertTrue(a < b), but with a nicer default message."""
+ if not a < b:
+ standardMsg = '%s not less than %s' % (safe_repr(a), safe_repr(b))
+ self.fail(self._formatMessage(msg, standardMsg))
+
+ def assertLessEqual(self, a, b, msg=None):
+ """Just like self.assertTrue(a <= b), but with a nicer default message."""
+ if not a <= b:
+ standardMsg = '%s not less than or equal to %s' % (safe_repr(a), safe_repr(b))
+ self.fail(self._formatMessage(msg, standardMsg))
+
+ def assertGreater(self, a, b, msg=None):
+ """Just like self.assertTrue(a > b), but with a nicer default message."""
+ if not a > b:
+ standardMsg = '%s not greater than %s' % (safe_repr(a), safe_repr(b))
+ self.fail(self._formatMessage(msg, standardMsg))
+
+ def assertGreaterEqual(self, a, b, msg=None):
+ """Just like self.assertTrue(a >= b), but with a nicer default message."""
+ if not a >= b:
+ standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b))
+ self.fail(self._formatMessage(msg, standardMsg))
+
+ def assertIsNone(self, obj, msg=None):
+ """Same as self.assertTrue(obj is None), with a nicer default message."""
+ if obj is not None:
+ standardMsg = '%s is not None' % (safe_repr(obj),)
+ self.fail(self._formatMessage(msg, standardMsg))
+
+ def assertIsNotNone(self, obj, msg=None):
+ """Included for symmetry with assertIsNone."""
+ if obj is None:
+ standardMsg = 'unexpectedly None'
+ self.fail(self._formatMessage(msg, standardMsg))
+
+ def assertIsInstance(self, obj, cls, msg=None):
+ """Same as self.assertTrue(isinstance(obj, cls)), with a nicer
+ default message."""
+ if not isinstance(obj, cls):
+ standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls)
+ self.fail(self._formatMessage(msg, standardMsg))
+
+ def assertNotIsInstance(self, obj, cls, msg=None):
+ """Included for symmetry with assertIsInstance."""
+ if isinstance(obj, cls):
+ standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls)
+ self.fail(self._formatMessage(msg, standardMsg))
+
+ def assertRaisesRegexp(self, expected_exception, expected_regexp,
+ callable_obj=None, *args, **kwargs):
+ """Asserts that the message in a raised exception matches a regexp.
+
+ Args:
+ expected_exception: Exception class expected to be raised.
+ expected_regexp: Regexp (re pattern object or string) expected
+ to be found in error message.
+ callable_obj: Function to be called.
+ args: Extra args.
+ kwargs: Extra kwargs.
+ """
+ if callable_obj is None:
+ return _AssertRaisesContext(expected_exception, self, expected_regexp)
+ try:
+ callable_obj(*args, **kwargs)
+ except expected_exception, exc_value:
+ if isinstance(expected_regexp, basestring):
+ expected_regexp = re.compile(expected_regexp)
+ if not expected_regexp.search(str(exc_value)):
+ raise self.failureException('"%s" does not match "%s"' %
+ (expected_regexp.pattern, str(exc_value)))
+ else:
+ if hasattr(expected_exception, '__name__'):
+ excName = expected_exception.__name__
+ else:
+ excName = str(expected_exception)
+ raise self.failureException, "%s not raised" % excName
+
+
+ def assertRegexpMatches(self, text, expected_regexp, msg=None):
+ """Fail the test unless the text matches the regular expression."""
+ if isinstance(expected_regexp, basestring):
+ expected_regexp = re.compile(expected_regexp)
+ if not expected_regexp.search(text):
+ msg = msg or "Regexp didn't match"
+ msg = '%s: %r not found in %r' % (msg, expected_regexp.pattern, text)
+ raise self.failureException(msg)
+
+ def assertNotRegexpMatches(self, text, unexpected_regexp, msg=None):
+ """Fail the test if the text matches the regular expression."""
+ if isinstance(unexpected_regexp, basestring):
+ unexpected_regexp = re.compile(unexpected_regexp)
+ match = unexpected_regexp.search(text)
+ if match:
+ msg = msg or "Regexp matched"
+ msg = '%s: %r matches %r in %r' % (msg,
+ text[match.start():match.end()],
+ unexpected_regexp.pattern,
+ text)
+ raise self.failureException(msg)
+
+class FunctionTestCase(TestCase):
+ """A test case that wraps a test function.
+
+ This is useful for slipping pre-existing test functions into the
+ unittest framework. Optionally, set-up and tidy-up functions can be
+ supplied. As with TestCase, the tidy-up ('tearDown') function will
+ always be called if the set-up ('setUp') function ran successfully.
+ """
+
+ def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
+ super(FunctionTestCase, self).__init__()
+ self._setUpFunc = setUp
+ self._tearDownFunc = tearDown
+ self._testFunc = testFunc
+ self._description = description
+
+ def setUp(self):
+ if self._setUpFunc is not None:
+ self._setUpFunc()
+
+ def tearDown(self):
+ if self._tearDownFunc is not None:
+ self._tearDownFunc()
+
+ def runTest(self):
+ self._testFunc()
+
+ def id(self):
+ return self._testFunc.__name__
+
+ def __eq__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+
+ return self._setUpFunc == other._setUpFunc and \
+ self._tearDownFunc == other._tearDownFunc and \
+ self._testFunc == other._testFunc and \
+ self._description == other._description
+
+ def __ne__(self, other):
+ return not self == other
+
+ def __hash__(self):
+ return hash((type(self), self._setUpFunc, self._tearDownFunc,
+ self._testFunc, self._description))
+
+ def __str__(self):
+ return "%s (%s)" % (strclass(self.__class__),
+ self._testFunc.__name__)
+
+ def __repr__(self):
+ return "<%s testFunc=%s>" % (strclass(self.__class__),
+ self._testFunc)
+
+ def shortDescription(self):
+ if self._description is not None:
+ return self._description
+ doc = self._testFunc.__doc__
+ return doc and doc.split("\n")[0].strip() or None
diff --git a/tests/vendor/unittest2/collector.py b/tests/vendor/unittest2/collector.py
new file mode 100644
index 0000000..28ff3f8
--- /dev/null
+++ b/tests/vendor/unittest2/collector.py
@@ -0,0 +1,9 @@
+import os
+import sys
+from unittest2.loader import defaultTestLoader
+
+def collector():
+ # import __main__ triggers code re-execution
+ __main__ = sys.modules['__main__']
+ setupDir = os.path.abspath(os.path.dirname(__main__.__file__))
+ return defaultTestLoader.discover(setupDir)
diff --git a/tests/vendor/unittest2/compatibility.py b/tests/vendor/unittest2/compatibility.py
new file mode 100644
index 0000000..b8f15dd
--- /dev/null
+++ b/tests/vendor/unittest2/compatibility.py
@@ -0,0 +1,64 @@
+import os
+import sys
+
+try:
+ from functools import wraps
+except ImportError:
+ # only needed for Python 2.4
+ def wraps(_):
+ def _wraps(func):
+ return func
+ return _wraps
+
+__unittest = True
+
+def _relpath_nt(path, start=os.path.curdir):
+ """Return a relative version of a path"""
+
+ if not path:
+ raise ValueError("no path specified")
+ start_list = os.path.abspath(start).split(os.path.sep)
+ path_list = os.path.abspath(path).split(os.path.sep)
+ if start_list[0].lower() != path_list[0].lower():
+ unc_path, rest = os.path.splitunc(path)
+ unc_start, rest = os.path.splitunc(start)
+ if bool(unc_path) ^ bool(unc_start):
+ raise ValueError("Cannot mix UNC and non-UNC paths (%s and %s)"
+ % (path, start))
+ else:
+ raise ValueError("path is on drive %s, start on drive %s"
+ % (path_list[0], start_list[0]))
+ # Work out how much of the filepath is shared by start and path.
+ for i in range(min(len(start_list), len(path_list))):
+ if start_list[i].lower() != path_list[i].lower():
+ break
+ else:
+ i += 1
+
+ rel_list = [os.path.pardir] * (len(start_list)-i) + path_list[i:]
+ if not rel_list:
+ return os.path.curdir
+ return os.path.join(*rel_list)
+
+# default to posixpath definition
+def _relpath_posix(path, start=os.path.curdir):
+ """Return a relative version of a path"""
+
+ if not path:
+ raise ValueError("no path specified")
+
+ start_list = os.path.abspath(start).split(os.path.sep)
+ path_list = os.path.abspath(path).split(os.path.sep)
+
+ # Work out how much of the filepath is shared by start and path.
+ i = len(os.path.commonprefix([start_list, path_list]))
+
+ rel_list = [os.path.pardir] * (len(start_list)-i) + path_list[i:]
+ if not rel_list:
+ return os.path.curdir
+ return os.path.join(*rel_list)
+
+if os.path is sys.modules.get('ntpath'):
+ relpath = _relpath_nt
+else:
+ relpath = _relpath_posix
diff --git a/tests/vendor/unittest2/loader.py b/tests/vendor/unittest2/loader.py
new file mode 100644
index 0000000..8ec2ead
--- /dev/null
+++ b/tests/vendor/unittest2/loader.py
@@ -0,0 +1,322 @@
+"""Loading unittests."""
+
+import os
+import re
+import sys
+import traceback
+import types
+import unittest
+
+from fnmatch import fnmatch
+
+from unittest2 import case, suite
+
+try:
+ from os.path import relpath
+except ImportError:
+ from unittest2.compatibility import relpath
+
+__unittest = True
+
+
+def _CmpToKey(mycmp):
+ 'Convert a cmp= function into a key= function'
+ class K(object):
+ def __init__(self, obj):
+ self.obj = obj
+ def __lt__(self, other):
+ return mycmp(self.obj, other.obj) == -1
+ return K
+
+
+# what about .pyc or .pyo (etc)
+# we would need to avoid loading the same tests multiple times
+# from '.py', '.pyc' *and* '.pyo'
+VALID_MODULE_NAME = re.compile(r'[_a-z]\w*\.py$', re.IGNORECASE)
+
+
+def _make_failed_import_test(name, suiteClass):
+ message = 'Failed to import test module: %s' % name
+ if hasattr(traceback, 'format_exc'):
+ # Python 2.3 compatibility
+ # format_exc returns two frames of discover.py as well
+ message += '\n%s' % traceback.format_exc()
+ return _make_failed_test('ModuleImportFailure', name, ImportError(message),
+ suiteClass)
+
+def _make_failed_load_tests(name, exception, suiteClass):
+ return _make_failed_test('LoadTestsFailure', name, exception, suiteClass)
+
+def _make_failed_test(classname, methodname, exception, suiteClass):
+ def testFailure(self):
+ raise exception
+ attrs = {methodname: testFailure}
+ TestClass = type(classname, (case.TestCase,), attrs)
+ return suiteClass((TestClass(methodname),))
+
+
+class TestLoader(unittest.TestLoader):
+ """
+ This class is responsible for loading tests according to various criteria
+ and returning them wrapped in a TestSuite
+ """
+ testMethodPrefix = 'test'
+ sortTestMethodsUsing = cmp
+ suiteClass = suite.TestSuite
+ _top_level_dir = None
+
+ def loadTestsFromTestCase(self, testCaseClass):
+ """Return a suite of all tests cases contained in testCaseClass"""
+ if issubclass(testCaseClass, suite.TestSuite):
+ raise TypeError("Test cases should not be derived from TestSuite."
+ " Maybe you meant to derive from TestCase?")
+ testCaseNames = self.getTestCaseNames(testCaseClass)
+ if not testCaseNames and hasattr(testCaseClass, 'runTest'):
+ testCaseNames = ['runTest']
+ loaded_suite = self.suiteClass(map(testCaseClass, testCaseNames))
+ return loaded_suite
+
+ def loadTestsFromModule(self, module, use_load_tests=True):
+ """Return a suite of all tests cases contained in the given module"""
+ tests = []
+ for name in dir(module):
+ obj = getattr(module, name)
+ if isinstance(obj, type) and issubclass(obj, unittest.TestCase):
+ tests.append(self.loadTestsFromTestCase(obj))
+
+ load_tests = getattr(module, 'load_tests', None)
+ tests = self.suiteClass(tests)
+ if use_load_tests and load_tests is not None:
+ try:
+ return load_tests(self, tests, None)
+ except Exception, e:
+ return _make_failed_load_tests(module.__name__, e,
+ self.suiteClass)
+ return tests
+
+ def loadTestsFromName(self, name, module=None):
+ """Return a suite of all tests cases given a string specifier.
+
+ The name may resolve either to a module, a test case class, a
+ test method within a test case class, or a callable object which
+ returns a TestCase or TestSuite instance.
+
+ The method optionally resolves the names relative to a given module.
+ """
+ parts = name.split('.')
+ if module is None:
+ parts_copy = parts[:]
+ while parts_copy:
+ try:
+ module = __import__('.'.join(parts_copy))
+ break
+ except ImportError:
+ del parts_copy[-1]
+ if not parts_copy:
+ raise
+ parts = parts[1:]
+ obj = module
+ for part in parts:
+ parent, obj = obj, getattr(obj, part)
+
+ if isinstance(obj, types.ModuleType):
+ return self.loadTestsFromModule(obj)
+ elif isinstance(obj, type) and issubclass(obj, unittest.TestCase):
+ return self.loadTestsFromTestCase(obj)
+ elif (isinstance(obj, types.UnboundMethodType) and
+ isinstance(parent, type) and
+ issubclass(parent, case.TestCase)):
+ return self.suiteClass([parent(obj.__name__)])
+ elif isinstance(obj, unittest.TestSuite):
+ return obj
+ elif hasattr(obj, '__call__'):
+ test = obj()
+ if isinstance(test, unittest.TestSuite):
+ return test
+ elif isinstance(test, unittest.TestCase):
+ return self.suiteClass([test])
+ else:
+ raise TypeError("calling %s returned %s, not a test" %
+ (obj, test))
+ else:
+ raise TypeError("don't know how to make test from: %s" % obj)
+
+ def loadTestsFromNames(self, names, module=None):
+ """Return a suite of all tests cases found using the given sequence
+ of string specifiers. See 'loadTestsFromName()'.
+ """
+ suites = [self.loadTestsFromName(name, module) for name in names]
+ return self.suiteClass(suites)
+
+ def getTestCaseNames(self, testCaseClass):
+ """Return a sorted sequence of method names found within testCaseClass
+ """
+ def isTestMethod(attrname, testCaseClass=testCaseClass,
+ prefix=self.testMethodPrefix):
+ return attrname.startswith(prefix) and \
+ hasattr(getattr(testCaseClass, attrname), '__call__')
+ testFnNames = filter(isTestMethod, dir(testCaseClass))
+ if self.sortTestMethodsUsing:
+ testFnNames.sort(key=_CmpToKey(self.sortTestMethodsUsing))
+ return testFnNames
+
+ def discover(self, start_dir, pattern='test*.py', top_level_dir=None):
+ """Find and return all test modules from the specified start
+ directory, recursing into subdirectories to find them. Only test files
+ that match the pattern will be loaded. (Using shell style pattern
+ matching.)
+
+ All test modules must be importable from the top level of the project.
+ If the start directory is not the top level directory then the top
+ level directory must be specified separately.
+
+ If a test package name (directory with '__init__.py') matches the
+ pattern then the package will be checked for a 'load_tests' function. If
+ this exists then it will be called with loader, tests, pattern.
+
+ If load_tests exists then discovery does *not* recurse into the package,
+ load_tests is responsible for loading all tests in the package.
+
+ The pattern is deliberately not stored as a loader attribute so that
+ packages can continue discovery themselves. top_level_dir is stored so
+ load_tests does not need to pass this argument in to loader.discover().
+ """
+ set_implicit_top = False
+ if top_level_dir is None and self._top_level_dir is not None:
+ # make top_level_dir optional if called from load_tests in a package
+ top_level_dir = self._top_level_dir
+ elif top_level_dir is None:
+ set_implicit_top = True
+ top_level_dir = start_dir
+
+ top_level_dir = os.path.abspath(top_level_dir)
+
+ if not top_level_dir in sys.path:
+ # all test modules must be importable from the top level directory
+ # should we *unconditionally* put the start directory in first
+ # in sys.path to minimise likelihood of conflicts between installed
+ # modules and development versions?
+ sys.path.insert(0, top_level_dir)
+ self._top_level_dir = top_level_dir
+
+ is_not_importable = False
+ if os.path.isdir(os.path.abspath(start_dir)):
+ start_dir = os.path.abspath(start_dir)
+ if start_dir != top_level_dir:
+ is_not_importable = not os.path.isfile(os.path.join(start_dir, '__init__.py'))
+ else:
+ # support for discovery from dotted module names
+ try:
+ __import__(start_dir)
+ except ImportError:
+ is_not_importable = True
+ else:
+ the_module = sys.modules[start_dir]
+ top_part = start_dir.split('.')[0]
+ start_dir = os.path.abspath(os.path.dirname((the_module.__file__)))
+ if set_implicit_top:
+ self._top_level_dir = os.path.abspath(os.path.dirname(os.path.dirname(sys.modules[top_part].__file__)))
+ sys.path.remove(top_level_dir)
+
+ if is_not_importable:
+ raise ImportError('Start directory is not importable: %r' % start_dir)
+
+ tests = list(self._find_tests(start_dir, pattern))
+ return self.suiteClass(tests)
+
+ def _get_name_from_path(self, path):
+ path = os.path.splitext(os.path.normpath(path))[0]
+
+ _relpath = relpath(path, self._top_level_dir)
+ assert not os.path.isabs(_relpath), "Path must be within the project"
+ assert not _relpath.startswith('..'), "Path must be within the project"
+
+ name = _relpath.replace(os.path.sep, '.')
+ return name
+
+ def _get_module_from_name(self, name):
+ __import__(name)
+ return sys.modules[name]
+
+ def _match_path(self, path, full_path, pattern):
+ # override this method to use alternative matching strategy
+ return fnmatch(path, pattern)
+
+ def _find_tests(self, start_dir, pattern):
+ """Used by discovery. Yields test suites it loads."""
+ paths = os.listdir(start_dir)
+
+ for path in paths:
+ full_path = os.path.join(start_dir, path)
+ if os.path.isfile(full_path):
+ if not VALID_MODULE_NAME.match(path):
+ # valid Python identifiers only
+ continue
+ if not self._match_path(path, full_path, pattern):
+ continue
+ # if the test file matches, load it
+ name = self._get_name_from_path(full_path)
+ try:
+ module = self._get_module_from_name(name)
+ except:
+ yield _make_failed_import_test(name, self.suiteClass)
+ else:
+ mod_file = os.path.abspath(getattr(module, '__file__', full_path))
+ realpath = os.path.splitext(mod_file)[0]
+ fullpath_noext = os.path.splitext(full_path)[0]
+ if realpath.lower() != fullpath_noext.lower():
+ module_dir = os.path.dirname(realpath)
+ mod_name = os.path.splitext(os.path.basename(full_path))[0]
+ expected_dir = os.path.dirname(full_path)
+ msg = ("%r module incorrectly imported from %r. Expected %r. "
+ "Is this module globally installed?")
+ raise ImportError(msg % (mod_name, module_dir, expected_dir))
+ yield self.loadTestsFromModule(module)
+ elif os.path.isdir(full_path):
+ if not os.path.isfile(os.path.join(full_path, '__init__.py')):
+ continue
+
+ load_tests = None
+ tests = None
+ if fnmatch(path, pattern):
+ # only check load_tests if the package directory itself matches the filter
+ name = self._get_name_from_path(full_path)
+ package = self._get_module_from_name(name)
+ load_tests = getattr(package, 'load_tests', None)
+ tests = self.loadTestsFromModule(package, use_load_tests=False)
+
+ if load_tests is None:
+ if tests is not None:
+ # tests loaded from package file
+ yield tests
+ # recurse into the package
+ for test in self._find_tests(full_path, pattern):
+ yield test
+ else:
+ try:
+ yield load_tests(self, tests, pattern)
+ except Exception, e:
+ yield _make_failed_load_tests(package.__name__, e,
+ self.suiteClass)
+
+defaultTestLoader = TestLoader()
+
+
+def _makeLoader(prefix, sortUsing, suiteClass=None):
+ loader = TestLoader()
+ loader.sortTestMethodsUsing = sortUsing
+ loader.testMethodPrefix = prefix
+ if suiteClass:
+ loader.suiteClass = suiteClass
+ return loader
+
+def getTestCaseNames(testCaseClass, prefix, sortUsing=cmp):
+ return _makeLoader(prefix, sortUsing).getTestCaseNames(testCaseClass)
+
+def makeSuite(testCaseClass, prefix='test', sortUsing=cmp,
+ suiteClass=suite.TestSuite):
+ return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromTestCase(testCaseClass)
+
+def findTestCases(module, prefix='test', sortUsing=cmp,
+ suiteClass=suite.TestSuite):
+ return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromModule(module)
diff --git a/tests/vendor/unittest2/main.py b/tests/vendor/unittest2/main.py
new file mode 100644
index 0000000..9db1d30
--- /dev/null
+++ b/tests/vendor/unittest2/main.py
@@ -0,0 +1,241 @@
+"""Unittest main program"""
+
+import sys
+import os
+import types
+
+from unittest2 import loader, runner
+try:
+ from unittest2.signals import installHandler
+except ImportError:
+ installHandler = None
+
+__unittest = True
+
+FAILFAST = " -f, --failfast Stop on first failure\n"
+CATCHBREAK = " -c, --catch Catch control-C and display results\n"
+BUFFEROUTPUT = " -b, --buffer Buffer stdout and stderr during test runs\n"
+
+USAGE_AS_MAIN = """\
+Usage: %(progName)s [options] [tests]
+
+Options:
+ -h, --help Show this message
+ -v, --verbose Verbose output
+ -q, --quiet Minimal output
+%(failfast)s%(catchbreak)s%(buffer)s
+Examples:
+ %(progName)s test_module - run tests from test_module
+ %(progName)s test_module.TestClass - run tests from
+ test_module.TestClass
+ %(progName)s test_module.TestClass.test_method - run specified test method
+
+[tests] can be a list of any number of test modules, classes and test
+methods.
+
+Alternative Usage: %(progName)s discover [options]
+
+Options:
+ -v, --verbose Verbose output
+%(failfast)s%(catchbreak)s%(buffer)s -s directory Directory to start discovery ('.' default)
+ -p pattern Pattern to match test files ('test*.py' default)
+ -t directory Top level directory of project (default to
+ start directory)
+
+For test discovery all test modules must be importable from the top
+level directory of the project.
+"""
+
+USAGE_FROM_MODULE = """\
+Usage: %(progName)s [options] [test] [...]
+
+Options:
+ -h, --help Show this message
+ -v, --verbose Verbose output
+ -q, --quiet Minimal output
+%(failfast)s%(catchbreak)s%(buffer)s
+Examples:
+ %(progName)s - run default set of tests
+ %(progName)s MyTestSuite - run suite 'MyTestSuite'
+ %(progName)s MyTestCase.testSomething - run MyTestCase.testSomething
+ %(progName)s MyTestCase - run all 'test*' test methods
+ in MyTestCase
+"""
+
+
+class TestProgram(object):
+ """A command-line program that runs a set of tests; this is primarily
+ for making test modules conveniently executable.
+ """
+ USAGE = USAGE_FROM_MODULE
+
+ # defaults for testing
+ failfast = catchbreak = buffer = progName = None
+
+ def __init__(self, module='__main__', defaultTest=None,
+ argv=None, testRunner=None,
+ testLoader=loader.defaultTestLoader, exit=True,
+ verbosity=1, failfast=None, catchbreak=None, buffer=None):
+ if isinstance(module, basestring):
+ self.module = __import__(module)
+ for part in module.split('.')[1:]:
+ self.module = getattr(self.module, part)
+ else:
+ self.module = module
+ if argv is None:
+ argv = sys.argv
+
+ self.exit = exit
+ self.verbosity = verbosity
+ self.failfast = failfast
+ self.catchbreak = catchbreak
+ self.buffer = buffer
+ self.defaultTest = defaultTest
+ self.testRunner = testRunner
+ self.testLoader = testLoader
+ self.progName = os.path.basename(argv[0])
+ self.parseArgs(argv)
+ self.runTests()
+
+ def usageExit(self, msg=None):
+ if msg:
+ print msg
+ usage = {'progName': self.progName, 'catchbreak': '', 'failfast': '',
+ 'buffer': ''}
+ if self.failfast != False:
+ usage['failfast'] = FAILFAST
+ if self.catchbreak != False and installHandler is not None:
+ usage['catchbreak'] = CATCHBREAK
+ if self.buffer != False:
+ usage['buffer'] = BUFFEROUTPUT
+ print self.USAGE % usage
+ sys.exit(2)
+
+ def parseArgs(self, argv):
+ if len(argv) > 1 and argv[1].lower() == 'discover':
+ self._do_discovery(argv[2:])
+ return
+
+ import getopt
+ long_opts = ['help', 'verbose', 'quiet', 'failfast', 'catch', 'buffer']
+ try:
+ options, args = getopt.getopt(argv[1:], 'hHvqfcb', long_opts)
+ for opt, value in options:
+ if opt in ('-h','-H','--help'):
+ self.usageExit()
+ if opt in ('-q','--quiet'):
+ self.verbosity = 0
+ if opt in ('-v','--verbose'):
+ self.verbosity = 2
+ if opt in ('-f','--failfast'):
+ if self.failfast is None:
+ self.failfast = True
+ # Should this raise an exception if -f is not valid?
+ if opt in ('-c','--catch'):
+ if self.catchbreak is None and installHandler is not None:
+ self.catchbreak = True
+ # Should this raise an exception if -c is not valid?
+ if opt in ('-b','--buffer'):
+ if self.buffer is None:
+ self.buffer = True
+ # Should this raise an exception if -b is not valid?
+ if len(args) == 0 and self.defaultTest is None:
+ # createTests will load tests from self.module
+ self.testNames = None
+ elif len(args) > 0:
+ self.testNames = args
+ if __name__ == '__main__':
+ # to support python -m unittest ...
+ self.module = None
+ else:
+ self.testNames = (self.defaultTest,)
+ self.createTests()
+ except getopt.error, msg:
+ self.usageExit(msg)
+
+ def createTests(self):
+ if self.testNames is None:
+ self.test = self.testLoader.loadTestsFromModule(self.module)
+ else:
+ self.test = self.testLoader.loadTestsFromNames(self.testNames,
+ self.module)
+
+ def _do_discovery(self, argv, Loader=loader.TestLoader):
+ # handle command line args for test discovery
+ self.progName = '%s discover' % self.progName
+ import optparse
+ parser = optparse.OptionParser()
+ parser.prog = self.progName
+ parser.add_option('-v', '--verbose', dest='verbose', default=False,
+ help='Verbose output', action='store_true')
+ if self.failfast != False:
+ parser.add_option('-f', '--failfast', dest='failfast', default=False,
+ help='Stop on first fail or error',
+ action='store_true')
+ if self.catchbreak != False and installHandler is not None:
+ parser.add_option('-c', '--catch', dest='catchbreak', default=False,
+ help='Catch ctrl-C and display results so far',
+ action='store_true')
+ if self.buffer != False:
+ parser.add_option('-b', '--buffer', dest='buffer', default=False,
+ help='Buffer stdout and stderr during tests',
+ action='store_true')
+ parser.add_option('-s', '--start-directory', dest='start', default='.',
+ help="Directory to start discovery ('.' default)")
+ parser.add_option('-p', '--pattern', dest='pattern', default='test*.py',
+ help="Pattern to match tests ('test*.py' default)")
+ parser.add_option('-t', '--top-level-directory', dest='top', default=None,
+ help='Top level directory of project (defaults to start directory)')
+
+ options, args = parser.parse_args(argv)
+ if len(args) > 3:
+ self.usageExit()
+
+ for name, value in zip(('start', 'pattern', 'top'), args):
+ setattr(options, name, value)
+
+ # only set options from the parsing here
+ # if they weren't set explicitly in the constructor
+ if self.failfast is None:
+ self.failfast = options.failfast
+ if self.catchbreak is None and installHandler is not None:
+ self.catchbreak = options.catchbreak
+ if self.buffer is None:
+ self.buffer = options.buffer
+
+ if options.verbose:
+ self.verbosity = 2
+
+ start_dir = options.start
+ pattern = options.pattern
+ top_level_dir = options.top
+
+ loader = Loader()
+ self.test = loader.discover(start_dir, pattern, top_level_dir)
+
+ def runTests(self):
+ if self.catchbreak:
+ installHandler()
+ if self.testRunner is None:
+ self.testRunner = runner.TextTestRunner
+ if isinstance(self.testRunner, (type, types.ClassType)):
+ try:
+ testRunner = self.testRunner(verbosity=self.verbosity,
+ failfast=self.failfast,
+ buffer=self.buffer)
+ except TypeError:
+ # didn't accept the verbosity, buffer or failfast arguments
+ testRunner = self.testRunner()
+ else:
+ # it is assumed to be a TestRunner instance
+ testRunner = self.testRunner
+ self.result = testRunner.run(self.test)
+ if self.exit:
+ sys.exit(not self.result.wasSuccessful())
+
+main = TestProgram
+
+def main_():
+ TestProgram.USAGE = USAGE_AS_MAIN
+ main(module=None)
+
diff --git a/tests/vendor/unittest2/result.py b/tests/vendor/unittest2/result.py
new file mode 100644
index 0000000..7770e64
--- /dev/null
+++ b/tests/vendor/unittest2/result.py
@@ -0,0 +1,183 @@
+"""Test result object"""
+
+import sys
+import traceback
+import unittest
+
+from StringIO import StringIO
+
+from unittest2 import util
+from unittest2.compatibility import wraps
+
+__unittest = True
+
+def failfast(method):
+ @wraps(method)
+ def inner(self, *args, **kw):
+ if getattr(self, 'failfast', False):
+ self.stop()
+ return method(self, *args, **kw)
+ return inner
+
+
+STDOUT_LINE = '\nStdout:\n%s'
+STDERR_LINE = '\nStderr:\n%s'
+
+class TestResult(unittest.TestResult):
+ """Holder for test result information.
+
+ Test results are automatically managed by the TestCase and TestSuite
+ classes, and do not need to be explicitly manipulated by writers of tests.
+
+ Each instance holds the total number of tests run, and collections of
+ failures and errors that occurred among those test runs. The collections
+ contain tuples of (testcase, exceptioninfo), where exceptioninfo is the
+ formatted traceback of the error that occurred.
+ """
+ _previousTestClass = None
+ _moduleSetUpFailed = False
+
+ def __init__(self):
+ self.failfast = False
+ self.failures = []
+ self.errors = []
+ self.testsRun = 0
+ self.skipped = []
+ self.expectedFailures = []
+ self.unexpectedSuccesses = []
+ self.shouldStop = False
+ self.buffer = False
+ self._stdout_buffer = None
+ self._stderr_buffer = None
+ self._original_stdout = sys.stdout
+ self._original_stderr = sys.stderr
+ self._mirrorOutput = False
+
+ def startTest(self, test):
+ "Called when the given test is about to be run"
+ self.testsRun += 1
+ self._mirrorOutput = False
+ if self.buffer:
+ if self._stderr_buffer is None:
+ self._stderr_buffer = StringIO()
+ self._stdout_buffer = StringIO()
+ sys.stdout = self._stdout_buffer
+ sys.stderr = self._stderr_buffer
+
+ def startTestRun(self):
+ """Called once before any tests are executed.
+
+ See startTest for a method called before each test.
+ """
+
+ def stopTest(self, test):
+ """Called when the given test has been run"""
+ if self.buffer:
+ if self._mirrorOutput:
+ output = sys.stdout.getvalue()
+ error = sys.stderr.getvalue()
+ if output:
+ if not output.endswith('\n'):
+ output += '\n'
+ self._original_stdout.write(STDOUT_LINE % output)
+ if error:
+ if not error.endswith('\n'):
+ error += '\n'
+ self._original_stderr.write(STDERR_LINE % error)
+
+ sys.stdout = self._original_stdout
+ sys.stderr = self._original_stderr
+ self._stdout_buffer.seek(0)
+ self._stdout_buffer.truncate()
+ self._stderr_buffer.seek(0)
+ self._stderr_buffer.truncate()
+ self._mirrorOutput = False
+
+
+ def stopTestRun(self):
+ """Called once after all tests are executed.
+
+ See stopTest for a method called after each test.
+ """
+
+ @failfast
+ def addError(self, test, err):
+ """Called when an error has occurred. 'err' is a tuple of values as
+ returned by sys.exc_info().
+ """
+ self.errors.append((test, self._exc_info_to_string(err, test)))
+ self._mirrorOutput = True
+
+ @failfast
+ def addFailure(self, test, err):
+ """Called when an error has occurred. 'err' is a tuple of values as
+ returned by sys.exc_info()."""
+ self.failures.append((test, self._exc_info_to_string(err, test)))
+ self._mirrorOutput = True
+
+ def addSuccess(self, test):
+ "Called when a test has completed successfully"
+ pass
+
+ def addSkip(self, test, reason):
+ """Called when a test is skipped."""
+ self.skipped.append((test, reason))
+
+ def addExpectedFailure(self, test, err):
+ """Called when an expected failure/error occured."""
+ self.expectedFailures.append(
+ (test, self._exc_info_to_string(err, test)))
+
+ @failfast
+ def addUnexpectedSuccess(self, test):
+ """Called when a test was expected to fail, but succeed."""
+ self.unexpectedSuccesses.append(test)
+
+ def wasSuccessful(self):
+ "Tells whether or not this result was a success"
+ return (len(self.failures) + len(self.errors) == 0)
+
+ def stop(self):
+ "Indicates that the tests should be aborted"
+ self.shouldStop = True
+
+ def _exc_info_to_string(self, err, test):
+ """Converts a sys.exc_info()-style tuple of values into a string."""
+ exctype, value, tb = err
+ # Skip test runner traceback levels
+ while tb and self._is_relevant_tb_level(tb):
+ tb = tb.tb_next
+ if exctype is test.failureException:
+ # Skip assert*() traceback levels
+ length = self._count_relevant_tb_levels(tb)
+ msgLines = traceback.format_exception(exctype, value, tb, length)
+ else:
+ msgLines = traceback.format_exception(exctype, value, tb)
+
+ if self.buffer:
+ output = sys.stdout.getvalue()
+ error = sys.stderr.getvalue()
+ if output:
+ if not output.endswith('\n'):
+ output += '\n'
+ msgLines.append(STDOUT_LINE % output)
+ if error:
+ if not error.endswith('\n'):
+ error += '\n'
+ msgLines.append(STDERR_LINE % error)
+ return ''.join(msgLines)
+
+ def _is_relevant_tb_level(self, tb):
+ return '__unittest' in tb.tb_frame.f_globals
+
+ def _count_relevant_tb_levels(self, tb):
+ length = 0
+ while tb and not self._is_relevant_tb_level(tb):
+ length += 1
+ tb = tb.tb_next
+ return length
+
+ def __repr__(self):
+ return "<%s run=%i errors=%i failures=%i>" % \
+ (util.strclass(self.__class__), self.testsRun, len(self.errors),
+ len(self.failures))
diff --git a/tests/vendor/unittest2/runner.py b/tests/vendor/unittest2/runner.py
new file mode 100644
index 0000000..15a6f88
--- /dev/null
+++ b/tests/vendor/unittest2/runner.py
@@ -0,0 +1,206 @@
+"""Running tests"""
+
+import sys
+import time
+import unittest
+
+from unittest2 import result
+
+try:
+ from unittest2.signals import registerResult
+except ImportError:
+ def registerResult(_):
+ pass
+
+__unittest = True
+
+
+class _WritelnDecorator(object):
+ """Used to decorate file-like objects with a handy 'writeln' method"""
+ def __init__(self,stream):
+ self.stream = stream
+
+ def __getattr__(self, attr):
+ if attr in ('stream', '__getstate__'):
+ raise AttributeError(attr)
+ return getattr(self.stream,attr)
+
+ def writeln(self, arg=None):
+ if arg:
+ self.write(arg)
+ self.write('\n') # text-mode streams translate to \r\n if needed
+
+
+class TextTestResult(result.TestResult):
+ """A test result class that can print formatted text results to a stream.
+
+ Used by TextTestRunner.
+ """
+ separator1 = '=' * 70
+ separator2 = '-' * 70
+
+ def __init__(self, stream, descriptions, verbosity):
+ super(TextTestResult, self).__init__()
+ self.stream = stream
+ self.showAll = verbosity > 1
+ self.dots = verbosity == 1
+ self.descriptions = descriptions
+
+ def getDescription(self, test):
+ doc_first_line = test.shortDescription()
+ if self.descriptions and doc_first_line:
+ return '\n'.join((str(test), doc_first_line))
+ else:
+ return str(test)
+
+ def startTest(self, test):
+ super(TextTestResult, self).startTest(test)
+ if self.showAll:
+ self.stream.write(self.getDescription(test))
+ self.stream.write(" ... ")
+ self.stream.flush()
+
+ def addSuccess(self, test):
+ super(TextTestResult, self).addSuccess(test)
+ if self.showAll:
+ self.stream.writeln("ok")
+ elif self.dots:
+ self.stream.write('.')
+ self.stream.flush()
+
+ def addError(self, test, err):
+ super(TextTestResult, self).addError(test, err)
+ if self.showAll:
+ self.stream.writeln("ERROR")
+ elif self.dots:
+ self.stream.write('E')
+ self.stream.flush()
+
+ def addFailure(self, test, err):
+ super(TextTestResult, self).addFailure(test, err)
+ if self.showAll:
+ self.stream.writeln("FAIL")
+ elif self.dots:
+ self.stream.write('F')
+ self.stream.flush()
+
+ def addSkip(self, test, reason):
+ super(TextTestResult, self).addSkip(test, reason)
+ if self.showAll:
+ self.stream.writeln("skipped %r" % (reason,))
+ elif self.dots:
+ self.stream.write("s")
+ self.stream.flush()
+
+ def addExpectedFailure(self, test, err):
+ super(TextTestResult, self).addExpectedFailure(test, err)
+ if self.showAll:
+ self.stream.writeln("expected failure")
+ elif self.dots:
+ self.stream.write("x")
+ self.stream.flush()
+
+ def addUnexpectedSuccess(self, test):
+ super(TextTestResult, self).addUnexpectedSuccess(test)
+ if self.showAll:
+ self.stream.writeln("unexpected success")
+ elif self.dots:
+ self.stream.write("u")
+ self.stream.flush()
+
+ def printErrors(self):
+ if self.dots or self.showAll:
+ self.stream.writeln()
+ self.printErrorList('ERROR', self.errors)
+ self.printErrorList('FAIL', self.failures)
+
+ def printErrorList(self, flavour, errors):
+ for test, err in errors:
+ self.stream.writeln(self.separator1)
+ self.stream.writeln("%s: %s" % (flavour, self.getDescription(test)))
+ self.stream.writeln(self.separator2)
+ self.stream.writeln("%s" % err)
+
+ def stopTestRun(self):
+ super(TextTestResult, self).stopTestRun()
+ self.printErrors()
+
+
+class TextTestRunner(unittest.TextTestRunner):
+ """A test runner class that displays results in textual form.
+
+ It prints out the names of tests as they are run, errors as they
+ occur, and a summary of the results at the end of the test run.
+ """
+ resultclass = TextTestResult
+
+ def __init__(self, stream=sys.stderr, descriptions=True, verbosity=1,
+ failfast=False, buffer=False, resultclass=None):
+ self.stream = _WritelnDecorator(stream)
+ self.descriptions = descriptions
+ self.verbosity = verbosity
+ self.failfast = failfast
+ self.buffer = buffer
+ if resultclass is not None:
+ self.resultclass = resultclass
+
+ def _makeResult(self):
+ return self.resultclass(self.stream, self.descriptions, self.verbosity)
+
+ def run(self, test):
+ "Run the given test case or test suite."
+ result = self._makeResult()
+ result.failfast = self.failfast
+ result.buffer = self.buffer
+ registerResult(result)
+
+ startTime = time.time()
+ startTestRun = getattr(result, 'startTestRun', None)
+ if startTestRun is not None:
+ startTestRun()
+ try:
+ test(result)
+ finally:
+ stopTestRun = getattr(result, 'stopTestRun', None)
+ if stopTestRun is not None:
+ stopTestRun()
+ else:
+ result.printErrors()
+ stopTime = time.time()
+ timeTaken = stopTime - startTime
+ if hasattr(result, 'separator2'):
+ self.stream.writeln(result.separator2)
+ run = result.testsRun
+ self.stream.writeln("Ran %d test%s in %.3fs" %
+ (run, run != 1 and "s" or "", timeTaken))
+ self.stream.writeln()
+
+ expectedFails = unexpectedSuccesses = skipped = 0
+ try:
+ results = map(len, (result.expectedFailures,
+ result.unexpectedSuccesses,
+ result.skipped))
+ expectedFails, unexpectedSuccesses, skipped = results
+ except AttributeError:
+ pass
+ infos = []
+ if not result.wasSuccessful():
+ self.stream.write("FAILED")
+ failed, errored = map(len, (result.failures, result.errors))
+ if failed:
+ infos.append("failures=%d" % failed)
+ if errored:
+ infos.append("errors=%d" % errored)
+ else:
+ self.stream.write("OK")
+ if skipped:
+ infos.append("skipped=%d" % skipped)
+ if expectedFails:
+ infos.append("expected failures=%d" % expectedFails)
+ if unexpectedSuccesses:
+ infos.append("unexpected successes=%d" % unexpectedSuccesses)
+ if infos:
+ self.stream.writeln(" (%s)" % (", ".join(infos),))
+ else:
+ self.stream.write("\n")
+ return result
diff --git a/tests/vendor/unittest2/signals.py b/tests/vendor/unittest2/signals.py
new file mode 100644
index 0000000..e40328d
--- /dev/null
+++ b/tests/vendor/unittest2/signals.py
@@ -0,0 +1,57 @@
+import signal
+import weakref
+
+from unittest2.compatibility import wraps
+
+__unittest = True
+
+
+class _InterruptHandler(object):
+ def __init__(self, default_handler):
+ self.called = False
+ self.default_handler = default_handler
+
+ def __call__(self, signum, frame):
+ installed_handler = signal.getsignal(signal.SIGINT)
+ if installed_handler is not self:
+ # if we aren't the installed handler, then delegate immediately
+ # to the default handler
+ self.default_handler(signum, frame)
+
+ if self.called:
+ self.default_handler(signum, frame)
+ self.called = True
+ for result in _results.keys():
+ result.stop()
+
+_results = weakref.WeakKeyDictionary()
+def registerResult(result):
+ _results[result] = 1
+
+def removeResult(result):
+ return bool(_results.pop(result, None))
+
+_interrupt_handler = None
+def installHandler():
+ global _interrupt_handler
+ if _interrupt_handler is None:
+ default_handler = signal.getsignal(signal.SIGINT)
+ _interrupt_handler = _InterruptHandler(default_handler)
+ signal.signal(signal.SIGINT, _interrupt_handler)
+
+
+def removeHandler(method=None):
+ if method is not None:
+ @wraps(method)
+ def inner(*args, **kwargs):
+ initial = signal.getsignal(signal.SIGINT)
+ removeHandler()
+ try:
+ return method(*args, **kwargs)
+ finally:
+ signal.signal(signal.SIGINT, initial)
+ return inner
+
+ global _interrupt_handler
+ if _interrupt_handler is not None:
+ signal.signal(signal.SIGINT, _interrupt_handler.default_handler)
diff --git a/tests/vendor/unittest2/suite.py b/tests/vendor/unittest2/suite.py
new file mode 100644
index 0000000..370ca5f
--- /dev/null
+++ b/tests/vendor/unittest2/suite.py
@@ -0,0 +1,287 @@
+"""TestSuite"""
+
+import sys
+import unittest
+from unittest2 import case, util
+
+__unittest = True
+
+
+class BaseTestSuite(unittest.TestSuite):
+ """A simple test suite that doesn't provide class or module shared fixtures.
+ """
+ def __init__(self, tests=()):
+ self._tests = []
+ self.addTests(tests)
+
+ def __repr__(self):
+ return "<%s tests=%s>" % (util.strclass(self.__class__), list(self))
+
+ def __eq__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return list(self) == list(other)
+
+ def __ne__(self, other):
+ return not self == other
+
+ # Can't guarantee hash invariant, so flag as unhashable
+ __hash__ = None
+
+ def __iter__(self):
+ return iter(self._tests)
+
+ def countTestCases(self):
+ cases = 0
+ for test in self:
+ cases += test.countTestCases()
+ return cases
+
+ def addTest(self, test):
+ # sanity checks
+ if not hasattr(test, '__call__'):
+ raise TypeError("%r is not callable" % (repr(test),))
+ if isinstance(test, type) and issubclass(test,
+ (case.TestCase, TestSuite)):
+ raise TypeError("TestCases and TestSuites must be instantiated "
+ "before passing them to addTest()")
+ self._tests.append(test)
+
+ def addTests(self, tests):
+ if isinstance(tests, basestring):
+ raise TypeError("tests must be an iterable of tests, not a string")
+ for test in tests:
+ self.addTest(test)
+
+ def run(self, result):
+ for test in self:
+ if result.shouldStop:
+ break
+ test(result)
+ return result
+
+ def __call__(self, *args, **kwds):
+ return self.run(*args, **kwds)
+
+ def debug(self):
+ """Run the tests without collecting errors in a TestResult"""
+ for test in self:
+ test.debug()
+
+
+class TestSuite(BaseTestSuite):
+ """A test suite is a composite test consisting of a number of TestCases.
+
+ For use, create an instance of TestSuite, then add test case instances.
+ When all tests have been added, the suite can be passed to a test
+ runner, such as TextTestRunner. It will run the individual test cases
+ in the order in which they were added, aggregating the results. When
+ subclassing, do not forget to call the base class constructor.
+ """
+
+
+ def run(self, result):
+ self._wrapped_run(result)
+ self._tearDownPreviousClass(None, result)
+ self._handleModuleTearDown(result)
+ return result
+
+ def debug(self):
+ """Run the tests without collecting errors in a TestResult"""
+ debug = _DebugResult()
+ self._wrapped_run(debug, True)
+ self._tearDownPreviousClass(None, debug)
+ self._handleModuleTearDown(debug)
+
+ ################################
+ # private methods
+ def _wrapped_run(self, result, debug=False):
+ for test in self:
+ if result.shouldStop:
+ break
+
+ if _isnotsuite(test):
+ self._tearDownPreviousClass(test, result)
+ self._handleModuleFixture(test, result)
+ self._handleClassSetUp(test, result)
+ result._previousTestClass = test.__class__
+
+ if (getattr(test.__class__, '_classSetupFailed', False) or
+ getattr(result, '_moduleSetUpFailed', False)):
+ continue
+
+ if hasattr(test, '_wrapped_run'):
+ test._wrapped_run(result, debug)
+ elif not debug:
+ test(result)
+ else:
+ test.debug()
+
+ def _handleClassSetUp(self, test, result):
+ previousClass = getattr(result, '_previousTestClass', None)
+ currentClass = test.__class__
+ if currentClass == previousClass:
+ return
+ if result._moduleSetUpFailed:
+ return
+ if getattr(currentClass, "__unittest_skip__", False):
+ return
+
+ try:
+ currentClass._classSetupFailed = False
+ except TypeError:
+ # test may actually be a function
+ # so its class will be a builtin-type
+ pass
+
+ setUpClass = getattr(currentClass, 'setUpClass', None)
+ if setUpClass is not None:
+ try:
+ setUpClass()
+ except Exception, e:
+ if isinstance(result, _DebugResult):
+ raise
+ currentClass._classSetupFailed = True
+ className = util.strclass(currentClass)
+ errorName = 'setUpClass (%s)' % className
+ self._addClassOrModuleLevelException(result, e, errorName)
+
+ def _get_previous_module(self, result):
+ previousModule = None
+ previousClass = getattr(result, '_previousTestClass', None)
+ if previousClass is not None:
+ previousModule = previousClass.__module__
+ return previousModule
+
+
+ def _handleModuleFixture(self, test, result):
+ previousModule = self._get_previous_module(result)
+ currentModule = test.__class__.__module__
+ if currentModule == previousModule:
+ return
+
+ self._handleModuleTearDown(result)
+
+
+ result._moduleSetUpFailed = False
+ try:
+ module = sys.modules[currentModule]
+ except KeyError:
+ return
+ setUpModule = getattr(module, 'setUpModule', None)
+ if setUpModule is not None:
+ try:
+ setUpModule()
+ except Exception, e:
+ if isinstance(result, _DebugResult):
+ raise
+ result._moduleSetUpFailed = True
+ errorName = 'setUpModule (%s)' % currentModule
+ self._addClassOrModuleLevelException(result, e, errorName)
+
+ def _addClassOrModuleLevelException(self, result, exception, errorName):
+ error = _ErrorHolder(errorName)
+ addSkip = getattr(result, 'addSkip', None)
+ if addSkip is not None and isinstance(exception, case.SkipTest):
+ addSkip(error, str(exception))
+ else:
+ result.addError(error, sys.exc_info())
+
+ def _handleModuleTearDown(self, result):
+ previousModule = self._get_previous_module(result)
+ if previousModule is None:
+ return
+ if result._moduleSetUpFailed:
+ return
+
+ try:
+ module = sys.modules[previousModule]
+ except KeyError:
+ return
+
+ tearDownModule = getattr(module, 'tearDownModule', None)
+ if tearDownModule is not None:
+ try:
+ tearDownModule()
+ except Exception, e:
+ if isinstance(result, _DebugResult):
+ raise
+ errorName = 'tearDownModule (%s)' % previousModule
+ self._addClassOrModuleLevelException(result, e, errorName)
+
+ def _tearDownPreviousClass(self, test, result):
+ previousClass = getattr(result, '_previousTestClass', None)
+ currentClass = test.__class__
+ if currentClass == previousClass:
+ return
+ if getattr(previousClass, '_classSetupFailed', False):
+ return
+ if getattr(result, '_moduleSetUpFailed', False):
+ return
+ if getattr(previousClass, "__unittest_skip__", False):
+ return
+
+ tearDownClass = getattr(previousClass, 'tearDownClass', None)
+ if tearDownClass is not None:
+ try:
+ tearDownClass()
+ except Exception, e:
+ if isinstance(result, _DebugResult):
+ raise
+ className = util.strclass(previousClass)
+ errorName = 'tearDownClass (%s)' % className
+ self._addClassOrModuleLevelException(result, e, errorName)
+
+
+class _ErrorHolder(object):
+ """
+ Placeholder for a TestCase inside a result. As far as a TestResult
+ is concerned, this looks exactly like a unit test. Used to insert
+ arbitrary errors into a test suite run.
+ """
+ # Inspired by the ErrorHolder from Twisted:
+ # http://twistedmatrix.com/trac/browser/trunk/twisted/trial/runner.py
+
+ # attribute used by TestResult._exc_info_to_string
+ failureException = None
+
+ def __init__(self, description):
+ self.description = description
+
+ def id(self):
+ return self.description
+
+ def shortDescription(self):
+ return None
+
+ def __repr__(self):
+ return "<ErrorHolder description=%r>" % (self.description,)
+
+ def __str__(self):
+ return self.id()
+
+ def run(self, result):
+ # could call result.addError(...) - but this test-like object
+ # shouldn't be run anyway
+ pass
+
+ def __call__(self, result):
+ return self.run(result)
+
+ def countTestCases(self):
+ return 0
+
+def _isnotsuite(test):
+ "A crude way to tell apart testcases and suites with duck-typing"
+ try:
+ iter(test)
+ except TypeError:
+ return True
+ return False
+
+
+class _DebugResult(object):
+ "Used by the TestSuite to hold previous class when running in debug."
+ _previousTestClass = None
+ _moduleSetUpFailed = False
+ shouldStop = False
diff --git a/tests/vendor/unittest2/util.py b/tests/vendor/unittest2/util.py
new file mode 100644
index 0000000..c45d008
--- /dev/null
+++ b/tests/vendor/unittest2/util.py
@@ -0,0 +1,99 @@
+"""Various utility functions."""
+
+__unittest = True
+
+
+_MAX_LENGTH = 80
+def safe_repr(obj, short=False):
+ try:
+ result = repr(obj)
+ except Exception:
+ result = object.__repr__(obj)
+ if not short or len(result) < _MAX_LENGTH:
+ return result
+ return result[:_MAX_LENGTH] + ' [truncated]...'
+
+def safe_str(obj):
+ try:
+ return str(obj)
+ except Exception:
+ return object.__str__(obj)
+
+def strclass(cls):
+ return "%s.%s" % (cls.__module__, cls.__name__)
+
+def sorted_list_difference(expected, actual):
+ """Finds elements in only one or the other of two, sorted input lists.
+
+ Returns a two-element tuple of lists. The first list contains those
+ elements in the "expected" list but not in the "actual" list, and the
+ second contains those elements in the "actual" list but not in the
+ "expected" list. Duplicate elements in either input list are ignored.
+ """
+ i = j = 0
+ missing = []
+ unexpected = []
+ while True:
+ try:
+ e = expected[i]
+ a = actual[j]
+ if e < a:
+ missing.append(e)
+ i += 1
+ while expected[i] == e:
+ i += 1
+ elif e > a:
+ unexpected.append(a)
+ j += 1
+ while actual[j] == a:
+ j += 1
+ else:
+ i += 1
+ try:
+ while expected[i] == e:
+ i += 1
+ finally:
+ j += 1
+ while actual[j] == a:
+ j += 1
+ except IndexError:
+ missing.extend(expected[i:])
+ unexpected.extend(actual[j:])
+ break
+ return missing, unexpected
+
+def unorderable_list_difference(expected, actual, ignore_duplicate=False):
+ """Same behavior as sorted_list_difference but
+ for lists of unorderable items (like dicts).
+
+ As it does a linear search per item (remove) it
+ has O(n*n) performance.
+ """
+ missing = []
+ unexpected = []
+ while expected:
+ item = expected.pop()
+ try:
+ actual.remove(item)
+ except ValueError:
+ missing.append(item)
+ if ignore_duplicate:
+ for lst in expected, actual:
+ try:
+ while True:
+ lst.remove(item)
+ except ValueError:
+ pass
+ if ignore_duplicate:
+ while actual:
+ item = actual.pop()
+ unexpected.append(item)
+ try:
+ while True:
+ actual.remove(item)
+ except ValueError:
+ pass
+ return missing, unexpected
+
+ # anything left in actual is unexpected
+ return missing, actual
diff --git a/tests/x509.der b/tests/x509.der
index fbc9e81..e3d1f11 100644
--- a/tests/x509.der
+++ b/tests/x509.der
Binary files differ
diff --git a/tests/x509.pem b/tests/x509.pem
index 4a1f1ee..bd13265 100644
--- a/tests/x509.pem
+++ b/tests/x509.pem
@@ -1,75 +1,101 @@
Certificate:
Data:
Version: 3 (0x2)
- Serial Number:
- d1:b6:bf:af:06:17:8c:bf
- Signature Algorithm: sha1WithRSAEncryption
+ Serial Number: 2 (0x2)
+ Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, ST=California, O=M2Crypto, CN=Heikki Toivonen
Validity
- Not Before: Jul 28 04:34:34 2009 GMT
- Not After : Jul 26 04:34:34 2019 GMT
+ Not Before: Oct 7 15:12:02 2018 GMT
+ Not After : Oct 4 15:12:02 2028 GMT
Subject: C=US, ST=California, O=M2Crypto, CN=X509
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
- RSA Public Key: (1024 bit)
- Modulus (1024 bit):
- 00:d3:62:55:12:30:b8:dc:84:7c:63:bd:80:1d:19:
- 1a:72:f2:28:f8:59:0b:2a:6b:f2:2a:23:9d:bb:0f:
- 7f:92:5e:dd:27:74:bc:78:0a:27:ab:1c:2e:23:1c:
- 26:77:48:b6:8f:03:ef:57:1c:a0:54:ae:1a:e8:f5:
- 24:a1:46:a1:27:48:55:33:98:fc:db:6a:83:2e:89:
- 3f:e0:f3:91:9d:da:4f:db:74:90:9d:a6:8d:4a:46:
- cb:9f:ba:b8:60:df:ae:ee:22:4b:3f:80:55:f7:1d:
- 89:3c:2b:28:df:46:19:d5:18:ac:e9:07:4e:40:81:
- 75:bc:da:5b:d5:e1:c2:04:15
+ RSA Public-Key: (2048 bit)
+ Modulus:
+ 00:ef:90:05:eb:97:7f:e3:10:d7:09:f4:1d:64:2a:
+ 21:d2:ba:39:e6:2c:81:ea:93:2b:58:af:5d:2e:a3:
+ 34:90:7a:e4:60:af:5a:ef:f1:19:2a:e9:b7:18:43:
+ f3:81:5e:77:4c:19:82:6f:00:4a:41:94:29:5a:0a:
+ 43:1a:a4:e9:c3:48:a8:66:04:ca:ee:ea:01:b6:54:
+ 02:1e:46:1a:a1:de:56:d1:47:6b:ab:09:20:d5:63:
+ b3:b4:c7:84:bd:02:1d:79:56:8a:f1:f4:d6:27:72:
+ b4:15:d2:5f:7a:73:db:d0:8f:0a:51:05:be:e7:79:
+ 0b:39:2a:d6:65:89:7d:d3:93:b5:25:8d:ce:9e:bb:
+ 67:7b:39:4a:83:2e:5d:e2:de:fd:e9:30:81:51:f4:
+ 1b:34:4b:d2:76:a0:9f:38:a8:53:6e:d9:9b:99:16:
+ 18:d7:41:5b:0e:e4:e4:a7:4c:cd:38:d3:ae:24:a0:
+ ce:0f:1e:4f:25:24:a3:31:e6:94:97:92:f8:f5:4b:
+ 48:4b:5b:c1:cc:95:b8:4d:c6:66:c1:5c:3e:24:4f:
+ b4:f3:98:f5:03:91:43:9b:de:a8:71:15:ef:2d:84:
+ 69:c7:35:02:fa:0f:41:95:cf:9e:b5:15:4f:7a:c6:
+ 2d:04:61:93:54:74:26:df:cc:22:2b:f7:c2:e8:06:
+ 04:0b
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
- Netscape Comment:
- OpenSSL Generated Certificate
X509v3 Subject Key Identifier:
- B1:C4:6F:98:6F:E8:3B:8C:A1:26:11:81:97:9A:12:50:4A:1A:6C:88
- X509v3 Authority Key Identifier:
- keyid:AD:64:45:74:8F:83:C7:2C:D5:D7:A0:85:91:10:40:9A:9C:96:CF:EE
-
- Signature Algorithm: sha1WithRSAEncryption
- 3f:0b:44:bc:d2:da:5f:a9:39:be:08:53:e6:fd:10:ff:d6:f0:
- a3:51:f6:be:03:20:cc:b3:52:cf:0f:7c:3f:56:42:6f:9d:72:
- 9b:09:a5:64:3f:43:29:24:2b:d6:79:94:54:2f:99:e8:ce:fe:
- fd:de:bb:ca:43:28:16:ff:32:ac:3d:c5:56:db:87:23:3c:d4:
- 69:f7:4e:1b:c4:be:c9:d8:27:99:2a:64:be:3a:6b:7e:51:85:
- db:75:35:40:a5:6c:ae:53:c3:09:e7:00:35:17:64:1a:17:71:
- c5:d5:59:e5:8f:fc:96:4a:f9:81:33:23:4c:c1:60:71:93:18:
- 0a:c4
+ AD:29:34:8E:8E:5A:8A:93:76:3C:ED:9F:2C:E6:6A:18:D2:D0:AF:C2
+ Signature Algorithm: sha256WithRSAEncryption
+ 35:d2:e4:c4:eb:01:ea:25:bc:31:91:06:6d:38:c0:86:f4:ad:
+ ef:59:f1:fa:f7:f1:26:04:4f:a3:92:4d:ea:7c:6a:8e:94:4d:
+ 59:cf:55:3e:d2:21:19:e1:ec:1f:01:89:53:80:1e:3d:c1:23:
+ 44:71:3d:f0:43:f4:3e:c7:d6:0e:45:62:64:7f:68:71:87:fe:
+ 26:5f:a5:13:ce:05:ae:66:1a:2a:f0:98:4a:62:23:19:44:22:
+ cf:0f:38:be:0d:ec:60:fd:45:f3:29:c2:cd:f5:1d:6d:44:05:
+ 11:ac:d2:a3:2f:63:3f:5e:7e:34:3c:fb:f6:70:2f:ae:d3:50:
+ 16:57:57:58:ba:41:a0:65:f3:45:a9:f6:ae:2f:a1:8f:83:84:
+ 59:4a:75:c4:58:b2:6b:4b:b5:25:5f:5a:a0:dd:d9:18:e2:d7:
+ a9:5a:da:0a:83:15:ab:08:a7:98:86:e2:fa:ba:4f:47:70:b6:
+ 90:70:8d:05:ca:08:a9:94:be:27:af:43:a9:6e:ec:12:6a:b2:
+ 8e:83:26:b8:72:cd:63:9b:19:a1:c9:ff:b2:c5:cf:ec:ce:7a:
+ 13:b8:dd:06:9f:55:85:0d:23:a1:ae:5e:50:67:57:b4:8d:e3:
+ 49:0f:c0:ee:42:06:64:6d:72:c4:7b:2b:7d:87:28:17:36:59:
+ 01:44:dc:38
-----BEGIN CERTIFICATE-----
-MIICjDCCAfWgAwIBAgIJANG2v68GF4y/MA0GCSqGSIb3DQEBBQUAME8xCzAJBgNV
-BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMREwDwYDVQQKEwhNMkNyeXB0bzEY
-MBYGA1UEAxMPSGVpa2tpIFRvaXZvbmVuMB4XDTA5MDcyODA0MzQzNFoXDTE5MDcy
-NjA0MzQzNFowRDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExETAP
-BgNVBAoTCE0yQ3J5cHRvMQ0wCwYDVQQDEwRYNTA5MIGfMA0GCSqGSIb3DQEBAQUA
-A4GNADCBiQKBgQDTYlUSMLjchHxjvYAdGRpy8ij4WQsqa/IqI527D3+SXt0ndLx4
-CierHC4jHCZ3SLaPA+9XHKBUrhro9SShRqEnSFUzmPzbaoMuiT/g85Gd2k/bdJCd
-po1KRsufurhg367uIks/gFX3HYk8KyjfRhnVGKzpB05AgXW82lvV4cIEFQIDAQAB
-o3sweTAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRl
-ZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUscRvmG/oO4yhJhGBl5oSUEoabIgwHwYD
-VR0jBBgwFoAUrWRFdI+DxyzV16CFkRBAmpyWz+4wDQYJKoZIhvcNAQEFBQADgYEA
-PwtEvNLaX6k5vghT5v0Q/9bwo1H2vgMgzLNSzw98P1ZCb51ymwmlZD9DKSQr1nmU
-VC+Z6M7+/d67ykMoFv8yrD3FVtuHIzzUafdOG8S+ydgnmSpkvjprflGF23U1QKVs
-rlPDCecANRdkGhdxxdVZ5Y/8lkr5gTMjTMFgcZMYCsQ=
+MIIDOjCCAiKgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBPMQswCQYDVQQGEwJVUzET
+MBEGA1UECAwKQ2FsaWZvcm5pYTERMA8GA1UECgwITTJDcnlwdG8xGDAWBgNVBAMM
+D0hlaWtraSBUb2l2b25lbjAeFw0xODEwMDcxNTEyMDJaFw0yODEwMDQxNTEyMDJa
+MEQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMREwDwYDVQQKDAhN
+MkNyeXB0bzENMAsGA1UEAwwEWDUwOTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
+AQoCggEBAO+QBeuXf+MQ1wn0HWQqIdK6OeYsgeqTK1ivXS6jNJB65GCvWu/xGSrp
+txhD84Fed0wZgm8ASkGUKVoKQxqk6cNIqGYEyu7qAbZUAh5GGqHeVtFHa6sJINVj
+s7THhL0CHXlWivH01idytBXSX3pz29CPClEFvud5Czkq1mWJfdOTtSWNzp67Z3s5
+SoMuXeLe/ekwgVH0GzRL0nagnzioU27Zm5kWGNdBWw7k5KdMzTjTriSgzg8eTyUk
+ozHmlJeS+PVLSEtbwcyVuE3GZsFcPiRPtPOY9QORQ5veqHEV7y2Eacc1AvoPQZXP
+nrUVT3rGLQRhk1R0Jt/MIiv3wugGBAsCAwEAAaMsMCowCQYDVR0TBAIwADAdBgNV
+HQ4EFgQUrSk0jo5aipN2PO2fLOZqGNLQr8IwDQYJKoZIhvcNAQELBQADggEBADXS
+5MTrAeolvDGRBm04wIb0re9Z8fr38SYET6OSTep8ao6UTVnPVT7SIRnh7B8BiVOA
+Hj3BI0RxPfBD9D7H1g5FYmR/aHGH/iZfpRPOBa5mGirwmEpiIxlEIs8POL4N7GD9
+RfMpws31HW1EBRGs0qMvYz9efjQ8+/ZwL67TUBZXV1i6QaBl80Wp9q4voY+DhFlK
+dcRYsmtLtSVfWqDd2Rji16la2gqDFasIp5iG4vq6T0dwtpBwjQXKCKmUvievQ6lu
+7BJqso6DJrhyzWObGaHJ/7LFz+zOehO43QafVYUNI6GuXlBnV7SN40kPwO5CBmRt
+csR7K32HKBc2WQFE3Dg=
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
-MIICXQIBAAKBgQDTYlUSMLjchHxjvYAdGRpy8ij4WQsqa/IqI527D3+SXt0ndLx4
-CierHC4jHCZ3SLaPA+9XHKBUrhro9SShRqEnSFUzmPzbaoMuiT/g85Gd2k/bdJCd
-po1KRsufurhg367uIks/gFX3HYk8KyjfRhnVGKzpB05AgXW82lvV4cIEFQIDAQAB
-AoGATPipcY48QlAb21XNqMrTTrfPI1+JKVFVRPLjJJJoKaxRa2SenDdWaoBAbJh7
-iUP49erA5D+QQkWDlwBs7i0B0NqSkZAUVTfzRjGackTNJUQ+smfeqRLMH+Oru6DS
-VFbb818nJOJKqMMhMz8SrPrrbg+qiHlJ3JUQnNzTYohOMAECQQDvTJBSSit34ZBO
-ABj4vWYucCnOygcpICQnIsG97sZmF8tuF55tA5e+0v9R7BPuyAjrQnKJqDj3r/AY
-AxhgngGVAkEA4iMGoHzoSQvh+gT0A2rPCtVo+URNswIEZhQmMuA0VjrFCphWkZE+
-3jgDsJTNQUJs4mczQMcBzL34Nh1cJThYgQJARMMrdXn6o6gdX0yH4HIMOqvgV5uW
-Eys5OEW0hm9mc0/DFQ+UZp7xq9PVqiS8VZEFfxTI9OVx+TqFM2EwUBMXQQJBAIge
-n0mRhl0Z6v+NZbh83X3e8h5BUCf1ieJMNKYhMT/KhnsXMdzTui0XOJldKKQksNgj
-WMWgROQSYctpJuM8pIECQQCNN27XVHs4YAQ6GvBkrHsK5w6LZkm6UaJgbCqDqyeS
-eqfPp9VRurZ/FhK1mPbgNN67U4Ik1nwjR0o8wD4mreIj
+MIIEpAIBAAKCAQEA75AF65d/4xDXCfQdZCoh0ro55iyB6pMrWK9dLqM0kHrkYK9a
+7/EZKum3GEPzgV53TBmCbwBKQZQpWgpDGqTpw0ioZgTK7uoBtlQCHkYaod5W0Udr
+qwkg1WOztMeEvQIdeVaK8fTWJ3K0FdJfenPb0I8KUQW+53kLOSrWZYl905O1JY3O
+nrtnezlKgy5d4t796TCBUfQbNEvSdqCfOKhTbtmbmRYY10FbDuTkp0zNONOuJKDO
+Dx5PJSSjMeaUl5L49UtIS1vBzJW4TcZmwVw+JE+085j1A5FDm96ocRXvLYRpxzUC
++g9Blc+etRVPesYtBGGTVHQm38wiK/fC6AYECwIDAQABAoIBAQCR6lmQzDB7L9Cr
+IWOdlQQRBJkrl8RyCr4GQJozQ/lKX3Ana+ep6mJ3/u8k+o6hJ9bmJUuLLNQN6Z7e
+Vw3Udspjxie8LAMnTqVIVxcLNYwXOAQNaMEt5lt3XkkhPb2eGmG1fH8ZLRYb5QPH
+nuHFBjjHabjQ7P0ApHuvkGYSZpKbgVjEIwWxCPlzMo0XmePK0dJVAxsmtNFSoJkD
+6UOwX8HN79thbSLwyCSnUUkHbglHLqgBvgLY4uW7BBMuFFW6v1jp1YR3gqhzrHgW
+q43WIOEJBBvoI1it8TA7N28IjiA/G+DKeM3KNYAc5m30iXtq+ky/G9xdrhOEDZTs
+mj4JInkhAoGBAPwZAmT1aZuftPp90IRATESrxGo0n1uZsF9CBur8+dZKPTgGrtfJ
+e+1yh+LKvowY0a4B82nehq0FcHsSjBHXRbwgHd4KSYV0LCc5ZwxQlPg9FKtziFmm
+RYPGanpNEdJ8tz0Wj67gP2aIHRaauFxTwSoXyfvrYLWHnvMotUH6QOejAoGBAPNF
+VzyJwzdT8WKx8CaWmIoSglE0wIcRtnOgHxZUuNnxdjjnRYgMQDE3GaDnK0TzyH4c
+3ewasxCVnfqTR9zPeyu3AdeaxWgOJGirYPQM3qxv85n/7BKGeBoAA3yf9kEpIw9h
+M80i1VfgXaRJ+ldwMgVJu5klG0jm/YCFzF6O7dh5AoGANUG/TL6/qb3KiOSNaXL/
+6b3zx5AIXlyQcv9K4NfCm++hETXwN+v7v0TjyhiUupn/qegFmUcGYoT0pzta1eYJ
+eF28kYzQzV2mej7ZMzPO1MZqmHHWy0GiC92d3uprKnFocIJUplf/bNSyeHUFH5Qe
+CZtu80ZdbtwQy0O9TwvkLEsCgYEAx6qcBUYVAi5Vqunc7+8e2ASFDV28v5+cHp7H
+pS54Yfk7TU0U1qsnbL2KvXO/IeLtJgVPaGAppG0Iswd7LhLlR2X3jxyq9dLVs0sm
+UmjVwrZIPJe/DR1tKfnk4r7wAV9gNVlUiQQUEwJGGXfWjzm49HomDXZVRKrCWmB2
+8w1gzhECgYBAKhY8brV3bKSKarmlqWV4bhFuxZ8BpY9e3l0MxX3/eHqdimbQEptA
+Q6aownp7nurRf9i1m8u1+zbp6efcweEaA9BR+bX0gaGgbDhUY1dQ0/YLUX1Pv5OE
+zxCUdc9xW3qTt9Pp/kglGCqM7Nrm71cV86FDHbjDUwY5MzvD1ZLQWg==
-----END RSA PRIVATE KEY-----
diff --git a/tests/x509_key.pem b/tests/x509_key.pem
new file mode 100644
index 0000000..0615b4d
--- /dev/null
+++ b/tests/x509_key.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEA75AF65d/4xDXCfQdZCoh0ro55iyB6pMrWK9dLqM0kHrkYK9a
+7/EZKum3GEPzgV53TBmCbwBKQZQpWgpDGqTpw0ioZgTK7uoBtlQCHkYaod5W0Udr
+qwkg1WOztMeEvQIdeVaK8fTWJ3K0FdJfenPb0I8KUQW+53kLOSrWZYl905O1JY3O
+nrtnezlKgy5d4t796TCBUfQbNEvSdqCfOKhTbtmbmRYY10FbDuTkp0zNONOuJKDO
+Dx5PJSSjMeaUl5L49UtIS1vBzJW4TcZmwVw+JE+085j1A5FDm96ocRXvLYRpxzUC
++g9Blc+etRVPesYtBGGTVHQm38wiK/fC6AYECwIDAQABAoIBAQCR6lmQzDB7L9Cr
+IWOdlQQRBJkrl8RyCr4GQJozQ/lKX3Ana+ep6mJ3/u8k+o6hJ9bmJUuLLNQN6Z7e
+Vw3Udspjxie8LAMnTqVIVxcLNYwXOAQNaMEt5lt3XkkhPb2eGmG1fH8ZLRYb5QPH
+nuHFBjjHabjQ7P0ApHuvkGYSZpKbgVjEIwWxCPlzMo0XmePK0dJVAxsmtNFSoJkD
+6UOwX8HN79thbSLwyCSnUUkHbglHLqgBvgLY4uW7BBMuFFW6v1jp1YR3gqhzrHgW
+q43WIOEJBBvoI1it8TA7N28IjiA/G+DKeM3KNYAc5m30iXtq+ky/G9xdrhOEDZTs
+mj4JInkhAoGBAPwZAmT1aZuftPp90IRATESrxGo0n1uZsF9CBur8+dZKPTgGrtfJ
+e+1yh+LKvowY0a4B82nehq0FcHsSjBHXRbwgHd4KSYV0LCc5ZwxQlPg9FKtziFmm
+RYPGanpNEdJ8tz0Wj67gP2aIHRaauFxTwSoXyfvrYLWHnvMotUH6QOejAoGBAPNF
+VzyJwzdT8WKx8CaWmIoSglE0wIcRtnOgHxZUuNnxdjjnRYgMQDE3GaDnK0TzyH4c
+3ewasxCVnfqTR9zPeyu3AdeaxWgOJGirYPQM3qxv85n/7BKGeBoAA3yf9kEpIw9h
+M80i1VfgXaRJ+ldwMgVJu5klG0jm/YCFzF6O7dh5AoGANUG/TL6/qb3KiOSNaXL/
+6b3zx5AIXlyQcv9K4NfCm++hETXwN+v7v0TjyhiUupn/qegFmUcGYoT0pzta1eYJ
+eF28kYzQzV2mej7ZMzPO1MZqmHHWy0GiC92d3uprKnFocIJUplf/bNSyeHUFH5Qe
+CZtu80ZdbtwQy0O9TwvkLEsCgYEAx6qcBUYVAi5Vqunc7+8e2ASFDV28v5+cHp7H
+pS54Yfk7TU0U1qsnbL2KvXO/IeLtJgVPaGAppG0Iswd7LhLlR2X3jxyq9dLVs0sm
+UmjVwrZIPJe/DR1tKfnk4r7wAV9gNVlUiQQUEwJGGXfWjzm49HomDXZVRKrCWmB2
+8w1gzhECgYBAKhY8brV3bKSKarmlqWV4bhFuxZ8BpY9e3l0MxX3/eHqdimbQEptA
+Q6aownp7nurRf9i1m8u1+zbp6efcweEaA9BR+bX0gaGgbDhUY1dQ0/YLUX1Pv5OE
+zxCUdc9xW3qTt9Pp/kglGCqM7Nrm71cV86FDHbjDUwY5MzvD1ZLQWg==
+-----END RSA PRIVATE KEY-----