2 Interface to OpenSSL BIO library
4 from ctypescrypto import libcrypto,pyver, inttype, chartype
5 from ctypes import c_char_p, c_void_p, c_int, string_at, c_long
6 from ctypes import POINTER, byref, create_string_buffer
9 Provides interface to OpenSSL memory bios
10 use str() or unicode() to get contents of writable bio
11 use bio member to pass to libcrypto function
14 def __init__(self, data=None, clone=False):
16 If data is specified, creates read-only BIO.
17 If clone is True, makes copy of data in the instance member
19 None, creates writable BIO, contents of which can be retrieved
24 method = libcrypto.BIO_s_mem()
25 self.bio = libcrypto.BIO_new(method)
27 if isinstance(data, chartype):
28 data = data.encode("utf-8")
32 self.bio = libcrypto.BIO_new_mem_buf(c_char_p(self.data), len(data))
34 self.bio = libcrypto.BIO_new_mem_buf(c_char_p(data), len(data))
38 Cleans up memory used by bio
40 if hasattr(self,'bio'):
41 libcrypto.BIO_free(self.bio)
46 Returns current contents of buffer as byte string
48 string_ptr = c_char_p(None)
49 string_len = libcrypto.BIO_ctrl(self.bio, 3, 0, byref(string_ptr))
50 return string_at(string_ptr, string_len)
52 def __unicode__(self):
54 Attempts to interpret current contents of buffer as UTF-8 string
55 and convert it to unicode
57 return self.__bytes__().decode("utf-8")
62 def read(self, length=None):
64 Reads data from readble BIO. For test purposes.
65 @param length - if specifed, limits amount of data read.
66 If not BIO is read until end of buffer
68 if not length is None:
69 if not isinstance(length, inttype) :
70 raise TypeError("length to read should be number")
71 buf = create_string_buffer(length)
72 readbytes = libcrypto.BIO_read(self.bio, buf, length)
74 raise NotImplementedError("Function is not supported by" +
80 return buf.raw[:readbytes]
82 buf = create_string_buffer(1024)
86 readbytes = libcrypto.BIO_read(self.bio, buf, 1024)
88 raise NotImplementedError("Function is not supported by " +
93 out += buf.raw[:readbytes]
96 def write(self, data):
98 Writes data to writable bio. For test purposes
101 if isinstance(data, unicode):
102 data = data.encode("utf-8")
106 if not isinstance(data, bytes):
107 data=str(data).encode("utf-8")
109 written = libcrypto.BIO_write(self.bio, data, len(data))
111 raise NotImplementedError("Function not supported by this BIO")
112 if written < len(data):
113 raise IOError("Not all data were successfully written")
117 Resets the read-only bio to start and discards all data from
120 libcrypto.BIO_ctrl(self.bio, 1, 0, None)
123 libcrypto.BIO_s_mem.restype = c_void_p
124 libcrypto.BIO_new.restype = c_void_p
125 libcrypto.BIO_new.argtypes = (c_void_p, )
126 libcrypto.BIO_ctrl.restype = c_long
127 libcrypto.BIO_ctrl.argtypes = (c_void_p, c_int, c_long, POINTER(c_char_p))
128 libcrypto.BIO_read.argtypes = (c_void_p, c_char_p, c_int)
129 libcrypto.BIO_write.argtypes = (c_void_p, c_char_p, c_int)
130 libcrypto.BIO_free.argtypes = (c_void_p, )
131 libcrypto.BIO_new_mem_buf.restype = c_void_p
132 libcrypto.BIO_new_mem_buf.argtypes = (c_char_p, c_int)