libcurl's default behavior for certificate pinning - c++

We are sending requests to a server using libcurl (7.51.0). We have a .pem file where we have a set of CA certificates that are being set via CURLOPT_CAINFO option.
curl_easy_setopt(mpCURL, CURLOPT_CAINFO, "/usr/certs/certificates.pem");
Now, I would like to figure out whether the CA certificates present within the .pem are pinned or not. How do I achieve this?
Also, according to the answer in the question Public key pinning in curl does not work without using certificates from the system, it seems like as long as the CURLOPT_SSL_VERIFYPEER and CURLOPT_SSL_VERIFYHOST options are left as defaults and a set of CA certificates are provided via CURLOPT_CAINFO, cURL library implements CA certificate pinning by default. Is that correct? Does that mean that libcurl pins all the certificates that are present in the .pem file?

I confirmed that CURLOPT_SSL_VERIFYPEER's default value enables CA pinning by default. As a result, it uses the certificates mentioned in CAPATH for CA pinning.

Related

MITM proxy, TLS 1.2 Certificate verification failed

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.

Difference between x509_store_add_cert & ssl_ctx_use_certificate?

I'm trying to load multiple certificates into an SSL_CTX.
Looking at the documentation, I was able to establish SSL connection using these 2 ways:
Create an X509_STORE, add certificates to the store, and then load the cert store into the SSL_CTX using SSL_CTX_set_cert_store.
Call SSL_CTX_use_certificate(ctx, cert) multiple times
Is there a difference between these two? I saw on StackOverflow somewhere that SSL_CTX_use_certificate does not work with self signed certs? (Loading CA certificate from memory) Why? I don't see this on the documentation anywhere. (What does it mean to be self signed?)
*also for #2, does calling SSL_CTX_use_certificate multiple times replace the existing certificate? Would I need to call SSL_CTX_add_extra_chain_cert?
The X509_STORE is used for building the certificate trust chain during certificate validation. Thus, any certificates added by X509_STORE_add_cert are used when validating the peer certificate.
SSL_CTX_use_certificate instead is used to set the local certificate used for authentication against the peer, i.e. this is to set the server certificate at the server and the client certificate at the client. It must be accompanied by a function to set the private key, like SSL_CTX_use_PrivateKey. SSL_CTX_use_certificate can be called multiple times and will either replace the existing certificate or add another one: i.e. one might have both an RSA and a ECDSA certificate at the same time with newer versions of OpenSSL.
SSL_CTX_use_certificate does not work with self signed certs?
OpenSSL does not care if the certificate is self-signed or not when using SSL_CTX_use_certificate. The communication peer which receives the certificate as authentication will hopefully care though and might complain since no local trust anchor is found to validate the certificate.

How to get the CA Certificate Used to Validate Client Certificate programmatically

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

Certificate expiration and SHA-1

Background: I'm a complete newbie when it comes to certificates.
We have a site running at https://global.projacked.com
The certificate is issued by AWS.
All works well for most of our customers but...
One of them is experiencing the following:
And when I click on "view certificate" I see:
So the question is: can we do anything on our end to make this work?
If not: what can I tell my customer to do to make it work? Is it a question of them updating their certificate? Or might it be cause by them being in a secured network (e.g. VPN)?
Thank you immensely in advance for your help
Your site global.projacked.com is serving a valid SHA-256 certificate. The customer who has reported this issue appears to be having its HTTPS traffic intercepted and inspected by some sort of a MITM software or device (the Issuer -- apotex-CA -- on the certificate they're seeing gives it away). The MITMing entity is generating a certificate that is trusted by the customer's browser but it happens to be a SHA-1 certificate causing Chrome to complain.
You cannot do anything to fix their issue. A lot of MITM software vendors have released updates that create SHA-256 certificates to avoid situations such as this. They can probably check to see if there are updates they can install that generate SHA-256 certificates or read this or this to see if they really need to have TLS traffic intercepted and inspected. Sadly, I've seen organizations where the "solution" to this issue is to install an older version of Chrome that did not care about SHA-1 certificates and disable auto-update. After all, burying your head in the sand is very good at blocking all the noise about this little thing called security.
The certificate issuer should be able to issue a certificate under SHA-256. You'll then need to replace the certificate on the server.
Some certificate authorities can give you new cert as a re-issue of the old one, some will require CSR (Certificate Signing Request) that can be constructed based on the existing private key, which likely resides on the server too.

How to establish a bi directional connection with ssl certificate?

I'm trying to connect with one of my client to call api methods from their server, the client want to have a bi-directional commnunication, they shared their security certificate which contains CACert.crt, another file with .crt, .key, .p7b, .pfx files. Now They want us to share our certificate. I've following questions:
How I install their certificate?
How I can generate my certificate? Do I need to purchase certificate for this or I need to generate something based on their certificate?
They mentioned about DataPower public certificate. After Googling, I found Datapower is from the IBM, can I create a free certificate from it?
I'm absolutely new to this, tried to google a lot, but couldn't make much sense.
It sounds like your client wants you to use a client certificate. They've provided you with a CA for you to use; just use that to fulfill the signing request for the certificate you generate.