internal static unsafe System.Security.Cryptography.SafeLocalAllocHandle CreateEncodedCertBlob(X509Certificate2Collection certificates)
 {
     System.Security.Cryptography.SafeLocalAllocHandle invalidHandle = System.Security.Cryptography.SafeLocalAllocHandle.InvalidHandle;
     if (certificates.Count > 0)
     {
         invalidHandle = System.Security.Cryptography.CAPI.LocalAlloc(0, new IntPtr(certificates.Count * Marshal.SizeOf(typeof(System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB))));
         System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB *handle = (System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB *)invalidHandle.DangerousGetHandle();
         X509Certificate2Enumerator enumerator = certificates.GetEnumerator();
         while (enumerator.MoveNext())
         {
             System.Security.Cryptography.CAPI.CERT_CONTEXT cert_context = *((System.Security.Cryptography.CAPI.CERT_CONTEXT *)System.Security.Cryptography.X509Certificates.X509Utils.GetCertContext(enumerator.Current).DangerousGetHandle());
             handle->cbData = cert_context.cbCertEncoded;
             handle->pbData = cert_context.pbCertEncoded;
             handle++;
         }
     }
     return(invalidHandle);
 }
        internal static RecipientInfoType GetRecipientInfoType(X509Certificate2 certificate)
        {
            RecipientInfoType unknown = RecipientInfoType.Unknown;

            if (certificate == null)
            {
                return(unknown);
            }
            System.Security.Cryptography.CAPI.CERT_CONTEXT cert_context = (System.Security.Cryptography.CAPI.CERT_CONTEXT)Marshal.PtrToStructure(System.Security.Cryptography.X509Certificates.X509Utils.GetCertContext(certificate).DangerousGetHandle(), typeof(System.Security.Cryptography.CAPI.CERT_CONTEXT));
            System.Security.Cryptography.CAPI.CERT_INFO    cert_info    = (System.Security.Cryptography.CAPI.CERT_INFO)Marshal.PtrToStructure(cert_context.pCertInfo, typeof(System.Security.Cryptography.CAPI.CERT_INFO));
            switch (System.Security.Cryptography.X509Certificates.X509Utils.OidToAlgId(cert_info.SubjectPublicKeyInfo.Algorithm.pszObjId))
            {
            case 0xa400:
                return(RecipientInfoType.KeyTransport);

            case 0xaa01:
            case 0xaa02:
                return(RecipientInfoType.KeyAgreement);
            }
            return(RecipientInfoType.Unknown);
        }
        internal static unsafe uint AddCertsToMessage(System.Security.Cryptography.SafeCryptMsgHandle safeCryptMsgHandle, X509Certificate2Collection bagOfCerts, X509Certificate2Collection chainOfCerts)
        {
            uint num = 0;
            X509Certificate2Enumerator enumerator = chainOfCerts.GetEnumerator();

            while (enumerator.MoveNext())
            {
                X509Certificate2 current = enumerator.Current;
                if (bagOfCerts.Find(X509FindType.FindByThumbprint, current.Thumbprint, false).Count == 0)
                {
                    System.Security.Cryptography.CAPI.CERT_CONTEXT   cert_context   = *((System.Security.Cryptography.CAPI.CERT_CONTEXT *)System.Security.Cryptography.X509Certificates.X509Utils.GetCertContext(current).DangerousGetHandle());
                    System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB cryptoapi_blob = new System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB {
                        cbData = cert_context.cbCertEncoded,
                        pbData = cert_context.pbCertEncoded
                    };
                    if (!System.Security.Cryptography.CAPI.CryptMsgControl(safeCryptMsgHandle, 0, 10, new IntPtr((long)((ulong)((IntPtr) & cryptoapi_blob)))))
                    {
                        throw new CryptographicException(Marshal.GetLastWin32Error());
                    }
                    num++;
                }
            }
            return(num);
        }
        internal static unsafe System.Security.Cryptography.CAPI.CMSG_SIGNER_ENCODE_INFO CreateSignerEncodeInfo(CmsSigner signer, bool silent)
        {
            System.Security.Cryptography.CAPI.CMSG_SIGNER_ENCODE_INFO cmsg_signer_encode_info = new System.Security.Cryptography.CAPI.CMSG_SIGNER_ENCODE_INFO(Marshal.SizeOf(typeof(System.Security.Cryptography.CAPI.CMSG_SIGNER_ENCODE_INFO)));
            System.Security.Cryptography.SafeCryptProvHandle          invalidHandle           = System.Security.Cryptography.SafeCryptProvHandle.InvalidHandle;
            uint pdwKeySpec       = 0;
            bool pfCallerFreeProv = false;

            cmsg_signer_encode_info.HashAlgorithm.pszObjId = signer.DigestAlgorithm.Value;
            if (string.Compare(signer.Certificate.PublicKey.Oid.Value, "1.2.840.10040.4.1", StringComparison.Ordinal) == 0)
            {
                cmsg_signer_encode_info.HashEncryptionAlgorithm.pszObjId = "1.2.840.10040.4.3";
            }
            cmsg_signer_encode_info.cAuthAttr    = (uint)signer.SignedAttributes.Count;
            cmsg_signer_encode_info.rgAuthAttr   = CreateCryptAttributes(signer.SignedAttributes);
            cmsg_signer_encode_info.cUnauthAttr  = (uint)signer.UnsignedAttributes.Count;
            cmsg_signer_encode_info.rgUnauthAttr = CreateCryptAttributes(signer.UnsignedAttributes);
            if (signer.SignerIdentifierType == SubjectIdentifierType.NoSignature)
            {
                cmsg_signer_encode_info.HashEncryptionAlgorithm.pszObjId = "1.3.6.1.5.5.7.6.2";
                cmsg_signer_encode_info.pCertInfo = IntPtr.Zero;
                cmsg_signer_encode_info.dwKeySpec = pdwKeySpec;
                if (!System.Security.Cryptography.CAPI.CryptAcquireContext(ref invalidHandle, (string)null, (string)null, 1, 0xf0000000))
                {
                    throw new CryptographicException(Marshal.GetLastWin32Error());
                }
                cmsg_signer_encode_info.hCryptProv = invalidHandle.DangerousGetHandle();
                GC.SuppressFinalize(invalidHandle);
                cmsg_signer_encode_info.SignerId.dwIdChoice = 1;
                X500DistinguishedName name = new X500DistinguishedName("CN=Dummy Signer")
                {
                    Oid = new Oid("1.3.6.1.4.1.311.21.9")
                };
                cmsg_signer_encode_info.SignerId.Value.IssuerSerialNumber.Issuer.cbData = (uint)name.RawData.Length;
                System.Security.Cryptography.SafeLocalAllocHandle handle2 = System.Security.Cryptography.CAPI.LocalAlloc(0x40, new IntPtr((long)cmsg_signer_encode_info.SignerId.Value.IssuerSerialNumber.Issuer.cbData));
                Marshal.Copy(name.RawData, 0, handle2.DangerousGetHandle(), name.RawData.Length);
                cmsg_signer_encode_info.SignerId.Value.IssuerSerialNumber.Issuer.pbData = handle2.DangerousGetHandle();
                GC.SuppressFinalize(handle2);
                cmsg_signer_encode_info.SignerId.Value.IssuerSerialNumber.SerialNumber.cbData = 1;
                System.Security.Cryptography.SafeLocalAllocHandle handle3 = System.Security.Cryptography.CAPI.LocalAlloc(0x40, new IntPtr((long)cmsg_signer_encode_info.SignerId.Value.IssuerSerialNumber.SerialNumber.cbData));
                byte *handle = (byte *)handle3.DangerousGetHandle();
                handle[0] = 0;
                cmsg_signer_encode_info.SignerId.Value.IssuerSerialNumber.SerialNumber.pbData = handle3.DangerousGetHandle();
                GC.SuppressFinalize(handle3);
                return(cmsg_signer_encode_info);
            }
            System.Security.Cryptography.SafeCertContextHandle certContext = System.Security.Cryptography.X509Certificates.X509Utils.GetCertContext(signer.Certificate);
            if (!System.Security.Cryptography.CAPI.CAPISafe.CryptAcquireCertificatePrivateKey(certContext, silent ? 70 : 6, IntPtr.Zero, ref invalidHandle, ref pdwKeySpec, ref pfCallerFreeProv))
            {
                throw new CryptographicException(Marshal.GetLastWin32Error());
            }
            cmsg_signer_encode_info.dwKeySpec  = pdwKeySpec;
            cmsg_signer_encode_info.hCryptProv = invalidHandle.DangerousGetHandle();
            GC.SuppressFinalize(invalidHandle);
            System.Security.Cryptography.CAPI.CERT_CONTEXT cert_context = *((System.Security.Cryptography.CAPI.CERT_CONTEXT *)certContext.DangerousGetHandle());
            cmsg_signer_encode_info.pCertInfo = cert_context.pCertInfo;
            if (signer.SignerIdentifierType == SubjectIdentifierType.SubjectKeyIdentifier)
            {
                uint pcbData = 0;
                System.Security.Cryptography.SafeLocalAllocHandle pvData = System.Security.Cryptography.SafeLocalAllocHandle.InvalidHandle;
                if (!System.Security.Cryptography.CAPI.CAPISafe.CertGetCertificateContextProperty(certContext, 20, pvData, ref pcbData))
                {
                    throw new CryptographicException(Marshal.GetLastWin32Error());
                }
                if (pcbData <= 0)
                {
                    return(cmsg_signer_encode_info);
                }
                pvData = System.Security.Cryptography.CAPI.LocalAlloc(0x40, new IntPtr((long)pcbData));
                if (!System.Security.Cryptography.CAPI.CAPISafe.CertGetCertificateContextProperty(certContext, 20, pvData, ref pcbData))
                {
                    throw new CryptographicException(Marshal.GetLastWin32Error());
                }
                cmsg_signer_encode_info.SignerId.dwIdChoice         = 2;
                cmsg_signer_encode_info.SignerId.Value.KeyId.cbData = pcbData;
                cmsg_signer_encode_info.SignerId.Value.KeyId.pbData = pvData.DangerousGetHandle();
                GC.SuppressFinalize(pvData);
            }
            return(cmsg_signer_encode_info);
        }
Пример #5
0
        private unsafe void Verify(X509Certificate2Collection extraStore, X509Certificate2 certificate, bool verifySignatureOnly)
        {
            System.Security.Cryptography.SafeLocalAllocHandle invalidHandle = System.Security.Cryptography.SafeLocalAllocHandle.InvalidHandle;
            System.Security.Cryptography.CAPI.CERT_CONTEXT    cert_context  = (System.Security.Cryptography.CAPI.CERT_CONTEXT)Marshal.PtrToStructure(System.Security.Cryptography.X509Certificates.X509Utils.GetCertContext(certificate).DangerousGetHandle(), typeof(System.Security.Cryptography.CAPI.CERT_CONTEXT));
            IntPtr ptr   = new IntPtr(((long)cert_context.pCertInfo) + ((long)Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CERT_INFO), "SubjectPublicKeyInfo")));
            IntPtr ptr2  = new IntPtr(((long)ptr) + ((long)Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CERT_PUBLIC_KEY_INFO), "Algorithm")));
            IntPtr ptr3  = new IntPtr(((long)ptr2) + ((long)Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPT_ALGORITHM_IDENTIFIER), "Parameters")));
            IntPtr pvKey = Marshal.ReadIntPtr(ptr2);

            if (System.Security.Cryptography.CAPI.CryptFindOIDInfo(1, pvKey, 3).Algid == 0x2200)
            {
                bool   flag = false;
                IntPtr ptr5 = new IntPtr(((long)ptr3) + ((long)Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB), "cbData")));
                IntPtr ptr6 = new IntPtr(((long)ptr3) + ((long)Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB), "pbData")));
                if (Marshal.ReadInt32(ptr5) == 0)
                {
                    flag = true;
                }
                else if (Marshal.ReadIntPtr(ptr6) == IntPtr.Zero)
                {
                    flag = true;
                }
                else if (Marshal.ReadInt32(Marshal.ReadIntPtr(ptr6)) == 5)
                {
                    flag = true;
                }
                if (flag)
                {
                    System.Security.Cryptography.SafeCertChainHandle ppChainContext = System.Security.Cryptography.SafeCertChainHandle.InvalidHandle;
                    System.Security.Cryptography.X509Certificates.X509Utils.BuildChain(new IntPtr(0L), System.Security.Cryptography.X509Certificates.X509Utils.GetCertContext(certificate), null, null, null, X509RevocationMode.NoCheck, X509RevocationFlag.ExcludeRoot, DateTime.Now, new TimeSpan(0, 0, 0), ref ppChainContext);
                    ppChainContext.Dispose();
                    uint pcbData = 0;
                    if (!System.Security.Cryptography.CAPI.CAPISafe.CertGetCertificateContextProperty(System.Security.Cryptography.X509Certificates.X509Utils.GetCertContext(certificate), 0x16, invalidHandle, ref pcbData))
                    {
                        throw new CryptographicException(Marshal.GetLastWin32Error());
                    }
                    if (pcbData > 0)
                    {
                        invalidHandle = System.Security.Cryptography.CAPI.LocalAlloc(0x40, new IntPtr((long)pcbData));
                        if (!System.Security.Cryptography.CAPI.CAPISafe.CertGetCertificateContextProperty(System.Security.Cryptography.X509Certificates.X509Utils.GetCertContext(certificate), 0x16, invalidHandle, ref pcbData))
                        {
                            throw new CryptographicException(Marshal.GetLastWin32Error());
                        }
                        Marshal.WriteInt32(ptr5, (int)pcbData);
                        Marshal.WriteIntPtr(ptr6, invalidHandle.DangerousGetHandle());
                    }
                }
            }
            if (this.m_parentSignerInfo == null)
            {
                if (!System.Security.Cryptography.CAPI.CryptMsgControl(this.m_signedCms.GetCryptMsgHandle(), 0, 1, cert_context.pCertInfo))
                {
                    throw new CryptographicException(Marshal.GetLastWin32Error());
                }
                goto Label_02F4;
            }
            int num2 = -1;
            int hr   = 0;

Label_022F:
            try
            {
                num2 = PkcsUtils.GetSignerIndex(this.m_signedCms.GetCryptMsgHandle(), this.m_parentSignerInfo, num2 + 1);
            }
            catch (CryptographicException)
            {
                if (hr == 0)
                {
                    throw;
                }
                throw new CryptographicException(hr);
            }
            uint cbData = 0;

            System.Security.Cryptography.SafeLocalAllocHandle pvData = System.Security.Cryptography.SafeLocalAllocHandle.InvalidHandle;
            PkcsUtils.GetParam(this.m_signedCms.GetCryptMsgHandle(), 0x1c, (uint)num2, out pvData, out cbData);
            if (cbData == 0)
            {
                hr = -2146885618;
                goto Label_022F;
            }

            fixed(byte *numRef = this.m_encodedSignerInfo)
            {
                if (!System.Security.Cryptography.CAPI.CAPISafe.CryptMsgVerifyCountersignatureEncoded(IntPtr.Zero, 0x10001, pvData.DangerousGetHandle(), cbData, new IntPtr((void *)numRef), (uint)this.m_encodedSignerInfo.Length, cert_context.pCertInfo))
                {
                    hr = Marshal.GetLastWin32Error();
                    goto Label_022F;
                }
            }

            pvData.Dispose();
Label_02F4:
            if (!verifySignatureOnly)
            {
                int num5 = VerifyCertificate(certificate, extraStore);
                if (num5 != 0)
                {
                    throw new CryptographicException(num5);
                }
            }
            invalidHandle.Dispose();
        }