SSL error RemoteCertificateNameMismatch - wcf

I am using WCF for the client to access service. I am trying to access the endpoint with TLS (https). I have certificates with both private and public keys.
If I have the end point of the service to have the host name same as the certificate name ("Issued To"), then i am able to access the service from the client.
If the names of the "issued to" and end point domain name are different i get the error "Could not establish trust relationship for the SSL/TLS secure channel with authority". I have added the certificates to "Trusted Root", "Personal" and "trusted People". In my service i have used "PeerOrChainTrust".
Please let me know if anybody has any idea on this.
Thanks,
Jan

In that case, you need to define the trust policy for the server on client side,
Call SetCertPolicy once before you make any call to the services.
using System.Net;
using System.Security.Cryptography.X509Certificates;
public static void SetCertPolicy()
{
ServicePointManager.ServerCertificateValidationCallback += RemoteCertValidate;
}
private static bool RemoteCertValidate( object sender, X509Certificate cert, X509Chain chain,
SslPolicyErrors error )
{
// trust any cert!!!
return true;
}

I don't think you can override the check on whether the certificate name matches the server name.
Some agents allow you to manually override after the warnings, but unless WCF has a setting to disable certificate validation with all the dangers that brings. SSL is designed first and foremost for the client to be able to validate which server it is talking to, otherwise you will be open to all sorts of vulnerabilities (including man-in-the-middle and fake servers).

Related

How gRPC's NewClientTLSFromCert generates TLS credentials from public key?

The google.golang.org/grpc/credentials library has the following method.
// NewClientTLSFromCert constructs TLS credentials from the provided root
// certificate authority certificate(s) to validate server connections. If
// certificates to establish the identity of the client need to be included in
// the credentials (eg: for mTLS), use NewTLS instead, where a complete
// tls.Config can be specified.
// serverNameOverride is for testing only. If set to a non empty string,
// it will override the virtual host name of authority (e.g. :authority header
// field) in requests.
func NewClientTLSFromCert(cp *x509.CertPool, serverNameOverride string) TransportCredentials {
return NewTLS(&tls.Config{ServerName: serverNameOverride, RootCAs: cp})
}
I am confused about how it can generate TLS credentials from a public key (the certificate here).
How will this work? If I generate credentials from a public cert, why would it be accepted on the server side whose TLS cert has been signed with the private key of the TLS CA?
What exactly happens here and how is the connection secured over here?
Transport "credentials" in gRPC are fully responsible for the handshake with the client/server. That means they include configuration other than just "credentials" like private keys and other secrets. For TLS here, it includes the root trust certificates to use when verifying the server's certificate. You can think of it as just "TLS configuration."

What's the "system trust roots on the apiserver" for the "caBundle" in defination of "WebhookClientConfig" of Kubernetes

When I check the definition of "WebhookClientConfig" of API of Kubernetes I found comments like this:
// `caBundle` is a PEM encoded CA bundle which will be used to validate the webhook's server certificate.
// If unspecified, system trust roots on the apiserver are used.
// +optional
CABundle []byte `json:"caBundle,omitempty" protobuf:"bytes,2,opt,name=caBundle"`
in WebhookClientConfig
I wonder to know, what's exactly the "system trust roots "?
and I'm afraid the internal signer for CSR API of Kubernetes is not one of them.
It is a good practice to use secure network connections. A Webhook-endpoint in Kubernetes is typically an endpoint in a private network. A custom private CABundle can be used to generate the TLS certificate to achieve a secure connection within the cluster. See e.g. contacting the webhook.
Webhooks can either be called via a URL or a service reference, and can optionally include a custom CA bundle to use to verify the TLS connection.
This CABundle is optional. See also service reference for how to connect.
If the webhook is running within the cluster, then you should use service instead of url. The service namespace and name are required. The port is optional and defaults to 443. The path is optional and defaults to "/".
Here is an example of a mutating webhook configured to call a service on port "1234" at the subpath "/my-path", and to verify the TLS connection against the ServerName my-service-name.my-service-namespace.svc using a custom CA bundle

activemq-cpp c++ client how to use ssl url to connect server

I am currently using the activemq-cpp c++ client to connect to the backend server. When using the TCP protocol, it is possible to communicate. I am using the example above at https://activemq.apache.org/components/cms/example. But now I need to use the SSL protocol. My code is as follows:
brokerURI ="failover:(ssl://xxxx:61617)";
auto connectionFactory = new ActiveMQConnectionFactory(brokerURI);
connectionFactory->setUsername(username);
connectionFactory->setPassword(password);
connection = connectionFactory->createConnection();
connection->start();
I got stuck in the start function and didn't throw any exceptions. I don't know why. Could give me a simple c++ ssl code connection demo for me to learn? Thank you.
The [example][1] documents the SSL configuration that you need to do, which is to tell the library where the key store, and trust store (and password) live.
// SSL:
// =========================
// To use SSL you need to specify the location of the trusted Root CA or the
// certificate for the broker you want to connect to. Using the Root CA allows
// you to use failover with multiple servers all using certificates signed by
// the trusted root. If using client authentication you also need to specify
// the location of the client Certificate.
//
// System::setProperty( "decaf.net.ssl.keyStore", "<path>/client.pem" );
// System::setProperty( "decaf.net.ssl.keyStorePassword", "password" );
// System::setProperty( "decaf.net.ssl.trustStore", "<path>/rootCA.pem" );
//
// The you just specify the ssl transport in the URI, for example:
//
// ssl://localhost:61617
//

How to get Remote server untrusted SSL certificate using Apache HTTP Client API

I have a remote server which may or may not be running using a valid SSL cert (using self-signed SSL cert).
We are making connection to remote server, which may fail if remote server is using self-signed SSL cert. So, we want to be able to download/view the remote server cert if our SSL handshake fails.
If I use Apache HTTP Client then I couldn't find a method which could allow me to view remote server certificate (you can do it with HttpsURLConnection but we are trying to avoid using it see this example).
I also looked into Spring RestTemplate, and it didn't provide any option either - I searched on Google and didn't find anything around Spring or Apache HTTP Client.
This should give you pretty much a complete control over the process of trust verification.
SSLContext sslContext = SSLContextBuilder.create()
.loadTrustMaterial((chain, authType) -> {
for (X509Certificate cert: chain) {
System.out.println(cert.getSubjectDN());
}
// Let the standard trust managers decide
// whether or not the cert chain is trusted
return false;
})
.build();
CloseableHttpClient client = HttpClientBuilder.create()
.setSSLContext(sslContext)
.build();

Unable to send mail to local SMTP server with TLS

So we have a local exchange server that we use as a SMTP server for our internal servers. I'm trying to fix so it works with TLS but right now it's not.
I have a wildcard certificate assigned to both SMTP and the IIS roles. But When I try to use send-mailmessage through PowerShell for example I am getting.
Send-MailMessage -SmtpServer mail.domain.com -UseSsl -port 465 -From fromaddress
-To tomailaddress -Subject test -BodyAsHtml test -Encoding ([System.Text.Encoding]::UTF8)
The remote certificate is invalid according to the validation procedure.
The certificate used is valid for me when I go to the IIS site (or any other site that uses the same certificate).
So what am I doing wrong? Or how can I troubleshoot this.
Keep noted that the SSL certificate for SMTP couldn´t be managed with the IIS. You need to use powershell here (Enable-ExchangeCertificate) [more infos here].
Example:
Enable-ExchangeCertificate -Thumbprint
434AC224C8459924B26521298CE8834C514856AB -Services SMTP
In general you can troubleshoot such a TLS connection (over port 465) with Openssl (see here for a howto).
The URL also has also some solutions in place, so I will not copy them all here. In general the issues are:
The SSL certificate isn´t fully trusted on the remote machine (or in the keystore, which didn´t apply to your powershell test, but might apply to your 3rd party software)
There is still a self signed SSL certificate in use with SMTP
Conclusion:
I think you still use a self signed ssl certificate on the SMTP port and should change that with the command above.
I had the same issue. First I used the below code to save a copy of the certificate used by the SMTP server (since I didn't have access to the server itself / even if you do have access, this shows which server's being presented so may flag if it's different to what you'd expected). I ran this via LinqPad5 as a c# Program.
void Main()
{
System.Net.ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(OutputCertificateCallback);
using (System.Net.Mail.SmtpClient S = new System.Net.Mail.SmtpClient("smtprelay.subdomain.example.com"))
{
S.EnableSsl = true;
using (System.Net.Mail.MailMessage M = new System.Net.Mail.MailMessage("john.bevan#example.com", "john.bevan#example.com", "Test", "Test"))
{
try
{
S.Send(M);
Console.WriteLine("Sent");
}
catch (Exception e)
{
Console.WriteLine("Error {0}", e);
}
}
}
}
private bool OutputCertificateCallback(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors)
{
Console.WriteLine(certificate);
System.IO.File.WriteAllBytes(#"C:\Temp\cert.cer", certificate.Export(System.Security.Cryptography.X509Certificates.X509ContentType.Cert));
var c2 = new System.Security.Cryptography.X509Certificates.X509Certificate2(certificate);
return c2.Verify();
}
I was then able to inspect the certificate by viewing the saved file: C:\Temp\cert.cer
Check the expiry date to ensure the certificate is valid.
If it's not, that's the problem. Get a new certificate.
Check that the root certificate in my client's trusted CAs:
Start, Run, MMC
File > Add/Remove SnapIn > Certificates > Add > My User Account > Finish > OK
Certificates - Current User > Trusted Root Certificate Authorities > Certificates
Search for the root CA (i.e. the one with the same name as your certificate) in this list
If it's not you may need to install the root CA, the intermediary CA, or the certificate itself (which you can do using the file you just saved using the above script).
Check that the port is open on the firewall. You can test this via the below PowerShell:
try {
$tcp = New-Object -TypeName 'system.net.sockets.tcpclient' -ArgumentList 'smtprelay.subdomain.example.com', 465
if ($tcp.Connected) {':)'} else {':('}
} catch {
':('
$_.Exception.Message
}
In my case, all of the above weren't enough to spot the issue. Eventually I realised the service used a wildcard certificate (e.g. *.example.com), but the mail server was on a subdomain (e.g. smtprelay.subdomain.example.com) so wasn't covered by this certificate. Using a wildcard on the subdomain (e.g. *.subdomain.example.com) would have worked; though we just requested that the service be given an explicitly named certificate (for smtprelay.subdomain.example.com), including the service's individual nodes' FQDNs as Subject Alternative Names, in case we ever needed to target a specific node for debugging.