Ejemplo n.º 1
0
        internal static unsafe SafeLocalAllocHandle CreateEncodedCertBlob(X509Certificate2Collection certificates)
        {
            SafeLocalAllocHandle localAllocHandle = SafeLocalAllocHandle.InvalidHandle;

            if (certificates.Count > 0)
            {
                localAllocHandle = CAPI.LocalAlloc(0U, new IntPtr(certificates.Count * Marshal.SizeOf(typeof(CAPI.CRYPTOAPI_BLOB))));
                CAPI.CRYPTOAPI_BLOB *cryptoapiBlobPtr = (CAPI.CRYPTOAPI_BLOB *)(void *) localAllocHandle.DangerousGetHandle();
                foreach (X509Certificate2 certificate in certificates)
                {
                    CAPI.CERT_CONTEXT certContext = *(CAPI.CERT_CONTEXT *)(void *) X509Utils.GetCertContext(certificate).DangerousGetHandle();
                    cryptoapiBlobPtr->cbData = certContext.cbCertEncoded;
                    cryptoapiBlobPtr->pbData = certContext.pbCertEncoded;
                    ++cryptoapiBlobPtr;
                }
            }
            return(localAllocHandle);
        }
Ejemplo n.º 2
0
        internal unsafe X509ExtensionCollection(SafeCertContextHandle safeCertContextHandle)
        {
            using (SafeCertContextHandle certContext = CAPI.CertDuplicateCertificateContext(safeCertContextHandle)) {
                CAPI.CERT_CONTEXT pCertContext = *((CAPI.CERT_CONTEXT *)certContext.DangerousGetHandle());
                CAPI.CERT_INFO    pCertInfo    = (CAPI.CERT_INFO)Marshal.PtrToStructure(pCertContext.pCertInfo, typeof(CAPI.CERT_INFO));
                uint   cExtensions             = pCertInfo.cExtension;
                IntPtr rgExtensions            = pCertInfo.rgExtension;

                for (uint index = 0; index < cExtensions; index++)
                {
                    X509Extension extension       = new X509Extension(new IntPtr((long)rgExtensions + (index * Marshal.SizeOf(typeof(CAPI.CERT_EXTENSION)))));
                    X509Extension customExtension = CryptoConfig.CreateFromName(extension.Oid.Value) as X509Extension;
                    if (customExtension != null)
                    {
                        customExtension.CopyFrom(extension);
                        extension = customExtension;
                    }
                    Add(extension);
                }
            }
        }
Ejemplo n.º 3
0
        internal static unsafe uint AddCertsToMessage(SafeCryptMsgHandle safeCryptMsgHandle, X509Certificate2Collection bagOfCerts, X509Certificate2Collection chainOfCerts)
        {
            uint num = 0U;

            foreach (X509Certificate2 certificate in chainOfCerts)
            {
                if (bagOfCerts.Find(X509FindType.FindByThumbprint, (object)certificate.Thumbprint, false).Count == 0)
                {
                    CAPI.CERT_CONTEXT certContext = *(CAPI.CERT_CONTEXT *)(void *) X509Utils.GetCertContext(certificate).DangerousGetHandle();
                    if (!CAPI.CryptMsgControl(safeCryptMsgHandle, 0U, 10U, new IntPtr((long)&new CAPI.CRYPTOAPI_BLOB()
                    {
                        cbData = certContext.cbCertEncoded,
                        pbData = certContext.pbCertEncoded
                    })))
                    {
                        throw new CryptographicException(Marshal.GetLastWin32Error());
                    }
                    ++num;
                }
            }
            return(num);
        }
Ejemplo n.º 4
0
        private unsafe void Verify(X509Certificate2Collection extraStore, X509Certificate2 certificate, bool verifySignatureOnly)
        {
            checked {
                // We need to find out if DSS parameters inheritance is necessary. If so, we need to
                // first build the chain to cause CAPI to inherit and set the parameters in the
                // CERT_PUBKEY_ALG_PARA_PROP_ID extended property. Once we have the parameters in
                // the property, we then need to retrieve a copy and point to it in the CERT_INFO
                // structure.
                SafeLocalAllocHandle pbParameters = SafeLocalAllocHandle.InvalidHandle;
                CAPI.CERT_CONTEXT    pCertContext = (CAPI.CERT_CONTEXT)Marshal.PtrToStructure(X509Utils.GetCertContext(certificate).DangerousGetHandle(), typeof(CAPI.CERT_CONTEXT));

                // Point to SubjectPublicKeyInfo field inside the CERT_INFO structure.
                IntPtr pSubjectPublicKeyInfo = new IntPtr((long)pCertContext.pCertInfo + (long)Marshal.OffsetOf(typeof(CAPI.CERT_INFO), "SubjectPublicKeyInfo"));

                // Point to Algorithm field inside the SubjectPublicKeyInfo field.
                IntPtr pAlgorithm = new IntPtr((long)pSubjectPublicKeyInfo + (long)Marshal.OffsetOf(typeof(CAPI.CERT_PUBLIC_KEY_INFO), "Algorithm"));

                // Point to Parameters field inside the Algorithm field.
                IntPtr pParameters = new IntPtr((long)pAlgorithm + (long)Marshal.OffsetOf(typeof(CAPI.CRYPT_ALGORITHM_IDENTIFIER), "Parameters"));

                // Retrieve the pszObjId pointer.
                IntPtr pObjId = Marshal.ReadIntPtr(pAlgorithm);

                // Translate the OID to AlgId value.
                CAPI.CRYPT_OID_INFO pOIDInfo = CAPI.CryptFindOIDInfo(CAPI.CRYPT_OID_INFO_OID_KEY, pObjId, CAPI.CRYPT_PUBKEY_ALG_OID_GROUP_ID);

                // Is this DSS?
                if (pOIDInfo.Algid == CAPI.CALG_DSS_SIGN)
                {
                    bool inheritParameters = false;

                    // This is DSS, so inherit the parameters if necessary.
                    IntPtr pcbData = new IntPtr((long)pParameters + (long)Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "cbData"));
                    IntPtr ppbData = new IntPtr((long)pParameters + (long)Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "pbData"));
                    if (Marshal.ReadInt32(pcbData) == 0)
                    {
                        inheritParameters = true;
                    }
                    else
                    {
                        // Need to inherit if NULL pbData or *pbData is 0x05 (NULL ASN tag).
                        if (Marshal.ReadIntPtr(ppbData) == IntPtr.Zero)
                        {
                            inheritParameters = true;
                        }
                        else
                        {
                            IntPtr pbData = Marshal.ReadIntPtr(ppbData);
                            if ((uint)Marshal.ReadInt32(pbData) == CAPI.ASN_TAG_NULL)
                            {
                                inheritParameters = true;
                            }
                        }
                    }

                    // Do we need to copy inherited DSS parameters?
                    if (inheritParameters)
                    {
                        // Build the chain to force CAPI to propagate the parameters to
                        // CERT_PUBKEY_ALG_PARA_PROP_ID extended property.
                        SafeCertChainHandle pChainContext = SafeCertChainHandle.InvalidHandle;
                        X509Utils.BuildChain(new IntPtr(CAPI.HCCE_CURRENT_USER),
                                             X509Utils.GetCertContext(certificate),
                                             null,
                                             null,
                                             null,
                                             X509RevocationMode.NoCheck,
                                             X509RevocationFlag.ExcludeRoot,
                                             DateTime.Now,
                                             new TimeSpan(0, 0, 0), // default
                                             ref pChainContext);
                        pChainContext.Dispose();

                        // The parameter is inherited in the extended property, but not copied
                        // to CERT_INFO, so we need to do it ourselves.
                        uint cbParameters = 0;

                        if (!CAPI.CAPISafe.CertGetCertificateContextProperty(X509Utils.GetCertContext(certificate),
                                                                             CAPI.CERT_PUBKEY_ALG_PARA_PROP_ID,
                                                                             pbParameters,
                                                                             ref cbParameters))
                        {
                            throw new CryptographicException(Marshal.GetLastWin32Error());
                        }

                        if (cbParameters > 0)
                        {
                            pbParameters = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(cbParameters));
                            if (!CAPI.CAPISafe.CertGetCertificateContextProperty(X509Utils.GetCertContext(certificate),
                                                                                 CAPI.CERT_PUBKEY_ALG_PARA_PROP_ID,
                                                                                 pbParameters,
                                                                                 ref cbParameters))
                            {
                                throw new CryptographicException(Marshal.GetLastWin32Error());
                            }

                            Marshal.WriteInt32(pcbData, (int)cbParameters);
                            Marshal.WriteIntPtr(ppbData, pbParameters.DangerousGetHandle());
                        }
                    }
                }

                // Is this counter signer?
                if (m_parentSignerInfo == null)
                {
                    // Just plain signer.
                    if (!CAPI.CryptMsgControl(m_signedCms.GetCryptMsgHandle(),
                                              0,
                                              CAPI.CMSG_CTRL_VERIFY_SIGNATURE,
                                              pCertContext.pCertInfo))
                    {
                        throw new CryptographicException(Marshal.GetLastWin32Error());
                    }
                }
                else
                {
                    // Counter signer, so need to first find parent signer's index.
                    int index          = -1;
                    int lastWin32Error = 0;

                    // Since we allow the same signer to sign more than once,
                    // we must than try all signatures of the same signer.
                    while (true)
                    {
                        try {
                            // Find index of parent signer.
                            index = PkcsUtils.GetSignerIndex(m_signedCms.GetCryptMsgHandle(), m_parentSignerInfo, index + 1);
                        }
                        catch (CryptographicException) {
                            // Did we ever find a signature of the same signer?
                            if (lastWin32Error == 0)
                            {
                                // No. So we just re-throw, which is most likely CAPI.CRYPT_E_SIGNER_NOT_FOUND.
                                throw;
                            }
                            else
                            {
                                // Yes. Throw previous error, which is most likely CAPI.NTE_BAD_SIGNATURE.
                                throw new CryptographicException(lastWin32Error);
                            }
                        }

                        // Now get the parent encoded singer info.
                        uint cbParentEncodedSignerInfo = 0;
                        SafeLocalAllocHandle pbParentEncodedSignerInfo = SafeLocalAllocHandle.InvalidHandle;

                        PkcsUtils.GetParam(m_signedCms.GetCryptMsgHandle(),
                                           CAPI.CMSG_ENCODED_SIGNER,
                                           (uint)index,
                                           out pbParentEncodedSignerInfo,
                                           out cbParentEncodedSignerInfo);

                        // Try next signer if we can't get parent of this signer.
                        if (cbParentEncodedSignerInfo == 0)
                        {
                            lastWin32Error = CAPI.CRYPT_E_NO_SIGNER;
                            continue;
                        }

                        fixed(byte *pbEncodedSignerInfo = m_encodedSignerInfo)
                        {
                            if (!CAPI.CAPISafe.CryptMsgVerifyCountersignatureEncoded(IntPtr.Zero,
                                                                                     CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING,
                                                                                     pbParentEncodedSignerInfo.DangerousGetHandle(),
                                                                                     cbParentEncodedSignerInfo,
                                                                                     new IntPtr(pbEncodedSignerInfo),
                                                                                     (uint)m_encodedSignerInfo.Length,
                                                                                     pCertContext.pCertInfo))
                            {
                                // Cache the error, and try next signer.
                                lastWin32Error = Marshal.GetLastWin32Error();
                                continue;
                            }
                        }

                        // Keep alive.
                        pbParentEncodedSignerInfo.Dispose();

                        // The signature is successfully verified.
                        break;
                    }
                }

                // Verfiy the cert if requested.
                if (!verifySignatureOnly)
                {
                    int hr = VerifyCertificate(certificate, extraStore);
                    if (hr != CAPI.S_OK)
                    {
                        throw new CryptographicException(hr);
                    }
                }

                // Keep alive.
                pbParameters.Dispose();
            }
        }
Ejemplo n.º 5
0
        private unsafe void Verify(X509Certificate2Collection extraStore, X509Certificate2 certificate, bool verifySignatureOnly)
        {
            SafeLocalAllocHandle pvData1 = SafeLocalAllocHandle.InvalidHandle;

            CAPI.CERT_CONTEXT certContext = (CAPI.CERT_CONTEXT)Marshal.PtrToStructure(X509Utils.GetCertContext(certificate).DangerousGetHandle(), typeof(CAPI.CERT_CONTEXT));
            IntPtr            ptr1        = new IntPtr((long)new IntPtr((long)certContext.pCertInfo + (long)Marshal.OffsetOf(typeof(CAPI.CERT_INFO), "SubjectPublicKeyInfo")) + (long)Marshal.OffsetOf(typeof(CAPI.CERT_PUBLIC_KEY_INFO), "Algorithm"));
            IntPtr            num1        = new IntPtr((long)ptr1 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPT_ALGORITHM_IDENTIFIER), "Parameters"));

            if ((int)CAPI.CryptFindOIDInfo(1U, Marshal.ReadIntPtr(ptr1), 3U).Algid == 8704)
            {
                bool   flag = false;
                IntPtr ptr2 = new IntPtr((long)num1 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "cbData"));
                IntPtr ptr3 = new IntPtr((long)num1 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "pbData"));
                if (Marshal.ReadInt32(ptr2) == 0)
                {
                    flag = true;
                }
                else if (Marshal.ReadIntPtr(ptr3) == IntPtr.Zero)
                {
                    flag = true;
                }
                else if (Marshal.ReadInt32(Marshal.ReadIntPtr(ptr3)) == 5)
                {
                    flag = true;
                }
                if (flag)
                {
                    SafeCertChainHandle invalidHandle = SafeCertChainHandle.InvalidHandle;
                    X509Utils.BuildChain(new IntPtr(0L), X509Utils.GetCertContext(certificate), (X509Certificate2Collection)null, (OidCollection)null, (OidCollection)null, X509RevocationMode.NoCheck, X509RevocationFlag.ExcludeRoot, DateTime.Now, new TimeSpan(0, 0, 0), ref invalidHandle);
                    invalidHandle.Dispose();
                    uint pcbData = 0U;
                    if (!CAPI.CAPISafe.CertGetCertificateContextProperty(X509Utils.GetCertContext(certificate), 22U, pvData1, out pcbData))
                    {
                        throw new CryptographicException(Marshal.GetLastWin32Error());
                    }
                    if (pcbData > 0U)
                    {
                        pvData1 = CAPI.LocalAlloc(64U, new IntPtr((long)pcbData));
                        if (!CAPI.CAPISafe.CertGetCertificateContextProperty(X509Utils.GetCertContext(certificate), 22U, pvData1, out pcbData))
                        {
                            throw new CryptographicException(Marshal.GetLastWin32Error());
                        }
                        Marshal.WriteInt32(ptr2, (int)pcbData);
                        Marshal.WriteIntPtr(ptr3, pvData1.DangerousGetHandle());
                    }
                }
            }
            if (this.m_parentSignerInfo == null)
            {
                if (!CAPI.CryptMsgControl(this.m_signedCms.GetCryptMsgHandle(), 0U, 1U, certContext.pCertInfo))
                {
                    throw new CryptographicException(Marshal.GetLastWin32Error());
                }
            }
            else
            {
                int num2 = -1;
                int hr   = 0;
                SafeLocalAllocHandle pvData2;
                while (true)
                {
                    try
                    {
                        num2 = PkcsUtils.GetSignerIndex(this.m_signedCms.GetCryptMsgHandle(), this.m_parentSignerInfo, num2 + 1);
                    }
                    catch (CryptographicException ex)
                    {
                        if (hr != 0)
                        {
                            throw new CryptographicException(hr);
                        }
                        throw;
                    }
                    uint cbData = 0U;
                    pvData2 = SafeLocalAllocHandle.InvalidHandle;
                    PkcsUtils.GetParam(this.m_signedCms.GetCryptMsgHandle(), 28U, (uint)num2, out pvData2, out cbData);
                    if ((int)cbData == 0)
                    {
                        hr = -2146885618;
                    }
                    else
                    {
                        fixed(byte *numPtr = this.m_encodedSignerInfo)
                        {
                            if (!CAPI.CAPISafe.CryptMsgVerifyCountersignatureEncoded(IntPtr.Zero, 65537U, pvData2.DangerousGetHandle(), cbData, new IntPtr((void *)numPtr), (uint)this.m_encodedSignerInfo.Length, certContext.pCertInfo))
                            {
                                hr = Marshal.GetLastWin32Error();
                            }
                            else
                            {
                                break;
                            }
                        }
                    }
                }
                // ISSUE: fixed variable is out of scope
                // ISSUE: __unpin statement
                __unpin(numPtr);
                pvData2.Dispose();
            }
            if (!verifySignatureOnly)
            {
                int hr = SignerInfo.VerifyCertificate(certificate, extraStore);
                if (hr != 0)
                {
                    throw new CryptographicException(hr);
                }
            }
            pvData1.Dispose();
        }
        static SafeCertStoreHandle ExportToMemoryStore(X509Certificate2Collection collection, IntPtr pCertContext)
        {
            CAPI.CERT_CONTEXT certContext = (CAPI.CERT_CONTEXT)Marshal.PtrToStructure(pCertContext, typeof(CAPI.CERT_CONTEXT));

            // No extra store nor intermediate certificates
            if ((collection == null || collection.Count <= 0) && certContext.hCertStore == IntPtr.Zero)
            {
                return(SafeCertStoreHandle.InvalidHandle);
            }

            // we always want to use CERT_STORE_ENUM_ARCHIVED_FLAG since we want to preserve the collection in this operation.
            // By default, Archived certificates will not be included.
            SafeCertStoreHandle certStoreHandle = CAPI.CertOpenStore(
                new IntPtr(CAPI.CERT_STORE_PROV_MEMORY),
                CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING,
                IntPtr.Zero,
                CAPI.CERT_STORE_ENUM_ARCHIVED_FLAG | CAPI.CERT_STORE_CREATE_NEW_FLAG,
                null);

            if (certStoreHandle == null || certStoreHandle.IsInvalid)
            {
                int error = Marshal.GetLastWin32Error();
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException(error));
            }

            //
            // We use CertAddCertificateLinkToStore to keep a link to the original store, so any property changes get
            // applied to the original store. This has a limit of 99 links per cert context however.
            //

            // Add extra store
            if (collection != null && collection.Count > 0)
            {
                foreach (X509Certificate2 x509 in collection)
                {
                    if (!CAPI.CertAddCertificateLinkToStore(certStoreHandle,
                                                            x509.Handle,
                                                            CAPI.CERT_STORE_ADD_ALWAYS,
                                                            SafeCertContextHandle.InvalidHandle))
                    {
                        int error = Marshal.GetLastWin32Error();
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException(error));
                    }
                }
            }

            // Add intermediates
            // The hCertStore needs to be acquired from an X509Certificate2 object
            // constructed using a fresh cert context handle. If we simply refer to the hCertStore
            // property of the certContext local variable directly, there is a risk that we are accessing
            // a closed store. This is because if the X509Certificate2(rawdata) constructor closes the store handle (hCertStore).
            // There is no way to know which constructor was used at this point.
            //
            using (SafeCertContextHandle safeCertContext
                       = CAPI.CertCreateCertificateContext(certContext.dwCertEncodingType,
                                                           certContext.pbCertEncoded,
                                                           certContext.cbCertEncoded))
            {
                //
                // Create an X509Certificate2 using the new cert context that dup's the provided certificate.
                //
                X509Certificate2 intermediatesCert = new X509Certificate2(safeCertContext.DangerousGetHandle());

                //
                // Dereference the handle to this intermediate cert and use it to access the handle
                // of this certificate's cert store. Then, call CAPI.CertAddCertificateLinkToStore
                // on each cert in this store by wrapping this cert store handle with an X509Store
                // object.
                //
                CAPI.CERT_CONTEXT intermediatesCertContext = (CAPI.CERT_CONTEXT)Marshal.PtrToStructure(intermediatesCert.Handle, typeof(CAPI.CERT_CONTEXT));
                if (intermediatesCertContext.hCertStore != IntPtr.Zero)
                {
                    X509Certificate2Collection intermediates = null;
                    X509Store store = new X509Store(intermediatesCertContext.hCertStore);

                    try
                    {
                        intermediates = store.Certificates;
                        foreach (X509Certificate2 x509 in intermediates)
                        {
                            if (!CAPI.CertAddCertificateLinkToStore(certStoreHandle,
                                                                    x509.Handle,
                                                                    CAPI.CERT_STORE_ADD_ALWAYS,
                                                                    SafeCertContextHandle.InvalidHandle))
                            {
                                int error = Marshal.GetLastWin32Error();
                                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException(error));
                            }
                        }
                    }
                    finally
                    {
                        SecurityUtils.ResetAllCertificates(intermediates);
                        store.Close();
                    }
                }
            }

            return(certStoreHandle);
        }
Ejemplo n.º 7
0
        internal static unsafe CAPI.CMSG_SIGNER_ENCODE_INFO CreateSignerEncodeInfo(CmsSigner signer, bool silent)
        {
            CAPI.CMSG_SIGNER_ENCODE_INFO signerEncodeInfo = new CAPI.CMSG_SIGNER_ENCODE_INFO(Marshal.SizeOf(typeof(CAPI.CMSG_SIGNER_ENCODE_INFO)));
            SafeCryptProvHandle          invalidHandle1   = SafeCryptProvHandle.InvalidHandle;
            uint pdwKeySpec       = 0U;
            bool pfCallerFreeProv = false;

            signerEncodeInfo.HashAlgorithm.pszObjId = signer.DigestAlgorithm.Value;
            if (string.Compare(signer.Certificate.PublicKey.Oid.Value, "1.2.840.10040.4.1", StringComparison.Ordinal) == 0)
            {
                signerEncodeInfo.HashEncryptionAlgorithm.pszObjId = "1.2.840.10040.4.3";
            }
            signerEncodeInfo.cAuthAttr    = (uint)signer.SignedAttributes.Count;
            signerEncodeInfo.rgAuthAttr   = PkcsUtils.CreateCryptAttributes(signer.SignedAttributes);
            signerEncodeInfo.cUnauthAttr  = (uint)signer.UnsignedAttributes.Count;
            signerEncodeInfo.rgUnauthAttr = PkcsUtils.CreateCryptAttributes(signer.UnsignedAttributes);
            if (signer.SignerIdentifierType == SubjectIdentifierType.NoSignature)
            {
                signerEncodeInfo.HashEncryptionAlgorithm.pszObjId = "1.3.6.1.5.5.7.6.2";
                signerEncodeInfo.pCertInfo = IntPtr.Zero;
                signerEncodeInfo.dwKeySpec = pdwKeySpec;
                if (!CAPI.CryptAcquireContext(out invalidHandle1, (string)null, (string)null, 1U, 4026531840U))
                {
                    throw new CryptographicException(Marshal.GetLastWin32Error());
                }
                signerEncodeInfo.hCryptProv = invalidHandle1.DangerousGetHandle();
                GC.SuppressFinalize((object)invalidHandle1);
                signerEncodeInfo.SignerId.dwIdChoice = 1U;
                X500DistinguishedName distinguishedName = new X500DistinguishedName("CN=Dummy Signer");
                distinguishedName.Oid = new Oid("1.3.6.1.4.1.311.21.9");
                signerEncodeInfo.SignerId.Value.IssuerSerialNumber.Issuer.cbData = (uint)distinguishedName.RawData.Length;
                SafeLocalAllocHandle localAllocHandle1 = CAPI.LocalAlloc(64U, new IntPtr((long)signerEncodeInfo.SignerId.Value.IssuerSerialNumber.Issuer.cbData));
                Marshal.Copy(distinguishedName.RawData, 0, localAllocHandle1.DangerousGetHandle(), distinguishedName.RawData.Length);
                signerEncodeInfo.SignerId.Value.IssuerSerialNumber.Issuer.pbData = localAllocHandle1.DangerousGetHandle();
                GC.SuppressFinalize((object)localAllocHandle1);
                signerEncodeInfo.SignerId.Value.IssuerSerialNumber.SerialNumber.cbData = 1U;
                SafeLocalAllocHandle localAllocHandle2 = CAPI.LocalAlloc(64U, new IntPtr((long)signerEncodeInfo.SignerId.Value.IssuerSerialNumber.SerialNumber.cbData));
                *(sbyte *)(void *)localAllocHandle2.DangerousGetHandle() = (sbyte)0;
                signerEncodeInfo.SignerId.Value.IssuerSerialNumber.SerialNumber.pbData = localAllocHandle2.DangerousGetHandle();
                GC.SuppressFinalize((object)localAllocHandle2);
                return(signerEncodeInfo);
            }
            else
            {
                System.Security.Cryptography.SafeCertContextHandle certContext1 = X509Utils.GetCertContext(signer.Certificate);
                if (!CAPI.CAPISafe.CryptAcquireCertificatePrivateKey(certContext1, silent ? 70U : 6U, IntPtr.Zero, out invalidHandle1, out pdwKeySpec, out pfCallerFreeProv))
                {
                    throw new CryptographicException(Marshal.GetLastWin32Error());
                }
                signerEncodeInfo.dwKeySpec  = pdwKeySpec;
                signerEncodeInfo.hCryptProv = invalidHandle1.DangerousGetHandle();
                GC.SuppressFinalize((object)invalidHandle1);
                CAPI.CERT_CONTEXT certContext2 = *(CAPI.CERT_CONTEXT *)(void *) certContext1.DangerousGetHandle();
                signerEncodeInfo.pCertInfo = certContext2.pCertInfo;
                if (signer.SignerIdentifierType == SubjectIdentifierType.SubjectKeyIdentifier)
                {
                    uint pcbData = 0U;
                    SafeLocalAllocHandle invalidHandle2 = SafeLocalAllocHandle.InvalidHandle;
                    if (!CAPI.CAPISafe.CertGetCertificateContextProperty(certContext1, 20U, invalidHandle2, out pcbData))
                    {
                        throw new CryptographicException(Marshal.GetLastWin32Error());
                    }
                    if (pcbData > 0U)
                    {
                        SafeLocalAllocHandle pvData = CAPI.LocalAlloc(64U, new IntPtr((long)pcbData));
                        if (!CAPI.CAPISafe.CertGetCertificateContextProperty(certContext1, 20U, pvData, out pcbData))
                        {
                            throw new CryptographicException(Marshal.GetLastWin32Error());
                        }
                        signerEncodeInfo.SignerId.dwIdChoice         = 2U;
                        signerEncodeInfo.SignerId.Value.KeyId.cbData = pcbData;
                        signerEncodeInfo.SignerId.Value.KeyId.pbData = pvData.DangerousGetHandle();
                        GC.SuppressFinalize((object)pvData);
                    }
                }
                return(signerEncodeInfo);
            }
        }