Self Signed Certificate: Can I trust the client being indeed the owner of the public key? - ssl

I am playing around with OpenSSL, and in my server code I have the following:
rc = SSL_get_verify_result(ssl);
printf("SSL_get_verify_result(): %i\n", rc);
cert = SSL_get_peer_certificate(ssl);
printf("SSL_get_peer_certificate(): %p\n", cert);
pkey = X509_get_pubkey(cert);
printf("X509_get_pubkey(): %p\n", pkey);
SSL_get_verify_result() returns X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN which is expected.
My question is, can I trust that the client is actually the owner of the pub key that I get using X509_get_pubkey() after SSL_get_verify_result() has failed with the above error.
In other words, can I perform authentication using this public key (assuming my server somehow has knowledge of this public key).
Thanks!

You can trust that the peer owns the private key of the certificate he supplies, because he also supplies a digital signature which is checked by SSL using the public key in the certificate. Only the owner of the private key can do that.
Whether you trust that the peer owns the identity expressed in the subject DN comes down to whether you trust the issuer, which in the case of a self-signed certificate is himself.
And whether that identity is authorised to communicate with your application is yet another question, which only your application can answer.

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."

C# X509Certificate2.PrivateKey threw exception "invalid provider type specified."

I have a trusted CA issued SSL certificate installed on Windows Server 2019. When the following code in ASP.NET MVC controller was run, it did retrieve the X509Certificate2, its HasProviateKey property was true. But when its PrivateKey property was accessed, it threw a CryptographicException: "invalid provider type specified."
X509Certificate2 certificate = null;
X509Store userCaStore = new X509Store(StoreName.My, StoreLocation.LocalMachine);
userCaStore.Open(OpenFlags.ReadOnly);
X509Certificate2Collection certificatesInStore = userCaStore.Certificates;
X509Certificate2Collection findResult = certificatesInStore.Find(X509FindType.FindByThumbprint, "xyz...", true);
if (findResult.Count != 1)
throw new Exception("Certificate not found.");
certificate = findResult[0];
userCaStore.Close();
The reason I need to access the private key, was that the server needs to accept some long-lasting TCP socket connections, and I plan to use the SSL certificate's public/private key to do the typical handshake: the client generates a random AES key, and uses the public key to encrypt this AES key and sends it to the server. That is why I need to access the private key on the server side to decrypt the AES key.
How do I do it?
I figured it out, partly. It has to do with the type of cryptography of the SSL certificate. I tried the same code to retrieve another trusted CA issued certificate and the PrivateKey property did present itself as RsaCryptoServiceProvider. The other thing that must be done is to right-click the certificate in the certificate store (mmc.exe) and select "All tasks | Manage private keys", and make sure the identity used by your code is there in a ACL.

Add SSL on mysubdomain.parseapp.com

I've created a subdomain for my parse app and I need to protect the connection while logging and during my session.
Assume that I don't have any public domain name and I will still use just the url of (mysubdomain.parseapp.com) then is all I need to get buy a certificate and get the two files for:
SSL Public Certificate
SSL Private Key
and just upload it to parse through the settings page ? or will I need to do something else ?
Just need a confirmation that my understanding is correct.
Kind Regards,
Robear
The private key would come from the server. A Certificate Authority is only going to give you a domain cert. For example "mysubdomain_parseapp.com_crt" and yes you'll need to upload the domain cert, private key (which is generated during the CSR request), plus the CA's intermediate cert (the CA should advise which one and where to download it).
In order for a CA to issue out a cert. You need to own the root domain or have permission by the owner. In your case you would need to prove that your the owner or have permision to purchase an SSL cert with "parseapp.com"

WCF client certificare not valid

I try to send a message to MSMQ using WCF. I want to use Transport security and sign messages. However, when I set clientcertificate credentials and try to send message, an error is being thrown: "An error occurred while sending to the queue: The user certificate is invalid. (-1072824276, 0xc00e002c)". Certificate is stored in LocalMachine\My location and has read only access set for ASPNET process.
Here are two common reasons a certificate is considered "invalid":
You don't have the private key associated with the certificate. If you don't have the private key, you need to re-install the cert with the private key, or get a new cert for which you do have the private key.
The certificate is issued by a certificate authority that is not trusted by your computer. If this is the problem, you need to install the issuing authority's certificate into your "Trusted Root Certificate Authority" store (there are security risks involved with doing this so make sure you read the pop-up warning that will come up when trying to do this).
View the certificate in the CertMgr.msc to see if its one of these issues. (Start > Run > CertMgr.msc > Personal > Certificates).

SSL error RemoteCertificateNameMismatch

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).