Certificate validating functions on Win32 - winapi

I was looking for the sequence of function calls which would need to be made in order to validate a certificate made as part of an https connection and I encountered this. I'm curious if the APIs offered by MS do hostname validation on certificates. Or is this left upto the developer?

Related

Does JWKS endpoint need https / TLS?

Currently, we embed the public key in the application for JWT validation. And we found the manual key rotation is quite hard. For example, the mobile app cannot switch the key on the same day when we replace the key from the server.
So, we are working on a automatic key rotation approach. The idea is the get the clients to switch to JWKS endpoint so that they can switch the new key without manual update.
I would like to ask do we need https to protect the JKWS endpoint? Because if we use https using internal CA or self-signed cert, we may have to manually replace the cert in every clients when it expires. This defeats the purpose of automatic key rotation.
You want TLS at JWKS endpoint. Without TLS you will have no guarantee that the keys are coming from your server (someone will be able to spoof the response). So TLS at the JWKS endpoint is a must.
You don't need mutual TLS, unless there are some high security requirements for that.
As you pointed out it's best to use certs signed by a trusted CA for that purpose.
I think to be more precise: you want to have the confidence in the response from the jwks endpoint, in both authenticity and integrity (i.e. you want to know the response came from the jwks endpoint, and it wasn't messed with).
TLS is one way to support that. Take note that there are such things as ssl termination which may mean that part of your connection is not covered.
HTTP signatures are another way to support this (although not fully specced out yet)

[golang]Is it possible to write TLS server without certificate?

From client I already have tls config which sets InsecureSkipVerify to true. How to write server for this client which take any cert.
Can tls.config help in server too? like setting InsecureSkipVerify to true?
No, as #JimB told you, TLS can't work without certificates.
The reasoning is simple: TLS is all about security, and certificates
are cryptographic keys which provide that security (TLS uses a so-called
"asymmetric cryptography" where each party has a key pair consisting of
a private and public parts; the public part is what get sent to another party
when doing a TLS handshake).
But on the other hand the security TLS provides is two-fold:
It provides mutual authentication of the parties participating in the
exchange.
It provides encryption of the transmission channel¹.
Certificates are used for both aspects: the fact they contain cryptographic keys is used for (2), and the fact they have owner's identity encoded
in them (and verified by whoever was issued a particular cercificate)
is used for (1).
Let me not digress into discussing how (1) works in detail
(though I truly urge you to read some theory on it) but (1) is what
you actually want to sidestep.
The good (for you) thing is that it's cheaply doable:
The TLS clients can be told to not verify the server's identity.
The TLS servers can be told to do the same (and often it's the default
mode they operate in—which is typical for regular websites
for instance).
You can create a so-called self-signed certificate for your TLS
server.
The latter requires nothing but something which is able to generate
X.509 certificates; OpenSSL is typically used for this;
just google for it.
If you're on Debian or Debian derivative (like Ubuntu, Mint etc)
consider installing the ssl-cert package and using
the make-ssl-cert program it provides.
¹ To be precise, they only protect the very initial phase of the exchange during which the parties generate and send to each other keys used for symmetric encryption, which are then used to encrypt the communication channel, and are regenerated (and re-exchanged) periodically. This is done because symmetric algoritms are way faster.

Is it possible for a server to see whether a HTTPS connection is monitored by Fiddler?

I'd like to know if it's possible for web services to detect HTTPS connections with "faked" root certificates created by Fiddler4 (Web debugging proxy) to prevent reverse engineering.
Is there any method to check whether the encryption is done with the original certificate or with one made by Fiddler?
A server has no way to know what certificate the client received unless the client sends the server that information.
From client JavaScript, you cannot detect such interception today; JavaScript does not expose the capabilities to introspect the certificate. It is possible to use Java or Flash inside a webpage to inspect the certificate received upon connecting to a server, but a sufficiently devious interceptor could just avoid MITM'ing the Java/Flash connection.
In contrast, a native code client application can detect what certificate was presented by the server and reject any certificate that doesn't match the expected certificate; this is called certificate pinning and it's a technique used by some applications. Note that this will block more than Fiddler; it'll also block connections through corporate inspection proxies (e.g. BlueCoat, ISA TMG, etc) and through some popular consumer antivirus programs' proxies (e.g. BitDefender). More importantly, users can circumvent your certificate pinning checks if they like; your code is running on their device, and they have the ability to modify your code in memory to strip out your certificate pinning checks. On some mobile devices, this code modification requires "jail-breaking" the device, but this isn't an insurmountable barrier.

Is a HTTPS connection secure without a valid SSL certificate?

I use a HTTPS connection without a valid SSL certificate. Is the connection safe? Is the information encrypted?
The connection is encrypted even if the SSL certificate isn't valid (expired, snake-oil, untrusted CA, etc.). The SSL certificate validation just makes sure you're connecting to the folks you think you're connecting to. Encryption doesn't do you any good if the folks decrypting your data are crackers instead of PayPal.
Actually it is possible to establish an encrypted connection between complete strangers without a certificate, using Diffie-Hellman or similar key exchange algorithms.
Alice and Bob agree on a random number x. Alice calculates
xa, where a is a large prime number known only to Alice, and sends that to Bob. Bob calculates xb and sends it to Alice. Alice calculates (xb)a, and Bob calculates (xa)b. Since (xa)b = (xb)a = xab, Alice and Bob now both know the number xab and can use it as an encryption key. The beauty of this is that Bob doesn't know a, Alice doesn't know b, and any eavesdroppers don't know either number (because calculating a from xa, in the case of large numbers, would take years).
As supercat points out, this by itself is still susceptible to a man-in-the-middle attack, and that's why at least one end of the transaction needs to authenticate using a certificate. To be accurate, though, it is not the server that checks this, it's the browser, and most browsers will let the user continue if the certificate is invalid (or possibly even garbage). In that event, the connection will still be considerably more secure than a regular connection. To listen in, you'd need to be able to manipulate IP routing or DNS lookups, and you'd have to set it up before the connection was first made, which is not easy to do.
BTW the keypairs in certificates are not what's used to encrypt actual traffic; they are used to establish a new single-use key for a much faster symmetric cipher (such as DES) which then does the rest of the work.
If there were no verification of SSL certificates, then someone who intercepted a communications channel could capture a request to connect to https://www.acmebank.com, send its own request to www.acmebank.com, and negotiate keys with both acmebank.com and the user. After that, it could receive each morsel of data from the user, decrypt with the user's key, and encrypt with acmebank's key, and do likewise with data from acmebank.com. The net effect would be that neither the user nor acmebank would see anything wrong, but the interceptor would be able to decrypt all of the data between the user and acmebank. The user and the bank will be using different keys to handle their communication, but neither entity will know this. Adding any standard aspect to the protocol to inquire what key is in use wouldn't help, since the interceptor could detect such queries and change the responses appropriately.
SSL prevents a man-in-the-middle attack by requiring the host to send the recipient a copy of the key the host is using, encrypted in a form that an intruder won't be able to fake (unless the intruder can fake CA credentials, at least). If one does not use a CA-issued certificate, there will be little protection against a man-in-the-middle attack, though the encrypted layer would prevent passive or retrospective decryption of session contents (BTW, I wish there were standards for something between unencrypted communication and SSL, for situations where passive or retrospective decryption are the primary threat, but I don't know of any).
Don't bother yourself anymore with invalid ssl certificate. You can now generate free browser valid certificate for your server as easily as you would generate a snakeoil (self-signed, browser invalid) certificate. Go see https://letsencrypt.org/ it's free and open to contributions.
Nope. What you're doing when using HTTPS is telling the browser to connect via a different port (443) whereas normally you connect via (80). Without a certificate, the server would refuse the connection. HTTPS is simply not possible without a certificate. Look here and you'll see a certificate is needed for it to work.
It's possible to establish an encrypted connection, yes, but it would still be possible that you're communicating with a cracked cpmputer instead of the real server. Like that, the cracked computer tells the server that he would be the client, decrypt all the data, store it and send the encrypted data to the client (and tell him he would be the server). So it's just a safe connection if there's no vulnerable point between the server and the client, which no one can guarantee.

SSL Client Cert Verification optimisation

We currently have a group of web-services exposing interfaces to a variety of different client types and roles.
Background:
Authentication is handled through SSL Client Certificate Verification. This is currently being done in web-service code (not by the HTTP server). We don't want to use any scheme less secure than this. This post is not talking about Authorisation, only Authentication.
The web-services talk both SOAP and REST(JSON) and I'm definitely not interested in starting a discussion about the merits of either approach.
All operations exposed via the web-services are stateless.
My problem is that verifying the client certificate on each requests is very heavyweight, and easily dominates CPU time on the application server. I've already tried seperating the Authentication & Application portions onto different physical servers to reduce load, but that doesn't improve dispatch speed overall - the request still takes a constant time to authenticate, no matter where that is done.
I'd like to try limiting the number of authentications by generating an HTTP cookie (with an associated server-side session) after successful client certificate verification, which when supplied by the client will cause client certificate verification to be skipped (though still talking over SSL). I'd also like to time-limit the sessions, and make the processes as transparent as possible from a client perspective.
My questions:
Is this still as secure? (and how can we optimise for security and pragmatism?)
Are there free implementations of this scheme? (I'm aware of the SiteMinder product by CA)
Given the above, should we continue to do Authentication in-application, or move to in-server ?
generating an HTTP cookie (with an
associated server-side session) after
successful client certificate
verification, which when supplied by
the client will cause client
certificate verification to be skipped
Is this still as secure? (and how can
we optimise for security and
pragmatism?)
It's not quite as secure in theory, because the server can no longer prove to himself that there's not a man-in-the-middle.
When the client was presents a client-side certificate, the server can trust it cryptographically. The client and server should be encrypting and data (well, the session key) based on the client's key. Without a client-side cert, the server can only hope that the client has done a good job of validating the server's certificate (as perceived by the client) and by doing so eliminated the possibility of Mr. MitM.
An out-of-the-box Windows client trusts over 200 root CA certificates. In the absence of a client-side cert, the server ends up trusting by extension.
Here's a nice writeup of what to look for in a packet capture to verify that a client cert is providing defense against MitM:
http://www.carbonwind.net/ISA/ACaseofMITM/ACaseofMITMpart3.htm
Explanation of this type of MitM.
http://www.networkworld.com/community/node/31124
This technique is actually used by some firewall appliances boxes to perform deep inspection into the SSL.
MitM used to seem like a big Mission Impossible-style production that took a lot to pull off. Really though it doesn't take any more than a compromised DNS resolver or router anywhere along the way. There are a lot of little Linksys and Netgear boxes out there in the world and probably two or three of them don't have the latest security updates.
In practice, this seems to be good enough for major financial institutions' sites, although recent evidence suggests that their risk assessment strategies are somewhat less than ideal.
Are there free implementations of this scheme? (I'm aware of the SiteMinder product by CA)
Just a client-side cookie, right? That seems to be a pretty standard part of every web app framework.
Given the above, should we continue to do Authentication in-application, or move to in-server ?
Hardware crypto accelerators (either a SSL proxy front end or an accelerator card) can speed this stuff up dramatically.
Moving the cert validation into the HTTP server might help. You may be doing some duplication in the crypto math anyway.
See if you would benefit from a cheaper algorithm or smaller key size on the client certs.
Once you validate a client cert, you could try caching a hash digest of it (or even the whole thing) for short time. That might save you from having to repeat the signature validations all the way up the chain of trust on every hit.
How often to your clients transact? If the ones making up the bulk of your transactions are hitting you frequently, you may be able to convince them to combine multiple transactions in a single SSL negotiation/authentication. Look into setting the HTTP Keep-Alive header. They may be doing that already to some extent. Perhaps your app is doing client cert validation on every HTTP request/response, or just once at the beginning of each session?
Anyway, those are some ideas, best of luck!

Resources