Inno Setup WinHttpRequest with optional certificate - https

I have a tomcat server configured to use TLS and client certificate authentication optionally.
Currently I am trying to establish a connection using Inno Setup with WinHttpRequest:
WinHttpReq := CreateOleObject('WinHttp.WinHttpRequest.5.1');
WinHttpReq.Open('POST', 'https://localhost:8443/api/validate', False);
WinHttpReq.Option(4) := '&H3300';
HTTPS errors are ignored; but receive this error message since I'm not setting any certificate for client validation:
A certificate is required to complete client authentication
So, what should I do to tell WinHttpReq that I don't have any certificate and continue?
I have tried using WinHttpSetOption:
WinHttpSetOption(WinHttpReq, WINHTTP_OPTION_CLIENT_CERT_CONTEXT, WINHTTP_NO_CLIENT_CERT_CONTEXT, 0);
But it is not an Inno Setup Pascal scripting valid function.
Thanks in advance.

Related

Why WinHttp does not send client certificate with chain?

I am working on a client-server application where server is web service which perform client authentication based on SSL client certificate. The client cert is issued by Root-CA -> Intermedia-CA-1 -> Intermedia-CA-2. I imported the cert to both user cert store and cert machine store.
Use WinHttpSetOption(request, WINHTTP_OPTION_CLIENT_CERT_CONTEXT, (LPVOID)pCertCtx, sizeof(*pCertCtx)) to set the client certificate.
WinHttp send both client certificate and the intermediate CAs when pCertCtx is searched from user store.
But WinHttp only send the client cert, does not send intermediate CAs, when pCertCtx is searched from local machine store or from in-memory cert store.
Why WinHttp has different behavior on these? Is there any options to force WinHttp always send both certificate and the chain?
Resolved by adding the intermedia ca to machine store.

SSL crashes periodically caused by certificate server certificate is not configured properly with HTTP.SYS

I'm trying to install a self-host WCF service on a server with Windows Server 2012.
I was following these steps:
import my pfx file with mmc
run "netsh http add sslcert ipport=0.0.0.0:49000 certhash=e09280ded2322eb858b38b3250e1a488f797b269 appid={4dc3e181-e14b-4a21-b022-59fc669b0914}"
install my service and start it
At first it works well. But after a few hours the ssl crashes and I can only get error msg at client as below
An unhandled exception of type 'System.ServiceModel.CommunicationException' occurred in mscorlib.dll.
Additional information: An error occurred while making the HTTP request to https://servername:49000/WCFServiceName. This could be due to the fact that the server certificate is not configured properly with HTTP.SYS in the HTTPS case. This could also be caused by a mismatch of the security binding between the client and the server.
run "netsh http delete sslcert ipport=0.0.0.0:49000"
and delete the imported pfx and then redo step1 and 2 can make ssl works again, but the problem will still appears in a few hours.
It's definitely not the SecurityProtocol problem, for I have already tried adding
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;
before request. And both server and client uses .Net Framework 4.5.2
I've tried "netsh http show sslcert", and got below result:
IP:port : 0.0.0.0:49000
Certificate Hash : e09280ded2322eb858b38b3250e1a488f797b269
Application ID : {4dc3e181-e14b-4a21-b022-59fc669b0914}
Certificate Store Name : My
Verify Client Certificate Revocation : Enabled
Verify Revocation Using Cached Client Certificate Only : Disabled
Usage Check : Enabled
Revocation Freshness Time : 0
URL Retrieval Timeout : 0
Ctl Identifier : (null)
Ctl Store Name : (null)
DS Mapper Usage : Disabled
Negotiate Client Certificate : Disabled
I've tried delete the sslcert binding on port 49000 and created an empty website binding to port 49000 in IIS and make my service listening to that port then. It works the first time and lasted for about a week before the same error pops out.
Where should I begin to locate and solve this wired problem?
First, we should ensure that the certificate private key could be accessed by WCF. The Network Service account (or Everyone account) should be added in the certificate READ/Writer group, then we run the application (windows service, or console?) with corresponding account.
https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-make-x-509-certificates-accessible-to-wcf
Second, as you know, TLS version need OS and Dotnetframework support, the default protocol version is ssl3.0/tls1.0(auto-negotiate, could not be configured). We had better use the latest OS version and .netframework4.7. I think this may be the cause of unstable communications.
Please refer to the below document.
https://learn.microsoft.com/en-us/dotnet/framework/network-programming/tls
Feel free to let me know if the problem still exists.

Windows Store App connect to HTTPS with an self-signed SSL certificate

I'm having a Windows Store App (Metro App) which I want to connect a web service I built through HTTPS. And I am using a self-signed certificate for my web service. But when I tried to connect it from my App through System.Net.HttpClient.PostAsync I got an exception said
"The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel."
Inner exception said
"The remote certificate is invalid according to the validation procedure."
I know this is because I'm using a self-signed certificate. I remembered in .NET I can use System.Net.ServicePointManager.ServerCertificateValidationCallback so that my application can pass the validation if the thumbprint is mine.
But I cannot find the relevant class/method in Windows Store runtime. How can I do that?
First, you should ideally be using Windows.Web.HttpClient. On that API, you can use httpClient.HttpBaseProtocolFilter.IgnorableServerCertificateErrors to set the cert errors that you're willing to accept. You can choose to ignore the Untrusted error, for example, but you should then manually check the thumbprint before actually sending any data.

Configure SSL on Windows HTTP server using HTTPAPI_VERSION_1 APIs

I configured SSL on my Windows HTTP server (HTTP listener) developed using HTTPAPI_VERSION_1 APIs using HttpSetServiceConfiguration.
I used a self signed certificate and followed the steps at this link to set it as trusted http://blogs.msdn.com/b/jpsanders/archive/2009/09/29/walkthrough-using-httplistener-as-an-ssl-simple-server.aspx
Then I tried using the sample in msdn named WinHttpPostSample to connect to the http server using https.
But WinHttpSendRequest API always fails with error
12044 (ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED)
How can we prevent the HTTP server from sending this error or to make it not compulsory for the server to have a client certificate to proceed ?

Apache 2 authentication error

Attempting to implement client authentication with an SSL cert, according to this HOWTO,
I receive the following errors.
Apache:
Re-negotiation handshake failed: Not accepted by client!?
Firefox:
ssl_error_handshake_failure_alert
I assume it is a configuration error, but have not been able to locate it.
Additional info:
Commercial CA server cert servers secure works without problem in Apache 2.2 & Passenger.
Only client authentication related directives do not work.
Is your certificate signed by verizon or someone like that? If not, you might want to add an exception in firefox. By default it stops you.
pd. doesn't sound like a passenger question
When you require client certificate authorization, you have to point Apache to file containing the root CA (and intermediates also) certificates which issued the client certificate
Also post your client authentication config part.

Resources