Verifying peer separate of sending https post - ssl

I need to send an https post to an external server. Is it best practice to first verify the external peer and then afterwards in a separate request to send the post data? Or is it ok to ask to verify the peer and send the post data in the same request? I'm using pycurl if that helps any. Thanks for any help.

From the CURL docs:
When CURLOPT_SSL_VERIFYPEER is nonzero, and the verification fails to prove that the certificate is authentic, the connection fails. When the option is zero, the peer certificate verification succeeds regardless.
The SSL negotiation phase happens before any data is sent, so if the external peer fails to verify, the connection will fail before any data is sent. It should be OK to do it all as one request.
SSL -- Negotiation Phase
http://www.ietf.org/proceedings/32/sec/cat.elgamal.slides.html
The client initiates the session
The server responds and sends its certificate
The client generates the master key and sends it encrypted using the server's public key
Requires a server certificate but does not require a client certificate
Requires a certain level of trust in the server's certificate
Optional client certificate can be used to authenticate the client to the server

Related

(60) SSL peer certificate or SSH remote key was not OK

Having problems installing PayPalCommerce in OpenCart,
After installing and trying to connect to PayPal I get this error!
"(60) SSL peer certificate or SSH remote key was not OK"
As anybody else come across problem as the server certs are just fine?
As Stated Server Certificats are fine, was thinking of changing the Curl SSL Veerify to False but that would defeat the whole purpose. And as the latest Security 1.2 (whatever abrevation).
Update your certificate authority bundle so that your HTTPS connection to the PayPal API endpoint can verify the connection is trusted.
One can be downloaded here, among other places.
If your attempted connection is using a specific certificate file rather than a CA bundle, delete the old certificate and either obtain the endpoint's current one to use instead or use CA verification of it

Use expired client certificate for testing

I'm trying to understand how to implement client certificate authentication with Kestrel/ASP.Net Core 6.0 on Windows.
So far I was able to successfully authenticate Firefox and Edge with a client certificate to my server prototype.
Now I want to test failures of client certificate authentication due to invalid certificates and decided to begin with a certificate which has expired.
The first issue I faced was that the browsers I am using are not willing to offer the expired certificate for authentication after I imported them into the MS certificate store, so I was hoping that a more versatile client like curl would allow me to do that.
So I set up WSL and figured out how to successfully authenticate curl with a (valid) client certificate to the server.
Then I switched to an expired certificate and happily noticed that I could not connect.
But after looking more closely at the scenario I'm getting the impression that this is because already curl seems to check the certificate and does note seem to even try to use it -- the reason for me to believe this is that my breakpoint in the certificate validation handler of the server are not hit, while they are hit when I'm testing with a valid certificate. In addition, when I disabled the ValidateValidityPeriod in the server CertificateAuthenticationDefaults options this did not have any effect.
(On the other hand, the pertinent message in the curl output
* TLSv1.2 (IN), TLS alert, certificate expired (557):
* OpenSSL SSL_read: error:14094415:SSL routines:ssl3_read_bytes:sslv3 alert certificate expired, errno 0
starts with TLSv1.2 (IN) - this seems to indicate that the certificate validation failure is on server side, doesn't it? I have to admit that I'm confused.)
Has anyone experience with testing the server side of client certificate validation and could hint me
either to convince curl to use the expired (or otherwise invalid) client certificate or
explain to me why the validation handler in Kestrel are not hit in the debugger or
suggest a different tool for that purpose?
(I alread tried the --insecure switch of curl, but that did not seem to help. I was also considering to write my own client, but I don't like testing self-written software with self-written tools).

How do Virtual Hosts and TLS work together?

As I understand it Virtual Hosts work in HTTP servers by receiving a HTTP request from the client and examining the Host header, which contains service1.example.com or service2.example.com, etc. and then forwarding the request based on some rules in the HTTP server configuration.
But as I understand it TLS works as follows:
Client opens connection to server.
Client and server have a handshake where the client checks the server's certificate is valid for the name the client is trying to access.
Client transmits the request.
Server transmits the response.
These two seem like they would be incompatible, the server doesn't know which TLS certificate to present to the client until after the request has been sent, but the client won't send the request until the handshake is completed.
They clearly aren't incompatible, I have run web servers with multiple separate TLS virtual hosts each with completely separate certificates. Where have I gone wrong here?

Confusion about HTTPS --> How is SSL handshake happing

I've always been an end consumer of HTTPS and have never really understood it that well but am looking to change that.
I am calling a RESTful web service over HTTPS. For example...
curl -X GET \
https://myCompanydns/rest/connect/v1.4/myEndpoint
With all my requests I send a basic authentication header i.e a username and password.
When I make these calls via my application I was expecting to have to add a certificate into like a jks (which I've had to do in the past) but on this occasion I've found that I can call the HTTPS web service without that.
For HTTPS to work I believe there is an SSL handshake? How is that happening successfully is this scenario without a jks?
Again, sorry for this beginner type question.
When doing a https://... request the client needs to verify that the servers certificate is the expected one - and not some man in the middle. This is done (among other things) by making sure that the servers certificate was issued by a trusted certificate authority (CA). Which CA is trusted is setup in the local trust store (i.e. local to the client). In the above call where no explicit trust store is given curl is using its default trust store. In the case where you've explicitly gave a jks you've provided the application with a specific trust store it should use.
For more on how the server certificates gets validated see SSL Certificate framework 101: How does the browser actually verify the validity of a given server certificate?.

403.7 IIS 7.5 SSL client certificate authentication issue

I am testing a web service with an external partner using 2 way SSL under IIS 7.5. I am requiring SSL, requiring a client cert, and using one to one mapping to authenticate to a domain account. I have configured everything and it works fine on our network (I am able to provide a client cert, get authenticated and invoke the service from browser and test harness).
From outside of our network (in most cases, see below), I am getting a 403.7 error. I have gone through the machine level certificate store and made sure the certificates and CAs are trusted.
Here's the weird thing. I obtained a Type I cert to test from home (and got 403.7 like our intended partner is). So I setup Fiddler to debug SSL and send my certificate, and this works for some reason. I setup a test harness to pass the exact same certificate, and got 403.7. I test in my browser (IE 9), don't get a prompt for a client cert, and get 403.7.
Any help appreciated.
Bill
Last time I checked, IIS was using re-negotiation (by default) to get the client certificate: there is a first handshake where the server doesn't request a client certificate, followed by another handshake (encrypted this time) where the server requests the certificate (via a TLS CertificateRequest message). This will prevent you from seeing anything from Wireshark, unless you configure it to use the server's private key and decipher the traffic (note that this only works with some cipher suites).
One way to see the client-certificate negotiation is to configure IIS to use initial client certificate negotiation, using netsh and clientcertnegotiation=true (which is about initial negotiation). At least the CertificateRequest and the certificate will be sent in clear during the handshake, so you should be able to see this with Wireshark.
If the client isn't sending a certificate to the server as a response to the CertificateRequest, you'll still see an empty Certificate message from the client.
If you don't export the private key with the certificate to use with Fiddler or whichever other client, there is no chance that it will be able to use the certificate. It may at best try to send the certificate, but the handshake will fail (since the CertificateVerify message needs to be signed by the client's private key).
I guess you may encounter a problem whereby:
not presenting a certificate is accepted by the server (it's effectively optional),
presenting an invalid certificate makes it fail and causes this 403.7 status code (many servers and SSL/TLS stacks would implement this as a fatal error, but TLS specification doesn't say that unsupported_certificate, certificate_revoked, certificate_expired, certificate_unknown should be fatal, so this is at the server's discretion).
Are you using the same physical machine to test both the in-network and external-network connections? If not, are you sure that the external-network client has the private key accessible?
I have not configured Fiddler client authentication before. Does it read the client certificate and key from the standard certificate stores? Does it read directly from a PKCS12?
One other thing that may be helpful is inspecting the TLS handshake in WireShark. Specifically, check out the Server's "Certificate Request" message, as the data here clues the client (IE9) which client certificates it should display in the prompt. Compare this for the internal and external connections.