private static byte[] EncodeData(byte[] publicKey, byte[] serialNumber)
        {
            IntPtr publicKeyPtr = IntPtr.Zero, serialNumberPtr = IntPtr.Zero;

            try
            {
                var identifier = new CERT_AUTHORITY_KEY_ID2_INFO();
                identifier.AuthorityCertIssuer = new CERT_ALT_NAME_INFO {
                    cAltEntry = 0
                };
                if (serialNumber != null)
                {
                    serialNumberPtr = Marshal.AllocHGlobal(serialNumber.Length);
                    Marshal.Copy(serialNumber, 0, serialNumberPtr, serialNumber.Length);
                    identifier.AuthorityCertSerialNumber = new CRYPTOAPI_BLOB {
                        cbData = (uint)serialNumber.Length, pbData = serialNumberPtr
                    };
                }
                if (publicKey != null)
                {
                    publicKeyPtr = Marshal.AllocHGlobal(publicKey.Length);
                    Marshal.Copy(publicKey, 0, publicKeyPtr, publicKey.Length);
                    identifier.KeyId = new CRYPTOAPI_BLOB {
                        cbData = (uint)publicKey.Length, pbData = publicKeyPtr
                    };
                }
                uint dataSize = 0;
                LocalBufferSafeHandle data;
                if (!Crypt32.CryptEncodeObjectEx(EncodingType.X509_ASN_ENCODING, OIDs.szOID_AUTHORITY_KEY_IDENTIFIER2, ref identifier, 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(publicKeyPtr);
                Marshal.FreeHGlobal(serialNumberPtr);
            }
        }
        // creates the basic constraints extension.
        static void CreateAuthorityKeyIdentifierExtension(
            ref CERT_EXTENSION pExtension,
            ref CRYPT_DATA_BLOB pKeyId)
        {
	        // set the certificate as a non-CA certificate.
            CERT_AUTHORITY_KEY_ID2_INFO keyInfo = new CERT_AUTHORITY_KEY_ID2_INFO();

	        keyInfo.KeyId.cbData = pKeyId.cbData;
	        keyInfo.KeyId.pbData = pKeyId.pbData;

	        pExtension.pszObjId  = szOID_AUTHORITY_KEY_IDENTIFIER2;
	        pExtension.fCritical = 0;
            
            GCHandle hKeyInfo = GCHandle.Alloc(keyInfo, GCHandleType.Pinned);
            IntPtr pData = IntPtr.Zero;
            int dwDataSize = 0;

            try
            {
	            // calculate amount of memory required.
                int bResult = NativeMethods.CryptEncodeObjectEx(
		            X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
		            szOID_AUTHORITY_KEY_IDENTIFIER2, // X509_AUTHORITY_KEY_ID,
		            hKeyInfo.AddrOfPinnedObject(),
		            0,
		            IntPtr.Zero,
	                IntPtr.Zero,
		            ref dwDataSize);

	            if (bResult == 0)
	            {
		            throw new InvalidOperationException("Could not get size for basic constraints extension.");
	            }

	            // allocate memory.
	            pData = Marshal.AllocHGlobal(dwDataSize);

	            // encode blob.
                bResult = NativeMethods.CryptEncodeObjectEx(
		            X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
		            szOID_AUTHORITY_KEY_IDENTIFIER2, // X509_AUTHORITY_KEY_ID,
		            hKeyInfo.AddrOfPinnedObject(),
		            0,
		            IntPtr.Zero,
		            pData,
		            ref dwDataSize);

	            if (bResult == 0)
	            {
		            throw new InvalidOperationException("Could not create for basic constraints extension.");
	            }

                pExtension.Value.cbData = dwDataSize;
                pExtension.Value.pbData = pData;
                pData = IntPtr.Zero;
            }
            finally
            {
                if (pData != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pData);
                }

                if (hKeyInfo.IsAllocated)
                {
                    hKeyInfo.Free();
                }
            }
        }