1 module ssl.openssl;
2 
3 import loader.loader;
4 
5 import core.stdc.config;
6 import core.stdc.string : strlen;
7 
8 struct SSL_CTX;
9 struct SSL;
10 struct SSL_METHOD;
11 struct X509_STORE_CTX;
12 
13 enum SSL_VERIFY_NONE = 0x00; // From Deimos bindings
14 
15 extern(C)
16 {
17 	alias VerifyCallback = int function(int, X509_STORE_CTX*);
18 
19 	int function() SSL_library_init;
20 	void function() OPENSSL_add_all_algorithms_noconf;
21 	void function() SSL_load_error_strings;
22 	int function(const SSL *ssl, int ret) SSL_get_error;
23 
24 	char* function(c_ulong e, char* buf) ERR_error_string;
25 
26 	SSL_CTX* function(const(SSL_METHOD)* meth) SSL_CTX_new;
27 	const(SSL_METHOD)* function() SSLv3_client_method; /* SSLv3 */
28 
29 	SSL* function(SSL_CTX* ctx) SSL_new;
30 	int function(SSL* s, int fd) SSL_set_fd;
31 	void function(SSL *s, int mode, VerifyCallback verify_callback) SSL_set_verify;
32 	int function(SSL* ssl) SSL_connect;
33 	int function(SSL* ssl,void* buf,int num) SSL_read;
34 	int function(SSL* ssl,const(void)* buf,int num) SSL_write;
35 
36 
37 }
38 
39 void loadOpenSSL()
40 {
41 	static bool loaded = false;
42 	if(loaded)
43 		return;
44 
45 	auto ssl = DynamicLibrary("ssleay32");
46 
47 	ssl.resolve!SSL_library_init;
48 	ssl.resolve!SSL_load_error_strings;
49 	ssl.resolve!SSL_get_error;
50 
51 	ssl.resolve!SSL_CTX_new;
52 	ssl.resolve!SSLv3_client_method;
53 	
54 	ssl.resolve!SSL_new;
55 	ssl.resolve!SSL_set_fd;
56 	ssl.resolve!SSL_set_verify;
57 	ssl.resolve!SSL_connect;
58 	ssl.resolve!SSL_read;
59 	ssl.resolve!SSL_write;
60 
61 	auto lib = DynamicLibrary("libeay32");
62 	lib.resolve!OPENSSL_add_all_algorithms_noconf;
63 	lib.resolve!ERR_error_string;
64 
65 	SSL_library_init();
66 	OPENSSL_add_all_algorithms_noconf();
67 	SSL_load_error_strings();
68 
69 	loaded = true;
70 }
71 
72 /**
73  * Thrown if an SSL error occurs.
74  */
75 class OpenSSLException : Exception
76 {
77 	private:
78 	int error_;
79 
80 	public:
81 	this(string msg, int error, string file = __FILE__, size_t line = __LINE__)
82 	{
83 		error_ = error;
84 		super(msg, file, line);
85 	}
86 
87 	int error() @property
88 	{
89 		return error_;
90 	}
91 }
92 
93 int sslEnforce(const SSL* ssl, int result, string file = __FILE__, size_t line = __LINE__)
94 {
95 	if(result < 0)
96 	{
97 		auto error = SSL_get_error(ssl, result);
98 
99 		char* zMsg = ERR_error_string(error, null);
100 
101 		auto msg = zMsg[0 .. strlen(zMsg)].idup;
102 
103 		throw new OpenSSLException(msg, error, file, line);
104 	}
105 
106 	return result;
107 }