]> www.wagner.pp.ru Git - oss/ctypescrypto.git/commitdiff
Fixed most pylint warning.
authorVictor Wagner <vitus@wagner.pp.ru>
Sat, 27 Jun 2015 21:34:15 +0000 (00:34 +0300)
committerVictor Wagner <vitus@wagner.pp.ru>
Sat, 27 Jun 2015 21:34:15 +0000 (00:34 +0300)
Incompatibile interface changes: DigestType methods size, block_size and name become properties

16 files changed:
ctypescrypto/__init__.py
ctypescrypto/bio.py
ctypescrypto/cipher.py
ctypescrypto/cms.py
ctypescrypto/digest.py
ctypescrypto/ec.py
ctypescrypto/engine.py
ctypescrypto/exception.py
ctypescrypto/mac.py
ctypescrypto/oid.py
ctypescrypto/pbkdf2.py
ctypescrypto/pkey.py
ctypescrypto/rand.py
ctypescrypto/x509.py
setup.py
tests/testdigest.py

index 196318843a5cd2b1b82901c6aff18a6b855368d9..ba1329ef257477fcda97ad3fbdd490a571e3a2f6 100644 (file)
@@ -4,7 +4,7 @@
 """
 
 
 """
 
 
-from ctypes import CDLL,c_char_p
+from ctypes import CDLL, c_char_p
 
 def config(filename=None):
     """
 
 def config(filename=None):
     """
@@ -16,5 +16,5 @@ def config(filename=None):
 __all__ = ['config']
 
 libcrypto = CDLL("libcrypto.so.1.0.0")
 __all__ = ['config']
 
 libcrypto = CDLL("libcrypto.so.1.0.0")
-libcrypto.OPENSSL_config.argtypes=(c_char_p,)
+libcrypto.OPENSSL_config.argtypes = (c_char_p, )
 libcrypto.OPENSSL_add_all_algorithms_conf()
 libcrypto.OPENSSL_add_all_algorithms_conf()
index 2c54212befd62372e7fb2fd54aa0cd47a96b5090..5040d0c1180487b55f3423492efc3be21fa39c5b 100644 (file)
 Interface to OpenSSL BIO library
 """
 from ctypescrypto import libcrypto
 Interface to OpenSSL BIO library
 """
 from ctypescrypto import libcrypto
-from ctypes import c_char_p, c_void_p, c_int, string_at, c_long,POINTER,byref, create_string_buffer
+from ctypes import c_char_p, c_void_p, c_int, string_at, c_long
+from ctypes import POINTER, byref, create_string_buffer
 class Membio(object):
 class Membio(object):
-    """ 
-        Provides interface to OpenSSL memory bios 
-        use str() or unicode() to get contents of writable bio
-        use bio member to pass to libcrypto function
     """
     """
-    def __init__(self,data=None):
-        """ If data is specified, creates read-only BIO. If data is
-            None, creates writable BIO, contents of which can be retrieved by str() or unicode()
+    Provides interface to OpenSSL memory bios
+    use str() or unicode() to get contents of writable bio
+    use bio member to pass to libcrypto function
+    """
+    def __init__(self, data=None):
+        """
+        If data is specified, creates read-only BIO. If data is
+        None, creates writable BIO, contents of which can be retrieved
+        by str() or unicode()
         """
         if data is None:
         """
         if data is None:
-            method=libcrypto.BIO_s_mem()
-            self.bio=libcrypto.BIO_new(method)
+            method = libcrypto.BIO_s_mem()
+            self.bio = libcrypto.BIO_new(method)
         else:
         else:
-            self.bio=libcrypto.BIO_new_mem_buf(c_char_p(data),len(data))
+            self.bio = libcrypto.BIO_new_mem_buf(c_char_p(data), len(data))
+
     def __del__(self):
         """
         Cleans up memory used by bio
         """
         libcrypto.BIO_free(self.bio)
     def __del__(self):
         """
         Cleans up memory used by bio
         """
         libcrypto.BIO_free(self.bio)
-        del(self.bio)
+        del self.bio
+
     def __str__(self):
         """
         Returns current contents of buffer as byte string
         """
     def __str__(self):
         """
         Returns current contents of buffer as byte string
         """
-        p=c_char_p(None)
-        l=libcrypto.BIO_ctrl(self.bio,3,0,byref(p))
-        return string_at(p,l)
+        string_ptr = c_char_p(None)
+        string_len = libcrypto.BIO_ctrl(self.bio, 3, 0, byref(string_ptr))
+        return string_at(string_ptr, string_len)
+
     def __unicode__(self):
         """
     def __unicode__(self):
         """
-        Attempts to interpret current contents of buffer as UTF-8 string and convert it to unicode
+        Attempts to interpret current contents of buffer as UTF-8 string
+        and convert it to unicode
         """
         return str(self).decode("utf-8")
         """
         return str(self).decode("utf-8")
-    def read(self,length=None):
+
+    def read(self, length=None):
         """
         Reads data from readble BIO. For test purposes.
         """
         Reads data from readble BIO. For test purposes.
-        @param length - if specifed, limits amount of data read. If not BIO is read until end of buffer
+        @param length - if specifed, limits amount of data read.
+        If not BIO is read until end of buffer
         """
         if not length is None:
         """
         if not length is None:
-            if not isinstance(length,(int,long)):
+            if not isinstance(length, (int, long)):
                 raise TypeError("length to read should be number")
                 raise TypeError("length to read should be number")
-            buf=create_string_buffer(length)
-            readbytes=libcrypto.BIO_read(self.bio,buf,length)
-            if readbytes==-2:
-                raise NotImplementedError("Function is not supported by this BIO")
-            if readbytes==-1:
+            buf = create_string_buffer(length)
+            readbytes = libcrypto.BIO_read(self.bio, buf, length)
+            if readbytes == -2:
+                raise NotImplementedError("Function is not supported by" +
+                                          "this BIO")
+            if readbytes == -1:
                 raise IOError
                 raise IOError
-            if readbytes==0:
+            if readbytes == 0:
                 return ""
             return buf.raw[:readbytes]
         else:
                 return ""
             return buf.raw[:readbytes]
         else:
-            buf=create_string_buffer(1024)
-            out=""
-            r=1
-            while r>0:
-                r=libcrypto.BIO_read(self.bio,buf,1024)
-                if r==-2:
-                    raise NotImplementedError("Function is not supported by this BIO")
-                if r==-1:
+            buf = create_string_buffer(1024)
+            out = ""
+            readbytes = 1
+            while readbytes > 0:
+                readbytes = libcrypto.BIO_read(self.bio, buf, 1024)
+                if readbytes == -2:
+                    raise NotImplementedError("Function is not supported by " +
+                                              "this BIO")
+                if readbytes == -1:
                     raise IOError
                     raise IOError
-                if (r>0):
-                    out+=buf.raw[:r]
-            return out  
+                if readbytes > 0:
+                    out += buf.raw[:readbytes]
+            return out
 
 
-    def write(self,data):
+    def write(self, data):
         """
         Writes data to writable bio. For test purposes
         """
         """
         Writes data to writable bio. For test purposes
         """
-        if isinstance(data,unicode):
-            data=data.encode("utf-8")
-        r=libcrypto.BIO_write(self.bio,data,len(data))
-        if r==-2:
+        if isinstance(data, unicode):
+            data = data.encode("utf-8")
+        else:
+            data = str(data)
+
+        written = libcrypto.BIO_write(self.bio, data, len(data))
+        if written == -2:
             raise NotImplementedError("Function not supported by this BIO")
             raise NotImplementedError("Function not supported by this BIO")
-        if r<len(data):
+        if written < len(data):
             raise IOError("Not all data were successfully written")
             raise IOError("Not all data were successfully written")
+
     def reset(self):
         """
     def reset(self):
         """
-        Resets the read-only bio to start and discards all data from writable bio
+        Resets the read-only bio to start and discards all data from
+        writable bio
         """
         """
-        libcrypto.BIO_ctrl(self.bio,1,0,None)
+        libcrypto.BIO_ctrl(self.bio, 1, 0, None)
 
 __all__ = ['Membio']
 
 __all__ = ['Membio']
-libcrypto.BIO_s_mem.restype=c_void_p
-libcrypto.BIO_new.restype=c_void_p
-libcrypto.BIO_new.argtypes=(c_void_p,)
-libcrypto.BIO_ctrl.restype=c_long
-libcrypto.BIO_ctrl.argtypes=(c_void_p,c_int,c_long,POINTER(c_char_p))
-libcrypto.BIO_read.argtypes=(c_void_p,c_char_p,c_int)
-libcrypto.BIO_write.argtypes=(c_void_p,c_char_p,c_int)
-libcrypto.BIO_free.argtypes=(c_void_p,)
-libcrypto.BIO_new_mem_buf.restype=c_void_p
-libcrypto.BIO_new_mem_buf.argtypes=(c_char_p,c_int)
-libcrypto.BIO_ctrl.argtypes=(c_void_p,c_int,c_int,c_void_p)
+libcrypto.BIO_s_mem.restype = c_void_p
+libcrypto.BIO_new.restype = c_void_p
+libcrypto.BIO_new.argtypes = (c_void_p, )
+libcrypto.BIO_ctrl.restype = c_long
+libcrypto.BIO_ctrl.argtypes = (c_void_p, c_int, c_long, POINTER(c_char_p))
+libcrypto.BIO_read.argtypes = (c_void_p, c_char_p, c_int)
+libcrypto.BIO_write.argtypes = (c_void_p, c_char_p, c_int)
+libcrypto.BIO_free.argtypes = (c_void_p, )
+libcrypto.BIO_new_mem_buf.restype = c_void_p
+libcrypto.BIO_new_mem_buf.argtypes = (c_char_p, c_int)
index 63373d6bf404d0cd339c8391339db6fa5a6bf764..d4035c1a34a8a5ec909578491b19a7cc5670138b 100644 (file)
 access to symmetric ciphers from libcrypto
 
 """
 access to symmetric ciphers from libcrypto
 
 """
-from ctypes import create_string_buffer,c_char_p,c_void_p,c_int,c_long,byref,POINTER
+from ctypes import create_string_buffer, c_char_p, c_void_p, c_int
+from ctypes import byref, POINTER
 from ctypescrypto import libcrypto
 from ctypescrypto.exception import LibCryptoError
 from ctypescrypto.oid import Oid
 
 CIPHER_ALGORITHMS = ("DES", "DES-EDE3", "BF", "AES-128", "AES-192", "AES-256")
 from ctypescrypto import libcrypto
 from ctypescrypto.exception import LibCryptoError
 from ctypescrypto.oid import Oid
 
 CIPHER_ALGORITHMS = ("DES", "DES-EDE3", "BF", "AES-128", "AES-192", "AES-256")
-CIPHER_MODES = ("STREAM","ECB","CBC", "CFB", "OFB", "CTR","GCM")
+CIPHER_MODES = ("STREAM", "ECB", "CBC", "CFB", "OFB", "CTR", "GCM")
 
 #
 
 
 #
 
-__all__ = ['CipherError','new','Cipher','CipherType']
+__all__ = ['CipherError', 'new', 'Cipher', 'CipherType']
 
 class CipherError(LibCryptoError):
 
 class CipherError(LibCryptoError):
+    """
+    Exception raise when OpenSSL function returns error
+    """
     pass
 
     pass
 
-def new(algname,key,encrypt=True,iv=None):
+def new(algname, key, encrypt=True, iv=None):
     """
     """
-        Returns new cipher object ready to encrypt-decrypt data
+    Returns new cipher object ready to encrypt-decrypt data
 
 
-        @param algname - string algorithm name like in opemssl command
-                        line
-        @param key - binary string representing ciher key
-        @param encrypt - if True (default) cipher would be initialized
+    @param algname - string algorithm name like in opemssl command
+                     line
+    @param key - binary string representing ciher key
+    @param encrypt - if True (default) cipher would be initialized
                     for encryption, otherwise - for decrypton
                     for encryption, otherwise - for decrypton
-        @param iv - initialization vector
+    @param iv - initialization vector
     """
     """
-    ct=CipherType(algname)
-    return Cipher(ct,key,iv,encrypt)
+    ciph_type = CipherType(algname)
+    return Cipher(ciph_type, key, iv, encrypt)
 
 
-class CipherType:
+class CipherType(object):
     """
     """
-        Describes cihper algorihm. Can be used to produce cipher
-        instance and to get various information about cihper
+    Describes cihper algorihm. Can be used to produce cipher
+    instance and to get various information about cihper
     """
 
     def __init__(self, cipher_name):
         """
     """
 
     def __init__(self, cipher_name):
         """
-            Constructs cipher algortihm using textual name as in openssl
-            command line
+        Constructs cipher algortihm using textual name as in openssl
+        command line
         """
         self.cipher = libcrypto.EVP_get_cipherbyname(cipher_name)
         if self.cipher is None:
             raise CipherError("Unknown cipher: %s" % cipher_name)
 
     def __del__(self):
         """
         self.cipher = libcrypto.EVP_get_cipherbyname(cipher_name)
         if self.cipher is None:
             raise CipherError("Unknown cipher: %s" % cipher_name)
 
     def __del__(self):
+        """
+        It is constant object with do-nothing del
+        """
         pass
         pass
+
     def block_size(self):
         """
     def block_size(self):
         """
-            Returns block size of the cipher
+        Returns block size of the cipher
         """
         return libcrypto.EVP_CIPHER_block_size(self.cipher)
         """
         return libcrypto.EVP_CIPHER_block_size(self.cipher)
+
     def key_length(self):
         """
     def key_length(self):
         """
-            Returns key length of the cipher
+        Returns key length of the cipher
         """
         return libcrypto.EVP_CIPHER_key_length(self.cipher)
         """
         return libcrypto.EVP_CIPHER_key_length(self.cipher)
+
     def iv_length(self):
         """
     def iv_length(self):
         """
-            Returns initialization vector length of the cipher
+        Returns initialization vector length of the cipher
         """
         return libcrypto.EVP_CIPHER_iv_length(self.cipher)
         """
         return libcrypto.EVP_CIPHER_iv_length(self.cipher)
+
     def flags(self):
         """
     def flags(self):
         """
-            Return cipher flags. Low three bits of the flags encode 
-            cipher mode (see mode). Higher bits  is combinatuon of
-            EVP_CIPH* constants defined in the <openssl/evp.h>
+        Return cipher flags. Low three bits of the flags encode
+        cipher mode (see mode). Higher bits  is combinatuon of
+        EVP_CIPH* constants defined in the <openssl/evp.h>
         """
         return libcrypto.EVP_CIPHER_flags(self.cipher)
         """
         return libcrypto.EVP_CIPHER_flags(self.cipher)
+
     def mode(self):
         """
     def mode(self):
         """
-            Returns cipher mode as string constant like CBC, OFB etc.
+        Returns cipher mode as string constant like CBC, OFB etc.
         """
         return CIPHER_MODES[self.flags() & 0x7]
         """
         return CIPHER_MODES[self.flags() & 0x7]
+
     def algo(self):
         """
     def algo(self):
         """
-            Return cipher's algorithm name, derived from OID
+        Return cipher's algorithm name, derived from OID
         """
         """
-        return self.oid().shortname() 
+        return self.oid().shortname()
+
     def oid(self):
         """
     def oid(self):
         """
-            Returns ASN.1 object identifier of the cipher as
-            ctypescrypto.oid.Oid object
+        Returns ASN.1 object identifier of the cipher as
+        ctypescrypto.oid.Oid object
         """
         return Oid(libcrypto.EVP_CIPHER_nid(self.cipher))
 
         """
         return Oid(libcrypto.EVP_CIPHER_nid(self.cipher))
 
-class Cipher:
+class Cipher(object):
     """
     """
-        Performs actual encrypton decryption
-        Note that object keeps some internal state. 
-        To obtain full ciphertext (or plaintext during decihpering)
-        user should concatenate results of all calls of update with
-        result of finish
+    Performs actual encrypton decryption
+    Note that object keeps some internal state.
+    To obtain full ciphertext (or plaintext during decihpering)
+    user should concatenate results of all calls of update with
+    result of finish
     """
     """
-    def __init__(self,  cipher_type, key, iv, encrypt=True):
+    def __init__(self, cipher_type, key, iv, encrypt=True):
         """
         """
-            Initializing cipher instance.
+        Initializing cipher instance.
 
 
-            @param  cipher_type - CipherType object
-            @param key = binary string representing the key
-            @param iv - binary string representing initializtion vector
-            @param encrypt - if True(default) we ere encrypting.
-                    Otherwise decrypting
+        @param cipher_type - CipherType object
+        @param key = binary string representing the key
+        @param iv - binary string representing initializtion vector
+        @param encrypt - if True(default) we ere encrypting.
+               Otherwise decrypting
 
         """
         self._clean_ctx()
 
         """
         self._clean_ctx()
@@ -117,23 +131,31 @@ class Cipher:
         if self.ctx == 0:
             raise CipherError("Unable to create cipher context")
         self.encrypt = encrypt
         if self.ctx == 0:
             raise CipherError("Unable to create cipher context")
         self.encrypt = encrypt
-        enc=1 if encrypt else 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")
         if not iv is None and len(iv) != cipher_type.iv_length():
             raise ValueError("Invalid IV length for this algorithm")
-            
+
         if len(key) != cipher_type.key_length():
             if (cipher_type.flags() & 8) != 0:
                 # Variable key length cipher.
         if len(key) != cipher_type.key_length():
             if (cipher_type.flags() & 8) != 0:
                 # Variable key length cipher.
-                result = libcrypto.EVP_CipherInit_ex(self.ctx, cipher_type.cipher, None, None, None, c_int(enc))
-                result = libcrypto.EVP_CIPHER_CTX_set_key_length(self.ctx,len(key))
+                result = libcrypto.EVP_CipherInit_ex(self.ctx,
+                                                     cipher_type.cipher,
+                                                     None, None, None,
+                                                     c_int(enc))
+                result = libcrypto.EVP_CIPHER_CTX_set_key_length(self.ctx,
+                                                                 len(key))
                 if result == 0:
                     self._clean_ctx()
                     raise CipherError("Unable to set key length")
                 if result == 0:
                     self._clean_ctx()
                     raise CipherError("Unable to set key length")
-                result = libcrypto.EVP_CipherInit_ex(self.ctx, None, None, key_ptr, iv_ptr, c_int(enc))
+                result = libcrypto.EVP_CipherInit_ex(self.ctx, None, None,
+                                                     key_ptr, iv_ptr,
+                                                     c_int(enc))
             else:
                 raise ValueError("Invalid key length for this algorithm")
         else:
             else:
                 raise ValueError("Invalid key length for this algorithm")
         else:
-            result = libcrypto.EVP_CipherInit_ex(self.ctx, cipher_type.cipher, None, key_ptr, iv_ptr, c_int(enc))
+            result = libcrypto.EVP_CipherInit_ex(self.ctx, cipher_type.cipher,
+                                                 None, key_ptr, iv_ptr,
+                                                 c_int(enc))
         if result == 0:
             self._clean_ctx()
             raise CipherError("Unable to initialize cipher")
         if result == 0:
             self._clean_ctx()
             raise CipherError("Unable to initialize cipher")
@@ -142,69 +164,74 @@ class Cipher:
         self.cipher_finalized = False
 
     def __del__(self):
         self.cipher_finalized = False
 
     def __del__(self):
+        """
+        We define _clean_ctx() to do all the cleanup
+        """
         self._clean_ctx()
 
     def padding(self, padding=True):
         """
         self._clean_ctx()
 
     def padding(self, padding=True):
         """
-            Sets padding mode of the cipher
+        Sets padding mode of the cipher
         """
         """
-        padding_flag=1 if padding else 0
+        padding_flag = 1 if padding else 0
         libcrypto.EVP_CIPHER_CTX_set_padding(self.ctx, padding_flag)
 
     def update(self, data):
         """
         libcrypto.EVP_CIPHER_CTX_set_padding(self.ctx, padding_flag)
 
     def update(self, data):
         """
-            Performs actual encrypton/decrypion
+        Performs actual encrypton/decrypion
 
 
-            @param data - part of the plain text/ciphertext to process
-            @returns - part of ciphercext/plain text
+        @param data - part of the plain text/ciphertext to process
+        @returns - part of ciphercext/plain text
 
 
-            Passd chunk of text doeesn't need to contain full ciher
-            blocks. If neccessery, part of passed data would be kept
-            internally until next data would be received or finish
-            called
+        Passed chunk of text doesn't need to contain full ciher
+        blocks. If neccessery, part of passed data would be kept
+        internally until next data would be received or finish
+        called
         """
         """
-        if self.cipher_finalized :
+        if self.cipher_finalized:
             raise CipherError("No updates allowed")
             raise CipherError("No updates allowed")
-        if not isinstance(data,str):
+        if not isinstance(data, str):
             raise TypeError("A string is expected")
         if len(data) == 0:
             return ""
             raise TypeError("A string is expected")
         if len(data) == 0:
             return ""
-        outbuf=create_string_buffer(self.block_size+len(data))
-        outlen=c_int(0)
-        ret=libcrypto.EVP_CipherUpdate(self.ctx,outbuf,byref(outlen),
-            data,len(data))
-        if ret <=0:
+        outbuf = create_string_buffer(self.block_size+len(data))
+        outlen = c_int(0)
+        ret = libcrypto.EVP_CipherUpdate(self.ctx, outbuf, byref(outlen),
+                                         data, len(data))
+        if ret <= 0:
             self._clean_ctx()
             self._clean_ctx()
-            self.cipher_finalized=True
-            del self.ctx
+            self.cipher_finalized = True
             raise CipherError("problem processing data")
             raise CipherError("problem processing data")
-        return outbuf.raw[:outlen.value]
-    
+        return outbuf.raw[:int(outlen.value)]
+
     def finish(self):
         """
     def finish(self):
         """
-            Finalizes processing. If some data are kept in the internal
-            state, they would be processed and returned.
+        Finalizes processing. If some data are kept in the internal
+        state, they would be processed and returned.
         """
         """
-        if self.cipher_finalized :
+        if self.cipher_finalized:
             raise CipherError("Cipher operation is already completed")
             raise CipherError("Cipher operation is already completed")
-        outbuf=create_string_buffer(self.block_size)
+        outbuf = create_string_buffer(self.block_size)
         self.cipher_finalized = True
         self.cipher_finalized = True
-        outlen=c_int(0)
-        result = libcrypto.EVP_CipherFinal_ex(self.ctx,outbuf , byref(outlen))
+        outlen = c_int(0)
+        result = libcrypto.EVP_CipherFinal_ex(self.ctx, outbuf, byref(outlen))
         if result == 0:
             self._clean_ctx()
             raise CipherError("Unable to finalize cipher")
         if result == 0:
             self._clean_ctx()
             raise CipherError("Unable to finalize cipher")
-        if outlen.value>0:
-            return outbuf.raw[:outlen.value]
+        if outlen.value > 0:
+            return outbuf.raw[:int(outlen.value)]
         else:
             return ""
         else:
             return ""
-        
+
     def _clean_ctx(self):
     def _clean_ctx(self):
+        """
+        Cleans up cipher ctx and deallocates it
+        """
         try:
             if self.ctx is not None:
                 libcrypto.EVP_CIPHER_CTX_cleanup(self.ctx)
                 libcrypto.EVP_CIPHER_CTX_free(self.ctx)
         try:
             if self.ctx is not None:
                 libcrypto.EVP_CIPHER_CTX_cleanup(self.ctx)
                 libcrypto.EVP_CIPHER_CTX_free(self.ctx)
-                del(self.ctx)
+                del self.ctx
         except AttributeError:
             pass
         self.cipher_finalized = True
         except AttributeError:
             pass
         self.cipher_finalized = True
@@ -213,18 +240,20 @@ class Cipher:
 #
 # Used C function block_size
 #
 #
 # Used C function block_size
 #
-libcrypto.EVP_CIPHER_block_size.argtypes=(c_void_p,)
-libcrypto.EVP_CIPHER_CTX_cleanup.argtypes=(c_void_p,)
-libcrypto.EVP_CIPHER_CTX_free.argtypes=(c_void_p,)
-libcrypto.EVP_CIPHER_CTX_new.restype=c_void_p
-libcrypto.EVP_CIPHER_CTX_set_padding.argtypes=(c_void_p,c_int)
-libcrypto.EVP_CipherFinal_ex.argtypes=(c_void_p,c_char_p,POINTER(c_int))
-libcrypto.EVP_CIPHER_flags.argtypes=(c_void_p,)
-libcrypto.EVP_CipherInit_ex.argtypes=(c_void_p,c_void_p,c_void_p,c_char_p,c_char_p,c_int)
-libcrypto.EVP_CIPHER_iv_length.argtypes=(c_void_p,)
-libcrypto.EVP_CIPHER_key_length.argtypes=(c_void_p,)
-libcrypto.EVP_CIPHER_nid.argtypes=(c_void_p,)
-libcrypto.EVP_CipherUpdate.argtypes=(c_void_p,c_char_p,POINTER(c_int),c_char_p,c_int)
-libcrypto.EVP_get_cipherbyname.restype=c_void_p
-libcrypto.EVP_get_cipherbyname.argtypes=(c_char_p,)
-libcrypto.EVP_CIPHER_CTX_set_key_length.argtypes=(c_void_p,c_int)
+libcrypto.EVP_CIPHER_block_size.argtypes = (c_void_p, )
+libcrypto.EVP_CIPHER_CTX_cleanup.argtypes = (c_void_p, )
+libcrypto.EVP_CIPHER_CTX_free.argtypes = (c_void_p, )
+libcrypto.EVP_CIPHER_CTX_new.restype = c_void_p
+libcrypto.EVP_CIPHER_CTX_set_padding.argtypes = (c_void_p, c_int)
+libcrypto.EVP_CipherFinal_ex.argtypes = (c_void_p, c_char_p, POINTER(c_int))
+libcrypto.EVP_CIPHER_flags.argtypes = (c_void_p, )
+libcrypto.EVP_CipherInit_ex.argtypes = (c_void_p, c_void_p, c_void_p, c_char_p,
+                                        c_char_p, c_int)
+libcrypto.EVP_CIPHER_iv_length.argtypes = (c_void_p, )
+libcrypto.EVP_CIPHER_key_length.argtypes = (c_void_p, )
+libcrypto.EVP_CIPHER_nid.argtypes = (c_void_p, )
+libcrypto.EVP_CipherUpdate.argtypes = (c_void_p, c_char_p, POINTER(c_int),
+                                       c_char_p, c_int)
+libcrypto.EVP_get_cipherbyname.restype = c_void_p
+libcrypto.EVP_get_cipherbyname.argtypes = (c_char_p, )
+libcrypto.EVP_CIPHER_CTX_set_key_length.argtypes = (c_void_p, c_int)
index 68f9c3f229626b9b544f7566b813fac9175be642..bc27e9e34f8d14cd09e63e6343fc8465610ba755 100644 (file)
@@ -10,11 +10,12 @@ create it from raw data and neccessary certificates.
 
 
 """
 
 
 """
-from ctypes import c_int, c_void_p, c_char_p, c_int
+from ctypes import c_int, c_void_p, c_char_p, c_int, c_uint, c_size_t, POINTER
 from ctypescrypto.exception import LibCryptoError
 from ctypescrypto import libcrypto
 from ctypescrypto.bio import Membio
 from ctypescrypto.oid import Oid
 from ctypescrypto.exception import LibCryptoError
 from ctypescrypto import libcrypto
 from ctypescrypto.bio import Membio
 from ctypescrypto.oid import Oid
+from ctypescrypto.x509 import StackOfX509
 
 class CMSError(LibCryptoError):
     """
 
 class CMSError(LibCryptoError):
     """
@@ -24,108 +25,112 @@ class CMSError(LibCryptoError):
 
 class Flags:
     """
 
 class Flags:
     """
-    Constants for flags passed to the CMS methods. 
+    Constants for flags passed to the CMS methods.
     Can be OR-ed together
     """
     Can be OR-ed together
     """
-    TEXT=1
-    NOCERTS=2
-    NO_CONTENT_VERIFY=4
-    NO_ATTR_VERIFY=8
-    NO_SIGS=NO_CONTENT_VERIFY|NO_ATTR_VERIFY
-    NOINTERN=0x10
-    NO_SIGNER_CERT_VERIFY=0x20
-    NO_VERIFY=0x20
-    DETACHED=0x40
-    BINARY=0x80
-    NOATTR=0x100
-    NOSMIMECAP =0x200
-    NOOLDMIMETYPE=0x400
-    CRLFEOL=0x800
-    STREAM=0x1000
-    NOCRL=0x2000
-    PARTIAL=0x4000
-    REUSE_DIGEST=0x8000
-    USE_KEYID=0x10000
-    DEBUG_DECRYPT=0x20000
+    TEXT = 1
+    NOCERTS = 2
+    NO_CONTENT_VERIFY = 4
+    NO_ATTR_VERIFY = 8
+    NO_SIGS = NO_CONTENT_VERIFY | NO_ATTR_VERIFY
+    NOINTERN = 0x10
+    NO_SIGNER_CERT_VERIFY = 0x20
+    NO_VERIFY = 0x20
+    DETACHED = 0x40
+    BINARY = 0x80
+    NOATTR = 0x100
+    NOSMIMECAP = 0x200
+    NOOLDMIMETYPE = 0x400
+    CRLFEOL = 0x800
+    STREAM = 0x1000
+    NOCRL = 0x2000
+    PARTIAL = 0x4000
+    REUSE_DIGEST = 0x8000
+    USE_KEYID = 0x10000
+    DEBUG_DECRYPT = 0x20000
 
 
-def CMS(data,format="PEM"):
+def CMS(data, format="PEM"):
     """
     Parses CMS data and returns either SignedData or EnvelopedData
     object
     """
     """
     Parses CMS data and returns either SignedData or EnvelopedData
     object
     """
-    b=Membio(data)
+    bio = Membio(data)
     if format == "PEM":
     if format == "PEM":
-        ptr=libcrypto.PEM_read_bio_CMS(b.bio,None,None,None)
+        ptr = libcrypto.PEM_read_bio_CMS(bio.bio, None, None, None)
     else:
     else:
-        ptr=libcrypto.d2i_CMS_bio(b.bio,None)
+        ptr = libcrypto.d2i_CMS_bio(bio.bio, None)
     typeoid = Oid(libcrypto.OBJ_obj2nid(libcrypto.CMS_get0_type(ptr)))
     typeoid = Oid(libcrypto.OBJ_obj2nid(libcrypto.CMS_get0_type(ptr)))
-    if typeoid.shortname()=="pkcs7-signedData":
+    if typeoid.shortname() == "pkcs7-signedData":
         return SignedData(ptr)
         return SignedData(ptr)
-    elif typeoid.shortname()=="pkcs7-envelopedData":
+    elif typeoid.shortname() == "pkcs7-envelopedData":
         return EnvelopedData(ptr)
         return EnvelopedData(ptr)
-    elif typeoid.shortname()=="pkcs7-encryptedData":
+    elif typeoid.shortname() == "pkcs7-encryptedData":
         return EncryptedData(ptr)
     else:
         raise NotImplementedError("cannot handle "+typeoid.shortname())
 
         return EncryptedData(ptr)
     else:
         raise NotImplementedError("cannot handle "+typeoid.shortname())
 
-class CMSBase(object): 
+class CMSBase(object):
     """
     Common ancessor for all CMS types.
     Implements serializatio/deserialization
     """
     """
     Common ancessor for all CMS types.
     Implements serializatio/deserialization
     """
-    def __init__(self,ptr=None):
-        self.ptr=ptr
+    def __init__(self, ptr=None):
+        self.ptr = ptr
     def __str__(self):
         """
         Serialize in DER format
         """
     def __str__(self):
         """
         Serialize in DER format
         """
-        b=Membio()
-        if not libcrypto.i2d_CMS_bio(b.bio,self.ptr):
+        bio = Membio()
+        if not libcrypto.i2d_CMS_bio(bio.bio, self.ptr):
             raise CMSError("writing CMS to PEM")
             raise CMSError("writing CMS to PEM")
-        return str(b)
+        return str(bio)
 
     def pem(self):
         """
         Serialize in PEM format
         """
 
     def pem(self):
         """
         Serialize in PEM format
         """
-        b=Membio()
-        if not libcrypto.PEM_write_bio_CMS(b.bio,self.ptr):
+        bio = Membio()
+        if not libcrypto.PEM_write_bio_CMS(bio.bio, self.ptr):
             raise CMSError("writing CMS to PEM")
             raise CMSError("writing CMS to PEM")
-        return str(b)
-        
-    
-        
+        return str(bio)
+
+
+#pylint: disable=R0921
 class SignedData(CMSBase):
 class SignedData(CMSBase):
+    """
+    Represents signed message (signeddata CMS type)
+    """
     @staticmethod
     @staticmethod
-    def create(data,cert,pkey,flags=Flags.BINARY,certs=[]):
+    def create(data, cert, pkey, flags=Flags.BINARY, certs=None):
         """
             Creates SignedData message by signing data with pkey and
             certificate.
 
             @param data - data to sign
         """
             Creates SignedData message by signing data with pkey and
             certificate.
 
             @param data - data to sign
+            @param cert - signer's certificate
             @param pkey - pkey object with private key to sign
             @param flags - OReed combination of Flags constants
             @param certs - list of X509 objects to include into CMS
         """
         if not pkey.cansign:
             raise ValueError("Specified keypair has no private part")
             @param pkey - pkey object with private key to sign
             @param flags - OReed combination of Flags constants
             @param certs - list of X509 objects to include into CMS
         """
         if not pkey.cansign:
             raise ValueError("Specified keypair has no private part")
-        if cert.pubkey!=pkey:
+        if cert.pubkey != pkey:
             raise ValueError("Certificate doesn't match public key")
             raise ValueError("Certificate doesn't match public key")
-        b=Membio(data)
-        if certs is not None and len(certs)>0:
-            certstack=StackOfX509(certs)
+        bio = Membio(data)
+        if certs is not None and len(certs) > 0:
+            certstack = StackOfX509(certs)
         else:
         else:
-            certstack=None
-        ptr=libcrypto.CMS_sign(cert.cert,pkey.ptr,certstack,b.bio,flags)
+            certstack = None
+        ptr = libcrypto.CMS_sign(cert.cert, pkey.ptr, certstack, bio.bio, flags)
         if ptr is None:
             raise CMSError("signing message")
         return SignedData(ptr)
         if ptr is None:
             raise CMSError("signing message")
         return SignedData(ptr)
-    def sign(self,cert,pkey,md=None,data=None,flags=Flags.BINARY):
+    def sign(self, cert, pkey, digest_type=None, data=None, flags=Flags.BINARY):
         """
             Adds another signer to already signed message
             @param cert - signer's certificate
             @param pkey - signer's private key
         """
             Adds another signer to already signed message
             @param cert - signer's certificate
             @param pkey - signer's private key
-            @param md - message digest to use as DigestType object 
+            @param digest_type - message digest to use as DigestType object
                 (if None - default for key would be used)
             @param data - data to sign (if detached and
                     Flags.REUSE_DIGEST is not specified)
                 (if None - default for key would be used)
             @param data - data to sign (if detached and
                     Flags.REUSE_DIGEST is not specified)
@@ -133,22 +138,21 @@ class SignedData(CMSBase):
         """
         if not pkey.cansign:
             raise ValueError("Specified keypair has no private part")
         """
         if not pkey.cansign:
             raise ValueError("Specified keypair has no private part")
-        if cert.pubkey!=pkey:
+        if cert.pubkey != pkey:
             raise ValueError("Certificate doesn't match public key")
             raise ValueError("Certificate doesn't match public key")
-        p1=libcrypto.CMS_sign_add1_Signer(self.ptr,cert.cert,pkey.ptr,
-            md.digest,flags)
-        if p1 is None:
+        if libcrypto.CMS_sign_add1_Signer(self.ptr, cert.cert, pkey.ptr,
+                                          digest_type.digest, flags) is None:
             raise CMSError("adding signer")
             raise CMSError("adding signer")
-        if flags & Flags.REUSE_DIGEST==0:
+        if flags & Flags.REUSE_DIGEST == 0:
             if data is not None:
             if data is not None:
-                b=Membio(data)
-                biodata=b.bio
+                bio = Membio(data)
+                biodata = bio.bio
             else:
             else:
-                biodata=None
-            res= libcrypto.CMS_final(self.ptr,biodata,None,flags)
-            if res<=0:
-                raise CMSError
-    def verify(self,store,flags,data=None,certs=[]):
+                biodata = None
+            res = libcrypto.CMS_final(self.ptr, biodata, None, flags)
+            if res <= 0:
+                raise CMSError("Cannot finalize CMS")
+    def verify(self, store, flags, data=None, certs=None):
         """
         Verifies signature under CMS message using trusted cert store
 
         """
         Verifies signature under CMS message using trusted cert store
 
@@ -160,42 +164,47 @@ class SignedData(CMSBase):
                 sertificates to search for signing certificates
         @returns True if signature valid, False otherwise
         """
                 sertificates to search for signing certificates
         @returns True if signature valid, False otherwise
         """
-        bio=None
-        if data!=None:
-            b=Membio(data)
-            bio=b.bio
-        if certs is not None and len(certs)>0:
-            certstack=StackOfX509(certs)
+        bio = None
+        if data != None:
+            bio_obj = Membio(data)
+            bio = bio_obj.bio
+        if certs is not None and len(certs) > 0:
+            certstack = StackOfX509(certs)
         else:
         else:
-            certstack=None
-        res=libcrypto.CMS_verify(self.ptr,certstack,store.store,bio,None,flags)
-        return res>0
-    @property   
+            certstack = None
+        res = libcrypto.CMS_verify(self.ptr, certstack, store.store, bio,
+                                   None, flags)
+        return res > 0
+
+    @property
     def signers(self):
         """
         Return list of signer's certificates
         """
     def signers(self):
         """
         Return list of signer's certificates
         """
-        p=libcrypto.CMS_get0_signers(self.ptr)
-        if p is None:
-            raise CMSError
-        return StackOfX509(ptr=p,disposable=False)
+        signerlist = libcrypto.CMS_get0_signers(self.ptr)
+        if signerlist is None:
+            raise CMSError("Cannot get signers")
+        return StackOfX509(ptr=signerlist, disposable=False)
+
     @property
     def data(self):
         """
         Returns signed data if present in the message
         """
     @property
     def data(self):
         """
         Returns signed data if present in the message
         """
-        b=Membio()
-        if not libcrypto.CMS_verify(self.ptr,None,None,None,b.bio,Flags.NO_VERIFY):
+        bio = Membio()
+        if not libcrypto.CMS_verify(self.ptr, None, None, None, bio.bio,
+                                    Flags.NO_VERIFY):
             raise CMSError("extract data")
             raise CMSError("extract data")
-        return str(b)
-    def addcert(self,cert):
+        return str(bio)
+
+    def addcert(self, cert):
         """
         Adds a certificate (probably intermediate CA) to the SignedData
         structure
         """
         """
         Adds a certificate (probably intermediate CA) to the SignedData
         structure
         """
-        if libcrypto.CMS_add1_cert(self.ptr,cert.cert)<=0:
-            raise CMSError("adding cert")
-    def addcrl(self,crl):
+        if libcrypto.CMS_add1_cert(self.ptr, cert.cert) <= 0:
+            raise CMSError("Cannot add cert")
+    def addcrl(self, crl):
         """
         Adds a CRL to the signed data structure
         """
         """
         Adds a CRL to the signed data structure
         """
@@ -205,10 +214,10 @@ class SignedData(CMSBase):
         """
         List of the certificates contained in the structure
         """
         """
         List of the certificates contained in the structure
         """
-        p=CMS_get1_certs(self.ptr)
-        if p is None:
+        certstack = libcrypto.CMS_get1_certs(self.ptr)
+        if certstack is None:
             raise CMSError("getting certs")
             raise CMSError("getting certs")
-        return StackOfX509(ptr=p,disposable=True)
+        return StackOfX509(ptr=certstack, disposable=True)
     @property
     def crls(self):
         """
     @property
     def crls(self):
         """
@@ -217,8 +226,12 @@ class SignedData(CMSBase):
         raise NotImplementedError
 
 class EnvelopedData(CMSBase):
         raise NotImplementedError
 
 class EnvelopedData(CMSBase):
+    """
+    Represents EnvelopedData CMS, i.e. message encrypted with session
+    keys, encrypted with recipient's public keys
+    """
     @staticmethod
     @staticmethod
-    def create(recipients,data,cipher,flags=0):
+    def create(recipients, data, cipher, flags=0):
         """
         Creates and encrypts message
         @param recipients - list of X509 objects
         """
         Creates and encrypts message
         @param recipients - list of X509 objects
@@ -226,13 +239,15 @@ class EnvelopedData(CMSBase):
         @param cipher - CipherType object
         @param flags - flag
         """
         @param cipher - CipherType object
         @param flags - flag
         """
-        recp=StackOfX509(recipients)
-        b=Membio(data)
-        p=libcrypto.CMS_encrypt(recp.ptr,b.bio,cipher.cipher_type,flags)
-        if p is None:
+        recp = StackOfX509(recipients)
+        bio = Membio(data)
+        cms_ptr = libcrypto.CMS_encrypt(recp.ptr, bio.bio, cipher.cipher_type,
+                                        flags)
+        if cms_ptr is None:
             raise CMSError("encrypt EnvelopedData")
             raise CMSError("encrypt EnvelopedData")
-        return EnvelopedData(p)
-    def decrypt(self,pkey,cert,flags=0):
+        return EnvelopedData(cms_ptr)
+
+    def decrypt(self, pkey, cert, flags=0):
         """
         Decrypts message
         @param pkey - private key to decrypt
         """
         Decrypts message
         @param pkey - private key to decrypt
@@ -245,15 +260,20 @@ class EnvelopedData(CMSBase):
             raise ValueError("Specified keypair has no private part")
         if pkey != cert.pubkey:
             raise ValueError("Certificate doesn't match private key")
             raise ValueError("Specified keypair has no private part")
         if pkey != cert.pubkey:
             raise ValueError("Certificate doesn't match private key")
-        b=Membio()
-        res=libcrypto.CMS_decrypt(self.ptr,pkey.ptr,cert.ccert,None,b.bio,flags)
-        if res<=0:
+        bio = Membio()
+        res = libcrypto.CMS_decrypt(self.ptr, pkey.ptr, cert.ccert, None,
+                                    bio.bio, flags)
+        if res <= 0:
             raise CMSError("decrypting CMS")
             raise CMSError("decrypting CMS")
-        return str(b)
+        return str(bio)
 
 class EncryptedData(CMSBase):
 
 class EncryptedData(CMSBase):
+    """
+    Represents encrypted data CMS structure, i.e. encrypted
+    with symmetric key, shared by sender and recepient.
+    """
     @staticmethod
     @staticmethod
-    def create(data,cipher,key,flags=0):
+    def create(data, cipher, key, flags=0):
         """
         Creates an EncryptedData message.
         @param data data to encrypt
         """
         Creates an EncryptedData message.
         @param data data to encrypt
@@ -262,24 +282,61 @@ class EncryptedData(CMSBase):
         @param key - byte array used as simmetic key
         @param flags - OR-ed combination of Flags constant
         """
         @param key - byte array used as simmetic key
         @param flags - OR-ed combination of Flags constant
         """
-        b=Membio(data)
-        ptr=libcrypto.CMS_EncryptedData_encrypt(b.bio,cipher.cipher_type,key,len(key),flags)
+        bio = Membio(data)
+        ptr = libcrypto.CMS_EncryptedData_encrypt(bio.bio, cipher.cipher_type,
+                                                  key, len(key), flags)
         if ptr is None:
             raise CMSError("encrypt data")
         return EncryptedData(ptr)
         if ptr is None:
             raise CMSError("encrypt data")
         return EncryptedData(ptr)
-    def decrypt(self,key,flags=0):
+
+    def decrypt(self, key, flags=0):
         """
         Decrypts encrypted data message
         @param key - symmetic key to decrypt
         @param flags - OR-ed combination of Flags constant
         """
         """
         Decrypts encrypted data message
         @param key - symmetic key to decrypt
         @param flags - OR-ed combination of Flags constant
         """
-        b=Membio()
-        if libcrypto.CMS_EncryptedData_decrypt(self.ptr,key,len(key),None,
-            b.bio,flags)<=0:
-                raise CMSError("decrypt data")
-        return str(b)
+        bio = Membio()
+        if libcrypto.CMS_EncryptedData_decrypt(self.ptr, key, len(key), None,
+                                               bio.bio, flags) <= 0:
+            raise CMSError("decrypt data")
+        return str(bio)
 
 
-__all__=['CMS','CMSError','Flags','SignedData','EnvelopedData','EncryptedData']
+__all__ = ['CMS', 'CMSError', 'Flags', 'SignedData', 'EnvelopedData',
+           'EncryptedData']
 
 
-libcrypto.CMS_verify.restype=c_int
-libcrypto.CMS_verify.argtypes=(c_void_p,c_void_p,c_void_p,c_void_p,c_void_p,c_int)
+libcrypto.CMS_add1_cert.restype = c_int
+libcrypto.CMS_add1_cert.argtypes = (c_void_p, c_void_p)
+libcrypto.CMS_decrypt.restype = c_int
+libcrypto.CMS_decrypt.argtypes = (c_void_p, c_void_p, c_void_p,
+                                  c_void_p, c_void_p, c_uint)
+libcrypto.CMS_encrypt.restype = c_void_p
+libcrypto.CMS_encrypt.argtypes = (c_void_p, c_void_p, c_void_p, c_uint)
+libcrypto.CMS_EncryptedData_decrypt.restype = c_int
+libcrypto.CMS_EncryptedData_decrypt.argtypes = (c_void_p, c_char_p, c_size_t,
+                                                c_void_p, c_void_p, c_uint)
+libcrypto.CMS_EncryptedData_encrypt.restype = c_void_p
+libcrypto.CMS_EncryptedData_encrypt.argtypes = (c_void_p, c_void_p, c_char_p,
+                                                c_size_t, c_uint)
+libcrypto.CMS_final.restype = c_int
+libcrypto.CMS_final.argtypes = (c_void_p, c_void_p, c_void_p, c_uint)
+libcrypto.CMS_get0_signers.restype = c_void_p
+libcrypto.CMS_get0_signers.argtypes = (c_void_p, )
+libcrypto.CMS_get1_certs.restype = c_void_p
+libcrypto.CMS_get1_certs.argtypes = (c_void_p, )
+libcrypto.CMS_sign.restype = c_void_p
+libcrypto.CMS_sign.argtypes = (c_void_p, c_void_p, c_void_p, c_void_p, c_uint)
+libcrypto.CMS_sign_add1_Signer.restype = c_void_p
+libcrypto.CMS_sign_add1_Signer.argtypes = (c_void_p, c_void_p, c_void_p,
+                                           c_void_p, c_uint)
+libcrypto.CMS_verify.restype = c_int
+libcrypto.CMS_verify.argtypes = (c_void_p, c_void_p, c_void_p, c_void_p,
+                                 c_void_p, c_int)
+libcrypto.d2i_CMS_bio.restype = c_void_p
+libcrypto.d2i_CMS_bio.argtypes = (c_void_p, POINTER(c_void_p))
+libcrypto.i2d_CMS_bio.restype = c_int
+libcrypto.i2d_CMS_bio.argtypes = (c_void_p, c_void_p)
+libcrypto.PEM_read_bio_CMS.restype = c_void_p
+libcrypto.PEM_read_bio_CMS.argtypes = (c_void_p, POINTER(c_void_p),
+                                       c_void_p, c_void_p)
+libcrypto.PEM_write_bio_CMS.restype = c_int
+libcrypto.PEM_write_bio_CMS.argtypes = (c_void_p, c_void_p)
index 6ebb82af2a583975c2629dfc3be20c3d3bb3da69..8a9a74e1dbb4d0ddae411ffced1c4dced1298c08 100644 (file)
 """
 """
-    Implements interface to OpenSSL EVP_Digest* functions.
+Implements interface to OpenSSL EVP_Digest* functions.
 
 
-    Interface  made as close to hashlib as possible.
+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).
+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.
+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 ctypes import c_int, c_char_p, c_void_p, POINTER, c_long, c_longlong
+from ctypes import 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")
 
 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']
+__all__ = ['DigestError', 'Digest', 'DigestType', 'new']
 
 class DigestError(LibCryptoError):
 
 class DigestError(LibCryptoError):
+    """ Exception raised if some OpenSSL function returns error """
     pass
 
 def new(algname):
     """
     pass
 
 def new(algname):
     """
-        Behaves just like hashlib.new. Creates digest object by
-        algorithm name
+    Behaves just like hashlib.new. Creates digest object by
+    algorithm name
     """
     """
-    md=DigestType(algname)
-    return Digest(md)
+
+    digest_type = DigestType(algname)
+    return Digest(digest_type)
 
 class DigestType(object):
     """
 
 class DigestType(object):
     """
-        
-        Represents EVP_MD object - constant structure which describes
-        digest algorithm
-
+    Represents EVP_MD object - constant structure which describes
+    digest algorithm
     """
     """
-    def __init__(self,  digest_name):
+    def __init__(self, digest_name):
         """
         """
-            Finds digest by its name. You can pass Oid object instead of
-            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
+        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:
         """
         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)
+            return
+
+        if isinstance(digest_name, Oid):
+            self.digest_name = digest_name.longname()
         else:
             self.digest_name = str(digest_name)
         else:
             self.digest_name = str(digest_name)
-            self.digest = libcrypto.EVP_get_digestbyname(self.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 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()
+        """ Returns name of the digest """
+        if not hasattr(self, 'digest_name'):
+            self.digest_name = Oid(libcrypto.EVP_MD_type(self.digest)
+                                  ).longname()
         return self.digest_name
         return self.digest_name
+
     def __del__(self):
     def __del__(self):
+        """ Empty destructor for constant object """
         pass
         pass
+
+    @property
     def digest_size(self):
     def digest_size(self):
+        """ Returns size of digest """
         return libcrypto.EVP_MD_size(self.digest)
         return libcrypto.EVP_MD_size(self.digest)
+
+    @property
     def block_size(self):
     def block_size(self):
+        """ Returns block size of the digest """
         return libcrypto.EVP_MD_block_size(self.digest)
         return libcrypto.EVP_MD_block_size(self.digest)
+
+    @property
     def oid(self):
     def oid(self):
+        """ Returns Oid object of digest type """
         return Oid(libcrypto.EVP_MD_type(self.digest))
 
 class Digest(object):
     """
         return Oid(libcrypto.EVP_MD_type(self.digest))
 
 class Digest(object):
     """
-        Represents EVP_MD_CTX object which actually used to calculate
-        digests.
-
+    Represents EVP_MD_CTX object which actually used to calculate
+    digests.
     """
     """
-    def __init__(self,digest_type):
+
+    def __init__(self, digest_type):
         """
         """
-            Initializes digest using given 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")
         self.ctx = libcrypto.EVP_MD_CTX_create()
         if self.ctx is None:
             raise DigestError("Unable to create digest context")
+        self.digest_out = None
+        self.digest_finalized = False
         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
         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()
+        self.digest_size = self.digest_type.digest_size
+        self.block_size = self.digest_type.block_size
 
     def __del__(self):
 
     def __del__(self):
+        """ Uses _clean_ctx internal method """
         self._clean_ctx()
 
     def update(self, data, length=None):
         """
         self._clean_ctx()
 
     def update(self, data, length=None):
         """
-            Hashes given byte string 
+        Hashes given byte string
 
 
-            @param data - string to hash
-            @param length - if not specifed, entire string is hashed,
-                    otherwise only first length bytes
+        @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 self.digest_finalized:
             raise DigestError("No updates allowed")
-        if not isinstance(data,str):
+        if not isinstance(data, str):
             raise TypeError("A string is expected")
         if length is None:
             length = len(data)
             raise TypeError("A string is expected")
         if length is None:
             length = len(data)
@@ -116,12 +132,12 @@ class Digest(object):
             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 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"
-        
+            raise DigestError("Unable to update digest")
+
     def digest(self, data=None):
         """
     def digest(self, data=None):
         """
-            Finalizes digest operation and return digest value
-            Optionally hashes more data before finalizing
+        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 self.digest_finalized:
             return self.digest_out.raw[:self.digest_size]
@@ -129,31 +145,36 @@ class Digest(object):
             self.update(data)
         self.digest_out = create_string_buffer(256)
         length = c_long(0)
             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 :
+        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):
         """
             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
+        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)
+
+        new_digest = Digest(self.digest_type)
+        libcrypto.EVP_MD_CTX_copy(new_digest.ctx, self.ctx)
         return new_digest
 
     def _clean_ctx(self):
         return new_digest
 
     def _clean_ctx(self):
+        """
+        Clears and deallocates context
+        """
         try:
             if self.ctx is not None:
                 libcrypto.EVP_MD_CTX_destroy(self.ctx)
         try:
             if self.ctx is not None:
                 libcrypto.EVP_MD_CTX_destroy(self.ctx)
-                del(self.ctx)
+                del self.ctx
         except AttributeError:
             pass
         self.digest_out = None
         self.digest_finalized = False
 
         except AttributeError:
             pass
         self.digest_out = None
         self.digest_finalized = False
 
-    def hexdigest(self,data=None):
+    def hexdigest(self, data=None):
         """
             Returns digest in the hexadecimal form. For compatibility
             with hashlib
         """
             Returns digest in the hexadecimal form. For compatibility
             with hashlib
@@ -164,13 +185,23 @@ class Digest(object):
 
 # Declare function result and argument types
 libcrypto.EVP_get_digestbyname.restype = c_void_p
 
 # Declare function result and argument types
 libcrypto.EVP_get_digestbyname.restype = c_void_p
-libcrypto.EVP_get_digestbyname.argtypes = (c_char_p,)
+libcrypto.EVP_get_digestbyname.argtypes = (c_char_p, )
 libcrypto.EVP_MD_CTX_create.restype = c_void_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,)
+# libcrypto.EVP_MD_CTX_create has no arguments
+libcrypto.EVP_DigestInit_ex.restupe = c_int
+libcrypto.EVP_DigestInit_ex.argtypes = (c_void_p, c_void_p, c_void_p)
+libcrypto.EVP_DigestUpdate.restype = c_int
+libcrypto.EVP_DigestUpdate.argtypes = (c_void_p, c_char_p, c_longlong)
+libcrypto.EVP_DigestFinal_ex.restype = c_int
+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.restype = c_int
+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.restype = c_int
+libcrypto.EVP_MD_block_size.argtypes = (c_void_p, )
+libcrypto.EVP_MD_size.restype = c_int
+libcrypto.EVP_MD_size.argtypes = (c_void_p, )
+libcrypto.EVP_MD_type.restype = c_int
+libcrypto.EVP_MD_type.argtypes = (c_void_p, )
index 7240b39b2e114b10feab3d6c4eee4a38b4cac17f..ef95fb6ca848b8db7f85eb0ec96799a5476152f8 100644 (file)
@@ -2,78 +2,79 @@
 Support for EC keypair operation missing form public libcrypto API
 """
 from ctypescrypto.pkey import PKey, PKeyError
 Support for EC keypair operation missing form public libcrypto API
 """
 from ctypescrypto.pkey import PKey, PKeyError
-from ctypes import c_void_p,c_char_p,c_int,byref
+from ctypes import c_void_p, c_char_p, c_int, byref
 from ctypescrypto import libcrypto
 
 from ctypescrypto import libcrypto
 
-__all__ = [ 'create']
+__all__ = ['create']
 
 
-def create(curve,data):
+def create(curve, data):
     """
     """
-        Creates EC keypair from the just secret key and curve name
-        
-        @param curve - name of elliptic curve
-        @param num - byte array or long number representing key
+    Creates EC keypair from the just secret key and curve name
+
+    @param curve - name of elliptic curve
+    @param num - byte array or long number representing key
     """
     """
-    ec=libcrypto.EC_KEY_new_by_curve_name(curve.nid)
-    if ec is None:  
+    ec_key = libcrypto.EC_KEY_new_by_curve_name(curve.nid)
+    if ec_key is None:
         raise PKeyError("EC_KEY_new_by_curvename")
         raise PKeyError("EC_KEY_new_by_curvename")
-    group=libcrypto.EC_KEY_get0_group(ec)
+    group = libcrypto.EC_KEY_get0_group(ec_key)
     if group is None:
         raise PKeyError("EC_KEY_get0_group")
     if group is None:
         raise PKeyError("EC_KEY_get0_group")
-    libcrypto.EC_GROUP_set_asn1_flag(group,1)
-    raw_key=libcrypto.BN_new()
-    if isinstance(data,int):
-        BN_hex2bn(byref(raw_key),hex(data))
+    libcrypto.EC_GROUP_set_asn1_flag(group, 1)
+    raw_key = libcrypto.BN_new()
+    if isinstance(data, int):
+        libcrypto.BN_hex2bn(byref(raw_key), hex(data))
     else:
         if raw_key is None:
             raise PKeyError("BN_new")
     else:
         if raw_key is None:
             raise PKeyError("BN_new")
-        if libcrypto.BN_bin2bn(data,len(data),raw_key) is None:
+        if libcrypto.BN_bin2bn(data, len(data), raw_key) is None:
             raise PKeyError("BN_bin2bn")
             raise PKeyError("BN_bin2bn")
-    ctx=libcrypto.BN_CTX_new()
+    ctx = libcrypto.BN_CTX_new()
     if ctx is None:
         raise PKeyError("BN_CTX_new")
     if ctx is None:
         raise PKeyError("BN_CTX_new")
-    order=libcrypto.BN_new()
+    order = libcrypto.BN_new()
     if order is None:
         raise PKeyError("BN_new")
     priv_key = libcrypto.BN_new()
     if priv_key is None:
         raise PKeyError("BN_new")
     if order is None:
         raise PKeyError("BN_new")
     priv_key = libcrypto.BN_new()
     if priv_key is None:
         raise PKeyError("BN_new")
-    if libcrypto.EC_GROUP_get_order(group,order,ctx) <=0:
+    if libcrypto.EC_GROUP_get_order(group, order, ctx) <= 0:
         raise PKeyError("EC_GROUP_get_order")
         raise PKeyError("EC_GROUP_get_order")
-    if libcrypto.BN_nnmod(priv_key,raw_key,order,ctx) <=0:
+    if libcrypto.BN_nnmod(priv_key, raw_key, order, ctx) <= 0:
         raise PKeyError("BN_nnmod")
         raise PKeyError("BN_nnmod")
-    if libcrypto.EC_KEY_set_private_key(ec,priv_key)<=0:
+    if libcrypto.EC_KEY_set_private_key(ec_key, priv_key) <= 0:
         raise PKeyError("EC_KEY_set_private_key")
         raise PKeyError("EC_KEY_set_private_key")
-    pub_key=libcrypto.EC_POINT_new(group)
+    pub_key = libcrypto.EC_POINT_new(group)
     if pub_key is None:
         raise PKeyError("EC_POINT_new")
     if pub_key is None:
         raise PKeyError("EC_POINT_new")
-    if libcrypto.EC_POINT_mul(group,pub_key,priv_key,None,None,ctx)<=0:
+    if libcrypto.EC_POINT_mul(group, pub_key, priv_key, None, None, ctx) <= 0:
         raise PKeyError("EC_POINT_mul")
         raise PKeyError("EC_POINT_mul")
-    if libcrypto.EC_KEY_set_public_key(ec,pub_key)<=0:
+    if libcrypto.EC_KEY_set_public_key(ec_key, pub_key) <= 0:
         raise PKeyError("EC_KEY_set_public_key")
     libcrypto.BN_free(raw_key)
     libcrypto.BN_free(order)
     libcrypto.BN_free(priv_key)
     libcrypto.BN_CTX_free(ctx)
         raise PKeyError("EC_KEY_set_public_key")
     libcrypto.BN_free(raw_key)
     libcrypto.BN_free(order)
     libcrypto.BN_free(priv_key)
     libcrypto.BN_CTX_free(ctx)
-    p=libcrypto.EVP_PKEY_new()
-    if p is None:
-        raise PKeyError("EVP_PKEY_new") 
-    if libcrypto.EVP_PKEY_set1_EC_KEY(p,ec)<=0:
+    pkey = libcrypto.EVP_PKEY_new()
+    if pkey is None:
+        raise PKeyError("EVP_PKEY_new")
+    if libcrypto.EVP_PKEY_set1_EC_KEY(pkey, ec_key) <= 0:
         raise PKeyError("EVP_PKEY_set1_EC_KEY")
         raise PKeyError("EVP_PKEY_set1_EC_KEY")
-    libcrypto.EC_KEY_free(ec)
-    return PKey(ptr=p,cansign=True)
+    libcrypto.EC_KEY_free(ec_key)
+    return PKey(ptr=pkey, cansign=True)
 
 
 
 
-libcrypto.EVP_PKEY_new.restype=c_void_p
-libcrypto.BN_new.restype=c_void_p
-libcrypto.BN_free.argtypes=(c_void_p,)
-libcrypto.BN_CTX_new.restype=c_void_p
-libcrypto.BN_CTX_free.argtypes=(c_void_p,)
-libcrypto.BN_bin2bn.argtypes=(c_char_p,c_int,c_void_p)
-libcrypto.EC_KEY_set_private_key.argtypes=(c_void_p,c_void_p)
-libcrypto.EC_POINT_new.argtypes=(c_void_p,)
-libcrypto.EC_POINT_new.restype=c_void_p
-libcrypto.EC_POINT_mul.argtypes=(c_void_p,c_void_p,c_void_p,c_void_p,c_void_p,c_void_p)
-libcrypto.EC_KEY_set_public_key.argtypes=(c_void_p,c_void_p)
+libcrypto.EVP_PKEY_new.restype = c_void_p
+libcrypto.BN_new.restype = c_void_p
+libcrypto.BN_free.argtypes = (c_void_p, )
+libcrypto.BN_CTX_new.restype = c_void_p
+libcrypto.BN_CTX_free.argtypes = (c_void_p, )
+libcrypto.BN_bin2bn.argtypes = (c_char_p, c_int, c_void_p)
+libcrypto.EC_KEY_set_private_key.argtypes = (c_void_p, c_void_p)
+libcrypto.EC_POINT_new.argtypes = (c_void_p, )
+libcrypto.EC_POINT_new.restype = c_void_p
+libcrypto.EC_POINT_mul.argtypes = (c_void_p, c_void_p, c_void_p, c_void_p,
+                                   c_void_p, c_void_p)
+libcrypto.EC_KEY_set_public_key.argtypes = (c_void_p, c_void_p)
 
 
 
 
index 0446d48c2649426fef33ba16ca10b19ae6b0c7d0..c2858e6ebd5b459a1dceac7eac99dc7d5be3388e 100644 (file)
@@ -1,38 +1,39 @@
 """
 engine loading and configuration
 """
 """
 engine loading and configuration
 """
-from ctypes import *
+from ctypes import c_void_p, c_char_p, c_int
 from ctypescrypto import libcrypto
 from ctypescrypto.exception import LibCryptoError
 
 from ctypescrypto import libcrypto
 from ctypescrypto.exception import LibCryptoError
 
-__all__=['default','set_default']
+__all__ = ['default', 'set_default']
 
 
-default=None
+default = None
 
 def set_default(engine):
     """
 
 def set_default(engine):
     """
-        Loads specified engine and sets it as default for all 
-        algorithms, supported by it
+    Loads specified engine and sets it as default for all
+    algorithms, supported by it
     """
     global default
     """
     global default
-    e=libcrypto.ENGINE_by_id(engine)
-    if e is None:
+    eng = libcrypto.ENGINE_by_id(engine)
+    if eng is None:
         # Try load engine
         # Try load engine
-        e = libcrypto.ENGINE_by_id("dynamic")
-        if  e is None:
+        eng = libcrypto.ENGINE_by_id("dynamic")
+        if  eng is None:
             raise LibCryptoError("Cannot get 'dynamic' engine")
             raise LibCryptoError("Cannot get 'dynamic' engine")
-        if not libcrypto.ENGINE_ctrl_cmd_string(e,"SO_PATH",engine,0):
+        if not libcrypto.ENGINE_ctrl_cmd_string(eng, "SO_PATH", engine, 0):
             raise LibCryptoError("Cannot execute ctrl cmd SO_PATH")
             raise LibCryptoError("Cannot execute ctrl cmd SO_PATH")
-        if not libcrypto.ENGINE_ctrl_cmd_string(e,"LOAD",None,0):
+        if not libcrypto.ENGINE_ctrl_cmd_string(eng, "LOAD", None, 0):
             raise LibCryptoError("Cannot execute ctrl cmd LOAD")
             raise LibCryptoError("Cannot execute ctrl cmd LOAD")
-    if e is None:
-        raise ValueError("Cannot find engine "+engine)
-    libcrypto.ENGINE_set_default(e,c_int(0xFFFF))
-    default=e
+    if eng is None:
+        raise ValueError("Cannot find engine " + engine)
+    libcrypto.ENGINE_set_default(eng, c_int(0xFFFF))
+    default = eng
 
 # Declare function result and arguments for used functions
 
 # Declare function result and arguments for used functions
-libcrypto.ENGINE_by_id.restype=c_void_p
-libcrypto.ENGINE_by_id.argtypes=(c_char_p,)
-libcrypto.ENGINE_set_default.argtypes=(c_void_p,c_int)
-libcrypto.ENGINE_ctrl_cmd_string.argtypes=(c_void_p,c_char_p,c_char_p,c_int)
-libcrypto.ENGINE_finish.argtypes=(c_char_p,)
+libcrypto.ENGINE_by_id.restype = c_void_p
+libcrypto.ENGINE_by_id.argtypes = (c_char_p, )
+libcrypto.ENGINE_set_default.argtypes = (c_void_p, c_int)
+libcrypto.ENGINE_ctrl_cmd_string.argtypes = (c_void_p, c_char_p, c_char_p,
+                                             c_int)
+libcrypto.ENGINE_finish.argtypes = (c_char_p, )
index 0e6fc438ad8a4dcb6076915eae2470be55191c3f..5eec20a0a471eb38c6460a14bd40914b619161ef 100644 (file)
@@ -1,50 +1,39 @@
 """
 Exception which extracts libcrypto error information
 """
 """
 Exception which extracts libcrypto error information
 """
-from ctypes import *
+from ctypes import c_ulong, c_char_p, create_string_buffer
 from ctypescrypto import libcrypto
 from ctypescrypto import libcrypto
-strings_loaded=False
+strings_loaded = False
 
 
-__all__ = ['LibCryptoError','clear_err_stack']
-
-def _check_null(s):
-    """
-    Handle transparently NULL returned from error reporting functions
-    instead of strings
-    """
-    if s is None:   
-        return ""
-    return s
+__all__ = ['LibCryptoError', 'clear_err_stack']
 
 class LibCryptoError(Exception):
     """
 
 class LibCryptoError(Exception):
     """
-        Exception for libcrypto errors. Adds all the info, which can be
-        extracted from internal (per-thread) libcrypto error stack to the message,
-        passed to the constructor.
+    Exception for libcrypto errors. Adds all the info, which can be
+    extracted from internal (per-thread) libcrypto error stack to the message,
+    passed to the constructor.
     """
     """
-    def __init__(self,msg):
+    def __init__(self, msg):
         global strings_loaded
         if not strings_loaded:
             libcrypto.ERR_load_crypto_strings()
             strings_loaded = True
         global strings_loaded
         if not strings_loaded:
             libcrypto.ERR_load_crypto_strings()
             strings_loaded = True
-        e=libcrypto.ERR_get_error()
-        m = msg
-        while e != 0:
-            m+="\n\t"+_check_null(libcrypto.ERR_lib_error_string(e))+":"+\
-              _check_null(libcrypto.ERR_func_error_string(e))+":"+\
-              _check_null(libcrypto.ERR_reason_error_string(e))
-            e=libcrypto.ERR_get_error()
-        self.args=(m,)
+        err_code = libcrypto.ERR_get_error()
+        mesg = msg
+        buf = create_string_buffer(128)
+        while err_code != 0:
+            mesg += "\n\t" + libcrypto.ERR_error_string(err_code, buf)
+            err_code = libcrypto.ERR_get_error()
+        super(LibCryptoError, self).__init__(mesg)
 
 def clear_err_stack():
     """
 
 def clear_err_stack():
     """
-      Clears internal libcrypto err stack. Call it if you've checked
-      return code and processed exceptional situation, so subsequent
-      raising of the LibCryptoError wouldn't list already handled errors
+    Clears internal libcrypto err stack. Call it if you've checked
+    return code and processed exceptional situation, so subsequent
+    raising of the LibCryptoError wouldn't list already handled errors
     """
     libcrypto.ERR_clear_error()
 
     """
     libcrypto.ERR_clear_error()
 
-
-libcrypto.ERR_lib_error_string.restype=c_char_p
-libcrypto.ERR_func_error_string.restype=c_char_p
-libcrypto.ERR_reason_error_string.restype=c_char_p
+libcrypto.ERR_get_error.restype = c_ulong
+libcrypto.ERR_error_string.restype = c_char_p
+libcrypto.ERR_error_string.argtypes = (c_ulong, c_char_p)
index 7b9381e52b90dd4361737e793cf7d1a5d004d62a..0a96cb063436175ef24ba89106aacf5626aa9174 100644 (file)
@@ -67,8 +67,8 @@ class MAC(Digest):
         for (name,val) in kwargs.items():
             if libcrypto.EVP_PKEY_CTX_ctrl_str(pctx,name,val)<=0:
                 raise DigestError("Unable to set mac parameter")
         for (name,val) in kwargs.items():
             if libcrypto.EVP_PKEY_CTX_ctrl_str(pctx,name,val)<=0:
                 raise DigestError("Unable to set mac parameter")
-        self.digest_size = self.digest_type.digest_size()
-        self.block_size = self.digest_type.block_size()
+        self.digest_size = self.digest_type.digest_size
+        self.block_size = self.digest_type.block_size
     def digest(self,data=None):
         """
         Method digest is redefined to return keyed MAC value instead of
     def digest(self,data=None):
         """
         Method digest is redefined to return keyed MAC value instead of
index 85b3aa03d888b8564f97c4b677309d3a71978177..28e12baa0ee64118cce86296d2a8082615d6c882 100644 (file)
@@ -1,58 +1,82 @@
-""" 
- Interface to OpenSSL object identifier database.
+"""
+Interface to OpenSSL object identifier database.
+
+It is primarily intended to deal with OIDs which are compiled into the
+database or defined in the openssl configuration files.
 
 
- It is primarily intended to deal with OIDs which are compiled into the
- database or defined in the openssl configuration files.
+But see create() function.
 
 
- But see create() function
+OpenSSL maintains database of OIDs, which contain long and short
+human-readable names, which correspond to Oid as well as canonical
+dotted-decimal representation, and links it to small integer, named
+numeric identifier or 'nid'. Most OpenSSL functions which deals with
+ASN.1 structures such as certificates or cryptographic messages,
+expect or return nids, but it is very bad idea to hardcode nids into
+your app, because it can change after mere recompilation of OpenSSL
+library.
 
 
+This module provides Oid object which represents entry to OpenSSL
+OID database.
 """
 from ctypescrypto import libcrypto
 from ctypes import c_char_p, c_void_p, c_int, create_string_buffer
 """
 from ctypescrypto import libcrypto
 from ctypes import c_char_p, c_void_p, c_int, create_string_buffer
+from ctypescrypto.exception import LibCryptoError
 
 
-__all__ = ['Oid','create','cleanup']
+__all__ = ['Oid', 'create', 'cleanup']
 
 class Oid(object):
     """
 
 class Oid(object):
     """
-        Represents an OID. It can be consturucted by textual
-        representation like Oid("commonName") or Oid("CN"),
-        dotted-decimal Oid("1.2.3.4") or using OpenSSL numeric
-        identifer (NID), which is typically returned or required by 
-        OpenSSL API functions. If object is consturcted from textual
-        representation which is not present in the database, it fails
-        with ValueError
+    Represents an OID (ASN.1 Object identifier).
 
 
-        attribute nid - contains object nid.
 
 
+    It can be consturucted by textual
+    representation like Oid("commonName") or Oid("CN"),
+    dotted-decimal Oid("1.2.3.4") or using OpenSSL numeric
+    identifer (NID), which is typically returned or required by
+    OpenSSL API functions. If object is consturcted from textual
+    representation which is not present in the database, it fails
+    with ValueError
 
 
+    attribute nid - contains object nid.
     """
 
     """
 
-    def __init__(self,value):
-        " Object constuctor. Accepts string or integer"
-        if isinstance(value,unicode):
-            value=value.encode('ascii')
-        if isinstance(value,str):
-            self.nid=libcrypto.OBJ_txt2nid(value)
-            if self.nid==0:
-                raise ValueError("Cannot find object %s in the database"%(value))
-        elif isinstance(value,(int,long)):
-            cn=libcrypto.OBJ_nid2sn(value)
-            if cn is None:
-                raise ValueError("No such nid %d in the database"%(value))
-            self.nid=value
+    def __init__(self, value):
+        """
+        Object constuctor. Accepts string, integer, or another Oid
+        object.
+
+        Integer should be OpenSSL numeric identifier (nid) as returned
+        by some libcrypto function or extracted from some libcrypto
+        structure
+        """
+        if isinstance(value, unicode):
+            value = value.encode('ascii')
+        if isinstance(value, str):
+            self.nid = libcrypto.OBJ_txt2nid(value)
+            if self.nid == 0:
+                raise ValueError("Cannot find object %s in the database" %
+                                 value)
+        elif isinstance(value, (int, long)):
+            short = libcrypto.OBJ_nid2sn(value)
+            if short is None:
+                raise ValueError("No such nid %d in the database" % value)
+            self.nid = value
+        elif isinstance(value, Oid):
+            self.nid = value.nid
         else:
             raise TypeError("Cannot convert this type to object identifier")
     def __hash__(self):
         else:
             raise TypeError("Cannot convert this type to object identifier")
     def __hash__(self):
-        " Returns NID "
+        " Hash of object is equal to nid because Oids with same nid are same"
         return self.nid
         return self.nid
-    def __cmp__(self,other):
+    def __cmp__(self, other):
         " Compares NIDs of two objects "
         " Compares NIDs of two objects "
-        return self.nid-other.nid
+        return self.nid - other.nid
     def __str__(self):
     def __str__(self):
-        " Default string representation of Oid is dotted-decimal"
+        " Default string representation of Oid is dotted-decimal "
         return self.dotted()
     def __repr__(self):
         return self.dotted()
     def __repr__(self):
-        return "Oid('%s')"%(self.dotted())
+        " Returns constructor call of Oid with dotted representation "
+        return "Oid('%s')" % (self.dotted())
     def shortname(self):
         " Returns short name if any "
         return libcrypto.OBJ_nid2sn(self.nid)
     def shortname(self):
         " Returns short name if any "
         return libcrypto.OBJ_nid2sn(self.nid)
@@ -61,57 +85,60 @@ class Oid(object):
         return  libcrypto.OBJ_nid2ln(self.nid)
     def dotted(self):
         " Returns dotted-decimal reperesentation "
         return  libcrypto.OBJ_nid2ln(self.nid)
     def dotted(self):
         " Returns dotted-decimal reperesentation "
-        obj=libcrypto.OBJ_nid2obj(self.nid)
-        buf=create_string_buffer(256)
-        libcrypto.OBJ_obj2txt(buf,256,obj,1)
+        obj = libcrypto.OBJ_nid2obj(self.nid)
+        buf = create_string_buffer(256)
+        libcrypto.OBJ_obj2txt(buf, 256, obj, 1)
         return buf.value
     @staticmethod
     def fromobj(obj):
         """
         Creates an OID object from the pointer to ASN1_OBJECT c structure.
         return buf.value
     @staticmethod
     def fromobj(obj):
         """
         Creates an OID object from the pointer to ASN1_OBJECT c structure.
-        Strictly for internal use
+        This method intended for internal use for submodules which deal
+        with libcrypto ASN1 parsing functions, such as x509 or CMS
         """
         """
-        nid=libcrypto.OBJ_obj2nid(obj)
-        if nid==0:
-            buf=create_string_buffer(80)
-            l=libcrypto.OBJ_obj2txt(buf,80,obj,1)
-            oid=create(buf[0:l],buf[0:l],buf[0:l])
+        nid = libcrypto.OBJ_obj2nid(obj)
+        if nid == 0:
+            buf = create_string_buffer(80)
+            dotted_len = libcrypto.OBJ_obj2txt(buf, 80, obj, 1)
+            dotted = buf[:dotted_len]
+            oid = create(dotted, dotted, dotted)
         else:
         else:
-            oid=Oid(nid)
+            oid = Oid(nid)
         return oid
 
         return oid
 
-def create(dotted,shortname,longname):
+def create(dotted, shortname, longname):
     """
     """
-        Creates new OID in the database
+    Creates new OID in the database
+
+    @param dotted - dotted-decimal representation of new OID
+    @param shortname - short name for new OID
+    @param longname - long name for new OID
+
+    @returns Oid object corresponding to new OID
 
 
-        @param dotted - dotted-decimal representation of new OID
-        @param shortname - short name for new OID
-        @param longname - long name for new OID
+    This function should be used with exreme care. Whenever
+    possible, it is better to add new OIDs via OpenSSL configuration
+    file
 
 
-        @returns Oid object corresponding to new OID
-        
-        This function should be used with exreme care. Whenever
-        possible, it is better to add new OIDs via OpenSSL configuration
-        file
+    Results of calling this function twice for same OIDor for
+    Oid alredy in database are undefined
 
 
-        Results of calling this function twice for same OIDor for
-        Oid alredy in database are undefined
     """
     """
-    nid=libcrypto.OBJ_create(dotted,shortname,longname)
+    nid = libcrypto.OBJ_create(dotted, shortname, longname)
     if nid == 0:
         raise LibCryptoError("Problem adding new OID to the  database")
     return Oid(nid)
 
 def cleanup():
     """
     if nid == 0:
         raise LibCryptoError("Problem adding new OID to the  database")
     return Oid(nid)
 
 def cleanup():
     """
-        Removes all the objects, dynamically added by current
-        application from database.
+    Removes all the objects, dynamically added by current
+    application from database.
     """
     libcrypto.OBJ_cleanup()
 
     """
     libcrypto.OBJ_cleanup()
 
-libcrypto.OBJ_nid2sn.restype=c_char_p
-libcrypto.OBJ_nid2ln.restype=c_char_p
-libcrypto.OBJ_nid2obj.restype=c_void_p
-libcrypto.OBJ_obj2txt.argtypes=(c_char_p,c_int,c_void_p,c_int)
-libcrypto.OBJ_txt2nid.argtupes=(c_char_p,)
-libcrypto.OBJ_create.argtypes=(c_char_p,c_char_p,c_char_p)
+libcrypto.OBJ_nid2sn.restype = c_char_p
+libcrypto.OBJ_nid2ln.restype = c_char_p
+libcrypto.OBJ_nid2obj.restype = c_void_p
+libcrypto.OBJ_obj2txt.argtypes = (c_char_p, c_int, c_void_p, c_int)
+libcrypto.OBJ_txt2nid.argtupes = (c_char_p, )
+libcrypto.OBJ_create.argtypes = (c_char_p, c_char_p, c_char_p)
index 85a99a5c097fc3cd5ee19cf55b33b03f8aa40ad4..bde567b5e361e119758ef0e7037a073ceb6bb519 100644 (file)
@@ -3,33 +3,34 @@ PKCS5 PBKDF2 function.
 
 """
 
 
 """
 
-from ctypes import c_char_p,c_int, c_void_p, create_string_buffer
+from ctypes import c_char_p, c_int, c_void_p, create_string_buffer
 from ctypescrypto import libcrypto
 from ctypescrypto.digest import DigestType
 from ctypescrypto import libcrypto
 from ctypescrypto.digest import DigestType
+from ctypescrypto.exception import LibCryptoError
 
 __all__ = ['pbkdf2']
 
 
 __all__ = ['pbkdf2']
 
-def pbkdf2(password,salt,outlen,digesttype="sha1",iterations=2000):
+def pbkdf2(password, salt, outlen, digesttype="sha1", iterations=2000):
     """
     """
-        Interface to PKCS5_PBKDF2_HMAC function
-        Parameters:
-            
-                @param password - password to derive key from
-                @param salt - random salt to use for key derivation
-                @param outlen - number of bytes to derive
-                @param digesttype - name of digest to use to use (default sha1)
-                @param iterations - number of iterations to use
+    Interface to PKCS5_PBKDF2_HMAC function
+    Parameters:
 
 
-                @returns outlen bytes of key material derived from password and salt
+    @param password - password to derive key from
+    @param salt - random salt to use for key derivation
+    @param outlen - number of bytes to derive
+    @param digesttype - name of digest to use to use (default sha1)
+    @param iterations - number of iterations to use
+
+    @returns outlen bytes of key material derived from password and salt
     """
     """
-    dt=DigestType(digesttype)
-    out=create_string_buffer(outlen)
-    res=libcrypto.PKCS5_PBKDF2_HMAC(password,len(password),salt,len(salt),
-        iterations,dt.digest,outlen,out)
-    if res<=0:
+    dgst = DigestType(digesttype)
+    out = create_string_buffer(outlen)
+    res = libcrypto.PKCS5_PBKDF2_HMAC(password, len(password), salt, len(salt),
+                                      iterations, dgst.digest, outlen, out)
+    if res <= 0:
         raise LibCryptoError("error computing PBKDF2")
     return out.raw
 
         raise LibCryptoError("error computing PBKDF2")
     return out.raw
 
-libcrypto.PKCS5_PBKDF2_HMAC.argtypes=(c_char_p,c_int,c_char_p,c_int,c_int,
-    c_void_p,c_int,c_char_p)
-libcrypto.PKCS5_PBKDF2_HMAC.restupe=c_int
+libcrypto.PKCS5_PBKDF2_HMAC.argtypes = (c_char_p, c_int, c_char_p, c_int, c_int,
+                                        c_void_p, c_int, c_char_p)
+libcrypto.PKCS5_PBKDF2_HMAC.restupe = c_int
index 1e7078463820f9d9011ba4526fddf4ad888e6057..59da723f7b93f926a44b2d766c19c00842ea939a 100644 (file)
@@ -5,297 +5,354 @@ PKey object of this module is wrapper around OpenSSL EVP_PKEY object.
 """
 
 
 """
 
 
-from ctypes import c_char_p,c_void_p,byref,c_int,c_long, c_longlong, create_string_buffer,CFUNCTYPE,POINTER
+from ctypes import c_char_p, c_void_p, c_int, c_long, POINTER
+from ctypes import create_string_buffer, byref, memmove, CFUNCTYPE
 from ctypescrypto import libcrypto
 from ctypescrypto import libcrypto
-from ctypescrypto.exception import LibCryptoError,clear_err_stack
+from ctypescrypto.exception import LibCryptoError, clear_err_stack
 from ctypescrypto.bio import Membio
 from ctypescrypto.bio import Membio
-import sys
 
 
-__all__ = ['PKeyError','password_callback','PKey']
+__all__ = ['PKeyError', 'password_callback', 'PKey', 'PW_CALLBACK_FUNC']
 class PKeyError(LibCryptoError):
 class PKeyError(LibCryptoError):
+    """ Exception thrown if libcrypto finctions return an error """
     pass
 
     pass
 
-CALLBACK_FUNC=CFUNCTYPE(c_int,c_char_p,c_int,c_int,c_char_p)
-def password_callback(buf,length,rwflag,u):
+PW_CALLBACK_FUNC = CFUNCTYPE(c_int, c_char_p, c_int, c_int, c_char_p)
+""" Function type for pem password callback """
+
+def password_callback(buf, length, rwflag, userdata):
     """
     """
-    Example password callback for private key. Assumes that 
-    password is store in the userdata parameter, so allows to pass password
+    Example password callback for private key. Assumes that
+    password is stored in the userdata parameter, so allows to pass password
     from constructor arguments to the libcrypto keyloading functions
     """
     from constructor arguments to the libcrypto keyloading functions
     """
-    cnt=len(u)
-    if length<cnt:
-        cnt=length
-    memmove(buf,u,cnt)
+    cnt = len(userdata)
+    if length < cnt:
+        cnt = length
+    memmove(buf, userdata, cnt)
     return cnt
 
     return cnt
 
-_cb=CALLBACK_FUNC(password_callback)
+_cb = PW_CALLBACK_FUNC(password_callback)
 
 class PKey(object):
 
 class PKey(object):
-    def __init__(self,ptr=None,privkey=None,pubkey=None,format="PEM",cansign=False,password=None):
+    """
+    Represents public/private key pair. Wrapper around EVP_PKEY
+    libcrypto object.
+
+    May contain either both private and public key (such objects can be
+    used for signing, deriving shared key as well as verifying or public
+    key only, which can be used for verifying or as peer key when
+    deriving.
+
+    @var cansign is true key has private part.
+    @var key contain pointer to EVP_PKEY and should be passed to various
+         libcrypto routines
+    """
+    def __init__(self, ptr=None, privkey=None, pubkey=None, format="PEM",
+                 cansign=False, password=None, callback=_cb):
         if not ptr is None:
         if not ptr is None:
-            self.key=ptr
-            self.cansign=cansign
+            self.key = ptr
+            self.cansign = cansign
             if not privkey is None or not pubkey is None:
             if not privkey is None or not pubkey is None:
-                raise TypeError("Just one of ptr, pubkey or privkey can be specified")
+                raise TypeError("Just one of ptr, pubkey or privkey can " +
+                                "be specified")
         elif not privkey is None:
             if not pubkey is None:
         elif not privkey is None:
             if not pubkey is None:
-                raise TypeError("Just one of ptr, pubkey or privkey can be specified")
-            b=Membio(privkey)
-            self.cansign=True
+                raise TypeError("Just one of ptr, pubkey or privkey can " +
+                                "be specified")
+            bio = Membio(privkey)
+            self.cansign = True
             if format == "PEM":
             if format == "PEM":
-                self.key=libcrypto.PEM_read_bio_PrivateKey(b.bio,None,_cb,c_char_p(password))
-            else: 
-                self.key=libcrypto.d2i_PrivateKey_bio(b.bio,None)
+                self.key = libcrypto.PEM_read_bio_PrivateKey(bio.bio, None,
+                                                             callback,
+                                                             c_char_p(password))
+            else:
+                self.key = libcrypto.d2i_PrivateKey_bio(bio.bio, None)
             if self.key is None:
                 raise PKeyError("error parsing private key")
         elif not pubkey is None:
             if self.key is None:
                 raise PKeyError("error parsing private key")
         elif not pubkey is None:
-            b=Membio(pubkey)
-            self.cansign=False
+            bio = Membio(pubkey)
+            self.cansign = False
             if format == "PEM":
             if format == "PEM":
-                self.key=libcrypto.PEM_read_bio_PUBKEY(b.bio,None,_cb,None)
+                self.key = libcrypto.PEM_read_bio_PUBKEY(bio.bio, None,
+                                                         callback,
+                                                         c_char_p(password))
             else:
             else:
-                self.key=libcrypto.d2i_PUBKEY_bio(b.bio,None)
+                self.key = libcrypto.d2i_PUBKEY_bio(bio.bio, None)
             if self.key is None:
                 raise PKeyError("error parsing public key")
         else:
             raise TypeError("Neither public, nor private key is specified")
             if self.key is None:
                 raise PKeyError("error parsing public key")
         else:
             raise TypeError("Neither public, nor private key is specified")
-            
+
 
     def __del__(self):
 
     def __del__(self):
+        """ Frees EVP_PKEY object (note, it is reference counted) """
         libcrypto.EVP_PKEY_free(self.key)
         libcrypto.EVP_PKEY_free(self.key)
-    def __eq__(self,other):
+
+    def __eq__(self, other):
         """ Compares two public keys. If one has private key and other
             doesn't it doesn't affect result of comparation
         """
         """ Compares two public keys. If one has private key and other
             doesn't it doesn't affect result of comparation
         """
-        return libcrypto.EVP_PKEY_cmp(self.key,other.key)==1
-    def __ne__(self,other):
+        return libcrypto.EVP_PKEY_cmp(self.key, other.key) == 1
+
+    def __ne__(self, other):
+        """ Compares two public key for not-equality """
         return not self.__eq__(other)
         return not self.__eq__(other)
+
     def __str__(self):
     def __str__(self):
-        """ printable representation of public key """  
-        b=Membio()
-        libcrypto.EVP_PKEY_print_public(b.bio,self.key,0,None)
-        return str(b)
+        """ printable representation of public key """
+        bio = Membio()
+        libcrypto.EVP_PKEY_print_public(bio.bio, self.key, 0, None)
+        return str(bio)
 
 
-    def sign(self,digest,**kwargs):
+    def sign(self, digest, **kwargs):
         """
         """
-            Signs given digest and retirns signature
-            Keyword arguments allows to set various algorithm-specific
-            parameters. See pkeyutl(1) manual.
+        Signs given digest and retirns signature
+        Keyword arguments allows to set various algorithm-specific
+        parameters. See pkeyutl(1) manual.
         """
         """
-        ctx=libcrypto.EVP_PKEY_CTX_new(self.key,None)
+        ctx = libcrypto.EVP_PKEY_CTX_new(self.key, None)
         if ctx is None:
             raise PKeyError("Initailizing sign context")
         if ctx is None:
             raise PKeyError("Initailizing sign context")
-        if libcrypto.EVP_PKEY_sign_init(ctx)<1:
+        if libcrypto.EVP_PKEY_sign_init(ctx) < 1:
             raise PKeyError("sign_init")
             raise PKeyError("sign_init")
-        self._configure_context(ctx,kwargs)
+        self._configure_context(ctx, kwargs)
         # Find out signature size
         # Find out signature size
-        siglen=c_long(0)
-        if libcrypto.EVP_PKEY_sign(ctx,None,byref(siglen),digest,len(digest))<1:
-            raise PKeyError("signing")  
-        sig=create_string_buffer(siglen.value)
-        libcrypto.EVP_PKEY_sign(ctx,sig,byref(siglen),digest,len(digest))
+        siglen = c_long(0)
+        if libcrypto.EVP_PKEY_sign(ctx, None, byref(siglen), digest,
+                                   len(digest)) < 1:
+            raise PKeyError("computing signature length")
+        sig = create_string_buffer(siglen.value)
+        if libcrypto.EVP_PKEY_sign(ctx, sig, byref(siglen), digest,
+                                   len(digest)) < 1:
+            raise PKeyError("signing")
         libcrypto.EVP_PKEY_CTX_free(ctx)
         libcrypto.EVP_PKEY_CTX_free(ctx)
-        return sig.raw[:siglen.value]
+        return sig.raw[:int(siglen.value)]
 
 
-    def verify(self,digest,signature,**kwargs):
+    def verify(self, digest, signature, **kwargs):
         """
         """
-            Verifies given signature on given digest
-            Returns True if Ok, False if don't match
-            Keyword arguments allows to set algorithm-specific
-            parameters
+        Verifies given signature on given digest
+        Returns True if Ok, False if don't match
+        Keyword arguments allows to set algorithm-specific
+        parameters
         """
         """
-        ctx=libcrypto.EVP_PKEY_CTX_new(self.key,None)
+        ctx = libcrypto.EVP_PKEY_CTX_new(self.key, None)
         if ctx is None:
             raise PKeyError("Initailizing verify context")
         if ctx is None:
             raise PKeyError("Initailizing verify context")
-        if libcrypto.EVP_PKEY_verify_init(ctx)<1:
+        if libcrypto.EVP_PKEY_verify_init(ctx) < 1:
             raise PKeyError("verify_init")
             raise PKeyError("verify_init")
-        self._configure_context(ctx,kwargs)
-        rv=libcrypto.EVP_PKEY_verify(ctx,signature,len(signature),digest,len(digest))
-        if rv<0:
+        self._configure_context(ctx, kwargs)
+        ret = libcrypto.EVP_PKEY_verify(ctx, signature, len(signature), digest,
+                                        len(digest))
+        if ret < 0:
             raise PKeyError("Signature verification")
         libcrypto.EVP_PKEY_CTX_free(ctx)
             raise PKeyError("Signature verification")
         libcrypto.EVP_PKEY_CTX_free(ctx)
-        return rv>0
-    def derive(self,peerkey,**kwargs):
+        return ret > 0
+
+    def derive(self, peerkey, **kwargs):
         """
         """
-            Derives shared key (DH,ECDH,VKO 34.10). Requires
-            private key available
+        Derives shared key (DH,ECDH,VKO 34.10). Requires
+        private key available
 
 
-            @param peerkey - other key (may be public only)
+        @param peerkey - other key (may be public only)
 
 
-            Keyword parameters are algorithm-specific
+        Keyword parameters are algorithm-specific
         """
         """
-        ctx=libcrypto.EVP_PKEY_CTX_new(self.key,None)
+        if not self.cansign:
+            raise ValueError("No private key available")
+        ctx = libcrypto.EVP_PKEY_CTX_new(self.key, None)
         if ctx is None:
             raise PKeyError("Initailizing derive context")
         if ctx is None:
             raise PKeyError("Initailizing derive context")
-        if libcrypto.EVP_PKEY_derive_init(ctx)<1:
+        if libcrypto.EVP_PKEY_derive_init(ctx) < 1:
             raise PKeyError("derive_init")
 
             raise PKeyError("derive_init")
 
-        
-        self._configure_context(ctx,kwargs,["ukm"])
-        if libcrypto.EVP_PKEY_derive_set_peer(ctx,peerkey.key)<=0:
+        # This is workaround around missing functionality in GOST engine
+        # it provides only numeric control command to set UKM, not
+        # string one.
+        self._configure_context(ctx, kwargs, ["ukm"])
+        if libcrypto.EVP_PKEY_derive_set_peer(ctx, peerkey.key) <= 0:
             raise PKeyError("Cannot set peer key")
         if "ukm" in kwargs:
             raise PKeyError("Cannot set peer key")
         if "ukm" in kwargs:
-             if libcrypto.EVP_PKEY_CTX_ctrl(ctx,-1,1<<10,8,8,kwargs["ukm"])<=0:
+            # We just hardcode numeric command to set UKM here
+            if libcrypto.EVP_PKEY_CTX_ctrl(ctx, -1, 1 << 10, 8, 8,
+                                           kwargs["ukm"]) <= 0:
                 raise PKeyError("Cannot set UKM")
                 raise PKeyError("Cannot set UKM")
-        keylen=c_long(0)
-        if libcrypto.EVP_PKEY_derive(ctx,None,byref(keylen))<=0:
+        keylen = c_long(0)
+        if libcrypto.EVP_PKEY_derive(ctx, None, byref(keylen)) <= 0:
             raise PKeyError("computing shared key length")
             raise PKeyError("computing shared key length")
-        buf=create_string_buffer(keylen.value)
-        if libcrypto.EVP_PKEY_derive(ctx,buf,byref(keylen))<=0:
+        buf = create_string_buffer(keylen.value)
+        if libcrypto.EVP_PKEY_derive(ctx, buf, byref(keylen)) <= 0:
             raise PKeyError("computing actual shared key")
         libcrypto.EVP_PKEY_CTX_free(ctx)
             raise PKeyError("computing actual shared key")
         libcrypto.EVP_PKEY_CTX_free(ctx)
-        return buf.raw[:keylen.value]
+        return buf.raw[:int(keylen.value)]
+
     @staticmethod
     @staticmethod
-    def generate(algorithm,**kwargs):
+    def generate(algorithm, **kwargs):
         """
         """
-            Generates new private-public key pair for given algorithm
-            (string like 'rsa','ec','gost2001') and algorithm-specific
-            parameters.
+        Generates new private-public key pair for given algorithm
+        (string like 'rsa','ec','gost2001') and algorithm-specific
+        parameters.
 
 
-            Algorithm specific paramteers for RSA:
+        Algorithm specific paramteers for RSA:
 
 
-            rsa_keygen_bits=number - size of key to be generated
-            rsa_keygen_pubexp - RSA public expontent(default 65537)
+        rsa_keygen_bits=number - size of key to be generated
+        rsa_keygen_pubexp - RSA public expontent(default 65537)
 
 
-            Algorithm specific parameters for DSA,DH and EC
+        Algorithm specific parameters for DSA,DH and EC
 
 
-            paramsfrom=PKey object
+        paramsfrom=PKey object
 
 
-            copy parameters of newly generated key from existing key
+        copy parameters of newly generated key from existing key
 
 
-            Algorithm specific parameters for GOST2001
+        Algorithm specific parameters for GOST2001
 
 
-            paramset= paramset name where name is one of
-            'A','B','C','XA','XB','test'
+        paramset= paramset name where name is one of
+        'A','B','C','XA','XB','test'
 
 
-            paramsfrom does work too
+        paramsfrom does work too
         """
         """
-        tmpeng=c_void_p(None)
-        ameth=libcrypto.EVP_PKEY_asn1_find_str(byref(tmpeng),algorithm,-1)
+        tmpeng = c_void_p(None)
+        ameth = libcrypto.EVP_PKEY_asn1_find_str(byref(tmpeng), algorithm, -1)
         if ameth is None:
         if ameth is None:
-            raise PKeyError("Algorithm %s not foind\n"%(algname))
+            raise PKeyError("Algorithm %s not foind\n"%(algorithm))
         clear_err_stack()
         clear_err_stack()
-        pkey_id=c_int(0)
-        libcrypto.EVP_PKEY_asn1_get0_info(byref(pkey_id),None,None,None,None,ameth)
+        pkey_id = c_int(0)
+        libcrypto.EVP_PKEY_asn1_get0_info(byref(pkey_id), None, None, None,
+                                          None, ameth)
         #libcrypto.ENGINE_finish(tmpeng)
         if "paramsfrom" in kwargs:
         #libcrypto.ENGINE_finish(tmpeng)
         if "paramsfrom" in kwargs:
-            ctx=libcrypto.EVP_PKEY_CTX_new(kwargs["paramsfrom"].key,None)
+            ctx = libcrypto.EVP_PKEY_CTX_new(kwargs["paramsfrom"].key, None)
         else:
         else:
-            ctx=libcrypto.EVP_PKEY_CTX_new_id(pkey_id,None)
+            ctx = libcrypto.EVP_PKEY_CTX_new_id(pkey_id, None)
         # FIXME support EC curve as keyword param by invoking paramgen
         # operation
         if ctx is None:
         # FIXME support EC curve as keyword param by invoking paramgen
         # operation
         if ctx is None:
-            raise PKeyError("Creating context for key type %d"%(pkey_id.value)) 
-        if libcrypto.EVP_PKEY_keygen_init(ctx) <=:
+            raise PKeyError("Creating context for key type %d"%(pkey_id.value))
+        if libcrypto.EVP_PKEY_keygen_init(ctx) <= 0:
             raise PKeyError("keygen_init")
             raise PKeyError("keygen_init")
-        PKey._configure_context(ctx,kwargs,["paramsfrom"])
-        key=c_void_p(None)
-        if libcrypto.EVP_PKEY_keygen(ctx,byref(key))<=0:
+        PKey._configure_context(ctx, kwargs, ["paramsfrom"])
+        key = c_void_p(None)
+        if libcrypto.EVP_PKEY_keygen(ctx, byref(key)) <= 0:
             raise PKeyError("Error generating key")
         libcrypto.EVP_PKEY_CTX_free(ctx)
             raise PKeyError("Error generating key")
         libcrypto.EVP_PKEY_CTX_free(ctx)
-        return PKey(ptr=key,cansign=True)
-    def exportpub(self,format="PEM"):
+        return PKey(ptr=key, cansign=True)
+
+    def exportpub(self, format="PEM"):
         """
         """
-            Returns public key as PEM or DER structure.
+        Returns public key as PEM or DER structure.
         """
         """
-        b=Membio()
+        bio = Membio()
         if format == "PEM":
         if format == "PEM":
-            r=libcrypto.PEM_write_bio_PUBKEY(b.bio,self.key)
+            retcode = libcrypto.PEM_write_bio_PUBKEY(bio.bio, self.key)
         else:
         else:
-            r=libcrypto.i2d_PUBKEY_bio(b.bio,self.key)
-        if r==0:
+            retcode = libcrypto.i2d_PUBKEY_bio(bio.bio, self.key)
+        if retcode == 0:
             raise PKeyError("error serializing public key")
             raise PKeyError("error serializing public key")
-        return str(b)
-    def exportpriv(self,format="PEM",password=None,cipher=None):
+        return str(bio)
+
+    def exportpriv(self, format="PEM", password=None, cipher=None,
+                   callback=_cb):
         """
         """
-            Returns private key as PEM or DER Structure.
-            If password and cipher are specified, encrypts key
-            on given password, using given algorithm. Cipher must be
-            an ctypescrypto.cipher.CipherType object
+        Returns private key as PEM or DER Structure.
+        If password and cipher are specified, encrypts key
+        on given password, using given algorithm. Cipher must be
+        an ctypescrypto.cipher.CipherType object
         """
         """
-        b=Membio()
+        bio = Membio()
         if cipher is None:
         if cipher is None:
-            evp_cipher=None
+            evp_cipher = None
         else:
         else:
-            if password is None:
-                raise NotImplementedError("Interactive password entry is not supported")
-            evp_cipher=cipher.cipher
+            evp_cipher = cipher.cipher
         if format == "PEM":
         if format == "PEM":
-            r=libcrypto.PEM_write_bio_PrivateKey(b.bio,self.key,evp_cipher,None,0,_cb,
-                password)
+            ret = libcrypto.PEM_write_bio_PrivateKey(bio.bio, self.key,
+                                                     evp_cipher, None, 0,
+                                                     callback,
+                                                     c_char_p(password))
         else:
         else:
-            if cipher is not None:
-                raise NotImplementedError("Der-formatted encrypted keys are not supported")
-            r=libcrypto.i2d_PrivateKey_bio(b.bio,self.key)
-        if r==0:
+            ret = libcrypto.i2d_PKCS8PrivateKey_bio(bio.bio, self.key,
+                                                    evp_cipher, None, 0,
+                                                    callback,
+                                                    c_char_p(password))
+        if ret == 0:
             raise PKeyError("error serializing private key")
             raise PKeyError("error serializing private key")
-        return str(b)
+        return str(bio)
+
     @staticmethod
     @staticmethod
-    def _configure_context(ctx,opts,skip=[]):
+    def _configure_context(ctx, opts, skip=()):
         """
         """
-            Configures context of public key operations
-            @param ctx - context to configure
-            @param opts - dictionary of options (from kwargs of calling
-                function)
-            @param skip - list of options which shouldn't be passed to
-                context
+        Configures context of public key operations
+        @param ctx - context to configure
+        @param opts - dictionary of options (from kwargs of calling
+            function)
+        @param skip - list of options which shouldn't be passed to
+            context
         """
 
         for oper in opts:
             if oper in skip:
                 continue
         """
 
         for oper in opts:
             if oper in skip:
                 continue
-            rv=libcrypto.EVP_PKEY_CTX_ctrl_str(ctx,oper,str(opts[oper]))
-            if rv==-2:
-                raise PKeyError("Parameter %s is not supported by key"%(oper,))
-            if rv<1:
-                raise PKeyError("Error setting parameter %s"%(oper,))
+            ret = libcrypto.EVP_PKEY_CTX_ctrl_str(ctx, oper, str(opts[oper]))
+            if ret == -2:
+                raise PKeyError("Parameter %s is not supported by key" % oper)
+            if ret < 1:
+                raise PKeyError("Error setting parameter %s" % oper)
 # Declare function prototypes
 # Declare function prototypes
-libcrypto.EVP_PKEY_cmp.argtypes=(c_void_p,c_void_p)
-libcrypto.PEM_read_bio_PrivateKey.restype=c_void_p
-libcrypto.PEM_read_bio_PrivateKey.argtypes=(c_void_p,POINTER(c_void_p),CALLBACK_FUNC,c_char_p) 
-libcrypto.PEM_read_bio_PUBKEY.restype=c_void_p
-libcrypto.PEM_read_bio_PUBKEY.argtypes=(c_void_p,POINTER(c_void_p),CALLBACK_FUNC,c_char_p)
-libcrypto.d2i_PUBKEY_bio.restype=c_void_p
-libcrypto.d2i_PUBKEY_bio.argtypes=(c_void_p,c_void_p)
-libcrypto.d2i_PrivateKey_bio.restype=c_void_p
-libcrypto.d2i_PrivateKey_bio.argtypes=(c_void_p,c_void_p)
-libcrypto.EVP_PKEY_print_public.argtypes=(c_void_p,c_void_p,c_int,c_void_p)
-libcrypto.EVP_PKEY_asn1_find_str.restype=c_void_p
-libcrypto.EVP_PKEY_asn1_find_str.argtypes=(c_void_p,c_char_p,c_int)
-libcrypto.EVP_PKEY_asn1_get0_info.restype=c_int
-libcrypto.EVP_PKEY_asn1_get0_info.argtypes=(POINTER(c_int),POINTER(c_int),POINTER(c_int),POINTER(c_char_p), POINTER(c_char_p),c_void_p)
-libcrypto.EVP_PKEY_cmp.restype=c_int
-libcrypto.EVP_PKEY_cmp.argtypes=(c_void_p,c_void_p)
-libcrypto.EVP_PKEY_CTX_ctrl_str.restype=c_int
-libcrypto.EVP_PKEY_CTX_ctrl_str.argtypes=(c_void_p,c_void_p,c_void_p)
-libcrypto.EVP_PKEY_CTX_ctrl.restype=c_int
-libcrypto.EVP_PKEY_CTX_ctrl.argtypes=(c_void_p,c_int,c_int,c_int,c_int,c_void_p)
-libcrypto.EVP_PKEY_CTX_free.argtypes=(c_void_p,)
-libcrypto.EVP_PKEY_CTX_new.restype=c_void_p
-libcrypto.EVP_PKEY_CTX_new.argtypes=(c_void_p,c_void_p)
-libcrypto.EVP_PKEY_CTX_new_id.restype=c_void_p
-libcrypto.EVP_PKEY_CTX_new_id.argtypes=(c_int,c_void_p)
-libcrypto.EVP_PKEY_derive.restype=c_int
-libcrypto.EVP_PKEY_derive.argtypes=(c_void_p,c_char_p,POINTER(c_long))
-libcrypto.EVP_PKEY_derive_init.restype=c_int
-libcrypto.EVP_PKEY_derive_init.argtypes=(c_void_p,)
-libcrypto.EVP_PKEY_derive_set_peer.restype=c_int
-libcrypto.EVP_PKEY_derive_set_peer.argtypes=(c_void_p,c_void_p)
-libcrypto.EVP_PKEY_free.argtypes=(c_void_p,)
-libcrypto.EVP_PKEY_keygen.restype=c_int
-libcrypto.EVP_PKEY_keygen.argtypes=(c_void_p,c_void_p)
-libcrypto.EVP_PKEY_keygen_init.restype=c_int
-libcrypto.EVP_PKEY_keygen_init.argtypes=(c_void_p,)
-libcrypto.EVP_PKEY_sign.restype=c_int
-libcrypto.EVP_PKEY_sign.argtypes=(c_void_p,c_char_p,POINTER(c_long),c_char_p,c_long)
-libcrypto.EVP_PKEY_sign_init.restype=c_int
-libcrypto.EVP_PKEY_sign_init.argtypes=(c_void_p,)
-libcrypto.EVP_PKEY_verify.restype=c_int
-libcrypto.EVP_PKEY_verify.argtypes=(c_void_p,c_char_p,c_long,c_char_p,c_long)
-libcrypto.EVP_PKEY_verify_init.restype=c_int
-libcrypto.EVP_PKEY_verify_init.argtypes=(c_void_p,)
-libcrypto.PEM_write_bio_PrivateKey.argtypes=(c_void_p,c_void_p,c_void_p,c_char_p,c_int,CALLBACK_FUNC,c_char_p)
-libcrypto.PEM_write_bio_PUBKEY.argtypes=(c_void_p,c_void_p)
-libcrypto.i2d_PUBKEY_bio.argtypes=(c_void_p,c_void_p)
-libcrypto.i2d_PrivateKey_bio.argtypes=(c_void_p,c_void_p)
-libcrypto.ENGINE_finish.argtypes=(c_void_p,)
+libcrypto.EVP_PKEY_cmp.argtypes = (c_void_p, c_void_p)
+libcrypto.PEM_read_bio_PrivateKey.restype = c_void_p
+libcrypto.PEM_read_bio_PrivateKey.argtypes = (c_void_p, POINTER(c_void_p),
+                                              PW_CALLBACK_FUNC, c_char_p)
+libcrypto.PEM_read_bio_PUBKEY.restype = c_void_p
+libcrypto.PEM_read_bio_PUBKEY.argtypes = (c_void_p, POINTER(c_void_p),
+                                          PW_CALLBACK_FUNC, c_char_p)
+libcrypto.d2i_PUBKEY_bio.restype = c_void_p
+libcrypto.d2i_PUBKEY_bio.argtypes = (c_void_p, c_void_p)
+libcrypto.d2i_PrivateKey_bio.restype = c_void_p
+libcrypto.d2i_PrivateKey_bio.argtypes = (c_void_p, c_void_p)
+libcrypto.EVP_PKEY_print_public.argtypes = (c_void_p, c_void_p, c_int, c_void_p)
+libcrypto.EVP_PKEY_asn1_find_str.restype = c_void_p
+libcrypto.EVP_PKEY_asn1_find_str.argtypes = (c_void_p, c_char_p, c_int)
+libcrypto.EVP_PKEY_asn1_get0_info.restype = c_int
+libcrypto.EVP_PKEY_asn1_get0_info.argtypes = (POINTER(c_int), POINTER(c_int),
+                                              POINTER(c_int), POINTER(c_char_p),
+                                              POINTER(c_char_p), c_void_p)
+libcrypto.EVP_PKEY_cmp.restype = c_int
+libcrypto.EVP_PKEY_cmp.argtypes = (c_void_p, c_void_p)
+libcrypto.EVP_PKEY_CTX_ctrl_str.restype = c_int
+libcrypto.EVP_PKEY_CTX_ctrl_str.argtypes = (c_void_p, c_void_p, c_void_p)
+libcrypto.EVP_PKEY_CTX_ctrl.restype = c_int
+libcrypto.EVP_PKEY_CTX_ctrl.argtypes = (c_void_p, c_int, c_int, c_int, c_int,
+                                        c_void_p)
+libcrypto.EVP_PKEY_CTX_free.argtypes = (c_void_p, )
+libcrypto.EVP_PKEY_CTX_new.restype = c_void_p
+libcrypto.EVP_PKEY_CTX_new.argtypes = (c_void_p, c_void_p)
+libcrypto.EVP_PKEY_CTX_new_id.restype = c_void_p
+libcrypto.EVP_PKEY_CTX_new_id.argtypes = (c_int, c_void_p)
+libcrypto.EVP_PKEY_derive.restype = c_int
+libcrypto.EVP_PKEY_derive.argtypes = (c_void_p, c_char_p, POINTER(c_long))
+libcrypto.EVP_PKEY_derive_init.restype = c_int
+libcrypto.EVP_PKEY_derive_init.argtypes = (c_void_p, )
+libcrypto.EVP_PKEY_derive_set_peer.restype = c_int
+libcrypto.EVP_PKEY_derive_set_peer.argtypes = (c_void_p, c_void_p)
+libcrypto.EVP_PKEY_free.argtypes = (c_void_p,)
+libcrypto.EVP_PKEY_keygen.restype = c_int
+libcrypto.EVP_PKEY_keygen.argtypes = (c_void_p, c_void_p)
+libcrypto.EVP_PKEY_keygen_init.restype = c_int
+libcrypto.EVP_PKEY_keygen_init.argtypes = (c_void_p, )
+libcrypto.EVP_PKEY_sign.restype = c_int
+libcrypto.EVP_PKEY_sign.argtypes = (c_void_p, c_char_p, POINTER(c_long),
+                                    c_char_p, c_long)
+libcrypto.EVP_PKEY_sign_init.restype = c_int
+libcrypto.EVP_PKEY_sign_init.argtypes = (c_void_p, )
+libcrypto.EVP_PKEY_verify.restype = c_int
+libcrypto.EVP_PKEY_verify.argtypes = (c_void_p, c_char_p, c_long, c_char_p,
+                                      c_long)
+libcrypto.EVP_PKEY_verify_init.restype = c_int
+libcrypto.EVP_PKEY_verify_init.argtypes = (c_void_p, )
+libcrypto.PEM_write_bio_PrivateKey.argtypes = (c_void_p, c_void_p, c_void_p,
+                                               c_char_p, c_int,
+                                               PW_CALLBACK_FUNC, c_char_p)
+libcrypto.PEM_write_bio_PUBKEY.argtypes = (c_void_p, c_void_p)
+libcrypto.i2d_PUBKEY_bio.argtypes = (c_void_p, c_void_p)
+libcrypto.i2d_PKCS8PrivateKey_bio.argtypes = (c_void_p, c_void_p, c_void_p,
+                                              c_char_p, c_int,
+                                              PW_CALLBACK_FUNC, c_char_p)
+libcrypto.ENGINE_finish.argtypes = (c_void_p, )
index 92e67e96b0dbbe303e663d077362c904656a7852..d9e966d67c67f6635751ce54338990ae788915eb 100644 (file)
@@ -6,40 +6,41 @@ from ctypes import create_string_buffer, c_char_p, c_int, c_double
 from ctypescrypto import libcrypto
 from ctypescrypto.exception import LibCryptoError
 
 from ctypescrypto import libcrypto
 from ctypescrypto.exception import LibCryptoError
 
-__all__ = ['RandError','bytes','pseudo_bytes','seed','status']
+__all__ = ['RandError', 'bytes', 'pseudo_bytes', 'seed', 'status']
 
 class RandError(LibCryptoError):
 
 class RandError(LibCryptoError):
+    """ Exception raised when openssl function return error """
     pass
 
     pass
 
-def bytes( num, check_result=False):
+def bytes(num, check_result=False):
     """
     """
-        Returns num bytes of cryptographically strong pseudo-random
-        bytes. If checkc_result is True, raises error if PRNG is not
-        seeded enough
+    Returns num bytes of cryptographically strong pseudo-random
+    bytes. If checkc_result is True, raises error if PRNG is not
+    seeded enough
     """
 
     """
 
-    if num <= 0 :
+    if num <= 0:
         raise ValueError("'num' should be > 0")
         raise ValueError("'num' should be > 0")
-    buffer = create_string_buffer(num)
-    result = libcrypto.RAND_bytes(buffer, num) 
+    buf = create_string_buffer(num)
+    result = libcrypto.RAND_bytes(buf, num)
     if check_result and result == 0:
         raise RandError("Random Number Generator not seeded sufficiently")
     if check_result and result == 0:
         raise RandError("Random Number Generator not seeded sufficiently")
-    return buffer.raw[:num]
+    return buf.raw[:num]
 
 def pseudo_bytes(num):
     """
 
 def pseudo_bytes(num):
     """
-        Returns num bytes of pseudo random data.  Pseudo- random byte
-        sequences generated by pseudo_bytes() will be unique if
-        they are of sufficient length, but are not necessarily
-        unpredictable. They can be used for non-cryptographic purposes
-        and for certain purposes in cryptographic protocols, but usually
-        not for key generation etc.
+    Returns num bytes of pseudo random data.  Pseudo- random byte
+    sequences generated by pseudo_bytes() will be unique if
+    they are of sufficient length, but are not necessarily
+    unpredictable. They can be used for non-cryptographic purposes
+    and for certain purposes in cryptographic protocols, but usually
+    not for key generation etc.
     """
     """
-    if num <= 0 :
+    if num <= 0:
         raise ValueError("'num' should be > 0")
         raise ValueError("'num' should be > 0")
-    buffer = create_string_buffer(num)
-    libcrypto.RAND_pseudo_bytes(buffer, num)
-    return buffer.raw[:num]
+    buf = create_string_buffer(num)
+    libcrypto.RAND_pseudo_bytes(buf, num)
+    return buf.raw[:num]
 
 def seed(data, entropy=None):
     """
 
 def seed(data, entropy=None):
     """
@@ -47,24 +48,24 @@ def seed(data, entropy=None):
         If entropy is not None, it should be floating point(double)
         value estimating amount of entropy  in the data (in bytes).
     """
         If entropy is not None, it should be floating point(double)
         value estimating amount of entropy  in the data (in bytes).
     """
-    if not isinstance(data,str):
+    if not isinstance(data, str):
         raise TypeError("A string is expected")
     ptr = c_char_p(data)
     size = len(data)
     if entropy is None:
         libcrypto.RAND_seed(ptr, size)
         raise TypeError("A string is expected")
     ptr = c_char_p(data)
     size = len(data)
     if entropy is None:
         libcrypto.RAND_seed(ptr, size)
-    else :
+    else:
         libcrypto.RAND_add(ptr, size, entropy)
 
 def status():
     """
         libcrypto.RAND_add(ptr, size, entropy)
 
 def status():
     """
-        Returns 1 if random generator is sufficiently seeded and 0
-        otherwise
+    Returns 1 if random generator is sufficiently seeded and 0
+    otherwise
     """
 
     return libcrypto.RAND_status()
     """
 
     return libcrypto.RAND_status()
-    
-libcrypto.RAND_add.argtypes=(c_char_p,c_int,c_double)
-libcrypto.RAND_seed.argtypes=(c_char_p,c_int)
-libcrypto.RAND_pseudo_bytes.argtypes=(c_char_p,c_int)
-libcrypto.RAND_bytes.argtypes=(c_char_p,c_int)
+
+libcrypto.RAND_add.argtypes = (c_char_p, c_int, c_double)
+libcrypto.RAND_seed.argtypes = (c_char_p, c_int)
+libcrypto.RAND_pseudo_bytes.argtypes = (c_char_p, c_int)
+libcrypto.RAND_bytes.argtypes = (c_char_p, c_int)
index 159956d72f457dc3640a95db75007092f8408bb0..40263cffea5d1e26528bb989231a92808bfc86a2 100644 (file)
@@ -1,5 +1,5 @@
 """
 """
-Implements interface to openssl X509 and X509Store structures, 
+Implements interface to openssl X509 and X509Store structures,
 I.e allows to load, analyze and verify certificates.
 
 X509Store objects are also used to verify other signed documets,
 I.e allows to load, analyze and verify certificates.
 
 X509Store objects are also used to verify other signed documets,
@@ -8,23 +8,23 @@ such as CMS, OCSP and timestamps.
 
 
 
 
 
 
-from ctypes import c_void_p,create_string_buffer,c_long,c_int,POINTER,c_char_p,Structure,cast
+from ctypes import c_void_p, c_long, c_int, POINTER, c_char_p, Structure, cast
 from ctypescrypto.bio import Membio
 from ctypescrypto.pkey import PKey
 from ctypescrypto.oid import Oid
 from ctypescrypto.exception import LibCryptoError
 from ctypescrypto import libcrypto
 from datetime import datetime
 from ctypescrypto.bio import Membio
 from ctypescrypto.pkey import PKey
 from ctypescrypto.oid import Oid
 from ctypescrypto.exception import LibCryptoError
 from ctypescrypto import libcrypto
 from datetime import datetime
+
 try:
     from pytz import utc
 except ImportError:
 try:
     from pytz import utc
 except ImportError:
-    from datetime import timedelta,tzinfo
-    ZERO=timedelta(0)
+    from datetime import timedelta, tzinfo
+    ZERO = timedelta(0)
     class UTC(tzinfo):
     class UTC(tzinfo):
-        """tzinfo object for UTC. 
+        """tzinfo object for UTC.
             If no pytz is available, we would use it.
         """
             If no pytz is available, we would use it.
         """
-
         def utcoffset(self, dt):
             return ZERO
 
         def utcoffset(self, dt):
             return ZERO
 
@@ -34,33 +34,33 @@ except ImportError:
         def dst(self, dt):
             return ZERO
 
         def dst(self, dt):
             return ZERO
 
-    utc=UTC()
+    utc = UTC()
 
 
-__all__ = ['X509','X509Error','X509Name','X509Store','StackOfX509']
+__all__ = ['X509', 'X509Error', 'X509Name', 'X509Store', 'StackOfX509']
 
 class _validity(Structure):
 
 class _validity(Structure):
-    """ ctypes representation of X509_VAL structure 
+    """ ctypes representation of X509_VAL structure
         needed to access certificate validity period, because openssl
         doesn't provide fuctions for it - only macros
     """
         needed to access certificate validity period, because openssl
         doesn't provide fuctions for it - only macros
     """
-    _fields_ =  [('notBefore',c_void_p),('notAfter',c_void_p)]
+    _fields_ = [('notBefore', c_void_p), ('notAfter', c_void_p)]
 
 class _cinf(Structure):
 
 class _cinf(Structure):
-    """ ctypes representtion of X509_CINF structure 
+    """ ctypes representtion of X509_CINF structure
         neede to access certificate data, which are accessable only
         via macros
     """
         neede to access certificate data, which are accessable only
         via macros
     """
-    _fields_ = [('version',c_void_p),
-        ('serialNumber',c_void_p),
-        ('sign_alg',c_void_p),
-        ('issuer',c_void_p),
-        ('validity',POINTER(_validity)),
-        ('subject',c_void_p),
-        ('pubkey',c_void_p),
-        ('issuerUID',c_void_p),
-        ('subjectUID',c_void_p),
-        ('extensions',c_void_p),
-        ]
+    _fields_ = [('version', c_void_p),
+                ('serialNumber', c_void_p),
+                ('sign_alg', c_void_p),
+                ('issuer', c_void_p),
+                ('validity', POINTER(_validity)),
+                ('subject', c_void_p),
+                ('pubkey', c_void_p),
+                ('issuerUID', c_void_p),
+                ('subjectUID', c_void_p),
+                ('extensions', c_void_p),
+               ]
 
 class _x509(Structure):
     """
 
 class _x509(Structure):
     """
@@ -68,11 +68,11 @@ class _x509(Structure):
     to access certificate data which are accesable only via
     macros, not functions
     """
     to access certificate data which are accesable only via
     macros, not functions
     """
-    _fields_ = [('cert_info',POINTER(_cinf)),
-                ('sig_alg',c_void_p),
-                ('signature',c_void_p),
+    _fields_ = [('cert_info', POINTER(_cinf)),
+                ('sig_alg', c_void_p),
+                ('signature', c_void_p),
                 # There are a lot of parsed extension fields there
                 # There are a lot of parsed extension fields there
-                ]
+               ]
 _px509 = POINTER(_x509)
 
 class X509Error(LibCryptoError):
 _px509 = POINTER(_x509)
 
 class X509Error(LibCryptoError):
@@ -85,7 +85,7 @@ class X509Error(LibCryptoError):
 
 class X509Name(object):
     """
 
 class X509Name(object):
     """
-    Class which represents X.509 distinguished name - typically 
+    Class which represents X.509 distinguished name - typically
     a certificate subject name or an issuer name.
 
     Now used only to represent information, extracted from the
     a certificate subject name or an issuer name.
 
     Now used only to represent information, extracted from the
@@ -93,22 +93,25 @@ class X509Name(object):
     certificate signing request
     """
     # XN_FLAG_SEP_COMMA_PLUS & ASN1_STRFLG_UTF8_CONVERT
     certificate signing request
     """
     # XN_FLAG_SEP_COMMA_PLUS & ASN1_STRFLG_UTF8_CONVERT
-    PRINT_FLAG=0x10010
-    ESC_MSB=4
-    def __init__(self,ptr=None,copy=False):
+    PRINT_FLAG = 0x10010
+    ESC_MSB = 4
+    def __init__(self, ptr=None, copy=False):
         """
         Creates a X509Name object
         """
         Creates a X509Name object
-        @param ptr - pointer to X509_NAME C structure (as returned by some  OpenSSL functions
-        @param copy - indicates that this structure have to be freed upon object destruction
+        @param ptr - pointer to X509_NAME C structure (as returned by some
+                     OpenSSL functions
+        @param copy - indicates that this structure have to be freed upon
+                      object destruction
         """
         if ptr is not None:
         """
         if ptr is not None:
-            self.ptr=ptr
-            self.need_free=copy
-            self.writable=False
+            self.ptr = ptr
+            self.need_free = copy
+            self.writable = False
         else:
         else:
-            self.ptr=libcrypto.X509_NAME_new()
-            self.need_free=True
-            self.writable=True
+            self.ptr = libcrypto.X509_NAME_new()
+            self.need_free = True
+            self.writable = True
+
     def __del__(self):
         """
         Frees if neccessary
     def __del__(self):
         """
         Frees if neccessary
@@ -117,62 +120,65 @@ class X509Name(object):
             libcrypto.X509_NAME_free(self.ptr)
     def __str__(self):
         """
             libcrypto.X509_NAME_free(self.ptr)
     def __str__(self):
         """
-        Produces an ascii representation of the name, escaping all symbols > 0x80
-        Probably it is not what you want, unless your native language is English
+        Produces an ascii representation of the name, escaping all
+        symbols > 0x80.  Probably it is not what you want, unless
+        your native language is English
         """
         """
-        b=Membio()
-        libcrypto.X509_NAME_print_ex(b.bio,self.ptr,0,self.PRINT_FLAG | self.ESC_MSB)
-        return str(b)
+        bio = Membio()
+        libcrypto.X509_NAME_print_ex(bio.bio, self.ptr, 0,
+                                     self.PRINT_FLAG | self.ESC_MSB)
+        return str(bio)
+
     def __unicode__(self):
         """
     def __unicode__(self):
         """
-        Produces unicode representation of the name. 
+        Produces unicode representation of the name.
         """
         """
-        b=Membio()
-        libcrypto.X509_NAME_print_ex(b.bio,self.ptr,0,self.PRINT_FLAG)
-        return unicode(b)
+        bio = Membio()
+        libcrypto.X509_NAME_print_ex(bio.bio, self.ptr, 0, self.PRINT_FLAG)
+        return unicode(bio)
     def __len__(self):
         """
         return number of components in the name
         """
         return libcrypto.X509_NAME_entry_count(self.ptr)
     def __len__(self):
         """
         return number of components in the name
         """
         return libcrypto.X509_NAME_entry_count(self.ptr)
-    def __cmp__(self,other):
+    def __cmp__(self, other):
         """
         Compares X509 names
         """
         """
         Compares X509 names
         """
-        return libcrypto.X509_NAME_cmp(self.ptr,other.ptr)
-    def __eq__(self,other):
-        return libcrypto.X509_NAME_cmp(self.ptr,other.ptr)==0
+        return libcrypto.X509_NAME_cmp(self.ptr, other.ptr)
+    def __eq__(self, other):
+        return libcrypto.X509_NAME_cmp(self.ptr, other.ptr) == 0
 
 
-    def __getitem__(self,key):
-        if isinstance(key,Oid):
+    def __getitem__(self, key):
+        if isinstance(key, Oid):
             # Return first matching field
             # Return first matching field
-            idx=libcrypto.X509_NAME_get_index_by_NID(self.ptr,key.nid,-1)
-            if idx<0:
-                raise KeyError("Key not found "+str(Oid))
-            entry=libcrypto.X509_NAME_get_entry(self.ptr,idx)
-            s=libcrypto.X509_NAME_ENTRY_get_data(entry)
-            b=Membio()
-            libcrypto.ASN1_STRING_print_ex(b.bio,s,self.PRINT_FLAG)
-            return unicode(b)
-        elif isinstance(key,(int,long)):
+            idx = libcrypto.X509_NAME_get_index_by_NID(self.ptr, key.nid, -1)
+            if idx < 0:
+                raise KeyError("Key not found " + str(Oid))
+            entry = libcrypto.X509_NAME_get_entry(self.ptr, idx)
+            value = libcrypto.X509_NAME_ENTRY_get_data(entry)
+            bio = Membio()
+            libcrypto.ASN1_STRING_print_ex(bio.bio, value, self.PRINT_FLAG)
+            return unicode(bio)
+        elif isinstance(key, (int, long)):
             # Return OID, string tuple
             # Return OID, string tuple
-            entry=libcrypto.X509_NAME_get_entry(self.ptr,key)
+            entry = libcrypto.X509_NAME_get_entry(self.ptr, key)
             if entry is None:
                 raise IndexError("name entry index out of range")
             if entry is None:
                 raise IndexError("name entry index out of range")
-            oid=Oid.fromobj(libcrypto.X509_NAME_ENTRY_get_object(entry))
-            s=libcrypto.X509_NAME_ENTRY_get_data(entry)
-            b=Membio()
-            libcrypto.ASN1_STRING_print_ex(b.bio,s,self.PRINT_FLAG)
-            return (oid,unicode(b))
+            oid = Oid.fromobj(libcrypto.X509_NAME_ENTRY_get_object(entry))
+            value = libcrypto.X509_NAME_ENTRY_get_data(entry)
+            bio = Membio()
+            libcrypto.ASN1_STRING_print_ex(bio.bio, value, self.PRINT_FLAG)
+            return (oid, unicode(bio))
         else:
             raise TypeError("X509 NAME can be indexed by Oids or integers only")
 
         else:
             raise TypeError("X509 NAME can be indexed by Oids or integers only")
 
-    def __setitem__(self,key,val):
+    def __setitem__(self, key, val):
         if not self.writable:
             raise ValueError("Attempt to modify constant X509 object")
         else:
             raise NotImplementedError
         if not self.writable:
             raise ValueError("Attempt to modify constant X509 object")
         else:
             raise NotImplementedError
-    def __delitem__(self,key):
+    def __delitem__(self, key):
         if not self.writable:
             raise ValueError("Attempt to modify constant X509 object")
         else:
         if not self.writable:
             raise ValueError("Attempt to modify constant X509 object")
         else:
@@ -182,111 +188,140 @@ class X509Name(object):
 
 class _x509_ext(Structure):
     """ Represens C structure X509_EXTENSION """
 
 class _x509_ext(Structure):
     """ Represens C structure X509_EXTENSION """
-    _fields_=[("object",c_void_p),
-            ("critical",c_int),
-            ("value",c_void_p)]
+    _fields_ = [("object", c_void_p),
+                ("critical", c_int),
+                ("value", c_void_p)
+               ]
 
 class X509_EXT(object):
     """ Python object which represents a certificate extension """
 
 class X509_EXT(object):
     """ Python object which represents a certificate extension """
-    def __init__(self,ptr,copy=False):
+    def __init__(self, ptr, copy=False):
         """ Initializes from the pointer to X509_EXTENSION.
             If copy is True, creates a copy, otherwise just
             stores pointer.
         """
         if copy:
         """ Initializes from the pointer to X509_EXTENSION.
             If copy is True, creates a copy, otherwise just
             stores pointer.
         """
         if copy:
-            self.ptr=libcrypto.X509_EXTENSION_dup(ptr)
+            self.ptr = libcrypto.X509_EXTENSION_dup(ptr)
         else:
         else:
-            self.ptr=cast(ptr,POINTER(_x509_ext))
+            self.ptr = cast(ptr, POINTER(_x509_ext))
     def __del__(self):
         libcrypto.X509_EXTENSION_free(self.ptr)
     def __str__(self):
     def __del__(self):
         libcrypto.X509_EXTENSION_free(self.ptr)
     def __str__(self):
-        b=Membio()
-        libcrypto.X509V3_EXT_print(b.bio,self.ptr,0x20010,0)
-        return str(b)
+        bio = Membio()
+        libcrypto.X509V3_EXT_print(bio.bio, self.ptr, 0x20010, 0)
+        return str(bio)
     def __unicode__(self):
     def __unicode__(self):
-        b=Membio()
-        libcrypto.X509V3_EXT_print(b.bio,self.ptr,0x20010,0)
-        return unicode(b)
+        bio = Membio()
+        libcrypto.X509V3_EXT_print(bio.bio, self.ptr, 0x20010, 0)
+        return unicode(bio)
     @property
     def oid(self):
     @property
     def oid(self):
+        "Returns OID of the extension"
         return Oid.fromobj(self.ptr[0].object)
     @property
         return Oid.fromobj(self.ptr[0].object)
     @property
-    def critical(self): 
-        return self.ptr[0].critical >0
-class _X509extlist(object): 
+    def critical(self):
+        "Returns True if extensin have critical flag set"
+        return self.ptr[0].critical > 0
+
+class _X509extlist(object):
     """
     """
-    Represents list of certificate extensions
+    Represents list of certificate extensions. Really it keeps
+    reference to certificate object
     """
     """
-    def __init__(self,cert):
-        self.cert=cert
+    def __init__(self, cert):
+        """
+        Initialize from X509 object
+        """
+        self.cert = cert
+
     def __len__(self):
     def __len__(self):
+        """
+        Returns number of extensions
+        """
         return libcrypto.X509_get_ext_count(self.cert.cert)
         return libcrypto.X509_get_ext_count(self.cert.cert)
-    def __getitem__(self,item):
-        p=libcrypto.X509_get_ext(self.cert.cert,item)
-        if p is None:
+
+    def __getitem__(self, item):
+        """
+        Returns extension by index, creating a copy
+        """
+        ext_ptr = libcrypto.X509_get_ext(self.cert.cert, item)
+        if ext_ptr is None:
             raise IndexError
             raise IndexError
-        return X509_EXT(p,True)
-    def find(self,oid):
+        return X509_EXT(ext_ptr, True)
+    def find(self, oid):
         """
         Return list of extensions with given Oid
         """
         """
         Return list of extensions with given Oid
         """
-        if not isinstance(oid,Oid):
+        if not isinstance(oid, Oid):
             raise TypeError("Need crytypescrypto.oid.Oid as argument")
             raise TypeError("Need crytypescrypto.oid.Oid as argument")
-        found=[]
-        l=-1
-        end=len(self)
+        found = []
+        index = -1
+        end = len(self)
         while True:
         while True:
-            l=libcrypto.X509_get_ext_by_NID(self.cert.cert,oid.nid,l)
-            if l>=end or l<0:
-                 break
-            found.append(self[l])
+            index = libcrypto.X509_get_ext_by_NID(self.cert.cert, oid.nid,
+                                                  index)
+            if index >= end or index < 0:
+                break
+            found.append(self[index])
         return found
         return found
-    def find_critical(self,crit=True):
+
+    def find_critical(self, crit=True):
         """
         Return list of critical extensions (or list of non-cricital, if
         optional second argument is False
         """
         if crit:
         """
         Return list of critical extensions (or list of non-cricital, if
         optional second argument is False
         """
         if crit:
-            flag=1
+            flag = 1
         else:
         else:
-            flag=0
-        found=[]
-        end=len(self)
-        l=-1
+            flag = 0
+        found = []
+        end = len(self)
+        index = -1
         while True:
         while True:
-            l=libcrypto.X509_get_ext_by_critical(self.cert.cert,flag,l)
-            if l>=end or l<0:
-                 break
-            found.append(self[l])
-        return found            
+            index = libcrypto.X509_get_ext_by_critical(self.cert.cert, flag,
+                                                       index)
+            if index >= end or index < 0:
+                break
+            found.append(self[index])
+        return found
+
+def _X509__asn1date_to_datetime(asn1date):
+    """ 
+    Converts openssl ASN1_TIME object to python datetime.datetime
+    """
+    bio = Membio()
+    libcrypto.ASN1_TIME_print(bio.bio, asn1date)
+    pydate = datetime.strptime(str(bio), "%b %d %H:%M:%S %Y %Z")
+    return pydate.replace(tzinfo=utc)
 
 class X509(object):
     """
 
 class X509(object):
     """
-    Represents X.509 certificate. 
+    Represents X.509 certificate.
     """
     """
-    def __init__(self,data=None,ptr=None,format="PEM"):
+    def __init__(self, data=None, ptr=None, format="PEM"):
         """
         Initializes certificate
         @param data - serialized certificate in PEM or DER format.
         """
         Initializes certificate
         @param data - serialized certificate in PEM or DER format.
-        @param ptr - pointer to X509, returned by some openssl function. 
+        @param ptr - pointer to X509, returned by some openssl function.
             mutually exclusive with data
         @param format - specifies data format. "PEM" or "DER", default PEM
         """
         if ptr is not None:
             mutually exclusive with data
         @param format - specifies data format. "PEM" or "DER", default PEM
         """
         if ptr is not None:
-            if data is not None: 
+            if data is not None:
                 raise TypeError("Cannot use data and ptr simultaneously")
             self.cert = ptr
         elif data is None:
             raise TypeError("data argument is required")
         else:
                 raise TypeError("Cannot use data and ptr simultaneously")
             self.cert = ptr
         elif data is None:
             raise TypeError("data argument is required")
         else:
-            b=Membio(data)
+            bio = Membio(data)
             if format == "PEM":
             if format == "PEM":
-                self.cert=libcrypto.PEM_read_bio_X509(b.bio,None,None,None)
+                self.cert = libcrypto.PEM_read_bio_X509(bio.bio, None, None,
+                                                        None)
             else:
             else:
-                self.cert=libcrypto.d2i_X509_bio(b.bio,None)
+                self.cert = libcrypto.d2i_X509_bio(bio.bio, None)
             if self.cert is None:
                 raise X509Error("error reading certificate")
             if self.cert is None:
                 raise X509Error("error reading certificate")
-        self.extensions=_X509extlist(self)      
+        self.extensions = _X509extlist(self)
     def __del__(self):
         """
         Frees certificate object
     def __del__(self):
         """
         Frees certificate object
@@ -294,62 +329,63 @@ class X509(object):
         libcrypto.X509_free(self.cert)
     def __str__(self):
         """ Returns der string of the certificate """
         libcrypto.X509_free(self.cert)
     def __str__(self):
         """ Returns der string of the certificate """
-        b=Membio()
-        if libcrypto.i2d_X509_bio(b.bio,self.cert)==0:
+        bio = Membio()
+        if libcrypto.i2d_X509_bio(bio.bio, self.cert) == 0:
             raise X509Error("error serializing certificate")
             raise X509Error("error serializing certificate")
-        return str(b)
+        return str(bio)
     def __repr__(self):
         """ Returns valid call to the constructor """
     def __repr__(self):
         """ Returns valid call to the constructor """
-        return "X509(data="+repr(str(self))+",format='DER')"
+        return "X509(data=" + repr(str(self)) + ",format='DER')"
     @property
     def pubkey(self):
         """EVP PKEy object of certificate public key"""
     @property
     def pubkey(self):
         """EVP PKEy object of certificate public key"""
-        return PKey(ptr=libcrypto.X509_get_pubkey(self.cert,False))
+        return PKey(ptr=libcrypto.X509_get_pubkey(self.cert, False))
     def pem(self):
         """ Returns PEM represntation of the certificate """
     def pem(self):
         """ Returns PEM represntation of the certificate """
-        b=Membio()
-        if libcrypto.PEM_write_bio_X509(b.bio,self.cert)==0:
+        bio = Membio()
+        if libcrypto.PEM_write_bio_X509(bio.bio, self.cert) == 0:
             raise X509Error("error serializing certificate")
             raise X509Error("error serializing certificate")
-        return str(b)
-    def verify(self,store=None,chain=[],key=None):  
-        """ 
-        Verify self. Supports verification on both X509 store object 
+        return str(bio)
+    def verify(self, store=None, chain=None, key=None):
+        """
+        Verify self. Supports verification on both X509 store object
         or just public issuer key
         @param store X509Store object.
         @param chain - list of X509 objects to add into verification
             context.These objects are untrusted, but can be used to
             build certificate chain up to trusted object in the store
         @param key - PKey object with open key to validate signature
         or just public issuer key
         @param store X509Store object.
         @param chain - list of X509 objects to add into verification
             context.These objects are untrusted, but can be used to
             build certificate chain up to trusted object in the store
         @param key - PKey object with open key to validate signature
-        
-        parameters store and key are mutually exclusive. If neither 
+
+        parameters store and key are mutually exclusive. If neither
         is specified, attempts to verify self as self-signed certificate
         """
         if store is not None and key is not None:
             raise X509Error("key and store cannot be specified simultaneously")
         if store is not None:
         is specified, attempts to verify self as self-signed certificate
         """
         if store is not None and key is not None:
             raise X509Error("key and store cannot be specified simultaneously")
         if store is not None:
-            ctx=libcrypto.X509_STORE_CTX_new()
+            ctx = libcrypto.X509_STORE_CTX_new()
             if ctx is None:
                 raise X509Error("Error allocating X509_STORE_CTX")
             if ctx is None:
                 raise X509Error("Error allocating X509_STORE_CTX")
-            if chain is not None and len(chain)>0:
-                ch=StackOfX509(chain)
+            if chain is not None and len(chain) > 0:
+                chain_ptr = StackOfX509(chain).ptr
             else:
             else:
-                ch=None
-            if libcrypto.X509_STORE_CTX_init(ctx,store.store,self.cert,ch) < 0:
+                chain_ptr = None
+            if libcrypto.X509_STORE_CTX_init(ctx, store.store, self.cert,
+                                             chain_ptr) < 0:
                 raise X509Error("Error allocating X509_STORE_CTX")
                 raise X509Error("Error allocating X509_STORE_CTX")
-            res= libcrypto.X509_verify_cert(ctx)
+            res = libcrypto.X509_verify_cert(ctx)
             libcrypto.X509_STORE_CTX_free(ctx)
             libcrypto.X509_STORE_CTX_free(ctx)
-            return res>0
+            return res > 0
         else:
             if key is None:
                 if self.issuer != self.subject:
                     # Not a self-signed certificate
                     return False
                 key = self.pubkey
         else:
             if key is None:
                 if self.issuer != self.subject:
                     # Not a self-signed certificate
                     return False
                 key = self.pubkey
-            res = libcrypto.X509_verify(self.cert,key.key)
+            res = libcrypto.X509_verify(self.cert, key.key)
             if res < 0:
                 raise X509Error("X509_verify failed")
             if res < 0:
                 raise X509Error("X509_verify failed")
-            return res>0
-            
+            return res > 0
+
     @property
     def subject(self):
         """ X509Name for certificate subject name """
     @property
     def subject(self):
         """ X509Name for certificate subject name """
@@ -361,134 +397,139 @@ class X509(object):
     @property
     def serial(self):
         """ Serial number of certificate as integer """
     @property
     def serial(self):
         """ Serial number of certificate as integer """
-        asnint=libcrypto.X509_get_serialNumber(self.cert)
-        b=Membio()
-        libcrypto.i2a_ASN1_INTEGER(b.bio,asnint)
-        return int(str(b),16)
-    @property 
+        asnint = libcrypto.X509_get_serialNumber(self.cert)
+        bio = Membio()
+        libcrypto.i2a_ASN1_INTEGER(bio.bio, asnint)
+        return int(str(bio), 16)
+    @property
     def version(self):
     def version(self):
-        """ certificate version as integer. Really certificate stores 0 for
-        version 1 and 2 for version 3, but we return 1 and 3 """
-        asn1int=cast(self.cert,_px509)[0].cert_info[0].version
-        return libcrypto.ASN1_INTEGER_get(asn1int)+1
+        """
+        certificate version as integer. Really certificate stores 0 for
+        version 1 and 2 for version 3, but we return 1 and 3
+        """
+        asn1int = cast(self.cert, _px509)[0].cert_info[0].version
+        return libcrypto.ASN1_INTEGER_get(asn1int) + 1
     @property
     def startDate(self):
         """ Certificate validity period start date """
     @property
     def startDate(self):
         """ Certificate validity period start date """
-        # Need deep poke into certificate structure (x)->cert_info->validity->notBefore 
-        global utc
-        asn1date=cast(self.cert,_px509)[0].cert_info[0].validity[0].notBefore
-        b=Membio()
-        libcrypto.ASN1_TIME_print(b.bio,asn1date)
-        return datetime.strptime(str(b),"%b %d %H:%M:%S %Y %Z").replace(tzinfo=utc)
+        # Need deep poke into certificate structure
+        # (x)->cert_info->validity->notBefore
+        asn1 = cast(self.cert, _px509)[0].cert_info[0].validity[0].notBefore
+        return __asn1date_to_datetime(asn1)
     @property
     def endDate(self):
         """ Certificate validity period end date """
     @property
     def endDate(self):
         """ Certificate validity period end date """
-        # Need deep poke into certificate structure (x)->cert_info->validity->notAfter
-        global utc
-        asn1date=cast(self.cert,_px509)[0].cert_info[0].validity[0].notAfter
-        b=Membio()
-        libcrypto.ASN1_TIME_print(b.bio,asn1date)
-        return datetime.strptime(str(b),"%b %d %H:%M:%S %Y %Z").replace(tzinfo=utc)
+        # Need deep poke into certificate structure
+        # (x)->cert_info->validity->notAfter
+        asn1 = cast(self.cert, _px509)[0].cert_info[0].validity[0].notAfter
+        return __asn1date_to_datetime(asn1)
     def check_ca(self):
         """ Returns True if certificate is CA certificate """
     def check_ca(self):
         """ Returns True if certificate is CA certificate """
-        return libcrypto.X509_check_ca(self.cert)>0
+        return libcrypto.X509_check_ca(self.cert) > 0
+
 class X509Store(object):
     """
 class X509Store(object):
     """
-        Represents trusted certificate store. Can be used to lookup CA 
-        certificates to verify
+    Represents trusted certificate store. Can be used to lookup CA
+    certificates to verify
 
 
-        @param file - file with several certificates and crls 
-                to load into store
-        @param dir - hashed directory with certificates and crls
-        @param default - if true, default verify location (directory) 
-            is installed
+    @param file - file with several certificates and crls
+            to load into store
+    @param dir - hashed directory with certificates and crls
+    @param default - if true, default verify location (directory)
+        is installed
 
     """
 
     """
-    def __init__(self,file=None,dir=None,default=False):
+    def __init__(self, file=None, dir=None, default=False):
         """
         """
-        Creates X509 store and installs lookup method. Optionally initializes 
+        Creates X509 store and installs lookup method. Optionally initializes
         by certificates from given file or directory.
         """
         #
         # Todo - set verification flags
         by certificates from given file or directory.
         """
         #
         # Todo - set verification flags
-        # 
-        self.store=libcrypto.X509_STORE_new()
+        #
+        self.store = libcrypto.X509_STORE_new()
         if self.store is None:
             raise X509Error("allocating store")
         if self.store is None:
             raise X509Error("allocating store")
-        lookup=libcrypto.X509_STORE_add_lookup(self.store,libcrypto.X509_LOOKUP_file())
+        lookup = libcrypto.X509_STORE_add_lookup(self.store,
+                                                 libcrypto.X509_LOOKUP_file())
         if lookup is None:
             raise X509Error("error installing file lookup method")
         if lookup is None:
             raise X509Error("error installing file lookup method")
-        if (file is not None):
-            if not libcrypto.X509_LOOKUP_ctrl(lookup,1,file,1,None)>0:
+        if file is not None:
+            if not libcrypto.X509_LOOKUP_ctrl(lookup, 1, file, 1, None) > 0:
                 raise X509Error("error loading trusted certs from file "+file)
                 raise X509Error("error loading trusted certs from file "+file)
-        lookup=libcrypto.X509_STORE_add_lookup(self.store,libcrypto.X509_LOOKUP_hash_dir())
+        lookup = libcrypto.X509_STORE_add_lookup(self.store,
+                                             libcrypto.X509_LOOKUP_hash_dir())
         if lookup is None:
             raise X509Error("error installing hashed lookup method")
         if dir is not None:
         if lookup is None:
             raise X509Error("error installing hashed lookup method")
         if dir is not None:
-            if not libcrypto.X509_LOOKUP_ctrl(lookup,2,dir,1,None)>0:
+            if not libcrypto.X509_LOOKUP_ctrl(lookup, 2, dir, 1, None) > 0:
                 raise X509Error("error adding hashed  trusted certs dir "+dir)
         if default:
                 raise X509Error("error adding hashed  trusted certs dir "+dir)
         if default:
-            if not libcrypto.X509_LOOKUP_ctrl(lookup,2,None,3,None)>0:
+            if not libcrypto.X509_LOOKUP_ctrl(lookup, 2, None, 3, None) > 0:
                 raise X509Error("error adding default trusted certs dir ")
                 raise X509Error("error adding default trusted certs dir ")
-    def add_cert(self,cert):
+    def add_cert(self, cert):
         """
         Explicitely adds certificate to set of trusted in the store
         @param cert - X509 object to add
         """
         """
         Explicitely adds certificate to set of trusted in the store
         @param cert - X509 object to add
         """
-        if not isinstance(cert,X509):
+        if not isinstance(cert, X509):
             raise TypeError("cert should be X509")
             raise TypeError("cert should be X509")
-        libcrypto.X509_STORE_add_cert(self.store,cert.cert)
-    def add_callback(self,callback):
+        libcrypto.X509_STORE_add_cert(self.store, cert.cert)
+    def add_callback(self, callback):
         """
         Installs callback function, which would receive detailed information
         about verified ceritificates
         """
         raise NotImplementedError
         """
         Installs callback function, which would receive detailed information
         about verified ceritificates
         """
         raise NotImplementedError
-    def setflags(self,flags):
+    def setflags(self, flags):
         """
         Set certificate verification flags.
         @param flags - integer bit mask. See OpenSSL X509_V_FLAG_* constants
         """
         """
         Set certificate verification flags.
         @param flags - integer bit mask. See OpenSSL X509_V_FLAG_* constants
         """
-        libcrypto.X509_STORE_set_flags(self.store,flags)    
-    def setpurpose(self,purpose):
+        libcrypto.X509_STORE_set_flags(self.store, flags)
+    def setpurpose(self, purpose):
         """
         Sets certificate purpose which verified certificate should match
         """
         Sets certificate purpose which verified certificate should match
-        @param purpose - number from 1 to 9 or standard strind defined in Openssl
-        possible strings - sslcient,sslserver, nssslserver, smimesign,smimeencrypt, crlsign, any,ocsphelper
-        """
-        if isinstance(purpose,str):
-            purp_no=X509_PURPOSE_get_by_sname(purpose)
-            if purp_no <=0:
-                raise X509Error("Invalid certificate purpose '"+purpose+"'")
-        elif isinstance(purpose,int):
+        @param purpose - number from 1 to 9 or standard strind defined
+                         in Openssl
+        possible strings - sslcient,sslserver, nssslserver, smimesign,i
+                         smimeencrypt, crlsign, any, ocsphelper
+        """
+        if isinstance(purpose, str):
+            purp_no = libcrypto.X509_PURPOSE_get_by_sname(purpose)
+            if purp_no <= 0:
+                raise X509Error("Invalid certificate purpose '%s'" % purpose)
+        elif isinstance(purpose, int):
             purp_no = purpose
             purp_no = purpose
-        if libcrypto.X509_STORE_set_purpose(self.store,purp_no)<=0:
+        if libcrypto.X509_STORE_set_purpose(self.store, purp_no) <= 0:
             raise X509Error("cannot set purpose")
             raise X509Error("cannot set purpose")
-    def setdepth(self,depth):
+    def setdepth(self, depth):
         """
         Sets the verification depth i.e. max length of certificate chain
         which is acceptable
         """
         """
         Sets the verification depth i.e. max length of certificate chain
         which is acceptable
         """
-        libcrypto.X509_STORE_set_depth(self.store,depth)
+        libcrypto.X509_STORE_set_depth(self.store, depth)
     def settime(self, time):
         """
         Set point in time used to check validity of certificates for
         Time can be either python datetime object or number of seconds
         sinse epoch
         """
     def settime(self, time):
         """
         Set point in time used to check validity of certificates for
         Time can be either python datetime object or number of seconds
         sinse epoch
         """
-        if isinstance(time,datetime.datetime) or isinstance(time,datetime.date):
-            d=int(time.strftime("%s"))
-        elif isinstance(time,int):
-            pass
+        if isinstance(time, datetime) or isinstance(time,
+                                                             datetime.date):
+            seconds = int(time.strftime("%s"))
+        elif isinstance(time, int):
+            seconds = time
         else:
         else:
-            raise TypeError("datetime.date, datetime.datetime or integer is required as time argument")
+            raise TypeError("datetime.date, datetime.datetime or integer " +
+                            "is required as time argument")
         raise NotImplementedError
 class StackOfX509(object):
     """
     Implements OpenSSL STACK_OF(X509) object.
     It looks much like python container types
     """
         raise NotImplementedError
 class StackOfX509(object):
     """
     Implements OpenSSL STACK_OF(X509) object.
     It looks much like python container types
     """
-    def __init__(self,certs=None,ptr=None,disposable=True):
+    def __init__(self, certs=None, ptr=None, disposable=True):
         """
         Create stack
         @param certs - list of X509 objects. If specified, read-write
         """
         Create stack
         @param certs - list of X509 objects. If specified, read-write
@@ -502,83 +543,89 @@ class StackOfX509(object):
         """
         if  ptr is None:
             self.need_free = True
         """
         if  ptr is None:
             self.need_free = True
-            self.ptr=libcrypto.sk_new_null()
+            self.ptr = libcrypto.sk_new_null()
             if certs is not None:
                 for crt in certs:
                     self.append(crt)
         elif certs is not None:
             if certs is not None:
                 for crt in certs:
                     self.append(crt)
         elif certs is not None:
-                raise ValueError("cannot handle certs an ptr simultaneously")
+            raise ValueError("cannot handle certs an ptr simultaneously")
         else:
             self.need_free = disposable
         else:
             self.need_free = disposable
-            self.ptr=ptr
+            self.ptr = ptr
     def __len__(self):
         return libcrypto.sk_num(self.ptr)
     def __len__(self):
         return libcrypto.sk_num(self.ptr)
-    def __getitem__(self,index):
-        if index <0 or index>=len(self):
+    def __getitem__(self, index):
+        if index < 0 or index >= len(self):
             raise IndexError
             raise IndexError
-        p=libcrypto.sk_value(self.ptr,index)
+        p = libcrypto.sk_value(self.ptr, index)
         return X509(ptr=libcrypto.X509_dup(p))
         return X509(ptr=libcrypto.X509_dup(p))
-    def __setitem__(self,index,value):
+    def __setitem__(self, index, value):
         if not self.need_free:
             raise ValueError("Stack is read-only")
         if not self.need_free:
             raise ValueError("Stack is read-only")
-        if index <0 or index>=len(self):
+        if index < 0 or index >= len(self):
             raise IndexError
             raise IndexError
-        if not isinstance(value,X509):
+        if not isinstance(value, X509):
             raise TypeError('StackOfX508 can contain only X509 objects')
             raise TypeError('StackOfX508 can contain only X509 objects')
-        p=libcrypto.sk_value(self.ptr,index)
-        libcrypto.sk_set(self.ptr,index,libcrypto.X509_dup(value.cert))
+        p = libcrypto.sk_value(self.ptr, index)
+        libcrypto.sk_set(self.ptr, index, libcrypto.X509_dup(value.cert))
         libcrypto.X509_free(p)
         libcrypto.X509_free(p)
-    def __delitem__(self,index):    
+    def __delitem__(self, index):
         if not self.need_free:
             raise ValueError("Stack is read-only")
         if not self.need_free:
             raise ValueError("Stack is read-only")
-        if index <0 or index>=len(self):
+        if index < 0 or index >= len(self):
             raise IndexError
             raise IndexError
-        p=libcrypto.sk_delete(self.ptr,index)
+        p = libcrypto.sk_delete(self.ptr, index)
         libcrypto.X509_free(p)
     def __del__(self):
         if self.need_free:
         libcrypto.X509_free(p)
     def __del__(self):
         if self.need_free:
-            libcrypto.sk_pop_free(self.ptr,libcrypto.X509_free)
-    def append(self,value):
+            libcrypto.sk_pop_free(self.ptr, libcrypto.X509_free)
+    def append(self, value):
+        """ Adds certificate to stack """
         if not self.need_free:
             raise ValueError("Stack is read-only")
         if not self.need_free:
             raise ValueError("Stack is read-only")
-        if not isinstance(value,X509):
+        if not isinstance(value, X509):
             raise TypeError('StackOfX508 can contain only X509 objects')
             raise TypeError('StackOfX508 can contain only X509 objects')
-        libcrypto.sk_push(self.ptr,libcrypto.X509_dup(value.cert))
-libcrypto.i2a_ASN1_INTEGER.argtypes=(c_void_p,c_void_p)
-libcrypto.ASN1_STRING_print_ex.argtypes=(c_void_p,c_void_p,c_long)
-libcrypto.PEM_read_bio_X509.restype=c_void_p
-libcrypto.PEM_read_bio_X509.argtypes=(c_void_p,POINTER(c_void_p),c_void_p,c_void_p)
-libcrypto.PEM_write_bio_X509.restype=c_int
-libcrypto.PEM_write_bio_X509.argtypes=(c_void_p,c_void_p)
-libcrypto.ASN1_TIME_print.argtypes=(c_void_p,c_void_p)
-libcrypto.ASN1_INTEGER_get.argtypes=(c_void_p,)
-libcrypto.ASN1_INTEGER_get.restype=c_long
-libcrypto.X509_get_serialNumber.argtypes=(c_void_p,)
-libcrypto.X509_get_serialNumber.restype=c_void_p
-libcrypto.X509_NAME_ENTRY_get_object.restype=c_void_p
-libcrypto.X509_NAME_ENTRY_get_object.argtypes=(c_void_p,)
-libcrypto.OBJ_obj2nid.argtypes=(c_void_p,)
-libcrypto.X509_NAME_get_entry.restype=c_void_p
-libcrypto.X509_NAME_get_entry.argtypes=(c_void_p,c_int)
-libcrypto.X509_STORE_new.restype=c_void_p
-libcrypto.X509_STORE_add_lookup.restype=c_void_p
-libcrypto.X509_STORE_add_lookup.argtypes=(c_void_p,c_void_p)
-libcrypto.X509_LOOKUP_file.restype=c_void_p
-libcrypto.X509_LOOKUP_hash_dir.restype=c_void_p
-libcrypto.X509_LOOKUP_ctrl.restype=c_int
-libcrypto.X509_LOOKUP_ctrl.argtypes=(c_void_p,c_int,c_char_p,c_long,POINTER(c_char_p))
-libcrypto.X509_EXTENSION_dup.argtypes=(c_void_p,)
-libcrypto.X509_EXTENSION_dup.restype=POINTER(_x509_ext)
-libcrypto.X509V3_EXT_print.argtypes=(c_void_p,POINTER(_x509_ext),c_long,c_int)
-libcrypto.X509_get_ext.restype=c_void_p
-libcrypto.X509_get_ext.argtypes=(c_void_p,c_int)
-libcrypto.X509V3_EXT_print.argtypes=(c_void_p,POINTER(_x509_ext),c_long,c_int)
-libcrypto.sk_set.argtypes=(c_void_p,c_int,c_void_p)
-libcrypto.sk_set.restype=c_void_p
-libcrypto.sk_value.argtypes=(c_void_p,c_int)
-libcrypto.sk_value.restype=c_void_p
-libcrypto.X509_dup.restype=c_void_p
-libcrypto.sk_new_null.restype=c_void_p
-libcrypto.X509_dup.argtypes=(c_void_p,)
-libcrypto.X509_NAME_hash.restype=c_long
-libcrypto.X509_NAME_hash.argtypes=(c_void_p,)
+        libcrypto.sk_push(self.ptr, libcrypto.X509_dup(value.cert))
+
+libcrypto.i2a_ASN1_INTEGER.argtypes = (c_void_p, c_void_p)
+libcrypto.ASN1_STRING_print_ex.argtypes = (c_void_p, c_void_p, c_long)
+libcrypto.PEM_read_bio_X509.restype = c_void_p
+libcrypto.PEM_read_bio_X509.argtypes = (c_void_p, POINTER(c_void_p),
+                                        c_void_p, c_void_p)
+libcrypto.PEM_write_bio_X509.restype = c_int
+libcrypto.PEM_write_bio_X509.argtypes = (c_void_p, c_void_p)
+libcrypto.ASN1_TIME_print.argtypes = (c_void_p, c_void_p)
+libcrypto.ASN1_INTEGER_get.argtypes = (c_void_p, )
+libcrypto.ASN1_INTEGER_get.restype = c_long
+libcrypto.X509_get_serialNumber.argtypes = (c_void_p, )
+libcrypto.X509_get_serialNumber.restype = c_void_p
+libcrypto.X509_NAME_ENTRY_get_object.restype = c_void_p
+libcrypto.X509_NAME_ENTRY_get_object.argtypes = (c_void_p, )
+libcrypto.OBJ_obj2nid.argtypes = (c_void_p, )
+libcrypto.X509_NAME_get_entry.restype = c_void_p
+libcrypto.X509_NAME_get_entry.argtypes = (c_void_p, c_int)
+libcrypto.X509_STORE_new.restype = c_void_p
+libcrypto.X509_STORE_add_lookup.restype = c_void_p
+libcrypto.X509_STORE_add_lookup.argtypes = (c_void_p, c_void_p)
+libcrypto.X509_LOOKUP_file.restype = c_void_p
+libcrypto.X509_LOOKUP_hash_dir.restype = c_void_p
+libcrypto.X509_LOOKUP_ctrl.restype = c_int
+libcrypto.X509_LOOKUP_ctrl.argtypes = (c_void_p, c_int, c_char_p, c_long,
+                                       POINTER(c_char_p))
+libcrypto.X509_EXTENSION_dup.argtypes = (c_void_p, )
+libcrypto.X509_EXTENSION_dup.restype = POINTER(_x509_ext)
+libcrypto.X509V3_EXT_print.argtypes = (c_void_p, POINTER(_x509_ext), c_long,
+                                       c_int)
+libcrypto.X509_get_ext.restype = c_void_p
+libcrypto.X509_get_ext.argtypes = (c_void_p, c_int)
+libcrypto.X509V3_EXT_print.argtypes = (c_void_p, POINTER(_x509_ext), c_long,
+                                       c_int)
+libcrypto.sk_set.argtypes = (c_void_p, c_int, c_void_p)
+libcrypto.sk_set.restype = c_void_p
+libcrypto.sk_value.argtypes = (c_void_p, c_int)
+libcrypto.sk_value.restype = c_void_p
+libcrypto.X509_dup.restype = c_void_p
+libcrypto.sk_new_null.restype = c_void_p
+libcrypto.X509_dup.argtypes = (c_void_p, )
+libcrypto.X509_NAME_hash.restype = c_long
+libcrypto.X509_NAME_hash.argtypes = (c_void_p, )
index 6d95b4602a2623fad871d58a0bdaecf23805516f..c9babe925d3211a2027fa8d71e744fb03673288e 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -33,7 +33,7 @@ class MyTests(distutils.cmd.Command):
 
 setup(
     name="ctypescrypto",
 
 setup(
     name="ctypescrypto",
-    version="0.2.7",
+    version="0.3.0",
     description="CTypes-based interface for some OpenSSL libcrypto features",
     author="Victor Wagner",
     author_email="vitus@wagner.pp.ru",
     description="CTypes-based interface for some OpenSSL libcrypto features",
     author="Victor Wagner",
     author_email="vitus@wagner.pp.ru",
index 120d73cae2bc6d1dfeee13ed8b0ed3f21cc63b90..7a48ed035a45a18156965d3a4892ffb094c450ba 100644 (file)
@@ -6,46 +6,46 @@ import unittest
 class TestDigestType(unittest.TestCase):
     def test_md4(self):
         d=digest.DigestType("md4")
 class TestDigestType(unittest.TestCase):
     def test_md4(self):
         d=digest.DigestType("md4")
-        self.assertEqual(d.digest_size(),16)
-        self.assertEqual(d.block_size(),64)
-        self.assertEqual(d.oid(),Oid("md4"))
+        self.assertEqual(d.digest_size,16)
+        self.assertEqual(d.block_size,64)
+        self.assertEqual(d.oid,Oid("md4"))
         self.assertEqual(d.name,'md4')
     def test_md5(self):
         d=digest.DigestType("md5")
         self.assertEqual(d.name,'md4')
     def test_md5(self):
         d=digest.DigestType("md5")
-        self.assertEqual(d.digest_size(),16)
-        self.assertEqual(d.block_size(),64)
-        self.assertEqual(d.oid(),Oid("md5"))
+        self.assertEqual(d.digest_size,16)
+        self.assertEqual(d.block_size,64)
+        self.assertEqual(d.oid,Oid("md5"))
         self.assertEqual(d.name,'md5')
     def test_sha1(self):
         d=digest.DigestType("sha1")
         self.assertEqual(d.name,'md5')
     def test_sha1(self):
         d=digest.DigestType("sha1")
-        self.assertEqual(d.digest_size(),20)
-        self.assertEqual(d.block_size(),64)
-        self.assertEqual(d.oid(),Oid("sha1"))
+        self.assertEqual(d.digest_size,20)
+        self.assertEqual(d.block_size,64)
+        self.assertEqual(d.oid,Oid("sha1"))
         self.assertEqual(d.name,'sha1')
     def test_sha256(self):
         d=digest.DigestType("sha256")
         self.assertEqual(d.name,'sha1')
     def test_sha256(self):
         d=digest.DigestType("sha256")
-        self.assertEqual(d.digest_size(),32)
-        self.assertEqual(d.block_size(),64)
-        self.assertEqual(d.oid(),Oid("sha256"))
+        self.assertEqual(d.digest_size,32)
+        self.assertEqual(d.block_size,64)
+        self.assertEqual(d.oid,Oid("sha256"))
         self.assertEqual(d.name,'sha256')
     def test_sha384(self):
         d=digest.DigestType("sha384")
         self.assertEqual(d.name,'sha256')
     def test_sha384(self):
         d=digest.DigestType("sha384")
-        self.assertEqual(d.digest_size(),48)
-        self.assertEqual(d.block_size(),128)
-        self.assertEqual(d.oid(),Oid("sha384"))
+        self.assertEqual(d.digest_size,48)
+        self.assertEqual(d.block_size,128)
+        self.assertEqual(d.oid,Oid("sha384"))
         self.assertEqual(d.name,'sha384')
     def test_sha512(self):
         d=digest.DigestType("sha512")
         self.assertEqual(d.name,'sha384')
     def test_sha512(self):
         d=digest.DigestType("sha512")
-        self.assertEqual(d.digest_size(),64)
-        self.assertEqual(d.block_size(),128)
-        self.assertEqual(d.oid(),Oid("sha512"))
+        self.assertEqual(d.digest_size,64)
+        self.assertEqual(d.block_size,128)
+        self.assertEqual(d.oid,Oid("sha512"))
         self.assertEqual(d.name,'sha512')
     def test_createfromoid(self):
         oid=Oid('sha256')
         d=digest.DigestType(oid)
         self.assertEqual(d.name,'sha512')
     def test_createfromoid(self):
         oid=Oid('sha256')
         d=digest.DigestType(oid)
-        self.assertEqual(d.digest_size(),32)
-        self.assertEqual(d.block_size(),64)
-        self.assertEqual(d.oid(),Oid("sha256"))
+        self.assertEqual(d.digest_size,32)
+        self.assertEqual(d.block_size,64)
+        self.assertEqual(d.oid,Oid("sha256"))
         self.assertEqual(d.name,'sha256')
     def test_createfromEVP_MD(self):
         d1=digest.DigestType("sha256")
         self.assertEqual(d.name,'sha256')
     def test_createfromEVP_MD(self):
         d1=digest.DigestType("sha256")
@@ -53,9 +53,9 @@ class TestDigestType(unittest.TestCase):
         with self.assertRaises(AttributeError):
             s=d2.name
         d2.digest=d1.digest
         with self.assertRaises(AttributeError):
             s=d2.name
         d2.digest=d1.digest
-        self.assertEqual(d2.digest_size(),32)
-        self.assertEqual(d2.block_size(),64)
-        self.assertEqual(d2.oid(),Oid("sha256"))
+        self.assertEqual(d2.digest_size,32)
+        self.assertEqual(d2.block_size,64)
+        self.assertEqual(d2.oid,Oid("sha256"))
         self.assertEqual(d2.name,'sha256')
     def test_invalidDigest(self):
         with self.assertRaises(digest.DigestError):
         self.assertEqual(d2.name,'sha256')
     def test_invalidDigest(self):
         with self.assertRaises(digest.DigestError):