user567879
user567879

Reputation: 5349

SSL client authentication returning Bad Certificate error

I was trying to connect to my custom wrote ssl server written in CPP. It has got client authentication features. Its throwing error Bad certificate when watched through Wireshark. At the server side the error returned was

14560:error:140890B2:SSL routines:SSL3_GET_CLIENT_CERTIFICATE:no certificate returned:s3_srvr.c:2619:

I used the following code to force requesting client certificate

SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
SSL_CTX_set_verify_depth(ctx, 1);

I could see client returning certificate in Wireshark.

Which function should be used to set the public key used for verifying the client certificate at the server side?

Upvotes: 1

Views: 16917

Answers (5)

Hariom saxena
Hariom saxena

Reputation: 11

Modify the server code with the below line:

Server code:

SSL_CTX_load_verify_locations(ctx,"client_certificate_ca.pem", NULL);
  • Here client_certificate_ca.pem is the file which generated the client certificates. verify your client certificate with the "client_certificate_ca.pem" file using below command.

verify -CAfile client_certificate_ca.pem client_certificate.pem

Client code:

if (SSL_CTX_use_certificate_file(ctx, "client_certificate.pem", SSL_FILETYPE_PEM) <= 0) 
{
}
if (SSL_CTX_use_PrivateKey_file(ctx, "client_certificate.ky", SSL_FILETYPE_PEM) <= 0)
{
}
if (!SSL_CTX_check_private_key(ctx))
{  
}

Upvotes: 0

Ranjan
Ranjan

Reputation: 1

Difference Between SSLCACertificateFile and SSLCertificateChainFile

SSLCertificateChainFile is generally the correct option to choose, as it has the least impact; it causes the listed file to be sent along with the certificate to any clients that connect.

Provide all the Root CA into the following file to resolve the issue SSLCACertificateFile (hereafter "CACert") does everything SSLCertificateChainFile does (hereafter "Chain"), and additionally permits the use of the cert in question to sign client certificates. This sort of authentication is quite rare (at least for the moment), and if you aren't using it, there's IMHO no reason to augment its functionality by using CACert instead of Chain. On the flipside, one could argue that there's no harm in the additional functionality, and CACert covers all cases. Both arguments are valid.

Needless to say, if you ask the cert vendor, they'll always push for CACert over Chain, since it gives them another thing (client certs) that they can potentially sell you down the line. ;)

Upvotes: 0

Swaru
Swaru

Reputation: 144

I was getting a similar error (only line number different):

140671281543104:error:140890B2:SSL routines:SSL3_GET_CLIENT_CERTIFICATE:no certificate returned:s3_srvr.c:3292:

I had generated self-signed certificates using the procedure mentioned in https://help.ubuntu.com/community/OpenSSL.

After juggling with the error for one day, i found that the error was because the self-generated CA was not in the trust chain of the machine I was using.

To add the CA to the trust chain in RHEL-7, one can follow the below procedure:

        To add a certificate in the simple PEM or DER file formats to the
        list of CAs trusted on the system:

        Copy it to the
                /etc/pki/ca-trust/source/anchors/
        subdirectory, and run the
                update-ca-trust
        command.

        If your certificate is in the extended BEGIN TRUSTED file format,
        then place it into the main source/ directory instead.

I think the above procedure can be followed for fedora too. If "update-ca-trust" command is not available, it might be useful to explore the commands like "update-ca-certificates". Hope this will be useful to someone.

Upvotes: 0

CCNA
CCNA

Reputation: 387

With wireshark, you will find out if the server ever requested certificate from the client. The command would be "CertificateRequest".

Upvotes: 0

sirgeorge
sirgeorge

Reputation: 6541

From the error messages it looks like your client does not present a certificate to server and you explicitely requested that a client needs to present one (in server code):

SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);

What you probably need is to tell your client code to use certificate (along with a private key):

SSL_CTX_use_certificate_chain_file(ctx, pcszCertPath);
SSL_CTX_use_PrivateKey_file(ctx, pcszPrivKeyPath,SSL_FILETYPE_PEM);

I hope that helps. Also make sure that your server uses the same certificate chain (that it trusts the same CA's). If this is a problem, let me know and I'll help you do that.

Upvotes: 1

Related Questions