EldoS | Feel safer!

Software components for data protection, secure storage and transfer

ValidateForSSL using a CA signed certificate

Also by EldoS: MsgConnect
Cross-platform protocol-independent communication framework for building peer-to-peer and client-server applications and middleware components.
#15453
Posted: 01/11/2011 09:13:39
by Sam Barber (Basic support level)
Joined: 01/11/2011
Posts: 7

Hi,

I've seen a couple of other relating to this but none of them seemed to have any answers other than read the documentation... which I have.

In your simpleFTPSDemo you use the ValidateForSSL method within the OnCertificateValidate event handler,
this method works fine when connecting to our server with a self signed certificate, but fails if that cert is signed by a certificate Authority.

It comes back with a response value of: 288
which I believe means the OCSP response could not be retrieved/validated, and the Issuer (CA) certificate was not found?

What needs to be added and where?

All i've found is that:
Code
SBHTTPCRL.Unit.RegisterHTTPCRLRetrieverFactory()
SBHTTPOCSPClient.Unit.RegisterHTTPOCSPClientFactory()
need to be added for HTTP retrieval of CRL's and OCSP which are both there.

Do you need to specify the servers to check some how and then will
validateForSSL do the rest or do different event handlers need to be added?

Looking at the certificate the OnCertificateValidate recieves by calling
Code
Certificate.Extensions.AuthorityInformationAccess.get_AccessDescriptions(0).AccessLocation
and looking at the URI it definitely has a ocsp url for that particular certificate there...

but I think I'm missing at least a couple of steps...

Any help would be much appreciated!
Cheers,
Sam
#15454
Posted: 01/11/2011 09:30:05
by Eugene Mayevski (EldoS Corp.)

Try turning off OCSP checks in the validator component and see whether it helps. If yes, then this means that OCSP responder for some server could not be contacted.

We have a special property MandatoryOCSPCheck which tells the component how to treat impossibility to obtain OCSP response. If MandatoryOCSPCheck is set to false, and OCSP response could not be obtained, then ValidityReason is set to OCSPNotVerified, but Validity itself is not set to Invalid. This lets you be notified about OCSP verification problems yet validate the chain successfully.


Sincerely yours
Eugene Mayevski
#15455
Posted: 01/11/2011 09:40:39
by Vsevolod Ievgiienko (EldoS Corp.)

You should also note that you firewall or proxy server can block OCSP requests. In this case you should setup HTTP client to make these requests using our TElHTTPOCSPClient component.
#15456
Posted: 01/11/2011 11:43:27
by Sam Barber (Basic support level)
Joined: 01/11/2011
Posts: 7

Hi guys, thanks for your help.

I tried changing the MandatoryOCSPCheck to false and it didn't make any difference, still the same error.

I did have a try validating the certificate with the sample OCSPClient and got a success message so this could suggest it could be a firewall or proxy server. Is there any sure way to check?

If I were to use the TElHTTPOCSPClient would I use it alongside the ValidateForSSL method or would I have to create completely new OnCertificateValidate event handler to include all the other CRL checks?

Thanks again!
Sam
#15457
Posted: 01/11/2011 12:28:40
by Eugene Mayevski (EldoS Corp.)

First of all, handle OnAfterCertificateValidation event which is fired for every validated certificate (not only the one in chain, but also those used to sign OCSP responses and CRLs), and see what certificate fails.

Next take TElHTTPSClient component and try accessing the OCSP URL from the certificate in question using this component. This will tell you if it can be accessed or you need to tune-up a proxy.


Sincerely yours
Eugene Mayevski
#15469
Posted: 01/12/2011 08:21:17
by Sam Barber (Basic support level)
Joined: 01/11/2011
Posts: 7

I've added the handler and pretty much just taken the code from example OCSPClient sample project:

Here is my OnAfterCertificateValidation handler, I set the reason back to 0 because the OnCertificateValidate has already set this to 288, I'm also checking that both the Server Certificate and the CA Certificate are not null because the handler runs for each certificate and on the first call CACertificate is null. Am I on the right lines?

Note: I have also added another loadCertificate method that loads the certificate recieved from the server straight into storage.

Code
private void Client_OnAfterCertificateValidation(object Sender, TElX509Certificate Certificate, TElX509Certificate CACertificate, ref TSBCertificateValidity Validity, ref int Reason, ref bool DoContinue)
        {
            string[] status = { "Success", "Malformed request", "Internal error", "Try later", "", "Signature required", "Unauthorized" };

            byte[] Reply = null;
            int res;
            short ServerResult = 0;
            int ReasonNew = 0;
            TSBCertificateValidity ValidityNew;
            int i;

            Reason = 0; //get rid of!

            if (Certificate != null && CACertificate != null)
            {
                LoadCertificates(Certificate, CertStorage);
                LoadCertificates(CACertificate, IssuerCertStorage);

                OCSPClient.IncludeSignature = true;
                OCSPClient.Nonce = SBUtils.Unit.BytesOfString(DateTime.Now.ToString()); // In real life use some cryptographically strong random data

                OCSPClient.URL = CACertificate.Extensions.AuthorityInformationAccess.get_AccessDescriptions(0).AccessLocation.UniformResourceIdentifier;

                if (OCSPClient.IncludeSignature)
                {
                    LoadCertificates(certLocation, SigningCertStorage);
                }

                res = OCSPClient.PerformRequest(ref ServerResult, ref Reply);


                if (res != 0)
                {
                    switch ((uint)res)
                    {
                        case SBOCSPCommon.Unit.SB_OCSP_ERROR_NO_PARAMETERS:
                            MessageBox.Show("URL not specified");
                            break;
                        case SBOCSPCommon.Unit.SB_OCSP_ERROR_NO_REPLY:
                            MessageBox.Show("Failed to retrieve a reply from OCSP server");
                            break;
                        case SBOCSPCommon.Unit.SB_OCSP_ERROR_WRONG_SIGNATURE:
                            MessageBox.Show("Reply from OCSP server contains invalid or broken signature");
                            break;
                        case SBOCSPCommon.Unit.SB_OCSP_ERROR_NO_CERTIFICATES:
                            MessageBox.Show("No certificates have been specified for checking");
                            break;
                        case SBOCSPCommon.Unit.SB_OCSP_ERROR_NO_ISSUER_CERTIFICATES:
                            MessageBox.Show("No issuer certificates were found");
                            break;
                        default:
                            MessageBox.Show(System.String.Format("Error {0} happened when trying to check certificate status", res));
                            break;
                    }
                }
                else
                {
                    MessageBox.Show("The server replied with the following status: " + status[ServerResult]);
                    if (ServerResult == SBOCSPCommon.Unit.oseSuccessful)
                    {
                        // First validate the server certificates
                        Validity = TSBCertificateValidity.cvStorageError;
                        if (OCSPClient.ReplyCertificates.Count == 0)
                            MessageBox.Show("The server didn\'t include signing certificates to the reply");
                        for (i = OCSPClient.ReplyCertificates.Count - 1; i >= 0; i--)
                        {
                            Validity = OCSPClient.ReplyCertificates.Validate(OCSPClient.ReplyCertificates.get_Certificates(i), ref Reason, System.DateTime.Now);
                            if (Validity == TSBCertificateValidity.cvInvalid)
                                break;
                        }
                        if (Validity == TSBCertificateValidity.cvInvalid)
                            MessageBox.Show("One of certificates, used to sign the reply, is not valid");

                        // Next, check certificate's status
                        for (i = 0; i < CertStorage.Count; i++)
                        {
                            switch (OCSPClient.get_CertStatus(i))
                            {
                                case SBOCSPCommon.Unit.csGood:
                                    MessageBox.Show(String.Format("Certificate {0} is ok", i));
                                    break;
                                case SBOCSPCommon.Unit.csRevoked:
                                    MessageBox.Show(String.Format("Certificate {0} has been revoked on {1}", i, OCSPClient.get_RevocationTime(i).ToString()));
                                    break;
                                case SBOCSPCommon.Unit.csUnknown:
                                    MessageBox.Show(String.Format("Certificate {0} is not known to OCSP server", i));
                                    break;
                            }
                        }
                    }
                }

            }


At this point the performRequest method is returning successful, and the certStatus is good, however I am not recieving any replyCertificates so the Validity is set to TSBCertificateValidity.cvStorageError.

Any further pointers would be much appreciated!

Thanks again,
Sam
#15471
Posted: 01/12/2011 08:44:26
by Vsevolod Ievgiienko (EldoS Corp.)

OCSPClient.ReplyCertificates.Count == 0 is a normal situation so you can make changes to code and do not interpret it as an error.
#15476
Posted: 01/12/2011 09:22:42
by Sam Barber (Basic support level)
Joined: 01/11/2011
Posts: 7

Cheers Vsevolod,

I'm having trouble understanding the different certificates that are validated. The OnAfterCertificateValidation handler is hit 3 times, only once where the CACertificate is not null. I thought it would only be the Server Certificate and the CA Certificate that are recieved?

This causes a problem with the method I have written.
Because I'm only doing my validation when the CACertificate is not null the Validation is still failing with the other two certificates.

Any ideas?
Cheers
#15477
Posted: 01/12/2011 09:47:55
by Eugene Mayevski (EldoS Corp.)

The event is fired for all involved certificates (as all of them are validated). This includes certificates and certificate chains, that sign the CRLs and OCSP responses. So it can happen that a dozen of certificates is validated when you try to validate one.


Sincerely yours
Eugene Mayevski
#15479
Posted: 01/12/2011 10:35:02
by Sam Barber (Basic support level)
Joined: 01/11/2011
Posts: 7

So is the process to only try and validate if there is a CACertificate?
and otherwise return Valid?

Otherwise how can you validate those without a CA? is there another method instead of PerformRequest that will allow you to validate without a CACert?
Also by EldoS: CallbackRegistry
A component to monitor and control Windows registry access and create virtual registry keys.

Reply

Statistics

Topic viewed 6263 times

Number of guests: 1, registered members: 0, in total hidden: 0




|

Back to top

As of July 15, 2016 EldoS Corporation will operate as a division of /n software inc. For more information, please read the announcement.

Got it!