Browse Source

SSL Server und SSL Klient für verschlüsselte SSL Verbindungen hinzugefügt

Kolja Strohm 6 years ago
parent
commit
06c5c16553
6 changed files with 595 additions and 121 deletions
  1. 121 1
      Network/Klient.cpp
  2. 36 0
      Network/Klient.h
  3. 7 0
      Network/Network.cpp
  4. 9 9
      Network/Network.vcxproj
  5. 351 111
      Network/Server.cpp
  6. 71 0
      Network/Server.h

+ 121 - 1
Network/Klient.cpp

@@ -224,4 +224,124 @@ Klient *Klient::release()
 	if( !ref )
 		delete this;
 	return 0;
-}
+}
+
+
+// Inhalt der SSLKlient Klasse aus Klient.h
+        // Konstruktor 
+SSLKlient::SSLKlient()
+{
+    ctx = SSL_CTX_new( SSLv23_client_method() );
+    ip = 0;
+    port = 0;
+    bio = BIO_new_ssl_connect( ctx );
+    BIO_get_ssl( bio, &ssl );
+    downStreamBytes = 0;
+    upStreamBytes = 0;
+    connected = 0;
+    ref = 1;
+}
+
+// Destruktor 
+SSLKlient::~SSLKlient()
+{
+    if( this->ip )
+        this->ip->release();
+    if( connected )
+        trenne();
+    SSL_CTX_free( ctx );
+}
+
+bool SSLKlient::verbinde( unsigned short port, const char *ip ) // verbindet mit Server
+{
+    this->port = port;
+    if( this->ip )
+        this->ip->release();
+    this->ip = new Text( ip );
+    Text adr = ip;
+    adr += ":";
+    adr += port;
+    BIO_set_conn_hostname( bio, adr );
+    connected = BIO_do_connect( bio ) > 0;
+    return connected;
+}
+
+bool SSLKlient::sende( const char *nachricht, int len ) // sendet zum Server
+{
+    int ll = 0;
+    while( len > 0 )
+    {
+        int l = SSL_write( ssl, nachricht + ll, len );
+        if( l <= 0 )
+            return 0; // Fehler
+        len -= l;
+        ll += l;
+    }
+    upStreamBytes += ll;
+    return 1;
+}
+
+bool SSLKlient::getNachricht( char *nachricht, int len ) // empfängt Nachricht
+{
+    if( !connected )
+        return 0;
+    int ll = 0;
+    while( len > 0 )
+    {
+        int l = SSL_read( ssl, nachricht + ll, len );
+        if( l <= 0 )
+            return 0; // Fehler
+        len -= l;
+        ll += l;
+    }
+    downStreamBytes += ll;
+    return 1;
+}
+
+int SSLKlient::getDownloadBytes( bool reset ) // gibt die anzahl von empfangen bytes zurück
+{
+    int ret = downStreamBytes;
+    if( reset )
+        downStreamBytes = 0;
+    return ret;
+}
+
+int SSLKlient::getUploadBytes( bool reset ) // gibt die anzahl von versendeter bytes zurück
+{
+    int ret = upStreamBytes;
+    if( reset )
+        upStreamBytes = 0;
+    return ret;
+}
+
+bool SSLKlient::trenne() // Trennt die Verbindung zum Server
+{
+    BIO_ssl_shutdown( bio );
+    connected = 0;
+    return 1;
+}
+
+// constant 
+unsigned short SSLKlient::getServerPort() const // gibt den Port des Servers zurück
+{
+    return port;
+}
+
+const char *SSLKlient::getServerIp() const // gibt die Ip des Servers zurück
+{
+    return ip->getText();
+}
+
+// Reference Counting 
+SSLKlient *SSLKlient::getThis()
+{
+    ref++;
+    return this;
+}
+
+SSLKlient *SSLKlient::release()
+{
+    if( !--ref )
+        delete this;
+    return 0;
+}

+ 36 - 0
Network/Klient.h

@@ -2,6 +2,8 @@
 #define Klient_H
 
 #include "Network.h"
+#include <openssl/bio.h>
+#include <openssl/ssl.h>
 
 namespace Framework
 {
@@ -9,6 +11,8 @@ namespace Framework
 	{
 		class Key;
 	}
+
+    class Text;
 }
 
 using namespace Framework;
@@ -54,6 +58,38 @@ namespace Network
 		__declspec( dllexport ) Klient *getThis();
 		__declspec( dllexport ) Klient *release();
 	};
+
+    class SSLKlient
+    {
+    private:
+        unsigned short port;
+        Text* ip;
+        SSL_CTX* ctx;
+        SSL* ssl;
+        BIO* bio;
+        int downStreamBytes;
+        int upStreamBytes;
+        bool connected;
+        int ref;
+
+    public:
+        // Konstruktor 
+        __declspec( dllexport ) SSLKlient();
+        // Destruktor 
+        __declspec( dllexport ) ~SSLKlient();
+        __declspec( dllexport ) bool verbinde( unsigned short port, const char *ip ); // verbindet mit Server
+        __declspec( dllexport ) bool sende( const char *nachricht, int len ); // sendet zum Server
+        __declspec( dllexport ) bool getNachricht( char *nachricht, int len ); // empfängt Nachricht
+        __declspec( dllexport ) int getDownloadBytes( bool reset ); // gibt die anzahl von empfangen bytes zurück
+        __declspec( dllexport ) int getUploadBytes( bool reset ); // gibt die anzahl von versendeter bytes zurück
+        __declspec( dllexport ) bool trenne(); // Trennt die Verbindung zum Server
+		// constant 
+        __declspec( dllexport ) unsigned short getServerPort() const; // gibt den Port des Servers zurück
+        __declspec( dllexport ) const char *getServerIp() const; // gibt die Ip des Servers zurück
+		// Reference Counting 
+        __declspec( dllexport ) SSLKlient *getThis();
+        __declspec( dllexport ) SSLKlient *release();
+    };
 }
 
 #endif

+ 7 - 0
Network/Network.cpp

@@ -3,6 +3,9 @@
 #include <iostream>
 #include <netdb.h>
 #endif
+#include <openssl/err.h>
+#include <openssl/ssl.h>
+#include <openssl/bio.h>
 
 // Starte Netzwerk
 void Network::Start( int maxClients )
@@ -14,6 +17,10 @@ void Network::Start( int maxClients )
 	if( fehler != 0 )
 		MessageBox( 0, "Win Sock 2.0 konnte nocht gestartet werden.", "Fehler", MB_ICONERROR );
 #endif
+    SSL_library_init();
+    SSL_load_error_strings();
+    ERR_load_BIO_strings();
+    OpenSSL_add_all_algorithms();
 }
 
 void Network::getHostName( char *name, int bufferLen )

+ 9 - 9
Network/Network.vcxproj

@@ -73,22 +73,22 @@
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <LinkIncremental>true</LinkIncremental>
-    <IncludePath>..\..\Framework;$(IncludePath)</IncludePath>
+    <IncludePath>..\..\Framework;..\..\..\OpenSSL\x64\Debug\Include;$(IncludePath)</IncludePath>
     <SourcePath>$(SourcePath)</SourcePath>
     <CustomBuildBeforeTargets>Build</CustomBuildBeforeTargets>
-    <LibraryPath>..\..\Framework\x64\Debug;$(LibraryPath)</LibraryPath>
+    <LibraryPath>..\..\Framework\x64\Debug;..\..\..\OpenSSL\x64\Debug\lib;$(LibraryPath)</LibraryPath>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <LinkIncremental>false</LinkIncremental>
     <CustomBuildBeforeTargets>Build</CustomBuildBeforeTargets>
-    <IncludePath>..\..\Framework;$(IncludePath)</IncludePath>
-    <LibraryPath>..\..\Framework\Release;$(LibraryPath)</LibraryPath>
+    <IncludePath>..\..\..\OpenSSL\x32\Release\include;..\..\Framework;$(IncludePath)</IncludePath>
+    <LibraryPath>..\..\..\OpenSSL\x32\Release\lib;..\..\Framework\Release;$(LibraryPath)</LibraryPath>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <LinkIncremental>false</LinkIncremental>
     <CustomBuildBeforeTargets>Build</CustomBuildBeforeTargets>
-    <IncludePath>..\..\Framework;$(IncludePath)</IncludePath>
-    <LibraryPath>..\..\Framework\x64\Release;$(LibraryPath)</LibraryPath>
+    <IncludePath>..\..\..\OpenSSL\x64\Release\include;..\..\Framework;$(IncludePath)</IncludePath>
+    <LibraryPath>..\..\..\OpenSSL\x64\Release\lib;..\..\Framework\x64\Release;$(LibraryPath)</LibraryPath>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
@@ -115,7 +115,7 @@
     <Link>
       <SubSystem>Windows</SubSystem>
       <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalDependencies>Ws2_32.lib;Framework.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>Crypt32.lib;libcrypto.lib;libssl.lib;Ws2_32.lib;Framework.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
     <CustomBuildStep>
       <Command>copy "..\x64\Debug\Network.dll" "..\..\..\Spiele Platform\Klient\Start\Start\network.dll"
@@ -141,7 +141,7 @@ copy "..\x64\Debug\Network.dll" "..\..\..\Spiele Platform\Klient\Fertig\Debug\x6
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>Ws2_32.lib;Framework.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>Crypt32.lib;libcrypto.lib;libssl.lib;Ws2_32.lib;Framework.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
     <CustomBuildStep>
       <Command>copy "..\Release\Network.dll" "..\..\..\Spiele Platform\Klient\Fertig\x32\network.dll"
@@ -165,7 +165,7 @@ copy "..\Release\Network.dll" "..\..\..\Spiele Platform\SMP\Fertig\x32\network.d
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>Ws2_32.lib;Framework.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>Crypt32.lib;libcrypto.lib;libssl.lib;Ws2_32.lib;Framework.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
     <CustomBuildStep>
       <Command>copy "..\x64\Release\Network.dll" "..\..\..\Spiele Platform\Klient\Fertig\x64\network.dll"

+ 351 - 111
Network/Server.cpp

@@ -3,6 +3,7 @@
 #include <string.h>
 #endif
 #include <Key.h>
+#include <Text.h>
 
 using namespace Network;
 
@@ -10,147 +11,147 @@ using namespace Network;
 // Konstruktor 
 Server::Server()
 {
-	sock = 0;
-	memset( &addresse, 0, sizeof( addresse ) ); // Adresse setzen
-	addresse.sin_family = AF_INET;
-	addresse.sin_addr.s_addr = ADDR_ANY;
-	ref = 1;
-	klients = 0;
+    sock = 0;
+    memset( &addresse, 0, sizeof( addresse ) ); // Adresse setzen
+    addresse.sin_family = AF_INET;
+    addresse.sin_addr.s_addr = ADDR_ANY;
+    ref = 1;
+    klients = 0;
 }
 
 // Destruktor 
 Server::~Server()
 {
-
+    trenne();
 }
 
 // nicht constant 
 bool Server::verbinde( unsigned short port, int warteschlangenLen ) // Öffnet das Socket
 {
-	sock = socket( AF_INET, SOCK_STREAM, 0 ); // Socket erstellen
-	addresse.sin_port = htons( port ); // port setzen
-	if( bind( sock, ( struct sockaddr* )&addresse, sizeof( addresse ) ) == -1 ) // socket öffnen
-		return 0; // Fehler
-	if( listen( sock, warteschlangenLen ) == -1 ) // Klients annehmen
-		return 0; // Fehler
-	return 1;
+    sock = socket( AF_INET, SOCK_STREAM, 0 ); // Socket erstellen
+    addresse.sin_port = htons( port ); // port setzen
+    if( bind( sock, ( struct sockaddr* )&addresse, sizeof( addresse ) ) == -1 ) // socket öffnen
+        return 0; // Fehler
+    if( listen( sock, warteschlangenLen ) == -1 ) // Klients annehmen
+        return 0; // Fehler
+    return 1;
 }
 
 SKlient *Server::getKlient() // nimmt Klient an
 {
-	if( !sock )
-		return 0;
-	sockaddr_in client;
-	int len = sizeof( addresse );
+    if( !sock )
+        return 0;
+    sockaddr_in client;
+    int len = sizeof( addresse );
 #ifdef WIN32
-	SOCKET cls = accept( sock, (sockaddr*)&client, &len ); // Klient empfangen
-	if( cls == INVALID_SOCKET )
-		return 0;
+    SOCKET cls = accept( sock, (sockaddr*)&client, &len ); // Klient empfangen
+    if( cls == INVALID_SOCKET )
+        return 0;
 #else
-	SOCKET cls = accept( sock, (sockaddr*)&client, (socklen_t*)&len ); // Klient empfangen
-	if( !cls )
-		return 0;
+    SOCKET cls = accept( sock, (sockaddr*)&client, (socklen_t*)&len ); // Klient empfangen
+    if( !cls )
+        return 0;
 #endif
-	client.sin_port = addresse.sin_port;
-	klients++;
-	return new SKlient( client, cls ); // Klient Handle Klasse zurückgeben
+    client.sin_port = addresse.sin_port;
+    klients++;
+    return new SKlient( client, cls ); // Klient Handle Klasse zurückgeben
 }
 
 int Server::getKlients( bool reset ) // gibt die Anzahl der Klients zurück
 {
-	int ret = klients;
-	if( reset )
-		klients = 0;
-	return ret;
+    int ret = klients;
+    if( reset )
+        klients = 0;
+    return ret;
 }
 
 bool Server::trenne() // beendet den Server
 {
-	if( !sock )
-		return 1;
-	if( closesocket( sock ) < 0 ) // socket schließen
-		return 0;
-	sock = 0;
-	return 1;
+    if( !sock )
+        return 1;
+    if( closesocket( sock ) < 0 ) // socket schließen
+        return 0;
+    sock = 0;
+    return 1;
 }
 
 // constant
 unsigned short Server::getPort() const // gibt den Port zurück
 {
-	return htons( addresse.sin_port );
+    return htons( addresse.sin_port );
 }
 
 // Reference Counting 
 Server *Server::getThis()
 {
-	ref++;
-	return this;
+    ref++;
+    return this;
 }
 
 Server *Server::release()
 {
-	ref--;
-	if( !ref )
-		delete this;
-	return 0;
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
 }
 
 // Inhalt der SKlient Klasse aus Server.h
 // Konstruktor 
 SKlient::SKlient( sockaddr_in addresse, SOCKET sock )
 {
-	clientAddr = addresse;
-	this->sock = sock;
-	ref = 1;
-	downStreamBytes = 0;
-	upStreamBytes = 0;
-	sendeKey = 0;
-	empfangKey = 0;
+    clientAddr = addresse;
+    this->sock = sock;
+    ref = 1;
+    downStreamBytes = 0;
+    upStreamBytes = 0;
+    sendeKey = 0;
+    empfangKey = 0;
 }
 
 // Destruktor 
 SKlient::~SKlient()
 {
     trenne();
-	if( sendeKey )
-		sendeKey->release();
-	if( empfangKey )
-		empfangKey->release();
+    if( sendeKey )
+        sendeKey->release();
+    if( empfangKey )
+        empfangKey->release();
 }
 
 // nicht constant 
 void SKlient::setSendeKeyZ( Encryption::Key *key ) // Setzt den Key fürs Senden
 {
-	if( sendeKey )
-		sendeKey->release();
-	sendeKey = key;
+    if( sendeKey )
+        sendeKey->release();
+    sendeKey = key;
 }
 
 void SKlient::setEmpfangKeyZ( Encryption::Key *key ) // Setzt den Key fürs Empfangen
 {
-	if( empfangKey )
-		empfangKey->release();
-	empfangKey = key;
+    if( empfangKey )
+        empfangKey->release();
+    empfangKey = key;
 }
 
 void SKlient::setSendeKey( char *key, int len ) // Setzt den Key fürs Senden
 {
-	if( !sendeKey )
-		sendeKey = new Encryption::Key();
-	sendeKey->setKey( key, len );
+    if( !sendeKey )
+        sendeKey = new Encryption::Key();
+    sendeKey->setKey( key, len );
 }
 
 void SKlient::setEmpfangKey( char *key, int len ) // Setzt den Key fürs Empfangen
 {
-	if( !empfangKey )
-		empfangKey = new Encryption::Key();
-	empfangKey->setKey( key, len );
+    if( !empfangKey )
+        empfangKey = new Encryption::Key();
+    empfangKey->setKey( key, len );
 }
 
 bool SKlient::sende( const char *nachricht, int len ) // sendet zum Klient
 {
-	if( !sock )
-		return 0;
+    if( !sock )
+        return 0;
     int ll = 0;
     while( len > 0 )
     {
@@ -164,14 +165,14 @@ bool SKlient::sende( const char *nachricht, int len ) // sendet zum Klient
         len -= l;
         ll += l;
     }
-	upStreamBytes += ll;
-	return 1;
+    upStreamBytes += ll;
+    return 1;
 }
 
 bool SKlient::getNachricht( char *nachricht, int len ) // empfängt Nachricht von Klient
 {
-	if( !sock )
-		return 0;
+    if( !sock )
+        return 0;
     int ll = 0;
     while( len > 0 )
     {
@@ -181,16 +182,16 @@ bool SKlient::getNachricht( char *nachricht, int len ) // empf
         len -= l;
         ll += l;
     }
-	downStreamBytes += ll;
-	return 1;
+    downStreamBytes += ll;
+    return 1;
 }
 
 bool SKlient::sendeEncrypted( const char *nachricht, int len ) // sendet zum Server
 {
-	if( !sendeKey )
-		return sende( nachricht, len );
-	Encryption::Bytes *n = new Encryption::Bytes( nachricht, len );
-	sendeKey->codieren( n->getThis() ); int ll = 0;
+    if( !sendeKey )
+        return sende( nachricht, len );
+    Encryption::Bytes *n = new Encryption::Bytes( nachricht, len );
+    sendeKey->codieren( n->getThis() ); int ll = 0;
     while( len > 0 )
     {
 #ifdef WIN32
@@ -207,14 +208,14 @@ bool SKlient::sendeEncrypted( const char *nachricht, int len ) // sendet zum Ser
         ll += l;
     }
     upStreamBytes += ll;
-	n->release();
-	return 1;
+    n->release();
+    return 1;
 }
 
 bool SKlient::getNachrichtEncrypted( char *nachricht, int len ) // empfängt Nachricht
 {
-	if( !empfangKey )
-		return getNachricht( nachricht, len );
+    if( !empfangKey )
+        return getNachricht( nachricht, len );
     int ll = 0;
     while( len > 0 )
     {
@@ -224,61 +225,300 @@ bool SKlient::getNachrichtEncrypted( char *nachricht, int len ) // empf
         len -= l;
         ll += l;
     }
-	Encryption::Bytes *n = new Encryption::Bytes();
-	n->setBytesZ( nachricht, ll );
-	empfangKey->decodieren( n );
-	downStreamBytes += ll;
-	return 1;
+    Encryption::Bytes *n = new Encryption::Bytes();
+    n->setBytesZ( nachricht, ll );
+    empfangKey->decodieren( n );
+    downStreamBytes += ll;
+    return 1;
 }
 
 int SKlient::getDownloadBytes( bool reset ) // gibt die anzahl von empfangen bytes zurück
 {
-	int ret = downStreamBytes;
-	if( reset )
-		downStreamBytes = 0;
-	return ret;
+    int ret = downStreamBytes;
+    if( reset )
+        downStreamBytes = 0;
+    return ret;
 }
 
 int SKlient::getUploadBytes( bool reset ) // gibt die anzahl von versendeter bytes zurück
 {
-	int ret = upStreamBytes;
-	if( reset )
-		upStreamBytes = 0;
-	return ret;
+    int ret = upStreamBytes;
+    if( reset )
+        upStreamBytes = 0;
+    return ret;
 }
 
 bool SKlient::trenne() // trennt die Verbindung zum Klient
 {
-	if( !sock )
-		return 0;
-	if( closesocket( sock ) < 0 ) // trennen
-		return 0;
-	sock = 0;
-	return 1;
+    if( !sock )
+        return 0;
+    if( closesocket( sock ) < 0 ) // trennen
+        return 0;
+    sock = 0;
+    return 1;
 }
 
 // constant 
 unsigned short SKlient::getPort() const // gibt den Port zurück
 {
-	return htons( clientAddr.sin_port );
+    return htons( clientAddr.sin_port );
 }
 
 const char *SKlient::getIp() const // gibt die Ip des Klients zurück
 {
-	return inet_ntoa( clientAddr.sin_addr );
+    return inet_ntoa( clientAddr.sin_addr );
 }
 
 // Reference Counting 
 SKlient *SKlient::getThis()
 {
-	ref++;
-	return this;
+    ref++;
+    return this;
 }
 
 SKlient *SKlient::release()
 {
-	ref--;
-	if( !ref )
-		delete this;
-	return 0;
-}
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}
+
+int pem_passwd_cb( char *buf, int size, int rwflag, void *userdata )
+{
+    const char *passw = ( (Text*)userdata )->getText();
+    memcpy( buf, passw, MIN( (unsigned int)size, strlen( passw ) + 1 ) );
+    return (int)strlen( buf );
+}
+
+// Inhalt der SSLServer Klasse
+// Konstruktor 
+SSLServer::SSLServer()
+{
+    s = 0;
+    ctx = SSL_CTX_new( SSLv23_server_method() );
+    SSL_CTX_set_default_passwd_cb( ctx, pem_passwd_cb );
+    passw = new Text();
+    SSL_CTX_set_default_passwd_cb_userdata( ctx, passw );
+    addr.sin_family = AF_INET;
+    addr.sin_addr.s_addr = htonl( INADDR_ANY );
+    klients = 0;
+    ref = 1;
+}
+
+// Destruktor 
+SSLServer::~SSLServer()
+{
+    trenne();
+    passw->release();
+}
+
+// nicht constant 
+// Setzt den Pfad zur Datei, in dem das Certifikat gespeichert ist
+bool SSLServer::setCertificateFile( const char *file )
+{
+    return SSL_CTX_use_certificate_file( ctx, file, SSL_FILETYPE_PEM ) > 0;
+}
+
+// Setzt den Pfad zur Datei, in dem der private Schlüssel gespeichert ist
+bool SSLServer::setPrivateKeyFile( const char *file )
+{
+    return SSL_CTX_use_PrivateKey_file( ctx, file, SSL_FILETYPE_PEM ) > 0;
+}
+
+// setzt das passwort des private keys (muss vor setPrivateKeyFile aufgerufen werden)
+void SSLServer::setPrivateKeyPassword( const char *password )
+{
+    passw->setText( password );
+}
+
+// Öffnet das Socket
+bool SSLServer::verbinde( unsigned short port, int warteschlangenLen )
+{
+    addr.sin_port = htons( port );
+    s = socket( AF_INET, SOCK_STREAM, 0 );
+    if( s < 0 )
+        return 0;
+    if( bind( s, ( struct sockaddr* )&addr, sizeof( addr ) ) < 0 )
+        return 0;
+    if( listen( s, warteschlangenLen ) < 0 )
+        return 0;
+    return 1;
+}
+
+// nimmt Klient an
+SSLSKlient *SSLServer::getKlient()
+{
+    if( !s )
+        return 0;
+    int len = sizeof( addr );
+    struct sockaddr_in addr;
+#ifdef WIN32
+    SOCKET client = accept( s, ( struct sockaddr* )&addr, &len );
+    if( client == INVALID_SOCKET )
+        return 0;
+#else
+    SOCKET client = accept( s, (sockaddr*)&addr, (socklen_t*)&len ); // Klient empfangen
+    if( !client )
+        return 0;
+#endif
+    addr.sin_port = this->addr.sin_port;
+    SSL *ssl = SSL_new( ctx );
+    SSL_set_fd( ssl, (int)client );
+    if( SSL_accept( ssl ) <= 0 )
+    {
+        SSL_free( ssl );
+        closesocket( client );
+        return 0;
+    }
+    klients++;
+    return new SSLSKlient( addr, ssl, client );
+}
+
+// gibt die Anzahl der Klients zurück
+int SSLServer::getKlients( bool reset )
+{
+    int ret = klients;
+    if( reset )
+        klients = 0;
+    return ret;
+}
+
+// beendet den Server
+bool SSLServer::trenne()
+{
+    if( !s )
+        return 1;
+    if( closesocket( s ) < 0 ) // socket schließen
+        return 0;
+    s = 0;
+    return 1;
+}
+
+// constant
+// gibt den Port zurück
+unsigned short SSLServer::getPort() const
+{
+    return htons( addr.sin_port );
+}
+
+// Reference Counting 
+SSLServer *SSLServer::getThis()
+{
+    ref++;
+    return this;
+}
+
+SSLServer *SSLServer::release()
+{
+    if( !--ref )
+        delete this;
+    return 0;
+}
+
+
+// Inhalt der SSLSKlient Klasse
+// Konstruktor 
+SSLSKlient::SSLSKlient( sockaddr_in client, SSL *ssl, SOCKET s )
+{
+    this->s = s;
+    clientAddr = client;
+    this->ssl = ssl;
+    downStreamBytes = 0;
+    upStreamBytes = 0;
+    ref = 1;
+}
+
+// Destruktor 
+SSLSKlient::~SSLSKlient()
+{
+    trenne();
+}
+
+// nicht constant 
+bool SSLSKlient::sende( const char *nachricht, int len ) // sendet zum Klient
+{
+    if( !ssl )
+        return 0;
+    int ll = 0;
+    while( len > 0 )
+    {
+        int l = SSL_write( ssl, nachricht + ll, len );
+        if( l <= 0 )
+            return 0; // Fehler
+        len -= l;
+        ll += l;
+    }
+    upStreamBytes += ll;
+    return 1;
+}
+
+bool SSLSKlient::getNachricht( char *nachricht, int len ) // empfängt Nachricht von Klient
+{
+    if( !ssl )
+        return 0;
+    int ll = 0;
+    while( len > 0 )
+    {
+        int l = (int)SSL_read( ssl, nachricht + ll, len );
+        if( l <= 0 )
+            return 0; // Fehler
+        len -= l;
+        ll += l;
+    }
+    downStreamBytes += ll;
+    return 1;
+}
+
+int SSLSKlient::getDownloadBytes( bool reset ) // gibt die anzahl von empfangen bytes zurück
+{
+    int ret = downStreamBytes;
+    if( reset )
+        downStreamBytes = 0;
+    return ret;
+}
+
+int SSLSKlient::getUploadBytes( bool reset ) // gibt die anzahl von versendeter bytes zurück
+{
+    int ret = upStreamBytes;
+    if( reset )
+        upStreamBytes = 0;
+    return ret;
+}
+
+bool SSLSKlient::trenne() // trennt die Verbindung zum Klient
+{
+    if( !ssl )
+        return 0;
+    SSL_free( ssl );
+    if( closesocket( s ) < 0 ) // trennen
+        return 0;
+    ssl = 0;
+    s = 0;
+    return 1;
+}
+
+// constant 
+unsigned short SSLSKlient::getPort() const // gibt den Port zurück
+{
+    return htons( clientAddr.sin_port );
+}
+
+const char *SSLSKlient::getIp() const // gibt die Ip des Klients zurück
+{
+    return inet_ntoa( clientAddr.sin_addr );
+}
+
+// Reference Counting 
+SSLSKlient *SSLSKlient::getThis()
+{
+    ref++;
+    return this;
+}
+
+SSLSKlient *SSLSKlient::release()
+{
+    if( !--ref )
+        delete this;
+    return 0;
+}

+ 71 - 0
Network/Server.h

@@ -2,6 +2,7 @@
 #define Server_H
 
 #include "Network.h"
+#include <openssl/ssl.h>
 
 namespace Framework
 {
@@ -9,6 +10,7 @@ namespace Framework
 	{
 		class Key;
 	}
+    class Text;
 }
 
 using namespace Framework;
@@ -78,6 +80,75 @@ namespace Network
 		__declspec( dllexport ) SKlient *getThis();
 		__declspec( dllexport ) SKlient *release();
 	};
+
+    class SSLSKlient;
+
+    class SSLServer
+    {
+    private:
+        SOCKET s;
+        SOCKADDR_IN addr;
+        SSL_CTX *ctx;
+        Text *passw;
+        int klients;
+        int ref;
+
+    public:
+        // Konstruktor 
+        __declspec( dllexport ) SSLServer();
+        // Destruktor 
+        __declspec( dllexport ) ~SSLServer();
+        // nicht constant 
+        // Setzt den Pfad zur Datei, in dem das Certifikat gespeichert ist
+        __declspec( dllexport ) bool setCertificateFile( const char *file );
+        // Setzt den Pfad zur Datei, in dem der private Schlüssel gespeichert ist
+        __declspec( dllexport ) bool setPrivateKeyFile( const char *file );
+        // setzt das passwort des private keys (muss vor setPrivateKeyFile aufgerufen werden)
+        __declspec( dllexport ) void setPrivateKeyPassword( const char *password );
+        // Öffnet das Socket
+        __declspec( dllexport ) bool verbinde( unsigned short port, int warteschlangenLen );
+        // nimmt Klient an
+        __declspec( dllexport ) SSLSKlient *getKlient(); 
+        // gibt die Anzahl der Klients zurück
+        __declspec( dllexport ) int getKlients( bool reset ); 
+        // beendet den Server
+        __declspec( dllexport ) bool trenne();
+        // constant
+        // gibt den Port zurück
+        __declspec( dllexport ) unsigned short getPort() const; 
+        // Reference Counting 
+        __declspec( dllexport ) SSLServer *getThis();
+        __declspec( dllexport ) SSLServer *release();
+    };
+
+    class SSLSKlient
+    {
+    private:
+        SOCKET s;
+        SSL* ssl;
+        sockaddr_in clientAddr;
+        int downStreamBytes;
+        int upStreamBytes;
+        int ref;
+
+    public:
+        // Konstruktor 
+        __declspec( dllexport ) SSLSKlient( sockaddr_in client, SSL *ssl, SOCKET s );
+        // Destruktor 
+        __declspec( dllexport ) ~SSLSKlient();
+        // nicht constant 
+        __declspec( dllexport ) bool sende( const char *nachricht, int len ); // sendet zum Klient
+        __declspec( dllexport ) bool getNachricht( char *nachricht, int len ); // empfängt Nachricht von Klient
+        __declspec( dllexport ) int getDownloadBytes( bool reset ); // gibt die anzahl von empfangen bytes zurück
+        __declspec( dllexport ) int getUploadBytes( bool reset ); // gibt die anzahl von versendeter bytes zurück
+        __declspec( dllexport ) bool trenne(); // trennt die Verbindung zum Klient
+		// constant 
+        __declspec( dllexport ) unsigned short getPort() const; // gibt den Port zurück
+        __declspec( dllexport ) const char *getIp() const; // gibt die Ip des Klients zurück
+        // Reference Counting 
+        __declspec( dllexport ) SSLSKlient *getThis();
+        __declspec( dllexport ) SSLSKlient *release();
+    };
 }
 
 #endif