Totalcmd und Clientzertifikate

German support forum

Moderators: white, Hacker, Stefan2

Helge01
Junior Member
Junior Member
Posts: 15
Joined: 2008-08-04, 14:06 UTC

Totalcmd und Clientzertifikate

Post by *Helge01 »

Hallo, ich benutze den Totalcmd mit dem WebDav Plugin über eine SSL Verbindung die auch gut funktioniert. Aus Sicherheitsgründen musste ich zusätzlich Clientzertifikate einführen womit die Verbindung nicht mehr geht da Totalcmd bei Clientzertifikate nicht den Zertifikatsspeicher von Windows nutzt (im Gegensatz zur SSL Verschlüsslung).
Wird dies noch integriert oder gibt es eine Möglichkeit die ich übersehen habe?

Helge
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 48083
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Post by *ghisler(Author) »

Leider muss ich da passen, ich wuesste schlicht nicht, wie man so etwas einbaut. Wenn jemand Beispielcode für mich hat, werde ich das aber gerne einbauen.

Das Plugin ist übrigens Open Source (vor allem aus Sicherheitsgründen), so dass jeder das bei Bedarf einbauen könnte...
Author of Total Commander
https://www.ghisler.com
CoolWater
Power Member
Power Member
Posts: 737
Joined: 2003-03-27, 16:33 UTC

Post by *CoolWater »

ghisler(Author) wrote:Wenn jemand Beispielcode für mich hat
Ggf. hilft dir dieses Beispiel weiter:
http://www.codeproject.com/KB/IP/wininet_ssl___certificate.aspx

Gruß
CoolWater
Helge01
Junior Member
Junior Member
Posts: 15
Joined: 2008-08-04, 14:06 UTC

Post by *Helge01 »

Danke für die raschen Antworten, so einen ähnlichen Link hatte ich auch, konnte ihn aber wegen der 3 Tages-Beschränkung nicht anhängen.
Wenn sich jemand finden würde zwecks Programmierung wäre ich dankbar. Testen wäre meinerseits kein Problem.

Gruß Helge
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 48083
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Post by *ghisler(Author) »

Danke für den Link, sieht ziemlich einfach aus, das einzubauen. Jetzt fehlt mir nur noch eine Funktion zum Auflisten aller Client-Zertifikate, damit der User eines auswählen kann im Verbindungsdialog...
Author of Total Commander
https://www.ghisler.com
Helge01
Junior Member
Junior Member
Posts: 15
Joined: 2008-08-04, 14:06 UTC

Post by *Helge01 »

Das ist ja klasse hier :D , nützt eventuell das hier was?


Anzeigen des Zertifikats-Auswahldialogs (z.B. damit ein Benutzer ein passendes Zertifikat aus dem Speicher auswählen kann)

X509Certificate2Collection certs =
X509Certificate2UI.SelectFromCollection(store.Certificates,
"Ihre Zertifikate",
"Bitte auswählen",
X509SelectionFlag.SingleSelection);

ist ein Ausschnitt aus dem Link den ich erst Morgen (3. Tag) reinsetzen kann :wink:

Gruß Helge
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 48083
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Post by *ghisler(Author) »

Leider nein, das ist .Net, ich brauche eine Windows API-Funktion. Es wird wohl auf CertEnumCertificatesInStore hinauslaufen. Leider liefert das direkt das komplette Zertifikat zurück - das lässt sich weder als Name anzeigen, noch speichern...
Author of Total Commander
https://www.ghisler.com
CoolWater
Power Member
Power Member
Posts: 737
Joined: 2003-03-27, 16:33 UTC

Post by *CoolWater »

ghisler(Author) wrote:Leider nein, das ist .Net, ich brauche eine Windows API-Funktion. Es wird wohl auf CertEnumCertificatesInStore hinauslaufen. Leider liefert das direkt das komplette Zertifikat zurück - das lässt sich weder als Name anzeigen, noch speichern...
Schau mal hier: http://msdn.microsoft.com/en-us/library/aa382363(VS.85).aspx

Code: Select all

while(pCertContext = CertEnumCertificatesInStore(hCertStore, pCertContext))
{
    if(CertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, pszNameString, 128))
        printf("\nCertificate for %s \n",pszNameString);
    else
        fprintf(stderr,"CertGetName failed. \n");
}
Alternativ kannst du auch GetLastError() aufrufen wenn HttpSendRequest nicht erfolgreich war... Ist GetLastError() == ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED, dann mit InternetErrorDlg das Fenster zur Zertifikatsauswahl anzeigen und fertig.

Oder statt des ErrorDlgs folgendes:

Code: Select all

DWORD dwCert = 0;
InternetSetOption(m_hRequest, INTERNET_OPTION_SECURITY_SELECT_CLIENT_CERT, &dwCert, sizeof(dwCert));
und dann den Request neu abschicken. Dann wird automatisch das richtige Zertifikat, sofern das vorhanden ist, ausgewählt.

Geht doch alles :D

Gruß
CoolWater
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 48083
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Post by *ghisler(Author) »

Danke, sieht gut aus! Die Frage ist nur, ob CERT_NAME_SIMPLE_DISPLAY_TYPE das Zertifikat eindeutig identifiziert, oder ob es mehrere Zertifikate mit demselben Namen geben kann. Das Plugin würde den Namen dann in den settings speichern, und genau diesen Namen bei der Verbindung zum Laden des Zertifikats verwenden.
Alternativ kannst du auch GetLastError() aufrufen wenn HttpSendRequest nicht erfolgreich war... Ist GetLastError() == ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED, dann mit InternetErrorDlg das Fenster zur Zertifikatsauswahl anzeigen und fertig.
Ja, das habe ich bei MSDN auch gesehen, ist aber echt mühsam, wenn man bei jeder Verbindung das Zertifikat erneut wählen muss...

INTERNET_OPTION_SECURITY_SELECT_CLIENT_CERT geht laut Microsoft nicht, siehe:
http://support.microsoft.com/?scid=kb%3Ben-us%3B224282&x=11&y=17
The INTERNET_OPTION_SECURITY_SELECT_CLIENT_CERT option to select a particular client certificate is not supported and should not be used. The result is unpredictable if the client has more than one client certificate on the computer.
Author of Total Commander
https://www.ghisler.com
Helge01
Junior Member
Junior Member
Posts: 15
Joined: 2008-08-04, 14:06 UTC

Post by *Helge01 »

In der Regel ist nur ein Clientzertifikat vorhanden, da kann man unter Internetoptionen unter Sicherheitseinstellungen den Punkt 'keine Aufforderung zur Clientzertifikatauswahl, wenn kein oder nur ein Zertifikat vorhanden ist' aktivieren.

Gruß Helge
CoolWater
Power Member
Power Member
Posts: 737
Joined: 2003-03-27, 16:33 UTC

Post by *CoolWater »

ghisler(Author) wrote:Das Plugin würde den Namen dann in den settings speichern, und genau diesen Namen bei der Verbindung zum Laden des Zertifikats verwenden.
Dann speicher doch zusätzlich noch den Issuer und die SerialNumber aus der CERT_INFO-Struktur. Mit diesen beiden Werten kannst du dann CertFindCertificateInStore aufrufen und als dwFindType CERT_FIND_SUBJECT_CERT nehmen. Das zusammen ist dann eindeutig genug ;)

Gruß
CoolWater
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 48083
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Post by *ghisler(Author) »

Gute Idee - würden der Name und die Serial Number zusammen auch reichen?
Author of Total Commander
https://www.ghisler.com
CoolWater
Power Member
Power Member
Posts: 737
Joined: 2003-03-27, 16:33 UTC

Post by *CoolWater »

ghisler(Author) wrote:Gute Idee - würden der Name und die Serial Number zusammen auch reichen?
Ja eigentlich speichert man den Issuer (CN-Wert) eines Zertifikats. Damit ginge das natürlich. Welchen Namen wolltest du denn speichern?
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 48083
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Post by *ghisler(Author) »

Den von CERT_NAME_SIMPLE_DISPLAY_TYPE zurückgelieferten - keine Ahnung, welcher das dann ist...
Author of Total Commander
https://www.ghisler.com
CoolWater
Power Member
Power Member
Posts: 737
Joined: 2003-03-27, 16:33 UTC

Post by *CoolWater »

ghisler(Author) wrote:Den von CERT_NAME_SIMPLE_DISPLAY_TYPE zurückgelieferten - keine Ahnung, welcher das dann ist...
Hmm, das kann unterschiedlich sein, siehe:
http://msdn.microsoft.com/en-us/library/aa376086(VS.85).aspx

Gruß
CoolWater
Post Reply