]> www.wagner.pp.ru Git - oss/ctypescrypto.git/blob - ctypescrypto/bio.py
Fixes some style. Improved tests coverage for bio,oid,digest and cipher. Prepare...
[oss/ctypescrypto.git] / ctypescrypto / bio.py
1 """
2 Interface to OpenSSL BIO library
3 """
4 from ctypescrypto import libcrypto
5 from ctypes import c_char_p, c_void_p, c_int, string_at, c_long,POINTER,byref, create_string_buffer
6 class Membio(object):
7         """ 
8                 Provides interface to OpenSSL memory bios 
9                 use str() or unicode() to get contents of writable bio
10                 use bio member to pass to libcrypto function
11         """
12         def __init__(self,data=None):
13                 """ If data is specified, creates read-only BIO. If data is
14                         None, creates writable BIO, contents of which can be retrieved by str() or unicode()
15                 """
16                 if data is None:
17                         method=libcrypto.BIO_s_mem()
18                         self.bio=libcrypto.BIO_new(method)
19                 else:
20                         self.bio=libcrypto.BIO_new_mem_buf(c_char_p(data),len(data))
21         def __del__(self):
22                 """
23                 Cleans up memory used by bio
24                 """
25                 libcrypto.BIO_free(self.bio)
26                 del(self.bio)
27         def __str__(self):
28                 """
29                 Returns current contents of buffer as byte string
30                 """
31                 p=c_char_p(None)
32                 l=libcrypto.BIO_ctrl(self.bio,3,0,byref(p))
33                 return string_at(p,l)
34         def __unicode__(self):
35                 """
36                 Attempts to interpret current contents of buffer as UTF-8 string and convert it to unicode
37                 """
38                 return str(self).decode("utf-8")
39         def read(self,length=None):
40                 """
41                 Reads data from readble BIO. For test purposes.
42                 @param length - if specifed, limits amount of data read. If not BIO is read until end of buffer
43                 """
44                 if not length is None:
45                         if not isinstance(length,(int,long)):
46                                 raise TypeError("length to read should be number")
47                         buf=create_string_buffer(length)
48                         readbytes=libcrypto.BIO_read(self.bio,buf,length)
49                         if readbytes==-2:
50                                 raise NotImplementedError("Function is not supported by this BIO")
51                         if readbytes==-1:
52                                 raise IOError
53                         if readbytes==0:
54                                 return ""
55                         return buf.raw[:readbytes]
56                 else:
57                         buf=create_string_buffer(1024)
58                         out=""
59                         r=1
60                         while r>0:
61                                 r=libcrypto.BIO_read(self.bio,buf,1024)
62                                 if r==-2:
63                                         raise NotImplementedError("Function is not supported by this BIO")
64                                 if r==-1:
65                                         raise IOError
66                                 if (r>0):
67                                         out+=buf.raw[:r]
68                         return out      
69
70         def write(self,data):
71                 """
72                 Writes data to writable bio. For test purposes
73                 """
74                 if isinstance(data,unicode):
75                         data=data.encode("utf-8")
76                 r=libcrypto.BIO_write(self.bio,data,len(data))
77                 if r==-2:
78                         raise NotImplementedError("Function not supported by this BIO")
79                 if r<len(data):
80                         raise IOError("Not all data were successfully written")
81         def reset(self):
82                 """
83                 Resets the read-only bio to start and discards all data from writable bio
84                 """
85                 libcrypto.BIO_ctrl(self.bio,1,0,None)
86
87 __all__ = ['Membio']
88 libcrypto.BIO_s_mem.restype=c_void_p
89 libcrypto.BIO_new.restype=c_void_p
90 libcrypto.BIO_new.argtypes=(c_void_p,)
91 libcrypto.BIO_ctrl.restype=c_long
92 libcrypto.BIO_ctrl.argtypes=(c_void_p,c_int,c_long,POINTER(c_char_p))
93 libcrypto.BIO_read.argtypes=(c_void_p,c_char_p,c_int)
94 libcrypto.BIO_write.argtypes=(c_void_p,c_char_p,c_int)
95 libcrypto.BIO_free.argtypes=(c_void_p,)
96 libcrypto.BIO_new_mem_buf.restype=c_void_p
97 libcrypto.BIO_new_mem_buf.argtypes=(c_char_p,c_int)
98 libcrypto.BIO_ctrl.argtypes=(c_void_p,c_int,c_int,c_void_p)