Esempio n. 1
0
        private static bool kull_m_crypto_hkey_session(uint calgid, IntPtr key, uint keyLen, uint flags, IntPtr hSessionKey, IntPtr hSessionProv)
        {
            bool      status = false;
            IntPtr    keyblob, pbSessionBlob, ptr;
            uint      dwkeyblob = 0;
            uint      dwLen     = 0;
            string    container;
            IntPtr    hPrivateKey;
            RSAPUBKEY pubk = new RSAPUBKEY();

            container = Guid.NewGuid().ToString();

            if (Natives.CryptAcquireContextA(ref hSessionProv, container, null, PROV_RSA_AES, CRYPT_NEWKEYSET))
            {
                hPrivateKey = IntPtr.Zero;
                if (Natives.CryptGenKey(hSessionProv, AT_KEYEXCHANGE, CRYPT_EXPORTABLE | (RSA1024BIT_KEY / 2), hPrivateKey)) // 1024
                {
                    if (Natives.CryptExportKey(hPrivateKey, IntPtr.Zero, PRIVATEKEYBLOB, 0, IntPtr.Zero, ref dwkeyblob))
                    {
                        keyblob = Marshal.AllocHGlobal((int)dwkeyblob);
                        if (keyblob != IntPtr.Zero)
                        {
                            if (Natives.CryptExportKey(hPrivateKey, IntPtr.Zero, PRIVATEKEYBLOB, 0, keyblob, ref dwkeyblob))
                            {
                                Natives.CryptDestroyKey(hPrivateKey);
                                hPrivateKey = IntPtr.Zero;
                                Marshal.PtrToStructure(IntPtr.Add(keyblob, Marshal.SizeOf(typeof(PUBLICKEYSTRUC))), pubk);
                                dwLen       = pubk.bitlen / 8;
                                pubk.pubexp = 1;//NOTE
                                ptr         = IntPtr.Add(keyblob, Marshal.SizeOf(typeof(PUBLICKEYSTRUC)) + Marshal.SizeOf(typeof(RSAPUBKEY)));

                                ptr = IntPtr.Add(ptr, 2 * (int)dwLen); // Skip pubexp, modulus, prime1, prime2
                                Marshal.WriteByte(ptr, 1);             //*ptr = 1; // Convert exponent1 to 1
                                ZeroMemory(IntPtr.Add(ptr, 1), ((int)dwLen / 2) - 1);
                                ptr = IntPtr.Add(ptr, (int)dwLen / 2); //ptr += dwLen / 2; // Skip exponent1
                                Marshal.WriteByte(ptr, 1);             //*ptr = 1; // Convert exponent2 to 1
                                ZeroMemory(IntPtr.Add(ptr, 1), ((int)dwLen / 2) - 1);
                                ptr = IntPtr.Add(ptr, (int)dwLen);     //ptr += dwLen; // Skip exponent2, coefficient
                                Marshal.WriteByte(ptr, 1);             //*ptr = 1; // Convert privateExponent to 1
                                ZeroMemory(IntPtr.Add(ptr, 1), ((int)dwLen / 2) - 1);

                                if (Natives.CryptImportKey(hSessionProv, keyblob, dwkeyblob, IntPtr.Zero, 0, ref hPrivateKey))
                                {
                                    dwkeyblob     = (uint)((1024 / 2 / 8) + sizeof(uint) + Marshal.SizeOf(typeof(BLOBHEADER))); // 1024
                                    pbSessionBlob = Marshal.AllocHGlobal((int)dwkeyblob);
                                    BLOBHEADER bSessionBlob = new BLOBHEADER();
                                    if (pbSessionBlob != IntPtr.Zero)
                                    {
                                        bSessionBlob.bType    = SIMPLEBLOB;
                                        bSessionBlob.bVersion = CUR_BLOB_VERSION;
                                        bSessionBlob.reserved = 0;
                                        bSessionBlob.aiKeyAlg = calgid;
                                        Marshal.StructureToPtr(bSessionBlob, pbSessionBlob, false);
                                        ptr = IntPtr.Add(pbSessionBlob, Marshal.SizeOf(typeof(BLOBHEADER)));
                                        Marshal.WriteInt32(ptr, CALG_RSA_KEYX); // *(ALG_ID*)ptr = CALG_RSA_KEYX;
                                        ptr = IntPtr.Add(ptr, sizeof(uint));    // ptr += sizeof(ALG_ID);

                                        for (int i = 0; i < keyLen; i++)
                                        {
                                            Marshal.WriteByte(IntPtr.Add(ptr, i), Marshal.ReadByte(IntPtr.Add(key, (int)keyLen - i - 1))); //ptr[i] = ((LPCBYTE)key)[keyLen - i - 1];
                                        }
                                        ptr = IntPtr.Add(ptr, (int)keyLen + 1);                                                            //ptr += (keyLen + 1);
                                        for (int i = 0; i < dwkeyblob - (sizeof(uint) + Marshal.SizeOf(typeof(BLOBHEADER)) + keyLen + 3); i++)
                                        {
                                            if (Marshal.ReadByte(IntPtr.Add(ptr, i)) == 0)
                                            {
                                                Marshal.WriteByte(IntPtr.Add(ptr, i), 0x42);                                           //ptr[i] = 0x42;
                                            }
                                        }
                                        Marshal.WriteByte(IntPtr.Add(pbSessionBlob, (int)dwkeyblob - 2), 2);//pbSessionBlob[dwkeyblob - 2] = 2;

                                        status = Natives.CryptImportKey(hSessionProv, pbSessionBlob, dwkeyblob, hPrivateKey, flags, ref hSessionKey);
                                        Marshal.FreeHGlobal(pbSessionBlob);
                                    }
                                }
                            }
                            Marshal.FreeHGlobal(keyblob);
                        }
                    }
                }
                if (hPrivateKey != IntPtr.Zero)
                {
                    Natives.CryptDestroyKey(hPrivateKey);
                }
                if (!status)
                {
                    kull_m_crypto_close_hprov_delete_container(hSessionProv);
                }
            }


            return(status);
        }