none
Programmatically Configure SSL Port RRS feed

  • Question

  • I'm trying to programmatically configure an SSL port via c# and am not able to get the p/invoke code to work properly. Following is the code, any help would be much appreciated! Thanks.

    static void Main (string [] args)
            {
                uint retVal = (uint)ErrorCodes.NOERROR;
                HttpApi.HTTPAPI_VERSION httpApiVersion = new HttpApi.HTTPAPI_VERSION(1, 0);
               
                retVal = HttpApi.HttpInitialize(httpApiVersion, HttpApi.HTTP_INITIALIZE_CONFIG, IntPtr.Zero);
               
                if ((uint)ErrorCodes.NOERROR == retVal)
                {
                    HttpApi.HTTP_SERVICE_CONFIG_SSL_SET configSslSet = new HttpApi.HTTP_SERVICE_CONFIG_SSL_SET();
                    HttpApi.HTTP_SERVICE_CONFIG_SSL_KEY httpServiceConfigSslKey = new HttpApi.HTTP_SERVICE_CONFIG_SSL_KEY();
                    HttpApi.HTTP_SERVICE_CONFIG_SSL_PARAM configSslParam = new HttpApi.HTTP_SERVICE_CONFIG_SSL_PARAM();
                   
                    IPAddress address = IPAddress.Any;
                    IPEndPoint ipEndPoint = new IPEndPoint(address, 9004);
                    SocketAddress socketAddress = ipEndPoint.Serialize();               
                                   
                    byte[] socketBytes = new byte[socketAddress.Size];

                    // Should copy the first 16 bytes (the SocketAddress has a 32 byte buffer, the size will only be 16, which is what the SOCKADDR accepts
                    for (int i = 0; i < socketAddress.Size; ++i)
                    {
                        socketBytes[i] = socketAddress[i];
                    }
                   
                    HttpApi.sockaddr addr = new HttpApi.sockaddr();
                    addr.sin_family = (short)AddressFamily.InterNetwork.GetHashCode();
                    addr.sin_port = 9004;
                    addr.sin_addr = new HttpApi.in_addr();
                    addr.sin_addr.sin_addr = socketBytes;
                   
                    httpServiceConfigSslKey.pIpPort = addr; //socketBytes;
                                   
                    configSslParam.AppId = Guid.NewGuid();
                    configSslParam.DefaultCertCheckMode = 0;
                    configSslParam.DefaultFlags = HttpApi.HTTP_SERVICE_CONFIG_SSL_FLAG_NEGOTIATE_CLIENT_CERT;
                    configSslParam.DefaultRevocationFreshnessTime = 0;
                    configSslParam.DefaultRevocationUrlRetrievalTimeout = 0;
                    configSslParam.pSslCertStoreName = StoreName.TrustedPeople.ToString();
                    configSslParam.pSslHash = ConvertStringToBytes("hash"); // obviously not the real hash
                    configSslParam.SslHashLength = configSslParam.pSslHash.Length;
                   
                    configSslSet.ParamDesc = configSslParam;
                    configSslSet.KeyDesc = httpServiceConfigSslKey;
               
                    retVal = HttpApi.HttpSetServiceConfiguration(IntPtr.Zero, HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo, ref configSslSet,
                        Marshal.SizeOf(configSslSet), IntPtr.Zero);
                   
                    if ((uint)ErrorCodes.NOERROR != retVal)
                    {
                        Console.WriteLine(string.Format("Failed to set the cert. Return code = {0}", retVal));
                    }
                   
                    HttpApi.HttpTerminate(HttpApi.HTTP_INITIALIZE_CONFIG, IntPtr.Zero);
                }
               
                Console.ReadKey(true);
            }
           
           
            private static byte[] ConvertStringToBytes(string input)
            {

                MemoryStream stream = new MemoryStream(); 

                using (StreamWriter writer = new StreamWriter(stream))
                {
                    writer.Write(input);
                    writer.Flush();
                } 

               return stream.ToArray();
            }

    NOTE: this code was in a different file called HttpApi.cs on my computer.

    #region Enums
       
        public enum ErrorCodes
        {
            NOERROR = 0x0
        }
       
        public enum HTTP_SERVICE_CONFIG_ID
        {
             HttpServiceConfigIPListenList = 0,
             HttpServiceConfigSSLCertInfo,
             HttpServiceConfigUrlAclInfo,
             HttpServiceConfigMax
        }
       
        #endregion Enums
           
        public static class HttpApi
        {
            #region Structures
           
            [StructLayout(LayoutKind.Sequential)]
            public struct in_addr
            {
                [MarshalAs(UnmanagedType.ByValArray, SizeConst=4)]
                public byte[] sin_addr;
            }

            [StructLayout(LayoutKind.Sequential)]
            public struct sockaddr
            {
                public short sin_family;
                public ushort sin_port;
                public in_addr sin_addr;
                [MarshalAs(UnmanagedType.ByValArray, SizeConst=8)]
                public byte[] sin_zero;
            }
           
            [StructLayout(LayoutKind.Sequential)]
            public struct HTTP_SERVICE_CONFIG_SSL_KEY
            {
                 public sockaddr pIpPort;
            }
           
            [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
            public struct HTTP_SERVICE_CONFIG_SSL_PARAM
            {
                 public int SslHashLength;
                 public byte[] pSslHash;
                 public Guid AppId;
                 [MarshalAs(UnmanagedType.LPWStr)]
                 public string pSslCertStoreName;
                 public uint DefaultCertCheckMode;
                 public int DefaultRevocationFreshnessTime;
                 public int DefaultRevocationUrlRetrievalTimeout;
                 [MarshalAs(UnmanagedType.LPWStr)]
                 public string pDefaultSslCtlIdentifier;
                 [MarshalAs(UnmanagedType.LPWStr)]
                 public string pDefaultSslCtlStoreName;
                 public uint DefaultFlags;
            }


            [StructLayout(LayoutKind.Sequential)]
            public struct HTTP_SERVICE_CONFIG_SSL_SET
            {
                 public HTTP_SERVICE_CONFIG_SSL_KEY KeyDesc;
                 public HTTP_SERVICE_CONFIG_SSL_PARAM ParamDesc;
            }
           
            [StructLayout(LayoutKind.Sequential, Pack = 2)]
            public struct HTTPAPI_VERSION
            {
                 public ushort HttpApiMajorVersion;
                 public ushort HttpApiMinorVersion;

                 public HTTPAPI_VERSION(ushort majorVersion, ushort minorVersion)
                 {
                     HttpApiMajorVersion = majorVersion;
                     HttpApiMinorVersion = minorVersion;
                 }
            }
                   
            #endregion Structures
           
            #region Constants
           
            public const uint HTTP_INITIALIZE_CONFIG = 0x00000002;
            public const uint HTTP_SERVICE_CONFIG_SSL_FLAG_USE_DS_MAPPER = 0x00000001;
            public const uint HTTP_SERVICE_CONFIG_SSL_FLAG_NEGOTIATE_CLIENT_CERT = 0x00000002;
            public const uint HTTP_SERVICE_CONFIG_SSL_FLAG_NO_RAW_FILTER = 0x00000004;
           
            #endregion Constants
                   
            #region DllImport
           
            [DllImport("httpapi.dll", SetLastError = true)]
            public static extern uint HttpSetServiceConfiguration(
                IntPtr ServiceIntPtr,
                HTTP_SERVICE_CONFIG_ID ConfigId,
                [In] ref HTTP_SERVICE_CONFIG_SSL_SET pConfigInformation,
                int ConfigInformationLength,
                IntPtr pOverlapped);
               
            [DllImport("httpapi.dll", SetLastError = true)]
            public static extern uint HttpInitialize(
                HTTPAPI_VERSION Version,
                uint Flags,
                IntPtr pReserved);
               
            [DllImport("httpapi.dll", SetLastError = true)]
            public static extern uint HttpTerminate(
                uint Flags,
                IntPtr pReserved);
       
            #endregion DllImport
        }
    Monday, November 16, 2009 11:52 PM

Answers

  • Hi,
    You may have a try following code snippet, hope it can help:
                 [DllImport("httpapi.dll", SetLastError = true)]
                 public static extern uint HttpSetServiceConfiguration(
                 IntPtr ServiceIntPtr,
                 HTTP_SERVICE_CONFIG_ID ConfigId,
                 IntPtr pConfigInformation,
                 int ConfigInformationLength,
                 IntPtr pOverlapped);


                 IntPtr pInputConfigInfo = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(HttpApi.HTTP_SERVICE_CONFIG_SSL_SET)));
                     Marshal.StructureToPtr(configSslSet, pInputConfigInfo, false);

                 retVal = HttpApi.HttpSetServiceConfiguration(IntPtr.Zero, HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo, pInputConfigInfo,
                 Marshal.SizeOf(configSslSet), IntPtr.Zero);


    See also: http://www.pinvoke.net/default.aspx/httpapi/HttpSetServiceConfiguration.html

    Thanks,
    Eric
    Please remember to mark helpful replies as answers and unmark them if they provide no help.
    Thursday, November 19, 2009 11:00 AM