[Boost-Asio] SSL Socket Beispiel
-
Hallo Gemeinde,
ich habe mir dieses Beispiel mal angeschaut: http://www.boost.org/doc/libs/1_43_0/doc/html/boost_asio/example/ssl/server.cpp und es versucht zum laufen zu bekommen, jedoch erfolglos. Das Programm lässt sich problemlos kompilieren, jedoch bekomme ich zur Laufzeit einen Fehler, den ich nicht richtig deuten kann. Beim Starten des Programms bekomme ich eine Exception ab:
Exception: Invalid argument
Ich konnte den Fehler auf folgende Zeilen Code einschrängen:
context_.set_options( boost::asio::ssl::context::default_workarounds | boost::asio::ssl::context::no_sslv2 | boost::asio::ssl::context::single_dh_use); context_.set_password_callback(boost::bind(&server::get_password, this)); context_.use_certificate_chain_file("ca_cert.pem"); context_.use_private_key_file("ca_cert.pem", boost::asio::ssl::context::pem); context_.use_tmp_dh_file("dh512.pem");Ich habe den Eindruck, das ich irgendwas mit den Zertifikaten falsch gemacht habe, jedoch weiß ich auch nicht so richtig was... Ich habe die Zertifikate mit OpenSSL erstellen und auch die Lib gegen das Programm gelinkt.
Ich muss dazu sagen, ich bin neu in der SSL-Materie...
Root Certificate
openssl req -new -x509 -keyout ssl_priv.pem -out ca_cert.pem -days 3650Diffie-Hellmann
openssl dhparam -out dh1024.pem 512Weiß jemand wo da der Fehler ist? Für mich ist die Boost-Doku da leider nicht ausreichend und andere Beispiele bekommt man auch nicht wirklich hinterher geschmissen.
Das Beispiel, ist 100% Copy & Paste um Tippfehler zu vermeiden.
Vielen Dank für die Hilfe.
so long
jd
-
Ich kenne mich mit Boost nicht aus, aber anscheinend gehts ja um einen fehlerhaften Parameter. Ich könnte mir nur vorstellen, dass es an server::get_password liegt. Vielleicht verträgt das Ding kein std::string und verlangt einen char *. Da ja bind benutzt wird könnte es ja sein, dass der Fehler sich daher erst zur Laufzeit äußert.
Aber wie gesagt, habe keine Ahnung von Boost. War nur eine spontante Idee.
-
Hallo Geminede,
ich habe mein Problem gelöst. Die Fehler waren die Zertifikate... Da es von Boost nicht genauer dokumentiert ist, weil es auch nicht dahin gehört und somit das wissen vorrausgesetzt wird, hier einige Infos zu dem Thema, wie ich das Problem gelöst habe:
Ein Knackpunkt ist das Certificate Chain File was nichts anderes ist als das Server-Zertifikat und den Server-Key in eine Datei zu klatschen... Wichtig ist auch die Erstellung der Zertifikate, die habe ich nach folgendem HowTo gemacht (Common Name habe ich bei mir den FQDN genommen und mich vom Client dann nach localhost connected):
http://mathias-kettner.de/lw_ca_zertifikat_erstellen.htmlDa ich nur Linux besitze, hier der Code um die Chain zu basteln, sollte aber unter Windows und Mac ähnlich laufen:
cat servercert.pem > server.pem cat serverkey.pem >> server.pemSomit akzeptiert Boost das Chain-File und den Private-Key. Für den Client nimmt man dann einfach das cacert.pem File (erstellt nach dem oberen Link)
Somit funktioniert das Server + Client Example von Boost. Eine Implementierung mit Echten (gültigen) Zertifikaten ist kein Problem.
Ich bin gerade dabei meine Kommunikation auf SSL umzustellen und muss sagen bis her keine Probleme (wenn man weiß wir das mit den Zertifikaten läuft).PS: Was etwas mist ist, sind die Exceptions: Invalid argument durch meine Erfahrung bis hierher ist das Problem das Zertifikat!
Ich habe mir auch ein eBook gekauft, welches ich euch nicht vorenthalten will, dort erfährt man sehr viel über Cryptographie, deren anwendung nutzen und schwächen: http://www.amazon.de/Angewandte-Kryptographie-Klassiker-Protokolle-Algorithmen/dp/3827372283/ref=sr_1_2?ie=UTF8&s=books&qid=1276712224&sr=8-2-spell
Ich hoffe ich habe hier jemanden weitergeholfen, da zu dem Theme die Internet suche recht frustrierend ist!
Viel Spass
so long
jdEDIT: Ganz wichtig die Pfade zu den Zertifikation sollten Stammrelativ sein... (/home/jan/projects/ssl-server/build/bin/server.pem)
-
ich habe das beispiel mit server mal ausprobiert
aber ich bekomme riesige mengen von fehlern
Ve1>Server.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "_SSLv23_server_method" in Funktion ""public: void __thiscall boost::asio::ssl::detail::openssl_context_service::create(struct ssl_ctx_st * &,enum boost::asio::ssl::context_base::method)" (?create@openssl_context_service@detail@ssl@asio@boost@@QAEXAAPAUssl_ctx_st@@W4method@context_base@345@@Z)".
und das 48 mal, diese verweise
ich hatte vor ssl socket in einer dll zu verwenden.
ein anderes programm soll eine funktion aus der dll aufrufen, die diese socketverbindung über ssl herstellt, die dll empfängt das signal, wenn die funktion aufgerufen wird, und soll als rückgabewert einen string liefern
und das "andere programm" die daten mitteilen,aber was ist das für ein fehler?
und bei der dll gibt es da eine main ? oder wie läuft das?
könnte mir jemand ein codebeispiel zeigen, das ich einfach nur komplieren bräuchte, bin eher in java zuhause und habe von c++ wenig ahnung, brauche aber diese dll
-
Der Fehler sagt, das du eine Lib nicht, oder falsch gelinkt hast. Ich vermute mal das du nicht gegen SSL gelinkt hast... Wenn du boost::asio mit SSL verwendest benötigst du OpenSSL. http://www.openssl.org/
-
openssl habe ich
unter http://www.openssl.org/source/openssl-1.0.0c.tar.gz habe ich das paket unter openssl/inculde mit include versehen, aber gelinkt habe ich openssl nicht weil in der entpackten openssl-1.0.0c.tar.gz keine *.lib dateien sind
-
juhuu habs hingekriegt, die dll is geschrieben worden,
leider weiss ich nicht was ich mit der funktion main(int argc, char* argv[]) mache?
die soll doch bei einem standardprogramm der einsteigespunkt sein , oder?
wenn ich jetzt ne dll habe weiss ich aus der hilfe das
// Dies ist das Beispiel einer exportierten Funktion.
OE_API int fnoe(void)
{
return 42;
}dies eine funktion ist, die man extern in der dll aufrufen kann und die einen rückgabewert liefert
, aber ich hätte jetzt gerne , das in der fnoe die main aufgerufen wird und der rückgabewert ein string ist, der die übertragenen informationen aus der socketverbindung enhält, also so :
OE_API string fnoe(user, passwort, server.pem)
{
return main(user,passwort, server.pem);
}aber die main hat ja dieses komische int argc und char* ,
könnte jemand für mich die server.cpp umschreiben, das dies wie oben funktioniert?
wärt mir ne echt große hilfe
-
is für mich echt wichtig, weiss keiner rat?
-
Du hast keine Ahnung was eine dll ist, geschweige eine main oder?
-
ich habe nicht viel ahnung von c++
in java wird das anderes gemacht mit der main klasse
hier in der server.cpp wird auf die variablen int argc, char* argv[] zugegriffen
. aber in der dll =dynamic link library , also die wird vom externen programm aus aufgerufen
soll die ssl-socketverbindung hergestellt werden und strings empfangen aus einem java ssl-socket-client
dazu muss ich irgendwie diese server.cpp auf dll betrieb umstellen und dafür sorgen das beim aufruf der dll-funktion, als rückgabewert der empfange string zurückgeschickt wird
-
Wieso musst du eine DLL hernehmen? DLLs können nicht Standalone agieren. Ob du Infos nun an eine DLL schickst oder eine interne Funktion ist egal Dlls kapseln lediglich ein Programm abschnitt quasi wie ein Modul, aber alleine können die nix. Dlls baut man wenn es Sinn macht. Copy & Paste von dem SSL-Example, von Boost.org. alles in eine Datei klatschen und testen. Wenn dein Client dann mit dem Server kommunizieren kannst, gut wenn nicht, Fehler suchen. Dann kann man dir hier auch helfen. Aber du versucht dein Programm von hinten zum laufen zu bekommen und gleichzeitig von vorne zu starten, ach und noch mit Dlls rum fuchteln.
Bau das doch mal Schrittweise auf, kompliziert machen kannst es später immer noch.
so long
jd
-
ok ich habe jetzt das boost server programm aus dem beispiel compiliert.
zunächst kommt, wenn ich es als konsolenanwendung in visual studio 2010 kompiliere , beim starten nur kurz usage serve <port> und dann is das programm auch schon beendet. ich schätze mal ich muss einen port irgendwie übergeben.
aber um die konsolenanwendung geht es mir gar nicht, sondern um die dll.
eine dll ist leider notwendig.
wenn ich nun den code in eine dll packe , weiss ich nicht, wie ich einen string empfangen kann vom client, also wie der befehl dazu ist.
ich habe den code :
BOOST_DLL_API int fnboost_dll(void) { try { if (argc != 2) { std::cerr << "Usage: server <port>\n"; // die meldung erschien immer, wenn ich dies als konsolenanwendung kompiliert habe return 1; } boost::asio::io_service io_service; using namespace std; // For atoi. server s(io_service, atoi(argv[1])); // das ist noch von der main, ist das der port? im format const char* io_service.run(); //hier wird wohl der ssl server gestart, aber wie empfange ich daten vom client? } catch (std::exception& e) { std::cerr << "Exception: " << e.what() << "\n"; } }die dll funktion fnboost_dll() wird aus einem anderen programm, welches die dll benutzt aufgerufen , und als rückgabewert der string den der ssl server vom client empfangen hat,
nur wie is der befehl zum empfangen?
außerdem gibt es da noch das problem, das am besten dei verbindung zwischen server und client aufrechterhalten werden soll, und nicht beim aufrufen der funktion die connection jedesmal neu etabliert wird ....
-
Wow super danke für den Post zu Zertifikaten!