コード例 #1
0
        private void RebuildExtensions()
        {
            if (_frozen)
            {
                return;
            }
            Marshal.FreeHGlobal(_blob);
            var structSize = Marshal.SizeOf(typeof(CERT_EXTENSION));

            _blob = Marshal.AllocHGlobal(structSize * _marshaledExtensions.Count);
            for (int index = 0, offset = 0; index < _marshaledExtensions.Count; index++, offset += structSize)
            {
                var marshalX509Extension = _marshaledExtensions[index];
                Marshal.StructureToPtr(marshalX509Extension.Value, IntPtrArithmetic.Add(_blob, offset), false);
            }
        }
コード例 #2
0
        private static byte[] EncodeExtension(IList <X509AlternativeName> altNames)
        {
            var certAltName = new CERT_ALT_NAME_INFO();

            certAltName.cAltEntry = (uint)altNames.Count;
            var structSize     = Marshal.SizeOf(typeof(CERT_ALT_NAME_ENTRY));
            var altNamesBuffer = Marshal.AllocHGlobal(structSize * altNames.Count);
            var unionValues    = new List <IntPtr>();

            try
            {
                for (int index = 0, offset = 0; index < altNames.Count; index++, offset += structSize)
                {
                    var altName = new CERT_ALT_NAME_ENTRY();
                    altName.dwAltNameChoice = (CertAltNameChoice)altNames[index].Type;
                    switch (altName.dwAltNameChoice)
                    {
                    case CertAltNameChoice.CERT_ALT_NAME_DNS_NAME:
                        altName.Value = new CERT_ALT_NAME_ENTRY_UNION
                        {
                            pwszDNSName = Marshal.StringToHGlobalUni((string)altNames[index].Value)
                        };
                        unionValues.Add(altName.Value.pwszDNSName);
                        break;

                    case CertAltNameChoice.CERT_ALT_NAME_URL:
                        altName.Value = new CERT_ALT_NAME_ENTRY_UNION
                        {
                            pwszURL = Marshal.StringToHGlobalUni((string)altNames[index].Value)
                        };
                        unionValues.Add(altName.Value.pwszURL);
                        break;

                    case CertAltNameChoice.CERT_ALT_NAME_IP_ADDRESS:
                        var ip           = (IPAddress)altNames[index].Value;
                        var addressBytes = ip.GetAddressBytes();
                        var ipBytes      = Marshal.AllocHGlobal(addressBytes.Length);
                        Marshal.Copy(addressBytes, 0, ipBytes, addressBytes.Length);
                        altName.Value = new CERT_ALT_NAME_ENTRY_UNION
                        {
                            IPAddress = new CRYPTOAPI_BLOB
                            {
                                cbData = (uint)addressBytes.Length,
                                pbData = ipBytes
                            }
                        };
                        unionValues.Add(ipBytes);
                        break;
                    }
                    Marshal.StructureToPtr(altName, IntPtrArithmetic.Add(altNamesBuffer, offset), false);
                }
                certAltName.rgAltEntry = altNamesBuffer;
                uint dataSize = 0;
                LocalBufferSafeHandle data;
                if (!Crypt32.CryptEncodeObjectEx(EncodingType.X509_ASN_ENCODING, OIDs.szOID_SUBJECT_ALT_NAME2, ref certAltName, 0x8000, IntPtr.Zero, out data, ref dataSize))
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }
                using (data)
                {
                    var buffer = new byte[dataSize];
                    Marshal.Copy(data.DangerousGetHandle(), buffer, 0, (int)dataSize);
                    return(buffer);
                }
            }
            finally
            {
                Marshal.FreeHGlobal(altNamesBuffer);
                unionValues.ForEach(Marshal.FreeHGlobal);
            }
        }