I am stuck with creating a http_client which uses a tls certificate (with a private key) for authentication. The cert is available in the windows certificate store.
Using http_client_config::validate_certificates is not clear to me.
Sample:
http_client_config client_config;
client_config.set_validate_certificates(true);
...
http_client client(U("https://url"), client_config);
The exception I get when trying to call the url is: "WinHttpSendRequest" 12044: A certificate is required
Can someone tell me to use a http_client with a tls cert?
Thank you.
Related
Trying to create my own simple MITM-proxy for the specific app which using TLS 1.2 protocol and connecting to several IP addresses, however got in stuck with the error in the app log "Certificate verify failed". How to solve this problem?
The app using about the following code to check the cert:
X509* cert = SSL_get_peer_certificate( ssl );
X509_STORE_CTX * xCtx = X509_STORE_CTX_new();
X509_STORE_CTX_init( xCtx, (X509_STORE*)Store, cert, NULL );
int res = X509_verify_cert( xCtx );
if( !res ) { /*Certificate verify failed*/ };
I did the following steps to achieve the result:
Created CA root key and self-signed certificate according to this manual. It is a bit outdated, so i have made some changes like md5 to sha256, also I didn't use pass phrase, used different key size and other minor changes.
Created proxy key and certificate using the above Root CA to sign it.
Both certificates have been added to the Local Computer Certificates in Personal and Trusted Root Certification Authorities (not sure if this was necessary). Btw, I'm using Windows 10.
Wrote a simple proxy server using sample code from here. Cert.pem and Key.pem took from the second step.
Changed all IP addresses in the app to 127.0.0.1:443 to see if TLS connection established successfully and we can receive first message with an Application Data.
I believe that connection established properly, because WireShark shows common sequence for establishing a TLS connection: Client/Server hello, Certificate, Client key exchange, two encrypted handshake messages. Moreover, using OpenSSL for testing connection:
openssl s_client -connect localhost:443
allow me to write some message and later successfully receive it using SSL_Read() in proxy server. However, there are some errors:
verify error:num=20:unable to get local issuer certificate
verify return:1
verify error:num=21:unable to verify the first certificate
verify return:1
Verify return code: 21 (unable to verify the first certificate)
Using OpenSSL client to directly connect to the original IP addresses give the same errors, but application works great.
Also the output:
openssl verify -CAfile "signing-ca-1.crt" "cert.crt"
WARNING: can't open config file: /usr/local/ssl/openssl.cnf
e:\MyProg\SSL_serv\Debug\cert.crt: OK
It seems that I missed something important. Could you please tell me how to solve this problem with cert?
One of the very purposes of having certificates, along with certificate authorities, is to prevent MITM. The app you are trying trick does the proper thing and checks the certificate. And it doesn't like your's. Its really that simple.
Is it possible to circumvent it and run MITM on an app anyway? Absolutely! Is it going to be easy? Probably not. What you need to do is to patch the app and remove this certificate check.
In a server application, once a connection has been established I can grab the client certificate from the SSL * I have. Is there a way to find out which CA I used to validate that certificate?
You can use the SSL_get0_verified_chain() function for this purpose. See the documentation here:
https://www.openssl.org/docs/man1.1.1/man3/SSL_get0_verified_chain.html
Note that this function was first introduced in OpenSSL 1.1.0, so this won't work in OpenSSL 1.0.2.
This post seems on point:
Find client certificate information from server in OpenSSL
Since SSL_get_peer_certificate returns an X509 cert, I would expect that the cert chain would be included (you couldn't handle a CRL properly without it, I'd think)?
This is my first time creating a WCF service. I need to use HTTPS as I will be using MembershipBinding. The steps I have taken up to this point are:
Created a certificate authority using the makecert.exe application - from this I have created a server certificate and a client certificate.
Added the certificate authority to the Trusted Root Certification Authorities within Microsoft Management Console.
Added the client and server certificates to my personal certificates within Microsoft Management Console.
Created a https binding for the service in IIS using the server certificate.
Set the appropriate permissions for the app pool on the server certificate.
Defined the service certificate within the serviceBehaviours node in the web.config.
I am now testing the service using the WCF Test Client but I am getting the message:
Error: Cannot obtain Metadata from https://localhost:444/Service.svc If this is a Windows (R) Communication Foundation service to which you have access, please check that you have enabled metadata publishing at the specified address. For help enabling metadata publishing, please refer to the MSDN documentation at http://go.microsoft.com/fwlink/?LinkId=65455.WS-Metadata Exchange Error URI: https://localhost:444/Service.svc Metadata contains a reference that cannot be resolved: 'https://localhost:444/Service.svc'. Could not establish trust relationship for the SSL/TLS secure channel with authority 'localhost:444'. The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel. The remote certificate is invalid according to the validation procedure.HTTP GET Error URI: https://localhost:444/Service.svc There was an error downloading 'https://localhost:444/Service.svc'. The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel. The remote certificate is invalid according to the validation procedure.
The error suggests that there is an issue trusting the certificate but I have trusted the certificate authority used to create it so I don't know how to resolve it. The service worked fine when I was using http.
Thanks in advance.
As your certificate is self-signed, you need to add a hack to your client call :
using (MyWCFServiceClient client = new MyWCFServiceClient())
{
#if DEBUG
ServicePointManager.ServerCertificateValidationCallback = TrustAllCertificatesCallback;
#endif
client.MyCall();
}
And the definition for TrustAllCertificatesCallback :
internal static bool TrustAllCertificatesCallback(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors errors)
{
bool isValid = true;
// TODO logic to check your self-signed certifiacte
return isValid;
}
The TrustAllCertificatesCallback callback should be deactivated on your production environement.
I have one .cer file which is a self-signed public certificate. I have added it in a truststore, configured it in a https connector, and referenced it in the WSC component. But while trying to run the code, I am getting a "no trusted certificate found error". Do I need to configure keystore or anything else?
Self signed certs can be used by the <tls:context> component. After configuration you're able to use it for http other other supported components.
<tls:context name="customContext">
<tls:trust-store path="/etc/mule/tls/.." password="yourPass"/>
<tls:key-store path="/etc/mule/tls/.." keyPassword="yourKeyPass" password="yourPass"/>
</tls:context>
More can be found at https://docs.mulesoft.com/mule-runtime/4.2/tls-configuration
I'm using thrift to write a C++ client which will call securely to the server (which is not written by me) written in java (code generated for both server and client using same thrift files). I'm a newbie in SSL communication. For the java server side, I imported the public key certificate of client to the server truststore (server-truststore.jks) to verify the client authenticity. I exported the public certificate from the server side keystore (server.jks) and used it in the client side to authenticate the server key certificate during the SSL handshake. If I list down what I did for the SSL communication:
Server Side (java):
exported the client's public key certificate to the server's truststore
Cleint Side (C++):
Loaded the server's public certificate which was exported from the server's keystore
separately loaded the client's public key and private key (This is because I can't directly use a java key store since the client is written in c++)
All the certificates used are self signed.
So far I have been unsuccessful and got the following error continuously:
SSL_connect: certificate verify failed
I have two questions:
Is the approach I used for SSL communication correct? If not, what is the correct one?
Any possible reasons for this error?
Thank you.
Check if you can verify the key invoking directly: openssl s_client -connect serverIP:Port .
If you can is problem of your code, and for that we will need more details about it.
If not... your are not using the cert. the server is sending you, or something is wrong with the certificate.