1 module ssl.socket; 2 3 import std.exception; 4 import std.socket; 5 6 import ssl.openssl; 7 8 version(force_ssl_load) shared static this() 9 { 10 loadOpenSSL(); 11 } 12 13 private SSL_CTX* sslContext; 14 15 void initSslContext() 16 { 17 if(!sslContext) 18 sslContext = SSL_CTX_new_p(SSLv23_client_method_p()); 19 } 20 21 version(force_ssl_load) static this() 22 { 23 initSslContext(); 24 } 25 26 /** 27 * Represents a secure TCP socket using SSLv3. 28 */ 29 class SslSocket : Socket 30 { 31 private: 32 SSL* ssl; 33 34 public: 35 /** 36 * Create a new unconnected and blocking SSL socket. 37 * See_Also: 38 * $(DPREF client, IrcClient.this) 39 */ 40 this(AddressFamily af) 41 { 42 loadOpenSSL(); 43 initSslContext(); 44 45 super(af, SocketType.STREAM, ProtocolType.TCP); 46 47 ssl = SSL_new_p(sslContext); 48 SSL_set_fd_p(ssl, super.handle); 49 SSL_set_verify_p(ssl, SSL_VERIFY_NONE, null); 50 } 51 52 override: 53 void connect(Address to) @trusted 54 { 55 super.connect(to); 56 sslEnforce(ssl, SSL_connect_p(ssl)); 57 } 58 59 ptrdiff_t receive(void[] buf) 60 { 61 return receive(buf, SocketFlags.NONE); 62 } 63 64 ptrdiff_t receive(void[] buf, SocketFlags flags) @trusted 65 { 66 auto result = sslEnforce(ssl, SSL_read_p(ssl, buf.ptr, cast(int)buf.length)); 67 return cast(ptrdiff_t)result; 68 } 69 70 ptrdiff_t send(const(void)[] buf) 71 { 72 return send(buf, SocketFlags.NONE); 73 } 74 75 ptrdiff_t send(const(void)[] buf, SocketFlags flags) @trusted 76 { 77 auto result = sslEnforce(ssl, SSL_write_p(ssl, buf.ptr, cast(int)buf.length)); 78 return cast(ptrdiff_t)result; 79 } 80 81 // TODO: What about sendTo? Throwing stub? 82 } 83