From bbf99577b2f9d071728f2e76263b14bf8f1d7580 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C4=9Bj=20Cepl?= Date: Thu, 20 Apr 2017 23:52:50 +0200 Subject: Add generated HTML docs. --- doc/doctrees/M2Crypto.PGP.doctree | Bin 0 -> 86275 bytes doc/doctrees/M2Crypto.SSL.doctree | Bin 0 -> 349777 bytes doc/doctrees/M2Crypto.doctree | Bin 0 -> 1257651 bytes doc/doctrees/ZServerSSL-HOWTO.doctree | Bin 0 -> 49245 bytes doc/doctrees/environment.pickle | Bin 0 -> 459094 bytes doc/doctrees/howto.ca.doctree | Bin 0 -> 51373 bytes doc/doctrees/howto.smime.doctree | Bin 0 -> 94672 bytes doc/doctrees/howto.ssl.doctree | Bin 0 -> 22402 bytes doc/doctrees/index.doctree | Bin 0 -> 7232 bytes doc/html/.buildinfo | 4 + doc/html/M2Crypto.PGP.html | 414 ++ doc/html/M2Crypto.SSL.html | 1606 +++++++ doc/html/M2Crypto.html | 4720 ++++++++++++++++++++ doc/html/ZServerSSL-HOWTO.html | 359 ++ doc/html/_modules/M2Crypto/ASN1.html | 347 ++ doc/html/_modules/M2Crypto/AuthCookie.html | 263 ++ doc/html/_modules/M2Crypto/BIO.html | 472 ++ doc/html/_modules/M2Crypto/BN.html | 152 + doc/html/_modules/M2Crypto/DH.html | 209 + doc/html/_modules/M2Crypto/DSA.html | 550 +++ doc/html/_modules/M2Crypto/EC.html | 553 +++ doc/html/_modules/M2Crypto/EVP.html | 569 +++ doc/html/_modules/M2Crypto/Engine.html | 239 + doc/html/_modules/M2Crypto/Err.html | 162 + doc/html/_modules/M2Crypto/PGP/PublicKey.html | 169 + doc/html/_modules/M2Crypto/PGP/PublicKeyRing.html | 192 + doc/html/_modules/M2Crypto/PGP/RSA.html | 122 + doc/html/_modules/M2Crypto/PGP/packet.html | 514 +++ doc/html/_modules/M2Crypto/RC4.html | 130 + doc/html/_modules/M2Crypto/RSA.html | 557 +++ doc/html/_modules/M2Crypto/Rand.html | 127 + doc/html/_modules/M2Crypto/SMIME.html | 416 ++ doc/html/_modules/M2Crypto/SSL.html | 134 + doc/html/_modules/M2Crypto/SSL/Checker.html | 393 ++ doc/html/_modules/M2Crypto/SSL/Cipher.html | 156 + doc/html/_modules/M2Crypto/SSL/Connection.html | 719 +++ doc/html/_modules/M2Crypto/SSL/Context.html | 542 +++ doc/html/_modules/M2Crypto/SSL/SSLServer.html | 157 + doc/html/_modules/M2Crypto/SSL/Session.html | 167 + .../M2Crypto/SSL/TwistedProtocolWrapper.html | 518 +++ doc/html/_modules/M2Crypto/SSL/cb.html | 192 + doc/html/_modules/M2Crypto/SSL/ssl_dispatcher.html | 139 + doc/html/_modules/M2Crypto/SSL/timeout.html | 130 + doc/html/_modules/M2Crypto/X509.html | 1504 +++++++ doc/html/_modules/M2Crypto/ftpslib.html | 185 + doc/html/_modules/M2Crypto/httpslib.html | 355 ++ doc/html/_modules/M2Crypto/m2crypto.html | 172 + doc/html/_modules/M2Crypto/m2urllib.html | 207 + doc/html/_modules/M2Crypto/m2urllib2.html | 274 ++ doc/html/_modules/M2Crypto/m2xmlrpclib.html | 173 + doc/html/_modules/M2Crypto/threading.html | 119 + doc/html/_modules/M2Crypto/util.html | 223 + doc/html/_modules/index.html | 129 + doc/html/_sources/M2Crypto.PGP.txt | 51 + doc/html/_sources/M2Crypto.SSL.txt | 91 + doc/html/_sources/M2Crypto.txt | 219 + doc/html/_sources/ZServerSSL-HOWTO.txt | 239 + doc/html/_sources/howto.ca.txt | 370 ++ doc/html/_sources/howto.smime.txt | 778 ++++ doc/html/_sources/howto.ssl.txt | 131 + doc/html/_sources/index.txt | 30 + doc/html/_static/ajax-loader.gif | Bin 0 -> 673 bytes doc/html/_static/basic.css | 540 +++ doc/html/_static/comment-bright.png | Bin 0 -> 3500 bytes doc/html/_static/comment-close.png | Bin 0 -> 3578 bytes doc/html/_static/comment.png | Bin 0 -> 3445 bytes doc/html/_static/default.css | 256 ++ doc/html/_static/doctools.js | 247 + doc/html/_static/down-pressed.png | Bin 0 -> 368 bytes doc/html/_static/down.png | Bin 0 -> 363 bytes doc/html/_static/file.png | Bin 0 -> 392 bytes doc/html/_static/jquery.js | 154 + doc/html/_static/minus.png | Bin 0 -> 199 bytes doc/html/_static/plus.png | Bin 0 -> 199 bytes doc/html/_static/pygments.css | 65 + doc/html/_static/searchtools.js | 560 +++ doc/html/_static/sidebar.js | 151 + doc/html/_static/underscore.js | 23 + doc/html/_static/up-pressed.png | Bin 0 -> 372 bytes doc/html/_static/up.png | Bin 0 -> 363 bytes doc/html/_static/websupport.js | 808 ++++ doc/html/genindex.html | 3258 ++++++++++++++ doc/html/howto.ca.html | 469 ++ doc/html/howto.smime.html | 847 ++++ doc/html/howto.ssl.html | 220 + doc/html/index.html | 194 + doc/html/objects.inv | Bin 0 -> 5904 bytes doc/html/py-modindex.html | 326 ++ doc/html/search.html | 105 + doc/html/searchindex.js | 1 + 90 files changed, 29567 insertions(+) create mode 100644 doc/doctrees/M2Crypto.PGP.doctree create mode 100644 doc/doctrees/M2Crypto.SSL.doctree create mode 100644 doc/doctrees/M2Crypto.doctree create mode 100644 doc/doctrees/ZServerSSL-HOWTO.doctree create mode 100644 doc/doctrees/environment.pickle create mode 100644 doc/doctrees/howto.ca.doctree create mode 100644 doc/doctrees/howto.smime.doctree create mode 100644 doc/doctrees/howto.ssl.doctree create mode 100644 doc/doctrees/index.doctree create mode 100644 doc/html/.buildinfo create mode 100644 doc/html/M2Crypto.PGP.html create mode 100644 doc/html/M2Crypto.SSL.html create mode 100644 doc/html/M2Crypto.html create mode 100644 doc/html/ZServerSSL-HOWTO.html create mode 100644 doc/html/_modules/M2Crypto/ASN1.html create mode 100644 doc/html/_modules/M2Crypto/AuthCookie.html create mode 100644 doc/html/_modules/M2Crypto/BIO.html create mode 100644 doc/html/_modules/M2Crypto/BN.html create mode 100644 doc/html/_modules/M2Crypto/DH.html create mode 100644 doc/html/_modules/M2Crypto/DSA.html create mode 100644 doc/html/_modules/M2Crypto/EC.html create mode 100644 doc/html/_modules/M2Crypto/EVP.html create mode 100644 doc/html/_modules/M2Crypto/Engine.html create mode 100644 doc/html/_modules/M2Crypto/Err.html create mode 100644 doc/html/_modules/M2Crypto/PGP/PublicKey.html create mode 100644 doc/html/_modules/M2Crypto/PGP/PublicKeyRing.html create mode 100644 doc/html/_modules/M2Crypto/PGP/RSA.html create mode 100644 doc/html/_modules/M2Crypto/PGP/packet.html create mode 100644 doc/html/_modules/M2Crypto/RC4.html create mode 100644 doc/html/_modules/M2Crypto/RSA.html create mode 100644 doc/html/_modules/M2Crypto/Rand.html create mode 100644 doc/html/_modules/M2Crypto/SMIME.html create mode 100644 doc/html/_modules/M2Crypto/SSL.html create mode 100644 doc/html/_modules/M2Crypto/SSL/Checker.html create mode 100644 doc/html/_modules/M2Crypto/SSL/Cipher.html create mode 100644 doc/html/_modules/M2Crypto/SSL/Connection.html create mode 100644 doc/html/_modules/M2Crypto/SSL/Context.html create mode 100644 doc/html/_modules/M2Crypto/SSL/SSLServer.html create mode 100644 doc/html/_modules/M2Crypto/SSL/Session.html create mode 100644 doc/html/_modules/M2Crypto/SSL/TwistedProtocolWrapper.html create mode 100644 doc/html/_modules/M2Crypto/SSL/cb.html create mode 100644 doc/html/_modules/M2Crypto/SSL/ssl_dispatcher.html create mode 100644 doc/html/_modules/M2Crypto/SSL/timeout.html create mode 100644 doc/html/_modules/M2Crypto/X509.html create mode 100644 doc/html/_modules/M2Crypto/ftpslib.html create mode 100644 doc/html/_modules/M2Crypto/httpslib.html create mode 100644 doc/html/_modules/M2Crypto/m2crypto.html create mode 100644 doc/html/_modules/M2Crypto/m2urllib.html create mode 100644 doc/html/_modules/M2Crypto/m2urllib2.html create mode 100644 doc/html/_modules/M2Crypto/m2xmlrpclib.html create mode 100644 doc/html/_modules/M2Crypto/threading.html create mode 100644 doc/html/_modules/M2Crypto/util.html create mode 100644 doc/html/_modules/index.html create mode 100644 doc/html/_sources/M2Crypto.PGP.txt create mode 100644 doc/html/_sources/M2Crypto.SSL.txt create mode 100644 doc/html/_sources/M2Crypto.txt create mode 100644 doc/html/_sources/ZServerSSL-HOWTO.txt create mode 100644 doc/html/_sources/howto.ca.txt create mode 100644 doc/html/_sources/howto.smime.txt create mode 100644 doc/html/_sources/howto.ssl.txt create mode 100644 doc/html/_sources/index.txt create mode 100644 doc/html/_static/ajax-loader.gif create mode 100644 doc/html/_static/basic.css create mode 100644 doc/html/_static/comment-bright.png create mode 100644 doc/html/_static/comment-close.png create mode 100644 doc/html/_static/comment.png create mode 100644 doc/html/_static/default.css create mode 100644 doc/html/_static/doctools.js create mode 100644 doc/html/_static/down-pressed.png create mode 100644 doc/html/_static/down.png create mode 100644 doc/html/_static/file.png create mode 100644 doc/html/_static/jquery.js create mode 100644 doc/html/_static/minus.png create mode 100644 doc/html/_static/plus.png create mode 100644 doc/html/_static/pygments.css create mode 100644 doc/html/_static/searchtools.js create mode 100644 doc/html/_static/sidebar.js create mode 100644 doc/html/_static/underscore.js create mode 100644 doc/html/_static/up-pressed.png create mode 100644 doc/html/_static/up.png create mode 100644 doc/html/_static/websupport.js create mode 100644 doc/html/genindex.html create mode 100644 doc/html/howto.ca.html create mode 100644 doc/html/howto.smime.html create mode 100644 doc/html/howto.ssl.html create mode 100644 doc/html/index.html create mode 100644 doc/html/objects.inv create mode 100644 doc/html/py-modindex.html create mode 100644 doc/html/search.html create mode 100644 doc/html/searchindex.js (limited to 'doc') diff --git a/doc/doctrees/M2Crypto.PGP.doctree b/doc/doctrees/M2Crypto.PGP.doctree new file mode 100644 index 0000000..85f452c Binary files /dev/null and b/doc/doctrees/M2Crypto.PGP.doctree differ diff --git a/doc/doctrees/M2Crypto.SSL.doctree b/doc/doctrees/M2Crypto.SSL.doctree new file mode 100644 index 0000000..3ccda5f Binary files /dev/null and b/doc/doctrees/M2Crypto.SSL.doctree differ diff --git a/doc/doctrees/M2Crypto.doctree b/doc/doctrees/M2Crypto.doctree new file mode 100644 index 0000000..73f49b8 Binary files /dev/null and b/doc/doctrees/M2Crypto.doctree differ diff --git a/doc/doctrees/ZServerSSL-HOWTO.doctree b/doc/doctrees/ZServerSSL-HOWTO.doctree new file mode 100644 index 0000000..3c2a9fc Binary files /dev/null and b/doc/doctrees/ZServerSSL-HOWTO.doctree differ diff --git a/doc/doctrees/environment.pickle b/doc/doctrees/environment.pickle new file mode 100644 index 0000000..d4e74d6 Binary files /dev/null and b/doc/doctrees/environment.pickle differ diff --git a/doc/doctrees/howto.ca.doctree b/doc/doctrees/howto.ca.doctree new file mode 100644 index 0000000..124cf99 Binary files /dev/null and b/doc/doctrees/howto.ca.doctree differ diff --git a/doc/doctrees/howto.smime.doctree b/doc/doctrees/howto.smime.doctree new file mode 100644 index 0000000..3329844 Binary files /dev/null and b/doc/doctrees/howto.smime.doctree differ diff --git a/doc/doctrees/howto.ssl.doctree b/doc/doctrees/howto.ssl.doctree new file mode 100644 index 0000000..438b79b Binary files /dev/null and b/doc/doctrees/howto.ssl.doctree differ diff --git a/doc/doctrees/index.doctree b/doc/doctrees/index.doctree new file mode 100644 index 0000000..281514e Binary files /dev/null and b/doc/doctrees/index.doctree differ diff --git a/doc/html/.buildinfo b/doc/html/.buildinfo new file mode 100644 index 0000000..d49bc3a --- /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: 2ba17edb1c13f7cef17e22ec0437fce4 +tags: fbb0d17656682115ca4d033fb2f83ba1 diff --git a/doc/html/M2Crypto.PGP.html b/doc/html/M2Crypto.PGP.html new file mode 100644 index 0000000..b64f7a2 --- /dev/null +++ b/doc/html/M2Crypto.PGP.html @@ -0,0 +1,414 @@ + + + + + + + + + + PGP Package — M2Crypto documentation + + + + + + + + + + + + + + + + +
+
+
+
+ +
+

PGP Package

+
+

PGP Package

+
+
+

PublicKey Module

+
+
+class M2Crypto.PGP.PublicKey.PublicKey(pubkey_pkt)[source]
+
+
+add_signature(userid, s_pkt)[source]
+
+ +
+
+add_userid(u_pkt)[source]
+
+ +
+
+decrypt(ctxt)[source]
+
+ +
+
+encrypt(ptxt)[source]
+
+ +
+
+keyid()[source]
+
+ +
+
+remove_userid(userid)[source]
+
+ +
+
+write(stream)[source]
+
+ +
+ +
+
+

PublicKeyRing Module

+
+
+class M2Crypto.PGP.PublicKeyRing.PublicKeyRing(keyring)[source]
+
+
+load()[source]
+
+ +
+
+save(keyring)[source]
+
+ +
+
+spurious()[source]
+
+ +
+ +
+
+M2Crypto.PGP.PublicKeyRing.load_pubring(filename='pubring.pgp')[source]
+
+ +
+
+

RSA Module

+

M2Crypto PGP2 RSA.

+

Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved.

+
+
+M2Crypto.PGP.RSA.new_pub_key(e_n)[source]
+

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.
+
+
+ +
+
+

constants Module

+

M2Crypto PGP2.

+

Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved.

+
+
+

packet Module

+
+
+class M2Crypto.PGP.packet.CKEPacket(ctb, body=None)[source]
+

Bases: M2Crypto.PGP.packet.Packet

+
+ +
+
+class M2Crypto.PGP.packet.CommentPacket(ctb, body=None)[source]
+

Bases: M2Crypto.PGP.packet.Packet

+
+
+pack()[source]
+
+ +
+ +
+
+class M2Crypto.PGP.packet.CompressedPacket(ctb, stream)[source]
+

Bases: M2Crypto.PGP.packet.Packet

+
+
+uncompress()[source]
+
+ +
+
+validate()[source]
+
+ +
+ +
+
+class M2Crypto.PGP.packet.LiteralPacket(ctb, body=None)[source]
+

Bases: M2Crypto.PGP.packet.Packet

+
+ +
+
+class M2Crypto.PGP.packet.PKEPacket(ctb, body=None)[source]
+

Bases: M2Crypto.PGP.packet.Packet

+
+ +
+
+class M2Crypto.PGP.packet.Packet(ctb, body=None)[source]
+
+
+pack()[source]
+
+ +
+
+pkc()[source]
+
+ +
+
+timestamp()[source]
+
+ +
+
+validate()[source]
+
+ +
+
+validity()[source]
+
+ +
+
+version()[source]
+
+ +
+ +
+
+class M2Crypto.PGP.packet.PacketStream(input)[source]
+
+
+close()[source]
+
+ +
+
+count()[source]
+
+ +
+
+read(keep_trying=0)[source]
+
+ +
+ +
+
+class M2Crypto.PGP.packet.PrivateKeyPacket(ctb, body=None)[source]
+

Bases: M2Crypto.PGP.packet.Packet

+
+
+is_encrypted()[source]
+
+ +
+ +
+
+class M2Crypto.PGP.packet.PublicKeyPacket(ctb, body=None)[source]
+

Bases: M2Crypto.PGP.packet.Packet

+
+
+pack()[source]
+
+ +
+
+pubkey()[source]
+
+ +
+ +
+
+class M2Crypto.PGP.packet.SignaturePacket(ctb, body=None)[source]
+

Bases: M2Crypto.PGP.packet.Packet

+
+
+pack()[source]
+
+ +
+
+validate()[source]
+
+ +
+ +
+
+class M2Crypto.PGP.packet.TrustPacket(ctb, body=None)[source]
+

Bases: M2Crypto.PGP.packet.Packet

+
+ +
+
+class M2Crypto.PGP.packet.UserIDPacket(ctb, body=None)[source]
+

Bases: M2Crypto.PGP.packet.Packet

+
+
+pack()[source]
+
+ +
+
+userid()[source]
+
+ +
+ +
+
+exception M2Crypto.PGP.packet.XXXError[source]
+

Bases: exceptions.Exception

+
+ +
+
+M2Crypto.PGP.packet.is_ctb(ctb)[source]
+
+ +
+
+M2Crypto.PGP.packet.make_ctb(value, llf)[source]
+
+ +
+
+ + +
+
+
+
+
+

Table Of Contents

+ + +

Previous topic

+

M2Crypto Package

+

Next topic

+

SSL Package

+

This Page

+ + + +
+
+
+
+ + + + \ No newline at end of file diff --git a/doc/html/M2Crypto.SSL.html b/doc/html/M2Crypto.SSL.html new file mode 100644 index 0000000..1c1eb09 --- /dev/null +++ b/doc/html/M2Crypto.SSL.html @@ -0,0 +1,1606 @@ + + + + + + + + + + SSL Package — M2Crypto documentation + + + + + + + + + + + + + + + +
+
+
+
+ +
+

SSL Package

+
+

SSL Package

+
+
+exception M2Crypto.SSL.SSLError[source]
+

Bases: exceptions.Exception

+
+ +
+
+exception M2Crypto.SSL.SSLTimeoutError[source]
+

Bases: M2Crypto.SSL.SSLError, socket.timeout

+
+ +
+
+

Checker Module

+

SSL peer certificate checking routines

+

Copyright (c) 2004-2007 Open Source Applications Foundation. +All rights reserved.

+

Copyright 2008 Heikki Toivonen. All rights reserved.

+
+
+exception M2Crypto.SSL.Checker.SSLVerificationError[source]
+

Bases: exceptions.Exception

+
+ +
+
+exception M2Crypto.SSL.Checker.NoCertificate[source]
+

Bases: M2Crypto.SSL.Checker.SSLVerificationError

+
+ +
+
+exception M2Crypto.SSL.Checker.WrongCertificate[source]
+

Bases: M2Crypto.SSL.Checker.SSLVerificationError

+
+ +
+
+exception M2Crypto.SSL.Checker.WrongHost(expectedHost, actualHost, fieldName='commonName')[source]
+

Bases: M2Crypto.SSL.Checker.SSLVerificationError

+
+ +
+
+class M2Crypto.SSL.Checker.Checker(host=None, peerCertHash=None, peerCertDigest='sha1')[source]
+
+
+numericIpMatch = <_sre.SRE_Pattern object at 0x1fe7dd0>
+
+ +
+ +
+
+

Cipher Module

+

SSL Ciphers

+

Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved.

+
+
+class M2Crypto.SSL.Cipher.Cipher(cipher)[source]
+
+
+name()[source]
+
+ +
+
+version()[source]
+
+ +
+ +
+
+class M2Crypto.SSL.Cipher.Cipher_Stack(stack)[source]
+
+ +
+
+

Connection Module

+
+
+class M2Crypto.SSL.Connection.Connection(ctx, sock=None, family=2)[source]
+

An SSL connection.

+
+
+accept()[source]
+

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.

+ +++ + + + +
Returns: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.
+
+ +
+
+accept_ssl()[source]
+

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.

+ +++ + + + +
Returns:
+
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.
+
+
+
+ +
+
+bind(addr)[source]
+
+ +
+
+clear()[source]
+

If there were errors in this connection, call clear() rather +than close() to end it, so that bad sessions will be cleared +from cache.

+
+ +
+
+clientPostConnectionCheck = <M2Crypto.SSL.Checker.Checker instance at 0x2057cf8>
+
+ +
+
+close()[source]
+
+ +
+
+connect(addr)[source]
+

Overloading socket.connect()

+ +++ + + + +
Parameters:addr – addresses have various depending on their type
+

:return:status of ssl_connect()

+
+ +
+
+connect_ssl()[source]
+
+ +
+
+fileno()[source]
+
+ +
+
+get_cipher()[source]
+

Return an M2Crypto.SSL.Cipher object for this connection; if the +connection has not been initialised with a cipher suite, return None.

+
+ +
+
+get_cipher_list(idx=0)[source]
+

Return the cipher suites for this connection as a string object.

+
+ +
+
+get_ciphers()[source]
+

Return an M2Crypto.SSL.Cipher_Stack object for this +connection; if the connection has not been initialised with +cipher suites, return None.

+
+ +
+
+get_context()[source]
+

Return the SSL.Context object associated with this connection.

+
+ +
+
+get_default_session_timeout()[source]
+
+ +
+
+get_peer_cert()[source]
+

Return the peer certificate.

+

If the peer did not provide a certificate, return None.

+
+ +
+
+get_peer_cert_chain()[source]
+

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.
+
+ +
+
+get_session()[source]
+
+ +
+
+get_shutdown()[source]
+

Get the current shutdown mode of the Connection.

+
+ +
+
+get_socket_read_timeout()[source]
+
+ +
+
+get_socket_write_timeout()[source]
+
+ +
+
+get_state()[source]
+

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.

+ +++ + + + +
Returns:6 letter string indicating the current state of the SSL +object ssl.
+
+ +
+
+get_verify_depth()[source]
+

Return the peer certificate verification depth.

+
+ +
+
+get_verify_mode()[source]
+

Return the peer certificate verification mode.

+
+ +
+
+get_verify_result()[source]
+

Return the peer certificate verification result.

+
+ +
+
+get_version()[source]
+

Return the TLS/SSL protocol version for this connection.

+
+ +
+
+getpeername()[source]
+

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.

+ +++ + + + +
Returns:
+
+ +
+
+getsockname()[source]
+

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

+
+ +
+
+getsockopt(level, optname, buflen=None)[source]
+

Get the value of the given socket option.

+ +++ + + + + + +
Parameters:
    +
  • 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).
  • +
  • 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.
  • +
  • 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.
  • +
+
Returns:

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).

+
+
+ +
+
+listen(qlen=5)[source]
+
+ +
+
+m2_bio_free()
+
+ +
+
+m2_ssl_free()
+
+ +
+
+makefile(mode='rb', bufsize=-1)[source]
+
+ +
+
+pending()[source]
+

Return the numbers of octets that can be read from the connection.

+
+ +
+
+read(size=1024)[source]
+
+ +
+
+recv(size=1024)
+
+ +
+
+renegotiate()[source]
+

Renegotiate this connection’s SSL parameters.

+
+ +
+
+send(data)
+
+ +
+
+sendall(data)
+
+ +
+
+serverPostConnectionCheck(*args, **kw)
+
+ +
+
+set_accept_state()[source]
+

Sets Connection to work in the server mode.

+
+ +
+
+set_bio(readbio, writebio)[source]
+

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).

+ +++ + + + +
Parameters:
    +
  • readbio – BIO for reading
  • +
  • writebio – BIO for writing.
  • +
+
+
+ +
+
+set_cipher_list(cipher_list)[source]
+

Set the cipher suites for this connection.

+
+ +
+
+set_client_CA_list_from_context()[source]
+

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.

+
+ +
+
+set_client_CA_list_from_file(cafile)[source]
+

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.

+ +++ + + + + + +
Parameters:cafile – Filename from which to load the CA list.
Returns:
+
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.

+
+
+ +
+
+set_connect_state()[source]
+

Sets Connection to work in the client mode.

+
+ +
+
+set_post_connection_check_callback(postConnectionCheck)[source]
+
+ +
+
+set_session(session)[source]
+
+ +
+
+set_session_id_ctx(id)[source]
+
+ +
+
+set_shutdown(mode)[source]
+

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.

+ +++ + + + +
Parameters:mode – set the mode bitmask.
+
+ +
+
+set_socket_read_timeout(timeo)[source]
+
+ +
+
+set_socket_write_timeout(timeo)[source]
+
+ +
+
+set_ssl_close_flag(flag)[source]
+

By default, SSL struct will be freed in __del__. Call with +m2.bio_close to override this default.

+ +++ + + + +
Parameters:flag – either m2.bio_close or m2.bio_noclose
+
+ +
+
+set_tlsext_host_name(name)[source]
+

Set the requested hostname for the SNI (Server Name Indication) +extension.

+
+ +
+
+setblocking(mode)[source]
+

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).

+ +++ + + + +
Parameters:mode – new mode to be set
+
+ +
+
+setsockopt(level, optname, value=None)[source]
+

Set the value of the given socket option.

+ +++ + + + + + +
Parameters:
    +
  • level – same as with getsockopt() above
  • +
  • optname – same as with getsockopt() above
  • +
  • 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).
  • +
+
Returns:

None for success or the error handler for failure.

+
+
+ +
+
+settimeout(timeout)[source]
+

Set this connection’s underlying socket’s timeout to _timeout_.

+
+ +
+
+setup_addr(addr)[source]
+
+ +
+
+setup_ssl()[source]
+
+ +
+
+shutdown(how)[source]
+
+ +
+
+ssl_get_error(ret)[source]
+
+ +
+
+verify_ok()[source]
+
+ +
+
+write(data)[source]
+
+ +
+ +
+
+

Context Module

+
+
+M2Crypto.SSL.Context.ctxmap()[source]
+
+ +
+
+class M2Crypto.SSL.Context.Context(protocol='tls', weak_crypto=None, post_connection_check=None)[source]
+

‘Context’ for SSL connections.

+
+
+add_session(session)[source]
+

Add the session to the context.

+ +++ + + + + + +
Parameters:session – the session to be added.
Returns:
+
0 The operation failed. It was tried to add the same
+
(identical) session twice.
+
+

1 The operation succeeded.

+
+
+ +
+
+close()[source]
+
+ +
+
+get_allow_unknown_ca()[source]
+

Get the context’s setting that accepts/rejects a peer +certificate if the certificate’s CA is unknown.

+

FIXME 2Bconverted to bool

+
+ +
+
+get_cert_store()[source]
+

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.
+
+ +
+
+get_session_cache_mode()[source]
+

Gets the current session caching.

+

The mode is set to m2.SSL_SESS_CACHE_* constants.

+ +++ + + + +
Returns:the previously set cache mode value.
+
+ +
+
+get_session_timeout()[source]
+

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.

+ +++ + + + +
Returns:the currently set timeout value.
+
+ +
+
+get_verify_depth()[source]
+

Returns the verification mode currently set in the SSL Context.

+
+ +
+
+get_verify_mode()[source]
+
+ +
+
+load_cert(certfile, keyfile=None, callback=<function passphrase_callback at 0x1faa848>)[source]
+

Load certificate and private key into the context.

+ +++ + + + +
Parameters:
    +
  • certfile – File that contains the PEM-encoded certificate.
  • +
  • keyfile – File that contains the PEM-encoded private key. +Default value of None indicates that the private key +is to be found in ‘certfile’.
  • +
  • callback – Callable object to be invoked if the private key is +passphrase-protected. Default callback provides a +simple terminal-style input for the passphrase.
  • +
+
+
+ +
+
+load_cert_chain(certchainfile, keyfile=None, callback=<function passphrase_callback at 0x1faa848>)[source]
+

Load certificate chain and private key into the context.

+ +++ + + + +
Parameters:
    +
  • certchainfile – File object containing the PEM-encoded +certificate chain.
  • +
  • keyfile – File object containing the PEM-encoded private +key. Default value of None indicates that the +private key is to be found in ‘certchainfile’.
  • +
  • callback – Callable object to be invoked if the private key +is passphrase-protected. Default callback +provides a simple terminal-style input for the +passphrase.
  • +
+
+
+ +
+
+load_client_CA(cafile)
+

Load CA certs into the context. These CA certs are sent to the +peer during SSLv3 certificate request.

+ +++ + + + +
Parameters:cafile – File object containing one or more PEM-encoded CA +certificates concatenated together.
+
+ +
+
+load_client_ca(cafile)
+

Load CA certs into the context. These CA certs are sent to the +peer during SSLv3 certificate request.

+ +++ + + + +
Parameters:cafile – File object containing one or more PEM-encoded CA +certificates concatenated together.
+
+ +
+
+load_verify_info(cafile=None, capath=None)
+

Load CA certs into the context.

+

These CA certs are used during verification of the peer’s +certificate.

+ +++ + + + + + +
Parameters:
    +
  • cafile – File containing one or more PEM-encoded CA +certificates concatenated together.
  • +
  • capath – Directory containing PEM-encoded CA certificates +(one certificate per file).
  • +
+
Returns:

+
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.

+

+
+
+ +
+
+load_verify_locations(cafile=None, capath=None)[source]
+

Load CA certs into the context.

+

These CA certs are used during verification of the peer’s +certificate.

+ +++ + + + + + +
Parameters:
    +
  • cafile – File containing one or more PEM-encoded CA +certificates concatenated together.
  • +
  • capath – Directory containing PEM-encoded CA certificates +(one certificate per file).
  • +
+
Returns:

+
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.

+

+
+
+ +
+
+m2_ssl_ctx_free()
+
+ +
+
+remove_session(session)[source]
+

Remove the session from the context.

+ +++ + + + + + +
Parameters:session – the session to be removed.
Returns:
+
0 The operation failed. The session was not found in
+
the cache.
+
+

1 The operation succeeded.

+
+
+ +
+
+set_allow_unknown_ca(ok)[source]
+

Set the context to accept/reject a peer certificate if the +certificate’s CA is unknown.

+ +++ + + + +
Parameters:ok – True to accept, False to reject.
+
+ +
+
+set_cipher_list(cipher_list)[source]
+

Sets the list of available ciphers.

+ +++ + + + + + +
Parameters:cipher_list – The format of the string is described in +ciphers(1).
Returns:1 if any cipher could be selected and 0 on complete +failure.
+
+ +
+
+set_client_CA_list_from_file(cafile)[source]
+

Load CA certs into the context. These CA certs are sent to the +peer during SSLv3 certificate request.

+ +++ + + + +
Parameters:cafile – File object containing one or more PEM-encoded CA +certificates concatenated together.
+
+ +
+
+set_default_verify_paths()[source]
+

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.

+
+
+
+ +
+
+set_info_callback(callback=<function ssl_info_callback at 0x202cf50>)[source]
+

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.

+ +++ + + + +
Parameters:callback – Callback function. The default prints +information to stderr.
+
+ +
+
+set_options(op)[source]
+

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.

+ +++ + + + + + +
Parameters:op – bitmask of additional options specified in +SSL_CTX_set_options(3) manpage.
Returns:the new options bitmask after adding options.
+
+ +
+
+set_session_cache_mode(mode)[source]
+

Enables/disables session caching.

+

The mode is set by using m2.SSL_SESS_CACHE_* constants.

+ +++ + + + + + +
Parameters:mode – new mode value.
Returns:the previously set cache mode value.
+
+ +
+
+set_session_id_ctx(id)[source]
+

Sets the session id for the SSL.Context w/in a session can be reused.

+ +++ + + + +
Parameters: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.
+
+ +
+
+set_session_timeout(timeout)[source]
+

Set new session timeout.

+

See self.get_session_timeout() for explanation of the session +timeouts.

+ +++ + + + + + +
Parameters:timeout – new timeout value.
Returns:the previously set timeout value.
+
+ +
+
+set_tmp_dh(dhpfile)[source]
+

Load ephemeral DH parameters into the context.

+ +++ + + + +
Parameters:dhpfile – Filename of the file containing the PEM-encoded +DH parameters.
+
+ +
+
+set_tmp_dh_callback(callback=None)[source]
+

Sets the callback function for SSL.Context.

+ +++ + + + +
Parameters:callback – Callable to be used when a DH parameters are required.
+
+ +
+
+set_tmp_rsa(rsa)[source]
+

Load ephemeral RSA key into the context.

+ +++ + + + +
Parameters:rsa – RSA.RSA instance.
+
+ +
+
+set_tmp_rsa_callback(callback=None)[source]
+

Sets the callback function to be used when +a temporary/ephemeral RSA key is required.

+
+ +
+
+set_verify(mode, depth, callback=None)[source]
+

Set verify options. Most applications will need to call this +method with the right options to make a secure SSL connection.

+ +++ + + + +
Parameters:
    +
  • 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.
  • +
  • depth – The maximum allowed depth of the certificate chain +returned by the peer.
  • +
  • callback – Callable that can be used to specify custom +verification checks.
  • +
+
+
+ +
+ +
+
+M2Crypto.SSL.Context.map()
+
+ +
+
+

SSLServer Module

+
+
+class M2Crypto.SSL.SSLServer.SSLServer(server_address, RequestHandlerClass, ssl_context, bind_and_activate=True)[source]
+

Bases: SocketServer.TCPServer

+
+
+handle_error(request, client_address)[source]
+
+ +
+
+handle_request()[source]
+
+ +
+ +
+
+class M2Crypto.SSL.SSLServer.ForkingSSLServer(server_address, RequestHandlerClass, ssl_context, bind_and_activate=True)[source]
+

Bases: SocketServer.ForkingMixIn, M2Crypto.SSL.SSLServer.SSLServer

+
+ +
+
+class M2Crypto.SSL.SSLServer.ThreadingSSLServer(server_address, RequestHandlerClass, ssl_context, bind_and_activate=True)[source]
+

Bases: SocketServer.ThreadingMixIn, M2Crypto.SSL.SSLServer.SSLServer

+
+ +
+
+

Session Module

+

SSL Session

+

Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved.

+
+
+class M2Crypto.SSL.Session.Session(session, _pyfree=0)[source]
+
+
+as_der()[source]
+
+ +
+
+as_text()[source]
+
+ +
+
+get_time()[source]
+
+ +
+
+get_timeout()[source]
+
+ +
+
+m2_ssl_session_free()
+
+ +
+
+set_time(t)[source]
+
+ +
+
+set_timeout(t)[source]
+
+ +
+
+write_bio(bio)[source]
+
+ +
+ +
+
+M2Crypto.SSL.Session.load_session(pemfile)[source]
+
+ +
+
+

TwistedProtocolWrapper Module

+

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.

+
+
+M2Crypto.SSL.TwistedProtocolWrapper.connectSSL(host, port, factory, contextFactory, timeout=30, bindAddress=None, reactor=<twisted.internet.epollreactor.EPollReactor object at 0x4996190>, postConnectionCheck=<M2Crypto.SSL.Checker.Checker instance at 0x3f0bc68>)[source]
+

A convenience function to start an SSL/TLS connection using Twisted.

+

See IReactorSSL interface in Twisted.

+
+ +
+
+M2Crypto.SSL.TwistedProtocolWrapper.connectTCP(host, port, factory, timeout=30, bindAddress=None, reactor=<twisted.internet.epollreactor.EPollReactor object at 0x4996190>, postConnectionCheck=<M2Crypto.SSL.Checker.Checker instance at 0x3f0b3f8>)[source]
+

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.

+
+ +
+
+M2Crypto.SSL.TwistedProtocolWrapper.listenSSL(port, factory, contextFactory, backlog=5, interface='', reactor=<twisted.internet.epollreactor.EPollReactor object at 0x4996190>, postConnectionCheck=<function _alwaysSucceedsPostConnectionCheck at 0x49948c0>)[source]
+

A convenience function to listen for SSL/TLS connections using Twisted.

+

See IReactorSSL interface in Twisted.

+
+ +
+
+M2Crypto.SSL.TwistedProtocolWrapper.listenTCP(port, factory, backlog=5, interface='', reactor=<twisted.internet.epollreactor.EPollReactor object at 0x4996190>, postConnectionCheck=None)[source]
+

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.

+
+ +
+
+class M2Crypto.SSL.TwistedProtocolWrapper.TLSProtocolWrapper(factory, wrappedProtocol, startPassThrough, client, contextFactory, postConnectionCheck)[source]
+

Bases: twisted.protocols.policies.ProtocolWrapper

+

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.

+
+
+clear()[source]
+

Clear this instance, after which it is ready for reuse.

+
+ +
+
+connectionLost(reason)[source]
+
+ +
+
+connectionMade()[source]
+
+ +
+
+dataReceived(data)[source]
+
+ +
+
+loseConnection()[source]
+
+ +
+
+startTLS(ctx)[source]
+

Start SSL/TLS. If this is not called, this instance just passes data +through untouched.

+
+ +
+
+write(data)[source]
+
+ +
+
+writeSequence(data)[source]
+
+ +
+ +
+
+

cb Module

+
+
+M2Crypto.SSL.cb.ssl_verify_callback_stub(ssl_ctx_ptr, x509_ptr, errnum, errdepth, ok)[source]
+
+ +
+
+M2Crypto.SSL.cb.ssl_verify_callback(ssl_ctx_ptr, x509_ptr, errnum, errdepth, ok)[source]
+
+ +
+
+M2Crypto.SSL.cb.ssl_verify_callback_allow_unknown_ca(ok, store)[source]
+
+ +
+
+M2Crypto.SSL.cb.ssl_info_callback(where, ret, ssl_ptr)[source]
+
+ +
+
+

ssl_dispatcher Module

+
+
+class M2Crypto.SSL.ssl_dispatcher.ssl_dispatcher(sock=None, map=None)[source]
+

Bases: asyncore.dispatcher

+
+
+connect(addr)[source]
+
+ +
+
+create_socket(ssl_context)[source]
+
+ +
+
+recv(buffer_size=4096)[source]
+

Receive data over SSL.

+
+ +
+
+send(buffer)[source]
+

Send data over SSL.

+
+ +
+ +
+
+

timeout Module

+

Support for SSL socket timeouts.

+

Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved.

+

Copyright 2008 Heikki Toivonen. All rights reserved.

+
+
+class M2Crypto.SSL.timeout.timeout(sec=600, microsec=0)[source]
+
+
+pack()[source]
+
+ +
+ +
+
+M2Crypto.SSL.timeout.struct_to_timeout(binstr)[source]
+
+ +
+
+M2Crypto.SSL.timeout.struct_size()[source]
+
+ +
+
+ + +
+
+
+
+
+

Table Of Contents

+ + +

Previous topic

+

PGP Package

+

This Page

+ + + +
+
+
+
+ + + + \ No newline at end of file diff --git a/doc/html/M2Crypto.html b/doc/html/M2Crypto.html new file mode 100644 index 0000000..f3775c2 --- /dev/null +++ b/doc/html/M2Crypto.html @@ -0,0 +1,4720 @@ + + + + + + + + + + M2Crypto Package — M2Crypto documentation + + + + + + + + + + + + + + + +
+
+
+
+ +
+

M2Crypto Package

+
+

M2Crypto Package

+
+
+

ASN1 Module

+
+
+class M2Crypto.ASN1.ASN1_Integer(asn1int, _pyfree=0)[source]
+
+
+m2_asn1_integer_free()
+
+ +
+ +
+
+class M2Crypto.ASN1.ASN1_Object(asn1obj, _pyfree=0)[source]
+
+
+m2_asn1_object_free()
+
+ +
+ +
+
+class M2Crypto.ASN1.ASN1_String(asn1str, _pyfree=0)[source]
+
+
+as_text(flags=0)[source]
+

output an ASN1_STRING structure according to the set flags.

+ +++ + + + + + +
Parameters:flags – determine the format of the output by using +predetermined constants, see ASN1_STRING_print_ex(3) +manpage for their meaning.
Returns:output an ASN1_STRING structure.
+
+ +
+
+m2_asn1_string_free()
+
+ +
+ +
+
+class M2Crypto.ASN1.ASN1_TIME(asn1_time=None, _pyfree=0, asn1_utctime=None)[source]
+
+
+get_datetime()[source]
+
+ +
+
+m2_asn1_time_free()
+
+ +
+
+set_datetime(date)[source]
+
+ +
+
+set_string(string)[source]
+

Set time from UTC string.

+
+ +
+
+set_time(time)[source]
+

Set time from seconds since epoch (int).

+
+ +
+ +
+
+M2Crypto.ASN1.ASN1_UTCTIME
+

alias of ASN1_TIME

+
+ +
+
+class M2Crypto.ASN1.LocalTimezone[source]
+

Bases: datetime.tzinfo

+

Localtimezone from datetime manual

+
+
+dst(dt)[source]
+
+ +
+
+tzname(dt)[source]
+
+ +
+
+utcoffset(dt)[source]
+
+ +
+ +
+
+

AuthCookie Module

+
+
+class M2Crypto.AuthCookie.AuthCookie(expiry, data, dough, mac)[source]
+
+
+data()[source]
+

Return the data portion of the cookie.

+
+ +
+
+expiry()[source]
+

Return the cookie’s expiry time.

+
+ +
+
+headerValue()[source]
+
+ +
+
+isExpired()[source]
+

Return 1 if the cookie has expired, 0 otherwise.

+
+ +
+
+mac()[source]
+

Return the cookie’s MAC.

+
+ +
+
+name()[source]
+
+ +
+
+output()[source]
+

Return the cookie’s output in “Set-Cookie” format.

+
+ +
+
+value()[source]
+

Return the cookie’s output minus the “Set-Cookie: ” portion.

+
+ +
+ +
+
+class M2Crypto.AuthCookie.AuthCookieJar[source]
+
+
+isGoodCookie(cookie)[source]
+
+ +
+
+isGoodCookieString(cookie_str, _debug=False)[source]
+
+ +
+
+makeCookie(expiry, data)[source]
+

Make a cookie

+ +++ + + + + + +
Parameters:
    +
  • expiry – expiration time (float in seconds)
  • +
  • data – cookie content
  • +
+
Returns:

AuthCookie object

+
+
+ +
+ +
+
+M2Crypto.AuthCookie.mix(expiry, data, format='exp=%f&data=%s&digest=')[source]
+
+ +
+
+M2Crypto.AuthCookie.unmix(dough, regex=<_sre.SRE_Pattern object at 0x1ec24a0>)[source]
+
+ +
+
+M2Crypto.AuthCookie.unmix3(dough, regex=<_sre.SRE_Pattern object at 0x1ec24a0>)[source]
+
+ +
+
+

BIO Module

+
+
+class M2Crypto.BIO.BIO(bio=None, _pyfree=0, _close_cb=None)[source]
+

Bases: object

+

Abstract object interface to the BIO API.

+
+
+bio_ptr()
+
+ +
+
+close()[source]
+
+ +
+
+fileno()[source]
+
+ +
+
+flush()[source]
+
+++ + + + +
Returns:1 for success, and 0 or -1 for failure
+
+ +
+
+m2_bio_free()
+
+ +
+
+read(size=None)[source]
+
+ +
+
+readable()[source]
+
+ +
+
+readline(size=4096)[source]
+
+ +
+
+readlines(sizehint='ignored')[source]
+
+ +
+
+reset()[source]
+

Sets the bio to its initial state +:return: 1 for success, and 0 or -1 for failure

+
+ +
+
+seek(off)[source]
+

Seek to the specified absolute offset.

+
+ +
+
+should_read()[source]
+

Returns whether the cause of the condition is the bio +should read more data

+
+ +
+
+should_retry()[source]
+

Can the call be attempted again, or was there an error +ie do_handshake

+
+ +
+
+should_write()[source]
+

Returns whether the cause of the condition is the bio +should write more data

+
+ +
+
+tell()[source]
+

Return the current offset.

+
+ +
+
+write(data)[source]
+
+++ + + + +
Returns:either data written, or [0, -1] for nothing written, +-2 not implemented
+
+ +
+
+write_close()[source]
+
+ +
+
+writeable()[source]
+
+ +
+ +
+
+exception M2Crypto.BIO.BIOError[source]
+

Bases: exceptions.Exception

+
+ +
+
+class M2Crypto.BIO.CipherStream(obio)[source]
+

Bases: M2Crypto.BIO.BIO

+

Object interface to BIO_f_cipher.

+
+
+SALT_LEN = 8
+
+ +
+
+close()[source]
+
+ +
+
+m2_bio_free()
+
+ +
+
+m2_bio_pop()
+
+ +
+
+set_cipher(algo, key, iv, op)[source]
+
+ +
+
+write_close()[source]
+
+ +
+ +
+
+class M2Crypto.BIO.File(pyfile, close_pyfile=1)[source]
+

Bases: M2Crypto.BIO.BIO

+

Object interface to BIO_s_pyfd

+

This class interfaces Python to OpenSSL functions that expect BIO *. For +general file manipulation in Python, use Python’s builtin file object.

+
+
+close()[source]
+
+ +
+
+reset()[source]
+

Sets the bio to its initial state +:return: 0 for success, and -1 for failure

+
+ +
+ +
+
+class M2Crypto.BIO.IOBuffer(under_bio, mode='rwb', _pyfree=1)[source]
+

Bases: M2Crypto.BIO.BIO

+

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.

+
+
+close()[source]
+
+ +
+
+m2_bio_free()
+
+ +
+
+m2_bio_pop()
+
+ +
+ +
+
+class M2Crypto.BIO.MemoryBuffer(data=None)[source]
+

Bases: M2Crypto.BIO.BIO

+

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.

+
+
+close()
+
+ +
+
+getvalue(size=0)
+
+ +
+
+read(size=0)[source]
+
+ +
+
+read_all(size=0)
+
+ +
+
+write_close()[source]
+
+ +
+ +
+
+class M2Crypto.BIO.SSLBio(_pyfree=1)[source]
+

Bases: M2Crypto.BIO.BIO

+

Object interface to BIO_f_ssl

+
+
+do_handshake()[source]
+

Do the handshake.

+

Return 1 if the handshake completes +Return 0 or a negative number if there is a problem

+
+ +
+
+set_ssl(conn, close_flag=0)[source]
+

Sets the bio to the SSL pointer which is +contained in the connection object.

+
+ +
+ +
+
+M2Crypto.BIO.openfile(filename, mode='rb')[source]
+
+ +
+
+

BN Module

+
+
+M2Crypto.BN.rand(bits, top=-1, bottom=0)[source]
+

Generate cryptographically strong random number.

+ +++ + + + +
Parameters:
    +
  • bits – Length of random number in bits.
  • +
  • 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.
  • +
  • bottom – If bottom is true, the number will be odd.
  • +
+
+
+ +
+
+M2Crypto.BN.rand_range(range)[source]
+

Generate a random number in a range.

+ +++ + + + + + +
Parameters:range – Upper limit for range.
Returns:A random number in the range [0, range)
+
+ +
+
+M2Crypto.BN.randfname(length)[source]
+

Return a random filename, which is simply a string where all +the characters are from the set [a-zA-Z0-9].

+ +++ + + + + + +
Parameters:length – Length of filename to return.
Returns:random filename string
+
+ +
+
+

DH Module

+
+
+class M2Crypto.DH.DH(dh, _pyfree=0)[source]
+

Object interface to the Diffie-Hellman key exchange +protocol.

+
+
+check_params()[source]
+
+ +
+
+compute_key(pubkey)[source]
+
+ +
+
+gen_key()[source]
+
+ +
+
+m2_dh_free()
+
+ +
+
+print_params(bio)[source]
+
+ +
+ +
+
+exception M2Crypto.DH.DHError[source]
+

Bases: exceptions.Exception

+
+ +
+
+M2Crypto.DH.gen_params(plen, g, callback=<function genparam_callback at 0x1faa758>)[source]
+
+ +
+
+M2Crypto.DH.load_params(file)[source]
+
+ +
+
+M2Crypto.DH.load_params_bio(bio)[source]
+
+ +
+
+M2Crypto.DH.set_params(p, g)[source]
+
+ +
+
+

DSA Module

+
+
+class M2Crypto.DSA.DSA(dsa, _pyfree=0)[source]
+

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)
+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 **')
+else:
+    print('  ** verification failed **')
+
+
+
+
+check_key()[source]
+

Check to be sure the DSA object has a valid private key.

+ +++ + + + +
Returns:1 (true) if a valid private key
+
+ +
+
+gen_key()[source]
+

Generate a key pair.

+
+ +
+
+m2_dsa_free()
+
+ +
+
+save_key(filename, cipher='aes_128_cbc', callback=<function passphrase_callback at 0x1faa848>)[source]
+

Save the DSA key pair to a file.

+ +++ + + + + + +
Parameters:
    +
  • filename – Save the DSA key pair to this file.
  • +
  • cipher – name of symmetric key algorithm and mode +to encrypt the private key.
  • +
+
Returns:

1 (true) if successful

+
+
+ +
+
+save_key_bio(bio, cipher='aes_128_cbc', callback=<function passphrase_callback at 0x1faa848>)[source]
+

Save DSA key pair to a BIO object.

+ +++ + + + + + +
Parameters:
    +
  • bio – Save DSA parameters to this object.
  • +
  • cipher – name of symmetric key algorithm and mode +to encrypt the private key.
  • +
+
Returns:

1 (true) if successful

+
+
+ +
+
+save_params(filename)[source]
+

Save the DSA parameters to a file.

+ +++ + + + + + +
Parameters:filename – Save the DSA parameters to this file.
Returns:1 (true) if successful
+
+ +
+
+save_params_bio(bio)[source]
+

Save DSA parameters to a BIO object.

+ +++ + + + + + +
Parameters:bio – Save DSA parameters to this object.
Returns:1 (true) if successful
+
+ +
+
+save_pub_key(filename)[source]
+

Save the DSA public key (with parameters) to a file.

+ +++ + + + + + +
Parameters:filename – Save DSA public key (with parameters) +to this file.
Returns:1 (true) if successful
+
+ +
+
+save_pub_key_bio(bio)[source]
+

Save DSA public key (with parameters) to a BIO object.

+ +++ + + + + + +
Parameters:bio – Save DSA public key (with parameters) +to this object.
Returns:1 (true) if successful
+
+ +
+
+set_params(p, q, g)[source]
+

Set new parameters.

+ +++ + + + +
Parameters:
    +
  • 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).
  • +
  • q – ditto
  • +
  • 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.
+
+
+ +
+
+sign(digest)[source]
+

Sign the digest.

+ +++ + + + + + +
Parameters:digest – SHA-1 hash of message (same as output +from MessageDigest, a “byte string”)
Returns:DSA signature, a tuple of two values, r and s, +both “byte strings”.
+
+ +
+
+sign_asn1(digest)[source]
+
+ +
+
+verify(digest, r, s)[source]
+

Verify a newly calculated digest against the signature +values r and s.

+ +++ + + + + + +
Parameters:
    +
  • digest – SHA-1 hash of message (same as output +from MessageDigest, a “byte string”)
  • +
  • r – r value of the signature, a “byte string”
  • +
  • s – s value of the signature, a “byte string”
  • +
+
Returns:

1 (true) if verify succeeded, 0 if failed

+
+
+ +
+
+verify_asn1(digest, blob)[source]
+
+ +
+ +
+
+exception M2Crypto.DSA.DSAError[source]
+

Bases: exceptions.Exception

+
+ +
+
+class M2Crypto.DSA.DSA_pub(dsa, _pyfree=0)[source]
+

Bases: M2Crypto.DSA.DSA

+

This class is a DSA context that only supports a public key +and verification. It does NOT support a private key or +signing.

+
+
+check_key()[source]
+
+++ + + + +
Returns:does DSA_pub contain a pub key?
+
+ +
+
+save_key(filename)
+

Save the DSA public key (with parameters) to a file.

+ +++ + + + + + +
Parameters:filename – Save DSA public key (with parameters) +to this file.
Returns:1 (true) if successful
+
+ +
+
+save_key_bio(bio)
+

Save DSA public key (with parameters) to a BIO object.

+ +++ + + + + + +
Parameters:bio – Save DSA public key (with parameters) +to this object.
Returns:1 (true) if successful
+
+ +
+
+sign(*argv)[source]
+
+ +
+
+sign_asn1(*argv)
+
+ +
+ +
+
+M2Crypto.DSA.gen_params(bits, callback=<function genparam_callback at 0x1faa758>)[source]
+

Factory function that generates DSA parameters and +instantiates a DSA object from the output.

+ +++ + + + + + +
Parameters:
    +
  • bits – The length of the prime to be generated. If +‘bits’ < 512, it is set to 512.
  • +
  • callback – A Python callback object that will be +invoked during parameter generation; it usual +purpose is to provide visual feedback.
  • +
+
Returns:

instance of DSA.

+
+
+ +
+
+M2Crypto.DSA.load_key(file, callback=<function passphrase_callback at 0x1faa848>)[source]
+

Factory function that instantiates a DSA object from a +PEM encoded DSA key pair.

+ +++ + + + + + +
Parameters:
    +
  • file – Names the file (a path) that contains the PEM +representation of the DSA key pair.
  • +
  • callback – A Python callback object that will be +invoked if the DSA key pair is +passphrase-protected.
  • +
+
Returns:

instance of DSA.

+
+
+ +
+
+M2Crypto.DSA.load_key_bio(bio, callback=<function passphrase_callback at 0x1faa848>)[source]
+

Factory function that instantiates a DSA object from a +PEM encoded DSA key pair.

+ +++ + + + + + +
Parameters:
    +
  • bio – Contains the PEM representation of the DSA +key pair.
  • +
  • callback – A Python callback object that will be +invoked if the DSA key pair is +passphrase-protected.
  • +
+
Returns:

instance of DSA.

+
+
+ +
+
+M2Crypto.DSA.load_params(file, callback=<function passphrase_callback at 0x1faa848>)[source]
+

Factory function that instantiates a DSA object with DSA +parameters from a file.

+ +++ + + + + + +
Parameters:
    +
  • file – Names the file (a path) that contains the PEM +representation of the DSA parameters.
  • +
  • callback – A Python callback object that will be +invoked if the DSA parameters file is +passphrase-protected.
  • +
+
Returns:

instance of DSA.

+
+
+ +
+
+M2Crypto.DSA.load_params_bio(bio, callback=<function passphrase_callback at 0x1faa848>)[source]
+

Factory function that instantiates a DSA object with DSA +parameters from a M2Crypto.BIO object.

+ +++ + + + + + +
Parameters:
    +
  • bio – Contains the PEM representation of the DSA +parameters.
  • +
  • callback – A Python callback object that will be +invoked if the DSA parameters file is +passphrase-protected.
  • +
+
Returns:

instance of DSA.

+
+
+ +
+
+M2Crypto.DSA.load_pub_key(file, callback=<function passphrase_callback at 0x1faa848>)[source]
+

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.

+ +++ + + + + + +
Parameters:
    +
  • file – Names the file (a path) that contains the PEM +representation of the DSA public key.
  • +
  • callback – A Python callback object that will be +invoked should the DSA public key be +passphrase-protected.
  • +
+
Returns:

instance of DSA_pub.

+
+
+ +
+
+M2Crypto.DSA.load_pub_key_bio(bio, callback=<function passphrase_callback at 0x1faa848>)[source]
+

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.

+ +++ + + + + + +
Parameters:
    +
  • bio – Contains the PEM representation of the DSA +public key (with params).
  • +
  • callback – A Python callback object that will be +invoked should the DSA public key be +passphrase-protected.
  • +
+
Returns:

instance of DSA_pub.

+
+
+ +
+
+M2Crypto.DSA.pub_key_from_params(p, q, g, pub)[source]
+

Factory function that instantiates a DSA_pub object using +the parameters and public key specified.

+ +++ + + + + + +
Parameters:
    +
  • p – value of p
  • +
  • q – value of q
  • +
  • g – value of g
  • +
  • pub – value of the public key
  • +
+
Returns:

instance of DSA_pub.

+
+
+ +
+
+M2Crypto.DSA.set_params(p, q, g)[source]
+

Factory function that instantiates a DSA object with DSA +parameters.

+ +++ + + + + + +
Parameters:
    +
  • p – value of p, a “byte string”
  • +
  • q – value of q, a “byte string”
  • +
  • g – value of g, a “byte string”
  • +
+
Returns:

instance of DSA.

+
+
+ +
+
+

EC Module

+
+
+class M2Crypto.EC.EC(ec, _pyfree=0)[source]
+

Object interface to a EC key pair.

+
+
+as_pem(cipher='aes_128_cbc', callback=<function passphrase_callback at 0x1faa848>)[source]
+

Returns the key(pair) as a string in PEM format. +If no password is passed and the cipher is set +it exits with error

+
+ +
+
+check_key()[source]
+
+ +
+
+compute_dh_key(pub_key)[source]
+

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.

+
+ +
+
+gen_key()[source]
+

Generates the key pair from its parameters. Use:

+
keypair = EC.gen_params(curve)
+keypair.gen_key()
+
+
+

to create an EC key pair.

+
+ +
+
+m2_ec_key_free()
+
+ +
+
+pub()[source]
+
+ +
+
+save_key(file, cipher='aes_128_cbc', callback=<function passphrase_callback at 0x1faa848>)[source]
+

Save the key pair to a file in PEM format.

+ +++ + + + +
Parameters:
    +
  • file – Name of filename to save key to.
  • +
  • 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.
  • +
  • callback – A Python callable object that is invoked +to acquire a passphrase with which to protect +the key. The default is +util.passphrase_callback.
  • +
+
+
+ +
+
+save_key_bio(bio, cipher='aes_128_cbc', callback=<function passphrase_callback at 0x1faa848>)[source]
+

Save the key pair to an M2Crypto.BIO.BIO object in PEM format.

+ +++ + + + +
Parameters:
    +
  • bio – M2Crypto.BIO.BIO object to save key to.
  • +
  • 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.
  • +
  • callback – A Python callable object that is invoked +to acquire a passphrase with which to protect +the key. The default is +util.passphrase_callback.
  • +
+
+
+ +
+
+save_pub_key(file)[source]
+

Save the public key to a filename in PEM format.

+ +++ + + + +
Parameters:file – Name of filename to save key to.
+
+ +
+
+save_pub_key_bio(bio)[source]
+

Save the public key to an M2Crypto.BIO.BIO object in PEM format.

+ +++ + + + +
Parameters:bio – M2Crypto.BIO.BIO object to save key to.
+
+ +
+
+sign_dsa(digest)[source]
+

Sign the given digest using ECDSA. Returns a tuple (r,s), the two +ECDSA signature parameters.

+
+ +
+
+sign_dsa_asn1(digest)[source]
+
+ +
+
+verify_dsa(digest, r, s)[source]
+

Verify the given digest using ECDSA. r and s are the ECDSA +signature parameters.

+
+ +
+
+verify_dsa_asn1(digest, blob)[source]
+
+ +
+ +
+
+exception M2Crypto.EC.ECError[source]
+

Bases: exceptions.Exception

+
+ +
+
+class M2Crypto.EC.EC_pub(ec, _pyfree=0)[source]
+

Bases: M2Crypto.EC.EC

+

Object interface to an EC public key. +((don’t like this implementation inheritance))

+
+
+get_der()[source]
+

Returns the public key in DER format as a buffer object.

+
+ +
+
+get_key()[source]
+

Returns the public key as a byte string.

+
+ +
+
+save_key(file)
+

Save the public key to a filename in PEM format.

+ +++ + + + +
Parameters:file – Name of filename to save key to.
+
+ +
+
+save_key_bio(bio)
+

Save the public key to an M2Crypto.BIO.BIO object in PEM format.

+ +++ + + + +
Parameters:bio – M2Crypto.BIO.BIO object to save key to.
+
+ +
+ +
+
+M2Crypto.EC.ec_error()[source]
+
+ +
+
+M2Crypto.EC.gen_params(curve)[source]
+

Factory function that generates EC parameters and +instantiates a EC object from the output.

+ +++ + + + +
Parameters:curve – This is the OpenSSL nid of the curve to use.
+
+ +
+
+M2Crypto.EC.get_builtin_curves()[source]
+
+ +
+
+M2Crypto.EC.load_key(file, callback=<function passphrase_callback at 0x1faa848>)[source]
+

Factory function that instantiates a EC object.

+ +++ + + + +
Parameters:
    +
  • file – Names the filename that contains the PEM representation +of the EC key pair.
  • +
  • callback – Python callback object that will be invoked +if the EC key pair is passphrase-protected.
  • +
+
+
+ +
+
+M2Crypto.EC.load_key_bio(bio, callback=<function passphrase_callback at 0x1faa848>)[source]
+

Factory function that instantiates a EC object.

+ +++ + + + +
Parameters:
    +
  • bio – M2Crypto.BIO object that contains the PEM +representation of the EC key pair.
  • +
  • callback – Python callback object that will be invoked +if the EC key pair is passphrase-protected.
  • +
+
+
+ +
+
+M2Crypto.EC.load_key_string(string, callback=<function passphrase_callback at 0x1faa848>)[source]
+

Load an EC key pair from a string.

+ +++ + + + + + +
Parameters:
    +
  • string – String containing EC key pair in PEM format.
  • +
  • callback – A Python callable object that is invoked +to acquire a passphrase with which to unlock the +key. The default is util.passphrase_callback.
  • +
+
Returns:

M2Crypto.EC.EC object.

+
+
+ +
+
+M2Crypto.EC.load_key_string_pubkey(string, callback=<function passphrase_callback at 0x1faa848>)[source]
+

Load an M2Crypto.EC.PKey from a public key as a string.

+ +++ + + + + + +
Parameters:
    +
  • string – String containing the key in PEM format.
  • +
  • callback – A Python callable object that is invoked +to acquire a passphrase with which to protect the +key.
  • +
+
Returns:

M2Crypto.EC.PKey object.

+
+
+ +
+
+M2Crypto.EC.load_pub_key(file)[source]
+

Load an EC public key from filename.

+ +++ + + + + + +
Parameters:file – Name of filename containing EC public key in PEM +format.
Returns:M2Crypto.EC.EC_pub object.
+
+ +
+
+M2Crypto.EC.load_pub_key_bio(bio)[source]
+

Load an EC public key from an M2Crypto.BIO.BIO object.

+ +++ + + + + + +
Parameters:bio – M2Crypto.BIO.BIO object containing EC public key in PEM +format.
Returns:M2Crypto.EC.EC_pub object.
+
+ +
+
+M2Crypto.EC.pub_key_from_der(der)[source]
+

Create EC_pub from DER.

+
+ +
+
+M2Crypto.EC.pub_key_from_params(curve, bytes)[source]
+

Create EC_pub from curve name and octet string.

+
+ +
+
+

EVP Module

+
+
+class M2Crypto.EVP.Cipher(alg, key, iv, op, key_as_bytes=0, d='md5', salt='12345678', i=1, padding=1)[source]
+
+
+final()[source]
+
+ +
+
+m2_cipher_ctx_free()
+
+ +
+
+set_padding(padding=1)[source]
+

Actually always return 1

+
+ +
+
+update(data)[source]
+
+ +
+ +
+
+exception M2Crypto.EVP.EVPError[source]
+

Bases: exceptions.Exception

+
+ +
+
+class M2Crypto.EVP.HMAC(key, algo='sha1')[source]
+
+
+digest()
+
+ +
+
+final()[source]
+
+ +
+
+m2_hmac_ctx_free()
+
+ +
+
+reset(key)[source]
+
+ +
+
+update(data)[source]
+
+ +
+ +
+
+class M2Crypto.EVP.MessageDigest(algo)[source]
+

Message Digest

+
+
+digest()
+
+ +
+
+final()[source]
+
+ +
+
+m2_md_ctx_free()
+
+ +
+
+update(data)[source]
+

Add data to be digested.

+ +++ + + + +
Returns:-1 for Python error, 1 for success, 0 for OpenSSL failure.
+
+ +
+ +
+
+class M2Crypto.EVP.PKey(pkey=None, _pyfree=0, md='sha1')[source]
+

Public Key

+
+
+as_der()[source]
+

Return key in DER format in a string

+
+ +
+
+as_pem(cipher='aes_128_cbc', callback=<function passphrase_callback at 0x1faa848>)[source]
+

Return key in PEM format in a string.

+ +++ + + + +
Parameters:
    +
  • 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.
  • +
  • callback – A Python callable object that is invoked +to acquire a passphrase with which to protect +the key. The default is +util.passphrase_callback.
  • +
+
+
+ +
+
+assign_rsa(rsa, capture=1)[source]
+

Assign the RSA key pair to self.

+ +++ + + + + + +
Parameters:
    +
  • rsa – M2Crypto.RSA.RSA object to be assigned to self.
  • +
  • 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.
  • +
+
Returns:

Return 1 for success and 0 for failure.

+
+
+ +
+
+final()
+

Return signature.

+ +++ + + + +
Returns:The signature.
+
+ +
+
+get_modulus()[source]
+

Return the modulus in hex format.

+
+ +
+
+get_rsa()[source]
+

Return the underlying RSA key if that is what the EVP +instance is holding.

+
+ +
+
+m2_md_ctx_free()
+
+ +
+
+m2_pkey_free()
+
+ +
+
+reset_context(md='sha1')[source]
+

Reset internal message digest context.

+ +++ + + + +
Parameters:md – The message digest algorithm.
+
+ +
+
+save_key(file, cipher='aes_128_cbc', callback=<function passphrase_callback at 0x1faa848>)[source]
+

Save the key pair to a file in PEM format.

+ +++ + + + +
Parameters:
    +
  • file – Name of file to save key to.
  • +
  • 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.
  • +
  • callback – A Python callable object that is invoked +to acquire a passphrase with which to protect +the key. The default is +util.passphrase_callback.
  • +
+
+
+ +
+
+save_key_bio(bio, cipher='aes_128_cbc', callback=<function passphrase_callback at 0x1faa848>)[source]
+

Save the key pair to the M2Crypto.BIO object ‘bio’ in PEM format.

+ +++ + + + +
Parameters:
    +
  • bio – M2Crypto.BIO object to save key to.
  • +
  • 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.
  • +
  • callback – A Python callable object that is invoked +to acquire a passphrase with which to protect +the key. The default is +util.passphrase_callback.
  • +
+
+
+ +
+
+sign_final()[source]
+

Return signature.

+ +++ + + + +
Returns:The signature.
+
+ +
+
+sign_init()[source]
+

Initialise signing operation with self.

+
+ +
+
+sign_update(data)[source]
+

Feed data to signing operation.

+ +++ + + + +
Parameters:data – Data to be signed.
+
+ +
+
+size()[source]
+

Return the size of the key in bytes.

+
+ +
+
+update(data)
+

Feed data to signing operation.

+ +++ + + + +
Parameters:data – Data to be signed.
+
+ +
+
+verify_final(sign)[source]
+

Return result of verification.

+ +++ + + + + + +
Parameters:sign – Signature to use for verification
Returns:Result of verification: 1 for success, 0 for failure, -1 on +other error.
+
+ +
+
+verify_init()[source]
+

Initialise signature verification operation with self.

+
+ +
+
+verify_update(data)[source]
+

Feed data to verification operation.

+ +++ + + + + + +
Parameters:data – Data to be verified.
Returns:-1 on Python error, 1 for success, 0 for OpenSSL error
+
+ +
+ +
+
+M2Crypto.EVP.hmac(key, data, algo='sha1')[source]
+
+ +
+
+M2Crypto.EVP.load_key(file, callback=<function passphrase_callback at 0x1faa848>)[source]
+

Load an M2Crypto.EVP.PKey from file.

+ +++ + + + + + +
Parameters:
    +
  • file – Name of file containing the key in PEM format.
  • +
  • callback – A Python callable object that is invoked +to acquire a passphrase with which to protect the +key.
  • +
+
Returns:

M2Crypto.EVP.PKey object.

+
+
+ +
+
+M2Crypto.EVP.load_key_bio(bio, callback=<function passphrase_callback at 0x1faa848>)[source]
+

Load an M2Crypto.EVP.PKey from an M2Crypto.BIO object.

+ +++ + + + + + +
Parameters:
    +
  • bio – M2Crypto.BIO object containing the key in PEM format.
  • +
  • callback – A Python callable object that is invoked +to acquire a passphrase with which to protect the +key.
  • +
+
Returns:

M2Crypto.EVP.PKey object.

+
+
+ +
+
+M2Crypto.EVP.load_key_bio_pubkey(bio, callback=<function passphrase_callback at 0x1faa848>)[source]
+

Load an M2Crypto.EVP.PKey from a public key as a M2Crypto.BIO object.

+ +++ + + + + + +
Parameters:
    +
  • bio – M2Crypto.BIO object containing the key in PEM format.
  • +
  • callback – A Python callable object that is invoked +to acquire a passphrase with which to protect the +key.
  • +
+
Returns:

M2Crypto.EVP.PKey object.

+
+
+ +
+
+M2Crypto.EVP.load_key_string(string, callback=<function passphrase_callback at 0x1faa848>)[source]
+

Load an M2Crypto.EVP.PKey from a string.

+ +++ + + + + + +
Parameters:
    +
  • string – String containing the key in PEM format.
  • +
  • callback – A Python callable object that is invoked +to acquire a passphrase with which to protect the +key.
  • +
+
Returns:

M2Crypto.EVP.PKey object.

+
+
+ +
+
+M2Crypto.EVP.load_key_string_pubkey(string, callback=<function passphrase_callback at 0x1faa848>)[source]
+

Load an M2Crypto.EVP.PKey from a public key as a string.

+ +++ + + + + + +
Parameters:
    +
  • string – String containing the key in PEM format.
  • +
  • callback – A Python callable object that is invoked +to acquire a passphrase with which to protect the +key.
  • +
+
Returns:

M2Crypto.EVP.PKey object.

+
+
+ +
+
+M2Crypto.EVP.pbkdf2(password, salt, iter, keylen)[source]
+

Derive a key from password using PBKDF2 algorithm specified in RFC 2898.

+ +++ + + + + + +
Parameters:
    +
  • password – Derive the key from this password.
  • +
  • salt – Salt.
  • +
  • iter – Number of iterations to perform.
  • +
  • keylen – Length of key to produce.
  • +
+
Returns:

Key.

+
+
+ +
+
+

Engine Module

+

M2Crypto wrapper for OpenSSL ENGINE API.

+

Pavel Shramov +IMEC MSU

+
+
+class M2Crypto.Engine.Engine(id=None, _ptr=None, _pyfree=1)[source]
+

Wrapper for ENGINE object.

+
+
+ctrl_cmd_string(cmd, arg, optional=0)[source]
+

Call ENGINE_ctrl_cmd_string

+
+ +
+
+finish()[source]
+

Release a functional and structural reference to the engine.

+
+ +
+
+get_id()[source]
+

Return engine id

+
+ +
+
+get_name()[source]
+

Return engine name

+
+ +
+
+init()[source]
+

Obtain a functional reference to the engine.

+ +++ + + + +
Returns:0 on error, non-zero on success.
+
+ +
+
+load_certificate(name)[source]
+

Load certificate from engine (e.g from smartcard). +NOTE: This function may be not implemented by engine!

+
+ +
+
+load_private_key(name, pin=None)[source]
+

Load private key with engine methods (e.g from smartcard). +If pin is not set it will be asked

+
+ +
+
+load_public_key(name, pin=None)[source]
+

Load public key with engine methods (e.g from smartcard).

+
+ +
+
+m2_engine_free()
+
+ +
+
+set_default(methods=65535)[source]
+

Use this engine as default for methods specified in argument

+ +++ + + + +
Parameters:methods – Possible values are bitwise OR of m2.ENGINE_METHOD_*
+
+ +
+ +
+
+exception M2Crypto.Engine.EngineError[source]
+

Bases: exceptions.Exception

+
+ +
+
+M2Crypto.Engine.cleanup()[source]
+

If you load any engines, you need to clean up after your application +is finished with the engines.

+
+ +
+
+M2Crypto.Engine.load_dynamic()[source]
+

Load dynamic engine

+
+ +
+
+M2Crypto.Engine.load_dynamic_engine(id, sopath)[source]
+

Load and return dymanic engine from sopath and assign id to it

+
+ +
+
+M2Crypto.Engine.load_openssl()[source]
+

Load openssl engine

+
+ +
+
+

Err Module

+
+
+exception M2Crypto.Err.M2CryptoError[source]
+

Bases: exceptions.Exception

+
+ +
+
+exception M2Crypto.Err.SSLError(err, client_addr)[source]
+

Bases: exceptions.Exception

+
+ +
+
+M2Crypto.Err.get_error()[source]
+
+ +
+
+M2Crypto.Err.get_error_code()[source]
+
+ +
+
+M2Crypto.Err.get_error_func(err)[source]
+
+ +
+
+M2Crypto.Err.get_error_lib(err)[source]
+
+ +
+
+M2Crypto.Err.get_error_reason(err)[source]
+
+ +
+
+M2Crypto.Err.get_x509_verify_error(err)[source]
+
+ +
+
+M2Crypto.Err.peek_error_code()[source]
+
+ +
+
+

RC4 Module

+
+
+class M2Crypto.RC4.RC4(key=None)[source]
+

Object interface to the stream cipher RC4.

+
+
+final()[source]
+
+ +
+
+rc4_free()
+
+ +
+
+set_key(key)[source]
+
+ +
+
+update(data)[source]
+
+ +
+ +
+
+

RSA Module

+
+
+class M2Crypto.RSA.RSA(rsa, _pyfree=0)[source]
+

RSA Key Pair.

+
+
+as_pem(cipher='aes_128_cbc', callback=<function passphrase_callback at 0x1faa848>)[source]
+

Returns the key(pair) as a string in PEM format.

+
+ +
+
+check_key()[source]
+
+++ + + + +
Returns: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).
+
+ +
+
+m2_rsa_free()
+
+ +
+
+private_decrypt(data, padding)[source]
+
+ +
+
+private_encrypt(data, padding)[source]
+
+ +
+
+pub()[source]
+
+ +
+
+public_decrypt(data, padding)[source]
+
+ +
+
+public_encrypt(data, padding)[source]
+
+ +
+
+save_key(file, cipher='aes_128_cbc', callback=<function passphrase_callback at 0x1faa848>)[source]
+

Save the key pair to a file in PEM format.

+ +++ + + + +
Parameters:
    +
  • file – Name of file to save key to.
  • +
  • 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.
  • +
  • callback – A Python callable object that is invoked +to acquire a passphrase with which to protect +the key. The default is +util.passphrase_callback.
  • +
+
+
+ +
+
+save_key_bio(bio, cipher='aes_128_cbc', callback=<function passphrase_callback at 0x1faa848>)[source]
+

Save the key pair to an M2Crypto.BIO.BIO object in PEM format.

+ +++ + + + +
Parameters:
    +
  • bio – M2Crypto.BIO.BIO object to save key to.
  • +
  • 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.
  • +
  • callback – A Python callable object that is invoked +to acquire a passphrase with which to protect +the key. The default is +util.passphrase_callback.
  • +
+
+
+ +
+
+save_key_der(file)[source]
+

Save the key pair to a file in DER format.

+ +++ + + + +
Parameters:file – Filename to save key to
+
+ +
+
+save_key_der_bio(bio)[source]
+

Save the key pair to an M2Crypto.BIO.BIO object in DER format.

+ +++ + + + +
Parameters:bio – M2Crypto.BIO.BIO object to save key to.
+
+ +
+
+save_pem(file, cipher='aes_128_cbc', callback=<function passphrase_callback at 0x1faa848>)
+

Save the key pair to a file in PEM format.

+ +++ + + + +
Parameters:
    +
  • file – Name of file to save key to.
  • +
  • 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.
  • +
  • callback – A Python callable object that is invoked +to acquire a passphrase with which to protect +the key. The default is +util.passphrase_callback.
  • +
+
+
+ +
+
+save_pub_key(file)[source]
+

Save the public key to a file in PEM format.

+ +++ + + + +
Parameters:file – Name of file to save key to.
+
+ +
+
+save_pub_key_bio(bio)[source]
+

Save the public key to an M2Crypto.BIO.BIO object in PEM format.

+ +++ + + + +
Parameters:bio – M2Crypto.BIO.BIO object to save key to.
+
+ +
+
+sign(digest, algo='sha1')[source]
+

Signs a digest with the private key

+ +++ + + + + + +
Parameters:
    +
  • digest – A digest created by using the digest method
  • +
  • algo – The method that created the digest. +Legal values like ‘sha1’,’sha224’, ‘sha256’, +‘ripemd160’, and ‘md5’.
  • +
+
Returns:

a string which is the signature

+
+
+ +
+
+sign_rsassa_pss(digest, algo='sha1', salt_length=20)[source]
+

Signs a digest with the private key using RSASSA-PSS

+ +++ + + + + + +
Parameters:
    +
  • digest – A digest created by using the digest method
  • +
  • salt_length – The length of the salt to use
  • +
  • algo – The hash algorithm to use +Legal values like ‘sha1’,’sha224’, ‘sha256’, +‘ripemd160’, and ‘md5’.
  • +
+
Returns:

a string which is the signature

+
+
+ +
+
+verify(data, signature, algo='sha1')[source]
+

Verifies the signature with the public key

+ +++ + + + + + +
Parameters:
    +
  • data – Data that has been signed
  • +
  • signature – The signature signed with the private key
  • +
  • algo – The method use to create digest from the data +before it was signed. Legal values like +‘sha1’,’sha224’, ‘sha256’, ‘ripemd160’, and ‘md5’.
  • +
+
Returns:

1 or 0, depending on whether the signature was +verified or not.

+
+
+ +
+
+verify_rsassa_pss(data, signature, algo='sha1', salt_length=20)[source]
+

Verifies the signature RSASSA-PSS

+ +++ + + + + + +
Parameters:
    +
  • data – Data that has been signed
  • +
  • signature – The signature signed with RSASSA-PSS
  • +
  • salt_length – The length of the salt that was used
  • +
  • algo – The hash algorithm to use +Legal values are for example ‘sha1’,’sha224’, +‘sha256’, ‘ripemd160’, and ‘md5’.
  • +
+
Returns:

1 or 0, depending on whether the signature was +verified or not.

+
+
+ +
+ +
+
+exception M2Crypto.RSA.RSAError[source]
+

Bases: exceptions.Exception

+
+ +
+
+class M2Crypto.RSA.RSA_pub(rsa, _pyfree=0)[source]
+

Bases: M2Crypto.RSA.RSA

+

Object interface to an RSA public key.

+
+
+check_key()[source]
+
+ +
+
+private_decrypt(*argv)[source]
+
+ +
+
+private_encrypt(*argv)[source]
+
+ +
+
+save_key(file, *args, **kw)[source]
+

Save public key to file.

+
+ +
+
+save_key_bio(bio, *args, **kw)[source]
+

Save public key to BIO.

+
+ +
+ +
+
+M2Crypto.RSA.gen_key(bits, e, callback=<function keygen_callback at 0x1ffa410>)[source]
+

Generate an RSA key pair.

+ +++ + + + + + +
Parameters:
    +
  • bits – Key length, in bits.
  • +
  • e – The RSA public exponent.
  • +
  • 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.
  • +
+
Returns:

M2Crypto.RSA.RSA object.

+
+
+ +
+
+M2Crypto.RSA.keygen_callback(p, n, out=<open file '<stdout>', mode 'w' at 0x7fc7ebc63150>)[source]
+

Default callback for gen_key().

+
+ +
+
+M2Crypto.RSA.load_key(file, callback=<function passphrase_callback at 0x1faa848>)[source]
+

Load an RSA key pair from file.

+ +++ + + + + + +
Parameters:
    +
  • file – Name of file containing RSA public key in PEM format.
  • +
  • callback – A Python callable object that is invoked +to acquire a passphrase with which to unlock the +key. The default is util.passphrase_callback.
  • +
+
Returns:

M2Crypto.RSA.RSA object.

+
+
+ +
+
+M2Crypto.RSA.load_key_bio(bio, callback=<function passphrase_callback at 0x1faa848>)[source]
+

Load an RSA key pair from an M2Crypto.BIO.BIO object.

+ +++ + + + + + +
Parameters:
    +
  • bio – M2Crypto.BIO.BIO object containing RSA key pair in PEM +format.
  • +
  • callback – A Python callable object that is invoked +to acquire a passphrase with which to unlock the +key. The default is util.passphrase_callback.
  • +
+
Returns:

M2Crypto.RSA.RSA object.

+
+
+ +
+
+M2Crypto.RSA.load_key_string(string, callback=<function passphrase_callback at 0x1faa848>)[source]
+

Load an RSA key pair from a string.

+ +++ + + + + + +
Parameters:
    +
  • string – String containing RSA key pair in PEM format.
  • +
  • callback – A Python callable object that is invoked +to acquire a passphrase with which to unlock the +key. The default is util.passphrase_callback.
  • +
+
Returns:

M2Crypto.RSA.RSA object.

+
+
+ +
+
+M2Crypto.RSA.load_pub_key(file)[source]
+

Load an RSA public key from file.

+ +++ + + + + + +
Parameters:file – Name of file containing RSA public key in PEM format.
Returns:M2Crypto.RSA.RSA_pub object.
+
+ +
+
+M2Crypto.RSA.load_pub_key_bio(bio)[source]
+

Load an RSA public key from an M2Crypto.BIO.BIO object.

+ +++ + + + + + +
Parameters:bio – M2Crypto.BIO.BIO object containing RSA public key in PEM +format.
Returns:M2Crypto.RSA.RSA_pub object.
+
+ +
+
+M2Crypto.RSA.new_pub_key(e_n)[source]
+

Instantiate an RSA_pub object from an (e, n) tuple.

+ +++ + + + + + +
Parameters:
    +
  • 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.
  • +
  • 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.
  • +
+
Returns:

M2Crypto.RSA.RSA_pub object.

+
+
+ +
+
+M2Crypto.RSA.rsa_error()[source]
+
+ +
+
+

Rand Module

+
+
+M2Crypto.Rand.rand_seed()
+
+ +
+
+M2Crypto.Rand.rand_add()
+
+ +
+
+M2Crypto.Rand.load_file()
+
+ +
+
+M2Crypto.Rand.save_file()
+
+ +
+
+M2Crypto.Rand.rand_bytes()
+
+ +
+
+M2Crypto.Rand.rand_pseudo_bytes(n)[source]
+
+ +
+
+M2Crypto.Rand.rand_file_name()[source]
+
+ +
+
+M2Crypto.Rand.rand_status()
+
+ +
+
+

SMIME Module

+
+
+class M2Crypto.SMIME.Cipher(algo)[source]
+

Object interface to EVP_CIPHER without all the frills of +M2Crypto.EVP.Cipher.

+
+ +
+
+class M2Crypto.SMIME.PKCS7(pkcs7=None, _pyfree=0)[source]
+
+
+get0_signers(certs, flags=0)[source]
+
+ +
+
+m2_pkcs7_free()
+
+ +
+
+type(text_name=0)[source]
+
+ +
+
+write(bio)[source]
+
+ +
+
+write_der(bio)[source]
+
+ +
+ +
+
+exception M2Crypto.SMIME.PKCS7_Error[source]
+

Bases: exceptions.Exception

+
+ +
+
+class M2Crypto.SMIME.SMIME[source]
+
+
+decrypt(pkcs7, flags=0)[source]
+
+ +
+
+encrypt(data_bio, flags=0)[source]
+
+ +
+
+load_key(keyfile, certfile=None, callback=<function passphrase_callback at 0x1faa848>)[source]
+
+ +
+
+load_key_bio(keybio, certbio=None, callback=<function passphrase_callback at 0x1faa848>)[source]
+
+ +
+
+set_cipher(cipher)[source]
+
+ +
+
+set_x509_stack(stack)[source]
+
+ +
+
+set_x509_store(store)[source]
+
+ +
+
+sign(data_bio, flags=0, algo='sha1')[source]
+
+ +
+
+unset_cipher()[source]
+
+ +
+
+unset_key()[source]
+
+ +
+
+unset_x509_stack()[source]
+
+ +
+
+unset_x509_store()[source]
+
+ +
+
+verify(pkcs7, data_bio=None, flags=0)[source]
+
+ +
+
+write(out_bio, pkcs7, data_bio=None, flags=0)[source]
+
+ +
+ +
+
+exception M2Crypto.SMIME.SMIME_Error[source]
+

Bases: exceptions.Exception

+
+ +
+
+M2Crypto.SMIME.load_pkcs7(p7file)[source]
+
+ +
+
+M2Crypto.SMIME.load_pkcs7_bio(p7_bio)[source]
+
+ +
+
+M2Crypto.SMIME.load_pkcs7_bio_der(p7_bio)[source]
+
+ +
+
+M2Crypto.SMIME.load_pkcs7_der(p7file)[source]
+
+ +
+
+M2Crypto.SMIME.smime_load_pkcs7(p7file)[source]
+
+ +
+
+M2Crypto.SMIME.smime_load_pkcs7_bio(p7_bio)[source]
+
+ +
+
+M2Crypto.SMIME.text_crlf(text)[source]
+
+ +
+
+M2Crypto.SMIME.text_crlf_bio(bio_in)[source]
+
+ +
+
+

X509 Module

+
+
+class M2Crypto.X509.CRL(crl=None, _pyfree=0)[source]
+

X509 Certificate Revocation List

+
+
+as_text()[source]
+

Return CRL in PEM format in a string.

+ +++ + + + +
Returns:String containing the CRL in PEM format.
+
+ +
+
+m2_x509_crl_free()
+
+ +
+ +
+
+class M2Crypto.X509.Request(req=None, _pyfree=0)[source]
+

X509 Certificate Request.

+
+
+add_extensions(ext_stack)[source]
+

Add X509 extensions to this request.

+ +++ + + + + + +
Parameters:ext_stack – Stack of extensions to add.
Returns:1 for success and 0 for failure
+
+ +
+
+as_der()[source]
+
+ +
+
+as_pem()[source]
+
+ +
+
+as_text()[source]
+
+ +
+
+get_pubkey()[source]
+

Get the public key for the request.

+ +++ + + + +
Returns:Public key from the request.
+
+ +
+
+get_subject()[source]
+
+ +
+
+get_version()[source]
+

Get version.

+ +++ + + + +
Returns:Returns version.
+
+ +
+
+m2_x509_req_free()
+
+ +
+
+save(filename, format=1)[source]
+

Saves X.509 certificate request to a file. Default output +format is PEM.

+ +++ + + + + + +
Parameters:
    +
  • filename – Name of the file the request will be saved to.
  • +
  • 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.
  • +
+
Returns:

1 for success, 0 for failure. +The error code can be obtained by ERR_get_error.

+
+
+ +
+
+save_pem(filename)[source]
+
+ +
+
+set_pubkey(pkey)[source]
+

Set the public key for the request.

+ +++ + + + + + +
Parameters:pkey – Public key
Returns:Return 1 for success and 0 for failure.
+
+ +
+
+set_subject(name)
+

Set subject name.

+ +++ + + + + + +
Parameters:name – subjectName field.
Returns:1 for success and 0 for failure
+
+ +
+
+set_subject_name(name)[source]
+

Set subject name.

+ +++ + + + + + +
Parameters:name – subjectName field.
Returns:1 for success and 0 for failure
+
+ +
+
+set_version(version)[source]
+

Set version.

+ +++ + + + + + +
Parameters:version – Version number.
Returns:Returns 0 on failure.
+
+ +
+
+sign(pkey, md)[source]
+
+++ + + + + + +
Parameters:
    +
  • pkey – PKey to be signed
  • +
  • md – used algorigthm
  • +
+
Returns:

1 for success and 0 for failure

+
+
+ +
+
+verify(pkey)[source]
+
+++ + + + + + +
Parameters:pkey – PKey to be verified
Returns:1 for success and 0 for failure
+
+ +
+ +
+
+class M2Crypto.X509.X509(x509=None, _pyfree=0)[source]
+

X.509 Certificate

+
+
+add_ext(ext)[source]
+

Add X509 extension to this certificate.

+ +++ + + + +
Parameters:ext – Extension
+

:return 1 for success and 0 for failure

+
+ +
+
+as_der()[source]
+
+ +
+
+as_pem()[source]
+
+ +
+
+as_text()[source]
+
+ +
+
+check_ca()[source]
+

Check if the certificate is a Certificate Authority (CA) certificate.

+ +++ + + + + + +
Returns:0 if the certificate is not CA, nonzero otherwise.
Requires :OpenSSL 0.9.8 or newer
+
+ +
+
+check_purpose(id, ca)[source]
+

Check if the certificate’s purpose matches the asked purpose.

+ +++ + + + + + +
Parameters:
    +
  • id – Purpose id. See X509_PURPOSE_* constants.
  • +
  • ca – 1 if the certificate should be CA, 0 otherwise.
  • +
+
Returns:

0 if the certificate purpose does not match, nonzero +otherwise.

+
+
+ +
+
+get_ext(name)[source]
+

Get X509 extension by name.

+ +++ + + + + + +
Parameters:name – Name of the extension
Returns:X509_Extension
+
+ +
+
+get_ext_at(index)[source]
+

Get X509 extension by index.

+ +++ + + + + + +
Parameters:index – Name of the extension
Returns:X509_Extension
+
+ +
+
+get_ext_count()[source]
+

Get X509 extension count.

+
+ +
+
+get_fingerprint(md='md5')[source]
+

Get the fingerprint of the certificate.

+ +++ + + + + + +
Parameters:md – Message digest algorithm to use.
Returns:String containing the fingerprint in hex format.
+
+ +
+
+get_issuer()[source]
+
+ +
+
+get_not_after()[source]
+
+ +
+
+get_not_before()[source]
+
+ +
+
+get_pubkey()[source]
+
+ +
+
+get_serial_number()[source]
+
+ +
+
+get_subject()[source]
+
+ +
+
+get_version()[source]
+
+ +
+
+m2_x509_free()
+
+ +
+
+save(filename, format=1)[source]
+

Saves X.509 certificate to a file. Default output +format is PEM.

+ +++ + + + + + +
Parameters:
    +
  • filename – Name of the file the cert will be saved to.
  • +
  • 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.
  • +
+
Returns:

1 for success or 0 for failure

+
+
+ +
+
+save_pem(filename)[source]
+
+++ + + + + + +
Parameters:filename – name of the file to be loaded
Returns:1 for success or 0 for failure
+
+ +
+
+set_issuer(name)[source]
+

Set issuer name.

+ +++ + + + +
Parameters:name – subjectName field.
+

:return 1 for success and 0 for failure

+
+ +
+
+set_issuer_name(name)[source]
+
+++ + + + +
Returns:1 on success, 0 on failure
+
+ +
+
+set_not_after(asn1_time)[source]
+
+++ + + + +
Returns:1 on success, 0 on failure
+
+ +
+
+set_not_before(asn1_time)[source]
+
+++ + + + +
Returns:1 on success, 0 on failure
+
+ +
+
+set_pubkey(pkey)[source]
+

Set the public key for the certificate

+ +++ + + + +
Parameters:pkey – Public key
+

:return 1 for success and 0 for failure

+
+ +
+
+set_serial_number(serial)[source]
+

Set serial number.

+ +++ + + + +
Parameters:serial – Serial number.
+

:return 1 for success and 0 for failure.

+
+ +
+
+set_subject(name)[source]
+

Set subject name.

+ +++ + + + +
Parameters:name – subjectName field.
+

:return 1 for success and 0 for failure

+
+ +
+
+set_subject_name(name)[source]
+
+++ + + + +
Returns:1 on success, 0 on failure
+
+ +
+
+set_version(version)[source]
+

Set version of the certificate.

+ +++ + + + + + +
Parameters:version – Version number.
Returns:Returns 0 on failure.
+
+ +
+
+sign(pkey, md)[source]
+

Sign the certificate.

+ +++ + + + +
Parameters:
    +
  • pkey – Public key
  • +
  • md – Message digest algorithm to use for signing, +for example ‘sha1’.
  • +
+
+

:return int

+
+ +
+
+verify(pkey=None)[source]
+
+ +
+ +
+
+exception M2Crypto.X509.X509Error[source]
+

Bases: exceptions.Exception

+
+ +
+
+class M2Crypto.X509.X509_Extension(x509_ext_ptr=None, _pyfree=1)[source]
+

X509 Extension

+
+
+get_critical()[source]
+

Return whether or not this is a critical extension.

+ +++ + + + +
Returns:Nonzero if this is a critical extension.
+
+ +
+
+get_name()[source]
+

Get the extension name, for example ‘subjectAltName’.

+
+ +
+
+get_value(flag=0, indent=0)[source]
+

Get the extension value, for example ‘DNS:www.example.com‘.

+ +++ + + + +
Parameters:
    +
  • flag – Flag to control what and how to print.
  • +
  • indent – How many spaces to print before actual value.
  • +
+
+
+ +
+
+m2_x509_extension_free()
+
+ +
+
+set_critical(critical=1)[source]
+

Mark this extension critical or noncritical. By default an +extension is not critical.

+ +++ + + + + + +
Parameters:critical – Nonzero sets this extension as critical. +Calling this method without arguments will +set this extension to critical.
Returns:1 for success, 0 for failure
+
+ +
+ +
+
+class M2Crypto.X509.X509_Extension_Stack(stack=None, _pyfree=0)[source]
+

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!
+
+
+m2_sk_x509_extension_free()
+
+ +
+
+pop()[source]
+

Pop X509_Extension object from the stack.

+ +++ + + + +
Returns:X509_Extension popped
+
+ +
+
+push(x509_ext)[source]
+

Push X509_Extension object onto the stack.

+ +++ + + + + + +
Parameters:x509_ext – X509_Extension object to be pushed onto the stack.
Returns:The number of extensions on the stack.
+
+ +
+ +
+
+class M2Crypto.X509.X509_Name(x509_name=None, _pyfree=0)[source]
+

X509 Name

+
+
+add_entry_by_txt(field, type, entry, len, loc, set)[source]
+

Add X509_Name field whose name is identified by its name.

+ +++ + + + +
Parameters:
    +
  • field – name of the entry
  • +
  • type – use MBSTRING_ASC or MBSTRING_UTF8 +(or standard ASN1 type like V_ASN1_IA5STRING)
  • +
  • entry – value
  • +
  • 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).

+ +++ + + + + + +
Parameters:
    +
  • loc – determines the index where the new entry is +inserted: if it is -1 it is appended.
  • +
  • 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.
  • +
+
Returns:

1 for success of 0 if an error occurred.

+
+
+ +
+
+as_der()[source]
+
+ +
+
+as_hash()[source]
+
+ +
+
+as_text(indent=0, flags=0)[source]
+

as_text returns the name as a string.

+ +++ + + + +
Parameters:
    +
  • indent – Each line in multiline format is indented +by this many spaces.
  • +
  • flags – Flags that control how the output should be formatted.
  • +
+
+
+ +
+
+entry_count()[source]
+
+ +
+
+get_entries_by_nid(nid)[source]
+

Retrieve the next index matching nid.

+ +++ + + + + + +
Parameters:nid – name of the entry (as m2.NID* constants)
Returns:list of X509_Name_Entry items
+
+ +
+
+m2_x509_name_free()
+
+ +
+
+nid = {'C': 14, 'serialNumber': 105, 'organizationName': 17, 'CN': 13, 'SP': 16, 'commonName': 13, 'L': 15, 'stateOrProvinceName': 16, 'ST': 16, 'emailAddress': 48, 'O': 17, 'localityName': 15, 'GN': 99, 'surname': 100, 'OU': 18, 'givenName': 99, 'Email': 48, 'organizationUnitName': 18, 'SN': 100}
+
+ +
+ +
+
+class M2Crypto.X509.X509_Name_Entry(x509_name_entry, _pyfree=0)[source]
+

X509 Name Entry

+
+
+create_by_txt(field, type, entry, len)[source]
+
+ +
+
+get_data()[source]
+
+ +
+
+get_object()[source]
+
+ +
+
+m2_x509_name_entry_free()
+
+ +
+
+set_data(data, type=4097)[source]
+

Sets the field name to asn1obj

+ +++ + + + + + +
Parameters:data – data in a binary form to be set
Returns:0 on failure, 1 on success
+
+ +
+
+set_object(asn1obj)[source]
+

Sets the field name to asn1obj

+ +++ + + + + + +
Parameters:asn1obj
Returns:0 on failure, 1 on success
+
+ +
+ +
+
+class M2Crypto.X509.X509_Stack(stack=None, _pyfree=0, _pyfree_x509=0)[source]
+

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!
+
+
+as_der()[source]
+

Return the stack as a DER encoded string

+
+ +
+
+m2_sk_x509_free()
+
+ +
+
+pop()[source]
+

pop a certificate from the stack.

+ +++ + + + +
Returns:X509 object that was popped, or None if there is +nothing to pop.
+
+ +
+
+push(x509)[source]
+

push an X509 certificate onto the stack.

+ +++ + + + + + +
Parameters:x509 – X509 object.
Returns:The number of X509 objects currently on the stack.
+
+ +
+ +
+
+class M2Crypto.X509.X509_Store(store=None, _pyfree=0)[source]
+

X509 Store

+
+
+add_cert(x509)
+
+ +
+
+add_x509(x509)[source]
+
+ +
+
+load_info(file)[source]
+
+++ + + + + + +
Parameters:file – filename
Returns:1 on success, 0 on failure
+
+ +
+
+load_locations(file)
+
+++ + + + + + +
Parameters:file – filename
Returns:1 on success, 0 on failure
+
+ +
+
+m2_x509_store_free()
+
+ +
+
+set_verify_cb(callback=None)[source]
+

Set callback which will be called when the store is verified. +Wrapper over OpenSSL X509_STORE_set_verify_cb().

+ +++ + + + + + + + + + +
Parameters: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.
Returns:None
+
+ +
+ +
+
+class M2Crypto.X509.X509_Store_Context(x509_store_ctx, _pyfree=0)[source]
+

X509 Store Context

+
+
+get1_chain()[source]
+

Get certificate chain.

+ +++ + + + +
Returns:Reference counted (i.e. safe to use even after the store +context goes away) stack of certificates in the chain.
+
+ +
+
+get_current_cert()[source]
+

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.
+
+ +
+
+get_error()[source]
+

Get error code.

+
+ +
+
+get_error_depth()[source]
+

Get error depth.

+
+ +
+
+m2_x509_store_ctx_free()
+
+ +
+ +
+
+M2Crypto.X509.load_cert(file, format=1)[source]
+

Load certificate from file.

+ +++ + + + + + +
Parameters:
    +
  • file – Name of file containing certificate in either DER or +PEM format.
  • +
  • format – Describes the format of the file to be loaded, +either PEM or DER.
  • +
+
Returns:

M2Crypto.X509.X509 object.

+
+
+ +
+
+M2Crypto.X509.load_cert_bio(bio, format=1)[source]
+

Load certificate from a bio.

+ +++ + + + + + +
Parameters:
    +
  • bio – BIO pointing at a certificate in either DER or PEM format.
  • +
  • format – Describes the format of the cert to be loaded, +either PEM or DER (via constants FORMAT_PEM +and FORMAT_FORMAT_DER)
  • +
+
Returns:

M2Crypto.X509.X509 object.

+
+
+ +
+
+M2Crypto.X509.load_cert_der_string(string)[source]
+

Load certificate from a string.

+ +++ + + + + + +
Parameters:string – String containing a certificate in DER format.
Returns:M2Crypto.X509.X509 object.
+
+ +
+
+M2Crypto.X509.load_cert_string(string, format=1)[source]
+

Load certificate from a string.

+ +++ + + + + + +
Parameters:
    +
  • string – String containing a certificate in either DER or PEM format.
  • +
  • format – Describes the format of the cert to be loaded, +either PEM or DER (via constants FORMAT_PEM +and FORMAT_FORMAT_DER)
  • +
+
Returns:

M2Crypto.X509.X509 object.

+
+
+ +
+
+M2Crypto.X509.load_crl(file)[source]
+

Load CRL from file.

+ +++ + + + + + +
Parameters:file – Name of file containing CRL in PEM format.
Returns:M2Crypto.X509.CRL object.
+
+ +
+
+M2Crypto.X509.load_request(file, format=1)[source]
+

Load certificate request from file.

+ +++ + + + + + +
Parameters:
    +
  • file – Name of file containing certificate request in +either PEM or DER format.
  • +
  • format – Describes the format of the file to be loaded, +either PEM or DER. (using constants FORMAT_PEM +and FORMAT_DER)
  • +
+
Returns:

Request object.

+
+
+ +
+
+M2Crypto.X509.load_request_bio(bio, format=1)[source]
+

Load certificate request from a bio.

+ +++ + + + + + +
Parameters:
    +
  • bio – BIO pointing at a certificate request in +either DER or PEM format.
  • +
  • format – Describes the format of the request to be loaded, +either PEM or DER. (using constants FORMAT_PEM +and FORMAT_DER)
  • +
+
Returns:

M2Crypto.X509.Request object.

+
+
+ +
+
+M2Crypto.X509.load_request_der_string(string)[source]
+

Load certificate request from a string.

+ +++ + + + + + +
Parameters:string – String containing a certificate request in DER format.
Returns:M2Crypto.X509.Request object.
+
+ +
+
+M2Crypto.X509.load_request_string(string, format=1)[source]
+

Load certificate request from a string.

+ +++ + + + + + +
Parameters:
    +
  • string – String containing a certificate request in +either DER or PEM format.
  • +
  • format – Describes the format of the request to be loaded, +either PEM or DER. (using constants FORMAT_PEM +and FORMAT_DER)
  • +
+
Returns:

M2Crypto.X509.Request object.

+
+
+ +
+
+M2Crypto.X509.new_extension(name, value, critical=0, _pyfree=1)[source]
+

Create new X509_Extension instance.

+
+ +
+
+M2Crypto.X509.new_stack_from_der(der_string)[source]
+

Create a new X509_Stack from DER string.

+ +++ + + + +
Returns:X509_Stack
+
+ +
+
+M2Crypto.X509.x509_store_default_cb(ok, ctx)[source]
+
+ +
+
+

callback Module

+
+
+

ftpslib Module

+
+
+class M2Crypto.ftpslib.FTP_TLS(host=None, ssl_ctx=None)[source]
+

Bases: ftplib.FTP

+

Python OO interface to client-side FTP/TLS.

+
+
+auth_ssl()[source]
+

Secure the control connection per AUTH SSL, aka AUTH TLS-P.

+
+ +
+
+auth_tls()[source]
+

Secure the control connection per AUTH TLS, aka AUTH TLS-C.

+
+ +
+
+ntransfercmd(cmd, rest=None)[source]
+

Initiate a data transfer.

+
+ +
+
+prot_c()[source]
+

Set up data connection in the clear.

+
+ +
+
+prot_p()[source]
+

Set up secure data connection.

+
+ +
+ +
+
+

httpslib Module

+
+
+class M2Crypto.httpslib.HTTPSConnection(host, port=None, strict=None, **ssl)[source]
+

Bases: httplib.HTTPConnection

+

This class allows communication via SSL using M2Crypto.

+
+
+close()[source]
+
+ +
+
+connect()[source]
+
+ +
+
+default_port = 443
+
+ +
+
+get_session()[source]
+
+ +
+
+set_session(session)[source]
+
+ +
+ +
+
+class M2Crypto.httpslib.ProxyHTTPSConnection(host, port=None, strict=None, username=None, password=None, **ssl)[source]
+

Bases: M2Crypto.httpslib.HTTPSConnection

+

An HTTPS Connection that uses a proxy and the CONNECT request.

+

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.

+

Finally, the actual request is sent over the SSL connection tunneling +through the proxy.

+
+
+connect()[source]
+
+ +
+
+endheaders(*args, **kwargs)[source]
+
+ +
+
+putheader(header, value)[source]
+
+ +
+
+putrequest(method, url, skip_host=0, skip_accept_encoding=0)[source]
+

putrequest is called before connect, so can interpret url and get +real host/port to be used to make CONNECT request to proxy

+
+ +
+ +
+
+

m2 Module

+
+
+

m2crypto Module

+
+
+class M2Crypto.m2crypto.stack_st_OPENSSL_BLOCK
+

Bases: SwigPyObject

+

::stack_st_OPENSSL_BLOCK

+
+
+stack
+

stack_st_OPENSSL_BLOCK.stack

+
+ +
+
+this
+
+ +
+
+thisown
+
+ +
+ +
+
+class M2Crypto.m2crypto.stack_st_OPENSSL_STRING
+

Bases: SwigPyObject

+

::stack_st_OPENSSL_STRING

+
+
+stack
+

stack_st_OPENSSL_STRING.stack

+
+ +
+
+this
+
+ +
+
+thisown
+
+ +
+ +
+
+

m2urllib Module

+
+
+M2Crypto.m2urllib.open_https(self, url, data=None, ssl_context=None)[source]
+

Open URL over the SSL connection.

+ +++ + + + + + +
Parameters:
    +
  • url – URL to be opened
  • +
  • data – data for the POST request
  • +
  • ssl_context – SSL.Context to be used
  • +
+
Returns:

+
+
+ +
+
+

m2urllib2 Module

+
+
+class M2Crypto.m2urllib2.HTTPSHandler(ssl_context=None)[source]
+

Bases: urllib2.AbstractHTTPHandler

+
+
+https_open(req)[source]
+

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
  • +
+
+
+ +
+
+https_request(request)
+
+ +
+ +
+
+M2Crypto.m2urllib2.build_opener(ssl_context=None, *handlers)[source]
+

Create an opener object from a list of handlers.

+

The opener will use several default handlers, including support +for HTTP and FTP.

+

If any of the handlers passed as arguments are subclasses of the +default handlers, the default handlers will not be used.

+
+ +
+
+

m2xmlrpclib Module

+
+
+class M2Crypto.m2xmlrpclib.SSL_Transport(ssl_context=None, *args, **kw)[source]
+

Bases: xmlrpclib.Transport

+
+
+request(host, handler, request_body, verbose=0)[source]
+
+ +
+
+user_agent = 'M2Crypto_XMLRPC/0.26.0 - xmlrpclib.py/1.0.1 (by www.pythonware.com)'
+
+ +
+ +
+
+

threading Module

+
+
+M2Crypto.threading.cleanup()[source]
+

End and cleanup threading support.

+
+ +
+
+M2Crypto.threading.init()[source]
+

Initialize threading support.

+
+ +
+
+

util Module

+
+
+exception M2Crypto.util.UtilError[source]
+

Bases: exceptions.Exception

+
+ +
+
+M2Crypto.util.bin_to_hex(b)[source]
+
+ +
+
+M2Crypto.util.genparam_callback(p, n, out=<open file '<stdout>', mode 'w' at 0x7fc7ebc63150>)[source]
+
+ +
+
+M2Crypto.util.no_passphrase_callback(*args)[source]
+
+ +
+
+M2Crypto.util.octx_to_num(x)[source]
+
+ +
+
+M2Crypto.util.passphrase_callback(v, prompt1='Enter passphrase:', prompt2='Verify passphrase:')[source]
+
+ +
+
+M2Crypto.util.pkcs5_pad(data, blklen=8)[source]
+
+ +
+
+M2Crypto.util.pkcs7_pad(data, blklen)[source]
+
+ +
+
+M2Crypto.util.py3bytes(x)[source]
+
+ +
+
+M2Crypto.util.py3str(x)[source]
+
+ +
+
+M2Crypto.util.quiet_genparam_callback(p, n, out)[source]
+
+ +
+ +
+ + +
+
+
+ +
+
+ + + + \ 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..dc1dc32 --- /dev/null +++ b/doc/html/ZServerSSL-HOWTO.html @@ -0,0 +1,359 @@ + + + + + + + + + + 1.   ZServerSSL-HOWTO — M2Crypto documentation + + + + + + + + + + + + + +
+
+
+
+ +
+

1.   ZServerSSL-HOWTO

+ +++ + + + + + + + +
author:Pheng Siong Ng <ngps@post1.com>
copyright:© 2000, 2001 by Ng Pheng Siong.
date:2003-06-22
+ +
+

1.1.   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.

+
+
+

1.2.   Preparation

+
    +
  1. Download M2Crypto 0.11, contained in the file m2crypto-0.11.zip.
  2. +
  3. Unpack m2crypto-0.11.zip. This will create a directory +m2crypto-0.11. Henceforth, we refer to this directory as $M2.
  4. +
  5. Install M2Crypto per the instructions in $M2/INSTALL.
  6. +
+

The ZServerSSL distribution is in $M2/demo/Zope. We shall refer to +this directory as $ZSSL.

+
+
+

1.3.   Installation

+

Below, we refer to your Zope top-level directory as $ZOPE.

+
    +
  1. Copy $ZSSL/z2s.py into $ZOPE.

    +
  2. +
  3. 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.

    +
  4. +
  5. Copy $ZSSL/dh1024.pem into $ZOPE. This file contains +Diffie-Hellman parameters for use by the SSL protocol.

    +
  6. +
  7. 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
    +
    +
  8. +
  9. Copy $ZSSL/ca.pem to $ZOPE. This file contains an +example Certification Authority (CA) certificate. For +information on operating your own CA, see HOWTO: Creating your own CA with OpenSSL or +one of numerous similar documents available on the web.

    +
  10. +
  11. 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.

    +
  12. +
  13. Copy $ZSSL/ZServer/HTTPS_Server.py to $ZOPE/ZServer.

    +
  14. +
  15. 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
    +
    +
  16. +
  17. Copy $ZSSL/ZServer/medusa/https_server.py to +$ZOPE/ZServer/medusa.

    +
  18. +
  19. Stop Zope, if it is running.

    +
  20. +
  21. 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
    • +
    +
  22. +
+
+
+

1.4.   Testing

+

Below, we assume your Zope server is running on localhost.

+
+
+

1.5.   HTTPS

+

This testing is done with Mozilla 1.1 on FreeBSD.

+
    +
  1. With a browser, connect to https://localhost:9443/. Browse around. +Check out your browser’s HTTPS informational screens.
  2. +
  3. Connect to https://localhost:9443/manage. Verify that you can access +Zope’s management functionality.
  4. +
+
+
+

1.6.   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.
+$
+
+
+
+

1.7.   WebDAV-Source-over-HTTPS

+

This testing is done with Mozilla 1.1 on FreeBSD.

+
    +
  1. Open the Mozilla Composer window.
  2. +
  3. Click “File”, “Open Web Location”. A dialog box appears.
  4. +
  5. Enter https://localhost:9444/index_html for the URL.
  6. +
  7. Select “Open in new Composer window.”
  8. +
  9. Click “Open”. A new Composer window will open with index_html +loaded.
  10. +
+
+
+

1.8.   Python with M2Crypto

+

This testing is done with M2Crypto 0.11 and Python 2.2.2 on FreeBSD.

+
+
+

1.9.   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()
+>>>
+
+
+
+
+

1.10.   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'}]
+>>>
+
+
+
+
+

1.11.   Conclusion

+

Well, it works! ;-)

+
+
+ + +
+
+
+ +
+
+ + + + \ 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..c290e6a --- /dev/null +++ b/doc/html/_modules/M2Crypto/ASN1.html @@ -0,0 +1,347 @@ + + + + + + + + + + M2Crypto.ASN1 — M2Crypto documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for M2Crypto.ASN1

+from __future__ import absolute_import
+
+"""
+M2Crypto wrapper for OpenSSL ASN1 API.
+
+Copyright (c) 1999-2004 Ng Pheng Siong. All rights reserved.
+
+Portions created by Open Source Applications Foundation (OSAF) are
+Copyright (C) 2005 OSAF. All Rights Reserved.
+"""
+
+import datetime
+import time
+
+from M2Crypto import BIO, m2, util
+if util.py27plus:
+    from typing import Any, Callable, Optional, Tuple  # noqa
+
+MBSTRING_FLAG = 0x1000
+MBSTRING_ASC = MBSTRING_FLAG | 1
+MBSTRING_BMP = MBSTRING_FLAG | 2
+
+
+
[docs]class ASN1_Integer: # noqa + + 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 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) + +
+
[docs]class ASN1_String: # noqa + + 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 __bytes__(self): + # type: () -> bytes + buf = BIO.MemoryBuffer() + m2.asn1_string_print(buf.bio_ptr(), self.asn1str) + return buf.read_all() + + def __str__(self): + # type: () -> str + return util.py3str(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 + +
[docs] 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 util.py3str(buf.read_all()) + +
+
[docs]class ASN1_Object: # noqa + + 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() # type: _UTC + + +
[docs]class LocalTimezone(datetime.tzinfo): + """ Localtimezone from datetime manual """ + def __init__(self): + # type: () -> None + self._stdoffset = datetime.timedelta(seconds=-time.timezone) + if time.daylight: + self._dstoffset = datetime.timedelta(seconds=-time.altzone) + else: + self._dstoffset = self._stdoffset + self._dstdiff = self._dstoffset - self._stdoffset + +
[docs] def utcoffset(self, dt): + # type: (datetime.datetime) -> datetime.timedelta + if self._isdst(dt): + return self._dstoffset + else: + return self._stdoffset +
+
[docs] def dst(self, dt): + # type: (datetime.datetime) -> datetime.timedelta + if self._isdst(dt): + return self._dstdiff + else: + return datetime.timedelta(0) +
+
[docs] def tzname(self, 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) + stamp = time.mktime(tt) + tt = time.localtime(stamp) + return tt.tm_isdst > 0 + +
+
[docs]class ASN1_TIME: # noqa + _ssl_months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", + "Sep", "Oct", "Nov", "Dec"] + m2_asn1_time_free = m2.asn1_time_free + + def __init__(self, asn1_time=None, _pyfree=0, asn1_utctime=None): + # type: (Optional[ASN1_TIME], int) -> 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_time = m2.asn1_time_new() + self._pyfree = 1 + + def __del__(self): + # type: () -> None + if getattr(self, '_pyfree', 0): + self.m2_asn1_time_free(self.asn1_time) + + def __str__(self): + # type: () -> str + assert m2.asn1_time_type_check(self.asn1_time), \ + "'asn1_time' type error'" + buf = BIO.MemoryBuffer() + m2.asn1_time_print(buf.bio_ptr(), self.asn1_time) + return util.py3str(buf.read_all()) + + def _ptr(self): + assert m2.asn1_time_type_check(self.asn1_time), \ + "'asn1_time' type error'" + return self.asn1_time + +
[docs] 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) +
+
[docs] 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) +
+
[docs] def get_datetime(self): + # type: () -> ASN1_TIME + date = str(self) + + timezone = None + if ' ' not in date: + 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, month)) + if rest.endswith(' GMT'): + timezone = UTC + rest = rest[:-4] + 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 +
+
[docs] 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 +
+ +
+
+
+
+
+ + +
+
+
+
+ + + + \ 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..a35c736 --- /dev/null +++ b/doc/html/_modules/M2Crypto/AuthCookie.html @@ -0,0 +1,263 @@ + + + + + + + + + + M2Crypto.AuthCookie — M2Crypto documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for M2Crypto.AuthCookie

+from __future__ import absolute_import
+
+"""Secure Authenticator Cookies
+
+Copyright (c) 1999-2002 Ng Pheng Siong. All rights reserved."""
+
+import logging
+import re
+import time
+
+from M2Crypto import Rand, m2, util, six
+from M2Crypto.six.moves.http_cookies import SimpleCookie  # pylint: disable=no-name-in-module,import-error
+
+if util.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__)
+
+
+
[docs]def mix(expiry, data, format=_MIX_FORMAT): + # type: (float, AnyStr, str) -> AnyStr + return format % (expiry, data) + +
+
[docs]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 + +
+
[docs]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) + else: + return None + +
+_TOKEN = '_M2AUTH_' # type: str + + +
[docs]class AuthCookieJar: + + _keylen = 20 # type: int + + def __init__(self): + # type: () -> None + self._key = Rand.rand_bytes(self._keylen) + + def _hmac(self, key, data): + # type: (bytes, str) -> str + return util.bin_to_hex(m2.hmac(key, util.py3bytes(data), m2.sha1())) + +
[docs] 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)) +
+
[docs] def isGoodCookie(self, cookie): + # type: (AuthCookie) -> Union[bool, int] + assert isinstance(cookie, AuthCookie) + if cookie.isExpired(): + return 0 + c = self.makeCookie(cookie._expiry, cookie._data) + return (c._expiry == cookie._expiry) \ + and (c._data == cookie._data) \ + and (c._mac == cookie._mac) \ + and (c.output() == cookie.output()) +
+
[docs] def isGoodCookieString(self, cookie_str, _debug=False): + # type: (Union[dict, bytes], bool) -> Union[bool, int] + c = SimpleCookie() + c.load(cookie_str) + if _TOKEN not in c: + log.error('_TOKEN not in c (keys = %s)', dir(c)) + return 0 + undough = unmix3(c[_TOKEN].value) + if undough is None: + log.error('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) + +
+
[docs]class AuthCookie: + + 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 = SimpleCookie() + self._cookie[_TOKEN] = '%s%s' % (dough, mac) + self._name = '%s%s' % (dough, mac) # WebKit only. + +
[docs] def expiry(self): + # type: () -> float + """Return the cookie's expiry time.""" + return self._expiry +
+
[docs] def data(self): + # type: () -> str + """Return the data portion of the cookie.""" + return self._data +
+
[docs] def mac(self): + # type: () -> str + """Return the cookie's MAC.""" + return self._mac +
+
[docs] def output(self): + # type: () -> str + """Return the cookie's output in "Set-Cookie" format.""" + return self._cookie.output() +
+
[docs] def value(self): + # type: () -> str + """Return the cookie's output minus the "Set-Cookie: " portion. + """ + return self._cookie[_TOKEN].value +
+
[docs] def isExpired(self): + # type: () -> bool + """Return 1 if the cookie has expired, 0 otherwise.""" + return isinstance(self._expiry, (float, six.integer_types)) and \ + (time.time() > self._expiry) + + # 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.
+
[docs] def name(self): + # type: () -> str + return self._name +
+
[docs] def headerValue(self): + # type: () -> str + return self.value()
+
+ +
+
+
+
+
+ + +
+
+
+
+ + + + \ 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..753291c --- /dev/null +++ b/doc/html/_modules/M2Crypto/BIO.html @@ -0,0 +1,472 @@ + + + + + + + + + + M2Crypto.BIO — M2Crypto documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for M2Crypto.BIO

+from __future__ import absolute_import
+
+"""M2Crypto wrapper for OpenSSL BIO API.
+
+Copyright (c) 1999-2004 Ng Pheng Siong. All rights reserved."""
+
+import logging
+import io  # noqa
+
+from M2Crypto import m2, six, util
+if util.py27plus:
+    from typing import AnyStr, Callable, Iterable, Optional, Union  # noqa
+
+log = logging.getLogger('BIO')
+
+
+
[docs]class BIOError(Exception): + pass +
+m2.bio_init(BIOError) + + +
[docs]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) + + def _ptr(self): + return self.bio + + # Deprecated. + bio_ptr = _ptr + +
[docs] def fileno(self): + # type: () -> int + return m2.bio_get_fd(self.bio) +
+
[docs] def readable(self): + # type: () -> bool + return not self.closed +
+
[docs] def read(self, size=None): + # type: (int) -> Union[bytes, bytearray] + if not self.readable(): + raise IOError('cannot read') + if size is None: + buf = bytearray() + while 1: + data = m2.bio_read(self.bio, 4096) + if not data: + break + buf += data + return buf + elif size == 0: + return b'' + elif size < 0: + raise ValueError('read count is negative') + else: + return bytes(m2.bio_read(self.bio, size)) +
+
[docs] def readline(self, size=4096): + # type: (int) -> bytes + if not self.readable(): + raise IOError('cannot read') + buf = m2.bio_gets(self.bio, size) + return buf +
+
[docs] def readlines(self, sizehint='ignored'): + # type: (Union[AnyStr, int]) -> Iterable[bytes] + if not self.readable(): + raise IOError('cannot read') + lines = [] + while 1: + buf = m2.bio_gets(self.bio, 4096) + if buf is None: + break + lines.append(buf) + return lines +
+
[docs] def writeable(self): + # type: () -> bool + return (not self.closed) and (not self.write_closed) +
+
[docs] def write(self, data): + # type: (AnyStr) -> int + """ + + :return: either data written, or [0, -1] for nothing written, + -2 not implemented + """ + if not self.writeable(): + raise IOError('cannot write') + if isinstance(data, six.text_type): + data = data.encode('utf8') + return m2.bio_write(self.bio, data) +
+
[docs] def write_close(self): + # type: () -> None + self.write_closed = 1 +
+
[docs] def flush(self): + # type: () -> None + """ + + :return: 1 for success, and 0 or -1 for failure + """ + m2.bio_flush(self.bio) +
+
[docs] def reset(self): + # type: () -> int + """ + Sets the bio to its initial state + :return: 1 for success, and 0 or -1 for failure + """ + return m2.bio_reset(self.bio) +
+
[docs] def close(self): + # type: () -> None + self.closed = 1 + if self._close_cb: + self._close_cb() +
+
[docs] def should_retry(self): + # type: () -> int + """ + Can the call be attempted again, or was there an error + ie do_handshake + + """ + return m2.bio_should_retry(self.bio) +
+
[docs] def should_read(self): + # type: () -> int + """ + Returns whether the cause of the condition is the bio + should read more data + """ + return m2.bio_should_read(self.bio) +
+
[docs] def should_write(self): + # type: () -> int + """ + Returns whether the cause of the condition is the bio + should write more data + """ + return m2.bio_should_write(self.bio) +
+
[docs] def tell(self): + """ + Return the current offset. + """ + return m2.bio_tell(self.bio) +
+
[docs] 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): + self.close() + +
+
[docs]class MemoryBuffer(BIO): + """ + 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. + """ + + def __init__(self, data=None): + # type: (Optional[bytes]) -> None + if data is not None and not isinstance(data, bytes): + raise TypeError( + "data must be bytes or None, not %s" % (type(data).__name__, )) + BIO.__init__(self) + 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) + +
[docs] def read(self, size=0): + # type: (int) -> bytes + if not self.readable(): + 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 + +
[docs] def write_close(self): + # type: () -> None + self.write_closed = 1 + m2.bio_set_mem_eof_return(self.bio, 0) +
+ close = write_close + +
+
[docs]class File(BIO): + + """ + Object interface to BIO_s_pyfd + + 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): + # type: (io.BytesIO, int) -> None + BIO.__init__(self, _pyfree=1) + self.pyfile = pyfile + self.close_pyfile = close_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) + +
[docs] def close(self): + # type: () -> None + self.closed = 1 + if self.close_pyfile: + self.pyfile.close() +
+
[docs] def reset(self): + # type: () -> int + """ + Sets the bio to its initial state + :return: 0 for success, and -1 for failure + """ + return super(File, self).reset() + +
+
[docs]def openfile(filename, mode='rb'): + # type: (AnyStr, AnyStr) -> File + return File(open(filename, mode)) + +
+
[docs]class IOBuffer(BIO): + + """ + 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. + """ + + m2_bio_pop = m2.bio_pop + m2_bio_free = m2.bio_free + + def __init__(self, under_bio, mode='rwb', _pyfree=1): + # type: (BIO, str, int) -> None + BIO.__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 + 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) + +
[docs] def close(self): + # type: () -> None + BIO.close(self) + +
+
[docs]class CipherStream(BIO): + + """ + Object interface to BIO_f_cipher. + """ + + SALT_LEN = m2.PKCS5_SALT_LEN + + m2_bio_pop = m2.bio_pop + m2_bio_free = m2.bio_free + + def __init__(self, obio): + # type: (BIO) -> None + BIO.__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() + +
[docs] def close(self): + # type: () -> None + self.m2_bio_pop(self.bio) + self.m2_bio_free(self.bio) + self.closed = 1 +
+
[docs] def write_close(self): + # type: () -> None + self.obio.write_close() +
+
[docs] 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) + 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()) + +
+
[docs]class SSLBio(BIO): + """ + Object interface to BIO_f_ssl + """ + def __init__(self, _pyfree=1): + # type: (int) -> None + BIO.__init__(self, _pyfree=_pyfree) + self.bio = m2.bio_new(m2.bio_f_ssl()) + self.closed = 0 + +
[docs] 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. + """ + 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) +
+
[docs] def do_handshake(self): + # 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)
+
+ +
+
+
+
+
+ + +
+
+
+
+ + + + \ 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..139fb19 --- /dev/null +++ b/doc/html/_modules/M2Crypto/BN.html @@ -0,0 +1,152 @@ + + + + + + + + + + M2Crypto.BN — M2Crypto documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for M2Crypto.BN

+from __future__ import absolute_import
+
+"""
+M2Crypto wrapper for OpenSSL BN (BIGNUM) API.
+
+Copyright (c) 2005 Open Source Applications Foundation. All rights reserved.
+"""
+
+from M2Crypto import m2, util
+if util.py27plus:
+    from typing import Optional  # noqa
+
+
+
[docs]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 + 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. + """ + return m2.bn_rand(bits, top, bottom) + +
+
[docs]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) + """ + return m2.bn_rand_range(range) + +
+
[docs]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. + :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 = [] # type: list + for x in range(length): + fname += [letters[m2.bn_rand_range(lettersLen)]] + + return ''.join(fname)
+
+ +
+
+
+
+
+ + +
+
+
+
+ + + + \ 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..20e4120 --- /dev/null +++ b/doc/html/_modules/M2Crypto/DH.html @@ -0,0 +1,209 @@ + + + + + + + + + + M2Crypto.DH — M2Crypto documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for M2Crypto.DH

+from __future__ import absolute_import
+
+"""M2Crypto wrapper for OpenSSL DH API.
+
+Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
+
+from M2Crypto import BIO, m2, util
+from M2Crypto.util import genparam_callback
+if util.py27plus:
+    from typing import AnyStr, Callable  # noqa
+
+
+
[docs]class DHError(Exception): + pass +
+m2.dh_init(DHError) + + +
[docs]class DH: + + """ + 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) + + 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" + return method(self.dh) + else: + 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()') + else: + self.__dict__[name] = value + + def _ptr(self): + return self.dh + +
[docs] def check_params(self): + # type: () -> int + assert m2.dh_type_check(self.dh), "'dh' type error" + return m2.dh_check(self.dh) +
+
[docs] def gen_key(self): + # type: () -> None + assert m2.dh_type_check(self.dh), "'dh' type error" + m2.dh_generate_key(self.dh) +
+
[docs] 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) +
+
[docs] 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) + +
+
[docs]def gen_params(plen, g, callback=genparam_callback): + # type: (int, int, Optional[Callable]) -> DH + dh_parms = m2.dh_generate_parameters(plen, g, callback) + dh_obj = DH(dh_parms, 1) + return dh_obj + +
+
[docs]def load_params(file): + # type: (AnyStr) -> DH + with BIO.openfile(file) as bio: + return load_params_bio(bio) +
+
[docs]def load_params_bio(bio): + # type: (BIO.BIO) -> DH + return DH(m2.dh_read_parameters(bio._ptr()), 1) + +
+
[docs]def set_params(p, g): + # type: (bytes, bytes) -> DH + dh = m2.dh_new() + m2.dh_set_pg(dh, p, g) + return DH(dh, 1) + + +# def free_params(cptr): +# m2.dh_free(cptr) + +
+DH_GENERATOR_2 = m2.DH_GENERATOR_2 +DH_GENERATOR_5 = m2.DH_GENERATOR_5 +
+ +
+
+
+
+
+ + +
+
+
+
+ + + + \ 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..680b32e --- /dev/null +++ b/doc/html/_modules/M2Crypto/DSA.html @@ -0,0 +1,550 @@ + + + + + + + + + + M2Crypto.DSA — M2Crypto documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for M2Crypto.DSA

+from __future__ import absolute_import, print_function
+
+"""
+    M2Crypto wrapper for OpenSSL DSA API.
+
+    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 BIO, m2, util
+if util.py27plus:
+    from typing import AnyStr, Callable, Tuple  # noqa
+
+
+
[docs]class DSAError(Exception): + pass +
+m2.dsa_init(DSAError) + + +
[docs]class DSA: + + """ + 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) + 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 **') + else: + 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. + + :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. + + :param name: name of variable to be returned. Must be + one of 'p', 'q', 'g', 'pub', 'priv'. + :return: value of specified variable (a "byte string") + """ + if name in ['p', 'q', 'g', 'pub', 'priv']: + method = getattr(m2, 'dsa_get_%s' % (name,)) + assert m2.dsa_type_check(self.dsa), "'dsa' type error" + return method(self.dsa) + else: + 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']: + raise DSAError('generate (pub, priv) via gen_key()') + else: + self.__dict__[name] = value + +
[docs] 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_pqg(self.dsa, p, q, g) +
+
[docs] 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) +
+
[docs] def save_params(self, filename): + # type: (AnyStr) -> int + """ + Save the DSA parameters to a file. + + :param filename: Save the DSA parameters to this file. + :return: 1 (true) if successful + """ + with BIO.openfile(filename, 'wb') as bio: + ret = m2.dsa_write_params_bio(self.dsa, bio._ptr()) + + return ret +
+
[docs] def save_params_bio(self, bio): + # type: (BIO.BIO) -> int + """ + Save DSA parameters to a BIO object. + + :param bio: Save DSA parameters to this object. + :return: 1 (true) if successful + """ + return m2.dsa_write_params_bio(self.dsa, bio._ptr()) +
+
[docs] 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. + + :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 + """ + with BIO.openfile(filename, 'wb') as bio: + ret = self.save_key_bio(bio, cipher, callback) + + return ret +
+
[docs] 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. + + :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 + """ + if cipher is None: + return m2.dsa_write_key_bio_no_cipher(self.dsa, + bio._ptr(), callback) + else: + ciph = getattr(m2, cipher, None) + if ciph is None: + raise DSAError('no such cipher: %s' % cipher) + else: + ciph = ciph() + return m2.dsa_write_key_bio(self.dsa, bio._ptr(), ciph, callback) +
+
[docs] def save_pub_key(self, filename): + # type: (AnyStr) -> int + """ + Save the DSA public key (with parameters) to a file. + + :param filename: Save DSA public key (with parameters) + to this file. + :return: 1 (true) if successful + """ + with BIO.openfile(filename, 'wb') as bio: + ret = self.save_pub_key_bio(bio) + + return ret +
+
[docs] def save_pub_key_bio(self, bio): + # type: (BIO.BIO) -> int + """ + Save DSA public key (with parameters) to a BIO object. + + :param bio: Save DSA public key (with parameters) + to this object. + :return: 1 (true) if successful + """ + return m2.dsa_write_pub_key_bio(self.dsa, bio._ptr()) +
+
[docs] def sign(self, digest): + # type: (bytes) -> Tuple[bytes, bytes] + """ + Sign the digest. + + :param digest: SHA-1 hash of message (same as output + from MessageDigest, a "byte string") + :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) +
+
[docs] def verify(self, digest, r, s): + # type: (bytes, bytes, bytes) -> int + """ + Verify a newly calculated digest against the signature + values r and s. + + :param digest: SHA-1 hash of message (same as output + from MessageDigest, a "byte string") + :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) +
+
[docs] def sign_asn1(self, digest): + assert self.check_key(), 'key is not initialised' + return m2.dsa_sign_asn1(self.dsa, digest) +
+
[docs] def verify_asn1(self, digest, blob): + assert self.check_key(), 'key is not initialised' + return m2.dsa_verify_asn1(self.dsa, digest, blob) +
+
[docs] def check_key(self): + """ + Check to be sure the DSA object has 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) + +
+
[docs]class DSA_pub(DSA): # noqa + + """ + This class is a DSA context that only supports a public key + and verification. It does NOT support a private key or + signing. + + """ + +
[docs] def sign(self, *argv): + # type: (Any) -> None + raise DSAError('DSA_pub object has no private key') +
+ sign_asn1 = sign + +
[docs] 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 + +
+
[docs]def gen_params(bits, callback=util.genparam_callback): + # type: (int, Callable) -> DSA + """ + Factory function that generates DSA parameters and + instantiates a DSA object from the output. + + :param bits: The length of the prime to be generated. If + 'bits' < 512, it is set to 512. + :param callback: A Python callback object that will be + invoked during parameter generation; it usual + purpose is to provide visual feedback. + :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) + +
+
[docs]def set_params(p, q, g): + # type: (bytes, bytes, bytes) -> DSA + """ + Factory function that instantiates a DSA object with DSA + parameters. + + :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_pqg(dsa, p, q, g) + return DSA(dsa, 1) + +
+
[docs]def load_params(file, callback=util.passphrase_callback): + # type: (AnyStr, Callable) -> DSA + """ + Factory function that instantiates a DSA object with DSA + parameters from a file. + + :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. + :return: instance of DSA. + """ + with BIO.openfile(file) as bio: + ret = load_params_bio(bio, callback) + + return ret + +
+
[docs]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. + + :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. + :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) + +
+
[docs]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. + + :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. + :return: instance of DSA. + """ + with BIO.openfile(file) as bio: + ret = load_key_bio(bio, callback) + + return ret + +
+
[docs]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. + + :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. + :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) + +
+
[docs]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) + +
+
[docs]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 + must contain the parameters in addition to the public key. + + :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. + :return: instance of DSA_pub. + """ + with BIO.openfile(file) as bio: + ret = load_pub_key_bio(bio, callback) + + return ret + +
+
[docs]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 + must contain the parameters in addition to the public key. + + :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. + :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)
+
+ +
+
+
+
+
+ + +
+
+
+
+ + + + \ 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..65e6690 --- /dev/null +++ b/doc/html/_modules/M2Crypto/EC.html @@ -0,0 +1,553 @@ + + + + + + + + + + M2Crypto.EC — M2Crypto documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for M2Crypto.EC

+from __future__ import absolute_import
+
+"""
+M2Crypto wrapper for OpenSSL ECDH/ECDSA API.
+
+@requires: OpenSSL 0.9.8 or newer
+
+Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved.
+
+Portions copyright (c) 2005-2006 Vrije Universiteit Amsterdam.
+All rights reserved."""
+
+from M2Crypto import BIO, m2, util
+if util.py27plus:
+    from typing import AnyStr, Callable, Dict, Optional, Tuple, Union  # noqa
+
+EC_Key = bytes
+
+
+
[docs]class ECError(Exception): + pass +
+m2.ec_init(ECError) + +# Curve identifier constants +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 +# 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 + + +
[docs]class EC: + + """ + 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) + +
[docs] 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) +
+
[docs] def pub(self): + # type: () -> EC_pub + # Don't let python free + return EC_pub(self.ec, 0) +
+
[docs] 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) +
+
[docs] 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. + """ + assert self._check_key_type(), "'ec' type error" + return m2.ecdsa_verify(self.ec, digest, r, s) +
+
[docs] 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) +
+
[docs] def verify_dsa_asn1(self, digest, blob): + assert self._check_key_type(), "'ec' type error" + return m2.ecdsa_verify_asn1(self.ec, digest, blob) +
+
[docs] 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 + applied. + """ + assert self.check_key(), 'key is not initialised' + return m2.ecdh_compute_key(self.ec, pub_key.ec) +
+
[docs] 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. + + :param bio: M2Crypto.BIO.BIO object to save key to. + + :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 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) + else: + ciph = getattr(m2, cipher, None) + if ciph is None: + raise ValueError('not such cipher %s' % cipher) + return m2.ec_key_write_bio(self.ec, bio._ptr(), ciph(), callback) +
+
[docs] 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. + + :param file: Name of filename to save key to. + + :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 callback: A Python callable object that is invoked + to acquire a passphrase with which to protect + the key. The default is + util.passphrase_callback. + """ + with BIO.openfile(file, 'wb') as bio: + return self.save_key_bio(bio, cipher, callback) +
+
[docs] def save_pub_key_bio(self, bio): + # type: (BIO.BIO) -> int + """ + Save the public key to an M2Crypto.BIO.BIO object in PEM format. + + :param bio: M2Crypto.BIO.BIO object to save key to. + """ + return m2.ec_key_write_pubkey(self.ec, bio._ptr()) +
+
[docs] def save_pub_key(self, file): + # type: (AnyStr) -> int + """ + Save the public key to a filename in PEM format. + + :param file: Name of filename to save key to. + """ + with BIO.openfile(file, 'wb') as bio: + return m2.ec_key_write_pubkey(self.ec, bio._ptr()) +
+
[docs] 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) + +
[docs] 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) + +
+
[docs]class EC_pub(EC): # noqa + + """ + Object interface to an EC public key. + ((don't like this implementation inheritance)) + """ + def __init__(self, ec, _pyfree=0): + # type: (EC, int) -> None + EC.__init__(self, ec, _pyfree) + self.der = None # type: Optional[bytes] + +
[docs] def get_der(self): + # type: () -> bytes + """ + Returns the public key in DER format as a buffer object. + """ + assert self.check_key(), 'key is not initialised' + if self.der is None: + self.der = m2.ec_key_get_public_der(self.ec) + return self.der +
+
[docs] 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 + +
+
[docs]def gen_params(curve): + # type: (int) -> EC + """ + 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. + """ + 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) + +
+
[docs]def load_key(file, callback=util.passphrase_callback): + # type: (AnyStr, Callable) -> EC + """ + Factory function that instantiates a EC object. + + :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. + """ + with BIO.openfile(file) as bio: + return load_key_bio(bio, callback) + +
+
[docs]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) + +
+
[docs]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 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) + +
+
[docs]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) + +
+
[docs]def load_key_string_pubkey(string, callback=util.passphrase_callback): + # type: (str, Callable) -> PKey + """ + Load an M2Crypto.EC.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.EC.PKey object. + """ + with BIO.MemoryBuffer(string) as bio: + return load_key_bio_pubkey(bio, callback) + +
+
[docs]def load_pub_key_bio(bio): + # type: (BIO.BIO) -> EC_pub + """ + Load an EC public key from an M2Crypto.BIO.BIO object. + + :param bio: M2Crypto.BIO.BIO object containing EC public key in PEM + format. + + :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) + +
+
[docs]def ec_error(): + # type: () -> ECError + raise ECError(m2.err_reason_error_string(m2.err_get_error())) + +
+
[docs]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) + +
+
[docs]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) + +
+
[docs]def get_builtin_curves(): + # type: () -> Tuple[Dict[str, Union[int, str]]] + return m2.ec_get_builtin_curves()
+
+ +
+
+
+
+
+ + +
+
+
+
+ + + + \ 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..4c7d6e0 --- /dev/null +++ b/doc/html/_modules/M2Crypto/EVP.html @@ -0,0 +1,569 @@ + + + + + + + + + + M2Crypto.EVP — M2Crypto documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for M2Crypto.EVP

+from __future__ import absolute_import
+
+"""M2Crypto wrapper for OpenSSL EVP API.
+
+Copyright (c) 1999-2004 Ng Pheng Siong. All rights reserved.
+
+Portions Copyright (c) 2004-2007 Open Source Applications Foundation.
+Author: Heikki Toivonen
+"""
+
+from M2Crypto import BIO, Err, RSA, m2, util
+if util.py27plus:
+    from typing import AnyStr, Optional, Callable  # noqa
+
+
+
[docs]class EVPError(Exception): + pass +
+m2.evp_init(EVPError) + + +
[docs]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. + :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) + +
+
[docs]class MessageDigest: + """ + Message Digest + """ + m2_md_ctx_free = m2.md_ctx_free + + def __init__(self, algo): + # type: (str) -> None + md = getattr(m2, algo, None) # type: Optional[Callable] + if md is None: + # 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) + if self.md is None: + raise ValueError('unknown algorithm', 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) + +
[docs] 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 m2.digest_update(self.ctx, data) +
+
[docs] def final(self): + return m2.digest_final(self.ctx) + + # Deprecated.
+ digest = final + +
+
[docs]class HMAC: + + 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() + 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) + +
[docs] def reset(self, key): + # type: (bytes) -> None + m2.hmac_init(self.ctx, key, self.md) +
+
[docs] def update(self, data): + # type: (bytes) -> None + m2.hmac_update(self.ctx, data) +
+
[docs] def final(self): + # type: () -> bytes + return m2.hmac_final(self.ctx) +
+ digest = final + +
+
[docs]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) + return m2.hmac(key, data, md()) + +
+
[docs]class Cipher: + + 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): + # 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() + if key_as_bytes: + kmd = getattr(m2, d, None) + if kmd is None: + raise ValueError('unknown message digest', d) + key = m2.bytes_to_key(self.cipher, kmd(), key, salt, iv, i) + 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): + # type: () -> None + if getattr(self, 'ctx', None): + self.m2_cipher_ctx_free(self.ctx) + +
[docs] def update(self, data): + # type: (bytes) -> bytes + return m2.cipher_update(self.ctx, data) +
+
[docs] def final(self): + # type: () -> bytes + return m2.cipher_final(self.ctx) +
+
[docs] def set_padding(self, padding=1): + # type: (int) -> int + """ + Actually always return 1 + """ + return m2.cipher_set_padding(self.ctx, padding) + +
+
[docs]class PKey: + """ + 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 # 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): + self.m2_md_ctx_free(self.ctx) + + def _ptr(self): + return self.pkey + + def _set_context(self, md): + # type: (str) -> None + mda = getattr(m2, md, None) # type: Optional[Callable] + if mda is None: + raise ValueError('unknown message digest', md) + self.md = mda() + self.ctx = m2.md_ctx_new() # type: Context + +
[docs] def reset_context(self, md='sha1'): + # type: (str) -> None + """ + Reset internal message digest context. + + :param md: The message digest algorithm. + """ + self._set_context(md) +
+
[docs] def sign_init(self): + # type: () -> None + """ + Initialise signing operation with self. + """ + m2.sign_init(self.ctx, self.md) +
+
[docs] def sign_update(self, data): + # type: (bytes) -> None + """ + Feed data to signing operation. + + :param data: Data to be signed. + """ + m2.sign_update(self.ctx, data) +
+
[docs] def sign_final(self): + # type: () -> bytes + """ + Return signature. + + :return: The signature. + """ + return m2.sign_final(self.ctx, self.pkey) + + # Deprecated
+ update = sign_update + final = sign_final + +
[docs] def verify_init(self): + # type: () -> None + """ + Initialise signature verification operation with self. + """ + m2.verify_init(self.ctx, self.md) +
+
[docs] def verify_update(self, data): + # type: (bytes) -> int + """ + Feed data to verification operation. + + :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) +
+
[docs] def verify_final(self, sign): + # type: (bytes) -> int + """ + Return result of verification. + + :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) +
+
[docs] def assign_rsa(self, rsa, capture=1): + # type: (RSA.RSA, int) -> int + """ + Assign the RSA key pair to self. + + :param rsa: M2Crypto.RSA.RSA object to be assigned to self. + + :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. + + :return: Return 1 for success and 0 for failure. + """ + if capture: + ret = m2.pkey_assign_rsa(self.pkey, rsa.rsa) + if ret: + rsa._pyfree = 0 + else: + ret = m2.pkey_set1_rsa(self.pkey, rsa.rsa) + return ret +
+
[docs] 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 +
+
[docs] 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. + + :param file: Name of file to save key to. + + :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 callback: A Python callable object that is invoked + to acquire a passphrase with which to protect + the key. The default is + util.passphrase_callback. + """ + with BIO.openfile(file, 'wb') as bio: + return self.save_key_bio(bio, cipher, callback) +
+
[docs] 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. + + :param bio: M2Crypto.BIO object to save key to. + + :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 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) + return m2.pkey_write_pem(self.pkey, bio._ptr(), proto(), callback) +
+
[docs] 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. + + :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 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() +
+
[docs] 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() +
+
[docs] def size(self): + # type: () -> int + """ + Return the size of the key in bytes. + """ + return m2.pkey_size(self.pkey) +
+
[docs] def get_modulus(self): + # type: () -> Optional[bytes] + """ + Return the modulus in hex format. + """ + return m2.pkey_get_modulus(self.pkey) + +
+
[docs]def load_key(file, callback=util.passphrase_callback): + # type: (AnyStr, Callable) -> PKey + """ + Load an M2Crypto.EVP.PKey from file. + + :param file: Name of file 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 = 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()) + return PKey(cptr, 1) + +
+
[docs]def load_key_bio(bio, callback=util.passphrase_callback): + # type: (BIO.BIO, Callable) -> PKey + """ + Load an M2Crypto.EVP.PKey from an 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(bio._ptr(), callback) + if cptr is None: + raise EVPError(Err.get_error()) + return PKey(cptr, 1) + +
+
[docs]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) + +
+
[docs]def load_key_string(string, callback=util.passphrase_callback): + # type: (AnyStr, Callable) -> PKey + """ + Load an M2Crypto.EVP.PKey from 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(bio, callback) + +
+
[docs]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)
+
+ +
+
+
+
+
+ + +
+
+
+
+ + + + \ 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..9812dbb --- /dev/null +++ b/doc/html/_modules/M2Crypto/Engine.html @@ -0,0 +1,239 @@ + + + + + + + + + + M2Crypto.Engine — M2Crypto documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for M2Crypto.Engine

+# vim: sts=4 sw=4 et
+"""
+M2Crypto wrapper for OpenSSL ENGINE API.
+
+Pavel Shramov
+IMEC MSU
+"""
+
+from M2Crypto import EVP, Err, X509, m2, six, util
+if util.py27plus:
+    from typing import AnyStr, Callable, Optional  # noqa
+
+
+
[docs]class EngineError(Exception): + pass +
+m2.engine_init_error(EngineError) + + +
[docs]class Engine: + """Wrapper for ENGINE object.""" + + m2_engine_free = m2.engine_free + + 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") + self._ptr = _ptr + if not self._ptr: + self._ptr = m2.engine_by_id(id) + if not self._ptr: + raise ValueError("Unknown engine: %s" % id) + self._pyfree = _pyfree + + def __del__(self): + # type: () -> None + if getattr(self, '_pyfree', 0): + self.m2_engine_free(self._ptr) + +
[docs] def init(self): + # type: () -> int + """Obtain a functional reference to the engine. + + :return: 0 on error, non-zero on success.""" + return m2.engine_init(self._ptr) +
+
[docs] def finish(self): + # type: () -> int + """Release a functional and structural reference to the engine.""" + return m2.engine_finish(self._ptr) +
+
[docs] def ctrl_cmd_string(self, cmd, arg, optional=0): + # type: (bytes, Optional[bytes], int) -> int + """Call ENGINE_ctrl_cmd_string""" + if not m2.engine_ctrl_cmd_string(self._ptr, cmd, arg, optional): + raise EngineError(Err.get_error()) +
+
[docs] def get_name(self): + # type: () -> bytes + """Return engine name""" + return m2.engine_get_name(self._ptr) +
+
[docs] def get_id(self): + # type: () -> bytes + """Return engine id""" + return m2.engine_get_id(self._ptr) +
+
[docs] 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): + # type: (Callable, bytes, Optional[bytes]) -> EVP.PKey + """Helper function for loading keys""" + ui = m2.ui_openssl() + cbd = m2.engine_pkcs11_data_new(pin) + try: + kptr = func(self._ptr, name, ui, cbd) + if not kptr: + raise EngineError(Err.get_error()) + key = EVP.PKey(kptr, _pyfree=1) + finally: + m2.engine_pkcs11_data_free(cbd) + return key + +
[docs] 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) +
+
[docs] 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) +
+
[docs] 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) + +
+
[docs]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(b'SO_PATH', sopath) + e.ctrl_cmd_string(b'ID', id) + e.ctrl_cmd_string(b'LIST_ADD', '1') + e.ctrl_cmd_string(b'LOAD', None) + return e + +
+
[docs]def load_dynamic(): + # type: () -> None + """Load dynamic engine""" + m2.engine_load_dynamic() + +
+
[docs]def load_openssl(): + # type: () -> None + """Load openssl engine""" + m2.engine_load_openssl() + +
+
[docs]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()
+
+ +
+
+
+
+
+ + +
+
+
+
+ + + + \ 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..955ab09 --- /dev/null +++ b/doc/html/_modules/M2Crypto/Err.html @@ -0,0 +1,162 @@ + + + + + + + + + + M2Crypto.Err — M2Crypto documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for M2Crypto.Err

+from __future__ import absolute_import
+
+"""M2Crypto wrapper for OpenSSL Error API.
+
+Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
+
+from M2Crypto import BIO, m2, util, six  # noqa
+if util.py27plus:
+    from typing import Optional  # noqa
+
+
+
[docs]def get_error(): + # type: () -> Optional[str] + err = BIO.MemoryBuffer() + m2.err_print_errors(err.bio_ptr()) + err_msg = err.read() + if err_msg: + return util.py3str(err_msg) + +
+
[docs]def get_error_code(): + # type: () -> int + return m2.err_get_error() + +
+
[docs]def peek_error_code(): + # type: () -> int + return m2.err_peek_error() + +
+
[docs]def get_error_lib(err): + # type: (int) -> str + return util.py3str(m2.err_lib_error_string(err)) + +
+
[docs]def get_error_func(err): + # type: (int) -> str + return util.py3str(m2.err_func_error_string(err)) + +
+
[docs]def get_error_reason(err): + # type: (int) -> str + return util.py3str(m2.err_reason_error_string(err)) + +
+
[docs]def get_x509_verify_error(err): + # type: (int) -> str + return util.py3str(m2.x509_get_verify_error(err)) + +
+
[docs]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): + # 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" % (get_error_func(self.err), s, + get_error_reason(self.err)) + +
+
[docs]class M2CryptoError(Exception): + pass
+
+ +
+
+
+
+
+ + +
+
+
+
+ + + + \ No newline at end of file diff --git a/doc/html/_modules/M2Crypto/PGP/PublicKey.html b/doc/html/_modules/M2Crypto/PGP/PublicKey.html new file mode 100644 index 0000000..8e9593b --- /dev/null +++ b/doc/html/_modules/M2Crypto/PGP/PublicKey.html @@ -0,0 +1,169 @@ + + + + + + + + + + M2Crypto.PGP.PublicKey — M2Crypto documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for M2Crypto.PGP.PublicKey

+from __future__ import absolute_import
+
+"""M2Crypto PGP2.
+
+Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
+
+from M2Crypto.PGP.RSA import new_pub_key
+from M2Crypto.RSA import pkcs1_padding
+from M2Crypto.PGP.packet import PublicKeyPacket  # noqa
+from M2Crypto.PGP.constants import *  # noqa
+from M2Crypto.PGP.packet import *  # noqa
+
+
+
[docs]class PublicKey: + def __init__(self, pubkey_pkt): + # type: (PublicKeyPacket) -> None + 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 = new_pub_key((pubkey_pkt._e, pubkey_pkt._n)) + self._userid = {} # type: dict + self._signature = {} # type: dict + +
[docs] def keyid(self): + # type: () -> bytes + return self._pubkey.n[-8:] +
+
[docs] def add_userid(self, u_pkt): + # type: (Packet.UserIDPacket) -> None + assert isinstance(u_pkt, UserIDPacket) + self._userid[u_pkt.userid()] = u_pkt +
+
[docs] def remove_userid(self, userid): + # type: (int) -> None + del self._userid[userid] +
+
[docs] def add_signature(self, userid, s_pkt): + # type: (int, SignaturePacket) -> None + assert isinstance(s_pkt, SignaturePacket) + assert userid in self._userid + if userid in self._signature: + self._signature.append(s_pkt) + else: + self._signature = [s_pkt] +
+ def __getitem__(self, id): + # type: (int) -> SignaturePacket + return self._userid[id] + + def __setitem__(self, *args): + raise NotImplementedError + + def __delitem__(self, id): + # type: (int) -> None + del self._userid[id] + if self._signature[id]: + del self._signature[id] + +
[docs] def write(self, stream): + # type: (IO[bytes]) -> None + pass +
+
[docs] def encrypt(self, ptxt): + # type: (bytes) -> bytes + # XXX Munge ptxt into pgp format. + return self._pubkey.public_encrypt(ptxt, pkcs1_padding) +
+
[docs] def decrypt(self, ctxt): + # type: (bytes) -> bytes + # XXX Munge ctxt into pgp format. + return self._pubkey.public_encrypt(ctxt, pkcs1_padding)
+
+ +
+
+
+
+
+ + +
+
+
+
+ + + + \ No newline at end of file diff --git a/doc/html/_modules/M2Crypto/PGP/PublicKeyRing.html b/doc/html/_modules/M2Crypto/PGP/PublicKeyRing.html new file mode 100644 index 0000000..6ca29ed --- /dev/null +++ b/doc/html/_modules/M2Crypto/PGP/PublicKeyRing.html @@ -0,0 +1,192 @@ + + + + + + + + + + M2Crypto.PGP.PublicKeyRing — M2Crypto documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for M2Crypto.PGP.PublicKeyRing

+from __future__ import absolute_import
+
+"""M2Crypto PGP2.
+
+Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
+
+from M2Crypto import util
+from M2Crypto.PGP.PublicKey import *  # noqa
+from M2Crypto.PGP.constants import *  # noqa
+from M2Crypto.PGP.packet import *  # noqa
+if util.py27plus:
+    from typing import Any, AnyStr, List, Tuple  # noqa
+
+
+
[docs]class PublicKeyRing: + def __init__(self, keyring): + # type: (object) -> None + import warnings + warnings.warn( + 'Deprecated. No maintainer for PGP. If you use this, ' + + 'please inform M2Crypto maintainer.', + DeprecationWarning) + + self._keyring = keyring + self._userid = {} # type: dict + self._keyid = {} # type: dict + self._spurious = [] # type: list + self._pubkey = [] # type: list + +
[docs] def load(self): + # type: () -> None + curr_pub = None + curr_index = -1 + + ps = PacketStream(self._keyring) + while 1: + pkt = ps.read() + + if pkt is None: + break + + elif isinstance(pkt, PublicKeyPacket): + 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, UserIDPacket): + 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, SignaturePacket): + 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): + # type: (int) -> int + return self._userid[id][0] + + def __setitem__(self, *args): + # type: (*List[Any]) -> None + raise NotImplementedError + + def __delitem__(self, id): + # type: (int) -> None + pkt, idx = self._userid[id] + del self._pubkey[idx] + del self._userid[idx] + pkt, idx = self._keyid[id] + del self._keyid[idx] + +
[docs] def spurious(self): + # type: () -> Tuple[SignaturePacket] + return tuple(self._spurious) +
+
[docs] def save(self, keyring): + # type: (file) -> None + for p in self._pubkey: + pp = p.pack() + keyring.write(pp) + +
+
[docs]def load_pubring(filename='pubring.pgp'): + # type: (AnyStr) -> PublicKeyRing + with open(filename, 'rb') as pkr_f: + pkr = PublicKeyRing(pkr_f) + pkr.load() + return pkr
+
+ +
+
+
+
+
+ + +
+
+
+
+ + + + \ No newline at end of file diff --git a/doc/html/_modules/M2Crypto/PGP/RSA.html b/doc/html/_modules/M2Crypto/PGP/RSA.html new file mode 100644 index 0000000..4c2151d --- /dev/null +++ b/doc/html/_modules/M2Crypto/PGP/RSA.html @@ -0,0 +1,122 @@ + + + + + + + + + + M2Crypto.PGP.RSA — M2Crypto documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for M2Crypto.PGP.RSA

+"""M2Crypto PGP2 RSA.
+
+Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
+
+from M2Crypto import m2, util
+from M2Crypto.RSA import RSA_pub  # noqa
+if util.py27plus:
+    from typing import Tuple  # noqa
+
+
+
[docs]def new_pub_key(e_n): + # type: (Tuple[int, int]) -> RSA_pub + """ + 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) + + (e, n) = e_n + rsa = m2.rsa_new() + m2.rsa_set_en_bin(rsa, e, n) + return RSA_pub(rsa, 1)
+
+ +
+
+
+
+
+ + +
+
+
+
+ + + + \ No newline at end of file diff --git a/doc/html/_modules/M2Crypto/PGP/packet.html b/doc/html/_modules/M2Crypto/PGP/packet.html new file mode 100644 index 0000000..bef4f47 --- /dev/null +++ b/doc/html/_modules/M2Crypto/PGP/packet.html @@ -0,0 +1,514 @@ + + + + + + + + + + M2Crypto.PGP.packet — M2Crypto documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for M2Crypto.PGP.packet

+from __future__ import absolute_import
+
+"""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. UNFINISHED, type hinting is probably wrong!!!
+
+# Be liberal in what you accept.
+# Be conservative in what you send.
+# Be lazy in what you eval.
+
+import struct
+
+from io import BytesIO
+
+from M2Crypto import util  # noqa
+from M2Crypto.util import octx_to_num
+from M2Crypto.PGP import constants  # noqa
+if util.py27plus:
+    from typing import AnyStr, IO, Optional, Tuple  # noqa
+
+_OK_VERSION = ('\002', '\003')
+_OK_VALIDITY = ('\000',)
+_OK_PKC = ('\001',)
+
+
+
[docs]class XXXError(Exception): + pass + +
+
[docs]class Packet: + def __init__(self, ctb, body=None): + # type: (int, Optional[str]) -> 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 = BytesIO(body) # type: Optional[IO[str]] + else: + self.body = None + +
[docs] def validate(self): + # type: () -> int + return 1 +
+
[docs] def pack(self): + # type: () -> None + raise NotImplementedError('%s.pack(): abstract method' % + (self.__class__,)) +
+
[docs] def version(self): + # type: () -> Optional[int] + if hasattr(self, '_version'): + return ord(self._version) + else: + return None +
+
[docs] def timestamp(self): + # type: () -> Optional[int] + if hasattr(self, '_timestamp'): + return struct.unpack('>L', self._timestamp)[0] + else: + return None +
+
[docs] def validity(self): + # type: () -> Optional[int] + if hasattr(self, '_validity'): + return struct.unpack('>H', self._validity)[0] + else: + return None +
+
[docs] def pkc(self): + # type: () -> Optional[bytes] + if hasattr(self, '_pkc'): + return self._pkc + else: + return None +
+ def _llf(self, lenf): + # type: (int) -> Tuple[int, bytes] + if lenf < 256: + return 0, chr(lenf) + elif lenf < 65536: + return 1, struct.pack('>H', lenf) + else: + assert lenf < 2**32 + return 2, struct.pack('>L', lenf) + + def _ctb(self, llf): + # type: (int) -> int + ctbv = _FACTORY[self.__class__] + return chr((1 << 7) | (ctbv << 2) | llf) + +
+
[docs]class PublicKeyPacket(Packet): # noqa + def __init__(self, ctb, body=None): + # type: (int, Optional[IO[str]) -> 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) + +
[docs] def pack(self): + # type: () -> str + if self.body is None: + self.body = BytesIO() + 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) +
+
[docs] def pubkey(self): + # type: () -> bytes + return self._pubkey.pub() + +
+
[docs]class TrustPacket(Packet): # noqa + # This implementation neither interprets nor emits trust packets. + def __init__(self, ctb, body=None): + # type: (int, Optional[AnyStr]) -> None + Packet.__init__(self, ctb, body) + if body is not None: + self.trust = self.body.read(1) + +
+
[docs]class UserIDPacket(Packet): # noqa + def __init__(self, ctb, body=None): + # type: (int, Optional[str]) -> None + Packet.__init__(self, ctb, body) + if body is not None: + self._userid = body + +
[docs] def pack(self): + # type: () -> int + if self.body is None: + self.body = '' + self.body += chr(len(self._userid)) + self.body += self._userid + return self.ctb + self.body +
+
[docs] def userid(self): + # type: () -> int + return self._userid + +
+
[docs]class CommentPacket(Packet): # noqa + def __init__(self, ctb, body=None): + # type: (int, Optional[int]) -> None + Packet.__init__(self, ctb, body) + if body is not None: + self.comment = self.body.getvalue() + +
[docs] def pack(self): + # type: () -> int + if self.body is None: + self.body = chr(len(self.comment)) + self.body += self.comment + return self.ctb + self.body + +
+
[docs]class SignaturePacket(Packet): # noqa + def __init__(self, ctb, body=None): + # type: (int, Optional[IO[bytes]]) -> 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() + +
[docs] def pack(self): + # type: () -> str + if self.body is None: + self.body = self._version + self.body += self._len_md_stuff + self.body += self._classification + self.body += self._timestamp + self.body += self._keyid + self.body += self._pkc + self.body += self._md_algo + self.body += self._md_chksum + self.body += self._sig + llf, lenf = self._llf(len(self.body)) + self.ctb = self.ctb | llf + return '%s%s%s' % (self.ctb, lenf, self.body) +
+
[docs] def validate(self): + # type: () -> None + # FIXME this looks broken ... returning None always? + if self._version not in _OK_VERSION: + return None + if self._len_md_stuff != '\005': + return None + +
+
[docs]class PrivateKeyPacket(Packet): # noqa + def __init__(self, ctb, body=None): + # type: (int, IO[bytes]) -> 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) + +
[docs] def is_encrypted(self): + # type: () -> int + return ord(self._cipher) + +
+
[docs]class CKEPacket(Packet): # noqa + def __init__(self, ctb, body=None): + # type: (int, IO[bytes]) -> 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() + +
+
[docs]class PKEPacket(Packet): # noqa + def __init__(self, ctb, body=None): + # type: (int, IO[bytes]) -> 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)) + +
+
[docs]class LiteralPacket(Packet): # noqa + def __init__(self, ctb, body=None): + # type: (int, IO[bytes]) -> 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() + +
+
[docs]class CompressedPacket(Packet): # noqa + def __init__(self, ctb, stream): + # type: (int, IO[bytes]) -> None + Packet.__init__(self, ctb, '') + if self.body is not None: + self.algo = stream.read(1) + # This reads the entire stream into memory. + self.data = stream.read() + +
[docs] def validate(self): + # type: () -> bool + return self.algo == '\001' +
+
[docs] def uncompress(self): + # type: () -> IO[bytes] + import zlib + decomp = zlib.decompressobj(-13) # RFC 2440, pg 61. + # This doubles the memory usage. + stream = BytesIO(decomp.decompress(self.data)) + return stream + +
+_FACTORY = { + 1: PKEPacket, + 2: SignaturePacket, + # 3 : message_digest_packet, # XXX not implemented + 5: PrivateKeyPacket, + 6: PublicKeyPacket, + # 8 : CompressedPacket, # special case + 9: CKEPacket, + 11: LiteralPacket, + 12: TrustPacket, + 13: UserIDPacket, + 14: CommentPacket, + PKEPacket: 1, + SignaturePacket: 2, + # 3 : message_digest_packet, + PrivateKeyPacket: 5, + PublicKeyPacket: 6, + # 8 : CompressedPacket, + CKEPacket: 9, + LiteralPacket: 11, + TrustPacket: 12, + UserIDPacket: 13, + CommentPacket: 14 +} + + +
[docs]class PacketStream: # noqa + def __init__(self, input): + # type: (IO[bytes]) -> None + self.stream = input + self.under_current = None + self._count = 0 + +
[docs] def close(self): + # type: () -> None + self.stream.close() + if self.under_current is not None: + self.under_current.close() +
+
[docs] def read(self, keep_trying=0): + # type: (int) -> Packet + 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 == constants.CTB_COMPRESSED_DATA: + self.under_current = self.stream + cp = CompressedPacket(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) +
+
[docs] def count(self): + # type: () -> int + return self._count + +
+
[docs]def is_ctb(ctb): + # type: (int) -> bool + return ctb & 0xc0 + +
+
[docs]def make_ctb(value, llf): + # type: (int, int) -> str + return chr((1 << 7) | (value << 2) | llf)
+
+ +
+
+
+
+
+ + +
+
+
+
+ + + + \ 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..dc7b374 --- /dev/null +++ b/doc/html/_modules/M2Crypto/RC4.html @@ -0,0 +1,130 @@ + + + + + + + + + + M2Crypto.RC4 — M2Crypto documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for M2Crypto.RC4

+from __future__ import absolute_import
+
+"""M2Crypto wrapper for OpenSSL RC4 API.
+
+Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
+
+from M2Crypto.m2 import rc4_free, rc4_new, rc4_set_key, rc4_update
+
+
[docs]class RC4: + + """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): + # type: () -> None + if getattr(self, 'cipher', None): + self.rc4_free(self.cipher) + +
[docs] def set_key(self, key): + # type: (bytes) -> None + rc4_set_key(self.cipher, key) +
+
[docs] def update(self, data): + # type: (bytes) -> bytes + return rc4_update(self.cipher, data) +
+
[docs] def final(self): + # type: () -> str + return ''
+
+ +
+
+
+
+
+ + +
+
+
+
+ + + + \ 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..30933d1 --- /dev/null +++ b/doc/html/_modules/M2Crypto/RSA.html @@ -0,0 +1,557 @@ + + + + + + + + + + M2Crypto.RSA — M2Crypto documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for M2Crypto.RSA

+from __future__ import absolute_import
+
+"""M2Crypto wrapper for OpenSSL RSA API.
+
+Copyright (c) 1999-2004 Ng Pheng Siong. All rights reserved."""
+
+import sys
+
+from M2Crypto import BIO, m2, util
+if util.py27plus:
+    from typing import Any, AnyStr, Callable, Dict, List, IO, Optional, Tuple  # noqa
+
+
+
[docs]class RSAError(Exception): + pass +
+m2.rsa_init(RSAError) + +no_padding = m2.no_padding +pkcs1_padding = m2.pkcs1_padding +sslv23_padding = m2.sslv23_padding +pkcs1_oaep_padding = m2.pkcs1_oaep_padding + + +
[docs]class RSA: + """ + RSA Key Pair. + """ + + 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): + # type: () -> int + return 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': + return m2.rsa_get_n(self.rsa) + else: + raise AttributeError + +
[docs] 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) +
+
[docs] 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) +
+
[docs] 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) +
+
[docs] 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) +
+
[docs] 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) +
+
[docs] 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. + + :param bio: M2Crypto.BIO.BIO object to save key to. + + :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 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) + else: + ciph = ciph() + return m2.rsa_write_key(self.rsa, bio._ptr(), ciph, callback) +
+
[docs] 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. + + :param file: Name of file to save key to. + + :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 callback: A Python callable object that is invoked + to acquire a passphrase with which to protect + the key. The default is + util.passphrase_callback. + """ + with BIO.openfile(file, 'wb') as bio: + return self.save_key_bio(bio, cipher, callback) +
+ save_pem = save_key + +
[docs] 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. + """ + bio = BIO.MemoryBuffer() + self.save_key_bio(bio, cipher, callback) + return bio.read() +
+
[docs] def save_key_der_bio(self, bio): + # type: (BIO.BIO) -> int + """ + Save the key pair to an M2Crypto.BIO.BIO object in DER format. + + :param bio: M2Crypto.BIO.BIO object to save key to. + """ + return m2.rsa_write_key_der(self.rsa, bio._ptr()) +
+
[docs] def save_key_der(self, file): + # type: (AnyStr) -> int + """ + Save the key pair to a file in DER format. + + :param file: Filename to save key to + """ + with BIO.openfile(file, 'wb') as bio: + return self.save_key_der_bio(bio) +
+
[docs] def save_pub_key_bio(self, bio): + # type: (BIO.BIO) -> int + """ + Save the public key to an M2Crypto.BIO.BIO object in PEM format. + + :param bio: M2Crypto.BIO.BIO object to save key to. + """ + return m2.rsa_write_pub_key(self.rsa, bio._ptr()) +
+
[docs] def save_pub_key(self, file): + # type: (AnyStr) -> int + """ + Save the public key to a file in PEM format. + + :param file: Name of file to save key to. + """ + with BIO.openfile(file, 'wb') as bio: + return m2.rsa_write_pub_key(self.rsa, bio._ptr()) +
+
[docs] def check_key(self): + # type: () -> int + """ + + :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) +
+
[docs] 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 + + :param digest: A digest created by using the digest method + + :param salt_length: The length of the salt to use + + :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 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) +
+
[docs] def verify_rsassa_pss(self, data, signature, algo='sha1', salt_length=20): + # type: (bytes, bytes, str, int) -> int + """ + Verifies the signature RSASSA-PSS + + :param data: Data that has been signed + + :param signature: The signature signed with RSASSA-PSS + + :param salt_length: The length of the salt that was used + + :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. + """ + hash = getattr(m2, algo, None) + + if hash is None: + 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) +
+
[docs] def sign(self, digest, algo='sha1'): + # type: (bytes, str) -> bytes + """ + Signs a digest with the private key + + :param digest: A digest created by using the digest method + + :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) + if digest_type is None: + raise ValueError('unknown algorithm', algo) + + return m2.rsa_sign(self.rsa, digest, digest_type) +
+
[docs] def verify(self, data, signature, algo='sha1'): + # type: (bytes, bytes, str) -> int + """ + Verifies the signature with the public key + + :param data: Data that has been signed + + :param signature: The signature signed with the private key + + :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: 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) + +
+
[docs]class RSA_pub(RSA): # noqa + + """ + Object interface to an RSA public key. + """ + + 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)') + else: + self.__dict__[name] = value + +
[docs] def private_encrypt(self, *argv): + # type: (*List[Any]) -> None + raise RSAError('RSA_pub object has no private key') +
+
[docs] def private_decrypt(self, *argv): + # type: (*List[Any]) -> None + raise RSAError('RSA_pub object has no private key') +
+
[docs] def save_key(self, file, *args, **kw): + # type: (AnyStr, *List[Any], **Dict[Any, Any]) -> int + """ + Save public key to file. + """ + return self.save_pub_key(file) +
+
[docs] def save_key_bio(self, bio, *args, **kw): + # type: (BIO.BIO, *List[Any], **Dict[Any, Any]) -> int + """ + Save public key to BIO. + """ + return self.save_pub_key_bio(bio) + + # save_key_der + + # save_key_der_bio +
+
[docs] def check_key(self): + # type: () -> int + return m2.rsa_check_pub_key(self.rsa) + +
+
[docs]def rsa_error(): + # type: () -> None + raise RSAError(m2.err_reason_error_string(m2.err_get_error())) + +
+
[docs]def keygen_callback(p, n, out=sys.stdout): + # type: (int, Any, IO[str]) -> None + """ + Default callback for gen_key(). + """ + ch = ['.', '+', '*', '\n'] + out.write(ch[p]) + out.flush() + +
+
[docs]def gen_key(bits, e, callback=keygen_callback): + # type: (int, int, Callable) -> RSA + """ + Generate an RSA key pair. + + :param bits: Key length, in bits. + + :param e: The RSA public exponent. + + :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. + + :return: M2Crypto.RSA.RSA object. + """ + return RSA(m2.rsa_generate_key(bits, e, callback), 1) + +
+
[docs]def load_key(file, callback=util.passphrase_callback): + # type: (AnyStr, Callable) -> RSA + """ + Load an RSA key pair from file. + + :param file: Name of file containing RSA public key 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.RSA.RSA object. + """ + with BIO.openfile(file) as bio: + return load_key_bio(bio, callback) + +
+
[docs]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. + + :param bio: M2Crypto.BIO.BIO object containing RSA 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.RSA.RSA object. + """ + rsa = m2.rsa_read_key(bio._ptr(), callback) + if rsa is None: + rsa_error() + return RSA(rsa, 1) + +
+
[docs]def load_key_string(string, callback=util.passphrase_callback): + # type: (AnyStr, Callable) -> RSA + """ + Load an RSA key pair from a string. + + :param string: String containing RSA 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.RSA.RSA object. + """ + bio = BIO.MemoryBuffer(string) + return load_key_bio(bio, callback) + +
+
[docs]def load_pub_key(file): + # type: (AnyStr) -> RSA_pub + """ + Load an RSA public key from file. + + :param file: Name of file containing RSA public key in PEM format. + + :return: M2Crypto.RSA.RSA_pub object. + """ + with BIO.openfile(file) as bio: + return load_pub_key_bio(bio) + +
+
[docs]def load_pub_key_bio(bio): + # type: (BIO.BIO) -> RSA_pub + """ + Load an RSA public key from an M2Crypto.BIO.BIO object. + + :param bio: M2Crypto.BIO.BIO object containing RSA public key in PEM + format. + + :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) + +
+
[docs]def new_pub_key(e_n): + # type: (Tuple[bytes, bytes]) -> RSA_pub + """ + Instantiate an RSA_pub object from an (e, n) tuple. + + :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 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. + + :return: M2Crypto.RSA.RSA_pub object. + """ + (e, n) = e_n + rsa = m2.rsa_new() + m2.rsa_set_en(rsa, e, n) + return RSA_pub(rsa, 1)
+
+ +
+
+
+
+
+ + +
+
+
+
+ + + + \ 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..f22a12f --- /dev/null +++ b/doc/html/_modules/M2Crypto/Rand.html @@ -0,0 +1,127 @@ + + + + + + + + + + M2Crypto.Rand — M2Crypto documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for M2Crypto.Rand

+from __future__ import absolute_import
+
+"""M2Crypto wrapper for OpenSSL PRNG. Requires OpenSSL 0.9.5 and above.
+
+Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
+
+from M2Crypto import m2, util
+if util.py27plus:
+    from typing import AnyStr, List  # noqa
+
+
+__all__ = ['rand_seed', 'rand_add', 'load_file', 'save_file', 'rand_bytes',
+           'rand_pseudo_bytes', 'rand_file_name', 'rand_status']
+
+rand_seed = m2.rand_seed  # type: (bytes) -> None
+rand_add = m2.rand_add  # type: (bytes, float) -> None
+load_file = m2.rand_load_file  # type: (AnyStr, int) -> int
+save_file = m2.rand_save_file  # type: (AnyStr) -> int
+rand_bytes = m2.rand_bytes  # type: (int) -> bytes
+rand_status = m2.rand_status  # type: () -> int
+
+
+
[docs]def rand_pseudo_bytes(n): + # type: (int) -> Tuple[bytes, int] + import warnings + warnings.warn('The underlying OpenSSL method has been ' + + 'deprecated. Use Rand.rand_bytes instead.', DeprecationWarning) + return m2.rand_pseudo_bytes(n) + +
+
[docs]def rand_file_name(): + # type: () -> str + return util.py3str(m2.rand_file_name())
+
+ +
+
+
+
+
+ + +
+
+
+
+ + + + \ 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..18a768d --- /dev/null +++ b/doc/html/_modules/M2Crypto/SMIME.html @@ -0,0 +1,416 @@ + + + + + + + + + + M2Crypto.SMIME — M2Crypto documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for M2Crypto.SMIME

+from __future__ import absolute_import
+
+"""M2Crypto wrapper for OpenSSL S/MIME API.
+
+Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
+
+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_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
+
+
+
[docs]class PKCS7_Error(Exception): # noqa + pass +
+m2.pkcs7_init(PKCS7_Error) + + +
[docs]class PKCS7: + + m2_pkcs7_free = m2.pkcs7_free + + def __init__(self, pkcs7=None, _pyfree=0): + # type: (Optional[bytes], int) -> None + """ + :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) + + def _ptr(self): + return self.pkcs7 + +
[docs] 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) +
+
[docs] def write(self, bio): + # type: (BIO.BIO) -> int + return m2.pkcs7_write_bio(self.pkcs7, bio._ptr()) +
+
[docs] def write_der(self, bio): + # type: (BIO.BIO) -> int + return m2.pkcs7_write_bio_der(self.pkcs7, bio._ptr()) +
+
[docs] 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) + +
+
[docs]def 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 = 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) + +
+
[docs]def load_pkcs7_der(p7file): + # type: (AnyStr) -> PKCS7 + bio = m2.bio_new_file(p7file, 'r') + if bio is None: + raise BIO.BIOError(Err.get_error()) + + try: + p7_ptr = m2.pkcs7_read_bio_der(bio) + finally: + m2.bio_free(bio) + + if p7_ptr is None: + raise PKCS7_Error(Err.get_error()) + return PKCS7(p7_ptr, 1) + +
+
[docs]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) + +
+
[docs]def load_pkcs7_bio_der(p7_bio): + # type: (BIO.BIO) -> PKCS7 + p7_ptr = m2.pkcs7_read_bio_der(p7_bio._ptr()) + if p7_ptr is None: + raise PKCS7_Error(Err.get_error()) + return PKCS7(p7_ptr, 1) + +
+
[docs]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) + +
+
[docs]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()) + if bio_ptr is None: + return PKCS7(p7_ptr, 1), None + else: + return PKCS7(p7_ptr, 1), BIO.BIO(bio_ptr, 1) + +
+
[docs]class Cipher: + + """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) + self.cipher = cipher() + + def _ptr(self): + return self.cipher + +
+
[docs]class SMIME_Error(Exception): # noqa + pass +
+m2.smime_init(SMIME_Error) + +# FIXME class has no __init__ method +
[docs]class SMIME: +
[docs] 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) +
+
[docs] 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) +
+
[docs] def set_x509_stack(self, stack): + # type: (X509.X509_Stack) -> None + assert isinstance(stack, X509.X509_Stack) + self.x509_stack = stack +
+
[docs] def set_x509_store(self, store): + # type: (X509.X509_Store) -> None + assert isinstance(store, X509.X509_Store) + self.x509_store = store +
+
[docs] def set_cipher(self, cipher): + # type: (Cipher) -> None + assert isinstance(cipher, Cipher) + self.cipher = cipher +
+
[docs] def unset_key(self): + # type: () -> None + del self.pkey + del self.x509 +
+
[docs] def unset_x509_stack(self): + # type: () -> None + del self.x509_stack +
+
[docs] def unset_x509_store(self): + # type: () -> None + del self.x509_store +
+
[docs] def unset_cipher(self): + # type: () -> None + del self.cipher +
+
[docs] 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()') + 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()) + return PKCS7(pkcs7, 1) +
+
[docs] 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()') + 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()) + return blob +
+
[docs] 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()') + + 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(), hash(), flags) + if pkcs7 is None: + raise SMIME_Error(Err.get_error()) + return PKCS7(pkcs7, 1) + else: + pkcs7 = m2.pkcs7_sign0(self.x509._ptr(), self.pkey._ptr(), + data_bio._ptr(), hash(), flags) + if pkcs7 is None: + raise SMIME_Error(Err.get_error()) + return PKCS7(pkcs7, 1) +
+
[docs] 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()') + if not hasattr(self, '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) + 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()) + return blob +
+
[docs] 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) + +
+
[docs]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()): + return bio_out.read() + else: + raise SMIME_Error(Err.get_error()) + +
+
[docs]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())
+
+ +
+
+
+
+
+ + +
+
+
+
+ + + + \ 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..6659f09 --- /dev/null +++ b/doc/html/_modules/M2Crypto/SSL.html @@ -0,0 +1,134 @@ + + + + + + + + + + M2Crypto.SSL — M2Crypto documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for M2Crypto.SSL

+from __future__ import absolute_import
+
+"""M2Crypto SSL services.
+
+Copyright (c) 1999-2004 Ng Pheng Siong. All rights reserved."""
+
+import socket
+
+# M2Crypto
+from M2Crypto import m2
+
+
+
[docs]class SSLError(Exception): + pass + +
+
[docs]class SSLTimeoutError(SSLError, socket.timeout): + pass +
+m2.ssl_init(SSLError, SSLTimeoutError) + +# M2Crypto.SSL +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 (ForkingSSLServer, SSLServer, + ThreadingSSLServer) +from M2Crypto.SSL.ssl_dispatcher import ssl_dispatcher +from M2Crypto.SSL.timeout import timeout + +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 +
+ +
+
+
+
+
+ + +
+
+
+
+ + + + \ 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..98338bb --- /dev/null +++ b/doc/html/_modules/M2Crypto/SSL/Checker.html @@ -0,0 +1,393 @@ + + + + + + + + + + M2Crypto.SSL.Checker — M2Crypto documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for M2Crypto.SSL.Checker

+"""
+SSL peer certificate checking routines
+
+Copyright (c) 2004-2007 Open Source Applications Foundation.
+All rights reserved.
+
+Copyright 2008 Heikki Toivonen. All rights reserved.
+"""
+
+__all__ = ['SSLVerificationError', 'NoCertificate', 'WrongCertificate',
+           'WrongHost', 'Checker']
+
+import re
+import socket
+
+from M2Crypto import X509, m2, util  # noqa
+if util.py27plus:
+    from typing import AnyStr, Optional  # noqa
+
+
+
[docs]class SSLVerificationError(Exception): + pass + +
+
[docs]class NoCertificate(SSLVerificationError): + pass + +
+
[docs]class WrongCertificate(SSLVerificationError): + pass + +
+
[docs]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 + certificate. + :param actualHost: The name of the host we actually found in the + certificate. + :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') + + 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) + return util.py3str(s) + +
+
[docs]class Checker: + + 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 = util.py3bytes(peerCertHash) + self.fingerprint = peerCertHash + 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 # type: str + + if self.fingerprint: + if self.digest not in ('sha1', 'md5'): + 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 = util.py3str(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 + self.useSubjectAltNameOnly = False + + # subjectAltName=DNS:somehost[, ...]* + try: + subjectAltName = peerCert.get_ext('subjectAltName').get_value() + if self._splitSubjectAltName(self.host, subjectAltName): + hostValidationPassed = True + elif self.useSubjectAltNameOnly: + raise WrongHost(expectedHost=self.host, + actualHost=subjectAltName, + fieldName='subjectAltName') + except LookupError: + pass + + # commonName=somehost[, ...]* + if not hostValidationPassed: + hasCommonName = False + commonNames = '' + for entry in peerCert.get_subject().get_entries_by_nid( + m2.NID_commonName): + hasCommonName = True + commonName = entry.get_data().as_text() + if not commonNames: + commonNames = commonName + else: + commonNames += ',' + commonName + if self._match(self.host, commonName): + hostValidationPassed = True + break + + if not hasCommonName: + raise WrongCertificate('no commonName in peer certificate') + + if not hostValidationPassed: + raise WrongHost(expectedHost=self.host, + actualHost=commonNames, + fieldName='commonName') + + return True + + def _splitSubjectAltName(self, host, subjectAltName): + # type: (AnyStr, AnyStr) -> bool + """ + >>> check = Checker() + >>> check._splitSubjectAltName(host='my.example.com', + ... subjectAltName='DNS:my.example.com') + True + >>> check._splitSubjectAltName(host='my.example.com', + ... subjectAltName='DNS:*.example.com') + True + >>> check._splitSubjectAltName(host='my.example.com', + ... subjectAltName='DNS:m*.example.com') + True + >>> 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>') + False + >>> 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') + True + >>> 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='') + False + >>> check._splitSubjectAltName(host='my.example.com', + ... subjectAltName='othername:<unsupported>') + False + >>> check.useSubjectAltNameOnly + False + """ + self.useSubjectAltNameOnly = False + for certHost in subjectAltName.split(','): + certHost = certHost.lower().strip() + if certHost[:4] == 'dns:': + 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') + True + >>> check._match(host='my.example.com', certHost='*.example.com') + True + >>> check._match(host='my.example.com', certHost='m*.example.com') + True + >>> check._match(host='my.example.com', certHost='m*.EXAMPLE.com') + True + >>> check._match(host='my.example.com', certHost='m*ample.com') + False + >>> check._match(host='my.example.com', certHost='*.*.com') + False + >>> check._match(host='1.2.3.4', certHost='1.2.3.4') + True + >>> check._match(host='1.2.3.4', certHost='*.2.3.4') + False + >>> check._match(host='1234', certHost='1234') + True + """ + # XXX See RFC 2818 and 3280 for matching rules, this is may not + # XXX yet be complete. + + host = host.lower() + certHost = certHost.lower() + + if host == certHost: + return True + + if certHost.count('*') > 1: + # Not sure about this, but being conservative + return False + + if self.numericIpMatch.match(host) or \ + self.numericIpMatch.match(certHost.replace('*', '')): + # Not sure if * allowed in numeric IP, but think not. + return False + + if certHost.find('\\') > -1: + # Not sure about this, maybe some encoding might have these. + # But being conservative for now, because regex below relies + # on this. + return False + + # Massage certHost so that it can be used in regex + certHost = certHost.replace('.', '\.') + certHost = certHost.replace('*', '[^\.]*') + 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 + doctest.testmod() +
+ +
+
+
+
+
+ + +
+
+
+
+ + + + \ 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..754babf --- /dev/null +++ b/doc/html/_modules/M2Crypto/SSL/Cipher.html @@ -0,0 +1,156 @@ + + + + + + + + + + M2Crypto.SSL.Cipher — M2Crypto documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for M2Crypto.SSL.Cipher

+"""SSL Ciphers
+
+Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
+
+__all__ = ['Cipher', 'Cipher_Stack']
+
+from M2Crypto import m2, util
+if util.py27plus:
+    from typing import Iterable  # noqa
+
+
+
[docs]class Cipher: + def __init__(self, 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)) + +
[docs] def version(self): + # type: () -> int + return m2.ssl_cipher_get_version(self.cipher) +
+
[docs] def name(self): + # type: () -> str + return util.py3str(m2.ssl_cipher_get_name(self.cipher)) + +
+
[docs]class Cipher_Stack: # noqa + def __init__(self, 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) + return Cipher(v) + + def __iter__(self): + # type: () -> Iterable + for i in xrange(m2.sk_ssl_cipher_num(self.stack)): + yield self[i]
+
+ +
+
+
+
+
+ + +
+
+
+
+ + + + \ 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..a1fb4c8 --- /dev/null +++ b/doc/html/_modules/M2Crypto/SSL/Connection.html @@ -0,0 +1,719 @@ + + + + + + + + + + M2Crypto.SSL.Connection — M2Crypto documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for M2Crypto.SSL.Connection

+from __future__ import absolute_import
+
+"""SSL Connection aka socket
+
+Copyright (c) 1999-2004 Ng Pheng Siong. All rights reserved.
+
+Portions created by Open Source Applications Foundation (OSAF) are
+Copyright (C) 2004-2007 OSAF. All Rights Reserved.
+
+Copyright 2008 Heikki Toivonen. All rights reserved.
+"""
+
+import logging
+import socket
+
+from M2Crypto import BIO, X509, m2, 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 util.py27plus:
+    from typing import Any, AnyStr, Callable, Dict, List, Optional, Tuple, Union  # noqa
+
+__all__ = ['Connection',
+           'timeout',  # XXX Not really, but for documentation purposes
+           ]
+
+log = logging.getLogger(__name__)
+
+
+def _serverPostConnectionCheck(*args, **kw):
+    # type: (*List[Any], **Dict[Any, Any]) -> int
+    return 1
+
+
+
[docs]class Connection: + + """An SSL connection.""" + + clientPostConnectionCheck = Checker.Checker() + serverPostConnectionCheck = _serverPostConnectionCheck + + m2_bio_free = m2.bio_free + m2_ssl_free = m2.ssl_free + + 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.socket = sock + else: + self.socket = socket.socket(family, socket.SOCK_STREAM) + self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + self._fileno = self.socket.fileno() + + 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) + + def __del__(self): + # type: () -> None + 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): + self.m2_ssl_free(self.ssl) + self.socket.close() + +
[docs] def close(self): + # type: () -> None + m2.ssl_shutdown(self.ssl) +
+
[docs] 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 + from cache. + """ + return m2.ssl_clear(self.ssl) +
+
[docs] 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) +
+
[docs] def get_shutdown(self): + # type: () -> None + """Get the current shutdown mode of the Connection.""" + return m2.ssl_get_shutdown(self.ssl) +
+
[docs] def bind(self, addr): + # type: (util.AddrType) -> None + self.socket.bind(addr) +
+
[docs] def listen(self, qlen=5): + # type: (int) -> None + self.socket.listen(qlen) +
+
[docs] def ssl_get_error(self, ret): + # type: (int) -> int + return m2.ssl_get_error(self.ssl, ret) +
+
[docs] def set_bio(self, readbio, writebio): + # 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()) +
+
[docs] def set_client_CA_list_from_file(self, cafile): + # 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. + + :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) +
+
[docs] 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) +
+
[docs] def setup_addr(self, addr): + # type: (util.AddrType) -> None + self.addr = addr +
+
[docs] 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 +
+
[docs] 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. + m2.ssl_set_bio(self.ssl, self.sockbio, self.sockbio) + # Make a BIO_f_ssl. + self.sslbio = m2.bio_new(m2.bio_f_ssl()) + # Link BIO_f_ssl with the SSL struct. + 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() + +
[docs] def set_accept_state(self): + # type: () -> None + """Sets Connection to work in the server mode.""" + m2.ssl_set_accept_state(self.ssl) +
+
[docs] def accept_ssl(self): + # 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) +
+
[docs] def accept(self): + # 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) + if check is not None: + if not check(ssl.get_peer_cert(), ssl.addr[0]): + raise Checker.SSLVerificationError( + 'post connection check failed') + return ssl, addr +
+
[docs] def set_connect_state(self): + # type: () -> None + """Sets Connection to work in the client mode.""" + m2.ssl_set_connect_state(self.ssl) +
+
[docs] def connect_ssl(self): + # type: () -> Optional[int] + return m2.ssl_connect(self.ssl, self._timeout) +
+
[docs] 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) + if check is not None: + if not check(self.get_peer_cert(), self.addr[0]): + raise Checker.SSLVerificationError( + 'post connection check failed') + return ret +
+
[docs] def shutdown(self, how): + # type: (int) -> None + m2.ssl_set_shutdown(self.ssl, how) +
+
[docs] def renegotiate(self): + # type: () -> int + """Renegotiate this connection's SSL parameters.""" + return m2.ssl_renegotiate(self.ssl) +
+
[docs] def pending(self): + # 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): + # 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, self._timeout) + + def _read_nbio(self, size=1024): + # type: (int) -> bytes + if size <= 0: + raise ValueError('size <= 0') + return m2.ssl_read_nbio(self.ssl, size) + +
[docs] def write(self, data): + # type: (bytes) -> int + if self._timeout != 0.0: + return self._write_bio(data) + return self._write_nbio(data)
+ sendall = send = write + +
[docs] def read(self, size=1024): + # type: (int) -> bytes + if self._timeout != 0.0: + return self._read_bio(size) + return self._read_nbio(size)
+ recv = read + +
[docs] def setblocking(self, 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) + if mode: + self._timeout = -1.0 + else: + self._timeout = 0.0 +
+
[docs] 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 +
+
[docs] def fileno(self): + # type: () -> int + return self.socket.fileno() +
+
[docs] 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) +
+
[docs] 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) +
+
[docs] def get_context(self): + # type: () -> SSL.Context + """Return the SSL.Context object associated with this connection.""" + return m2.ssl_get_ssl_ctx(self.ssl) +
+
[docs] def get_state(self): + # 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) +
+
[docs] def verify_ok(self): + # type: () -> bool + return (m2.ssl_get_verify_result(self.ssl) == m2.X509_V_OK) +
+
[docs] def get_verify_mode(self): + # type: () -> int + """Return the peer certificate verification mode.""" + return m2.ssl_get_verify_mode(self.ssl) +
+
[docs] def get_verify_depth(self): + # type: () -> int + """Return the peer certificate verification depth.""" + return m2.ssl_get_verify_depth(self.ssl) +
+
[docs] def get_verify_result(self): + # type: () -> int + """Return the peer certificate verification result.""" + return m2.ssl_get_verify_result(self.ssl) +
+
[docs] def get_peer_cert(self): + # 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) +
+
[docs] def get_peer_cert_chain(self): + # 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. + """ + 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) +
+
[docs] def get_cipher(self): + # type: () -> Optional[SSL.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) +
+
[docs] def get_ciphers(self): + # type: () -> Optional[SSL: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) +
+
[docs] 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) +
+
[docs] 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) +
+
[docs] def makefile(self, mode='rb', bufsize=-1): + # type: (AnyStr, int) -> socket._fileobject + return socket._fileobject(self, mode, bufsize) +
+
[docs] 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() +
+
[docs] 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() +
+
[docs] 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())) +
+
[docs] def get_session(self): + # type: () -> SSL.Session + sess = m2.ssl_get_session(self.ssl) + return Session(sess) +
+
[docs] def set_session(self, session): + # type: (SSL.Session) -> None + m2.ssl_set_session(self.ssl, session._ptr()) +
+
[docs] def get_default_session_timeout(self): + # type: () -> int + return m2.ssl_get_default_session_timeout(self.ssl) +
+
[docs] def get_socket_read_timeout(self): + # type: () -> SSL.timeout + return timeout.struct_to_timeout( + self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_RCVTIMEO, + timeout.struct_size())) +
+
[docs] def get_socket_write_timeout(self): + # type: () -> SSL.timeout + return timeout.struct_to_timeout( + self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_SNDTIMEO, + timeout.struct_size())) +
+
[docs] def set_socket_read_timeout(self, timeo): + # type: (SSL.timeout) -> None + assert isinstance(timeo, timeout.timeout) + self.socket.setsockopt( + socket.SOL_SOCKET, socket.SO_RCVTIMEO, timeo.pack()) +
+
[docs] def set_socket_write_timeout(self, timeo): + # type: (SSL.timeout) -> None + assert isinstance(timeo, timeout.timeout) + self.socket.setsockopt( + socket.SOL_SOCKET, socket.SO_SNDTIMEO, timeo.pack()) +
+
[docs] def get_version(self): + # type: () -> str + """Return the TLS/SSL protocol version for this connection.""" + return m2.ssl_get_version(self.ssl) +
+
[docs] def set_post_connection_check_callback(self, postConnectionCheck): # noqa + # type: (Callable) -> None + self.postConnectionCheck = postConnectionCheck +
+
[docs] 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)
+
+ +
+
+
+
+
+ + +
+
+
+
+ + + + \ 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..1a377ba --- /dev/null +++ b/doc/html/_modules/M2Crypto/SSL/Context.html @@ -0,0 +1,542 @@ + + + + + + + + + + M2Crypto.SSL.Context — M2Crypto documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for M2Crypto.SSL.Context

+from __future__ import absolute_import
+
+"""SSL Context
+
+Copyright (c) 1999-2004 Ng Pheng Siong. All rights reserved."""
+
+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']
+
+
+class _ctxmap:  # noqa
+    singleton = None  # type: Optional[_ctxmap]
+
+    def __init__(self):
+        # type: () -> None
+        """Simple WeakReffed list.
+        """
+        self._ctxmap = WeakValueDictionary()
+
+    def __getitem__(self, key):
+        # type: (int) -> Any
+        return self._ctxmap[key]
+
+    def __setitem__(self, key, value):
+        # type: (int, Any) -> None
+        self._ctxmap[key] = value
+
+    def __delitem__(self, key):
+        # type: (int) -> None
+        del self._ctxmap[key]
+
+
+
[docs]def ctxmap(): + # type: () -> _ctxmap + if _ctxmap.singleton is None: + _ctxmap.singleton = _ctxmap() + return _ctxmap.singleton +# deprecated!!!
+map = ctxmap + + +
[docs]class Context: + + """'Context' for SSL connections.""" + + m2_ssl_ctx_free = m2.ssl_ctx_free + + 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: + # 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 # 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) + +
[docs] def close(self): + # type: () -> None + del ctxmap()[int(self.ctx)] +
+
[docs] 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. + :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'. + :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: + 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') +
+
[docs] 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 + certificate chain. + :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'. + :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: + 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') +
+
[docs] 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 + certificates concatenated together. + """ + m2.ssl_ctx_set_client_CA_list_from_file(self.ctx, cafile) + + # Deprecated.
+ load_client_CA = load_client_ca = set_client_CA_list_from_file + +
[docs] def load_verify_locations(self, cafile=None, capath=None): + # 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. + + :param capath: Directory containing PEM-encoded CA certificates + (one certificate per file). + + :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.") + return m2.ssl_ctx_load_verify_locations(self.ctx, cafile, capath) + + # Deprecated.
+ load_verify_info = load_verify_locations + +
[docs] 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(), '') +
+
[docs] 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!') +
+
[docs] 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. + """ + self.allow_unknown_ca = ok +
+
[docs] 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 +
+
[docs] 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 + SSL.verify_peer is used. Clients would also typically + add SSL.verify_fail_if_no_peer_cert. + :param depth: The maximum allowed depth of the certificate chain + returned by the peer. + :param callback: Callable that can be used to specify custom + verification checks. + """ + if callback is None: + m2.ssl_ctx_set_verify_default(self.ctx, mode) + else: + m2.ssl_ctx_set_verify(self.ctx, mode, callback) + m2.ssl_ctx_set_verify_depth(self.ctx, depth) +
+
[docs] def get_verify_mode(self): + # type: () -> int + return m2.ssl_ctx_get_verify_mode(self.ctx) +
+
[docs] 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) +
+
[docs] def set_tmp_dh(self, dhpfile): + # type: (AnyStr) -> int + """Load ephemeral DH parameters into the context. + + :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) +
+
[docs] 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) +
+
[docs] def set_tmp_rsa(self, rsa): + # type: (RSA.RSA) -> int + """Load ephemeral RSA key into the context. + + :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) +
+
[docs] 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) +
+
[docs] 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. + """ + m2.ssl_ctx_set_info_callback(self.ctx, callback) +
+
[docs] 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) +
+
[docs] 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()) +
+
[docs] 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()) +
+
[docs] 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) +
+
[docs] 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) +
+
[docs] 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) +
+
[docs] 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) +
+
[docs] 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) +
+
[docs] 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. + """ + return X509.X509_Store(m2.ssl_ctx_get_cert_store(self.ctx))
+
+ +
+
+
+
+
+ + +
+
+
+
+ + + + \ 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..898c32a --- /dev/null +++ b/doc/html/_modules/M2Crypto/SSL/SSLServer.html @@ -0,0 +1,157 @@ + + + + + + + + + + M2Crypto.SSL.SSLServer — M2Crypto documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for M2Crypto.SSL.SSLServer

+from __future__ import absolute_import, print_function
+
+"""SSLServer
+
+Copyright (c) 1999-2002 Ng Pheng Siong. All rights reserved."""
+
+# M2Crypto
+from M2Crypto.SSL import SSLError
+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, ForkingMixIn,
+                                             TCPServer, ThreadingMixIn)
+from socket import socket  # noqa
+if util.py27plus:
+    from typing import Union  # noqa
+
+__all__ = ['SSLServer', 'ForkingSSLServer', 'ThreadingSSLServer']
+
+
+
[docs]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. + """ + 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() + +
[docs] def handle_request(self): + # type: () -> None + request = None + client_address = None + try: + request, client_address = self.get_request() + if self.verify_request(request, client_address): + self.process_request(request, client_address) + except SSLError: + self.handle_error(request, client_address) +
+
[docs] def handle_error(self, request, client_address): + # type: (Union[socket, Connection], util.AddrType) -> None + print('-' * 40) + import traceback + traceback.print_exc() + print('-' * 40) + +
+
[docs]class ForkingSSLServer(ForkingMixIn, SSLServer): + pass + +
+
[docs]class ThreadingSSLServer(ThreadingMixIn, SSLServer): + pass
+
+ +
+
+
+
+
+ + +
+
+
+
+ + + + \ 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..cd54906 --- /dev/null +++ b/doc/html/_modules/M2Crypto/SSL/Session.html @@ -0,0 +1,167 @@ + + + + + + + + + + M2Crypto.SSL.Session — M2Crypto documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for M2Crypto.SSL.Session

+"""SSL Session
+
+Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
+
+__all__ = ['Session', 'load_session']
+
+from M2Crypto import BIO, Err, m2, util
+from M2Crypto.SSL import SSLError
+if util.py27plus:
+    from typing import AnyStr  # noqa
+
+
+
[docs]class Session: + + 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 + +
[docs] def as_text(self): + # type: () -> bytes + buf = BIO.MemoryBuffer() + m2.ssl_session_print(buf.bio_ptr(), self.session) + return buf.read_all() +
+
[docs] def as_der(self): + # type: () -> bytes + buf = BIO.MemoryBuffer() + m2.i2d_ssl_session(buf.bio_ptr(), self.session) + return buf.read_all() +
+
[docs] def write_bio(self, bio): + # type: (BIO.BIO) -> int + return m2.ssl_session_write_bio(bio.bio_ptr(), self.session) +
+
[docs] def get_time(self): + # type: () -> int + return m2.ssl_session_get_time(self.session) +
+
[docs] def set_time(self, t): + # type: (int) -> int + return m2.ssl_session_set_time(self.session, t) +
+
[docs] def get_timeout(self): + # type: () -> int + return m2.ssl_session_get_timeout(self.session) +
+
[docs] def set_timeout(self, t): + # type: (int) -> int + return m2.ssl_session_set_timeout(self.session, t) + +
+
[docs]def load_session(pemfile): + # type: (AnyStr) -> Session + with BIO.openfile(pemfile) as f: + cptr = m2.ssl_session_read_pem(f.bio_ptr()) + if cptr is None: + raise SSLError(Err.get_error()) + return Session(cptr, 1)
+
+ +
+
+
+
+
+ + +
+
+
+
+ + + + \ 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..c0b7245 --- /dev/null +++ b/doc/html/_modules/M2Crypto/SSL/TwistedProtocolWrapper.html @@ -0,0 +1,518 @@ + + + + + + + + + + M2Crypto.SSL.TwistedProtocolWrapper — M2Crypto documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for M2Crypto.SSL.TwistedProtocolWrapper

+"""
+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 logging
+
+import twisted.internet.reactor
+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 twisted.protocols.policies import ProtocolWrapper
+if util.py27plus:
+    from typing import AnyStr, Callable, Optional  # noqa
+    from zope.interface import implementer
+
+log = logging.getLogger(__name__)
+
+
+def _alwaysSucceedsPostConnectionCheck(peerX509, expectedHost):
+    return 1
+
+
+
[docs]def connectSSL(host, port, factory, contextFactory, timeout=30, + bindAddress=None, + reactor=twisted.internet.reactor, + 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. + """ + wrappingFactory = policies.WrappingFactory(factory) + wrappingFactory.protocol = lambda factory, wrappedProtocol: \ + TLSProtocolWrapper(factory, + wrappedProtocol, + startPassThrough=0, + client=1, + contextFactory=contextFactory, + postConnectionCheck=postConnectionCheck) + return reactor.connectTCP(host, port, wrappingFactory, timeout, bindAddress) + +
+
[docs]def connectTCP(host, port, factory, timeout=30, bindAddress=None, + reactor=twisted.internet.reactor, + postConnectionCheck=Checker()): + # type: (str, int, object, int, Optional[util.AddrType], object, Callable) -> object + """ + 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. + """ + wrappingFactory = policies.WrappingFactory(factory) + wrappingFactory.protocol = lambda factory, wrappedProtocol: \ + TLSProtocolWrapper(factory, + wrappedProtocol, + startPassThrough=1, + client=1, + contextFactory=None, + postConnectionCheck=postConnectionCheck) + return reactor.connectTCP(host, port, wrappingFactory, timeout, bindAddress) + +
+
[docs]def listenSSL(port, factory, contextFactory, backlog=5, interface='', + reactor=twisted.internet.reactor, + postConnectionCheck=_alwaysSucceedsPostConnectionCheck): + """ + A convenience function to listen for SSL/TLS connections using Twisted. + + See IReactorSSL interface in Twisted. + """ + wrappingFactory = policies.WrappingFactory(factory) + wrappingFactory.protocol = lambda factory, wrappedProtocol: \ + TLSProtocolWrapper(factory, + wrappedProtocol, + startPassThrough=0, + client=0, + contextFactory=contextFactory, + postConnectionCheck=postConnectionCheck) + return reactor.listenTCP(port, wrappingFactory, backlog, interface) + +
+
[docs]def listenTCP(port, factory, backlog=5, interface='', + reactor=twisted.internet.reactor, + postConnectionCheck=None): + """ + 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. + """ + wrappingFactory = policies.WrappingFactory(factory) + wrappingFactory.protocol = lambda factory, wrappedProtocol: \ + TLSProtocolWrapper(factory, + wrappedProtocol, + startPassThrough=1, + client=0, + contextFactory=None, + postConnectionCheck=postConnectionCheck) + return reactor.listenTCP(port, wrappingFactory, backlog, interface) + +
+class _BioProxy: + """ + 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: + """ + 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) +
[docs]class TLSProtocolWrapper(ProtocolWrapper): + """ + 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. + """ + + def __init__(self, factory, wrappedProtocol, startPassThrough, client, + contextFactory, postConnectionCheck): + """ + :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. + The called function is getContext(). + :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 + self.factory = factory + self.wrappedProtocol = wrappedProtocol + + # wrappedProtocol == client/server instance + # factory.wrappedFactory == client/server factory + + 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 + if postConnectionCheck is None: + self.postConnectionCheck = _alwaysSucceedsPostConnectionCheck + else: + self.postConnectionCheck = postConnectionCheck + + if not startPassThrough: + self.startTLS(contextFactory.getContext()) + +
[docs] def clear(self): + """ + Clear this instance, after which it is ready for reuse. + """ + if getattr(self, 'tlsStarted', 0): + self.sslBio = None + self.ssl = None + self.internalBio = None + self.networkBio = None + self.data = '' + self.encrypted = '' + 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 +
+
[docs] def startTLS(self, ctx): + """ + Start SSL/TLS. If this is not called, this instance just passes data + through untouched. + """ + # NOTE: This method signature must match the startTLS() method Twisted + # 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') + + self.ctx = ctx + + self.internalBio = m2.bio_new(m2.bio_s_bio()) + m2.bio_set_write_buf_size(self.internalBio, 0) + self.networkBio = _BioProxy(m2.bio_new(m2.bio_s_bio())) + m2.bio_set_write_buf_size(self.networkBio._ptr(), 0) + m2.bio_make_bio_pair(self.internalBio, self.networkBio._ptr()) + + self.sslBio = _BioProxy(m2.bio_new(m2.bio_f_ssl())) + + self.ssl = _SSLProxy(m2.ssl_new(self.ctx.ctx)) + + if self.isClient: + 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) + + # Need this for writes that are larger than BIO pair buffers + mode = m2.ssl_get_mode(self.ssl._ptr()) + m2.ssl_set_mode(self.ssl._ptr(), + mode | + m2.SSL_MODE_ENABLE_PARTIAL_WRITE | + m2.SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER) + + self.tlsStarted = 1 +
+
[docs] def write(self, data): + if not self.tlsStarted: + ProtocolWrapper.write(self, data) + return + + try: + encryptedData = self._encrypt(data) + ProtocolWrapper.write(self, encryptedData) + self.helloDone = 1 + 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 +
+
[docs] def writeSequence(self, data): + if not self.tlsStarted: + ProtocolWrapper.writeSequence(self, ''.join(data)) + return + + self.write(''.join(data)) +
+
[docs] def loseConnection(self): + # XXX Do we need to do m2.ssl_shutdown(self.ssl._ptr())? + ProtocolWrapper.loseConnection(self) +
+
[docs] def connectionMade(self): + ProtocolWrapper.connectionMade(self) + if self.tlsStarted and self.isClient and not self.helloDone: + self._clientHello() +
+
[docs] def dataReceived(self, data): + if not self.tlsStarted: + ProtocolWrapper.dataReceived(self, data) + return + + self.encrypted += data + + try: + while 1: + decryptedData = self._decrypt() + + self._check() + + encryptedData = self._encrypt() + ProtocolWrapper.write(self, encryptedData) + + ProtocolWrapper.dataReceived(self, decryptedData) + + if decryptedData == '' and encryptedData == '': + break + 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 +
+
[docs] def connectionLost(self, reason): + # type: (AnyStr) -> None + self.clear() + ProtocolWrapper.connectionLost(self, reason) +
+ def _check(self): + if not self.checked and m2.ssl_is_init_finished(self.ssl._ptr()): + x509 = m2.ssl_get_peer_cert(self.ssl._ptr()) + if x509 is not None: + x509 = X509.X509(x509, 1) + if self.isClient: + host = self.transport.addr[0] + else: + host = self.transport.getPeer().host + if not self.postConnectionCheck(x509, host): + raise SSLVerificationError('post connection check') + self.checked = 1 + + def _clientHello(self): + try: + # We rely on OpenSSL implicitly starting with client hello + # when we haven't yet established an SSL connection + encryptedData = self._encrypt(clientHello=1) + ProtocolWrapper.write(self, encryptedData) + self.helloDone = 1 + 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 = '' + 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 r <= 0: + assert(m2bio_should_retry(sslBioPtr)) + else: + assert self.checked + self.data = self.data[r:] + + pending = m2bio_ctrl_pending(networkBio) + if pending: + d = m2bio_read(networkBio, pending) + if d is not None: # This is strange, but d can be None + encryptedData += d + else: + assert(m2bio_should_retry(networkBio)) + else: + break + return encryptedData + + def _decrypt(self, data=''): + # XXX near mirror image of _encrypt - refactor + 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 + + while 1: + g = m2bio_ctrl_get_write_guarantee(networkBio) + if g > 0 and self.encrypted != '': + r = m2bio_write(networkBio, self.encrypted) + if r <= 0: + assert(m2bio_should_retry(networkBio)) + else: + self.encrypted = self.encrypted[r:] + + pending = m2bio_ctrl_pending(sslBioPtr) + if pending: + d = m2bio_read(sslBioPtr, pending) + if d is not None: # This is strange, but d can be None + decryptedData += d + else: + assert(m2bio_should_retry(sslBioPtr)) + else: + break + + return decryptedData
+
+ +
+
+
+
+
+ + +
+
+
+
+ + + + \ 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..73d515a --- /dev/null +++ b/doc/html/_modules/M2Crypto/SSL/cb.html @@ -0,0 +1,192 @@ + + + + + + + + + + M2Crypto.SSL.cb — M2Crypto documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for M2Crypto.SSL.cb

+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']
+
+
+
[docs]def ssl_verify_callback_stub(ssl_ctx_ptr, x509_ptr, errnum, errdepth, ok): + # Deprecated + return ok +
+unknown_issuer = [ # type: List[int] + m2.X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT, + 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, +] + + +
[docs]def ssl_verify_callback(ssl_ctx_ptr, x509_ptr, errnum, errdepth, ok): + # type: (bytes, bytes, int, int, int) -> int + # Deprecated + + 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.flush() + ok = 1 + # CRL checking goes here... + if ok: + if ssl_ctx.get_verify_depth() >= errdepth: + ok = 1 + else: + ok = 0 + return ok + +
+
[docs]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.
+
[docs]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: + state = "SSL connect" + 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))) + sys.stderr.flush() + return + + 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.flush() + else: + 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: + 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.flush() + return
+
+ +
+
+
+
+
+ + +
+
+
+
+ + + + \ 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..73709e3 --- /dev/null +++ b/doc/html/_modules/M2Crypto/SSL/ssl_dispatcher.html @@ -0,0 +1,139 @@ + + + + + + + + + + M2Crypto.SSL.ssl_dispatcher — M2Crypto documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for M2Crypto.SSL.ssl_dispatcher

+from __future__ import absolute_import
+
+"""SSL dispatcher
+
+Copyright (c) 1999-2002 Ng Pheng Siong. All rights reserved."""
+
+# Python
+import asyncore
+import socket
+
+# M2Crypto
+from M2Crypto import util  # noqa
+from M2Crypto.SSL.Connection import Connection
+from M2Crypto.SSL.Context import Context  # noqa
+
+__all__ = ['ssl_dispatcher']
+
+
+
[docs]class ssl_dispatcher(asyncore.dispatcher): # noqa + +
[docs] def create_socket(self, ssl_context): + # 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() +
+
[docs] def connect(self, addr): + # type: (util.AddrType) -> None + self.socket.setblocking(1) + self.socket.connect(addr) + self.socket.setblocking(0) +
+
[docs] def recv(self, buffer_size=4096): + # type: (int) -> bytes + """Receive data over SSL.""" + return self.socket.recv(buffer_size) +
+
[docs] def send(self, buffer): + # type: (bytes) -> int + """Send data over SSL.""" + return self.socket.send(buffer)
+
+ +
+
+
+
+
+ + +
+
+
+
+ + + + \ 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..849ae6d --- /dev/null +++ b/doc/html/_modules/M2Crypto/SSL/timeout.html @@ -0,0 +1,130 @@ + + + + + + + + + + M2Crypto.SSL.timeout — M2Crypto documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for M2Crypto.SSL.timeout

+"""Support for SSL socket timeouts.
+
+Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved.
+
+Copyright 2008 Heikki Toivonen. All rights reserved.
+"""
+
+__all__ = ['DEFAULT_TIMEOUT', 'timeout', 'struct_to_timeout', 'struct_size']
+
+import struct
+
+DEFAULT_TIMEOUT = 600  # type: int
+
+
+
[docs]class timeout: + + def __init__(self, sec=DEFAULT_TIMEOUT, microsec=0): + # type: (int, int) -> None + self.sec = sec + self.microsec = microsec + +
[docs] def pack(self): + return struct.pack('ll', self.sec, self.microsec) + +
+
[docs]def struct_to_timeout(binstr): + # type: (bytes) -> timeout + (s, ms) = struct.unpack('ll', binstr) + return timeout(s, ms) + +
+
[docs]def struct_size(): + # type: () -> int + return struct.calcsize('ll')
+
+ +
+
+
+
+
+ + +
+
+
+
+ + + + \ 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..4682200 --- /dev/null +++ b/doc/html/_modules/M2Crypto/X509.html @@ -0,0 +1,1504 @@ + + + + + + + + + + M2Crypto.X509 — M2Crypto documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for M2Crypto.X509

+from __future__ import absolute_import
+
+"""M2Crypto wrapper for OpenSSL X509 API.
+
+Copyright (c) 1999-2004 Ng Pheng Siong. All rights reserved.
+
+Portions created by Open Source Applications Foundation (OSAF) are
+Copyright (C) 2004-2007 OSAF. All Rights Reserved.
+Author: Heikki Toivonen
+"""
+
+import binascii
+import logging
+
+from M2Crypto import ASN1, BIO, EVP, Err, m2, util  # noqa
+if util.py27plus:
+    from typing import AnyStr, Optional  # noqa
+
+FORMAT_DER = 0
+FORMAT_PEM = 1
+
+log = logging.getLogger(__name__)
+
+
+
[docs]class X509Error(Exception): + pass +
+m2.x509_init(X509Error) + +V_OK = m2.X509_V_OK # type: int + + +
[docs]def x509_store_default_cb(ok, ctx): + # type: (int, X509_Store_Context) -> int + return ok + +
+
[docs]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 '': + raise ValueError('value must be precomputed hash') + ctx = m2.x509v3_set_nconf() + if ctx is None: + raise MemoryError( + 'Not enough memory when creating a new X509 extension') + 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 + +
+
[docs]class X509_Extension: # noqa + """ + 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 + +
[docs] def set_critical(self, critical=1): + # type: (int) -> int + """ + Mark this extension critical or noncritical. By default an + extension is not 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) +
+
[docs] def get_critical(self): + # type: () -> int + """ + Return whether or not this is a critical extension. + + :return: Nonzero if this is a critical extension. + """ + return m2.x509_extension_get_critical(self.x509_ext) +
+
[docs] def get_name(self): + # type: () -> str + """ + Get the extension name, for example 'subjectAltName'. + """ + return util.py3str(m2.x509_extension_get_name(self.x509_ext)) +
+
[docs] 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. + """ + buf = BIO.MemoryBuffer() + m2.x509_ext_print(buf.bio_ptr(), self.x509_ext, flag, indent) + return util.py3str(buf.read_all()) + +
+
[docs]class X509_Extension_Stack: # noqa + """ + 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! + """ + + 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)) + else: + self.stack = m2.sk_x509_extension_new_null() + self._pyfree = 1 + 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 + +
[docs] def push(self, x509_ext): + # type: (X509_Extension) -> int + """ + Push X509_Extension object onto 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()) + assert ret == len(self.pystack) + return ret +
+
[docs] def pop(self): + # type: () -> X509_Extension + """ + Pop X509_Extension object from the stack. + + :return: X509_Extension popped + """ + x509_ext_ptr = m2.sk_x509_extension_pop(self.stack) + if x509_ext_ptr is None: + assert len(self.pystack) == 0 + return None + return self.pystack.pop() + +
+
[docs]class X509_Name_Entry: # noqa + """ + 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 + +
[docs] 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()) +
+
[docs] def set_data(self, data, type=ASN1.MBSTRING_ASC): + # 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, util.py3bytes(data)) +
+
[docs] def get_object(self): + # type: () -> ASN1.ASN1_Object + return ASN1.ASN1_Object( + m2.x509_name_entry_get_object(self.x509_name_entry)) +
+
[docs] def get_data(self): + # type: () -> ASN1.ASN1_String + return ASN1.ASN1_String( + m2.x509_name_entry_get_data(self.x509_name_entry)) +
+
[docs] 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) + +
+
[docs]class X509_Name: # noqa + """ + 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 + } + + 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._pyfree = 1 + + def __del__(self): + # type: () -> None + if getattr(self, '_pyfree', 0): + self.m2_x509_name_free(self.x509_name) + + def __str__(self): + # 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 util.py3str(m2.x509_name_by_nid(self.x509_name, self.nid[attr])) + + if attr in self.__dict__: + return self.__dict__[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], + util.py3bytes(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 range(self.entry_count()): + yield self[i] + + def _ptr(self): + assert m2.x509_name_type_check(self.x509_name), \ + "'x509_name' type error" + return self.x509_name + +
[docs] def add_entry_by_txt(self, 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, + util.py3bytes(field), type, + entry, len, loc, set) +
+
[docs] def entry_count(self): + # type: () -> int + return m2.x509_name_entry_count(self.x509_name) +
+
[docs] 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 + + while True: + lastpos = m2.x509_name_get_index_by_nid(self.x509_name, nid, + lastpos) + if lastpos == -1: + break + + ret.append(self[lastpos]) + + return ret +
+
[docs] 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 + by this many spaces. + :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() + m2.x509_name_print_ex(buf.bio_ptr(), self.x509_name, indent, flags) + return util.py3str(buf.read_all()) +
+
[docs] def as_der(self): + # type: () -> bytes + assert m2.x509_name_type_check(self.x509_name), \ + "'x509_name' type error" + return m2.x509_name_get_der(self.x509_name) +
+
[docs] def as_hash(self): + # type: () -> int + assert m2.x509_name_type_check(self.x509_name), \ + "'x509_name' type error" + return m2.x509_name_hash(self.x509_name) + +
+
[docs]class X509: + """ + X.509 Certificate + """ + + 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._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 + +
[docs] def as_text(self): + # type: () -> str + assert m2.x509_type_check(self.x509), "'x509' type error" + buf = BIO.MemoryBuffer() + m2.x509_print(buf.bio_ptr(), self.x509) + return util.py3str(buf.read_all()) +
+
[docs] def as_der(self): + # type: () -> bytes + assert m2.x509_type_check(self.x509), "'x509' type error" + return m2.i2d_x509(self.x509) +
+
[docs] def as_pem(self): + # type: () -> bytes + buf = BIO.MemoryBuffer() + m2.x509_write_pem(buf.bio_ptr(), self.x509) + return buf.read_all() +
+
[docs] def save_pem(self, filename): + # type: (AnyStr) -> int + """ + :param filename: name of the file to be loaded + :return: 1 for success or 0 for failure + """ + with BIO.openfile(filename, 'wb') as bio: + return m2.x509_write_pem(bio.bio_ptr(), self.x509) +
+
[docs] def save(self, filename, format=FORMAT_PEM): + # type: (AnyStr, int) -> int + """ + Saves X.509 certificate to a file. Default output + format is PEM. + + :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 + """ + 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") +
+
[docs] def set_version(self, version): + # type: (int) -> int + """ + Set version of the certificate. + + :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) +
+
[docs] 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_time._ptr()) +
+
[docs] 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_time._ptr()) +
+
[docs] 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) +
+
[docs] 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) +
+
[docs] def get_version(self): + # type: () -> int + assert m2.x509_type_check(self.x509), "'x509' type error" + return m2.x509_get_version(self.x509) +
+
[docs] 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) +
+
[docs] def set_serial_number(self, serial): + # type: (ASN1.ASN1_Integer) -> int + """ + Set 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 + # is C pointer to x509's internal serial number. + 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) +
+
[docs] def get_not_before(self): + # type: () -> ASN1.ASN1_TIME + assert m2.x509_type_check(self.x509), "'x509' type error" + return ASN1.ASN1_TIME(m2.x509_get_not_before(self.x509)) +
+
[docs] def get_not_after(self): + # type: () -> ASN1.ASN1_TIME + assert m2.x509_type_check(self.x509), "'x509' type error" + 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 +
+
[docs] 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) +
+
[docs] def set_pubkey(self, pkey): + # type: (EVP.PKey) -> int + """ + Set the public key for the certificate + + :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) +
+
[docs] 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)) +
+
[docs] def set_issuer(self, name): + # type: (X509_Name) -> int + """ + Set issuer name. + + :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) +
+
[docs] 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)) +
+
[docs] def set_subject(self, name): + # type: (X509_Name) -> int + """ + Set subject name. + + :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) +
+
[docs] def add_ext(self, ext): + # type: (X509_Extension) -> int + """ + Add X509 extension to this certificate. + + :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) +
+
[docs] def get_ext(self, name): + # type: (str) -> X509_Extension + """ + Get X509 extension by name. + + :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 = util.py3bytes(name) + for i in range(m2.x509_get_ext_count(x509)): + ext_ptr = m2x509_get_ext(x509, i) + if m2x509_extension_get_name(ext_ptr) == name: + return X509_Extension(ext_ptr, _pyfree=0) + + raise LookupError +
+
[docs] def get_ext_at(self, index): + # type: (int) -> X509_Extension + """ + Get X509 extension by index. + + :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) +
+
[docs] def get_ext_count(self): + # type: () -> int + """ + Get X509 extension count. + """ + return m2.x509_get_ext_count(self.x509) +
+
[docs] def sign(self, pkey, md): + # type: (EVP.PKey, str) -> int + """ + Sign the certificate. + + :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) + return m2.x509_sign(self.x509, pkey.pkey, mda()) +
+
[docs] 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) +
+
[docs] 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 m2.x509_check_ca(self.x509) +
+
[docs] 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. + """ + return m2.x509_check_purpose(self.x509, id, ca) +
+
[docs] 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. + """ + der = self.as_der() + md = EVP.MessageDigest(md) + md.update(der) + digest = md.final() + return util.py3str(binascii.hexlify(digest).upper()) + +
+
[docs]def load_cert(file, format=FORMAT_PEM): + # type: (AnyStr, int) -> X509 + """ + Load certificate from file. + + :param file: Name of file containing certificate in either DER or + PEM format. + + :param format: Describes the format of the file to be loaded, + either PEM or DER. + + :return: M2Crypto.X509.X509 object. + """ + 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()) + 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") + +
+
[docs]def load_cert_bio(bio, format=FORMAT_PEM): + # type: (BIO.BIO, int) -> X509 + """ + Load certificate from a bio. + + :param bio: BIO pointing at 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) + + :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()) + return X509(cptr, _pyfree=1) + +
+
[docs]def load_cert_string(string, format=FORMAT_PEM): + # type: (AnyStr, int) -> X509 + """ + Load certificate from a string. + + :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) + + :return: M2Crypto.X509.X509 object. + """ + string = util.py3bytes(string) + bio = BIO.MemoryBuffer(string) + return load_cert_bio(bio, format) + +
+
[docs]def load_cert_der_string(string): + # type: (AnyStr) -> X509 + """ + Load certificate from a string. + + :param string: String containing a certificate in DER format. + + :return: M2Crypto.X509.X509 object. + """ + string = util.py3bytes(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) + +
+
[docs]class X509_Store_Context: # noqa + """ + 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): + # 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 + +
[docs] 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. + """ + return X509(m2.x509_store_ctx_get_current_cert(self.ctx), _pyfree=0) +
+
[docs] def get_error(self): + # type: () -> int + """ + Get error code. + """ + return m2.x509_store_ctx_get_error(self.ctx) +
+
[docs] def get_error_depth(self): + # type: () -> int + """ + Get error depth. + """ + return m2.x509_store_ctx_get_error_depth(self.ctx) +
+
[docs] def get1_chain(self): + # type: () -> X509_Stack + """ + Get certificate chain. + + :return: Reference counted (i.e. safe to use even after the store + context goes away) stack of certificates in the chain. + """ + return X509_Stack(m2.x509_store_ctx_get1_chain(self.ctx), 1, 1) + +
+
[docs]class X509_Store: # noqa + """ + 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) + + def _ptr(self): + return self.store + +
[docs] def load_info(self, file): + # type: (AnyStr) -> int + """ + :param file: filename + + :return: 1 on success, 0 on failure + """ + ret = m2.x509_store_load_locations(self.store, file) + if ret < 1: + raise X509Error(Err.get_error()) + return ret +
+ load_locations = load_info + +
[docs] def add_x509(self, x509): + # type: (X509) -> int + assert isinstance(x509, X509) + return m2.x509_store_add_cert(self.store, x509._ptr()) +
+
[docs] 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 + +
+
[docs]class X509_Stack: # noqa + """ + 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! + """ + + 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 + num = m2.sk_x509_num(self.stack) + for i in range(num): + self.pystack.append(X509(m2.sk_x509_value(self.stack, i), + _pyfree=_pyfree_x509)) + else: + self.stack = m2.sk_x509_new_null() + self._pyfree = 1 + 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) + + def _ptr(self): + return self.stack + +
[docs] 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. + """ + assert isinstance(x509, X509) + self.pystack.append(x509) + ret = m2.sk_x509_push(self.stack, x509._ptr()) + assert ret == len(self.pystack) + return ret +
+
[docs] 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. + """ + x509_ptr = m2.sk_x509_pop(self.stack) + if x509_ptr is None: + assert len(self.pystack) == 0 + return None + return self.pystack.pop() +
+
[docs] def as_der(self): + # type: () -> bytes + """ + Return the stack as a DER encoded string + """ + return m2.get_der_encoding_stack(self.stack) + +
+
[docs]def new_stack_from_der(der_string): + # type: (bytes) -> X509_Stack + """ + Create a new X509_Stack from DER string. + + :return: X509_Stack + """ + der_string = util.py3bytes(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) + +
+
[docs]class Request: + """ + X509 Certificate 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) + +
[docs] def as_text(self): + # type: () -> str + buf = BIO.MemoryBuffer() + m2.x509_req_print(buf.bio_ptr(), self.req) + return util.py3str(buf.read_all()) +
+
[docs] def as_pem(self): + # type: () -> bytes + buf = BIO.MemoryBuffer() + m2.x509_req_write_pem(buf.bio_ptr(), self.req) + return buf.read_all() +
+
[docs] def as_der(self): + # type: () -> bytes + buf = BIO.MemoryBuffer() + m2.i2d_x509_req_bio(buf.bio_ptr(), self.req) + return buf.read_all() +
+
[docs] def save_pem(self, filename): + # type: (AnyStr) -> int + with BIO.openfile(filename, 'wb') as bio: + return m2.x509_req_write_pem(bio.bio_ptr(), self.req) +
+
[docs] def save(self, filename, format=FORMAT_PEM): + # type: (AnyStr, int) -> int + """ + Saves X.509 certificate request to a file. Default output + format is PEM. + + :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. + """ + 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") +
+
[docs] def get_pubkey(self): + # type: () -> EVP.PKey + """ + Get the public key for the request. + + :return: Public key from the request. + """ + return EVP.PKey(m2.x509_req_get_pubkey(self.req), _pyfree=1) +
+
[docs] def set_pubkey(self, pkey): + # type: (EVP.PKey) -> int + """ + Set the public key for the request. + + :param pkey: Public key + + :return: Return 1 for success and 0 for failure. + """ + return m2.x509_req_set_pubkey(self.req, pkey.pkey) +
+
[docs] def get_version(self): + # type: () -> int + """ + Get version. + + :return: Returns version. + """ + return m2.x509_req_get_version(self.req) +
+
[docs] def set_version(self, version): + # type: (int) -> int + """ + Set version. + + :param version: Version number. + :return: Returns 0 on failure. + """ + return m2.x509_req_set_version(self.req, version) +
+
[docs] def get_subject(self): + # type: () -> X509_Name + return X509_Name(m2.x509_req_get_subject_name(self.req)) +
+
[docs] def set_subject_name(self, name): + # type: (X509_Name) -> int + """ + Set subject name. + + :param name: subjectName field. + :return: 1 for success and 0 for failure + """ + return m2.x509_req_set_subject_name(self.req, name.x509_name) +
+ set_subject = set_subject_name + +
[docs] def add_extensions(self, ext_stack): + # type: (X509_Extension_Stack) -> int + """ + Add X509 extensions to this request. + + :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()) +
+
[docs] 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) +
+
[docs] 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) + return m2.x509_req_sign(self.req, pkey.pkey, mda()) + +
+
[docs]def load_request(file, format=FORMAT_PEM): + # type: (AnyStr, int) -> Request + """ + Load certificate request from file. + + :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. + """ + 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") + + if cptr is None: + raise X509Error(Err.get_error()) + return Request(cptr, 1) + +
+
[docs]def load_request_bio(bio, format=FORMAT_PEM): + # type: (BIO.BIO, int) -> Request + """ + Load certificate request from a bio. + + :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()) + return Request(cptr, _pyfree=1) + +
+
[docs]def load_request_string(string, format=FORMAT_PEM): + # type: (AnyStr, int) -> Request + """ + Load certificate request from a string. + + :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) + + :return: M2Crypto.X509.Request object. + """ + string = util.py3bytes(string) + bio = BIO.MemoryBuffer(string) + return load_request_bio(bio, format) + +
+
[docs]def load_request_der_string(string): + # type: (AnyStr) -> Request + """ + Load certificate request from a string. + + :param string: String containing a certificate request in DER format. + :return: M2Crypto.X509.Request object. + """ + string = util.py3bytes(string) + bio = BIO.MemoryBuffer(string) + return load_request_bio(bio, FORMAT_DER) + +
+
[docs]class CRL: + """ + X509 Certificate Revocation List + """ + + 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) + +
[docs] def as_text(self): + # type: () -> str + """ + Return CRL in PEM format in a string. + + :return: String containing the CRL in PEM format. + """ + buf = BIO.MemoryBuffer() + m2.x509_crl_print(buf.bio_ptr(), self.crl) + return util.py3str(buf.read_all()) + +
+
[docs]def load_crl(file): + # type: (AnyStr) -> CRL + """ + Load CRL from file. + + :param file: Name of file containing CRL in PEM format. + + :return: M2Crypto.X509.CRL object. + """ + with BIO.openfile(file) as f: + cptr = m2.x509_crl_read_pem(f.bio_ptr()) + + if cptr is None: + raise X509Error(Err.get_error()) + return CRL(cptr, 1)
+
+ +
+
+
+
+
+ + +
+
+
+
+ + + + \ 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..d1877a1 --- /dev/null +++ b/doc/html/_modules/M2Crypto/ftpslib.html @@ -0,0 +1,185 @@ + + + + + + + + + + M2Crypto.ftpslib — M2Crypto documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for M2Crypto.ftpslib

+from __future__ import absolute_import
+
+"""M2Crypto client-side FTP/TLS.
+
+This implementation complies with draft-murray-auth-ftp-ssl-07.txt.
+
+Example:
+
+>>> from M2Crypto import ftpslib
+>>> f = ftpslib.FTP_TLS()
+>>> f.connect('', 9021)
+'220 spinnaker.dyndns.org M2Crypto (Medusa) FTP/TLS server v0.07 ready.'
+>>> f.auth_tls()
+>>> f.set_pasv(0)
+>>> f.login('ftp', 'ngps@')
+'230 Ok.'
+>>> f.retrlines('LIST')
+-rw-rw-r--   1 0        198          2326 Jul  3  1996 apache_pb.gif
+drwxrwxr-x   7 0        198          1536 Oct 10  2000 manual
+drwxrwxr-x   2 0        198           512 Oct 31  2000 modpy
+drwxrwxr-x   2 0        198           512 Oct 31  2000 bobo
+drwxr-xr-x   2 0        198         14336 May 28 15:54 postgresql
+drwxr-xr-x   4 100      198           512 May 16 17:19 home
+drwxr-xr-x   7 100      100          3584 Sep 23  2000 openacs
+drwxr-xr-x  10 0        0             512 Aug  5  2000 python1.5
+-rw-r--r--   1 100      198           326 Jul 29 03:29 index.html
+drwxr-xr-x  12 0        0             512 May 31 17:08 python2.1
+'226 Transfer complete'
+>>> f.quit()
+'221 Goodbye.'
+>>>
+
+
+Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
+
+# We want to import whole stdlib ftplib objects, because our users want
+# to use them.
+from ftplib import *  # noqa
+
+# M2Crypto
+from M2Crypto import SSL
+
+
+
[docs]class FTP_TLS(FTP): # noqa + + """Python OO interface to client-side FTP/TLS.""" + + def __init__(self, host=None, ssl_ctx=None): + """Initialise the client. If 'host' is supplied, connect to it.""" + if ssl_ctx is not None: + self.ssl_ctx = ssl_ctx + else: + self.ssl_ctx = SSL.Context() + FTP.__init__(self, host) + self.prot = 0 + +
[docs] def auth_tls(self): + """Secure the control connection per AUTH TLS, aka AUTH TLS-C.""" + self.voidcmd('AUTH TLS') + s = SSL.Connection(self.ssl_ctx, self.sock) + s.setup_ssl() + s.set_connect_state() + s.connect_ssl() + self.sock = s + self.file = self.sock.makefile() +
+
[docs] def auth_ssl(self): + """Secure the control connection per AUTH SSL, aka AUTH TLS-P.""" + raise NotImplementedError +
+
[docs] def prot_p(self): + """Set up secure data connection.""" + self.voidcmd('PBSZ 0') + self.voidcmd('PROT P') + self.prot = 1 +
+
[docs] def prot_c(self): + """Set up data connection in the clear.""" + self.voidcmd('PROT C') + self.prot = 0 +
+
[docs] def ntransfercmd(self, cmd, rest=None): + """Initiate a data transfer.""" + conn, size = FTP.ntransfercmd(self, cmd, rest) + if self.prot: + conn = SSL.Connection(self.ssl_ctx, conn) + conn.setup_ssl() + conn.set_connect_state() + conn.set_session(self.sock.get_session()) + conn.connect_ssl() + return conn, size
+
+ +
+
+
+
+
+ + +
+
+
+
+ + + + \ 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..e8ab639 --- /dev/null +++ b/doc/html/_modules/M2Crypto/httpslib.html @@ -0,0 +1,355 @@ + + + + + + + + + + M2Crypto.httpslib — M2Crypto documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for M2Crypto.httpslib

+from __future__ import absolute_import
+
+"""M2Crypto support for Python's httplib.
+
+Copyright (c) 1999-2004 Ng Pheng Siong. All rights reserved."""
+
+import base64
+import socket
+
+from M2Crypto import SSL, six, util
+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 util.py27plus:
+    from typing import Any, AnyStr, Callable, Dict, List, Optional  # noqa
+
+
+
[docs]class HTTPSConnection(HTTPConnection): + + """ + This class allows communication via SSL using M2Crypto. + """ + + default_port = HTTPS_PORT + + def __init__(self, host, port=None, strict=None, **ssl): + # type: (str, Optional[int], Optional[bool], **Dict[Any, 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: %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() + HTTPConnection.__init__(self, host, port, strict) + +
[docs] def connect(self): + # 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) + 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 +
+
[docs] 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 + # business is over and gc kicks in. + # + # XXX Long-running callers beware leakage. + # + # XXX 05-Jan-2002: This module works with Python 2.2, + # XXX but I've not investigated if the above conditions + # XXX remain. + pass +
+
[docs] def get_session(self): + # type: () -> SSL.Session.Session + return self.sock.get_session() +
+
[docs] def set_session(self, session): + # type: (SSL.Session.Session) -> None + self.session = session + +
+
[docs]class ProxyHTTPSConnection(HTTPSConnection): + """ + An HTTPS Connection that uses a proxy and the CONNECT request. + + 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. + + Finally, the actual request is sent over the SSL connection tunneling + through the proxy. + """ + + _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): + # type: (str, Optional[int], Optional[bool], Optional[AnyStr], Optional[AnyStr], **Dict[Any, Any]) -> None + """ + Create the ProxyHTTPSConnection object. + + :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.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 + +
[docs] def putrequest(self, method, url, skip_host=0, skip_accept_encoding=0): + # 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 + try: + username_password, host_port = netloc.split('@') + except ValueError: + host_port = netloc + + try: + host, port_s = host_port.split(':') + port = int(port_s) + except ValueError: + host = host_port + # try to get port from proto + try: + port = self._ports[proto] + except KeyError: + raise ValueError("unknown protocol for: %s" % url) + + self._real_host = host # type: str + self._real_port = port # type: int + rest = urlunsplit((None, None, path, query, fragment)) + HTTPSConnection.putrequest(self, method, rest, skip_host, + skip_accept_encoding) +
+
[docs] 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 + if header.lower() == self._AUTH_HEADER.lower(): + self._proxy_auth = value + else: + HTTPSConnection.putheader(self, header, value) +
+
[docs] def endheaders(self, *args, **kwargs): + # type: (*List[Any], **Dict[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, *args, **kwargs) +
+
[docs] def connect(self): + # type: () -> None + HTTPConnection.connect(self) + + # 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 + self.close() + 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 + "\r\n" + return util.py3bytes(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() + self.sock.set_connect_state() + 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 util.py3bytes("Basic %s" % enc_userpass)
+
+ +
+
+
+
+
+ + +
+
+
+
+ + + + \ No newline at end of file diff --git a/doc/html/_modules/M2Crypto/m2crypto.html b/doc/html/_modules/M2Crypto/m2crypto.html new file mode 100644 index 0000000..00852dc --- /dev/null +++ b/doc/html/_modules/M2Crypto/m2crypto.html @@ -0,0 +1,172 @@ + + + + + + + + + + M2Crypto.m2crypto — M2Crypto documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for M2Crypto.m2crypto

+# 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
+
+ +
+
+
+
+
+ + +
+
+
+
+ + + + \ 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..44d3ac7 --- /dev/null +++ b/doc/html/_modules/M2Crypto/m2urllib.html @@ -0,0 +1,207 @@ + + + + + + + + + + M2Crypto.m2urllib — M2Crypto documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for M2Crypto.m2urllib

+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."""
+
+from M2Crypto import SSL, httpslib, six, util
+
+from M2Crypto.six.moves.urllib_response import addinfourl
+if util.py27plus:
+    from typing import AnyStr, Optional  # noqa
+
+# 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
+
+
+
[docs]def open_https(self, url, data=None, ssl_context=None): + # type: (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 ssl_context is not None and isinstance(ssl_context, SSL.Context): + self.ctx = ssl_context + else: + self.ctx = SSL.Context() + user_passwd = None + 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.username + 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 urltype.lower() != 'http': + realhost = None + else: + 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 = base64.encodestring(user_passwd).strip() + else: + auth = None + # Start here! + h = httpslib.HTTPSConnection(host=host, ssl_context=self.ctx) + # h.set_debuglevel(1) + # Stop here! + if data is not None: + h.putrequest('POST', selector) + h.putheader('Content-type', 'application/x-www-form-urlencoded') + 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: + 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 addinfourl(fp, resp.msg, "https:" + url) + # Stop again. + +# Minor brain surgery.
+URLopener.open_https = open_https +
+ +
+
+
+
+
+ + +
+
+
+
+ + + + \ 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..2b18152 --- /dev/null +++ b/doc/html/_modules/M2Crypto/m2urllib2.html @@ -0,0 +1,274 @@ + + + + + + + + + + M2Crypto.m2urllib2 — M2Crypto documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for M2Crypto.m2urllib2

+from __future__ import absolute_import
+
+"""
+M2Crypto enhancement to Python's urllib2 for handling
+'https' url's.
+
+Code from urllib2 is Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+Python Software Foundation; All Rights Reserved
+
+Summary of changes:
+ - Use an HTTPSProxyConnection if the request is going through a proxy.
+ - Add the SSL context to the https connection when performing https_open.
+ - Add the M2Crypto HTTPSHandler when building a default opener.
+"""
+
+import socket
+
+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(mother_class):  # noqa
+    """socket._fileobject that propagates self.close() to the socket.
+
+    Python 2.5 provides this as socket._fileobject(sock, close=True).
+    """
+
+# for python 3
+try:
+    AbstractHTTPHandler
+except NameError:
+    # somehow this won't get imported by the import * above
+    import urllib.request
+    AbstractHTTPHandler = urllib.request.AbstractHTTPHandler
+
+
+
[docs]class HTTPSHandler(AbstractHTTPHandler): + def __init__(self, ssl_context=None): + # type: (SSL.Context) -> None + AbstractHTTPHandler.__init__(self) + + if ssl_context is not None: + assert isinstance(ssl_context, SSL.Context), ssl_context + self.ctx = ssl_context + else: + self.ctx = SSL.Context() + + # Copied from urllib2, so we can set the ssl context. +
[docs] 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 + """ + # 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 = url_parse(full_url)[1] + + if target_host != host: + request_uri = urldefrag(full_url)[0] + h = httpslib.ProxyHTTPSConnection(host=host, ssl_context=self.ctx) + else: + 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) + + headers = dict(req.headers) + headers.update(req.unredirected_hdrs) + # We want to make an HTTP/1.1 request, but the addinfourl + # class isn't prepared to deal with a persistent connection. + # It will try to read all remaining data from the socket, + # which will block while the server waits for the next request. + # So make sure the connection gets closed after the (only) + # request. + headers["Connection"] = "close" + try: + h.request(req.get_method(), request_uri, req.data, headers) + r = h.getresponse() + except socket.error as err: # XXX what error? + raise URLError(err) + + # Pick apart the HTTPResponse object to get the addinfourl + # object initialized properly. + + # Wrap the HTTPResponse object in socket's file object adapter + # for Windows. That adapter calls recv(), so delegate recv() + # to read(). This weird wrapping allows the returned object to + # have readline() and readlines() methods. + + r.recv = r.read + fp = socket._fileobject(r, close=True) + + 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
+
[docs]def build_opener(ssl_context=None, *handlers): + # type: (Optional[SSL.Context], *List[object]) -> OpenerDirector + """Create an opener object from a list of handlers. + + The opener will use several default handlers, including support + for HTTP and FTP. + + If any of the handlers passed as arguments are subclasses of the + default handlers, the default handlers will not be used. + """ + + def isclass(obj): + return isinstance(obj, type) or hasattr(obj, "__bases__") + + opener = OpenerDirector() + default_classes = [ProxyHandler, UnknownHandler, HTTPHandler, + HTTPDefaultErrorHandler, HTTPRedirectHandler, + FTPHandler, FileHandler, HTTPErrorProcessor] + skip = [] + for klass in default_classes: + for check in handlers: + if isclass(check): + if issubclass(check, klass): + skip.append(klass) + elif isinstance(check, klass): + skip.append(klass) + for klass in skip: + default_classes.remove(klass) + + for klass in default_classes: + opener.add_handler(klass()) + + # Add the HTTPS handler with ssl_context + if HTTPSHandler not in skip: + opener.add_handler(HTTPSHandler(ssl_context)) + + for h in handlers: + if isclass(h): + h = h() + opener.add_handler(h) + return opener
+
+ +
+
+
+
+
+ + +
+
+
+
+ + + + \ 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..7869083 --- /dev/null +++ b/doc/html/_modules/M2Crypto/m2xmlrpclib.html @@ -0,0 +1,173 @@ + + + + + + + + + + M2Crypto.m2xmlrpclib — M2Crypto documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for M2Crypto.m2xmlrpclib

+from __future__ import absolute_import
+
+"""M2Crypto enhancement to xmlrpclib.
+
+Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
+
+import base64
+
+import M2Crypto
+
+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__
+
+
+
[docs]class SSL_Transport(Transport): # noqa + + user_agent = "M2Crypto_XMLRPC/%s - %s" % (__version__, + Transport.user_agent) + + def __init__(self, ssl_context=None, *args, **kw): + # type: (Optional[SSL.Context], *List[Any], **Dict[Any, Any]) -> None + Transport.__init__(self, *args, **kw) + if ssl_context is None: + self.ssl_ctx = SSL.Context() + else: + self.ssl_ctx = ssl_context + +
[docs] 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.HTTPSConnection(_host, int(_port), + ssl_context=self.ssl_ctx) + if verbose: + h.set_debuglevel(1) + + # What follows is as in xmlrpclib.Transport. (Except the authz bit.) + h.putrequest("POST", handler) + + # required by HTTP/1.1 + h.putheader("Host", _host) + + # required by XML-RPC + h.putheader("User-Agent", self.user_agent) + h.putheader("Content-Type", "text/xml") + h.putheader("Content-Length", str(len(request_body))) + + # Authorisation. + if user_passwd is not None: + auth = base64.encodestring(user_passwd).strip() + h.putheader('Authorization', 'Basic %s' % auth) + + h.endheaders() + + if request_body: + h.send(request_body) + + errcode, errmsg, headers = h.getreply() + + if errcode != 200: + raise ProtocolError( + host + handler, + errcode, errmsg, + headers + ) + + self.verbose = verbose + return self.parse_response(h.getfile())
+
+ +
+
+
+
+
+ + +
+
+
+
+ + + + \ 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..41edb54 --- /dev/null +++ b/doc/html/_modules/M2Crypto/threading.html @@ -0,0 +1,119 @@ + + + + + + + + + + M2Crypto.threading — M2Crypto documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for M2Crypto.threading

+from __future__ import absolute_import
+
+"""
+M2Crypto threading support, required for multithreaded applications.
+
+Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
+
+# M2Crypto
+from M2Crypto import m2
+
+
+
[docs]def init(): + # type: () -> None + """ + Initialize threading support. + """ + m2.threading_init() + +
+
[docs]def cleanup(): + # type: () -> None + """ + End and cleanup threading support. + """ + m2.threading_cleanup()
+
+ +
+
+
+
+
+ + +
+
+
+
+ + + + \ 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..0667b9f --- /dev/null +++ b/doc/html/_modules/M2Crypto/util.html @@ -0,0 +1,223 @@ + + + + + + + + + + M2Crypto.util — M2Crypto documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for M2Crypto.util

+from __future__ import absolute_import
+"""
+    M2Crypto utility routines.
+
+    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
+
+# 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 m2, six
+if py27plus:
+    from typing import AnyStr, Tuple, Union  # noqa
+    # see https://github.com/python/typeshed/issues/222
+    AddrType = Union[Tuple[str, int], str]
+
+log = logging.getLogger('util')
+
+
+
[docs]class UtilError(Exception): + pass +
+m2.util_init(UtilError) + + +
[docs]def pkcs5_pad(data, blklen=8): + # type: (str, int) -> str + pad = (8 - (len(data) % 8)) + return data + chr(pad) * pad + +
+
[docs]def pkcs7_pad(data, blklen): + # type: (str, int) -> str + if blklen > 255: + raise ValueError('illegal block size') + pad = (blklen - (len(data) % blklen)) + return data + chr(pad) * pad + + +# before the introduction of py3{bytes,str}, python2 code +# was just using args as-is
+if six.PY2: + def py3bytes(x): + # type: (AnyStr) -> Optional[bytes,bytearray] + if isinstance(x, unicode): + return x.encode('utf8') + elif isinstance(x, (bytearray, str)): + return x + else: + raise TypeError('No string argument provided') + + def py3str(x): + # type: (Optional[str,bytearray]) -> str + if isinstance(x, bytearray): + return str(x) + elif isinstance(x, (str, unicode)): + return x + else: + raise TypeError('No string argument provided') +else: +
[docs] def py3bytes(x): + # type: (AnyStr) -> Optional[bytes,bytearray] + if isinstance(x, str): + return bytes(x, encoding='utf8') + elif isinstance(x, (bytes, bytearray)): + return x + else: + raise TypeError('No string argument provided') +
+
[docs] def py3str(x): + # type: (Optional[AnyStr,bytearray]) -> str + if isinstance(x, (bytes, bytearray)): + return x.decode('utf8') + elif isinstance(x, str): + return x + else: + raise TypeError('No string argument provided') + +
+
[docs]def bin_to_hex(b): + # type: (bytes) -> str + return py3str(binascii.b2a_base64(b)[:-1]) + +
+
[docs]def octx_to_num(x): + # type: (bytes) -> int + return int(binascii.hexlify(x), 16) + +
+
[docs]def genparam_callback(p, n, out=sys.stdout): + # type: (int, Any, file) -> None + ch = ['.', '+', '*', '\n'] + out.write(ch[p]) + out.flush() + +
+
[docs]def quiet_genparam_callback(p, n, out): + # type: (Any, Any, Any) -> None + pass + +
+
[docs]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) + if v: + p2 = getpass(prompt2) + if p1 == p2: + break + else: + break + except KeyboardInterrupt: + return None + return p1 + +
+
[docs]def no_passphrase_callback(*args): + # type: (List[Any]) -> str + return ''
+
+ +
+
+
+
+
+ + +
+
+
+
+ + + + \ 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..872a977 --- /dev/null +++ b/doc/html/_modules/index.html @@ -0,0 +1,129 @@ + + + + + + + + + + Overview: module code — M2Crypto documentation + + + + + + + + + + + + + +
+ +
+
+ + +
+
+
+
+ + + + \ No newline at end of file diff --git a/doc/html/_sources/M2Crypto.PGP.txt b/doc/html/_sources/M2Crypto.PGP.txt new file mode 100644 index 0000000..5396b5d --- /dev/null +++ b/doc/html/_sources/M2Crypto.PGP.txt @@ -0,0 +1,51 @@ +PGP Package +=========== + +:mod:`PGP` Package +------------------ + +.. automodule:: M2Crypto.PGP + :members: + :undoc-members: + :show-inheritance: + +:mod:`PublicKey` Module +----------------------- + +.. automodule:: M2Crypto.PGP.PublicKey + :members: + :undoc-members: + :show-inheritance: + +:mod:`PublicKeyRing` Module +--------------------------- + +.. automodule:: M2Crypto.PGP.PublicKeyRing + :members: + :undoc-members: + :show-inheritance: + +:mod:`RSA` Module +----------------- + +.. automodule:: M2Crypto.PGP.RSA + :members: + :undoc-members: + :show-inheritance: + +:mod:`constants` Module +----------------------- + +.. automodule:: M2Crypto.PGP.constants + :members: + :undoc-members: + :show-inheritance: + +:mod:`packet` Module +-------------------- + +.. automodule:: M2Crypto.PGP.packet + :members: + :undoc-members: + :show-inheritance: + diff --git a/doc/html/_sources/M2Crypto.SSL.txt b/doc/html/_sources/M2Crypto.SSL.txt new file mode 100644 index 0000000..233c1eb --- /dev/null +++ b/doc/html/_sources/M2Crypto.SSL.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.txt b/doc/html/_sources/M2Crypto.txt new file mode 100644 index 0000000..31a03ad --- /dev/null +++ b/doc/html/_sources/M2Crypto.txt @@ -0,0 +1,219 @@ +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.PGP + M2Crypto.SSL + diff --git a/doc/html/_sources/ZServerSSL-HOWTO.txt b/doc/html/_sources/ZServerSSL-HOWTO.txt new file mode 100644 index 0000000..91ef5af --- /dev/null +++ b/doc/html/_sources/ZServerSSL-HOWTO.txt @@ -0,0 +1,239 @@ +:orphan: + +.. _zserverssl-howto: + +ZServerSSL-HOWTO +################ + +:author: Pheng Siong Ng +: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) + ... + +:: + + + + Zope + +

NgPS Desktop Portal

+ +   So many hacks.
+   So little time.
+ +

Link Farm

+ + +
Powered by Zope + +:: + + >>> 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.txt b/doc/html/_sources/howto.ca.txt new file mode 100644 index 0000000..e950b59 --- /dev/null +++ b/doc/html/_sources/howto.ca.txt @@ -0,0 +1,370 @@ +:orphan: + +.. _howto-ca: + +HOWTO: Creating your own CA with OpenSSL +######################################## + +:author: Pheng Siong Ng +: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 `__ 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) + + 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: + Verifying password - Enter PEM pass phrase: + ----- + 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: + Verifying password - Enter PEM pass phrase: + ----- + 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 []: + An optional company name []: + 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: + 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: + 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 `__ using +`M2Crypto `__. + diff --git a/doc/html/_sources/howto.smime.txt b/doc/html/_sources/howto.smime.txt new file mode 100644 index 0000000..715e7c4 --- /dev/null +++ b/doc/html/_sources/howto.smime.txt @@ -0,0 +1,778 @@ +:orphan: + +.. _howto-smime: + +HOWTO: Programming S/MIME in Python with M2Crypto +================================================= + +:author: Pheng Siong Ng +:copyright: © 2000, 2001 by Ng Pheng Siong. + +Introduction +============ + +`M2Crypto `__ is a +`Python `__ interface to +`OpenSSL `__. 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, ````, +shall be the sender of S/MIME messages, while S/MIME Recipient, +````, 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 + + 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: + Verifying password - Enter Export Password: + +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 `__ *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 `__ +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.txt b/doc/html/_sources/howto.ssl.txt new file mode 100644 index 0000000..7f3278c --- /dev/null +++ b/doc/html/_sources/howto.ssl.txt @@ -0,0 +1,131 @@ +:orphan: + +.. _howto-ssl: + +HOWTO: Programming SSL in Python with M2Crypto +============================================== + +:author: Pheng Siong Ng and Heikki Toivonen (heikki@osafoundation.org) +:copyright: © 2000, 2001 by Ng Pheng Siong, + portions © 2006 by Open Source Applications Foundation + +Introduction +============ + +`M2Crypto `__ is a +`Python `__ interface to +`OpenSSL `__. 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 `__ +file from the +`NSS `__ project and +convert it with the little M2Crypto utility script +`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.txt b/doc/html/_sources/index.txt new file mode 100644 index 0000000..a472668 --- /dev/null +++ b/doc/html/_sources/index.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 Binary files /dev/null and b/doc/html/_static/ajax-loader.gif differ diff --git a/doc/html/_static/basic.css b/doc/html/_static/basic.css new file mode 100644 index 0000000..43e8baf --- /dev/null +++ b/doc/html/_static/basic.css @@ -0,0 +1,540 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2011 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%; +} + +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 input[type="text"] { + width: 170px; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + width: 30px; +} + +img { + border: 0; +} + +/* -- 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%; +} + +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 dl, table.indextable dd { + margin-top: 0; + margin-bottom: 0; +} + +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; +} + +/* -- general body styles --------------------------------------------------- */ + +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 { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.field-list ul { + padding-left: 1em; +} + +.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.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.field-list td, table.field-list th { + border: 0 !important; +} + +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; +} + +/* -- 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, .highlighted { + background-color: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.refcount { + color: #060; +} + +.optional { + font-size: 1.3em; +} + +.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 */ +} + +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; +} + +tt.descname { + background-color: transparent; + font-weight: bold; + font-size: 1.2em; +} + +tt.descclassname { + background-color: transparent; +} + +tt.xref, a tt { + background-color: transparent; + font-weight: bold; +} + +h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { + 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; +} + +/* -- 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..551517b Binary files /dev/null and b/doc/html/_static/comment-bright.png differ diff --git a/doc/html/_static/comment-close.png b/doc/html/_static/comment-close.png new file mode 100644 index 0000000..09b54be Binary files /dev/null and b/doc/html/_static/comment-close.png differ diff --git a/doc/html/_static/comment.png b/doc/html/_static/comment.png new file mode 100644 index 0000000..92feb52 Binary files /dev/null and b/doc/html/_static/comment.png differ diff --git a/doc/html/_static/default.css b/doc/html/_static/default.css new file mode 100644 index 0000000..21f3f50 --- /dev/null +++ b/doc/html/_static/default.css @@ -0,0 +1,256 @@ +/* + * default.css_t + * ~~~~~~~~~~~~~ + * + * Sphinx stylesheet -- default theme. + * + * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +@import url("basic.css"); + +/* -- page layout ----------------------------------------------------------- */ + +body { + font-family: sans-serif; + font-size: 100%; + background-color: #11303d; + color: #000; + margin: 0; + padding: 0; +} + +div.document { + background-color: #1c4e63; +} + +div.documentwrapper { + float: left; + width: 100%; +} + +div.bodywrapper { + margin: 0 0 0 230px; +} + +div.body { + background-color: #ffffff; + color: #000000; + padding: 0 20px 30px 20px; +} + +div.footer { + color: #ffffff; + width: 100%; + padding: 9px 0 9px 0; + text-align: center; + font-size: 75%; +} + +div.footer a { + color: #ffffff; + text-decoration: underline; +} + +div.related { + background-color: #133f52; + line-height: 30px; + color: #ffffff; +} + +div.related a { + color: #ffffff; +} + +div.sphinxsidebar { +} + +div.sphinxsidebar h3 { + font-family: 'Trebuchet MS', sans-serif; + color: #ffffff; + font-size: 1.4em; + font-weight: normal; + margin: 0; + padding: 0; +} + +div.sphinxsidebar h3 a { + color: #ffffff; +} + +div.sphinxsidebar h4 { + font-family: 'Trebuchet MS', sans-serif; + color: #ffffff; + font-size: 1.3em; + font-weight: normal; + margin: 5px 0 0 0; + padding: 0; +} + +div.sphinxsidebar p { + color: #ffffff; +} + +div.sphinxsidebar p.topless { + margin: 5px 10px 10px 10px; +} + +div.sphinxsidebar ul { + margin: 10px; + padding: 0; + color: #ffffff; +} + +div.sphinxsidebar a { + color: #98dbcc; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + + + +/* -- hyperlink styles ------------------------------------------------------ */ + +a { + color: #355f7c; + text-decoration: none; +} + +a:visited { + color: #355f7c; + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + + + +/* -- body styles ----------------------------------------------------------- */ + +div.body h1, +div.body h2, +div.body h3, +div.body h4, +div.body h5, +div.body h6 { + font-family: 'Trebuchet MS', sans-serif; + background-color: #f2f2f2; + font-weight: normal; + color: #20435c; + border-bottom: 1px solid #ccc; + margin: 20px -20px 10px -20px; + padding: 3px 0 3px 10px; +} + +div.body h1 { margin-top: 0; font-size: 200%; } +div.body h2 { font-size: 160%; } +div.body h3 { font-size: 140%; } +div.body h4 { font-size: 120%; } +div.body h5 { font-size: 110%; } +div.body h6 { font-size: 100%; } + +a.headerlink { + color: #c60f0f; + font-size: 0.8em; + padding: 0 4px 0 4px; + text-decoration: none; +} + +a.headerlink:hover { + background-color: #c60f0f; + color: white; +} + +div.body p, div.body dd, div.body li { + text-align: justify; + line-height: 130%; +} + +div.admonition p.admonition-title + p { + display: inline; +} + +div.admonition p { + margin-bottom: 5px; +} + +div.admonition pre { + margin-bottom: 5px; +} + +div.admonition ul, div.admonition ol { + margin-bottom: 5px; +} + +div.note { + background-color: #eee; + border: 1px solid #ccc; +} + +div.seealso { + background-color: #ffc; + border: 1px solid #ff6; +} + +div.topic { + background-color: #eee; +} + +div.warning { + background-color: #ffe4e4; + border: 1px solid #f66; +} + +p.admonition-title { + display: inline; +} + +p.admonition-title:after { + content: ":"; +} + +pre { + padding: 5px; + background-color: #eeffcc; + color: #333333; + line-height: 120%; + border: 1px solid #ac9; + border-left: none; + border-right: none; +} + +tt { + background-color: #ecf0f3; + padding: 0 1px 0 1px; + font-size: 0.95em; +} + +th { + background-color: #ede; +} + +.warning tt { + background: #efc2c2; +} + +.note tt { + background: #d6d6d6; +} + +.viewcode-back { + font-family: sans-serif; +} + +div.viewcode-block:target { + background-color: #f4debf; + border-top: 1px solid #ac9; + border-bottom: 1px solid #ac9; +} \ No newline at end of file diff --git a/doc/html/_static/doctools.js b/doc/html/_static/doctools.js new file mode 100644 index 0000000..d4619fd --- /dev/null +++ b/doc/html/_static/doctools.js @@ -0,0 +1,247 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for all documentation. + * + * :copyright: Copyright 2007-2011 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; +}; + +/** + * small function to check if an array contains + * a given item. + */ +jQuery.contains = function(arr, item) { + for (var i = 0; i < arr.length; i++) { + if (arr[i] == item) + return true; + } + return false; +}; + +/** + * 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) { + if (node.nodeType == 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) { + var 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); + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this); + }); + } + } + return this.each(function() { + highlight(this); + }); +}; + +/** + * Small JavaScript module for the documentation. + */ +var Documentation = { + + init : function() { + this.fixFirefoxAnchorBug(); + this.highlightSearchWords(); + this.initIndexTable(); + }, + + /** + * 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() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this headline')). + appendTo(this); + }); + $('dt[id]').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this definition')). + appendTo(this); + }); + }, + + /** + * workaround a firefox stupidity + */ + 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'); + window.setTimeout(function() { + $.each(terms, function() { + body.highlightText(this.toLowerCase(), 'highlighted'); + }); + }, 10); + $('') + .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); + } +}; + +// quick alias for translations +_ = Documentation.gettext; + +$(document).ready(function() { + Documentation.init(); +}); diff --git a/doc/html/_static/down-pressed.png b/doc/html/_static/down-pressed.png new file mode 100644 index 0000000..6f7ad78 Binary files /dev/null and b/doc/html/_static/down-pressed.png differ diff --git a/doc/html/_static/down.png b/doc/html/_static/down.png new file mode 100644 index 0000000..3003a88 Binary files /dev/null and b/doc/html/_static/down.png differ diff --git a/doc/html/_static/file.png b/doc/html/_static/file.png new file mode 100644 index 0000000..d18082e Binary files /dev/null and b/doc/html/_static/file.png differ diff --git a/doc/html/_static/jquery.js b/doc/html/_static/jquery.js new file mode 100644 index 0000000..7c24308 --- /dev/null +++ b/doc/html/_static/jquery.js @@ -0,0 +1,154 @@ +/*! + * jQuery JavaScript Library v1.4.2 + * http://jquery.com/ + * + * Copyright 2010, John Resig + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * Copyright 2010, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * + * Date: Sat Feb 13 22:33:48 2010 -0500 + */ +(function(A,w){function ma(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(ma,1);return}c.ready()}}function Qa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,j){var i=a.length;if(typeof b==="object"){for(var o in b)X(a,o,b[o],f,e,d);return a}if(d!==w){f=!j&&f&&c.isFunction(d);for(o=0;o)[^>]*$|^#([\w-]+)$/,Ua=/^.[^:#\[\.,]*$/,Va=/\S/, +Wa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Xa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,R=Array.prototype.slice,ya=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(a==="body"&&!b){this.context=s;this[0]=s.body;this.selector="body";this.length=1;return this}if(typeof a==="string")if((d=Ta.exec(a))&& +(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Xa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=sa([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return c.merge(this,a)}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return T.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a);return c.merge(this, +a)}else return!b||b.jquery?(b||T).find(a):c(b).find(a);else if(c.isFunction(a))return T.ready(a);if(a.selector!==w){this.selector=a.selector;this.context=a.context}return c.makeArray(a,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){var f=c();c.isArray(a)?ba.apply(f,a):c.merge(f,a);f.prevObject=this;f.context=this.context;if(b=== +"find")f.selector=this.selector+(this.selector?" ":"")+d;else if(b)f.selector=this.selector+"."+b+"("+d+")";return f},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this, +function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,j,i,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b
a"; +var e=d.getElementsByTagName("*"),j=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!j)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(j.getAttribute("style")),hrefNormalized:j.getAttribute("href")==="/a",opacity:/^0.55$/.test(j.style.opacity),cssFloat:!!j.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected, +parentNode:d.removeChild(d.appendChild(s.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(i){}a.insertBefore(b,a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}try{delete b.test}catch(o){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function k(){c.support.noCloneEvent= +false;d.detachEvent("onclick",k)});d.cloneNode(true).fireEvent("onclick")}d=s.createElement("div");d.innerHTML="";a=s.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var k=s.createElement("div");k.style.width=k.style.paddingLeft="1px";s.body.appendChild(k);c.boxModel=c.support.boxModel=k.offsetWidth===2;s.body.removeChild(k).style.display="none"});a=function(k){var n= +s.createElement("div");k="on"+k;var r=k in n;if(!r){n.setAttribute(k,"return;");r=typeof n[k]==="function"}return r};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=j=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ya=0,za={};c.extend({cache:{},expando:G,noData:{embed:true,object:true, +applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var f=a[G],e=c.cache;if(!f&&typeof b==="string"&&d===w)return null;f||(f=++Ya);if(typeof b==="object"){a[G]=f;e[f]=c.extend(true,{},b)}else if(!e[f]){a[G]=f;e[f]={}}a=e[f];if(d!==w)a[b]=d;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{if(c.support.deleteExpando)delete a[c.expando]; +else a.removeAttribute&&a.removeAttribute(c.expando);delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this, +a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b=== +w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var Aa=/[\n\t]/g,ca=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|input|object|select|textarea)/i, +cb=/^(a|area)$/i,Ba=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(n){var r=c(this);r.addClass(a.call(this,n,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var j=b?d:0;for(d=b?d+1:e.length;j=0;else if(c.nodeName(this,"select")){var u=c.makeArray(r);c("option",this).each(function(){this.selected= +c.inArray(c(this).val(),u)>=0});if(!u.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var j=$a.test(b);if(b in a&&f&&!j){if(e){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed"); +a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&j?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var O=/\.(.*)$/,db=function(a){return a.replace(/[^\w\s\.\|`]/g, +function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;var e,j;if(d.handler){e=d;d=e.handler}if(!d.guid)d.guid=c.guid++;if(j=c.data(a)){var i=j.events=j.events||{},o=j.handle;if(!o)j.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,arguments):w};o.elem=a;b=b.split(" ");for(var k,n=0,r;k=b[n++];){j=e?c.extend({},e):{handler:d,data:f};if(k.indexOf(".")>-1){r=k.split("."); +k=r.shift();j.namespace=r.slice(0).sort().join(".")}else{r=[];j.namespace=""}j.type=k;j.guid=d.guid;var u=i[k],z=c.event.special[k]||{};if(!u){u=i[k]=[];if(!z.setup||z.setup.call(a,f,r,o)===false)if(a.addEventListener)a.addEventListener(k,o,false);else a.attachEvent&&a.attachEvent("on"+k,o)}if(z.add){z.add.call(a,j);if(!j.handler.guid)j.handler.guid=d.guid}u.push(j);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){var e,j=0,i,o,k,n,r,u,z=c.data(a), +C=z&&z.events;if(z&&C){if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(e in C)c.event.remove(a,e+b)}else{for(b=b.split(" ");e=b[j++];){n=e;i=e.indexOf(".")<0;o=[];if(!i){o=e.split(".");e=o.shift();k=new RegExp("(^|\\.)"+c.map(o.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(r=C[e])if(d){n=c.event.special[e]||{};for(B=f||0;B=0){a.type= +e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(j){}if(!a.isPropagationStopped()&& +f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){f=a.target;var i,o=c.nodeName(f,"a")&&e==="click",k=c.event.special[e]||{};if((!k._default||k._default.call(d,a)===false)&&!o&&!(f&&f.nodeName&&c.noData[f.nodeName.toLowerCase()])){try{if(f[e]){if(i=f["on"+e])f["on"+e]=null;c.event.triggered=true;f[e]()}}catch(n){}if(i)f["on"+e]=i;c.event.triggered=false}}},handle:function(a){var b,d,f,e;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive; +if(!b){d=a.type.split(".");a.type=d.shift();f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}e=c.data(this,"events");d=e[a.type];if(e&&d){d=d.slice(0);e=0;for(var j=d.length;e-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},fa=function(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Fa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data", +e);if(!(f===w||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:fa,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return fa.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return fa.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a, +"_change_data",Fa(a))}},setup:function(){if(this.type==="file")return false;for(var a in ea)c.event.add(this,a+".specialChange",ea[a]);return da.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return da.test(this.nodeName)}};ea=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a, +d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var j in d)this[b](j,f,d[j],e);return this}if(c.isFunction(f)){e=f;f=w}var i=b==="one"?c.proxy(e,function(k){c(this).unbind(k,i);return e.apply(this,arguments)}):e;if(d==="unload"&&b!=="one")this.one(d,f,e);else{j=0;for(var o=this.length;j0){y=t;break}}t=t[g]}m[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, +e=0,j=Object.prototype.toString,i=false,o=true;[0,0].sort(function(){o=false;return 0});var k=function(g,h,l,m){l=l||[];var q=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return l;for(var p=[],v,t,y,S,H=true,M=x(h),I=g;(f.exec(""),v=f.exec(I))!==null;){I=v[3];p.push(v[1]);if(v[2]){S=v[3];break}}if(p.length>1&&r.exec(g))if(p.length===2&&n.relative[p[0]])t=ga(p[0]+p[1],h);else for(t=n.relative[p[0]]?[h]:k(p.shift(),h);p.length;){g=p.shift();if(n.relative[g])g+=p.shift(); +t=ga(g,t)}else{if(!m&&p.length>1&&h.nodeType===9&&!M&&n.match.ID.test(p[0])&&!n.match.ID.test(p[p.length-1])){v=k.find(p.shift(),h,M);h=v.expr?k.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:p.pop(),set:z(m)}:k.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=v.expr?k.filter(v.expr,v.set):v.set;if(p.length>0)y=z(t);else H=false;for(;p.length;){var D=p.pop();v=D;if(n.relative[D])v=p.pop();else D="";if(v==null)v=h;n.relative[D](y,v,M)}}else y=[]}y||(y=t);y||k.error(D|| +g);if(j.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))l.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&l.push(t[g]);else l.push.apply(l,y);else z(y,l);if(S){k(S,q,l,m);k.uniqueSort(l)}return l};k.uniqueSort=function(g){if(B){i=o;g.sort(B);if(i)for(var h=1;h":function(g,h){var l=typeof h==="string";if(l&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,q=g.length;m=0))l||m.push(v);else if(l)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()}, +CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||m.push.apply(m, +g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,l){return!!k(l[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)}, +text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}}, +setFilters:{first:function(g,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return hl[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h= +h[3];l=0;for(m=h.length;l=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m=== +"="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+)/g,function(g, +h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!=="undefined"&& +q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTML=""; +if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="

";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l];h=null}}(); +(function(){var g=s.createElement("div");g.innerHTML="
";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPosition(h)&16)}: +function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f0)for(var j=d;j0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,j= +{},i;if(f&&a.length){e=0;for(var o=a.length;e-1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},index:function(a){if(!a||typeof a=== +"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode", +d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")? +a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeType!==1||!c(a).is(d));){a.nodeType=== +1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/"},F={option:[1,""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div
","
"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d= +c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this}, +wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})}, +prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b, +this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild); +return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Ja, +""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length===1){d[b](this[0]); +return this}else{e=0;for(var j=d.length;e0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec(i)||["", +""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]===""&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.push(i);else e= +c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b.events)e[k]? +c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styleFloat",ja= +function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter= +Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a, +"border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f= +a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b= +a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=//gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ka=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!== +"string")return zb.call(this,a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}var j=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(i,o){if(o==="success"||o==="notmodified")j.html(e?c("
").append(i.responseText.replace(tb,"")).find(e):i.responseText);d&&j.each(d,[i.responseText,o,i])}});return this}, +serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ub.test(this.nodeName)||vb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), +function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href, +global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&& +e.success.call(k,o,i,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(k,x,i);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),j,i,o,k=a&&a.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(n==="GET")N.test(e.url)||(e.url+=(ka.test(e.url)? +"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||N.test(e.url))){j=e.jsonpCallback||"jsonp"+sb++;if(e.data)e.data=(e.data+"").replace(N,"="+j+"$1");e.url=e.url.replace(N,"="+j+"$1");e.dataType="script";A[j]=A[j]||function(q){o=q;b();d();A[j]=w;try{delete A[j]}catch(p){}z&&z.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache=== +false&&n==="GET"){var r=J(),u=e.url.replace(wb,"$1_="+r+"$2");e.url=u+(u===e.url?(ka.test(e.url)?"&":"?")+"_="+r:"")}if(e.data&&n==="GET")e.url+=(ka.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");r=(r=xb.exec(e.url))&&(r[1]&&r[1]!==location.protocol||r[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&r){var z=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!j){var B= +false;C.onload=C.onreadystatechange=function(){if(!B&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){B=true;b();d();C.onload=C.onreadystatechange=null;z&&C.parentNode&&z.removeChild(C)}}}z.insertBefore(C,z.firstChild);return w}var E=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since", +c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}r||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ga){}if(e.beforeSend&&e.beforeSend.call(k,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",[x,e]);var g=x.onreadystatechange=function(q){if(!x||x.readyState===0||q==="abort"){E|| +d();E=true;if(x)x.onreadystatechange=c.noop}else if(!E&&x&&(x.readyState===4||q==="timeout")){E=true;x.onreadystatechange=c.noop;i=q==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";var p;if(i==="success")try{o=c.httpData(x,e.dataType,e)}catch(v){i="parsererror";p=v}if(i==="success"||i==="notmodified")j||b();else c.handleError(e,x,i,p);d();q==="timeout"&&x.abort();if(e.async)x=null}};try{var h=x.abort;x.abort=function(){x&&h.call(x); +g("abort")}}catch(l){}e.async&&e.timeout>0&&setTimeout(function(){x&&!E&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status=== +1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b=== +"json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(i,o){if(c.isArray(o))c.each(o,function(k,n){b||/\[\]$/.test(i)?f(i,n):d(i+"["+(typeof n==="object"||c.isArray(n)?k:"")+"]",n)});else!b&&o!=null&&typeof o==="object"?c.each(o,function(k,n){d(i+"["+k+"]",n)}):f(i,o)}function f(i,o){o=c.isFunction(o)?o():o;e[e.length]=encodeURIComponent(i)+"="+encodeURIComponent(o)}var e=[];if(b===w)b=c.ajaxSettings.traditional; +if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var j in a)d(j,a[j]);return e.join("&").replace(yb,"+")}});var la={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,W,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();la[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration=== +"number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]|| +c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(j){return e.step(j)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start; +this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now= +this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem, +e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b
"; +a.insertBefore(b,a.firstChild);d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==j;a.removeChild(b); +c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),j=parseInt(c.curCSS(a,"top",true),10)||0,i=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a, +d,e);d={top:b.top-e.top+j,left:b.left-e.left+i};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top- +f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],j;if(!e)return null;if(f!==w)return this.each(function(){if(j=wa(this))j.scrollTo(!a?f:c(j).scrollLeft(),a?f:c(j).scrollTop());else this[d]=f});else return(j=wa(e))?"pageXOffset"in j?j[a?"pageYOffset": +"pageXOffset"]:c.support.boxModel&&j.document.documentElement[d]||j.document.body[d]:e[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(j){var i=c(this);i[d](f.call(this,j,i[d]()))});return"scrollTo"in +e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window); diff --git a/doc/html/_static/minus.png b/doc/html/_static/minus.png new file mode 100644 index 0000000..da1c562 Binary files /dev/null and b/doc/html/_static/minus.png differ diff --git a/doc/html/_static/plus.png b/doc/html/_static/plus.png new file mode 100644 index 0000000..b3cb374 Binary files /dev/null and b/doc/html/_static/plus.png differ diff --git a/doc/html/_static/pygments.css b/doc/html/_static/pygments.css new file mode 100644 index 0000000..8213e90 --- /dev/null +++ b/doc/html/_static/pygments.css @@ -0,0 +1,65 @@ +.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 .sb { color: #4070a0 } /* Literal.String.Backtick */ +.highlight .sc { color: #4070a0 } /* Literal.String.Char */ +.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 .vc { color: #bb60d5 } /* Name.Variable.Class */ +.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */ +.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */ +.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..663be4c --- /dev/null +++ b/doc/html/_static/searchtools.js @@ -0,0 +1,560 @@ +/* + * searchtools.js_t + * ~~~~~~~~~~~~~~~~ + * + * Sphinx JavaScript utilties for the full-text search. + * + * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/** + * 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 occurance, the + * latter for highlighting it. + */ + +jQuery.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 = $('
').text(excerpt); + $.each(hlwords, function() { + rv = rv.highlightText(this, 'highlighted'); + }); + return rv; +} + + +/** + * 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; + } +} + + +/** + * 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, success: null, + dataType: "script", cache: true}); + }, + + 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() { + Search._pulse_status = (Search._pulse_status + 1) % 4; + var dotString = ''; + for (var 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 + */ + performSearch : function(query) { + // create the required interface elements + this.out = $('#search-results'); + this.title = $('

' + _('Searching') + '

').appendTo(this.out); + this.dots = $('').appendTo(this.title); + this.status = $('

').appendTo(this.out); + this.output = $('