]> www.wagner.pp.ru Git - oss/ctypescrypto.git/blob - ctypescrypto/bio.py
92de35c5dd27fe4eba15966b038e6aa24590d732
[oss/ctypescrypto.git] / ctypescrypto / bio.py
1 from ctypescrypto import libcrypto
2 from ctypes import c_char_p, c_void_p, c_int, string_at, c_long,POINTER,byref, create_string_buffer
3 class Membio:
4         """ 
5                 Provides interface to OpenSSL memory bios 
6                 use str() to get contents of writable bio
7                 use bio member to pass to libcrypto function
8         """
9         def __init__(self,data=None):
10                 """ If data is specified, creates read-only BIO. If data is
11                         None, creates writable BIO
12                 """
13                 if data is None:
14                         method=libcrypto.BIO_s_mem()
15                         self.bio=libcrypto.BIO_new(method)
16                 else:
17                         self.bio=libcrypto.BIO_new_mem_buf(c_char_p(data),len(data))
18         def __del__(self):
19                 libcrypto.BIO_free(self.bio)
20                 del(self.bio)
21         def __str__(self):
22                 p=c_char_p(None)
23                 l=libcrypto.BIO_ctrl(self.bio,3,0,byref(p))
24                 return string_at(p,l)
25         def read(self,length=None):
26                 if not length is None:
27                         if type(length)!=type(0):
28                                 raise TypeError("length to read should be number")
29                         buf=create_string_buffer(length)
30                         readbytes=libcrypto.BIO_read(self.bio,buf,length)
31                         if readbytes==-2:
32                                 raise NotImplementedError("Function is not supported by this BIO")
33                         if readbytes==-1:
34                                 raise IOError
35                         if readbytes==0:
36                                 return ""
37                         return buf.raw[:readbytes]
38                 else:
39                         buf=create_string_buffer(1024)
40                         out=""
41                         r=1
42                         while r>0:
43                                 r=libcrypto.BIO_read(self.bio,buf,1024)
44                                 if r==-2:
45                                         raise NotImplementedError("Function is not supported by this BIO")
46                                 if r==-1:
47                                         raise IOError
48                                 if (r>0):
49                                         out+=buf.raw[:r]
50                         return out      
51
52         def write(self,data):
53                 r=libcrypto.BIO_write(self.bio,data,len(data))
54                 if r==-2:
55                         raise NotImplementedError("Function not supported by this BIO")
56                 if r<len(data):
57                         raise IOError("Not all data were successfully written")
58
59 #FIXME TODO - BIO should have stream-like interface
60 libcrypto.BIO_s_mem.restype=c_void_p
61 libcrypto.BIO_new.restype=c_void_p
62 libcrypto.BIO_new.argtypes=(c_void_p,)
63 libcrypto.BIO_ctrl.restype=c_long
64 libcrypto.BIO_ctrl.argtypes=(c_void_p,c_int,c_long,POINTER(c_char_p))
65 libcrypto.BIO_read.argtypes=(c_void_p,c_char_p,c_int)
66 libcrypto.BIO_write.argtypes=(c_void_p,c_char_p,c_int)