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 }