Clientseitiger Webservice-Aufruf: Remotezertifikat ungültig

7. Mai 2018 18:27

Hallo zusammen!

Ich habe bereits Google und sämtliche NAV Foren durchstöbert und leider keine Lösung für mein Problem gefunden.
Ich hoffe jemand kann mir hierbei weiterhelfen:

Ich rufe eine externe API per https-Verbindung auf und rufe Daten von dieser ab, nehme also die Clientrolle ein. Das hat bisher auch funktioniert.
(Ich nutze die Standard Funktionen in Codeunit 1297, mehr dazu unten)
Jetzt hat der Betreiber der API ein neues Zertifikat eingespielt und seitdem erhalte ich die Fehlermeldung: "Das Remotezertifikat ist laut Validierungsverfahren ungültig".

WIe gesagt hat die Schnittstelle vor der Zertifikatsänderung funktioniert, also habe ich mich mit dem Zertifikat beschäftigt und alle möglichen Fehlerquellen geprüft:
    - Subdomain: Ich verbinde mich zu einer Subdomain, nennen wir sie foo.host.de -> Zertifikat ist gültig für *.host.de, also gültig für alle Subdomains des Hosts. Das kann es nicht sein.
    - Zertifikatsgültigkeit: Das Zertifikat ist gültig von 05.01.2018 bis 05.01.2019 -> Das kann es auch nicht sein.
    - Aussteller: Selbstsignierte Zertifikate werden berechtigterweise nicht erfolgreich validiert, also habe ich den Aussteller geprüft -> Aussteller ist DIgiCert, das Stammzertifikat ist im Zerrtifikatsspeicher enthalten und gültig bis weit nach 2030. Da der Aufruf im Browser funktioniert, habe ich das Zertifikat exportiert und zusätzlich in den Zertifikatsspeicher importiert, leider immer noch keine erfolgreiche Validierung.
    All das jeweils auf der Dienstamaschine, denn die .NET Komponenten werden auf dem Dienst ausgeführt (RunOnClient=No). -> Das kann es also auch nicht sein.

Jetzt bin ich mit meinem Latein am Ende.
EIn Aufruf der API über Browser funktioniert ohne Zertifikatswarnung, ich vermute die .NET Komponente prüft zu "Hart" evtl.aufgrund der Subdomain?!
Leider weiß ich nicht wie das vorige Zertifikat aussah.

Anbei noch die Art und Weise wie ich COD1297 (HttpWebRequestMgt) implementiert habe:
Code:
LOCAL ExecuteWebServiceRequest(Url : Text;User : Text)

HttpWebRequestMgt.Initialize(Url);
HttpWebRequestMgt.AddBasicAuthCredentials(User,'Pass'); // Diese Funktion ist nicht im Standard
HttpWebRequestMgt.CreateInstream(ResponseInStream);
IF NOT HttpWebRequestMgt.GetResponse(ResponseInStream,HttpStatusCode,ResponseHeaders) THEN
  HttpWebRequestMgt.ProcessFaultResponse(ErrorText)
ELSE
  ImportXmlDoc(ResponseInStream);


Die Funktion "HttpWebRequestMgt.GetResponse" ruft WebRequestHelper.GetWebResponse auf:
Code:
GetResponse(VAR ResponseInStream : InStream;VAR HttpStatusCode : DotNet "System.Net.HttpStatusCode";VAR ResponseHeaders : DotNet "System.Collections.Specialized.NameValueCollection") : Boolean
EXIT(WebRequestHelper.GetWebResponse(HttpWebRequest,HttpWebResponse,ResponseInStream,HttpStatusCode,
    ResponseHeaders,GlobalProgressDialogEnabled));

Innerhalb dieser Funktion wird der Fehler in der Anweisung "HttpWebRequest.GetResponse" geworfen:
Code:
[TryFunction] GetWebResponse(VAR HttpWebRequest : DotNet "System.Net.HttpWebRequest";VAR HttpWebResponse : DotNet "System.Net.HttpWebResponse";VAR ResponseInStream : InStream;VAR HttpStatusCode : DotNet "System.Net.HttpStatusCode";VAR ResponseHeaders
IF ProgressDialogEnabled THEN
  ProcessingWindow.OPEN(ProcessingWindowMsg);

CLEARLASTERROR;
HttpWebResponse := HttpWebRequest.GetResponse; // Hier wird der Fehler geworfen
HttpWebResponse.GetResponseStream.CopyTo(ResponseInStream);
HttpStatusCode := HttpWebResponse.StatusCode;
ResponseHeaders := HttpWebResponse.Headers;

IF ProgressDialogEnabled THEN
  ProcessingWindow.CLOSE;


Vielleicht sehe ich vor lauter Bäumen den Wald nicht mehr.
Ich bin für jede Idee dankbar!

Vielen Dank!
Thanassi

Re: Clientseitiger Webservice-Aufruf: Remotezertifikat ungül

8. Mai 2018 08:00

Hallo,

versuche mal den Traffic mit Fiddler zu debuggen. Vielleicht erhältst du dadurch mehr Informationen.

Gruß

Michael

Re: Clientseitiger Webservice-Aufruf: Remotezertifikat ungül

8. Mai 2018 08:53

Hallo Thanassi,

Fiddler oder auch der Network Monitor sind gute Ansätze. Wir hatten nach einem Update von Dynamics NAV 2017 (ich meine es war CU 7) auf CU 14 ein ähnliches Problem.

Spannenderweise hat sich zwischen diesen Releases, zumindest für Version 2017, etwas an der Zertifikatsvalidierung geändert. Vorher wurde ein Zertifikat quasi gar nicht geprüft und immer durchgewunken (ein genereller Validation Callback, wenn ich mich korrekt erinnere). Ich gehe davon aus, das trifft auch auf Version 2016 zu.

Mit den neueren Releases ist das nicht mehr so. Da wir hinter einem Zwangsproxy hängen, aber der Funktionsbenutzer keine generellen Proxy-Einstellungen hinterlegt hat (WinHttpProxy), findet, anders als bei einer Übertragung bei der ein Proxy explizit gesetzt wird, das System zu dem Zeitpunkt kein Zertifikat (kommt nicht raus, da Proxy), durchwinken ist nicht mehr erlaubt -> Fehler. Denn hier wird nur der im System konfigurierte Proxy verwendet. Beu uns funktionierte es so lange der Zertifikatscache gültig war.

Auch wenn obiges nicht 100% zutrifft, helfen dir diese Infos vielleicht, zusammen mit der Netzwertkprotokollierung, das Problem zu finden.

Re: Clientseitiger Webservice-Aufruf: Remotezertifikat ungül

8. Mai 2018 10:27

Vielen Dank für die guten Ansätze und Infos @Michael und @Carsten.
Leider habe ich keine Admin Rechte auf die Service Maschine, aber evtl. kann ich den Traffic zwischen ServiceMaschine, Port 443 von meinem Computer aus abhören.
Ich werde das mal versuchen und berichte.

Viele Grüße
Thanassi

Re: Clientseitiger Webservice-Aufruf: Remotezertifikat ungül

8. Mai 2018 10:58

Ich befürchte das wird dir nicht helfen. Das Problem tritt ja zwischen Server und extern auf.

Re: Clientseitiger Webservice-Aufruf: Remotezertifikat ungül

8. Mai 2018 18:19

@SilverX: Ich habe mich falsch ausgedrückt. Ich meinte, ich könnte von meinem Computer aus den Netzwerkverkehr zwischen Server und extern abhören.
Also eine klassische Middleman-Attacke :-D
Aber wie befürchtet funktioniert das nicht, ich muss auf den DiensteServer...

In NAV2016 gibt es in der Serverkonfiguration die Option "Enable Certificate Validation", falls Du diese Änderung meinst. Diese ist auch gesetzt.
Abgesehen davon sind wir auch nicht hinter einem Proxy.

Da es vor der Zertifikatsänderung funktioniert hat, kann es auch nicht daran liegen...

Ich kenne aus der Linux Welt die known_hosts-Datei, in welcher bei der ersten ssh-Verbindung zu einem Host dessen Fingerabdruck abgelegt wird.
GIbt es in der WIndows-Welt ein Äquivalent? Die Googlesuche findet hierzu nur Threads zu Fingerabdruck-Scannern :roll:

Ich kann doch nicht der einzige mit diesem Zertifikatsfehler sein.

Vielen Dank für Eure Hilfe
Thanassi