/* This is CLIENT only at this point. Don't try to bind/accept with these. FIXME: Windows isn't implemented On Windows, it uses Microsoft schannel so it doesn't need openssl or gnutls as a dependency. On other platforms, it uses the openssl api, which should work with both openssl and gnutls. btw, interesting: http://msdn.microsoft.com/en-us/library/windows/desktop/aa364510%28v=vs.85%29.aspx */ public import std.socket; // see also: // http://msdn.microsoft.com/en-us/library/aa380536%28v=vs.85%29.aspx import deimos.openssl.ssl; static this() { SSL_library_init(); OpenSSL_add_all_algorithms(); SSL_load_error_strings(); } pragma(lib, "crypto"); pragma(lib, "ssl"); class OpenSslSocket : Socket { private SSL* ssl; private SSL_CTX* ctx; private void initSsl() { ctx = SSL_CTX_new(SSLv3_client_method()); assert(ctx !is null); ssl = SSL_new(ctx); SSL_set_fd(ssl, this.handle); } @trusted override void connect(Address to) { super.connect(to); if(SSL_connect(ssl) == -1) throw new Exception("ssl connect"); } @trusted override ptrdiff_t send(const(void)[] buf, SocketFlags flags) { return SSL_write(ssl, buf.ptr, cast(uint) buf.length); } override ptrdiff_t send(const(void)[] buf) { return send(buf, SocketFlags.NONE); } @trusted override ptrdiff_t receive(void[] buf, SocketFlags flags) { return SSL_read(ssl, buf.ptr, cast(int)buf.length); } override ptrdiff_t receive(void[] buf) { return receive(buf, SocketFlags.NONE); } this(AddressFamily af) { super(af, SocketType.STREAM); initSsl(); } this(socket_t sock, AddressFamily af) { super(sock, af); initSsl(); } ~this() { SSL_free(ssl); SSL_CTX_free(ctx); } } version(ssl_test) void main() { auto sock = new OpenSslSocket(AddressFamily.INET); sock.connect(new InternetAddress("localhost", 443)); sock.send("GET / HTTP/1.0\r\n\r\n"); import std.stdio; char[1024] buffer; writeln(buffer[0 .. sock.receive(buffer)]); }