First of all - I apologize, because I have used the solution that was described by @devstuff. However, I have found some ways to improve it.
- adding self-signed certificates handling
 
- comparison by the Raw data of certificates
 
- actual certificate authority validation
 
- some additional comments and improvements
 
Here is my modification:
private static X509Certificate2 caCertificate2 = null;
/// <summary>
/// Validates the SSL server certificate.
/// </summary>
/// <param name="sender">An object that contains state information for this validation.</param>
/// <param name="cert">The certificate used to authenticate the remote party.</param>
/// <param name="chain">The chain of certificate authorities associated with the remote certificate.</param>
/// <param name="sslPolicyErrors">One or more errors associated with the remote certificate.</param>
/// <returns>Returns a boolean value that determines whether the specified certificate is accepted for authentication; true to accept or false to reject.</returns>
private static bool ValidateServerCertficate(
        object sender,
        X509Certificate cert,
        X509Chain chain,
        SslPolicyErrors sslPolicyErrors)
{
    if (sslPolicyErrors == SslPolicyErrors.None)
    {
        // Good certificate.
        return true;
    }
    // If the following line is not added, then for the self-signed cert an error will be (not tested with let's encrypt!):
    // "A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider. (UntrustedRoot)"
    chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority;
    // convert old-style cert to new-style cert
    var returnedServerCert2 = new X509Certificate2(cert);
    // This part is very important. Adding known root here. It doesn't have to be in the computer store at all. Neither do certificates.
    chain.ChainPolicy.ExtraStore.Add(caCertificate2);
    // 1. Checks if ff the certs are OK (not expired/revoked/etc) 
    // 2. X509VerificationFlags.AllowUnknownCertificateAuthority will make sure that untrusted certs are OK
    // 3. IMPORTANT: here, if the chain contains the wrong CA - the validation will fail, as the chain is wrong!
    bool isChainValid = chain.Build(returnedServerCert2);
    if (!isChainValid)
    {
        string[] errors = chain.ChainStatus
            .Select(x => String.Format("{0} ({1})", x.StatusInformation.Trim(), x.Status))
            .ToArray();
        string certificateErrorsString = "Unknown errors.";
        if (errors != null && errors.Length > 0)
        {
            certificateErrorsString = String.Join(", ", errors);
        }
        Log.Error("Trust chain did not complete to the known authority anchor. Errors: " + certificateErrorsString);
        return false;
    }
    // This piece makes sure it actually matches your known root
    bool isValid = chain.ChainElements
        .Cast<X509ChainElement>()
        .Any(x => x.Certificate.RawData.SequenceEqual(caCertificate2.GetRawCertData()));
    if (!isValid)
    {
        Log.Error("Trust chain did not complete to the known authority anchor. Thumbprints did not match.");
    }
    return isValid;
}
setting certificates:
caCertificate2 = new X509Certificate2("auth/ca.crt", "");
var clientCertificate2 = new X509Certificate2("auth/client.pfx", "");
passing delegate method
ServerCertificateValidationCallback(ValidateServerCertficate)
client.pfx is generated with KEY and CERT as such:
openssl pkcs12 -export -in client.crt -inkey client.key -out client.pfx