]> www.wagner.pp.ru Git - oss/ctypescrypto.git/commitdiff
cleaned up documentation
authorVictor Wagner <vitus@wagner.pp.ru>
Sat, 25 Oct 2014 17:42:01 +0000 (21:42 +0400)
committerVictor Wagner <vitus@wagner.pp.ru>
Sat, 25 Oct 2014 17:42:01 +0000 (21:42 +0400)
README.md
ctypescrypto/__init__.py
ctypescrypto/bio.py
ctypescrypto/cipher.py
ctypescrypto/ec.py [new file with mode: 0644]
ctypescrypto/engine.py
ctypescrypto/exception.py
ctypescrypto/oid.py
ctypescrypto/pkey.py
tests/testcipher.py

index 2054f7bc5730d733c3f3b3d202797e3a503a3a3a..27991db27b447735a1e444ca4fcd520b18b3b641 100644 (file)
--- a/README.md
+++ b/README.md
@@ -7,48 +7,96 @@ This module is based on works from
 
 http://code.google.com/p/ctypescrypto/
 
 
 http://code.google.com/p/ctypescrypto/
 
-It is aimed to provide Python interface to OpenSSL libcrypto function
-
-Now supported:
-
-bio.py - interfase to OpenSSL stream abstraction BIO. Now supports
-       memory BIOs this module intended to use for parsing/serializing
-       various ASN.1 based formats like private keys or certificates
-       Status: bare minimum functionality is implemented and covered by
-       rests
-
-oid.py - interface to OpenSSL ASN.1 Object Identifier databsase.
-       Allows to convert numeric identifier (NIDs) returned by various
-       OpenSSL function to readable names or dotted-decimal OIDs and back
-       Status: Fully implemented and covered by tests.
-
-engine.py - interface to loadable modules with alternate implementations
-    of cryptoalgorithms.
-       Status: Bare minumum, neccessary to use GOST algorithms is
-       implemented.
-
-rand.py - interface to pseudo-random number generator.
-       Status: Implemented. Tests now only ensure that no segfault occurs
-       if arugments are passed correctly
-
-digests.py  - Interface  to EVP\_Digest\* family of functions. 
-       Really does almost same as hashlib, which even is able to take
-       advantage of loaded engines if compiled against dynamic libcrypto
-       Status: fully implemented and covered by tests
-
-ciphers.py - Interface to EVP\_Cipher family of function. 
-       Status: Needs test coverage
-
-pkey.py - Low-level private key operations (like pkey, genpkey and p
-    keyutl command line ops), all via algorithm-agnostic EVP interface.
-       Status: Designed and started to implement but most functionality 
-       not yet covered by tests
-
-exception.py OpenSSL error stack to python exception conversion
-       Implemented.
-
-x509 X509 certificates. Support parsing of X509 certificates,
-       verification and extracting of field values. Possible extnesion -
-       support creattion of PKCS10 certificate requests.
-       Status: Interface designed and partially implemented
+most recent version can be checked out from
+
+https://github.com/vbwagner/ctypescrypto.git
+
+It is aimed to provide Python interface to OpenSSL libcrypto functions.
+All the objects in this library are just wrappers around some OpenSSL
+data structures and groups of functions.
+
+
+
+Digest calculation
+------------------
+
+Module *ctypescrypto.digest* contain *new()* function which produces
+objects simular to python *hashlib* module objects. 
+
+On the systems where hashlib is linked with libcrypto dynamically,
+hashlib even able to make use of digest types, provided by loadable
+engines. 
+
+This module would utilize same copy of libcrypto library as other
+ctypescrypto modules, so it would work with engine-provided digests.
+
+Symmetric ciphers
+-----------------
+
+Module *ctypescrypto.cipher* contain *new()* function which provides
+way to create cipher objects. Cipher padding can be configure later.
+This object provides methods *update* and *finish* which allows to
+encrypt/decrypt data. All ciphers, supported by your version of OpenSSL
+and its loadable engines are supported.
+
+Public key operations
+---------------------
+
+Module *ctypescrypto.pkey* provides *PKey* object, which represents
+public/private key pair or just public key. With this object you can
+sign data, derive shared key and verify signatures.
+
+This is quite low-level object, which can be used to implement some
+non-standard protocols and operations.
+
+X509 certificates
+-----------------
+
+Module *ctypescrypto.x509* contains objects *X509* which represents
+certificate (and can be constructed from string, contained PEM
+or DER certificate) and object *X509Store* which is a store of trusted
+CA certificates which can be used to high-level signature verifications
+(i.e. in PKCS7/CMS messages).
+
+Certificate has properties corresponding to its subject and issuer
+names, public key (of course it is PKey object described above) and
+serial number. Subject and issuer names can be indexed by OIDs or by
+position of field. Unicode in the names is supported.
+
+There is no support for certificate validity time yet.
+
+OID database
+------------
+
+OpenSSL conteins internal object identifiers (OID) database. Each OID
+have apart from dotted-decimal representation long name, short name and
+numeric identifer. Module *ctypescrypto.oid* provides interface to the
+database. *Oid* objects store numeric identifier internally and can
+return both long and short name and dotted-decimal representation.
+
+BIO library
+-----------
+
+OpenSSL contain BIO (basic input-output) abstraction. And all object
+serialization/deserialization use this library. Also human-readble
+representation of  ASN.1 structures use this library extensively. So,
+we've to develop python object which allow to read from python string
+via BIO abstraction or write to buffer, which can be returned as python
+string or unicode object. 
+
+Exceptions
+----------
+
+Exceptions, used in the *ctypescrypto* to report problems are tied
+closely with OpenSSL error-reporting functions, so if such an exception
+occurs, as much as possibly information from inside libcrypto would be
+available in the Python
+
+Engine support
+--------------
+
+There is just one function *ctypescrypt.engine.set_default*. which loads 
+specified engine by id and makes it default for all algorithms,
+supported by it. It is enough for me to use Russian national
+cryptographic algoritms, provided by *gost* engine.
 
 
index d4dcf7c103374f834aea36b70f0ca0fabd3ecd72..27ad0c50b8a9efa0f91a851a7381e83cb9f7a809 100644 (file)
@@ -3,7 +3,15 @@
 
 """
 
 
 """
 
-from ctypes import CDLL
+from ctypes import CDLL,c_char_p
+
+def config(filename=None):
+       """
+               Loads OpenSSL Config file. If none are specified, loads default
+               (compiled in) one
+       """
+       libcrypto.OPENSSL_config(filename)
 
 libcrypto = CDLL("libcrypto.so.1.0.0")
 
 libcrypto = CDLL("libcrypto.so.1.0.0")
+libcrypto.OPENSSL_config.argtypes=(c_char_p,)
 libcrypto.OPENSSL_add_all_algorithms_conf()
 libcrypto.OPENSSL_add_all_algorithms_conf()
index f8150f72cebc25db4b8604a33c88f6a1c64f727d..a33310572cdc54213a70c10881044e0bce0c6fc9 100644 (file)
@@ -1,3 +1,6 @@
+"""
+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
 class Membio:
 from ctypescrypto import libcrypto
 from ctypes import c_char_p, c_void_p, c_int, string_at, c_long,POINTER,byref, create_string_buffer
 class Membio:
index 3320d2f95031116e1e1f0d172f9241f05ee4c93c..c2053e988354574d299e0bd1c36e6cf98c7ff701 100644 (file)
@@ -1,3 +1,7 @@
+"""
+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 ctypescrypto import libcrypto
 from ctypescrypto.exception import LibCryptoError
 from ctypes import create_string_buffer,c_char_p,c_void_p,c_int,c_long,byref,POINTER
 from ctypescrypto import libcrypto
 from ctypescrypto.exception import LibCryptoError
diff --git a/ctypescrypto/ec.py b/ctypescrypto/ec.py
new file mode 100644 (file)
index 0000000..d325212
--- /dev/null
@@ -0,0 +1,33 @@
+"""
+Support for EC keypair operation missing form public libcrypto API
+"""
+
+
+def create(curve,num):
+       """
+               Creates EC keypair from the just secret key and curve name
+               
+               @param curve - name of elliptic curve
+               @param num - long number representing key
+       """
+       p=libcrypto.EVP_PKEY_new()
+       ec=libcrypto.EC_KEY_new_by_curvename(curve.nid)
+       group=libcrypto.EC_KEY_get0_group(ec)
+       EC_KEY_set_private_key(ec,bn)
+       priv_key=libcrypt.BN_new()
+       ctx=BN_CTX_new()
+       h="%x"%(num)
+       libcrypto.BN_hex2bn(byref(priv_key),h)
+       libcrypto.EC_KEY_set_private_key(ec,priv_key)
+       pub_key=libcrypto.EC_POINT_new(group)
+       libcrypto.EC_POINT_mul(group,pub_key,priv_key,None,None,ctx)
+       libcrypto.BN_free(a)
+       libcrypto.EVP_PKEY_set1_EC_KEY(p,ec)
+       libcrypto.EC_KEY_free(ec)
+       return PKey(ptr=p,cansign=True)
+
+
+libcrypto.EVP_PKEY_new.restype=c_void_p
+libcrypto.BN_new.restype=c_void_p
+libcrypto.BN_hex2bn.argtypes(POINTER(c_void_p),c_char_p)
+libcrypto.EC_KEY_set_private_key
index f05fcb0a49200e2d65149d9166983e6b024f05ab..dd7c0281b34a255670d55ab868322128b10a3d93 100644 (file)
@@ -1,9 +1,16 @@
+"""
+engine loading and configuration
+"""
 from ctypes import *
 from ctypescrypto import libcrypto
 from ctypescrypto.exception import LibCryptoError
 default=None
 
 def set_default(engine):
 from ctypes import *
 from ctypescrypto import libcrypto
 from ctypescrypto.exception import LibCryptoError
 default=None
 
 def set_default(engine):
+       """
+               Loads specified engine and sets it as default for all 
+               algorithms, supported by it
+       """
        global default
        e=libcrypto.ENGINE_by_id(engine)
        if e is None:
        global default
        e=libcrypto.ENGINE_by_id(engine)
        if e is None:
index f0f3c5343238cabcd382c68ebe03e9738760c7fc..c4710eca32742a817bfb1204a0d7550bcce8d433 100644 (file)
@@ -1,3 +1,6 @@
+"""
+Exception which extracts libcrypto error information
+"""
 from ctypes import *
 from ctypescrypto import libcrypto
 strings_loaded=False
 from ctypes import *
 from ctypescrypto import libcrypto
 strings_loaded=False
index 9852043e0b936cf8e5b9dc5b0c25cbbed2011734..976cd3f8e5b7cf07cc6ab86e93e1400d4acac52d 100644 (file)
@@ -1,5 +1,6 @@
 """    
  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.
 
index e4c8c0257c27924e22f458a529a374517a46c372..f011443a2173ede8058e21c4323ba2967462ace2 100644 (file)
@@ -1,3 +1,11 @@
+"""
+low-level private/public keypair operation
+
+PKey object of this module is wrapper around OpenSSL EVP_PKEY object.
+"""
+
+This module provides interface for 
+
 from ctypes import c_char_p,c_void_p,byref,c_int,c_long, c_longlong, create_string_buffer,CFUNCTYPE,POINTER
 from ctypescrypto import libcrypto
 from ctypescrypto.exception import LibCryptoError,clear_err_stack
 from ctypes import c_char_p,c_void_p,byref,c_int,c_long, c_longlong, create_string_buffer,CFUNCTYPE,POINTER
 from ctypescrypto import libcrypto
 from ctypescrypto.exception import LibCryptoError,clear_err_stack
@@ -8,6 +16,11 @@ class PKeyError(LibCryptoError):
 
 CALLBACK_FUNC=CFUNCTYPE(c_int,c_char_p,c_int,c_int,c_char_p)
 def password_callback(buf,length,rwflag,u):
 
 CALLBACK_FUNC=CFUNCTYPE(c_int,c_char_p,c_int,c_int,c_char_p)
 def password_callback(buf,length,rwflag,u):
+"""
+Example password callback for private key. Assumes that 
+password is store in the userdata parameter, so allows to pass password
+from constructor arguments to the libcrypto keyloading functions
+"""
        cnt=len(u)
        if length<cnt:
                cnt=length
        cnt=len(u)
        if length<cnt:
                cnt=length
index d9857cfeb18cb16e32608b9e7ec9f775dd253f2e..3cc848c0a963600841d271c59d0cd6916d924f3a 100644 (file)
@@ -1,6 +1,7 @@
 from ctypescrypto.oid import Oid
 from ctypescrypto import cipher
 import unittest
 from ctypescrypto.oid import Oid
 from ctypescrypto import cipher
 import unittest
+import sys
 
 
 class TestCipherType(unittest.TestCase):
 
 
 class TestCipherType(unittest.TestCase):
@@ -84,6 +85,8 @@ class TestEncryptDecrypt(unittest.TestCase):
                c=cipher.new("bf-ofb",encryptkey,iv=iv)
                ciphertext=c.update(data)+c.finish()
                decryptkey=encryptkey[0:5]+encryptkey[5:]
                c=cipher.new("bf-ofb",encryptkey,iv=iv)
                ciphertext=c.update(data)+c.finish()
                decryptkey=encryptkey[0:5]+encryptkey[5:]
+               with open("cipher.txt","w") as f:
+                       f.write(repr(ciphertext)+"\n")
                d=cipher.new("bf-ofb",decryptkey,encrypt=False,iv=iv)
                deciph=d.update(ciphertext)+d.finish()
                self.assertEqual(deciph,data)
                d=cipher.new("bf-ofb",decryptkey,encrypt=False,iv=iv)
                deciph=d.update(ciphertext)+d.finish()
                self.assertEqual(deciph,data)