def __init__(self, data=None): # type: (Optional[bytes]) -> None super(MemoryBuffer, self).__init__(self) if data is not None and not isinstance(data, bytes): raise TypeError( "data must be bytes or None, not %s" % (type(data).__name__, )) self.bio = m2.bio_new(m2.bio_s_mem()) self._pyfree = 1 if data is not None: m2.bio_write(self.bio, data)
def __init__(self, data=None): # type: (Optional[bytes]) -> None super(MemoryBuffer, self).__init__(self) if data is not None and not isinstance(data, bytes): raise TypeError("data must be bytes or None, not %s" % (type(data).__name__, )) self.bio = m2.bio_new(m2.bio_s_mem()) self._pyfree = 1 if data is not None: m2.bio_write(self.bio, data)
def _encrypt(self, data='', clientHello=0): # XXX near mirror image of _decrypt - refactor self.data += data g = m2.bio_ctrl_get_write_guarantee(self.sslBio._ptr()) if g > 0 and self.data != '' or clientHello: r = m2.bio_write(self.sslBio._ptr(), self.data) if r <= 0: assert (m2.bio_should_retry(self.sslBio._ptr())) else: assert (self.checked) self.data = self.data[r:] encryptedData = '' while 1: pending = m2.bio_ctrl_pending(self.networkBio) if pending: d = m2.bio_read(self.networkBio, pending) if d is not None: # This is strange, but d can be None encryptedData += d else: assert (m2.bio_should_retry(self.networkBio)) else: break return encryptedData
def _translate(self, write_bio, write_bio_buf, read_bio, force_write=False): data = [] encrypting = write_bio is self._bio_ssl write_bio = write_bio.obj read_bio = read_bio.obj while True: writable = m2.bio_ctrl_get_write_guarantee(write_bio) > 0 if (writable and write_bio_buf) or force_write: # If force_write is True, we want to start the handshake. We call # bio_write() even if there's nothing in the buffer, to cause OpenSSL to # implicitly send the client hello. chunk = write_bio_buf.pop(0) if write_bio_buf else '' r = m2.bio_write(write_bio, chunk) if r <= 0: # If BIO_write returns <= 0 due to an error condition, it should # raise. Otherwise we expect bio_should_retry() to return True. Do a # quick sanity check. if not m2.bio_should_retry(write_bio): raise TLSProtocolError('Unexpected internal state: should_retry()' 'is False without error') if not self._rmon.active and m2.bio_should_read(self._bio_ssl.obj): # The BIO write failed, the SSL BIO is now telling us we should # read, and the read monitor is not active. Update the read # monitor now, which will register with the notifier because the # SSL BIO should read, allowing us to read from the socket to # satisfy whatever the underlying SSL protocol is doing. self._update_read_monitor() else: if encrypting: # We are encrypting user data to send to peer. Require the # remote end be validated first. We should not normally # get here until ClientHello is completed successfully. assert(self._validated) chunk = chunk[r:] if chunk: # Insert remainder of chunk back into the buffer. write_bio_buf.insert(0, chunk) pending = m2.bio_ctrl_pending(read_bio) if not pending: break chunk = m2.bio_read(read_bio, pending) if chunk is not None: data.append(chunk) else: # It's possible for chunk to be None, even though bio_ctrl_pending() # told us there was data waiting in the BIO. I suspect this happens # when all the bytes in the BIO are used for the SSL protocol and # none are user data. assert(m2.bio_should_retry(read_bio)) return ''.join(data)
def write(self, data): # type: (AnyStr) -> int """Write data to BIO. :return: either data written, or [0, -1] for nothing written, -2 not implemented """ if not self.writeable(): raise IOError('cannot write') if isinstance(data, six.text_type): data = data.encode('utf8') return m2.bio_write(self.bio, data)
def c_style(HOST, PORT, req): # Set up SSL context. ctx = m2.ssl_ctx_new(m2.sslv3_method()) m2.ssl_ctx_use_cert(ctx, 'client.pem') m2.ssl_ctx_use_privkey(ctx, 'client.pem') # Make the socket connection. s = socket(AF_INET, SOCK_STREAM) s.connect((HOST, PORT)) # Set up the SSL connection. sbio = m2.bio_new_socket(s.fileno(), 0) ssl = m2.ssl_new(ctx) m2.ssl_set_bio(ssl, sbio, sbio) m2.ssl_connect(ssl) sslbio = m2.bio_new(m2.bio_f_ssl()) m2.bio_set_ssl(sslbio, ssl, 0) # Push a buffering BIO over the SSL BIO. iobuf = m2.bio_new(m2.bio_f_buffer()) topbio = m2.bio_push(iobuf, sslbio) # Send the request. m2.bio_write(sslbio, req) # Receive the response. while 1: data = m2.bio_gets(topbio, 4096) if not data: break sys.stdout.write(data) # Cleanup. May be missing some necessary steps. ;-| m2.bio_pop(topbio) m2.bio_free(iobuf) m2.ssl_shutdown(ssl) m2.ssl_free(ssl) m2.ssl_ctx_free(ctx) s.close()
def _decrypt(self, data=''): # XXX near mirror image of _encrypt - refactor self.encrypted += data g = m2.bio_ctrl_get_write_guarantee(self.networkBio) if g > 0 and self.encrypted != '': r = m2.bio_write(self.networkBio, self.encrypted) if r <= 0: assert (m2.bio_should_retry(self.networkBio)) else: self.encrypted = self.encrypted[r:] decryptedData = '' while 1: pending = m2.bio_ctrl_pending(self.sslBio._ptr()) if pending: d = m2.bio_read(self.sslBio._ptr(), pending) if d is not None: # This is strange, but d can be None decryptedData += d else: assert (m2.bio_should_retry(self.sslBio._ptr())) else: break return decryptedData
def _translate(self, write_bio, write_bio_buf, read_bio, force_write=False): data = [] encrypting = write_bio is self._bio_ssl write_bio = write_bio.obj read_bio = read_bio.obj while True: writable = m2.bio_ctrl_get_write_guarantee(write_bio) > 0 if (writable and write_bio_buf) or force_write: # If force_write is True, we want to start the handshake. We call # bio_write() even if there's nothing in the buffer, to cause OpenSSL to # implicitly send the client hello. chunk = write_bio_buf.pop(0) if write_bio_buf else '' r = m2.bio_write(write_bio, chunk) if r <= 0: # If BIO_write returns <= 0 due to an error condition, it should # raise. Otherwise we expect bio_should_retry() to return True. Do a # quick sanity check. if not m2.bio_should_retry(write_bio): raise TLSProtocolError( 'Unexpected internal state: should_retry()' 'is False without error') if not self._rmon.active and m2.bio_should_read( self._bio_ssl.obj): # The BIO write failed, the SSL BIO is now telling us we should # read, and the read monitor is not active. Update the read # monitor now, which will register with the notifier because the # SSL BIO should read, allowing us to read from the socket to # satisfy whatever the underlying SSL protocol is doing. self._update_read_monitor() else: if encrypting: # We are encrypting user data to send to peer. Require the # remote end be validated first. We should not normally # get here until ClientHello is completed successfully. assert (self._validated) chunk = chunk[r:] if chunk: # Insert remainder of chunk back into the buffer. write_bio_buf.insert(0, chunk) pending = m2.bio_ctrl_pending(read_bio) if not pending: break chunk = m2.bio_read(read_bio, pending) if chunk is not None: data.append(chunk) else: # It's possible for chunk to be None, even though bio_ctrl_pending() # told us there was data waiting in the BIO. I suspect this happens # when all the bytes in the BIO are used for the SSL protocol and # none are user data. assert (m2.bio_should_retry(read_bio)) return ''.join(data)
def write(self, data): if not self.writeable(): raise IOError('cannot write') return m2.bio_write(self.bio, data)
def cmembufi(iter, txt=txt): buf = m2.bio_new(m2.bio_s_mem()) for i in range(iter): m2.bio_write(buf, txt) m2.bio_set_mem_eof_return(buf, 0) out = m2.bio_read(buf, m2.bio_ctrl_pending(buf))
def __init__(self, data=None): BIO.__init__(self) self.bio = m2.bio_new(m2.bio_s_mem()) self._pyfree = 1 if data is not None: m2.bio_write(self.bio, data)
Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved.""" from M2Crypto import m2 m2.lib_init() use_mem = 1 if use_mem: bio = m2.bio_new(m2.bio_s_mem()) else: bio = m2.bio_new_file('XXX', 'wb') ciph = m2.bf_cbc() filt = m2.bio_new(m2.bio_f_cipher()) m2.bio_set_cipher(filt, ciph, 'key', 'iv', 1) m2.bio_push(filt, bio) m2.bio_write(filt, '12345678901234567890') m2.bio_flush(filt) m2.bio_pop(filt) m2.bio_free(filt) if use_mem: m2.bio_set_mem_eof_return(bio, 0) xxx = m2.bio_read(bio, 100) print `xxx`, len(xxx) m2.bio_free(bio) if use_mem: bio = m2.bio_new(m2.bio_s_mem()) m2.bio_write(bio, xxx) m2.bio_set_mem_eof_return(bio, 0) else: bio = m2.bio_new_file('XXX', 'rb')