]> www.wagner.pp.ru Git - oss/ctypescrypto.git/commitdiff
style fixes
authorVictor Wagner <vitus@wagner.pp.ru>
Sun, 21 Dec 2014 10:04:43 +0000 (13:04 +0300)
committerVictor Wagner <vitus@wagner.pp.ru>
Sun, 21 Dec 2014 10:04:43 +0000 (13:04 +0300)
README.md
ctypescrypto/__init__.py
ctypescrypto/cipher.py
ctypescrypto/cms.py
ctypescrypto/digest.py

index ee8356bb2df12c72eb9e20359c5626831388609f..4b6d5d872d38203535571ded095024990b2a033b 100644 (file)
--- a/README.md
+++ b/README.md
@@ -78,6 +78,19 @@ python big integer.
 X509 certificates
 -----------------
 
+Certificates are cryptographically signed documents, which tie together
+public key and some attributes of key owner (certificate subject).
+Certificates are signed by some trusted organizations called Certificate
+Authorities (one which have issued given certificate, is called
+certificate issuer). Your browser or operating system typically have
+predefined store of the trusted CA certificates (although nothing
+prevent you from running your own CA using openssl command line utility,
+and trust only it). 
+
+
+
+Certificates are described in [RFC 5280](http://tools.ietf.org/html/rfc5280)
+
 Module **ctypescrypto.x509** contains objects **X509** which represents
 certificate (and can be constructed from string, contained PEM
 or DER certificate) and object **X509Store** which is a store of trusted
@@ -103,6 +116,16 @@ some operations with CMS and certificate verification.
 CMS documents
 -------------
 
+CMS stands for Cryptographic Message Syntax. It is defined in the
+[RFC 5652](http://tools.ietf.org/html/rfc5652).
+CMS defines several types of documents. There is **SignedData**,
+which can be read by anyone, but is protected from authorized changes
+by digital signature of its author. There is **EnvelopedData** protected
+from unauthorized reading by cipher and allowed to be read only by
+owners of certain private keys, and there is **EncryptedData**, which
+are protected by symmetric cipher keys.
+
+
 There is basic factory function **CMS()**, which parses PEM or der
 representation of cryptographic message and generates appropriate
 object. There are **SignedData**, **EnvelopedData** and
index ebf8c41a7750e6c9dd3a2bc31976c4df65270489..7ae712565d643d6ac7621652cdc061e9976ba754 100644 (file)
@@ -13,7 +13,7 @@ def config(filename=None):
        """
        libcrypto.OPENSSL_config(filename)
 
-__all__ = ['bio','cipher','cms','config','digest','ec','engine','exception','oid','pbkdf2','pkey','rand','x509']
+__all__ = ['config']
 
 libcrypto = CDLL("libcrypto.so.1.0.0")
 libcrypto.OPENSSL_config.argtypes=(c_char_p,)
index 815a42541897232853a0721b9fea12be9d42217b..ff614783a77f965680f84018c48850f93a16ad88 100644 (file)
@@ -117,10 +117,7 @@ class Cipher:
                if self.ctx == 0:
                        raise CipherError("Unable to create cipher context")
                self.encrypt = encrypt
-               if encrypt: 
-                       enc = 1
-               else: 
-                       enc = 0
+               enc=1 if encrypt else 0
                if not iv is None and len(iv) != cipher_type.iv_length():
                        raise ValueError("Invalid IV length for this algorithm")
                        
@@ -151,10 +148,7 @@ class Cipher:
                """
                        Sets padding mode of the cipher
                """
-               if padding:
-                       padding_flag = 1
-               else:
-                       padding_flag = 0
+               padding_flag=1 if padding else 0
                libcrypto.EVP_CIPHER_CTX_set_padding(self.ctx, padding_flag)
 
        def update(self, data):
@@ -173,7 +167,7 @@ class Cipher:
                        raise CipherError("No updates allowed")
                if not isinstance(data,str):
                        raise TypeError("A string is expected")
-               if len(data) <= 0:
+               if len(data) == 0:
                        return ""
                outbuf=create_string_buffer(self.block_size+len(data))
                outlen=c_int(0)
index 3158b628f087d7ff21f25d7f0fbee57a1d6c4e36..5a54bde1441ddb3f68d00c81f8748cb332a906f8 100644 (file)
@@ -171,7 +171,7 @@ class SignedData(CMSBase):
                res=libcrypto.CMS_verify(self.ptr,certstack,store.store,bio,None,flags)
                return res>0
        @property       
-       def signers(self,store=None):
+       def signers(self):
                """
                Return list of signer's certificates
                """
index 30d77c5a57b35f19d2f0aa501f010581ae4740dc..586a1fbdce0d9872c4c6b7d82fae54826533cd4b 100644 (file)
-"""\r
-       Implements interface to OpenSSL EVP_Digest* functions.\r
-\r
-       Interface  made as close to hashlib as possible.\r
-\r
-       This module is really an excess effort. Hashlib allows access to\r
-       mostly same functionality except oids and nids of hashing\r
-       algortithms (which might be needed for private key operations).\r
-\r
-       hashlib even allows to use engine-provided digests if it is build\r
-       with dinamically linked libcrypto - so use\r
-       ctypescrypto.engine.set_default("gost",xFFFF) and md_gost94\r
-       algorithm would be available both to this module and hashlib.\r
-\r
-"""\r
-from ctypes import c_int, c_char_p, c_void_p, POINTER, c_long,c_longlong, create_string_buffer,byref\r
-from ctypescrypto import libcrypto\r
-from ctypescrypto.exception import LibCryptoError\r
-from ctypescrypto.oid import Oid\r
-DIGEST_ALGORITHMS = ("MD5", "SHA1", "SHA224", "SHA256", "SHA384", "SHA512")\r
-\r
-__all__ = ['DigestError','Digest','DigestType','new']\r
-\r
-class DigestError(LibCryptoError):\r
-       pass\r
-\r
-def new(algname):\r
-       """\r
-               Behaves just like hashlib.new. Creates digest object by\r
-               algorithm name\r
-       """\r
-       md=DigestType(algname)\r
-       return Digest(md)\r
-\r
-class DigestType(object):\r
-       """\r
-               \r
-               Represents EVP_MD object - constant structure which describes\r
-               digest algorithm\r
-\r
-       """\r
-       def __init__(self,      digest_name):\r
-               """\r
-                       Finds digest by its name. You can pass Oid object instead of\r
-                       name.\r
-\r
-                       Special case is when None is passed as name. In this case\r
-                       unitialized digest is created, and can be initalized later\r
-                       by setting its digest attribute to pointer to EVP_MD\r
-               """\r
-               if digest_name is None:\r
-                       return \r
-               if isinstance(digest_name,Oid):\r
-                       self.digest_name=digest_name.longname()\r
-                       self.digest=libcrypto.EVP_get_digestbyname(self.digest_name)\r
-               else:\r
-                       self.digest_name = str(digest_name)\r
-                       self.digest = libcrypto.EVP_get_digestbyname(self.digest_name)\r
-               if self.digest is None:\r
-                       raise DigestError("Unknown digest: %s" % self.digest_name)\r
-\r
-       @property\r
-       def name(self):\r
-               if not hasattr(self,'digest_name'):\r
-                       self.digest_name=Oid(libcrypto.EVP_MD_type(self.digest)).longname()\r
-               return self.digest_name\r
-       def __del__(self):\r
-               pass\r
-       def digest_size(self):\r
-               return libcrypto.EVP_MD_size(self.digest)\r
-       def block_size(self):\r
-               return libcrypto.EVP_MD_block_size(self.digest)\r
-       def oid(self):\r
-               return Oid(libcrypto.EVP_MD_type(self.digest))\r
-\r
-class Digest(object):\r
-       """\r
-               Represents EVP_MD_CTX object which actually used to calculate\r
-               digests.\r
-\r
-       """\r
-       def __init__(self,digest_type):\r
-               """\r
-                       Initializes digest using given type.\r
-               """\r
-               self._clean_ctx()\r
-               self.ctx = libcrypto.EVP_MD_CTX_create()\r
-               if self.ctx is None:\r
-                       raise DigestError("Unable to create digest context")\r
-               result = libcrypto.EVP_DigestInit_ex(self.ctx, digest_type.digest, None)\r
-               if result == 0:\r
-                       self._clean_ctx()\r
-                       raise DigestError("Unable to initialize digest")\r
-               self.digest_type = digest_type\r
-               self.digest_size = self.digest_type.digest_size()\r
-               self.block_size = self.digest_type.block_size()\r
-\r
-       def __del__(self):\r
-               self._clean_ctx()\r
-\r
-       def update(self, data, length=None):\r
-               """\r
-                       Hashes given byte string \r
-\r
-                       @param data - string to hash\r
-                       @param length - if not specifed, entire string is hashed,\r
-                                       otherwise only first length bytes\r
-               """\r
-               if self.digest_finalized:\r
-                       raise DigestError("No updates allowed")\r
-               if not isinstance(data,str):\r
-                       raise TypeError("A string is expected")\r
-               if length is None:\r
-                       length = len(data)\r
-               elif length > len(data):\r
-                       raise ValueError("Specified length is greater than length of data")\r
-               result = libcrypto.EVP_DigestUpdate(self.ctx, c_char_p(data), length)\r
-               if result != 1:\r
-                       raise DigestError, "Unable to update digest"\r
-               \r
-       def digest(self, data=None):\r
-               """\r
-                       Finalizes digest operation and return digest value\r
-                       Optionally hashes more data before finalizing\r
-               """\r
-               if self.digest_finalized:\r
-                       return self.digest_out.raw[:self.digest_size]\r
-               if data is not None:\r
-                       self.update(data)\r
-               self.digest_out = create_string_buffer(256)\r
-               length = c_long(0)\r
-               result = libcrypto.EVP_DigestFinal_ex(self.ctx, self.digest_out, byref(length))\r
-               if result != 1 :\r
-                       raise DigestError("Unable to finalize digest")\r
-               self.digest_finalized = True\r
-               return self.digest_out.raw[:self.digest_size]\r
-       def copy(self):\r
-               """\r
-                       Creates copy of the digest CTX to allow to compute digest\r
-                       while being able to hash more data\r
-               """\r
-               new_digest=Digest(self.digest_type)\r
-               libcrypto.EVP_MD_CTX_copy(new_digest.ctx,self.ctx)\r
-               return new_digest\r
-\r
-       def _clean_ctx(self):\r
-               try:\r
-                       if self.ctx is not None:\r
-                               libcrypto.EVP_MD_CTX_destroy(self.ctx)\r
-                               del(self.ctx)\r
-               except AttributeError:\r
-                       pass\r
-               self.digest_out = None\r
-               self.digest_finalized = False\r
-\r
-       def hexdigest(self,data=None):\r
-               """\r
-                       Returns digest in the hexadecimal form. For compatibility\r
-                       with hashlib\r
-               """\r
-               from base64 import b16encode\r
-               return b16encode(self.digest(data))\r
-\r
-\r
-# Declare function result and argument types\r
-libcrypto.EVP_get_digestbyname.restype = c_void_p\r
-libcrypto.EVP_get_digestbyname.argtypes = (c_char_p,)\r
-libcrypto.EVP_MD_CTX_create.restype = c_void_p\r
-libcrypto.EVP_DigestInit_ex.argtypes = (c_void_p,c_void_p,c_void_p)\r
-libcrypto.EVP_DigestUpdate.argtypes = (c_void_p,c_char_p,c_longlong)\r
-libcrypto.EVP_DigestFinal_ex.argtypes = (c_void_p,c_char_p,POINTER(c_long))\r
-libcrypto.EVP_MD_CTX_destroy.argtypes = (c_void_p,)\r
-libcrypto.EVP_MD_CTX_copy.argtypes=(c_void_p, c_void_p)\r
-libcrypto.EVP_MD_type.argtypes=(c_void_p,)\r
-libcrypto.EVP_MD_size.argtypes=(c_void_p,)\r
-libcrypto.EVP_MD_block_size.argtypes=(c_void_p,)\r
+"""
+       Implements interface to OpenSSL EVP_Digest* functions.
+
+       Interface  made as close to hashlib as possible.
+
+       This module is really an excess effort. Hashlib allows access to
+       mostly same functionality except oids and nids of hashing
+       algortithms (which might be needed for private key operations).
+
+       hashlib even allows to use engine-provided digests if it is build
+       with dinamically linked libcrypto - so use
+       ctypescrypto.engine.set_default("gost",xFFFF) and md_gost94
+       algorithm would be available both to this module and hashlib.
+
+"""
+from ctypes import c_int, c_char_p, c_void_p, POINTER, c_long,c_longlong, create_string_buffer,byref
+from ctypescrypto import libcrypto
+from ctypescrypto.exception import LibCryptoError
+from ctypescrypto.oid import Oid
+DIGEST_ALGORITHMS = ("MD5", "SHA1", "SHA224", "SHA256", "SHA384", "SHA512")
+
+__all__ = ['DigestError','Digest','DigestType','new']
+
+class DigestError(LibCryptoError):
+       pass
+
+def new(algname):
+       """
+               Behaves just like hashlib.new. Creates digest object by
+               algorithm name
+       """
+       md=DigestType(algname)
+       return Digest(md)
+
+class DigestType(object):
+       """
+               
+               Represents EVP_MD object - constant structure which describes
+               digest algorithm
+
+       """
+       def __init__(self,      digest_name):
+               """
+                       Finds digest by its name. You can pass Oid object instead of
+                       name.
+
+                       Special case is when None is passed as name. In this case
+                       unitialized digest is created, and can be initalized later
+                       by setting its digest attribute to pointer to EVP_MD
+               """
+               if digest_name is None:
+                       return 
+               if isinstance(digest_name,Oid):
+                       self.digest_name=digest_name.longname()
+                       self.digest=libcrypto.EVP_get_digestbyname(self.digest_name)
+               else:
+                       self.digest_name = str(digest_name)
+                       self.digest = libcrypto.EVP_get_digestbyname(self.digest_name)
+               if self.digest is None:
+                       raise DigestError("Unknown digest: %s" % self.digest_name)
+
+       @property
+       def name(self):
+               if not hasattr(self,'digest_name'):
+                       self.digest_name=Oid(libcrypto.EVP_MD_type(self.digest)).longname()
+               return self.digest_name
+       def __del__(self):
+               pass
+       def digest_size(self):
+               return libcrypto.EVP_MD_size(self.digest)
+       def block_size(self):
+               return libcrypto.EVP_MD_block_size(self.digest)
+       def oid(self):
+               return Oid(libcrypto.EVP_MD_type(self.digest))
+
+class Digest(object):
+       """
+               Represents EVP_MD_CTX object which actually used to calculate
+               digests.
+
+       """
+       def __init__(self,digest_type):
+               """
+                       Initializes digest using given type.
+               """
+               self._clean_ctx()
+               self.ctx = libcrypto.EVP_MD_CTX_create()
+               if self.ctx is None:
+                       raise DigestError("Unable to create digest context")
+               result = libcrypto.EVP_DigestInit_ex(self.ctx, digest_type.digest, None)
+               if result == 0:
+                       self._clean_ctx()
+                       raise DigestError("Unable to initialize digest")
+               self.digest_type = digest_type
+               self.digest_size = self.digest_type.digest_size()
+               self.block_size = self.digest_type.block_size()
+
+       def __del__(self):
+               self._clean_ctx()
+
+       def update(self, data, length=None):
+               """
+                       Hashes given byte string 
+
+                       @param data - string to hash
+                       @param length - if not specifed, entire string is hashed,
+                                       otherwise only first length bytes
+               """
+               if self.digest_finalized:
+                       raise DigestError("No updates allowed")
+               if not isinstance(data,str):
+                       raise TypeError("A string is expected")
+               if length is None:
+                       length = len(data)
+               elif length > len(data):
+                       raise ValueError("Specified length is greater than length of data")
+               result = libcrypto.EVP_DigestUpdate(self.ctx, c_char_p(data), length)
+               if result != 1:
+                       raise DigestError, "Unable to update digest"
+               
+       def digest(self, data=None):
+               """
+                       Finalizes digest operation and return digest value
+                       Optionally hashes more data before finalizing
+               """
+               if self.digest_finalized:
+                       return self.digest_out.raw[:self.digest_size]
+               if data is not None:
+                       self.update(data)
+               self.digest_out = create_string_buffer(256)
+               length = c_long(0)
+               result = libcrypto.EVP_DigestFinal_ex(self.ctx, self.digest_out, byref(length))
+               if result != 1 :
+                       raise DigestError("Unable to finalize digest")
+               self.digest_finalized = True
+               return self.digest_out.raw[:self.digest_size]
+       def copy(self):
+               """
+                       Creates copy of the digest CTX to allow to compute digest
+                       while being able to hash more data
+               """
+               new_digest=Digest(self.digest_type)
+               libcrypto.EVP_MD_CTX_copy(new_digest.ctx,self.ctx)
+               return new_digest
+
+       def _clean_ctx(self):
+               try:
+                       if self.ctx is not None:
+                               libcrypto.EVP_MD_CTX_destroy(self.ctx)
+                               del(self.ctx)
+               except AttributeError:
+                       pass
+               self.digest_out = None
+               self.digest_finalized = False
+
+       def hexdigest(self,data=None):
+               """
+                       Returns digest in the hexadecimal form. For compatibility
+                       with hashlib
+               """
+               from base64 import b16encode
+               return b16encode(self.digest(data))
+
+
+# Declare function result and argument types
+libcrypto.EVP_get_digestbyname.restype = c_void_p
+libcrypto.EVP_get_digestbyname.argtypes = (c_char_p,)
+libcrypto.EVP_MD_CTX_create.restype = c_void_p
+libcrypto.EVP_DigestInit_ex.argtypes = (c_void_p,c_void_p,c_void_p)
+libcrypto.EVP_DigestUpdate.argtypes = (c_void_p,c_char_p,c_longlong)
+libcrypto.EVP_DigestFinal_ex.argtypes = (c_void_p,c_char_p,POINTER(c_long))
+libcrypto.EVP_MD_CTX_destroy.argtypes = (c_void_p,)
+libcrypto.EVP_MD_CTX_copy.argtypes=(c_void_p, c_void_p)
+libcrypto.EVP_MD_type.argtypes=(c_void_p,)
+libcrypto.EVP_MD_size.argtypes=(c_void_p,)
+libcrypto.EVP_MD_block_size.argtypes=(c_void_p,)