Not able to bind Server Certificate to my IIS site.

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Not able to bind Server Certificate to my IIS site.

mandarbalshankargmail
This post has NOT been accepted by the mailing list yet.
Hello all,

1. I've created a IIS site using following code:

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
     xmlns:iis="http://schemas.microsoft.com/wix/IIsExtension">
  <Fragment>
    <DirectoryRef Id="INSTALLFOLDER">
     
     
      <Component Id="CreateABCAppPool" Guid="{YOUR-GUID-HERE}" KeyPath="yes">
        <iis:WebAppPool Id="ABCAppPool"
                        Name="ABCAppPool"
                        Identity="applicationPoolIdentity"
                        ManagedPipelineMode="Integrated"
                        ManagedRuntimeVersion="v4.0" />
      </Component>

     
      <Component Id="CreateABCWebsite" Guid="{YOUR-GUID-HERE}" KeyPath="yes">
       
        <iis:WebSite Id="ABCWebsite" Description='ABCServices' Directory='INSTALLFOLDER' AutoStart='yes' StartOnInstall='yes'>
          <iis:WebAddress Id="AllUnassigned" Secure="yes" Port="443"/>
          <iis:WebApplication Id="ABCMVCApplication" Name="[ABCWebsite][WEBSITE_ID]" WebAppPool="ABCAppPool"></iis:WebApplication>
        </iis:WebSite>
      </Component>


    </DirectoryRef>

    <ComponentGroup Id="ABCWebsiteIssConfiguration">
      <ComponentRef Id="CreateABCAppPool" />
      <ComponentRef Id="CreateABCWebsite" />
    </ComponentGroup>

  </Fragment>
</Wix>

2. I've created a Custom Action for binding a Server Certificate to it; as follows:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Deployment.WindowsInstaller;
using Microsoft.Web.Administration;
using System.Security.Cryptography.X509Certificates;
using System.Diagnostics;
using System.Security.Principal;

namespace CertificateBinding
{
    public class CustomActions
    {
        const string portal = "ABCServices";
        const string protocol = "https";
        const string sslport = "*:443:";
        const string friendlyName = "ABCServiceCertificate";  

        //CustomAction to bind Server Certificate to IIS Website
        [CustomAction]
        public static ActionResult BindCertificate(Session session)
        {
            ActionResult result = ActionResult.Failure;
            session.Log("Start UpdateBinding...");  

            bool outcome = UpdateBinding(portal, protocol, sslport, friendlyName, session);
            if (outcome)
            {
                result = ActionResult.Success;
            }
                    session.Log("End UpdateBinding..");
                    return result;
             
        }

        /// <summary>
        /// Check whether returning boolean value 1
        /// </summary>
        /// <returns></returns>
        private static bool UpdateBinding(string sitename, string protocol, string port, string certFriendlyName, Session session)
        {
            session.Log("Inside UpdateBinding...");
            bool result=false;
            session.Log(string.Format("Binding info (Port) {0}.", port));
            session.Log(string.Format("Certificate Subject {0}.", certFriendlyName));

            using (ServerManager serverManager = new ServerManager())
            {
                session.Log("Before site...");
                Site site = serverManager.Sites.Where(x => x.Name == sitename).SingleOrDefault();
                session.Log(string.Format(site.Name));
                session.Log("After site...");

                X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);

                store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadWrite);

                var certificate = store.Certificates.OfType<X509Certificate2>().Where(x => x.FriendlyName == certFriendlyName).FirstOrDefault();

                if (certificate != null)
                {
                    session.Log(string.Format("Certificate - Friendly Name: {0}. Thumbprint {1} . CertHash {2}", certificate.FriendlyName, certificate.Thumbprint, certificate.GetCertHash()));

                    site.Bindings[0].CertificateHash = certificate.GetCertHash();
                    session.Log("certHash done");
                    site.Bindings[0].CertificateStoreName = store.Name;
                    session.Log("storename done");
                    site.Bindings[0].BindingInformation = port;
                    session.Log("port done");
                    serverManager.CommitChanges();
                    session.Log("commit done");
                    result = true;
                }
                else
                {
    session.Log(string.Format("Could not find a certificate with Subject Name:{0}.", certFriendlyName));
                }
                store.Close();

            }
            return result;    
        }
    }//End of Class
}//End of Namespace

Getting following error in log file at serverManager.CommitChanges(); in code:

Exception thrown by custom action:
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.IO.IOException: 5
   at Microsoft.Web.Management.Utility.HttpApiWrapper.DeleteSSLBinding(IPEndPoint endPoint)
   at Microsoft.Web.Administration.BindingManager.BindingTransaction.Commit()
   at Microsoft.Web.Administration.BindingManager.Save()
   at Microsoft.Web.Administration.ServerManager.CommitChanges()
   at CertificateBinding.CustomActions.UpdateBinding(String sitename, String protocol, String port, String certFriendlyName, Session session)
   at CertificateBinding.CustomActions.BindCertificate(Session session)
   --- End of inner exception stack trace ---
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object arguments, Signature sig, Boolean constructor)
   at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object parameters, Object arguments)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object parameters, CultureInfo culture)
   at Microsoft.Deployment.WindowsInstaller.CustomActionProxy.InvokeCustomAction(Int32 sessionHandle, String entryPoint, IntPtr remotingDelegatePtr)
CustomAction UpdateBinding returned actual error code 1603 (note this may not be 100% accurate if translation happened inside sandbox)
Action ended 8:47:37: UpdateBinding. Return value 3.
Action ended 8:47:37: INSTALL. Return value 1.