.net6 HttpClient memory leak when target endpoint CA certificate is not in trust store? - ssl

I have an old Dell R710 server with iDRCA6 up and running. I have C# utility to grab power usage statistics via HTTPS (1 call per each minute). iDRAC itself contain certificate signed by my pfSense based CA.
Because SSL is 'broken' in my case - I was using ServerCertificateCustomValidationCallback with return true. I am aware about all security risks here. But what I was not aware about is next two point:
Being started on machine where CA certificate is not installed to trusted store - dotnet.exe constantly open connections to unclear CDN (like vip0x00f.map2.ssl.hwcdn.net; a23-216-77-44.deploy.static.akamaitechnologies.com; https-83-2-226-48.sabc.llnw.net)
Memory occupied by dotnet.exe process grown up and up and after one day it is already about 1GB (we started with just 20MB).
Memory dump contains only 12-14 megabytes of managed objects, the rest is something unmanaged.
After I have installed CA certificate to trusted store - additional CDN connections is not opening anymore and memory is not growing anymore.
You can see additional strange CDN connections with simple C# code like:
using (var client = new HttpClient())
{
var resp = await client.GetStringAsync("https://expired.badssl.com/");
Console.WriteLine($"Response length is {resp.Length}.");
}
Did anyone know what is going on here and where I can read more?
I am already check all recommendations from:
https://josef.codes/you-are-probably-still-using-httpclient-wrong-and-it-is-destabilizing-your-software/
https://www.aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/
All using's are in place, Cancellations token as well. As I have mentioned: just adding CA certificate to windows trusted root CA solving CDN and memory leaking issues, but why?

Related

How can I get Letsencrypt certificates before adding the server to production

I am trying to lunch new servers automatically when needed but I am having some difficulty getting the certificate before making the server live. What I want to do is run a setup script which gets all the packages, websites and certificates ready and after that add the server to production. However, Letsencrypt wants me to verify that the server requesting the certificate is actually the website which replies to requests. How can I get the Letsencrypt certificate before adding the server to production? I don't want requests to the real website to be routed to the new server until it is fully setup and has the certificates.
One solution I thought of is to save the certificates on an AWS S3 bucket and synchronize them whenever a renewal is needed. Then when I setup a new server I just get the latest certificate from my AWS S3 bucket and I don't have to worry about getting the certificate from the CA until after the server is added to production.But this solution doesn't seem "clean" and would require me to have an S3 bucket just for my Letsencrypt certificate which also adds another weakness where a certificate could be stolen from.
Is there a more simple solution which I haven't thought of yet?
In a load-balanced (LB) scenario, you should consider having exactly one entity responsible for performing LE certificate acquisition. Things get complicated with multiple entities doing this asynchronously - you'd need to be able to guarantee that the ACME challenges get routed to the relevant server(s), and your LB doesn't have that information (without additional complexity).
So I'd suggest either:
Terminating HTTPS at your load-balancer. Then none of your servers need to care about HTTPS or certificates.
Having one "special" server that's responsible for interacting with LE, and then distributing the cert to the other servers. The details of how you do that is implementation-dependent, because it depends on how you're managing server/service configuration.

TLS/SSL certificate verification

I am new to TLS/SSL so this might be a very basic question, but I've been searching a lot an could not find an answer.
I am trying to implement a TLS/SSL client. This client will run on an embedded unit with Windows OS on it (XPe or WES7). My implementation uses GnuTLS.
How do I get the list of trusted authorities to my unit so my client can verify the server's certificate? Is it supposed to be a file stored on the client side, that the client is responsible for keeping up to date? Or can my client somehow get this list from the internet each time it is needed and not maintain it locally?
The Certificating Authority (CA) master certificates are stored client side and the client is responsible for keeping them up to date. Keeping them up to date isn't as hard as it sounds, as CA certificates aren't changed that often - most are valid for 5-10 years at least.
Client side storage is necessary because any given internet site your application uses might be compromised.
To get a list, you might start by looking at the CA certificates distributed with a browser or at the cacerts file distributed with Java. Before releasing your code, you'll probably want to check that the certs you use are genuine by checking them against information provided by the CA.
Go to any Windows machine and run "certman.msc" from command-line. Export each CA certificate (Intermediate Certificates, Trusted Authorities) to file (BER, PEM), then import these certificates into your embedded software. Now you can validate email certificates, the same way Windows does (i.e. using various x.509 related RFCs and CRLs)

Renew SSL certificates on huge number of machines

I'm using SSL certificates in a client-server application; both the client and the server are using 2 certificates that will expire soon. Normally, you'd just replace the certificates with new ones, but this cannot happen at once because of the huge numbers of clients.
So, if only the servers and a part of the clients are updated, the rest of the clients won't be able to authenticate anymore.
A quick fix is to replace the binaries with a version which simply disregards expiry date of the certificates; the update of the clients can be done sequentially, as long as it will finish before the certificates expire.
Long term solutions I thought about:
use Puppet to push new certificates on clients
unfortunately, not viable because not all clients are/will be managed via Puppet
use a second set of certificates
if first set has expired, use the second one
in this manner, server will have new certificates, a part of clients will have new certificates and the rest of the clients will have old certificates, but everything works
client requests a new certificate from the server, if the current one has expired.
Are there any other solutions?
I assume you use the SSL certificates for an online SSL connection, like HTTPS, or SFTP.
The big question is: Do you still trust and want to use your server-side key! If so you can just re-issue the server certificate with a new expiration date still using the old key and thus extending the lifetime. The question is, if you still trust the old key or if it should be replaced. Old clients may still connect to you at that point.. You are still using the same public / private key pair, just made a new 'lifetime version' of the certificate for it. (That is what most public servers do..)
Using two sets of active SSL certificates for different keys on the server side is not really viable and only possible if you have good control over the handshake process on the client side and your server application supports it. The issue is that during an SSL negotiation, the server has to send its certificate first and the only indication it might get from the client is a ServerName extension during the ClientHello. (Assuming the client actually sends one). Otherwise the server is 'at a loss' on what the other side will or will not support. (There are some other extensions that might help for in indicating supported CA certificates, but your clients should support those).
The first is the most practical for the clients that do support it. Just renew their certificates (and perhaps keys) and push them. And you are done with those.
For the others, updating the client software and making sure they generate a new key and request a new certificate from the server when they need it (or in advance) might be the best solution.

Self signed certificate for machine to machine https connection

I need to set up https communication between a Tomcat application server and a back end system. The web server hosts a public website, so is in a DMZ.
My question is if there any advantage in using official CA certificates, over using self signed certificates in this situation (machine to machine communication)?
I keep hearing self signed certificates should not be used on production systems, but I'm not sure I understand why (for machine to machine communication).
The risk lies in how effective the defenses protecting the hosts in question are, including the network connection between them. Given that weaknesses and exploits are being found all the time, it is reasonable to say there could be issues with self-signed certificates used in a production environment - which includes hosts in a DMZ.
Here's the reason: man-in-the-middle. In short, if either host - or the network between them - becomes compromised, then the traffic between them will still be encrypted, but because the certificate is self-signed, a man-in-the-middle (aka "MITM") would be able to introduce a transparent proxy using a self-signed cert, which will be trusted by both sides.
If instead your hosts use a public CA, then the MITM approach cannot work.
If the annual $15-50 investment per host is more costly than the information on and between them - including what could be on them (e.g., compromised, serving malware), then the choice is simple: don't worry about buying certs. Otherwise, it's important to look into them.
The comment by Adam Hupp on this webpage provides a good, simple scenario:
http://www.vedetta.com/self-signed-ssl-certificates-vs-commercial-ssl-certificates-how-mozilla-is-killing-self-signed-certificates
And here's a more fleshed out description of the risk:
http://blog.ivanristic.com/2008/07/vast-numbers-of.html
And finally a balanced look at the two scenarios, though this article only considers self-signed OK when there is a fully-functional, properly protected and implemented Certificate Authority server installed:
http://www.networkworld.com/news/tech/2012/021512-ssl-certificates-256189.html
I see no advantage in using official certificates for this task - besides the fact that your marketing dept. could claim your infrastructure is "100% certified by $CA". Encryption algorithm/strength and cert duration can be the same, depending on how you configure it.
The recommendations you hear probably focus on the far more common usage of HTTPS for communication with browsers, which nowadays complain about self signed certs. For data transfer between servers, I think it's good practice to encrypt traffic the way you plan on doing it!

What is best way to update digital certificates from server to many clients when certificate expires?

One of my friend is working on issue related to updating expired digital certificates.
He is working on Java application(Swings I guess), which has 4000 clients. All those need a digital certificate to connect to the application and this certificate expires every year.
At the end of year he needs to update the certificate credentials for all clients. Currently this is manual process, done by connecting to each of 4000 systems either locally or by remote connection.
He is got task to convert this process to be an automated process.
Normally the client-side certificate (used by authenticating the client on the server) needs to be passed to the client physically (on the carrier), otherwise, if the certificate is sent via electronic channels, there's a high risk of interception. But if secure connection is used, then the problem becomes less critical.
So the answer depends on how the client-side application is built. The easiest approach would be to add capabilities to refresh the certificate (before it expires) right from the application. The application would request fresh certificate from the server.
If no such capabilities are built-in and there's no way to add them, then the answer would depend on where the client-side application stores the certificate, used for authentication. If it's some file, then automating remote desktop connection using some automation tool would be the only choice.