import socket; def dumpHexadecimal(buffer): print ' '.join('%02x'%i for i in buffer); s = socket.socket(socket.AF_INET, socket.SOCK_STREAM); s.connect(("localhost", 3306)); print "Receiving Initial handshake packet:"; InitialHandshakePacket = s.recv(78); dumpHexadecimal(bytearray(InitialHandshakePacket)); print "\nSending SSL Request packet:"; SSLRequestPacket = bytearray([ 0x20, 0x00, 0x00, # Payload length: 32 0x01, # Sequence ID: 1 0x08, 0x8a, 0x08, 0x00, # Capabilities: includes CLIENT_SSL 0xff, 0xff, 0xff, 0x00, # Maximum packet size: 2^14 - 1 0x21, # Character set # Reserved, 23 zeros 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]); dumpHexadecimal(SSLRequestPacket); s.sendall(SSLRequestPacket); SSLVersionMajor = 0x03; SSLVersionMinor = 0x00; # Please note, changing this to 0x01 for TLS 1.0 results in a correct SSL record from MySQL/yaSSL print "\nSending ClientHello:"; ClientHello = bytearray([ 0x16, # Content type: Handshake SSLVersionMajor, SSLVersionMinor, # Protocol version: 3.0 0x00, 0x2f, # Fragment length: 47 0x01, # Message type: ClientHello 0x00, 0x00, 0x2b, # Handshake body length: 43 SSLVersionMajor, SSLVersionMinor, # ClientHello.ProtocolVersion # ClientHello.Random (=32 bytes) 0x50, 0xb5, 0xe1, 0xd5, 0x85, 0xa5, 0x56, 0x20, 0x25, 0x42, 0x84, 0xae, 0x42, 0x21, 0x4f, 0xb1, 0xb9, 0xd9, 0x17, 0xef, 0x3f, 0x70, 0x88, 0x46, 0x8b, 0x0f, 0x29, 0xfb, 0x41, 0xf6, 0x9d, 0x0c, 0x00, # Empty ClientHello.SessionID 0x00, 0x04, # Two cipher suites in ClientHello.CipherSuite: 0x00, 0x05, # SSL_RSA_WITH_RC4_128_SHA 0x00, 0x04, # SSL_RSA_WITH_RC4_128_MD5 0x01, # 1 Compression method: 0x00 # CompressionMethod.null ]); dumpHexadecimal(ClientHello); s.sendall(ClientHello); print "\nReceiving ServerHello:"; ServerHello = s.recv(767); # 767 is indicated by received SSL record, but as it turns out there not that many bytes available dumpHexadecimal(bytearray(ServerHello)); s.close();