I've searching for a solution to my problem for a couple days now and have found almost nothing. Here's the issue: I need to attach an SSL certificate to a website in IIS 6. I can set the https binding but every time I try to set the certificate's thumbprint, and the certificate store, for the binding I get COM Exceptions. Here's my code.
Private Const UnformattedMetabasePathForSiteProperties As String = "IIS://localhost/W3SVC/{0}"
Private metabasePath As String
Public Sub BindCertificateToSite(iisSiteId As Integer, ByVal aCertificate As X509Certificate2) Implements IIisSslHandler.BindCertificatetoSite
metabasePath = UnformattedMetabasePathForSiteProperties.FormatIt(iisSiteId)
Dim ipAddress As String = GetProperty(metabasePath, "ServerBindings")
Contract.Require(Not String.IsNullOrEmpty(ipAddress), New Exception("Failed to find the site's http binding and IP address. Can not bind certificate to site."))
ipAddress = ipAddress.Split(":")(0)
SetProperty(metabasePath, "SecureBindings", ipAddress & ":443:", True)
SetProperty(metabasePath, "SSLStoreName", "MY", True)
SetBinaryProperty(metabasePath, "SSLCertHash", aCertificate.Thumbprint, True)
End Sub
Private Sub SetProperty(ByVal metabasePath As String, ByVal propertyName As String, ByVal newValue As Object, clearCurrentValue As Boolean)
Dim path As DirectoryEntry
path = New DirectoryEntry(metabasePath)
If clearCurrentValue Then path.Properties(propertyName).Clear()
path.Properties(propertyName).Add(newValue)
path.CommitChanges()
End Sub
Private Sub SetBinaryProperty(ByVal metabasePath As String, ByVal propertyName As String, ByVal newValue As Object, clearCurrentValue As Boolean)
Dim path As DirectoryEntry
path = New DirectoryEntry(metabasePath)
Dim propValues As PropertyValueCollection
propValues = path.Properties(propertyName)
If clearCurrentValue Then propValues.Clear()
propValues.Add(newValue)
path.CommitChanges()
End Sub
The exceptions I get ocurrs at the propValues.Add call for both the SSLStoreName and the SSLCertHash
SSLStoreName exception: An exception of type 'System.Runtime.InteropServices.COMException' occurred in System.DirectoryServices.dll but was not handled in user code. Additional information: A specified logon session does not exist. It may already have been terminated. (Exception from HRESULT: 0x80070520)
SSLCertHash Exception: An exception of type 'System.Runtime.InteropServices.COMException' occurred in mscorlib.dll but was not handled in user code. Additional information: Exception from HRESULT: 0x8000500C
I have found other questions here on the stack and other sites on the net that seem to point to a flaw in the .Net framework when it comes to IIS 6 but I'm hoping that's not the case here. So my question: Why isn't this working and how can I fix it?
Ok so i finally got this to work. As such I'm posting this code for future stackers and myself.
Private Const UnformattedMetabasePathForSiteProperties As String = "IIS://localhost/W3SVC/{0}"
Private metabasePath As String
Public Sub BindCertificateToSite(iisSiteId As Integer, ByVal aCertificate As X509Certificate2) Implements IIisSslHandler.BindCertificatetoSite
metabasePath = UnformattedMetabasePathForSiteProperties.FormatIt(iisSiteId)
Dim ipAddress As String = GetProperty(metabasePath, "ServerBindings")
Contract.Require(Not String.IsNullOrEmpty(ipAddress), New Exception("Failed to find the site's http binding and IP address. Can not bind certificate to site."))
ipAddress = ipAddress.Split(":")(0)
SetProperty(metabasePath, "SecureBindings", ipAddress & ":443:", True)
SetProperty(metabasePath, "SSLStoreName", "MY", True)
SetBinaryProperty(metabasePath, "SSLCertHash", aCertificate.GetCertHash(), True)
End Sub
Private Sub SetProperty(ByVal metabasePath As String, ByVal propertyName As String, ByVal newValue As Object, clearCurrentValue As Boolean)
Dim path As DirectoryEntry
path = New DirectoryEntry(metabasePath)
If clearCurrentValue Then path.Properties(propertyName).Clear()
path.Invoke("Put", propertyName, newValue)
path.CommitChanges()
End Sub
Private Sub SetBinaryProperty(ByVal metabasePath As String, ByVal propertyName As String, ByVal newValue As Object, clearCurrentValue As Boolean)
Dim path As DirectoryEntry
path = New DirectoryEntry(metabasePath)
Dim propValues As PropertyValueCollection
propValues = path.Properties(propertyName)
If clearCurrentValue Then propValues.Clear()
path.Invoke("Put", propertyName, newValue)
path.CommitChanges()
End Sub
User contributions licensed under CC BY-SA 3.0