+"""
+Interface to OpenSSL BIO library
+"""
from ctypescrypto import libcrypto
from ctypes import c_char_p, c_void_p, c_int, string_at, c_long,POINTER,byref, create_string_buffer
class Membio:
"""
Provides interface to OpenSSL memory bios
- use str() to get contents of writable bio
+ use str() or unicode() to get contents of writable bio
use bio member to pass to libcrypto function
"""
def __init__(self,data=None):
""" If data is specified, creates read-only BIO. If data is
- None, creates writable BIO
+ None, creates writable BIO, contents of which can be retrieved by str() or unicode()
"""
if data is None:
method=libcrypto.BIO_s_mem()
else:
self.bio=libcrypto.BIO_new_mem_buf(c_char_p(data),len(data))
def __del__(self):
+ """
+ Cleans up memory used by bio
+ """
libcrypto.BIO_free(self.bio)
del(self.bio)
def __str__(self):
+ """
+ Returns current contents of buffer as byte string
+ """
p=c_char_p(None)
l=libcrypto.BIO_ctrl(self.bio,3,0,byref(p))
return string_at(p,l)
+ def __unicode__(self):
+ """
+ Attempts to interpret current contents of buffer as UTF-8 string and convert it to unicode
+ """
+ return str(self).decode("utf-8")
def read(self,length=None):
+ """
+ Reads data from readble BIO. For test purposes.
+ @param length - if specifed, limits amount of data read. If not BIO is read until end of buffer
+ """
if not length is None:
if type(length)!=type(0):
raise TypeError("length to read should be number")
return out
def write(self,data):
+ """
+ Writes data to writable bio. For test purposes
+ """
+ if isinstance(data,unicode):
+ data=data.encode("utf-8")
r=libcrypto.BIO_write(self.bio,data,len(data))
if r==-2:
raise NotImplementedError("Function not supported by this BIO")
if r<len(data):
raise IOError("Not all data were successfully written")
+ def reset(self):
+ """
+ Resets the read-only bio to start and discards all data from writable bio
+ """
+ libcrypto.BIO_ctrl(self.bio,1,0,None)
-#FIXME TODO - BIO should have stream-like interface
+__all__ = ['Membio']
libcrypto.BIO_s_mem.restype=c_void_p
libcrypto.BIO_new.restype=c_void_p
libcrypto.BIO_new.argtypes=(c_void_p,)
libcrypto.BIO_free.argtypes=(c_void_p,)
libcrypto.BIO_new_mem_buf.restype=c_void_p
libcrypto.BIO_new_mem_buf.argtypes=(c_char_p,c_int)
+libcrypto.BIO_ctrl.argtypes=(c_void_p,c_int,c_int,c_void_p)