ncrypt-0.6.4/0000700000175000017500000000000010620074071011011 5ustar fx5fx5ncrypt-0.6.4/ncrypt_x509.pxd0000700000175000017500000000022610512376024013640 0ustar fx5fx5cdef extern from "openssl/x509.h" : ctypedef struct X509 cdef class X509Certificate : cdef X509 *x cdef int fromX509( self, X509 *xptr ) ncrypt-0.6.4/ncrypt_x509.pyx0000700000175000017500000004047310512376024013675 0ustar fx5fx5cimport ncrypt_digest, ncrypt_rsa from ncrypt_digest cimport EVP_MD from ncrypt_rsa cimport RSA import ncrypt_err, ncrypt_rsa import time, calendar cdef extern from "openssl/asn1.h" : ctypedef struct ASN1_STRING ctypedef struct ASN1_OBJECT int OBJ_txt2nid( char *s ) int OBJ_obj2nid( ASN1_OBJECT *x ) char *OBJ_nid2ln( int n ) char *OBJ_nid2sn( int n ) int ASN1_STRING_to_UTF8( unsigned char **out, ASN1_STRING *inp ) void OPENSSL_free( void *p ) cdef enum : NID_undef ctypedef struct ASN1_INTEGER void M_ASN1_INTEGER_free( ASN1_INTEGER *ai ) ctypedef struct ASN1_TIME : int length int type unsigned char *data long flags ASN1_TIME *ASN1_TIME_set( ASN1_TIME *t, long seconds ) ctypedef struct ASN1_GENERALIZEDTIME : int length int type unsigned char *data long flags void ASN1_GENERALIZEDTIME_free( ASN1_GENERALIZEDTIME *t ) ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set( ASN1_GENERALIZEDTIME *t, long seconds ) ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime( ASN1_TIME *t, ASN1_GENERALIZEDTIME **gt ) cdef extern from "openssl/bio.h" : ctypedef struct BIO_METHOD ctypedef struct BIO BIO_METHOD *BIO_s_mem() BIO *BIO_new( BIO_METHOD *m ) int BIO_free( BIO *b ) int BIO_write( BIO *b, void *buf, int num ) cdef extern from "openssl/bn.h" : ctypedef struct BIGNUM BIGNUM *BN_new() void BN_free( BIGNUM *bn ) BIGNUM *ASN1_INTEGER_to_BN( ASN1_INTEGER *ai, BIGNUM *bn ) ASN1_INTEGER *BN_to_ASN1_INTEGER( BIGNUM *bn, ASN1_INTEGER *ai ) cdef extern from "utils.h" : object BNToLong( BIGNUM *bn ) int LongToBN( object x, BIGNUM *bn ) object GetBIOData( BIO *b ) cdef extern from "openssl/rsa.h" : void RSA_free( RSA *x ) RSA *RSAPublicKey_dup( RSA *x ) cdef extern from "openssl/evp.h" : ctypedef struct EVP_PKEY : int type EVP_PKEY *EVP_PKEY_new() void EVP_PKEY_free( EVP_PKEY *x ) int EVP_PKEY_type( int type ) RSA *EVP_PKEY_get1_RSA( EVP_PKEY *x ) int EVP_PKEY_set1_RSA( EVP_PKEY *pk, RSA *r ) cdef enum : EVP_PKEY_RSA cdef extern from "openssl/x509.h" : ctypedef struct X509_NAME_ENTRY ctypedef struct X509_NAME X509_NAME *X509_NAME_new() void X509_NAME_free( X509_NAME *x ) X509_NAME *X509_NAME_dup( X509_NAME *x ) int X509_NAME_entry_count( X509_NAME *x ) int X509_NAME_add_entry_by_txt( X509_NAME *x, char *fieldName, int type, unsigned char *fieldValue, int len, int loc, int set ) X509_NAME_ENTRY *X509_NAME_get_entry( X509_NAME *x, int loc ) ASN1_OBJECT *X509_NAME_ENTRY_get_object( X509_NAME_ENTRY *x ) ASN1_STRING *X509_NAME_ENTRY_get_data( X509_NAME_ENTRY *x ) X509 *X509_new() void X509_free( X509 *x ) X509 *X509_dup( X509 *x ) long X509_get_version( X509 *x ) int X509_set_version( X509 *x, long version ) ASN1_INTEGER *X509_get_serialNumber( X509 *x ) int X509_set_serialNumber( X509 *x, ASN1_INTEGER *sn ) X509_NAME *X509_get_issuer_name( X509 *x ) int X509_set_issuer_name( X509 *x, X509_NAME *issuer ) X509_NAME *X509_get_subject_name( X509 *x ) int X509_set_subject_name( X509 *x, X509_NAME *subject ) EVP_PKEY *X509_get_pubkey( X509 *x ) int X509_set_pubkey( X509 *x, EVP_PKEY *pk ) ASN1_TIME *X509_get_notBefore( X509 *x ) ASN1_TIME *X509_get_notAfter( X509 *x ) int X509_sign( X509 *x, EVP_PKEY *pk, EVP_MD *md ) int i2d_X509( X509 *x, unsigned char **out ) X509 *d2i_X509( X509 **px, unsigned char **inp, int len ) cdef enum : MBSTRING_ASC cdef extern from "openssl/pem.h" : int PEM_write_bio_X509( BIO *b, X509 *x ) X509 *PEM_read_bio_X509( BIO *b, void *, void *, void * ) cdef extern from "Python.h" : ctypedef struct PyObject void Py_DECREF( PyObject *obj ) void Py_INCREF( PyObject *obj ) PyObject *Raw_PyString_FromStringAndSize "PyString_FromStringAndSize" ( char *s, int len ) char *Raw_PyString_AsString "PyString_AsString" ( PyObject *s ) int _PyString_Resize( PyObject **s, int newsize ) object PyString_FromStringAndSize( char *s, int len ) object PyString_FromString( char *s ) int PyString_AsStringAndSize( object obj, char **buffer, int *length ) class X509Error( ncrypt_err.BaseLibraryError ) : pass cdef class X509Name : cdef X509_NAME *xn def __new__( self ) : self.xn = NULL def __dealloc__( self ) : if self.xn : X509_NAME_free( self.xn ) def __init__( self ) : cdef X509_NAME *newxn newxn = X509_NAME_new() if not newxn : raise X509Error, 'unable to allocate X509_NAME structure' if self.xn : X509_NAME_free( self.xn ) self.xn = newxn cdef int fromX509_NAME( self, X509_NAME *xnptr ) : cdef X509_NAME *newxn newxn = X509_NAME_dup( xnptr ) if not newxn : return 0 if self.xn : X509_NAME_free( self.xn ) self.xn = newxn return 1 def entryCount( self ) : return X509_NAME_entry_count( self.xn ) def addEntry( self, char *fieldName, char *fieldValue ) : cdef int result result = X509_NAME_add_entry_by_txt( self.xn, fieldName, MBSTRING_ASC, fieldValue, -1, -1, 0 ) if not result : raise X509Error, 'unable to add name entry' def getEntry( self, int index ) : cdef X509_NAME_ENTRY *e e = X509_NAME_get_entry( self.xn, index ) if not e : raise X509Error, 'no entry available at index %d' % index cdef ASN1_OBJECT *keyObj cdef int keyNid keyObj = X509_NAME_ENTRY_get_object( e ) keyNid = OBJ_obj2nid( keyObj ) cdef char *keyStr keyStr = OBJ_nid2ln( keyNid ) if not keyStr : keyStr = OBJ_nid2sn( keyNid ) if not keyStr : raise X509Error, 'unable to get field name for entry' key = PyString_FromString( keyStr ) cdef ASN1_STRING *valueObj valueObj = X509_NAME_ENTRY_get_data( e ) cdef char *valueStr cdef int result result = ASN1_STRING_to_UTF8( &valueStr, valueObj ) if result < 0 : raise X509Error, 'unable to get field value for entry' try : value = PyString_FromStringAndSize( valueStr, result ) finally : OPENSSL_free( valueStr ) return (key,value) def lookupEntry( self, fieldName ) : cdef int i, n i = 0 n = self.entryCount() while i < n : (k,v) = self.getEntry( i ) if k == fieldName : return v i = i + 1 raise X509Error, 'unable to find field name: %s' % fieldName cdef class X509Certificate : def __new__( self, data=None ) : self.x = NULL def __dealloc__( self ) : if self.x : X509_free( self.x ) def __init__( self, data=None ) : cdef X509 *newx if data is not None : self.fromDER( data ) else : newx = X509_new() if not newx : raise X509Error, 'unable to allocate X509 structure' if self.x : X509_free( self.x ) self.x = newx cdef int fromX509( self, X509 *xptr ) : cdef X509 *newx newx = X509_dup( xptr ) if not newx : return 0 if self.x : X509_free( self.x ) self.x = newx return 1 def getVersion( self ) : return X509_get_version( self.x ) def setVersion( self, int version ) : X509_set_version( self.x, version ) def getSerialNumber( self ) : cdef ASN1_INTEGER *sn cdef BIGNUM *bn sn = X509_get_serialNumber( self.x ) bn = ASN1_INTEGER_to_BN( sn, NULL ) try : return BNToLong( bn ) finally : BN_free( bn ) def setSerialNumber( self, serialNumber ) : cdef int result cdef BIGNUM *bn cdef ASN1_INTEGER *sn bn = BN_new() sn = NULL try : result = LongToBN( serialNumber, bn ) if result < 0 : raise TypeError, 'serial number must be int/long' sn = BN_to_ASN1_INTEGER( bn, NULL ) if not sn : raise X509Error, 'unable to set serial number' result = X509_set_serialNumber( self.x, sn ) if not result : raise X509Error, 'unable to set serial number' finally : BN_free( bn ) if sn != NULL : M_ASN1_INTEGER_free( sn ) def getIssuer( self ) : cdef X509_NAME *issuer issuer = X509_get_issuer_name( self.x ) cdef X509Name xn cdef int result xn = X509Name() result = xn.fromX509_NAME( issuer ) if not result : raise X509Error, 'unable to get issuer' return xn def setIssuer( self, X509Name xn not None ) : cdef X509_NAME *issuer issuer = X509_NAME_dup( xn.xn ) if not issuer : raise X509Error, 'unable to copy X509_NAME' cdef int result try : result = X509_set_issuer_name( self.x, issuer ) if not result : raise X509Error, 'unable to set issuer' finally : X509_NAME_free( issuer ) def getSubject( self ) : cdef X509_NAME *subject subject = X509_get_subject_name( self.x ) cdef X509Name xn cdef int result xn = X509Name() result = xn.fromX509_NAME( subject ) if not result : raise X509Error, 'unable to get subject' return xn def setSubject( self, X509Name xn not None ) : cdef X509_NAME *subject subject = X509_NAME_dup( xn.xn ) if not subject : raise X509Error, 'unable to copy X509_NAME' cdef int result try : result = X509_set_subject_name( self.x, subject ) if not result : raise X509Error, 'unable to set subject' finally : X509_NAME_free( subject ) def getPublicKey( self ) : cdef EVP_PKEY *pk pk = X509_get_pubkey( self.x ) if not pk : raise X509Error, 'unable to get public key' cdef int pkType cdef RSA *r r = NULL cdef ncrypt_rsa.RSAKey rsaKey try : pkType = EVP_PKEY_type( pk.type ) if pkType != EVP_PKEY_RSA : raise X509Error, 'unsupported public key type, only RSA supported' r = EVP_PKEY_get1_RSA( pk ) if not r : raise X509Error, 'unable to get RSA public key' rsaKey = ncrypt_rsa.RSAKey() rsaKey.loadCPublicKey( r ) return rsaKey finally : EVP_PKEY_free( pk ) if r != NULL : RSA_free( r ) def setPublicKey( self, ncrypt_rsa.RSAKey rsaKey not None ) : if not rsaKey.hasPublicKey() : raise X509Error, 'invalid public key' cdef RSA *r cdef EVP_PKEY *pk pk = NULL cdef int result r = RSAPublicKey_dup( rsaKey.rsa ) if not r : raise X509Error, 'unable to copy RSA public key' try : pk = EVP_PKEY_new() if not pk : raise X509Error, 'unable to allocate EVP_PKEY structure' result = EVP_PKEY_set1_RSA( pk, r ) assert result != 0 result = X509_set_pubkey( self.x, pk ) assert result != 0 finally : RSA_free( r ) if pk != NULL : EVP_PKEY_free( pk ) def getNotBefore( self ) : cdef ASN1_GENERALIZEDTIME *gt gt = ASN1_TIME_to_generalizedtime( X509_get_notBefore(self.x), NULL ) if not gt : raise X509Error, 'invalid time value' try : s = PyString_FromStringAndSize( gt.data, gt.length ) if len(s) != 15 : raise X509Error, 'invalid time data length' if s[-1] != 'Z' : raise X509Error, 'invalid time data' f = '%Y%m%d%H%M%S' return calendar.timegm( time.strptime(s[:-1],f) ) finally : ASN1_GENERALIZEDTIME_free( gt ) def setNotBefore( self, long seconds ) : cdef ASN1_TIME *t t = ASN1_TIME_set( X509_get_notBefore(self.x), seconds ) if not t : raise X509Error, 'unable to set time' def getNotAfter( self ) : cdef ASN1_GENERALIZEDTIME *gt gt = ASN1_TIME_to_generalizedtime( X509_get_notAfter(self.x), NULL ) if not gt : raise X509Error, 'invalid time value' try : s = PyString_FromStringAndSize( gt.data, gt.length ) if len(s) != 15 : raise X509Error, 'invalid time data length' if s[-1] != 'Z' : raise X509Error, 'invalid time data' f = '%Y%m%d%H%M%S' return calendar.timegm( time.strptime(s[:-1],f) ) finally : ASN1_GENERALIZEDTIME_free( gt ) def setNotAfter( self, long seconds ) : cdef ASN1_TIME *t t = ASN1_TIME_set( X509_get_notAfter(self.x), seconds ) if not t : raise X509Error, 'unable to set time' def sign( self, ncrypt_rsa.RSAKey rsaKey not None, ncrypt_digest.DigestType digestType not None ) : if not rsaKey.hasPrivateKey() : raise X509Error, 'private key not initialized' cdef EVP_PKEY *pk cdef int result pk = EVP_PKEY_new() if not pk : raise X509Error, 'unable to allocate EVP_PKEY structure' try : result = EVP_PKEY_set1_RSA( pk, rsaKey.rsa ) if not result : raise X509Error, 'error in initializing key' result = X509_sign( self.x, pk, digestType.m ) if not result : raise X509Error, 'error in signing certificate' finally : EVP_PKEY_free( pk ) def fromDER( self, data ) : cdef X509 *newx cdef char *p cdef int dataLen, result result = PyString_AsStringAndSize( data, &p, &dataLen ) if result < 0 : raise TypeError, 'a string is expected' newx = d2i_X509( NULL, &p, dataLen ) if not newx : raise X509Error, 'unable to load object from data' if self.x : X509_free( self.x ) self.x = newx def toDER( self ) : cdef int len, len1 cdef PyObject *derStr len = i2d_X509( self.x, NULL ) if len < 0 : raise X509Error, 'error in cert data' derStr = Raw_PyString_FromStringAndSize( NULL, len ) if derStr == NULL : raise MemoryError, 'unable to allocate string' cdef char *p p = Raw_PyString_AsString( derStr ) try : len1 = i2d_X509( self.x, &p ) assert len == len1 return derStr finally : Py_DECREF( derStr ) def fromPEM( self, data ) : cdef char *p cdef int dataLen, result cdef BIO *b cdef X509 *newx result = PyString_AsStringAndSize( data, &p, &dataLen ) if result < 0 : raise TypeError, 'a string is expected' b = BIO_new( BIO_s_mem() ) if not b : raise X509Error, 'unable to allocate BIO structure' try : result = BIO_write( b, p, dataLen ) if result < 0 : raise X509Error, 'unable to write data to BIO' newx = PEM_read_bio_X509( b, NULL, NULL, NULL ) if not newx : raise X509Error, 'unable to load object from data' if self.x : X509_free( self.x ) self.x = newx finally : BIO_free( b ) def toPEM( self ) : cdef int result cdef BIO *b b = BIO_new( BIO_s_mem() ) if not b : raise X509Error, 'unable to allocate a BIO structure' try : result = PEM_write_bio_X509( b, self.x ) if not result : raise X509Error, 'error in cert data' ret = GetBIOData( b ) if ret is None : raise X509Error, 'error in creating PEM data' return ret finally : BIO_free( b ) ncrypt-0.6.4/ncrypt_rsa.pxd0000700000175000017500000000070010512376023013714 0ustar fx5fx5cdef extern from "openssl/rsa.h" : ctypedef struct BIGNUM ctypedef struct RSA : int pad long version void *meth void *engine BIGNUM *n BIGNUM *e BIGNUM *d BIGNUM *p BIGNUM *q BIGNUM *dmp1 BIGNUM *dmq1 BIGNUM *iqmp cdef class RSAKey : cdef RSA *rsa cdef void loadCPublicKey( self, RSA *r ) cdef void loadCPrivateKey( self, RSA *r ) ncrypt-0.6.4/ncrypt_rsa.pyx0000700000175000017500000004723310512376024013756 0ustar fx5fx5cdef extern from "openssl/evp.h" : ctypedef struct EVP_CIPHER EVP_CIPHER *EVP_des_ede3_cbc() cdef extern from "openssl/crypto.h" : void OPENSSL_free( void *p ) cdef extern from "openssl/bn.h" : ctypedef struct BIGNUM ctypedef struct BN_CTX BIGNUM *BN_new() void BN_free( BIGNUM *x ) cdef extern from "openssl/bio.h" : ctypedef struct BIO_METHOD ctypedef struct BIO BIO_METHOD *BIO_s_mem() BIO *BIO_new( BIO_METHOD *m ) int BIO_free( BIO *b ) int BIO_write( BIO *b, void *buf, int num ) cdef extern from "utils.h" : object BNToLong( BIGNUM *bn ) int LongToBN( object x, BIGNUM *bn ) object GetBIOData( BIO *b ) cdef extern from "openssl/rsa.h" : cdef enum : RSA_PKCS1_PADDING RSA_PKCS1_OAEP_PADDING RSA *RSA_new() void RSA_free( RSA *x ) RSA *RSAPublicKey_dup( RSA *x ) RSA *RSAPrivateKey_dup( RSA *x ) int RSA_size( RSA *x ) RSA *RSA_generate_key( int num, int e, void (*callback)(int,int,void*), void *cb_arg ) int RSA_check_key( RSA *x ) int RSA_blinding_on( RSA *x, BN_CTX *bnctx ) void RSA_blinding_off( RSA *x ) int RSA_public_encrypt( int srcLen, unsigned char *src, unsigned char *dest, RSA *x, int padding ) int RSA_private_decrypt( int srcLen, unsigned char *src, unsigned char *dest, RSA *x, int padding ) int RSA_sign( int type, unsigned char *m, unsigned int mlen, unsigned char *sigret, unsigned int *siglen, RSA *x ) int RSA_verify( int type, unsigned char *m, unsigned int mlen, unsigned char *sigbuf, unsigned int siglen, RSA *x ) int i2d_RSAPublicKey( RSA *r, unsigned char **out ) RSA *d2i_RSAPublicKey( RSA **r, unsigned char **inp, int len ) int i2d_RSAPrivateKey( RSA *r, unsigned char **out ) RSA *d2i_RSAPrivateKey( RSA **r, unsigned char **inp, int len ) cdef extern from "openssl/pem.h" : int PEM_write_bio_RSAPublicKey( BIO *b, RSA *r ) RSA *PEM_read_bio_RSAPublicKey( BIO *b, void *, void *, void * ) int PEM_write_bio_RSAPrivateKey( BIO *b, RSA *r, EVP_CIPHER *, void *, int, void *, void * ) RSA *PEM_read_bio_RSAPrivateKey( BIO *b, void *, void *, void * ) cdef extern from "stdlib.h" : void *malloc( int size ) void free( void *ptr ) cdef extern from "string.h": void *memcpy(void *dest, void*src, int n) cdef extern from "Python.h" : ctypedef struct PyObject void Py_DECREF( PyObject *obj ) void Py_INCREF( PyObject *obj ) int PyInt_Check( object obj ) int PyLong_Check( object obj ) int PyString_Check( object obj ) object PyLong_FromString( char *p, char **pend, int base ) object PyObject_Str( object obj ) char *PyString_AsString( object obj ) int PyString_AsStringAndSize( object obj, char **ptr, int *len ) object PyString_FromStringAndSize( char *p, int len ) PyObject *Raw_PyString_FromStringAndSize "PyString_FromStringAndSize" ( char *s, int len ) char *Raw_PyString_AsString "PyString_AsString" ( PyObject *s ) import ncrypt_err cdef struct PemCbData : int length char *data cdef int _password_callback(char *buf, int size, int rwflag, void *u) : cdef PemCbData* d cdef int cp_size d = u if d.data == NULL : buf[0] = 0 return 0 else: if size > d.length : cp_size = d.length else: cp_size = size memcpy( buf, d.data, cp_size ) buf[size-1] = 0 return cp_size class RSAError(ncrypt_err.BaseLibraryError) : pass cdef void _rsa_callback( int type, int num, void *cb_arg ) : cb = cb_arg cb( type, num ) PADDING_PKCS1 = 0 PADDING_PKCS1_OAEP = 1 cdef class RSAKey : def __new__( self ) : self.rsa = RSA_new() def __dealloc__( self ) : RSA_free( self.rsa ) def __init__( self ) : pass cdef void loadCPublicKey( self, RSA *r ) : cdef RSA *newrsa newrsa = RSAPublicKey_dup( r ) RSA_free( self.rsa ) self.rsa = newrsa cdef void loadCPrivateKey( self, RSA *r ) : cdef RSA *newrsa newrsa = RSAPrivateKey_dup( r ) RSA_free( self.rsa ) self.rsa = newrsa def generate( self, bits=1024, **kw ) : cdef RSA *newKey cdef int e e = kw.get( 'e', 5 ) callback = kw.get( 'callback', None ) if callback is None : newKey = RSA_generate_key( bits, e, NULL, NULL ) else : newKey = RSA_generate_key( bits, e, _rsa_callback, callback ) if newKey == NULL : raise RSAError, 'key generation failed' RSA_free( self.rsa ) self.rsa = newKey def size( self ) : if not self.rsa.n : raise RSAError, 'key not initialized' return RSA_size( self.rsa ) def check( self ) : cdef RSA *r r = self.rsa if (not r.e) or (not r.n) or (not r.d) : raise RSAError, 'private key not initialized' if (not r.p) or (not r.q) : raise RSAError, 'primes not initialized' return RSA_check_key( r ) def enableBlinding( self, enable=True ) : if not self.rsa.d : raise RSAError, 'private key not initialized' cdef int result if enable : result = RSA_blinding_on( self.rsa, NULL ) if not result : raise RSAError, 'unable to enable blinding' else : RSA_blinding_off( self.rsa ) def getN( self ) : if not self.rsa.n : raise RSAError, "'n' not initialized" return BNToLong( self.rsa.n ) def getE( self ) : if not self.rsa.e : raise RSAError, "'e' not initialized" return BNToLong( self.rsa.e ) def getD( self ) : if not self.rsa.d : raise RSAError, "'d' not initialized" return BNToLong( self.rsa.d ) def getP( self ) : if not self.rsa.p : raise RSAError, "'p' not initialized" return BNToLong( self.rsa.p ) def getQ( self ) : if not self.rsa.q : raise RSAError, "'q' not initialized" return BNToLong( self.rsa.q ) def hasPublicKey( self ) : if not self.rsa.n : return False if not self.rsa.e : return False return True def hasPrivateKey( self ) : if not self.rsa.d : return False return True def getPublicKey( self ) : cdef RSA *r r = self.rsa if (not r.n) or (not r.e) : raise RSAError, 'key not initialized' return (BNToLong(r.n),BNToLong(r.e)) def getPrivateKey( self ) : cdef RSA *r cdef BIGNUM *x r = self.rsa if (not r.n) or (not r.e) or (not r.d) : raise RSAError, 'private key not initialized' if (not r.p) or (not r.q) or (not r.dmp1) or (not r.dmq1) or (not r.iqmp) : raise RSAError, 'private key not initialized' return (BNToLong(r.n),BNToLong(r.e),BNToLong(r.d), BNToLong(r.p),BNToLong(r.q),BNToLong(r.dmp1),BNToLong(r.dmq1), BNToLong(r.iqmp)) def loadPublicKey( self, publicKey ) : cdef BIGNUM *bn_n, *bn_e cdef int result1, result2 n,e = publicKey bn_n, bn_e = BN_new(), BN_new() result1 = LongToBN( n, bn_n ) result2 = LongToBN( e, bn_e ) if (result1 < 0) or (result2 < 0) : BN_free( bn_n ) BN_free( bn_e ) raise RSAError, 'invalid public key' RSA_free( self.rsa ) self.rsa = RSA_new() self.rsa.n, self.rsa.e = bn_n, bn_e def loadPrivateKey( self, privateKey ) : cdef BIGNUM *bn[8] cdef int i, result if len(privateKey) != 8 : raise TypeError, 'private key must have 8 elements' for i from 0 <= i < 8 : bn[i] = BN_new() for i from 0 <= i < 8 : result = LongToBN( privateKey[i], bn[i] ) if result < 0 : for i from 0 <= i < 8 : BN_free( bn[i] ) raise RSAError, 'invalid private key' RSA_free( self.rsa ) self.rsa = RSA_new() cdef RSA *r r = self.rsa r.n, r.e, r.d, r.p, r.q = bn[0], bn[1], bn[2], bn[3], bn[4] r.dmp1, r.dmq1, r.iqmp = bn[5], bn[6], bn[7] def paddingSize( self, paddingMode ) : if paddingMode == PADDING_PKCS1 : return 12 if paddingMode == PADDING_PKCS1_OAEP : return 42 raise RSAError, 'unknown padding mode' def maxInputSize( self, paddingMode=PADDING_PKCS1_OAEP ) : return self.size() - self.paddingSize(paddingMode) def encrypt( self, data, paddingMode=PADDING_PKCS1_OAEP ) : cdef int paddingCode if paddingMode == PADDING_PKCS1 : paddingCode = RSA_PKCS1_PADDING elif paddingMode == PADDING_PKCS1_OAEP : paddingCode = RSA_PKCS1_OAEP_PADDING else : raise RSAError, 'unknown padding mode' if (not self.rsa.n) or (not self.rsa.e) : raise RSAError, 'public key not initialized' size = self.size() maxSize = self.maxInputSize(paddingMode) if len(data) > maxSize : raise RSAError, 'encryption input is too long, maxsize=%d' % maxSize cdef int result cdef unsigned char *plainText cdef int plainTextLen result = PyString_AsStringAndSize( data, &plainText, &plainTextLen ) if result < 0 : raise TypeError, "'data' must be a string" cdef unsigned char *cipherText cipherText = malloc( size ) cdef int cipherTextLen cipherTextLen = RSA_public_encrypt( plainTextLen, plainText, cipherText, self.rsa, paddingCode ) if cipherTextLen < 0 : free( cipherText ) raise RSAError, 'RSA encryption failed' assert cipherTextLen == size try : return PyString_FromStringAndSize( cipherText, cipherTextLen ) finally : free( cipherText ) def decrypt( self, data, paddingMode=PADDING_PKCS1_OAEP ) : cdef int paddingCode paddingCode = -1 if paddingMode == PADDING_PKCS1 : paddingCode = RSA_PKCS1_PADDING elif paddingMode == PADDING_PKCS1_OAEP : paddingCode = RSA_PKCS1_OAEP_PADDING else : raise RSAError, 'unknown padding mode' if (not self.rsa.n) or (not self.rsa.e) or (not self.rsa.d) : raise RSAError, 'private key not initialized' size = self.size() cdef int result cdef unsigned char *cipherText cdef int cipherTextLen result = PyString_AsStringAndSize( data, &cipherText, &cipherTextLen ) if result < 0 : raise TypeError, "'data' must be a string" cdef unsigned char *plainText cdef int plainTextLen plainText = malloc( self.size() ) plainTextLen = RSA_private_decrypt( cipherTextLen, cipherText, plainText, self.rsa, paddingCode ) if plainTextLen < 0 : free( plainText ) raise RSAError, 'RSA decryption failed' try : return PyString_FromStringAndSize( plainText, plainTextLen ) finally : free( plainText ) def sign( self, digest, digestType ) : if (not self.rsa.n) or (not self.rsa.e) or (not self.rsa.d) : raise RSAError, 'private key not initialized' cdef int nid nid = digestType.nid() cdef int result cdef unsigned char *digestBuf cdef unsigned int digestLen result = PyString_AsStringAndSize( digest, &digestBuf, &digestLen ) if result < 0 : raise TypeError, "'digest' must be a string" cdef int size size = self.size() cdef unsigned char *sigBuf cdef unsigned int sigLen sigLen = size sigBuf = malloc( sigLen ) result = RSA_sign( nid, digestBuf, digestLen, sigBuf, &sigLen, self.rsa ) if not result : free( sigBuf ) raise RSAError, 'RSA sign failed' try : return PyString_FromStringAndSize( sigBuf, sigLen ) finally : free( sigBuf ) def verify( self, signature, digest, digestType ) : if (not self.rsa.n) or (not self.rsa.e) : raise RSAError, 'public key not initialized' cdef int nid nid = digestType.nid() cdef int result cdef unsigned char *digestBuf cdef unsigned int digestLen result = PyString_AsStringAndSize( digest, &digestBuf, &digestLen ) if result < 0 : raise TypeError, "'digest' must be a string" cdef unsigned char *sigBuf cdef unsigned int sigLen result = PyString_AsStringAndSize( signature, &sigBuf, &sigLen ) if result < 0 : raise TypeError, "'signature' must be a string" result = RSA_verify( nid, digestBuf, digestLen, sigBuf, sigLen, self.rsa ) if not result : raise RSAError, 'RSA verify failed' def fromDER_PrivateKey( self, data ) : cdef RSA *newrsa cdef char *p cdef int dataLen, result result = PyString_AsStringAndSize( data, &p, &dataLen ) if result < 0 : raise TypeError, 'a string is expected' newrsa = d2i_RSAPrivateKey( NULL, &p, dataLen ) if not newrsa : raise RSAError, 'unable to load object from data' RSA_free( self.rsa ) self.rsa = newrsa def toDER_PrivateKey( self ) : cdef int len, len1 cdef PyObject *derStr if not self.hasPrivateKey() : raise RSAError, 'private key not initialized' len = i2d_RSAPrivateKey( self.rsa, NULL ) if len < 0 : raise RSAError, 'error in private key data' derStr = Raw_PyString_FromStringAndSize( NULL, len ) if derStr == NULL : raise MemoryError, 'unable to allocate string' cdef char *p p = Raw_PyString_AsString( derStr ) try : len1 = i2d_RSAPrivateKey( self.rsa, &p ) assert len == len1 return derStr finally : Py_DECREF( derStr ) def fromDER_PublicKey( self, data ) : cdef RSA *newrsa cdef char *p cdef int dataLen, result result = PyString_AsStringAndSize( data, &p, &dataLen ) if result < 0 : raise TypeError, 'a string is expected' newrsa = d2i_RSAPublicKey( NULL, &p, dataLen ) if not newrsa : raise RSAError, 'unable to load object from data' RSA_free( self.rsa ) self.rsa = newrsa def toDER_PublicKey( self ) : cdef int len, len1 cdef PyObject *derStr if not self.hasPublicKey() : raise RSAError, 'public key not initialized' len = i2d_RSAPublicKey( self.rsa, NULL ) if len < 0 : raise RSAError, 'error in public key data' derStr = Raw_PyString_FromStringAndSize( NULL, len ) if derStr == NULL : raise MemoryError, 'unable to allocate string' cdef char *p p = Raw_PyString_AsString( derStr ) try : len1 = i2d_RSAPublicKey( self.rsa, &p ) assert len == len1 return derStr finally : Py_DECREF( derStr ) def fromPEM_PrivateKey( self, data, password=None ) : cdef char *p cdef int dataLen, result cdef PemCbData passwd_cb_data cdef BIO *b cdef RSA *newrsa result = PyString_AsStringAndSize( data, &p, &dataLen ) if result < 0 : raise TypeError, 'a string is expected' b = BIO_new( BIO_s_mem() ) if not b : raise RSAError, 'unable to allocate BIO structure' try : result = BIO_write( b, p, dataLen ) if result < 0 : raise RSAError, 'unable to write data to BIO' if password is None : passwd_cb_data.data = NULL passwd_cb_data.length = 0 else : result = PyString_AsStringAndSize( password, &p, &dataLen ) if result < 0 : raise TypeError, 'password is not a string' else: passwd_cb_data.data = p passwd_cb_data.length = dataLen newrsa = PEM_read_bio_RSAPrivateKey( b, NULL, &_password_callback, &passwd_cb_data ) if not newrsa : raise RSAError, 'unable to load object from data' RSA_free( self.rsa ) self.rsa = newrsa finally : BIO_free( b ) def toPEM_PrivateKey( self, password=None ) : if not self.hasPrivateKey() : raise RSAError, 'private key not initialized' cdef char *p,*q cdef int dataLen, result cdef BIO *b b = BIO_new( BIO_s_mem() ) if not b : raise RSAError, 'unable to allocate a BIO structure' try : if password is None : result = PEM_write_bio_RSAPrivateKey( b, self.rsa, NULL, NULL, 0, NULL, NULL ) else: result = PyString_AsStringAndSize( password, &p, &dataLen ) if result < 0 : raise TypeError, 'password is not a string' q = ( malloc( dataLen ) ) # Since PEM_write_bio_RSAPrivateKey does'nt guarantee that p will be unmodified if q == NULL : raise MemoryError, 'error allocating memory for password' memcpy( q, p, dataLen ) try : result = PEM_write_bio_RSAPrivateKey( b, self.rsa, EVP_des_ede3_cbc(), p, dataLen, NULL, NULL ) finally : free( q ) if not result : raise RSAError, 'error in public key data' ret = GetBIOData( b ) if ret is None : raise RSAError, 'error in creating PEM data' return ret finally : BIO_free( b ) def fromPEM_PublicKey( self, data ) : cdef char *p cdef int dataLen, result cdef BIO *b cdef RSA *newrsa result = PyString_AsStringAndSize( data, &p, &dataLen ) if result < 0 : raise TypeError, 'a string is expected' b = BIO_new( BIO_s_mem() ) if not b : raise RSAError, 'unable to allocate BIO structure' try : result = BIO_write( b, p, dataLen ) if result < 0 : raise RSAError, 'unable to write data to BIO' newrsa = PEM_read_bio_RSAPublicKey( b, NULL, NULL, NULL ) if not newrsa : raise RSAError, 'unable to load object from data' RSA_free( self.rsa ) self.rsa = newrsa finally : BIO_free( b ) def toPEM_PublicKey( self ) : if not self.hasPublicKey() : raise RSAError, 'public key not initialized' cdef int result cdef BIO *b b = BIO_new( BIO_s_mem() ) if not b : raise RSAError, 'unable to allocate a BIO structure' try : result = PEM_write_bio_RSAPublicKey( b, self.rsa ) if not result : raise RSAError, 'error in public key data' ret = GetBIOData( b ) if ret is None : raise RSAError, 'error in creating PEM data' return ret finally : BIO_free( b ) ncrypt-0.6.4/ncrypt_bignum.pyx0000700000175000017500000000447510512376023014452 0ustar fx5fx5cdef extern from "openssl/bn.h" : ctypedef struct BIGNUM BIGNUM *BN_new() void BN_free( BIGNUM *x ) void BN_clear( BIGNUM *x ) int BN_dec2bn( BIGNUM **x, char *str ) char *BN_bn2dec( BIGNUM *x ) int BN_num_bytes( BIGNUM *x ) int BN_num_bits( BIGNUM *x ) cdef extern from "openssl/crypto.h" : void OPENSSL_free( void *p ) cdef extern from "Python.h" : int PyString_Check( object obj ) int PyInt_Check( object obj ) int PyLong_Check( object obj ) char *PyString_AsString( object obj ) int PyString_AsStringAndSize( object obj, char **buffer, int *length ) object PyString_FromStringAndSize( char *buf, int buf_size ) object Py_BuildValue( char *fmt, ... ) object PyObject_Str( object obj ) object PyLong_FromString( char *p, char **pend, int base ) cdef extern from "stdlib.h" : void *malloc( int size ) void free( void *p ) cdef class BigNum : cdef BIGNUM *bn def __new__( self, x=None ) : self.bn = BN_new() cdef _free( self ) : BN_free( self.bn ) self.bn = NULL def __dealloc__( self ) : self._free() def __init__( self, x=None ) : if PyInt_Check(x) or PyLong_Check(x) : x = PyObject_Str( x ) cdef char *s cdef int result if PyString_Check(x) : s = PyString_AsString(x) result = BN_dec2bn( &self.bn, s ) if result == 0 : raise ValueError, 'invalid string value passed' elif x is not None : raise TypeError, 'invalid type passed, require int/long/str' def clear( self ) : BN_clear( self.bn ) def toLong( self ) : cdef char *s s = BN_bn2dec( self.bn ) try : return PyLong_FromString( s, NULL, 10 ) finally : OPENSSL_free( s ) def fromLong( self, x ) : if not PyLong_Check(x) and not PyInt_Check(x) : raise TypeError, 'long/int type required' x = PyObject_Str( x ) cdef char *s cdef int result s = PyString_AsString( x ) result = BN_dec2bn( &self.bn, s ) if result == 0 : raise ValueError, 'invalid string value passed' def numBytes( self ) : return BN_num_bytes( self.bn ) def numBits( self ) : return BN_num_bits( self.bn ) ncrypt-0.6.4/ncrypt_err.pyx0000700000175000017500000000422410512376023013751 0ustar fx5fx5cdef extern from "openssl/err.h" : unsigned long ERR_get_error() unsigned long ERR_peek_error() char *ERR_lib_error_string( unsigned long e ) char *ERR_func_error_string( unsigned long e ) char *ERR_reason_error_string( unsigned long e ) void ERR_clear_error() cdef extern from "Python.h" : object PyString_FromString( char *p ) cdef object MakePyString( char *p ) : if not p : return '' return PyString_FromString( p ) cdef object buildErrorTuple( unsigned long errCode ) : cdef char *libStr, *funcStr, *reasonStr libStr = ERR_lib_error_string( errCode ) funcStr = ERR_func_error_string( errCode ) reasonStr = ERR_reason_error_string( errCode ) return ( errCode, MakePyString(libStr), MakePyString(funcStr), MakePyString(reasonStr) ) def getError() : return buildErrorTuple( ERR_get_error() ) def peekError() : return buildErrorTuple( ERR_peek_error() ) def clearErrors() : ERR_clear_error() class BaseError( Exception ) : def __init__( self, *args ) : Exception.__init__( self, *args ) class LibraryErrorInfo : def initErrorInfo( self ) : cdef unsigned long errCode (self.errorCode, self.errorLib, self.errorFunc, self.errorReason) = getError() self.nestedErrors = [] while ERR_peek_error() != 0 : self.nestedErrors.append( getError() ) def updateArgs( self, args ) : reason = self.getReason() if (len(args) == 1) and isinstance(args[0],str) and reason : args = ( '%s (%s)' % (args[0],reason), ) return args def getCode( self ) : return self.errorCode def getLib( self ) : return self.errorLib def getFunc( self ) : return self.errorFunc def getReason( self ) : return self.errorReason def getError( self ) : return (self.errorCode, self.errorLib, self.errorFunc, self.errorReason) def getNestedErrors( self ) : return self.nestedErrors class BaseLibraryError( BaseError, LibraryErrorInfo ) : def __init__( self, *args ) : LibraryErrorInfo.initErrorInfo( self ) args = self.updateArgs( args ) BaseError.__init__( self, *args ) ncrypt-0.6.4/ncrypt_ssl.pyx0000700000175000017500000003012310512376024013760 0ustar fx5fx5from ncrypt_x509 cimport X509 cimport ncrypt_x509 from ncrypt_dh cimport DH_s cimport ncrypt_dh from ncrypt_rsa cimport RSA cimport ncrypt_rsa import ncrypt_err import ncrypt_x509 cdef extern from "openssl/rsa.h" : void RSA_free( RSA *x ) RSA *RSAPrivateKey_dup( RSA *x ) cdef extern from "openssl/x509.h" : X509 *X509_dup( X509 *x ) void X509_free( X509 *x ) ctypedef struct X509_STORE_CTX int X509_STORE_CTX_get_error( X509_STORE_CTX *ctx ) cdef enum : X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT cdef extern from "openssl/ssl.h" : ctypedef struct SSL_METHOD SSL_METHOD *SSLv2_method() SSL_METHOD *SSLv2_client_method() SSL_METHOD *SSLv2_server_method() SSL_METHOD *SSLv3_method() SSL_METHOD *SSLv3_client_method() SSL_METHOD *SSLv3_server_method() SSL_METHOD *TLSv1_method() SSL_METHOD *TLSv1_client_method() SSL_METHOD *TLSv1_server_method() SSL_METHOD *SSLv23_method() SSL_METHOD *SSLv23_client_method() SSL_METHOD *SSLv23_server_method() ctypedef struct SSL_CTX SSL_CTX *SSL_CTX_new( SSL_METHOD *meth ) void SSL_CTX_free( SSL_CTX *ctx ) long SSL_CTX_set_session_cache_mode( SSL_CTX *ctx, long mode ) long SSL_CTX_set_mode( SSL_CTX *ctx, long mode ) int SSL_CTX_use_certificate( SSL_CTX *ctx, X509 *x ) int SSL_CTX_use_RSAPrivateKey( SSL_CTX *ctx, RSA *r ) void SSL_CTX_set_verify( SSL_CTX *ctx, int mode, int (*verify_callback)(int,X509_STORE_CTX*) ) long SSL_CTX_set_tmp_dh( SSL_CTX *ctx, DH_s *dh ) long SSL_CTX_set_options( SSL_CTX *ctx, long options ) cdef enum : SSL_SESS_CACHE_OFF SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER SSL_VERIFY_NONE SSL_VERIFY_PEER SSL_VERIFY_FAIL_IF_NO_PEER_CERT SSL_VERIFY_CLIENT_ONCE SSL_OP_SINGLE_DH_USE ctypedef struct SSL SSL *SSL_new( SSL_CTX *ctx ) void SSL_free( SSL *ssl ) int SSL_set_fd( SSL *ssl, int fd ) int SSL_get_error( SSL *ssl, int ret ) int SSL_connect( SSL *ssl ) int SSL_accept( SSL *ssl ) int SSL_get_verify_result( SSL *ssl ) X509 *SSL_get_peer_certificate( SSL *ssl ) int SSL_pending( SSL *ssl ) int SSL_read( SSL *ssl, void *buf, int num ) int SSL_write( SSL *ssl, void *buf, int num ) int SSL_shutdown( SSL *ssl ) cdef enum : SSL_ERROR_NONE SSL_ERROR_ZERO_RETURN SSL_ERROR_WANT_READ SSL_ERROR_WANT_WRITE SSL_ERROR_WANT_X509_LOOKUP SSL_ERROR_SYSCALL SSL_ERROR_SSL cdef extern from "openssl/err.h" : void ERR_clear_error() cdef extern from "Python.h" : ctypedef struct PyObject void Py_DECREF( PyObject *obj ) void Py_XDECREF( PyObject *obj ) void Py_INCREF( PyObject *obj ) int PyString_AsStringAndSize( PyObject *obj, char **buffer, int *length ) PyObject *PyString_FromStringAndSize( char *buf, int buf_size ) int _PyString_Resize( PyObject **s, int newsize ) char *PyString_AsString( PyObject *s ) SSL_METHOD_SSLv2 = 0 SSL_METHOD_SSLv3 = 1 SSL_METHOD_TLSv1 = 2 SSL_METHOD_SSLv23 = 3 SSL_METHOD_MAX = 4 SSL_METHOD_TYPE_CLIENT = 0 SSL_METHOD_TYPE_SERVER = 1 SSL_METHOD_TYPE_GENERIC = 2 SSL_METHOD_TYPE_MAX = 3 class SSLError( ncrypt_err.BaseError ) : pass class SSLCertificateError( SSLError ) : pass class SSLWantError( SSLError ) : pass class SSLWantReadError( SSLWantError ) : pass class SSLWantWriteError( SSLWantError ) : pass class SSLWantX509LookupError( SSLWantError ) : pass class SSLZeroReturnError( SSLError ) : pass class SSLLibraryError( SSLError, ncrypt_err.LibraryErrorInfo ) : def __init__( self, *args ) : ncrypt_err.LibraryErrorInfo.initErrorInfo( self ) args = self.updateArgs( args ) SSLError.__init__( self, *args ) class SSLSysCallError( SSLLibraryError ) : pass class SSLProtocolError( SSLLibraryError ) : pass SSL_VERIFY_MODE_NONE = 0 SSL_VERIFY_MODE_SELF_SIGNED = 1 SSL_VERIFY_MODE_MAX = 2 cdef SSL_METHOD *getSSLMethod( int method, int methodType ) : m, t = method, methodType if m == SSL_METHOD_SSLv2 : if t == SSL_METHOD_TYPE_CLIENT : return SSLv2_client_method() elif t == SSL_METHOD_TYPE_SERVER : return SSLv2_server_method() elif t == SSL_METHOD_TYPE_GENERIC : return SSLv2_method() elif m == SSL_METHOD_SSLv3 : if t == SSL_METHOD_TYPE_CLIENT : return SSLv3_client_method() elif t == SSL_METHOD_TYPE_SERVER : return SSLv3_server_method() elif t == SSL_METHOD_TYPE_GENERIC : return SSLv3_method() elif m == SSL_METHOD_TLSv1 : if t == SSL_METHOD_TYPE_CLIENT : return TLSv1_client_method() elif t == SSL_METHOD_TYPE_SERVER : return TLSv1_server_method() elif t == SSL_METHOD_TYPE_GENERIC : return TLSv1_method() elif m == SSL_METHOD_SSLv23 : if t == SSL_METHOD_TYPE_CLIENT : return SSLv23_client_method() elif t == SSL_METHOD_TYPE_SERVER : return SSLv23_server_method() elif t == SSL_METHOD_TYPE_GENERIC : return SSLv23_method() return NULL cdef int SelfSignedVerifyCallback( int preverify_ok, X509_STORE_CTX *ctx ) : if preverify_ok : return 1 cdef int verifyErr verifyErr = X509_STORE_CTX_get_error( ctx ) if verifyErr == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT : return 1 return 0 cdef class SSLContext : cdef SSL_CTX *c def __new__( self, sslMethod, sslMethodType=-1 ) : self.c = NULL def __dealloc__( self ) : if self.c : SSL_CTX_free( self.c ) def __init__( self, int sslMethod, int sslMethodType=-1 ) : if (sslMethod < 0) or (sslMethod >= SSL_METHOD_MAX) : raise ValueError, 'invalid ssl method' if sslMethodType == -1 : sslMethodType = SSL_METHOD_TYPE_GENERIC if (sslMethodType < 0) or (sslMethodType >= SSL_METHOD_TYPE_MAX) : raise ValueError, 'invalid ssl method type' if self.c : SSL_CTX_free( self.c ) self.c = NULL self.c = SSL_CTX_new( getSSLMethod(sslMethod,sslMethodType) ) if not self.c : raise SSLLibraryError, 'unable to initialize ssl context' SSL_CTX_set_session_cache_mode( self.c, SSL_SESS_CACHE_OFF ) SSL_CTX_set_mode( self.c, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER ) def setCertificate( self, ncrypt_x509.X509Certificate x not None ) : cdef X509 *x1 x1 = X509_dup( x.x ) if not x1 : raise SSLLibraryError, 'unable to allocate X509 certificate' cdef int result try : result = SSL_CTX_use_certificate( self.c, x1 ) if not result : raise SSLLibraryError, 'unable to set certificate' finally : X509_free( x1 ) def setPrivateKey( self, ncrypt_rsa.RSAKey rk not None ) : if not rk.hasPrivateKey() : raise SSLLibraryError, 'RSA private key not initialized' cdef RSA *rk1 rk1 = RSAPrivateKey_dup( rk.rsa ) if not rk1 : raise SSLLibraryError, 'unable to allocate RSA private key' cdef int result try : result = SSL_CTX_use_RSAPrivateKey( self.c, rk1 ) if not result : raise SSLLibraryError, 'unable to set RSA private key' finally : RSA_free( rk1 ) def setVerifyMode( self, int mode ) : if (mode < 0) or (mode >= SSL_VERIFY_MODE_MAX) : raise ValueError, 'invalid verification mode' if mode == SSL_VERIFY_MODE_NONE : SSL_CTX_set_verify( self.c, SSL_VERIFY_NONE, NULL ) elif mode == SSL_VERIFY_MODE_SELF_SIGNED : SSL_CTX_set_verify( self.c, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT|SSL_VERIFY_CLIENT_ONCE, SelfSignedVerifyCallback ) def enableDH( self, ncrypt_dh.DH dh not None ) : cdef long result result = SSL_CTX_set_tmp_dh( self.c, dh.dh ) if not result : raise SSLLibraryError, 'unable to enable dh' SSL_CTX_set_options( self.c, SSL_OP_SINGLE_DH_USE ) cdef class SSLConnection : cdef SSL *s cdef object sslContext cdef readonly object sock def __new__( self, sslContext, sock ) : self.s = NULL def __dealloc__( self ) : if self.s : SSL_free( self.s ) def __init__( self, SSLContext sslContext not None, sock ) : if self.s : SSL_free( self.s ) self.s = NULL self.s = SSL_new( sslContext.c ) if not self.s : raise SSLLibraryError, 'unable to initialize ssl state' self.sslContext = sslContext self.sock = sock cdef int result result = SSL_set_fd( self.s, sock.fileno() ) if result == 0 : raise SSLLibraryError, 'unable to set socket fd' cdef object getSSLError( self, int result ) : cdef int err err = SSL_get_error( self.s, result ) if err == SSL_ERROR_WANT_READ : return SSLWantReadError( 'SSL needs more readable data' ) if err == SSL_ERROR_WANT_WRITE : return SSLWantWriteError( 'SSL needs to write more data' ) if err == SSL_ERROR_WANT_X509_LOOKUP : return SSLWantX509LookupError( 'SSL x509 callback is pending' ) if err == SSL_ERROR_ZERO_RETURN : return SSLZeroReturnError( 'SSL connection has shutdown' ) if err == SSL_ERROR_SYSCALL : return SSLSysCallError( 'SSL internal syscall error' ) if err == SSL_ERROR_SSL : return SSLProtocolError( 'SSL protocol error' ) assert err != SSL_ERROR_NONE return SSLLibraryError( 'unknown SSL error' ) def connect( self ) : ERR_clear_error() cdef int result, err result = SSL_connect( self.s ) if result <= 0 : raise self.getSSLError( result ) def accept( self ) : ERR_clear_error() cdef int result, err result = SSL_accept( self.s ) if result <= 0 : raise self.getSSLError( result ) def getVerifyResult( self ) : return SSL_get_verify_result( self.s ) def getPeerCertificate( self ) : cdef X509 *x x = SSL_get_peer_certificate( self.s ) if not x : raise SSLCertificateError, 'no peer certificate available' cdef ncrypt_x509.X509Certificate cert cdef int result try : cert = ncrypt_x509.X509Certificate() result = cert.fromX509( x ) if not result : raise SSLLibraryError, 'unable to allocate copy certificate' return cert finally : X509_free( x ) def pending( self ) : return SSL_pending( self.s ) def recv( self, int bufsize ) : ERR_clear_error() cdef PyObject *buf cdef char *ptr buf = PyString_FromStringAndSize( NULL, bufsize ) if not buf : raise MemoryError, 'unable to allocate string' cdef int result try : ptr = PyString_AsString( buf ) assert ptr != NULL result = SSL_read( self.s, ptr, bufsize ) if result <= 0 : e = self.getSSLError( result ) if isinstance(e,SSLZeroReturnError ) : return '' raise e if result != bufsize : result = _PyString_Resize( &buf, result ) assert result == 0 return buf finally : Py_XDECREF( buf ) def send( self, data ) : ERR_clear_error() cdef char *ptr cdef int dataLen, result result = PyString_AsStringAndSize( data, &ptr, &dataLen ) if result < 0 : raise TypeError, 'a string is expected' if dataLen == 0 : return 0 result = SSL_write( self.s, ptr, dataLen ) if result <= 0 : raise self.getSSLError( result ) return result def shutdown( self ) : cdef int result result = SSL_shutdown( self.s ) if result < 0 : raise self.getSSLError( result ) return result ncrypt-0.6.4/ncrypt.c0000700000175000017500000000510510512376023012502 0ustar fx5fx5#include "Python.h" #include #include #include #include extern void initncrypt_err(); extern void initncrypt_digest(); extern void initncrypt_cipher(); extern void initncrypt_rand(); extern void initncrypt_bignum(); extern void initncrypt_dh(); extern void initncrypt_rsa(); extern void initncrypt_x509(); extern void initncrypt_ssl(); void init_sub_module( PyObject *ncryptMod, char *moduleName, void (*mod_init_func)() ) { char fullModName[256], shadowModName[256]; PyObject *subMod, *allList, *sysModules; int result; assert( strlen(moduleName) < 100 ); sprintf( fullModName, "_ncrypt.%s", moduleName ); sprintf( shadowModName, "ncrypt_%s", moduleName ); (*mod_init_func)(); subMod = PyImport_ImportModule( shadowModName ); assert( subMod ); result = PyObject_SetAttrString( ncryptMod, moduleName, subMod ); assert( result == 0 ); if ( PyObject_HasAttrString(ncryptMod,"__all__") ) { PyObject *pyModName; allList = PyObject_GetAttrString( ncryptMod, "__all__" ); assert( allList ); pyModName = PyString_FromString( moduleName ); assert( pyModName ); result = PyList_Append( allList, pyModName ); assert( result == 0 ); Py_DECREF( pyModName ); Py_DECREF( allList ); } else { allList = Py_BuildValue( "[s]", moduleName ); assert( result == 0 ); result = PyObject_SetAttrString( ncryptMod, "__all__", allList ); assert( result == 0 ); Py_DECREF( allList ); } sysModules = PySys_GetObject( "modules" ); assert( sysModules ); result = PyDict_SetItemString( sysModules, fullModName, subMod ); assert( result == 0 ); Py_DECREF( subMod ); } PyMODINIT_FUNC init_ncrypt() { PyObject *mod; OpenSSL_add_all_algorithms(); OpenSSL_add_ssl_algorithms(); SSL_load_error_strings(); EVP_add_cipher_alias( SN_des_ede3_ecb, "DES-EDE3-ECB" ); mod = Py_InitModule( "_ncrypt", NULL ); assert( mod ); init_sub_module( mod, "err", initncrypt_err ); init_sub_module( mod, "digest", initncrypt_digest ); init_sub_module( mod, "cipher", initncrypt_cipher ); init_sub_module( mod, "rand", initncrypt_rand ); init_sub_module( mod, "bignum", initncrypt_bignum ); init_sub_module( mod, "dh", initncrypt_dh ); init_sub_module( mod, "rsa", initncrypt_rsa ); init_sub_module( mod, "x509", initncrypt_x509 ); init_sub_module( mod, "ssl", initncrypt_ssl ); } ncrypt-0.6.4/ncrypt_digest.pxd0000700000175000017500000000015210512376023014407 0ustar fx5fx5cdef extern from "openssl/evp.h" : ctypedef struct EVP_MD cdef class DigestType : cdef EVP_MD *m ncrypt-0.6.4/ncrypt_digest.pyx0000700000175000017500000000705410512376023014444 0ustar fx5fx5cdef extern from "openssl/evp.h" : ctypedef struct EVP_MD_CTX ctypedef struct EVP_MD EVP_MD *EVP_get_digestbyname( char *name ) void EVP_add_digest( EVP_MD *evpMd ) void EVP_add_digest_alias( char *realName, char *aliasName ) int EVP_MD_type( EVP_MD *evpMd ) char *EVP_MD_name( EVP_MD *evpMd ) int EVP_MD_size( EVP_MD *evpMd ) int EVP_MD_block_size( EVP_MD *evpMd ) EVP_MD_CTX *EVP_MD_CTX_create() void EVP_MD_CTX_destroy( EVP_MD_CTX *ctx ) int EVP_DigestInit_ex( EVP_MD_CTX *ctx, EVP_MD *mdType, void *engine ) int EVP_DigestUpdate( EVP_MD_CTX *ctx, void *data, unsigned int dataLen ) int EVP_DigestFinal_ex( EVP_MD_CTX *ctx, unsigned char *md, unsigned int *mdLen ) cdef enum : EVP_MAX_MD_SIZE cdef extern from "Python.h" : int PyString_AsStringAndSize( object obj, char **buffer, int *length ) object PyString_FromStringAndSize( char *buf, int buf_size ) cdef extern from "utils.h" : void HexEncode( void *src, int srcLen, void *dest, int destLen ) void HexDecode( void *src, int srcLen, void *dest, int destLen ) import ncrypt_err class DigestError( ncrypt_err.BaseLibraryError ): pass ALGORITHMS = ('MD5','SHA1','SHA224','SHA256','SHA384','SHA512') cdef class DigestType : def __new__( self, evpMd ) : self.m = NULL def __dealloc__( self ) : pass def __init__( self, evpMd ) : self.m = EVP_get_digestbyname( evpMd ) if self.m == NULL : raise DigestError, 'unknown digest: %s' % evpMd def name( self ) : return EVP_MD_name( self.m ) def size( self ) : return EVP_MD_size( self.m ) def blockSize( self ) : return EVP_MD_block_size( self.m ) def nid( self ) : return EVP_MD_type( self.m ) cdef class Digest : cdef EVP_MD_CTX *ctx cdef int digestFinalized cdef readonly object digestType def __new__( self, digestType ) : self.ctx = NULL self.digestFinalized = 0 cdef void cleanupCtx( self ) : if self.ctx != NULL : EVP_MD_CTX_destroy( self.ctx ) self.ctx = NULL self.digestFinalized = 0 def __dealloc__( self ) : self.cleanupCtx() def __init__( self, DigestType digestType not None ) : self.cleanupCtx() self.ctx = EVP_MD_CTX_create() cdef int result result = EVP_DigestInit_ex( self.ctx, digestType.m, NULL ) if result != 1 : raise DigestError, 'unable to initialize digest' self.digestType = digestType def update( self, data ) : if self.digestFinalized != 0 : raise DigestError, 'no further update() operations allowed' cdef char *s cdef int slen cdef int result result = PyString_AsStringAndSize( data, &s, &slen ) if result < 0 : raise TypeError, 'a string is expected' result = EVP_DigestUpdate( self.ctx, s, slen ) if result != 1 : raise DigestError, 'unable to update digest' def digest( self, data=None ) : if self.digestFinalized != 0 : raise DigestError, 'digest operation is already completed' if data is not None : self.update( data ) cdef unsigned char md[EVP_MAX_MD_SIZE] cdef unsigned int mdLen cdef int result result = EVP_DigestFinal_ex( self.ctx, md, &mdLen ) if result != 1 : raise DigestError, 'unable to finalize digest' self.digestFinalized = 1 return PyString_FromStringAndSize( md, mdLen ) ncrypt-0.6.4/LICENSE.txt0000644000175000017500000000207410620074071012651 0ustar fx5fx5Copyright (c) 2005,2006,2007 Tachyon Technologies Pvt. Ltd. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ncrypt-0.6.4/ncrypt/0000700000175000017500000000000010512376023012332 5ustar fx5fx5ncrypt-0.6.4/ncrypt/test/0000700000175000017500000000000010512376023013311 5ustar fx5fx5ncrypt-0.6.4/ncrypt/test/ssl/0000700000175000017500000000000010512376023014112 5ustar fx5fx5ncrypt-0.6.4/ncrypt/test/ssl/sslclient.py0000700000175000017500000000123110512376023016464 0ustar fx5fx5import sys, os, socket from ncrypt import * ctx = ssl.SSLContext( ssl.SSL_METHOD_TLSv1 ) certFile = 'sreeram.cert' c = x509.X509Certificate() print 'loading certificate:', certFile c.fromPEM( file(certFile).read() ) rk = rsa.RSAKey() keyFile = 'sreeram.key' print 'loading key:', keyFile rk.fromPEM_PrivateKey( file(keyFile).read() ) ctx.setCertificate( c ) ctx.setPrivateKey( rk ) ctx.setVerifyMode( ssl.SSL_VERIFY_MODE_SELF_SIGNED ) a = ( 'localhost', 4433 ) s = socket.socket( socket.AF_INET, socket.SOCK_STREAM ) s.connect( a ) sc = ssl.SSLConnection( ctx, s ) sc.connect() sc.send( 'Hello There\r\n' ) sc.shutdown() s.close() ncrypt-0.6.4/ncrypt/test/ssl/sreeram.cert0000700000175000017500000000253310512376023016435 0ustar fx5fx5-----BEGIN CERTIFICATE----- MIIDyDCCAzGgAwIBAgIJAKaweC1SFXh3MA0GCSqGSIb3DQEBBQUAMIGfMQswCQYD VQQGEwJJTjETMBEGA1UECBMKVGFtaWwgTmFkdTEQMA4GA1UEBxMHQ2hlbm5haTEd MBsGA1UEChMUVGFjaHlvbiBUZWNobm9sb2dpZXMxDDAKBgNVBAsUA1ImRDEUMBIG A1UEAxMLSyBTIFNyZWVyYW0xJjAkBgkqhkiG9w0BCQEWF3NyZWVyYW1AdGFjaHlv bnRlY2gubmV0MB4XDTA1MDgwMTA1NTcyNFoXDTA2MDgwMTA1NTcyNFowgZ8xCzAJ BgNVBAYTAklOMRMwEQYDVQQIEwpUYW1pbCBOYWR1MRAwDgYDVQQHEwdDaGVubmFp MR0wGwYDVQQKExRUYWNoeW9uIFRlY2hub2xvZ2llczEMMAoGA1UECxQDUiZEMRQw EgYDVQQDEwtLIFMgU3JlZXJhbTEmMCQGCSqGSIb3DQEJARYXc3JlZXJhbUB0YWNo eW9udGVjaC5uZXQwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALUQaUfbPhDT Y2pCAZ8vUoBugVBVbwJaYt6fEaHt1g31nNHLr9s68L4DzcEY1oV82RikBWVWMefP 3QAANvWDceJy4PS8epwTl8knRa0YrbItSf60yeut11/fINyP94T+FSQ9DTF5QwYl HqmOeYydcu+4Pfktx3R7qKRinMwXrn15AgMBAAGjggEIMIIBBDAdBgNVHQ4EFgQU QZsPDHE1ORPhAqoefdQUbIvlaeMwgdQGA1UdIwSBzDCByYAUQZsPDHE1ORPhAqoe fdQUbIvlaeOhgaWkgaIwgZ8xCzAJBgNVBAYTAklOMRMwEQYDVQQIEwpUYW1pbCBO YWR1MRAwDgYDVQQHEwdDaGVubmFpMR0wGwYDVQQKExRUYWNoeW9uIFRlY2hub2xv Z2llczEMMAoGA1UECxQDUiZEMRQwEgYDVQQDEwtLIFMgU3JlZXJhbTEmMCQGCSqG SIb3DQEJARYXc3JlZXJhbUB0YWNoeW9udGVjaC5uZXSCCQCmsHgtUhV4dzAMBgNV HRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAK5MVc59v6IAmG6ViWfIwh3RYCR6 btqQ+S42EMjtwBiryYOY9m7IF8muCluqzZ5wEMMLtsgV5a6cnfFuNvo9o2vwgum+ TQ+C7MJGg0iN4Xt4XtVlGQe+dMGABBJLlRFnM1xK85F7IF9rRHRLrNQBqTc8rweA G646QqsWVFoEwC8x -----END CERTIFICATE----- ncrypt-0.6.4/ncrypt/test/ssl/sslserver1.py0000700000175000017500000000404310512376023016601 0ustar fx5fx5import sys, os, socket, time from ncrypt import * certFile = 'sreeram.cert' c = x509.X509Certificate() print 'loading certificate:', certFile c.fromPEM( file(certFile).read() ) rk = rsa.RSAKey() keyFile = 'sreeram.key' print 'loading key:', keyFile rk.fromPEM_PrivateKey( file(keyFile).read() ) dhParamsFile = 'dhparams.pem' dhParams = dh.DH() print 'loading dh params:', dhParamsFile dhParams.fromPEM_Parameters( file(dhParamsFile).read() ) def handleSSLError( func, exceptFunc=None ) : try : func() except ssl.SSLLibraryError, sle : print sle.__class__, sle print sle.getError() print sle.getNestedErrors() if exceptFunc : exceptFunc() except ssl.SSLError, se : print se.__class__, se if exceptFunc : exceptFunc() listenSock = socket.socket( socket.AF_INET, socket.SOCK_STREAM ) listenSock.bind( ('localhost',4433) ) listenSock.listen( 5 ) ctx = ssl.SSLContext( ssl.SSL_METHOD_SSLv23 ) def initCtx() : print 'setting certificate' ctx.setCertificate( c ) print 'setting private key' ctx.setPrivateKey( rk ) ctx.setVerifyMode( ssl.SSL_VERIFY_MODE_SELF_SIGNED ) print 'enabling dh' ctx.enableDH( dhParams ) handleSSLError( initCtx, lambda : sys.exit(-1) ) while 1 : (c,remoteAddr) = listenSock.accept() print 'received connection from:', remoteAddr sc = ssl.SSLConnection( ctx, c ) def connLoop() : sc.accept() print 'verify result =', sc.getVerifyResult() try : clientCert = sc.getPeerCertificate() print 'peer certificate present' except ssl.SSLError, se : print se.__class__, se print 'no peer certificate' while 1 : s = sc.recv( 1024 ) if not s : print 'connection shutdown' break sys.stdout.write( s ) sys.stdout.flush() handleSSLError( connLoop ) handleSSLError( sc.shutdown ) c.close() ncrypt-0.6.4/ncrypt/test/ssl/dhparams.pem0000700000175000017500000000037210512376023016421 0ustar fx5fx5-----BEGIN DH PARAMETERS----- MIGHAoGBAPVOPE8/dHHSmoRlBwylo0rFJp1kxhqm/PMzj7AXMST2rBUR5m9hkPs6 20fK6M6nX9kwvgSVGKdhMQ7ibTZ/3P7GfiMU5ex5iSg1eYVupD4qMDZgaaJM52RH SgxU7uuEEcFQzX1IEWVPobObut72O8KxpAtNYNII4HxlC/hvyfsbAgEC -----END DH PARAMETERS----- ncrypt-0.6.4/ncrypt/test/ssl/sslserver.py0000700000175000017500000000355710512376023016531 0ustar fx5fx5import sys, os, socket, time from ncrypt import * print 'generating RSA key...' rk = rsa.RSAKey() rk.generate() print 'building certificate' c = x509.X509Certificate() xn = x509.X509Name() xn.addEntry( 'commonName', 'ks' ) c.setVersion( 3 ) c.setSerialNumber( 1 ) c.setSubject( xn ) c.setIssuer( xn ) c.setPublicKey( rk ) c.setNotBefore( 0 ) c.setNotAfter( int(time.time()) + 365*24*60*60 ) c.sign( rk, digest.DigestType('sha1') ) if err.peekError()[0] : print err.peekError() print err.getError() sys.exit( -1 ) dhParams = dh.DH() print 'generating dh parameters..' dhParams.generateParameters( 512, 2 ) print 'done generating dh parameters' listenSock = socket.socket( socket.AF_INET, socket.SOCK_STREAM ) listenSock.bind( ('localhost',4433) ) listenSock.listen( 5 ) ctx = ssl.SSLContext( ssl.SSL_METHOD_SSLv23 ) print 'setting certificate' ctx.setCertificate( c ) try : pass except ssl.SSLLibraryError, e : print e print e.getError() print e.getNestedErrors() sys.exit( -1 ) print 'setting private key' ctx.setPrivateKey( rk ) print 'enabling dh' ctx.enableDH( dhParams ) def handleSSLError( func ) : try : func() except ssl.SSLLibraryError, sle : print sle.__class__, sle print sle.getError() print sle.getNestedErrors() except ssl.SSLError, se : print se.__class__, se while 1 : (c,remoteAddr) = listenSock.accept() print 'received connection from:', remoteAddr sc = ssl.SSLConnection( ctx, c ) def connLoop() : sc.accept() while 1 : s = sc.recv( 1024 ) if not s : print 'connection shutdown' break sys.stdout.write( s ) sys.stdout.flush() handleSSLError( connLoop ) handleSSLError( sc.shutdown ) c.close() ncrypt-0.6.4/ncrypt/test/ssl/sreeram.key0000700000175000017500000000157310512376023016273 0ustar fx5fx5-----BEGIN RSA PRIVATE KEY----- MIICXgIBAAKBgQC1EGlH2z4Q02NqQgGfL1KAboFQVW8CWmLenxGh7dYN9ZzRy6/b OvC+A83BGNaFfNkYpAVlVjHnz90AADb1g3HicuD0vHqcE5fJJ0WtGK2yLUn+tMnr rddf3yDcj/eE/hUkPQ0xeUMGJR6pjnmMnXLvuD35Lcd0e6ikYpzMF659eQIDAQAB AoGBALNOlkQfvR4iiPAgf8Sps3UWeh8ZC/7zjbfTJT4L7xAR7IPix7s+akxyLd+M /lxhYAjD3cgWDQP42G34yHRoAG1K2AYqU9r/CBdideUf+RuGloGFLEj4lE0003/W RkCAs0b8LQHNQ7DIHJUKGd8f6iqfkPrtt+kZ+08aouku5QCBAkEA4drzqMefv2zg Z9h9oCeJvhWgJy/O9546WmyaEAEtDUI+8vLQmAZfXJDiaFWg6uJdDrER2Q56RPZT Al2NgQBx6QJBAM07B5iEan2IbUyqPlaInQa2JVoJZp2s/BDA8UvDx74xh1abZvEA QvEY+0nJbgME2Iki5eR0qfGywmKeHBRGZRECQHqtwZg2BnGmJCaEE4jAsTMM8BcZ AuTBj5S6VNzIpr4C88pnViKdo4LWOATQLj4ngsCOMdGi6Ys3+VLZmhkuMrECQQDK OKADaHaFuyf3oshJ+9K+CjxDu3+hXhIBcBxSy1bF0YfJjtagIeHULwlsa047K0sx 1XEw6sOJpNpk0eZZFAQBAkEAyNgYDFl1481JQtASdAE1iCEU25TtT5sq8JMowSCJ Ezk2Wlv9aYmbfOyZImTGlnLY318oN3P4iRtkAXTRkGtIyw== -----END RSA PRIVATE KEY----- ncrypt-0.6.4/ncrypt/test/ssl/__init__.py0000700000175000017500000000004010512376023016220 0ustar fx5fx5''' SSL Tests for PyNCrypt '''ncrypt-0.6.4/ncrypt/test/sha1hash.py0000700000175000017500000000055210512376023015370 0ustar fx5fx5import sys from ncrypt import digest def main() : if len(sys.argv) != 2 : print 'usage: sha1hash ' return fileName = sys.argv[1] dt = digest.DigestType( 'SHA1' ) d = digest.Digest( dt ) hash = d.digest( file(sys.argv[1],'rb').read() ) print hash.encode('hex') if __name__ == '__main__' : main() ncrypt-0.6.4/ncrypt/test/key32.file0000700000175000017500000000004010512376023015104 0ustar fx5fx501234567012345670123456701234567ncrypt-0.6.4/ncrypt/test/testrand.py0000700000175000017500000000145210512376023015514 0ustar fx5fx5import sys, os, unittest from ncrypt import rand class RandTestCase( unittest.TestCase ) : def testBytes( self ) : for i in range(1,2000) : s = rand.bytes( i, checkResult=1 ) self.assertEquals( len(s), i ) def testLargeBytes( self ) : n = 4096 for i in range(2000) : s = rand.bytes( n, checkResult=1 ) self.assertEquals( len(s), n ) def testPseudoBytes( self ) : for i in range(1,2000) : s = rand.pseudoBytes( i ) self.assertEquals( len(s), i ) def testLargePseudoBytes( self ) : n = 4096 for i in range(2000) : s = rand.pseudoBytes( n ) self.assertEquals( len(s), n ) if __name__ == '__main__' : unittest.main() ncrypt-0.6.4/ncrypt/test/filterprog.py0000700000175000017500000000326610512376023016052 0ustar fx5fx5import sys, os, getopt def usage( otherOptsHelp ) : progName = os.path.split(sys.argv[0])[1] if otherOptsHelp : print 'Usage: %s %s [-o outfile] [infile]' % (progName,otherOptsHelp) else : print 'Usage: %s [-o outfile] [infile]' % progName def main( callback, otherOpts='', otherOptsHelp='', longOpts=None ) : otherArgs = {} longOptsList = longOpts if longOptsList is None : longOptsList = [] try : opts, args = getopt.getopt( sys.argv[1:], 'o:'+otherOpts, longOptsList ) except getopt.GetoptError, s : print 'Error: %s' % s usage( otherOptsHelp ) return inFile = None outFile = None if len(args) > 1 : print 'Too many arguments provided' usage( otherOptsHelp ) return if len(args) == 1 : try : inFile = file( args[0], 'rb' ) except IOError : print 'Unable to open input file:', args[0] usage( otherOptsHelp ) return for o,a in opts : if o == '-o' : try : outFile = file( a, 'wb' ) except IOError : print 'Unable to open output file:', a usage( otherOptsHelp ) return else : otherArgs[o] = a if not inFile : inFile = sys.stdin if not outFile : outFile = sys.stdout callback( inFile, outFile, otherArgs ) def echoTest( inFile, outFile, args ) : while True : data = inFile.read( 1024 ) if not data : break outFile.write( data ) outFile.close() inFile.close() if __name__ == '__main__' : main( echoTest ) ncrypt-0.6.4/ncrypt/test/testrsa.py0000700000175000017500000001116610512376023015360 0ustar fx5fx5import sys, os, unittest from ncrypt import rsa, digest class RSATestCase( unittest.TestCase ) : def __init__( self, methodName='runTest' ) : self.keys = {} self.data = [] x = '' for l in range(256) : self.data.append( x ) x += chr( (l % 26) + ord('a') ) for (i,x) in enumerate(self.data) : assert i == len(x) unittest.TestCase.__init__( self, methodName ) def _genKey( self, numBits ) : k = rsa.RSAKey() k.generate( numBits ) self.assertEquals( k.size()*8, numBits ) self.assert_( k.hasPrivateKey ) return k def _getKey( self, numBits ) : if not self.keys.has_key(numBits) : self.keys[numBits] = self._genKey( numBits ) return self.keys[numBits] def _testEncrypt( self, pk, sk ) : print '' for paddingMode in [rsa.PADDING_PKCS1,rsa.PADDING_PKCS1_OAEP] : for plainText in self.data : if len(plainText) > pk.maxInputSize(paddingMode) : self.assertRaises( rsa.RSAError, pk.encrypt, plainText, paddingMode ) else : print 'pad=%d, max=%d, len(pt)=%d' % ( pk.paddingSize(paddingMode), pk.maxInputSize(paddingMode), len(plainText) ) cipherText = pk.encrypt( plainText, paddingMode ) self.assertEquals( len(cipherText), pk.size() ) plainText1 = sk.decrypt( cipherText, paddingMode ) self.assertEquals( plainText1, plainText ) def _testSign( self, pk, sk ) : print '' for algo in digest.ALGORITHMS : print algo dt = digest.DigestType( algo ) hashList = [] sigList = [] print 'signing...' for msg in self.data : d = digest.Digest(dt).digest( msg ) hashList.append( d ) sig = sk.sign( d, dt ) sigList.append( sig ) print 'verifying...' for (hash,sig) in zip(hashList,sigList) : pk.verify( sig, hash, dt ) hashList = hashList[1:] + hashList[:1] for (hash,sig) in zip(hashList,sigList) : self.assertRaises( rsa.RSAError, pk.verify, sig, hash, dt ) def _splitKey( self, k ) : pkData, skData = k.getPublicKey(), k.getPrivateKey() pk, sk = rsa.RSAKey(), rsa.RSAKey() pk.loadPublicKey( pkData ) sk.loadPrivateKey( skData ) return (pk, sk) def _testKeyEncrypt( self, numBits, split=False, blinding=False ) : k = self._getKey( numBits ) if split : pk, sk = self._splitKey( k ) else : pk, sk = k, k sk.enableBlinding( blinding ) self._testEncrypt( pk, sk ) def _testKeySign( self, numBits, split=False, blinding=False ) : k = self._getKey( numBits ) if split : pk, sk = self._splitKey( k ) else : pk, sk = k, k sk.enableBlinding( blinding ) self._testSign( pk, sk ) def testDefault( self ) : self._testKeyEncrypt( 1024 ) self._testKeySign( 1024 ) def testBlinding( self ) : self._testKeyEncrypt( 1024, blinding=True ) self._testKeySign( 1024, blinding=True ) def testSplit( self ) : self._testKeyEncrypt( 1024, split=True ) self._testKeySign( 1024, split=True ) def testSplitBlinding( self ) : self._testKeyEncrypt( 1024, split=True, blinding=True ) self._testKeySign( 1024, split=True, blinding=True ) def test_PEM_encryption( self ) : key = self._getKey( 1024 ) data = key.toPEM_PrivateKey( password='foo' ) data1 = key.toPEM_PrivateKey( password='bar' ) data2 = key.toPEM_PrivateKey() new_key = rsa.RSAKey() self.assertRaises( rsa.RSAError, lambda:new_key.fromPEM_PrivateKey(data) ) self.assertRaises( rsa.RSAError, lambda:new_key.fromPEM_PrivateKey(data,password='bar') ) new_key.fromPEM_PrivateKey( data, password='foo' ) self.failIfEqual( data, data1 ) self.failIfEqual( data, data2 ) data = key.toPEM_PrivateKey( password='foo\x00bar\x00' ) k = rsa.RSAKey() k.fromPEM_PrivateKey( data, password='foo\x00bar\x00' ) self.assertEqual( k.toPEM_PrivateKey(), key.toPEM_PrivateKey() ) if __name__ == '__main__' : unittest.main() ncrypt-0.6.4/ncrypt/test/test.py0000700000175000017500000000114410512376023014645 0ustar fx5fx5''' Unified TestSuite for PyNcrypt ''' import unittest import ncrypt.test.testcipher import ncrypt.test.testdigest import ncrypt.test.testrand import ncrypt.test.testrsa class PyNCryptTestSuite(unittest.TestSuite): test_modules = [ncrypt.test.testcipher,ncrypt.test.testdigest, ncrypt.test.testrand,ncrypt.test.testrsa] def __init__(self): unittest.TestSuite.__init__(self) self.addTests(map(unittest.defaultTestLoader.loadTestsFromModule,self.test_modules)) if __name__ == '__main__': runner = unittest.TextTestRunner() runner.run(PyNCryptTestSuite())ncrypt-0.6.4/ncrypt/test/decrypt.py0000700000175000017500000000250610512376023015343 0ustar fx5fx5from ncrypt import cipher import filterprog otherOptsHelp = '[-c ] [-m ] [--nopadding] -k ' def usage() : filterprog.usage( otherOptsHelp ) def filterMain( inFile, outFile, args ) : cipherName = args.get( '-c', 'DES-EDE3' ) modeName = args.get( '-m', 'CBC' ) fullName = '-'.join( [cipherName,modeName] ) try : cipherType = cipher.CipherType( fullName ) except cipher.CipherError : print 'Unknown cipher: %s' % fullName usage() return keyFile = args.get( '-k', 'key.file' ) try : key = file(keyFile,'rb').read() except IOError : print 'Unable to open key file: %s' % keyFile usage() return try : c = cipher.DecryptCipher( cipherType, key, None ) except cipher.CipherError, s : print 'Error: %s' % s usage() return paddingEnabled = not args.has_key('--nopadding') c.enablePadding( paddingEnabled ) while 1 : data = inFile.read( 1024 ) if not data : break data = c.update( data ) outFile.write( data ) data = c.finish() outFile.write( data ) inFile.close() outFile.close() if __name__ == '__main__' : filterprog.main( filterMain, 'c:m:k:', otherOptsHelp, ['nopadding'] ) ncrypt-0.6.4/ncrypt/test/testcipher.py0000700000175000017500000001774610512376023016057 0ustar fx5fx5import sys, os, unittest from ncrypt import cipher class CipherTestCase( unittest.TestCase ) : def __init__( self, methodName='runTest' ) : self.algos = cipher.ALGORITHMS self.modes = cipher.MODES self.cipherTypes = [] for a in self.algos : for m in self.modes : ct = cipher.CipherType( a, m ) self.cipherTypes.append( ct ) self.data = [] k = '' for l in range(100) : self.data.append( k ) k += chr( (l % 26) + ord('a') ) for (i,k) in enumerate(self.data) : assert i == len(k) unittest.TestCase.__init__( self, methodName ) def testNames( self ) : for ct in self.cipherTypes : if ct.algo() == 'DES-EDE3' and ct.mode() == 'ECB' : self.assertEquals( ct.algo(), ct.name() ) else : self.assertEquals( '-'.join([ct.algo(),ct.mode()]), ct.name() ) self.assertRaises( cipher.CipherError, cipher.CipherType, 'DES-EDE3', '' ) self.assertRaises( TypeError, cipher.CipherType, 'DES-EDE3', None ) self.assertRaises( cipher.CipherError, cipher.CipherType, 'adsfasdf', 'ECB' ) def testCipherType( self ) : dtInfo = [ (ct.name(),ct.blockSize(),ct.keyLength(),ct.ivLength()) for ct in self.cipherTypes] for ct in self.cipherTypes : bs, ivl, keyl = ct.blockSize(), ct.ivLength(), ct.keyLength() self.assert_( bs >= 1 ) self.assert_( (ivl >= 8) and (ivl <= keyl) ) if ct.mode() in 'OFB CFB'.split() : self.assertEquals( 1, bs ) else : self.assertEquals( bs, ivl ) def testError1( self ) : self.assertRaises( TypeError, cipher.Cipher, 'DES-CBC', '12345678', None, 1 ) def testError2( self ) : ct = cipher.CipherType( 'DES', 'CBC' ) self.assertRaises( TypeError, cipher.Cipher, ct, 12345678, None, 1 ) def testError3( self ) : for ct in self.cipherTypes : self.assertRaises( TypeError, cipher.EncryptCipher, ct, 1234, None ) self.assertRaises( TypeError, cipher.DecryptCipher, ct, 1234, None ) self.assertRaises( cipher.CipherError, cipher.EncryptCipher, ct, 'abcd', None ) self.assertRaises( cipher.CipherError, cipher.DecryptCipher, ct, 'abcd', None ) def testError4( self ) : for ct in self.cipherTypes : k = self.data[ ct.keyLength() ] ec = cipher.EncryptCipher( ct, k, None ) cipherText = ec.update( 'hi' ) cipherText += ec.finish() self.assertRaises( cipher.CipherError, ec.update, 'bye' ) self.assertRaises( cipher.CipherError, ec.finish ) dc = cipher.DecryptCipher( ct, k, None ) plainText = dc.update( cipherText ) plainText += dc.finish() self.assertRaises( cipher.CipherError, dc.update, plainText ) self.assertRaises( cipher.CipherError, dc.finish ) def testError5( self ) : for ct in self.cipherTypes : k = self.data[ ct.keyLength() ] for cipherText in self.data : dc = cipher.DecryptCipher( ct, k, None ) plainText = dc.update( cipherText ) if ct.blockSize() == 1 : plainText += dc.finish() self.assertEquals( len(plainText), len(cipherText) ) else : try : plainText += dc.finish() self.assert_( len(plainText) < len(cipherText) ) except cipher.CipherError : pass def _testCipher( self, useiv ) : for ct in self.cipherTypes : k = self.data[ ct.keyLength() ] if useiv : iv = self.data[ ct.ivLength() ] else : iv = None for plainText in self.data : ec = cipher.EncryptCipher( ct, k, iv ) cipherText = ec.update( plainText ) cipherText += ec.finish() self.assert_( (len(cipherText) % ct.blockSize()) == 0 ) if ct.blockSize() > 1 : self.assert_( len(cipherText) >= ct.blockSize() ) self.assert_( len(cipherText)-len(plainText) <= ct.blockSize() ) else : self.assertEquals( len(cipherText),len(plainText) ) dc = cipher.DecryptCipher( ct, k, iv ) plainText1 = dc.update( cipherText ) plainText1 += dc.finish() self.assertEquals( plainText, plainText1 ) def testCipherWithIV( self ) : self._testCipher( useiv=True ) def testCipherWithoutIV( self ) : self._testCipher( useiv=False ) def _testCipherIncremental( self, useiv ) : allPlainText = ''.join( self.data ) for ct in self.cipherTypes : k = self.data[ ct.keyLength() ] if useiv : iv = self.data[ct.ivLength()] else : iv = None ec = cipher.EncryptCipher( ct, k, iv ) cipherText = [] for x in self.data : cipherText.append( ec.update(x) ) cipherText.append( ec.finish() ) allCipherText = ''.join( cipherText ) if ct.blockSize() > 1 : self.assert_( len(allCipherText) >= ct.blockSize() ) self.assert_( len(allCipherText)-len(allPlainText) <= ct.blockSize() ) else : self.assertEquals( len(allCipherText), len(allPlainText) ) dc = cipher.DecryptCipher( ct, k, iv ) plainText = [] for x in cipherText : plainText.append( dc.update(x) ) plainText.append( dc.finish() ) self.assertEquals( ''.join(plainText), allPlainText ) def testCipherIncrementalWithIV( self ) : self._testCipherIncremental( useiv=True ) def testCipherIncrementalWithoutIV( self ) : self._testCipherIncremental( useiv=False ) def _testCipherNoPadding( self, useiv ) : for ct in self.cipherTypes : k = self.data[ ct.keyLength() ] if useiv : iv = self.data[ct.ivLength()] else : iv = None cipherTextList = [] for plainText in self.data : ec = cipher.EncryptCipher( ct, k, iv ) ec.enablePadding( False ) cipherText = ec.update( plainText ) if len(plainText) % ct.blockSize() == 0 : cipherText += ec.finish() self.assertEquals( len(cipherText), len(plainText) ) cipherTextList.append( cipherText ) else : self.assertRaises( cipher.CipherError, ec.finish ) cipherTextList.append( None ) for cipherText in cipherTextList : if cipherText is None : continue assert (len(cipherText) % ct.blockSize()) == 0 dc = cipher.DecryptCipher( ct, k, iv ) dc.enablePadding( False ) plainText = dc.update( cipherText ) plainText += dc.finish() self.assertEquals( plainText, self.data[len(cipherText)] ) for cipherText in self.data : if len(cipherText) % ct.blockSize() != 0 : continue dc = cipher.DecryptCipher( ct, k, iv ) dc.enablePadding( False ) plainText = dc.update( cipherText ) plainText += dc.finish() self.assertEquals( len(cipherText), len(plainText) ) def testCipherNoPaddingWithIV( self ) : self._testCipherNoPadding( useiv=True ) def testCipherNoPaddingWithoutIV( self ) : self._testCipherNoPadding( useiv=False ) if __name__ == '__main__' : unittest.main() ncrypt-0.6.4/ncrypt/test/md5hash.py0000700000175000017500000000055010512376023015217 0ustar fx5fx5import sys from ncrypt import digest def main() : if len(sys.argv) != 2 : print 'usage: md5hash ' return fileName = sys.argv[1] dt = digest.DigestType( 'MD5' ) d = digest.Digest( dt ) hash = d.digest( file(sys.argv[1],'rb').read() ) print hash.encode('hex') if __name__ == '__main__' : main() ncrypt-0.6.4/ncrypt/test/hash.py0000700000175000017500000000115610512376023014614 0ustar fx5fx5from ncrypt import digest import filterprog def filterMain( inFile, outFile, args ) : digestName = args.get( '-h', 'MD5' ) try : digestType = digest.DigestType( digestName ) except digest.DigestError : print 'Unknown digest: %s' % digestName return d = digest.Digest( digestType ) while 1 : data = inFile.read( 1024 ) if not data : break d.update( data ) print>>outFile, d.digest().encode('hex') inFile.close() outFile.close() if __name__ == '__main__' : filterprog.main( filterMain, 'h:', '[-h ]' ) ncrypt-0.6.4/ncrypt/test/testdigest.py0000700000175000017500000000503210512376023016045 0ustar fx5fx5import sys, os, unittest, md5, sha from ncrypt import digest md5Type = digest.DigestType( 'MD5' ) sha1Type = digest.DigestType( 'SHA1' ) def doMD5( data ) : return digest.Digest(md5Type).digest( data ) def doSHA1( data ) : return digest.Digest(sha1Type).digest( data ) class DigestTestCase( unittest.TestCase ) : def setUp( self ) : self.dtList = [digest.DigestType(algo) for algo in digest.ALGORITHMS] self.dtMap = dict( zip(digest.ALGORITHMS,self.dtList) ) def testMD5( self ) : self.assertEquals( doMD5('hi'), md5.md5('hi').digest() ) def testSHA1( self ) : self.assertEquals( doSHA1('hi'), sha.sha('hi').digest() ) def testNames( self ) : for (k,v) in self.dtMap.items() : self.assertEquals( k, v.name() ) def testInfo( self ) : dtInfo = [(dt.name(),dt.blockSize(),dt.size()*8,dt.nid()) for dt in self.dtList] def testDigests( self ) : s = '' for i in range(1000) : for dt in self.dtList : d = digest.Digest(dt) dv = d.digest(s) self.assertEquals( len(dv), dt.size() ) if dt.name() == 'MD5' : self.assertEquals( dv, md5.md5(s).digest() ) elif dt.name() == 'SHA1' : self.assertEquals( dv, sha.sha(s).digest() ) s += chr(i%256) def testFullDigests( self ) : s = '' fullDigests = [digest.Digest(dt) for dt in self.dtList] md5Digest = md5.new() shaDigest = sha.new() for i in range(1000) : for d in fullDigests : d.update( s ) md5Digest.update( s ) shaDigest.update( s ) s += chr(i%256) fullDigestValues = [d.digest() for d in fullDigests] for (i,d) in enumerate(fullDigests) : self.assertEquals( len(fullDigestValues[i]), d.digestType.size() ) if d.digestType.name() == 'MD5' : self.assertEquals( fullDigestValues[i], md5Digest.digest() ) elif d.digestType.name() == 'SHA1' : self.assertEquals( fullDigestValues[i], shaDigest.digest() ) def testErrors( self ) : self.assertRaises( digest.DigestError, digest.DigestType, 'blah' ) self.assertRaises( TypeError, digest.Digest, None ) d = digest.Digest( sha1Type ) d.update( '' ) d.digest() self.assertRaises( digest.DigestError, d.digest ) if __name__ == '__main__' : unittest.main() ncrypt-0.6.4/ncrypt/test/encrypt.py0000700000175000017500000000250610512376023015355 0ustar fx5fx5from ncrypt import cipher import filterprog otherOptsHelp = '[-c ] [-m ] [--nopadding] -k ' def usage() : filterprog.usage( otherOptsHelp ) def filterMain( inFile, outFile, args ) : cipherName = args.get( '-c', 'DES-EDE3' ) modeName = args.get( '-m', 'CBC' ) fullName = '-'.join( [cipherName,modeName] ) try : cipherType = cipher.CipherType( fullName ) except cipher.CipherError : print 'Unknown cipher: %s' % fullName usage() return keyFile = args.get( '-k', 'key.file' ) try : key = file(keyFile,'rb').read() except IOError : print 'Unable to open key file: %s' % keyFile usage() return try : c = cipher.EncryptCipher( cipherType, key, None ) except cipher.CipherError, s : print 'Error: %s' % s usage() return paddingEnabled = not args.has_key('--nopadding') c.enablePadding( paddingEnabled ) while 1 : data = inFile.read( 1024 ) if not data : break data = c.update( data ) outFile.write( data ) data = c.finish() outFile.write( data ) inFile.close() outFile.close() if __name__ == '__main__' : filterprog.main( filterMain, 'c:m:k:', otherOptsHelp, ['nopadding'] ) ncrypt-0.6.4/ncrypt/test/__init__.py0000700000175000017500000000003410512376023015422 0ustar fx5fx5''' Tests for PyNCrypt '''ncrypt-0.6.4/ncrypt/test/key.file0000700000175000017500000000004010512376023014737 0ustar fx5fx501234567012345670123456701234567ncrypt-0.6.4/ncrypt/test/key16.file0000700000175000017500000000002010512376023015104 0ustar fx5fx50123456701234567ncrypt-0.6.4/ncrypt/rand.py0000700000175000017500000000003210512376023013626 0ustar fx5fx5from _ncrypt.rand import *ncrypt-0.6.4/ncrypt/dh.py0000700000175000017500000000003210512376023013275 0ustar fx5fx5from _ncrypt.dh import * ncrypt-0.6.4/ncrypt/bignum.py0000700000175000017500000000003410512376023014165 0ustar fx5fx5from _ncrypt.bignum import *ncrypt-0.6.4/ncrypt/digest.py0000700000175000017500000000003610512376023014165 0ustar fx5fx5from _ncrypt.digest import * ncrypt-0.6.4/ncrypt/x509.py0000700000175000017500000000003210512376023013407 0ustar fx5fx5from _ncrypt.x509 import *ncrypt-0.6.4/ncrypt/err.py0000700000175000017500000000003310512376023013473 0ustar fx5fx5from _ncrypt.err import * ncrypt-0.6.4/ncrypt/rsa.py0000700000175000017500000000003110512376023013466 0ustar fx5fx5from _ncrypt.rsa import *ncrypt-0.6.4/ncrypt/ssl.py0000700000175000017500000000003110512376023013502 0ustar fx5fx5from _ncrypt.ssl import *ncrypt-0.6.4/ncrypt/__init__.py0000700000175000017500000000026710512376023014453 0ustar fx5fx5''' PyNCrypt Module ''' #~ from _ncrypt import err,digest,cipher,rand,bignum,rsa,x509,ssl __all__ = [ 'bignum', 'cipher', 'digest', 'err', 'rand', 'dh', 'rsa', 'ssl', 'x509' ] ncrypt-0.6.4/ncrypt/cipher.py0000700000175000017500000000003410512376023014156 0ustar fx5fx5from _ncrypt.cipher import *ncrypt-0.6.4/utils.c0000700000175000017500000000377510512376024012337 0ustar fx5fx5#include #include "utils.h" static unsigned char hexTab[] = "0123456789abcdef"; void HexEncode( const void *src, int srcLen, void *dest, int destLen ) { const unsigned char *a = (const unsigned char *)src; unsigned char *b = (unsigned char *)dest; assert( destLen >= 2*srcLen ); for ( ; srcLen; --srcLen ) { *(b++) = hexTab[(*a) >> 4]; *(b++) = hexTab[(*a) & 0xF]; ++a; } } #define HEX2CHAR(c) \ (((c >= '0') && (c <= '9')) ? (c-'0') : \ ((c >= 'a') && (c <= 'f')) ? (c+10-'a') : \ ((c >= 'A') && (c <= 'F')) ? (c+10-'A') : -1) // srcLen must be even // destLen must be >= srcLen/2 int HexDecode( const void *src, int srcLen, void *dest, int destLen ) { const unsigned char *a = (const unsigned char *)src; unsigned char *b = (unsigned char *)dest; int x; assert( srcLen % 2 == 0 ); assert( destLen >= srcLen/2 ); for ( ; srcLen; srcLen-=2 ) { x = (HEX2CHAR(a[0]) << 4) | HEX2CHAR(a[1]); if ( x >> 8 ) return -1; *(b++) = (unsigned char)x; a += 2; } return 0; } EVP_CIPHER_CTX *AllocCipherContext() { return (EVP_CIPHER_CTX *)OPENSSL_malloc( sizeof(EVP_CIPHER_CTX) ); } void FreeCipherContext( EVP_CIPHER_CTX *ptr ) { OPENSSL_free( ptr ); } PyObject *BNToLong( BIGNUM *bn ) { char *s = BN_bn2dec( bn ); PyObject *x = PyLong_FromString( s, NULL, 10 ); OPENSSL_free( s ); return x; } int LongToBN( PyObject *x, BIGNUM *bn ) { PyObject *s; int result; if ( (!PyLong_Check(x)) && (!PyInt_Check(x)) ) { return -1; } s = PyObject_Str( x ); result = BN_dec2bn( &bn, PyString_AsString(s) ); Py_DECREF( s ); if ( result == 0 ) return -1; return 0; } PyObject *GetBIOData( BIO *b ) { char *p; long size = BIO_get_mem_data( b, &p ); if ( size < 0 ) { Py_INCREF( Py_None ); return Py_None; } return PyString_FromStringAndSize( p, size ); } ncrypt-0.6.4/utils.h0000700000175000017500000000113010512376024012323 0ustar fx5fx5#ifndef _ncrypt_utils_h #define _ncrypt_utils_h #include #include #include #include // destLen must be >= 2*srcLen void HexEncode( const void *src, int srcLen, void *dest, int destLen ); // srcLen must be even // destLen must be >= srcLen/2 int HexDecode( const void *src, int srcLen, void *dest, int destLen ); EVP_CIPHER_CTX *AllocCipherContext(); void FreeCipherContext( EVP_CIPHER_CTX *ptr ); PyObject *BNToLong( BIGNUM *bn ); int LongToBN( PyObject *x, BIGNUM *bn ); PyObject *GetBIOData( BIO *b ); #endif ncrypt-0.6.4/setup.py0000700000175000017500000000667710512376024012551 0ustar fx5fx5'''PyNCrypt: Yet another OpenSSL wrapper for python ''' classifiers = """\ Development Status :: 3 - Alpha Intended Audience :: Developers License :: OSI Approved :: GNU General Public License (GPL) Programming Language :: Python Programming Language :: C Topic :: Software Development :: Libraries :: Python Modules Topic :: Security :: Cryptography Operating System :: Microsoft :: Windows """ try: from setuptools import setup except: from distutils.core import setup from distutils.core import Extension from distutils.command.build_ext import build_ext from distutils.command.clean import clean from distutils.sysconfig import get_python_inc,get_python_lib from distutils import log from Pyrex.Distutils import build_ext as pyrex_build_ext import os,os.path,sys,re class custom_clean(clean): def run(self): clean.run(self) log.info("removing the pyrex generated c files") if not self.dry_run: for extn in self.distribution.ext_modules: for srcfile in [x for x in extn.sources if x.endswith('pyx')]: filename = srcfile[:-4]+'.c' try: os.remove(srcfile[:-4]+'.c') log.info("removing '%s'", filename) except OSError: pass include_dirs = [] libraries_dirs = [] libraries = [] defines = [] def scan_argv(argname,default=None): for arg in sys.argv: if len(arg) > len(argname) and arg[:len(argname)]==argname: sys.argv.remove(arg) return arg[len(argname):] return default def scan_argv_dir(argname,default=None): ret = scan_argv(argname,default) if(ret != default and ret is not None): return re.sub(r'^(\'|\")?([\W\w]*)(?(1)(\'|\"))$',r'\2',ret) return ret if sys.version_info < (2,4): raise RuntimeError,"PyNCrypt requires Python 2.4 or greater" if sys.platform == "win32": OPENSSL_DIR = scan_argv_dir('--openssl-dir=',r'C:\openssl') include_dirs.append(os.path.join(OPENSSL_DIR,'include')) libraries_dirs.append(os.path.join(OPENSSL_DIR,'lib')) libraries.extend(['libeay32', 'ssleay32']) libraries.extend(['gdi32','user32','Ws2_32','Advapi32']) defines.append(('WIN32',None)) else: libraries.extend( ['ssl','crypto'] ) doclines = __doc__.split("\n") include_dirs.append(get_python_inc(plat_specific=1)) setup(name='ncrypt', classifiers = classifiers, version='0.6.4', description='Yet another OpenSSL wrapper for python', author='K.S Sreeram', author_email='sreeram@tachyontech.net', maintainer='K.S Sreeram, Jeethu Rao', maintainer_email='sreeram@tachyontech.net, jeethu@tachyontech.net', url='http://www.tachyontech.net', packages = ['ncrypt','ncrypt.test','ncrypt.test.ssl'], package_dir = {'ncrypt':'ncrypt','test': 'ncrypt.test'}, ext_modules=[Extension('_ncrypt', ['ncrypt.c','utils.c', 'ncrypt_bignum.pyx','ncrypt_cipher.pyx','ncrypt_digest.pyx', 'ncrypt_err.pyx','ncrypt_rand.pyx','ncrypt_dh.pyx', 'ncrypt_rsa.pyx','ncrypt_ssl.pyx','ncrypt_x509.pyx', # PXD Files #~ 'ncrypt_digest.pxd','ncrypt_rsa.pxd','ncrypt_x509.pxd' ], include_dirs=include_dirs,library_dirs=libraries_dirs,libraries=libraries,define_macros=defines)], cmdclass = {'build_ext': pyrex_build_ext,'clean':custom_clean} ) ncrypt-0.6.4/website/0000700000175000017500000000000010512376025012457 5ustar fx5fx5ncrypt-0.6.4/website/ncrypt-0.6.4.ebuild0000700000175000017500000000057210512376024015635 0ustar fx5fx5inherit distutils DESCRIPTION="NCrypt is a python wrapper for OpenSSL built using Pyrex." HOMEPAGE="http://tachyon.in/ncrypt/" SRC_URI="http://tachyon.in/ncrypt/${P}.tar.gz" LICENSE="MIT" SLOT="0" KEYWORDS="~x86" IUSE="" PYTHON_MODNAME="ncrypt" DEPEND="dev-python/pyrex dev-libs/openssl" src_compile() { python setup.py build } src_install() { distutils_src_install } ncrypt-0.6.4/website/usage.txt0000700000175000017500000002021310512376024014324 0ustar fx5fx5NCrypt - Usage Examples ======================= Examples are provided for the following modules: - ncrypt.digest_ - *hash algorithms* - `compute hash`_ - `compute hash for large data`_ - ncrypt.cipher_ - *symmetric key encryption/decryption* - `show cipher information`_ - `encrypt/decrypt`_ - `encrypt/decrypt large data`_ - ncrypt.rsa_ - *public key crypto using RSA* - `generate RSA key`_ - `convert to PEM`_ - `encrypt with public key`_ - `decrypt with private key`_ - `sign with private key`_ - `verify signature with public key`_ - ncrypt.dh_ - *diffie-hellman key exchange* - ncrypt.x509_ - *create/manipulate X.509 certificates used in SSL* - ncrypt.ssl_ - *SSL/TLS network protocol* ncrypt.digest ------------- - `compute hash`_ - `compute hash for large data`_ _`compute hash`:: from ncrypt.digest import DigestType, Digest sha256Type = DigestType( 'SHA256' ) def calc_sha256( data ) : d = Digest( sha256Type ) return d.digest( data ) _`compute hash for large data`:: md5Type = DigestType( 'MD5' ) def calc_md5( file_obj ) : d = Digest( md5Type ) while 1 : data = file_obj.read( 65536 ) if not data : break d.update( data ) return d.digest() ncrypt.cipher ------------- - `show cipher information`_ - `encrypt/decrypt`_ - `encrypt/decrypt large data`_ _`show cipher information`:: from ncrypt.cipher import CipherType def show_info( algo, mode ) : ct = CipherType( algo, mode ) print 'name = %s' % ct.name() print 'blockSize = %d bits' % (ct.blockSize()*8) print 'keyLength = %d bits' % (ct.keyLength()*8) print 'ivLength = %d bits' % (ct.ivLength()*8) >>> show_info( 'AES-128', 'CBC' ) name = AES-128-CBC blockSize = 128 bits keyLength = 128 bits ivLength = 128 bits >>> show_info( 'AES-256', 'CBC' ) name = AES-256-CBC blockSize = 128 bits keyLength = 256 bits ivLength = 128 bits >>> show_info( 'BF', 'CBC' ) name = BF-CBC blockSize = 64 bits keyLength = 128 bits ivLength = 64 bits _`encrypt/decrypt`:: from ncrypt.cipher import EncryptCipher, DecryptCipher def do_encrypt( cipherType, key, iv, plain_text ) : enc = EncryptCipher( cipherType, key, iv ) cipher_text = enc.finish( plain_text ) return cipher_text def do_decrypt( cipherType, key, iv, cipher_text ) : dec = DecryptCipher( cipherType, key, iv ) plain_text = dec.finish( cipher_text ) return plain_text >>> from ncrypt.cipher import CipherType >>> ct = CipherType( 'AES-128', 'CBC' ) >>> key = 'a' * ct.keyLength() # dummy key >>> iv = 'b' * ct.ivLength() # dummy initial-vector >>> plain_text = 'my secret' >>> >>> enc = EncryptCipher( ct, key, iv ) >>> cipher_text = enc.finish( plain_text ) >>> cipher_text '\xee\xef\xa6\xa2b\xa7\xbd\x17f\xf7HI\xbcd\xb9c' >>> >>> dec = DecryptCipher( ct, key, iv ) >>> new_plain_text = dec.finish( cipher_text ) >>> new_plain_text 'my secret' # when trying to decrypt invalid cipher text # CipherError is thrown >>> dec = DecryptCipher( ct, key, iv ) >>> dec.finish( 'blah' ) ncrypt_cipher.CipherError: error in cipher operation (wrong final block length) _`encrypt/decrypt large data`:: from ncrypt.cipher import EncryptCipher, DecryptCipher def encrypt_file( cipherType, key, iv, in_file, out_file ) : enc = EncryptCipher( cipherType, key, iv ) while 1 : data = in_file.read( 8192 ) if not data : break out_data = enc.update( data ) out_file.write( out_data ) final_data = enc.finish() out_file.write( final_data ) def decrypt_file( cipherType, key, iv, in_file, out_file ) : dec = DecryptCipher( cipherType, key, iv ) while 1 : data = in_file.read( 8192 ) if not data : break out_data = dec.update( data ) out_file.write( out_data ) final_data = dec.finish() out_file.write( final_data ) ncrypt.rsa ---------- - `generate RSA key`_ - `convert to PEM`_ - `encrypt with public key`_ - `decrypt with private key`_ - `sign with private key`_ - `verify signature with public key`_ _`generate RSA key`:: >>> from ncrypt.rsa import RSAKey >>> >>> key1 = RSAKey() >>> key1.generate( bits=1024 ) >>> key2 = RSAKey() >>> key2.generate( bits=2048 ) _`convert to PEM`:: >>> public_key_data = key1.toPEM_PublicKey() >>> print public_key_data -----BEGIN RSA PUBLIC KEY----- MIGHAoGBAMRU0a9uJviPv845ksWO4LLnxzGNhaUgAEXv0tU+q48qaPFiRQ2h0ygJ 0AHgSCGjslJumbZKBOaWWTChAwrdqH6bEFN10jPk4n4LlzHR/qayy68QQjQtzI9m GqejD6bK1FZKw7+Weg9AiXkLKFSAtPDVdUz+IZjwO/4pGDXaLE2ZAgEF -----END RSA PUBLIC KEY----- >>> private_key_data = key1.toPEM_PrivateKey() >>> print private_key_data -----BEGIN RSA PRIVATE KEY----- MIICWwIBAAKBgQDEVNGvbib4j7/OOZLFjuCy58cxjYWlIABF79LVPquPKmjxYkUN odMoCdAB4Egho7JSbpm2SgTmllkwoQMK3ah+mxBTddIz5OJ+C5cx0f6mssuvEEI0 LcyPZhqnow+mytRWSsO/lnoPQIl5CyhUgLTw1XVM/iGY8Dv+KRg12ixNmQIBBQKB gQCdEKe/i1Jgcv/YLg8Eck1b7J9a154dszNrJkJEMiLY7rpatQQK59wgB9mbGdNO HI6oWHr4Ozce3q3AgM875IbKRz/gO80bvb8xipcYjFj9XpRlt2A32Y+oJhprVGCf e/VWjtJGS11lFvfqQ095kKuis+6eEoCeikIlngqLmJ9FHQJBAPQYdVjCprsqMaJG AdE4mousFb4D27MQWnF20LIlrhh2vDo/ioQcaPE1qwS4l4E/eyc1P2/I3sxmEmPw SIdd14MCQQDN6AXSTyp8iU58FFFRVs9w5hotBhKqyKLFAtDHcTFXau3d/V00KOfy nekyTGUKnupNVcf3N/P3Azy/mr7UB1+zAkEAknUTNUGXPRlQ+vbN4+7DIJpzcgJQ nqNpd0dKBH0CDq2kIvLstaqlXYaZz6H0gL+wSrmMdkVSeqOkolz4UThOGwJAUlzP IOx3ZQO4/m6G7VXsk489q5wHd4N0Ts3tHJOtVirFi/7yFN0plD8qFB6O0QxduIi2 YuMuYs4YTKRMVM+/4QJAeMNAGhp4A8Cy5rg8M23YRVIaGJZVC0DKQZLptBfSiqtW iZmAdozBoNU+KEn8CvIB7+NbYRb16JqxRrmjaFlkjg== -----END RSA PRIVATE KEY----- _`encrypt with public key`:: >>> key = RSAKey() >>> key.fromPEM_PublicKey( public_key_data ) >>> >>> key.maxInputSize() 86 >>> plain_text = 'my secret' >>> len(plain_text) 9 >>> cipher_text = key.encrypt( plain_text ) >>> cipher_text '\x054\x0c\xf4)7P\x99\x85\x91\xb7\xdad\xa4\x9d\xe6s\xbd\xfd\x1f\xd4\xee\x03\x04x \xdc\xa7Ob\x18\xa7[\xaey\x01\xf1\xb1\xb5\xa6\xec\x89\xac\xf3\xa4x\xfdy\xc8\x98\x f8\xcaj\xb3x\xe3\xab<-\xca@\xe7\xbc\xef\xe8\xbb<\x1dS\x9e>> key = RSAKey() >>> key.fromPEM_PrivateKey( private_key_data ) >>> >>> new_plain_text = key.decrypt( cipher_text ) >>> new_plain_text 'my secret' _`sign with private key`:: >>> from ncrypt.digest import Digest, DigestType >>> >>> key = RSAKey() >>> key.fromPEM_PrivateKey( private_key_data ) >>> >>> data = 'data to be signed' >>> >>> digestType = DigestType( 'SHA1' ) >>> digest = Digest( digestType ).digest( data ) >>> >>> signature = key.sign( digest, digestType ) >>> signature '2\xbf\xe6\x97@\xa2vx\xb4\xb5\x99\xa7w\xd6\xb7\x8fs\xf6\xda\x08\xd2\x81\xa8\xf0\ x80=9\xc7\xe2\x0b\xb1\x13\\)cc\xafx\x02\xf8\x95\x00\xdc\xaa\x06\x96\x1e6\xb8N\x8 8\xfb\xe7\xc5\xfa\x83\xf4\x81}"uK[\xbd\x03\x15\x9cE\xb0\xa1\x9cZ\x888l\x8b\x1dn( \t\x8e(\x0b\r\xa4q\xd9\x14\xb1\x9c.+"\xa7\xec\x00,\x8b6\x9a\xc9E\xdd\xb3P\x16\xd 1\xc5\x89M\xa0\x0f\x8fP\xed\x14\xa3l\xad\xd2U\xd2z\x03\xaa\x18\xf7\xbd' _`verify signature with public key`:: >>> key = RSAKey() >>> key.fromPEM_PublicKey( public_key_data ) >>> >>> key.verify( signature, digest, digestType ) # throws RSAError if verification failed ncrypt.dh --------- :: Coming soon... ncrypt.x509 ----------- :: Coming soon... ncrypt.ssl ---------- :: Coming soon... ncrypt-0.6.4/website/style.css0000700000175000017500000000113010512376024014326 0ustar fx5fx5body,p,table,li,h1,h2,h3,hr { font-family: Verdana, Arial, 'Sans Serif'; font-size: 95% } strong { font-family: Verdana, Arial, 'Sans Serif'; font-size: 85% } h1.title { font-size: 110% } body { #ffffff; } a:link {COLOR: navy;} a:visited {COLOR: firebrick;} a:active {COLOR: seashell;} a:hover {COLOR: navy;} div { margin:0; padding:0 .25em 0 0; } pre.literal-block, pre.doctest-block { margin-left: 2em ; margin-right: 2em ; background-color: #ffffff; border: thin black solid; padding: 5px; } /* stylesheet adapted from http://twill.idyll.org */ ncrypt-0.6.4/website/index.html0000700000175000017500000000525710512376025014470 0ustar fx5fx5 NCrypt

NCrypt

NCrypt is a python wrapper for OpenSSL built using Pyrex.

Features

  • hash algorithms (md5, sha1, sha256, sha512 etc.)
  • symmetric encryption algorithms (aes256, aes128, 3des, blowfish etc.)
  • public key crypto with RSA
  • diffie-hellman key exchange
  • create/manipulate X.509 certificates
  • SSL/TLS network protocol
  • MIT License

Download

To compile from source you'll need OpenSSL and Pyrex installed.

Warning: The Pyrex generated code generates a HUGE number of compiler warnings.

Linux:

python setup.py build
python setup.py install

Win32:

python setup.py --openssl-dir=c:\openssl build
python setup.py install

Documentation

Usage examples are available here.

Mailing List

A mailing list has been setup at ncrypt-users@tachyon.in. Go here to subscribe. The list archives are available here.

ncrypt-0.6.4/website/index.txt0000700000175000017500000000256210512376024014336 0ustar fx5fx5====== NCrypt ====== NCrypt is a python wrapper for OpenSSL built using `Pyrex `__. Features -------- - hash algorithms (*md5, sha1, sha256, sha512 etc.*) - symmetric encryption algorithms (*aes256, aes128, 3des, blowfish etc.*) - public key crypto with RSA - diffie-hellman key exchange - create/manipulate X.509 certificates - SSL/TLS network protocol - MIT License Download -------- - `ncrypt-0.6.4.tar.gz `__ - `ncrypt-0.6.4.zip `__ - `ncrypt-0.6.4.win32-py2.4.exe `__ (with OpenSSL 0.9.8d statically linked) - `ncrypt-0.6.4.ebuild `__ (Gentoo Ebuild) To compile from source you'll need OpenSSL and Pyrex installed. Warning: The Pyrex generated code generates a HUGE number of compiler warnings. Linux:: python setup.py build python setup.py install Win32:: python setup.py --openssl-dir=c:\openssl build python setup.py install Documentation ------------- Usage examples are available `here `__. Mailing List ------------ A mailing list has been setup at ncrypt-users@tachyon.in. Go `here `__ to subscribe. The list archives are available `here `__. ncrypt-0.6.4/website/docutils.conf0000700000175000017500000000010310512376024015150 0ustar fx5fx5 [html4css1 writer] stylesheet: style.css embed-stylesheet: no ncrypt-0.6.4/website/usage.html0000700000175000017500000003007010512376025014454 0ustar fx5fx5 NCrypt - Usage Examples

NCrypt - Usage Examples

Examples are provided for the following modules:

ncrypt.digest

compute hash:

from ncrypt.digest import DigestType, Digest

sha256Type = DigestType( 'SHA256' )

def calc_sha256( data ) :
    d = Digest( sha256Type )
    return d.digest( data )

compute hash for large data:

md5Type = DigestType( 'MD5' )

def calc_md5( file_obj ) :
    d = Digest( md5Type )
    while 1 :
        data = file_obj.read( 65536 )
        if not data : break
        d.update( data )
    return d.digest()

ncrypt.cipher

show cipher information:

from ncrypt.cipher import CipherType

def show_info( algo, mode ) :
    ct = CipherType( algo, mode )
    print 'name = %s' % ct.name()
    print 'blockSize = %d bits' % (ct.blockSize()*8)
    print 'keyLength = %d bits' % (ct.keyLength()*8)
    print 'ivLength = %d bits' % (ct.ivLength()*8)

>>> show_info( 'AES-128', 'CBC' )
name = AES-128-CBC
blockSize = 128 bits
keyLength = 128 bits
ivLength = 128 bits

>>> show_info( 'AES-256', 'CBC' )
name = AES-256-CBC
blockSize = 128 bits
keyLength = 256 bits
ivLength = 128 bits

>>> show_info( 'BF', 'CBC' )
name = BF-CBC
blockSize = 64 bits
keyLength = 128 bits
ivLength = 64 bits

encrypt/decrypt:

from ncrypt.cipher import EncryptCipher, DecryptCipher

def do_encrypt( cipherType, key, iv, plain_text ) :
    enc = EncryptCipher( cipherType, key, iv )
    cipher_text = enc.finish( plain_text )
    return cipher_text

def do_decrypt( cipherType, key, iv, cipher_text ) :
    dec = DecryptCipher( cipherType, key, iv )
    plain_text = dec.finish( cipher_text )
    return plain_text

>>> from ncrypt.cipher import CipherType
>>> ct = CipherType( 'AES-128', 'CBC' )
>>> key = 'a' * ct.keyLength()   # dummy key
>>> iv = 'b' * ct.ivLength()     # dummy initial-vector
>>> plain_text = 'my secret'
>>>
>>> enc = EncryptCipher( ct, key, iv )
>>> cipher_text = enc.finish( plain_text )
>>> cipher_text
'\xee\xef\xa6\xa2b\xa7\xbd\x17f\xf7HI\xbcd\xb9c'
>>>
>>> dec = DecryptCipher( ct, key, iv )
>>> new_plain_text = dec.finish( cipher_text )
>>> new_plain_text
'my secret'

# when trying to decrypt invalid cipher text
# CipherError is thrown

>>> dec = DecryptCipher( ct, key, iv )
>>> dec.finish( 'blah' )
ncrypt_cipher.CipherError: error in cipher operation (wrong final block length)

encrypt/decrypt large data:

from ncrypt.cipher import EncryptCipher, DecryptCipher

def encrypt_file( cipherType, key, iv, in_file, out_file ) :
    enc = EncryptCipher( cipherType, key, iv )
    while 1 :
        data = in_file.read( 8192 )
        if not data : break
        out_data = enc.update( data )
        out_file.write( out_data )
    final_data = enc.finish()
    out_file.write( final_data )

def decrypt_file( cipherType, key, iv, in_file, out_file ) :
    dec = DecryptCipher( cipherType, key, iv )
    while 1 :
        data = in_file.read( 8192 )
        if not data : break
        out_data = dec.update( data )
        out_file.write( out_data )
    final_data = dec.finish()
    out_file.write( final_data )

ncrypt.rsa

generate RSA key:

>>> from ncrypt.rsa import RSAKey
>>>
>>> key1 = RSAKey()
>>> key1.generate( bits=1024 )

>>> key2 = RSAKey()
>>> key2.generate( bits=2048 )

convert to PEM:

>>> public_key_data = key1.toPEM_PublicKey()
>>> print public_key_data
-----BEGIN RSA PUBLIC KEY-----
MIGHAoGBAMRU0a9uJviPv845ksWO4LLnxzGNhaUgAEXv0tU+q48qaPFiRQ2h0ygJ
0AHgSCGjslJumbZKBOaWWTChAwrdqH6bEFN10jPk4n4LlzHR/qayy68QQjQtzI9m
GqejD6bK1FZKw7+Weg9AiXkLKFSAtPDVdUz+IZjwO/4pGDXaLE2ZAgEF
-----END RSA PUBLIC KEY-----

>>> private_key_data = key1.toPEM_PrivateKey()
>>> print private_key_data
-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQDEVNGvbib4j7/OOZLFjuCy58cxjYWlIABF79LVPquPKmjxYkUN
odMoCdAB4Egho7JSbpm2SgTmllkwoQMK3ah+mxBTddIz5OJ+C5cx0f6mssuvEEI0
LcyPZhqnow+mytRWSsO/lnoPQIl5CyhUgLTw1XVM/iGY8Dv+KRg12ixNmQIBBQKB
gQCdEKe/i1Jgcv/YLg8Eck1b7J9a154dszNrJkJEMiLY7rpatQQK59wgB9mbGdNO
HI6oWHr4Ozce3q3AgM875IbKRz/gO80bvb8xipcYjFj9XpRlt2A32Y+oJhprVGCf
e/VWjtJGS11lFvfqQ095kKuis+6eEoCeikIlngqLmJ9FHQJBAPQYdVjCprsqMaJG
AdE4mousFb4D27MQWnF20LIlrhh2vDo/ioQcaPE1qwS4l4E/eyc1P2/I3sxmEmPw
SIdd14MCQQDN6AXSTyp8iU58FFFRVs9w5hotBhKqyKLFAtDHcTFXau3d/V00KOfy
nekyTGUKnupNVcf3N/P3Azy/mr7UB1+zAkEAknUTNUGXPRlQ+vbN4+7DIJpzcgJQ
nqNpd0dKBH0CDq2kIvLstaqlXYaZz6H0gL+wSrmMdkVSeqOkolz4UThOGwJAUlzP
IOx3ZQO4/m6G7VXsk489q5wHd4N0Ts3tHJOtVirFi/7yFN0plD8qFB6O0QxduIi2
YuMuYs4YTKRMVM+/4QJAeMNAGhp4A8Cy5rg8M23YRVIaGJZVC0DKQZLptBfSiqtW
iZmAdozBoNU+KEn8CvIB7+NbYRb16JqxRrmjaFlkjg==
-----END RSA PRIVATE KEY-----

encrypt with public key:

>>> key = RSAKey()
>>> key.fromPEM_PublicKey( public_key_data )
>>>
>>> key.maxInputSize()
86
>>> plain_text = 'my secret'
>>> len(plain_text)
9
>>> cipher_text = key.encrypt( plain_text )
>>> cipher_text
'\x054\x0c\xf4)7P\x99\x85\x91\xb7\xdad\xa4\x9d\xe6s\xbd\xfd\x1f\xd4\xee\x03\x04x
\xdc\xa7Ob\x18\xa7[\xaey\x01\xf1\xb1\xb5\xa6\xec\x89\xac\xf3\xa4x\xfdy\xc8\x98\x
f8\xcaj\xb3x\xe3\xab<-\xca@\xe7\xbc\xef\xe8\xbb<\x1dS\x9e<y\xa7\xe9\x81`%\xce\xa
5\xa98\x93\xe6O\xc6EQ\x18\xc4\x87\x84b\xf5\x0fU%\xda\xc7\x0c?\xb8C\xcaiAx$\x11A\
x94\x14\x175=\xd02\xd6\x08\x18d\x8aq\t\xeb</\xd6\x1c\xb1'

decrypt with private key:

>>> key = RSAKey()
>>> key.fromPEM_PrivateKey( private_key_data )
>>>
>>> new_plain_text = key.decrypt( cipher_text )
>>> new_plain_text
'my secret'

sign with private key:

>>> from ncrypt.digest import Digest, DigestType
>>>
>>> key = RSAKey()
>>> key.fromPEM_PrivateKey( private_key_data )
>>>
>>> data = 'data to be signed'
>>>
>>> digestType = DigestType( 'SHA1' )
>>> digest = Digest( digestType ).digest( data )
>>>
>>> signature = key.sign( digest, digestType )
>>> signature
'2\xbf\xe6\x97@\xa2vx\xb4\xb5\x99\xa7w\xd6\xb7\x8fs\xf6\xda\x08\xd2\x81\xa8\xf0\
x80=9\xc7\xe2\x0b\xb1\x13\\)cc\xafx\x02\xf8\x95\x00\xdc\xaa\x06\x96\x1e6\xb8N\x8
8\xfb\xe7\xc5\xfa\x83\xf4\x81}"uK[\xbd\x03\x15\x9cE\xb0\xa1\x9cZ\x888l\x8b\x1dn(
\t\x8e(\x0b\r\xa4q\xd9\x14\xb1\x9c.+"\xa7\xec\x00,\x8b6\x9a\xc9E\xdd\xb3P\x16\xd
1\xc5\x89M\xa0\x0f\x8fP\xed\x14\xa3l\xad\xd2U\xd2z\x03\xaa\x18\xf7\xbd'

verify signature with public key:

>>> key = RSAKey()
>>> key.fromPEM_PublicKey( public_key_data )
>>>
>>> key.verify( signature, digest, digestType )
# throws RSAError if verification failed

ncrypt.dh

Coming soon...

ncrypt.x509

Coming soon...

ncrypt.ssl

Coming soon...
ncrypt-0.6.4/ncrypt_rand.pyx0000700000175000017500000000327510512376023014112 0ustar fx5fx5cdef extern from "openssl/rand.h" : int RAND_bytes( unsigned char *buf, int num ) int RAND_pseudo_bytes( unsigned char *buf, int num ) void RAND_add( void *buf, int num, double entropy ) void RAND_seed( void *buf, int num ) int RAND_status() cdef extern from "Python.h" : int PyString_AsStringAndSize( object obj, char **buffer, int *length ) object PyString_FromStringAndSize( char *buf, int buf_size ) object Py_BuildValue( char *fmt, ... ) cdef extern from "stdlib.h" : void *malloc( int size ) void free( void *p ) import ncrypt_err class RandError( ncrypt_err.BaseLibraryError ) : pass def bytes( int num, int checkResult=0 ) : cdef char *buf cdef int result if num <= 0 : raise ValueError, "'num' should be > 0" buf = malloc( num ) try : result = RAND_bytes( buf, num ) if checkResult and (result == 0) : raise RandError, 'RNG not seeded sufficiently' return PyString_FromStringAndSize( buf, num ) finally : free( buf ) def pseudoBytes( int num ) : cdef char *buf if num <= 0 : raise ValueError, "'num' should be > 0" buf = malloc( num ) try : RAND_pseudo_bytes( buf, num ) return PyString_FromStringAndSize( buf, num ) finally : free( buf ) def seed( data, entropy=None ) : cdef char *ptr cdef int size, result result = PyString_AsStringAndSize( data, &ptr, &size ) if result < 0 : raise TypeError, 'a string is expected' if entropy is None : RAND_seed( ptr, size ) else : RAND_add( ptr, size, entropy ) def status() : return RAND_status() ncrypt-0.6.4/ncrypt_cipher.pyx0000700000175000017500000001435410512376023014440 0ustar fx5fx5cdef extern from "openssl/evp.h" : ctypedef struct EVP_CIPHER_CTX ctypedef struct EVP_CIPHER EVP_CIPHER *EVP_get_cipherbyname( char *name ) void EVP_add_cipher( EVP_CIPHER *evpCipher ) void EVP_add_cipher_alias( char *realName, char *aliasName ) char *EVP_CIPHER_name( EVP_CIPHER *evpCipher ) int EVP_CIPHER_block_size( EVP_CIPHER *evpCipher ) int EVP_CIPHER_key_length( EVP_CIPHER *evpCipher ) int EVP_CIPHER_iv_length( EVP_CIPHER *evpCipher ) void EVP_CIPHER_CTX_init( EVP_CIPHER_CTX *ctx ) int EVP_CIPHER_CTX_cleanup( EVP_CIPHER_CTX *ctx ) int EVP_CIPHER_CTX_set_padding( EVP_CIPHER_CTX *ctx, int paddingFlag ) int EVP_CipherInit_ex( EVP_CIPHER_CTX *ctx, EVP_CIPHER *evpCipher, void *engine, unsigned char *key, unsigned char *iv, int enc ) int EVP_CipherUpdate( EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, unsigned char *indata, int inl ) int EVP_CipherFinal_ex( EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl ) cdef enum : EVP_MAX_BLOCK_LENGTH cdef extern from "Python.h" : int PyString_AsStringAndSize( object obj, char **buffer, int *length ) object PyString_FromStringAndSize( char *buf, int buf_size ) void *malloc( int size ) void *realloc( void *ptr, int size ) void free( void *ptr ) cdef extern from "utils.h" : EVP_CIPHER_CTX *AllocCipherContext() void FreeCipherContext( EVP_CIPHER_CTX *ptr ) import ncrypt_err class CipherError( ncrypt_err.BaseLibraryError ) : pass MODES = ( 'CBC', 'CFB', 'OFB', 'ECB' ) ALGORITHMS = ( 'DES', 'DES-EDE3', 'BF', 'AES-128', 'AES-192', 'AES-256' ) cdef class CipherType : cdef EVP_CIPHER *c cdef object cipherAlgo, cipherMode def __new__( self, cipherAlgo, cipherMode ) : self.c = NULL def __dealloc__( self ) : pass def __init__( self, cipherAlgo, cipherMode ) : cipherName = '-'.join( [cipherAlgo,cipherMode] ) self.cipherAlgo = cipherAlgo self.cipherMode = cipherMode self.c = EVP_get_cipherbyname( cipherName ) if self.c == NULL : raise CipherError, 'unknown cipher: %s' % cipherName def algo( self ) : return self.cipherAlgo def mode( self ) : return self.cipherMode def name( self ) : return EVP_CIPHER_name( self.c ) def blockSize( self ) : return EVP_CIPHER_block_size( self.c ) def keyLength( self ) : return EVP_CIPHER_key_length( self.c ) def ivLength( self ) : return EVP_CIPHER_iv_length( self.c ) def EncryptCipher( cipherType, key, iv ) : return Cipher( cipherType, key, iv, 1 ) def DecryptCipher( cipherType, key, iv ) : return Cipher( cipherType, key, iv, 0 ) cdef class Cipher : cdef char *outBuffer cdef int outBufferSize cdef EVP_CIPHER_CTX *ctx cdef int cipherFinalized def __new__( self, cipherType, key, iv, encryptFlag ) : self.outBuffer = NULL self.outBufferSize = 0 self.ctx = AllocCipherContext() EVP_CIPHER_CTX_init( self.ctx ) self.cipherFinalized = 0 def __dealloc__( self ) : EVP_CIPHER_CTX_cleanup( self.ctx ) FreeCipherContext( self.ctx ) free( self.outBuffer ) def __init__( self, CipherType cipherType not None, key, iv, encryptFlag ) : cdef char *keyPtr, *ivPtr cdef int keyLen, ivLen, result result = PyString_AsStringAndSize( key, &keyPtr, &keyLen ) if result < 0 : raise TypeError, "'key' must be a string" if keyLen != cipherType.keyLength() : raise CipherError, 'invalid key length %d, expected %d' % (keyLen,cipherType.keyLength()) if iv is None : ivPtr = NULL ivLen = 0 else : result = PyString_AsStringAndSize( iv, &ivPtr, &ivLen ) if result < 0 : raise TypeError, "'iv' must be a string" if ivLen != cipherType.ivLength() : raise CipherError, 'invalid iv length %d, expected %d' % (ivLen,cipherType.ivLength()) cdef int enc if encryptFlag : enc = 1 else : enc = 0 result = EVP_CipherInit_ex( self.ctx, cipherType.c, NULL, keyPtr, ivPtr, enc ) if result == 0 : raise CipherError, 'unable to initialize cipher' self.cipherFinalized = 0 def enablePadding( self, padding ) : cdef int paddingFlag if padding : paddingFlag = 1 else : paddingFlag = 0 EVP_CIPHER_CTX_set_padding( self.ctx, paddingFlag ) cdef void growBuffer( self, int requiredSize ) : if requiredSize > self.outBufferSize : self.outBuffer = realloc( self.outBuffer, requiredSize ) self.outBufferSize = requiredSize def update( self, data ) : cdef char *inData cdef int inDataLen, outDataLen, result if self.cipherFinalized : raise CipherError, 'cipher operation already completed' result = PyString_AsStringAndSize( data, &inData, &inDataLen ) if result < 0 : raise TypeError, 'a string is required' if inDataLen == 0 : return '' self.growBuffer( inDataLen + EVP_MAX_BLOCK_LENGTH ) outDataLen = self.outBufferSize result = EVP_CipherUpdate( self.ctx, self.outBuffer, &outDataLen, inData, inDataLen ) if result == 0 : raise CipherError, 'error in cipher operation' return PyString_FromStringAndSize( self.outBuffer, outDataLen ) cdef object _finish( self ) : if self.cipherFinalized : raise CipherError, 'cipher operation already completed' self.cipherFinalized = 1 cdef int outDataLen, result self.growBuffer( EVP_MAX_BLOCK_LENGTH ) outDataLen = self.outBufferSize result = EVP_CipherFinal_ex( self.ctx, self.outBuffer, &outDataLen ) if result == 0 : raise CipherError, 'error in cipher operation' return PyString_FromStringAndSize( self.outBuffer, outDataLen ) def finish( self, data=None ) : if data is not None : return self.update(data) + self._finish() else : return self._finish() ncrypt-0.6.4/ncrypt_dh.pxd0000700000175000017500000000041510512376023013525 0ustar fx5fx5cdef extern from "openssl/dh.h" : ctypedef struct BIGNUM ctypedef struct DH_s "DH" : int pad int version BIGNUM *p BIGNUM *g long length BIGNUM *pub_key BIGNUM *priv_key cdef class DH : cdef DH_s *dh ncrypt-0.6.4/ncrypt_dh.pyx0000700000175000017500000002044210512376023013554 0ustar fx5fx5cdef extern from "openssl/bn.h" : ctypedef struct BIGNUM BIGNUM *BN_new() void BN_free( BIGNUM *x ) cdef extern from "openssl/dh.h" : DH_s *DH_new() void DH_free( DH_s *dh ) int DH_size( DH_s *dh ) DH_s *DH_generate_parameters( int prime_len, int generator, void (*callback)(int,int,void *), void *cb_arg ) int DH_check( DH_s *dh, int *codes ) int DH_generate_key( DH_s *dh ) int DH_compute_key( unsigned char *key, BIGNUM *pub_key, DH_s *dh ) int i2d_DHparams( DH_s *dh, unsigned char **out ) DH_s *d2i_DHparams( DH_s **dh, unsigned char **inp, int len ) cdef extern from "openssl/bio.h" : ctypedef struct BIO_METHOD ctypedef struct BIO BIO_METHOD *BIO_s_mem() BIO *BIO_new( BIO_METHOD *m ) int BIO_free( BIO *b ) int BIO_write( BIO *b, void *buf, int num ) cdef extern from "openssl/pem.h" : int PEM_write_bio_DHparams( BIO *b, DH_s *s ) DH_s *PEM_read_bio_DHparams( BIO *b, void *, void *, void * ) cdef extern from "utils.h" : object BNToLong( BIGNUM *bn ) int LongToBN( object x, BIGNUM *bn ) object GetBIOData( BIO *b ) cdef extern from "stdlib.h" : void *malloc( int size ) void free( void *ptr ) cdef extern from "Python.h" : ctypedef struct PyObject void Py_DECREF( PyObject *obj ) int PyString_AsStringAndSize( object obj, char **ptr, int *len ) object PyString_FromStringAndSize( char *p, int len ) PyObject *Raw_PyString_FromStringAndSize "PyString_FromStringAndSize"( char *s, int len ) char *Raw_PyString_AsString "PyString_AsString" ( PyObject *o ) import ncrypt_err class DHError( ncrypt_err.BaseLibraryError ) : pass cdef class DH : def __new__( self ) : self.dh = DH_new() def __dealloc__( self ) : DH_free( self.dh ) def __init__( self ) : pass def size( self ) : if (not self.dh.p) or (not self.dh.g) : raise DHError, 'dh params not initialized' return DH_size( self.dh ) def generateParameters( self, primeLen, generator ) : cdef DH_s *newdh newdh = DH_generate_parameters( primeLen, generator, NULL, NULL ) if not newdh : raise DHError, 'error generating dh parameters' DH_free( self.dh ) self.dh = newdh def check( self ) : if (not self.dh.p) or (not self.dh.g) : raise DHError, 'dh params not initialized' cdef int result, codes result = DH_check( self.dh, &codes ) if not result : raise DHError, 'error in check dh params' if codes : msg = 'dh params are not ok (%d)' % codes raise DHError, msg def generateKey( self ) : if (not self.dh.p) or (not self.dh.g) : raise DHError, 'dh params are not initialized' cdef int result result = DH_generate_key( self.dh ) if not result : raise DHError, 'error in generating key' def computeKey( self, peerPubKey ) : if (not self.dh.p) or (not self.dh.g) : raise DHError, 'dh params are not initialized' if (not self.dh.priv_key) or (not self.dh.pub_key) : raise DHError, 'dh private key not initialized' cdef BIGNUM *bn_peerPubKey cdef int result bn_peerPubKey = BN_new() result = LongToBN( peerPubKey, bn_peerPubKey ) if result < 0 : BN_free( bn_peerPubKey ) raise DHError, 'invalid peerPubKey value' cdef unsigned char *keyBuf keyBuf = malloc( DH_size(self.dh) ) result = DH_compute_key( keyBuf, bn_peerPubKey, self.dh ) BN_free( bn_peerPubKey ) if result < 0 : free( keyBuf ) raise DHError, 'error in computing shared key' sharedKey = PyString_FromStringAndSize( keyBuf, result ) free( keyBuf ) return sharedKey def getP( self ) : if not self.dh.p : return None return BNToLong( self.dh.p ) def setP( self, p ) : cdef BIGNUM *bn_p cdef int result bn_p = BN_new() result = LongToBN( p, bn_p ) if result < 0 : BN_free( bn_p ) raise DHError, 'invalid p value' if self.dh.p : BN_free( self.dh.p ) self.dh.p = bn_p def getG( self ) : if not self.dh.g : return None return BNToLong( self.dh.g ) def setG( self, g ) : cdef BIGNUM *bn_g cdef int result bn_g = BN_new() result = LongToBN( g, bn_g ) if result < 0 : BN_free( bn_g ) raise DHError, 'invalid g value' if self.dh.g : BN_free( self.dh.g ) self.dh.g = bn_g def getPublicKey( self ) : if not self.dh.pub_key : return None return BNToLong( self.dh.pub_key ) def setPublicKey( self, pubKey ) : cdef BIGNUM *bn_pubKey cdef int result bn_pubKey = BN_new() result = LongToBN( pubKey, bn_pubKey ) if result < 0 : BN_free( bn_pubKey ) raise DHError, 'invalid pubKey value' if self.dh.pub_key : BN_free( self.dh.pub_key ) self.dh.pub_key = bn_pubKey def getPrivateKey( self ) : if not self.dh.priv_key : return None return BNToLong( self.dh.priv_key ) def setPrivateKey( self, privKey ) : cdef BIGNUM *bn_privKey cdef int result bn_privKey = BN_new() result = LongToBN( privKey, bn_privKey ) if result < 0 : BN_free( bn_privKey ) raise DHError, 'invalid privKey value' if self.dh.priv_key : BN_free( self.dh.priv_key ) self.dh.priv_key = bn_privKey def fromDER_Parameters( self, data ) : cdef char *p cdef int result, dataLen result = PyString_AsStringAndSize( data, &p, &dataLen ) if result < 0 : raise TypeError, 'a string is expected' cdef DH_s *newdh newdh = d2i_DHparams( NULL, &p, dataLen ) if not newdh : raise DHError, 'unable to load object from data' DH_free( self.dh ) self.dh = newdh def toDER_Parameters( self ) : if (not self.dh.p) or (not self.dh.g) : raise DHError, 'dh params not initialized' cdef int len len = i2d_DHparams( self.dh, NULL ) if len < 0 : raise DHError, 'error in dh params data' cdef PyObject *derStr derStr = Raw_PyString_FromStringAndSize( NULL, len ) if derStr == NULL : raise MemoryError, 'unable to allocate string' cdef char *p p = Raw_PyString_AsString( derStr ) try : len1 = i2d_DHparams( self.dh, &p ) assert len == len1 return derStr finally : Py_DECREF( derStr ) def fromPEM_Parameters( self, data ) : cdef char *p cdef int dataLen, result result = PyString_AsStringAndSize( data, &p, &dataLen ) if result < 0 : raise TypeError, 'a string is expected' cdef BIO *b b = BIO_new( BIO_s_mem() ) if not b : raise DHError, 'unable to allocate BIO structure' cdef DH_s *newdh try : result = BIO_write( b, p, dataLen ) if result < 0 : raise DHError, 'unable to write data to BIO' newdh = PEM_read_bio_DHparams( b, NULL, NULL, NULL ) if not newdh : raise DHError, 'unable to load object from data' DH_free( self.dh ) self.dh = newdh finally : BIO_free( b ) def toPEM_Parameters( self ) : if (not self.dh.p) or (not self.dh.g) : raise DHError, 'dh params not initialized' cdef BIO *b b = BIO_new( BIO_s_mem() ) if not b : raise DHError, 'unable to allocate a BIO structure' cdef int result try : result = PEM_write_bio_DHparams( b, self.dh ) if not result : raise DHError, 'error in dh params data' ret = GetBIOData( b ) if ret is None : raise DHError, 'error in creating PEM data' return ret finally : BIO_free( b )