0 votes
by (420 points)

We are using IMAP as an inbound protocol for outlook.office365.com on 993 port.

We are facing issue in ValidateCertificate()

public virtual void ValidateCertificate(object sender, SslCertificateValidationEventArgs e)
        {
            ValidationResult result;

            if (IgnoreCRLCheck)
                result = e.Certificate.Validate(e.ServerName, ValidationOptions.SkipRevocationCheck, CertificateChainEngine.LocalMachine);
            else
                result = e.Certificate.Validate(e.ServerName, ValidationOptions.None, CertificateChainEngine.LocalMachine);

            LogMessage.LogInfoProgress("ValidatingCertificate()", "result.Valid:" + result.Valid.ToString() + " Status:" + result.Status.ToString(), EmailQueue);

            if (result.Valid)
            {
                CertificateStatus = true;
                e.Accept();
            }
            else
            {
                CertificateError = result.Status.ToString();
                CertificateStatus = false;
                e.Reject();
            }
        }

CertificateException : Server certificate was rejected by the verifier because of other problem.

Any pointers on this.

Imap Rebex version: 2.0.6026.0

Applies to: Rebex Secure Mail

1 Answer

0 votes
by (148k points)
selected by
 
Best answer

This exception only indicates that your custom certificate validator called e.Reject(). To be able to tell more, we would need to see result.Status. Please note that calling e.Reject(result.Status) instead of just e.Reject() would produce a more meaningful exception message.

by (420 points)
We have logged the value of result.Status and that is "IncompleteChain", Exception message is,

"CertificateException : Server certificate was rejected by the verifier because of other problem."

We are wondering what reason could cause this?

Same build with same configuration is working in other lab environment.
by (148k points)
Incomplete chain error indicates that the certificate engine was unable to construct the whole chain of certificates from the supplied certificate. A certificate chain includes the server certificate, any intermediate CA certificates and the root CA certificates. Calling "e.CertificateChain.Validate(...)" instead of "e.Certificate.Validate(...)" should solve the issue.

The original variant would still work if the intermediate CA certificates were available in the local machine's intermediate CA store. This is probably the case in the other lab environment. However, their presence is not guaranteed. Calling CertificateChain.Validate(...) ensures that intermediate CA certificates provided by the server are taken into account as well.
by (420 points)
Thanks for your quick reply.

We are not calling "e.CertificateChain.Validate(...)" instead we are calling "e.Certificate.Validate(...)", which you are suggesting. You can verify in shared source at first question.

In "e.Certificate.Validate(...)" last parameter we have provided as,
CertificateChainEngine.LocalMachine

There we have only two options LocalMachine and CurrentUser. I don't believe that will matter. what is your view?
by (148k points)
I was suggesting you call "e.CertificateChain.Validate(...)". Calling "e.Certificate.Validate(...)" is incorrect in most scenarios and it's causing the exception. Sorry for the confusion. CertificateChainEngine does not matter in this case.
by (420 points)
Oh sorry I misunderstood it.

"CertificateChainEngine does not matter in this case.",
So do you have any pointer or solution to this case?
by (148k points)
Well, what happens if you use "e.CertificateChain.Validate(...)"? Is there still an exception? If there is, what's the value of result.Status?
by (420 points)
Well CertificateChain.Validate() solved this exception. Thank you Lukas.
by (420 points)
Could you please elaborate more on "e.CertificateChain.Validate(...)" and "e.Certificate.Validate(...)".

Wanted to know whether CertificateChain.Validate() will also work in case of normal certificate which is not a chain certificates?

So my question is if we use CertificateChain.Validate() the will it work in both the scenario Certificate chain and normal certificate?
by (73.6k points)
Please specify what do you mean by normal certificate.

We can define three kinds of certificates:
 1. Root Certification Authority (also called Root CA or Root certificate or Root)
 2. Intermediate Certification Authority (also called Intermediate CA or CA certificate or CA)
 3. Leaf certificate (also called Client certificate or just certificate)

Following applies:
1. Root CA is issued by itself (this defines what Root means: self-issued certificate)
2. CA is issued either by Root CA or another Intermediate CA
3. Leaf certificate is issued either by Root CA or Intermediate CA

When you are connecting to a server, the server presents itself using Leaf certificate.
In some cases the server can present itself using Intermediate CA.
In absolutely rare scenarios the server presents itself using Root CA (this is typically test machine or private intranet machine).

The most typical configuration of the server is to send Leaf certficate and all Intermediate CA certficates, so the client is able to build the certificate chain up to Root CA.

Please note that "Validate certificate" means to always validate whole certificate chain form the given certificate up to its Root CA. There is no reason to validate only Leaf certificate without validating Root CA - if Root CA is untrusted also Leaf certificate is untrusted.

Conclusion:
If you call "e.Certificate.Validate(...)" the Intermadiate CA certificates sent by the server are ignored and the chain is built only using certificates in your local machine certificate store. This often leads to mentioned "IncompleteChain" error, because local machine CA store doesn't contain all every-issued-world-wide CA certificates.

This is why "e.CertificateChain.Validate(...)" is suggested.
...