How to make RNIFSend of BizTalk RosettaNet Accelerator work with self-signed certificates

Microsoft

If self-signed certificates are used with RosettaNet web application (i.e: RNIFSend and RNIFReceive), then you may keep getting the following 400 bad requests due to SSL failure.

 

Event Type:        Error

Event Source:    BizTalk Server

Event Category: (1)

Event ID:              5754

Date:                     3/31/2020

Time:                     12:39:11 AM

User:                     N/A

Computer:          wjzhan779VM

Description:

A message sent to adapter "HTTP" on send port "WENZHE2020.Async" with URI "http://localhost/BTARNApp/RNIFSend.aspx?TPUrl=https%%3a%%2f%%2fwenbim373vm%%2fBTARNApp%%2fRNIFReceiv..." is suspended.

 Error details: The remote server returned an error: (400) Bad Request.

 MessageId:  {C5F206DB-1CFD-4152-9291-C95FAA364464}

InstanceID: {DB2A8C6E-1154-4819-A117-A2FC92EFD30A}

 

For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp.

 

However you verified all SSL related certs and config are correct:

 

  • All Cert trust relationship looks good.
  • Browser access to both SSL sites are fine.
  • No certificate chain verification errors in CAPI2 log.

 

The root cause is actually inside the logic of the following function of RNIFSend web page while handling self-signed certificates. It only adds parent CA certificates into chainThumbprints which leads to this list always be empty since we directly adds self-signed public cert into trust root store.

 

        private bool AcceptSSLCertificate(Object sender,

            X509Certificate certificate,

            X509Chain certificateChain,

            System.Net.Security.SslPolicyErrors sslPolicyErrors)

        {

            Boolean isCertFound = false;

            List<string> chainThumbprints = new List<string>();

 

            foreach (X509ChainElement element in certificateChain.ChainElements)

            {

                if (element.Certificate.Thumbprint != certificate.GetCertHashString())

                {

                    chainThumbprints.Add(element.Certificate.Thumbprint);

                }

            }

           

            X509Store trustedRootStore = new X509Store(StoreName.Root, StoreLocation.LocalMachine);

            trustedRootStore.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly);

 

            X509Certificate2Collection storecollection = (X509Certificate2Collection)trustedRootStore.Certificates;

            foreach (X509Certificate2 x509 in storecollection)

            {

                if (chainThumbprints.Contains(x509.Thumbprint))

                {

                    isCertFound = true;

                    break;

                }

            }

           

            return isCertFound;

        }

 

So the solution is to build a custom Microsoft.Solutions.BTARN.RNIFSend.dll from SDK sample and comment that if statement. Then deployed this customized RNIFSend to IIS to perform data sending.

 

 

 

 

  private bool AcceptSSLCertificate(Object sender,
            X509Certificate certificate,
            X509Chain certificateChain,
            System.Net.Security.SslPolicyErrors sslPolicyErrors)
        {
            Boolean isCertFound = false;
            List<string> chainThumbprints = new List<string>();

            foreach (X509ChainElement element in certificateChain.ChainElements)
            {
                //if (element.Certificate.Thumbprint != certificate.GetCertHashString())
                {
                    chainThumbprints.Add(element.Certificate.Thumbprint);
                }
            }
            
            X509Store trustedRootStore = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
            trustedRootStore.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly);

            X509Certificate2Collection storecollection = (X509Certificate2Collection)trustedRootStore.Certificates;
            foreach (X509Certificate2 x509 in storecollection)
            {
                if (chainThumbprints.Contains(x509.Thumbprint))
                {
                    isCertFound = true;
                    break;
                }
            }
            
            return isCertFound;
        }

 

 

 

This custom RNIFSend page will be able to work well with self-signed certificates.

 

0 Replies