示例#1
0
 private void CoSign(CmsSigner signer, bool silent)
 {
     CAPI.CMSG_SIGNER_ENCODE_INFO signerEncodeInfo = PkcsUtils.CreateSignerEncodeInfo(signer, silent);
     try
     {
         SafeLocalAllocHandle localAllocHandle = CAPI.LocalAlloc(64U, new IntPtr(Marshal.SizeOf(typeof(CAPI.CMSG_SIGNER_ENCODE_INFO))));
         try
         {
             Marshal.StructureToPtr((object)signerEncodeInfo, localAllocHandle.DangerousGetHandle(), false);
             if (!CAPI.CryptMsgControl(this.m_safeCryptMsgHandle, 0U, 6U, localAllocHandle.DangerousGetHandle()))
             {
                 throw new CryptographicException(Marshal.GetLastWin32Error());
             }
         }
         finally
         {
             Marshal.DestroyStructure(localAllocHandle.DangerousGetHandle(), typeof(CAPI.CMSG_SIGNER_ENCODE_INFO));
             localAllocHandle.Dispose();
         }
     }
     finally
     {
         signerEncodeInfo.Dispose();
     }
     int num = (int)PkcsUtils.AddCertsToMessage(this.m_safeCryptMsgHandle, this.Certificates, PkcsUtils.CreateBagOfCertificates(signer));
 }
示例#2
0
        public void RemoveSignature(int index)
        {
            if (m_safeCryptMsgHandle == null || m_safeCryptMsgHandle.IsInvalid)
            {
                throw new InvalidOperationException(SecurityResources.GetResourceString("Cryptography_Cms_MessageNotSigned"));
            }

            unsafe {
                uint dwSigners = 0;
                uint cbCount   = (uint)Marshal.SizeOf(typeof(uint));

                if (!CAPI.CAPISafe.CryptMsgGetParam(m_safeCryptMsgHandle,
                                                    CAPI.CMSG_SIGNER_COUNT_PARAM,
                                                    0,
                                                    new IntPtr(&dwSigners),
                                                    new IntPtr(&cbCount)))
                {
                    throw new CryptographicException(Marshal.GetLastWin32Error());
                }

                if (index < 0 || index >= (int)dwSigners)
                {
                    throw new ArgumentOutOfRangeException("index", SecurityResources.GetResourceString("ArgumentOutOfRange_Index"));
                }

                if (!CAPI.CryptMsgControl(m_safeCryptMsgHandle,
                                          0,
                                          CAPI.CMSG_CTRL_DEL_SIGNER,
                                          new IntPtr(&index)))
                {
                    throw new CryptographicException(Marshal.GetLastWin32Error());
                }
            }
        }
示例#3
0
        private void CoSign(CmsSigner signer, bool silent)
        {
            CAPI.CMSG_SIGNER_ENCODE_INFO signerEncodeInfo = PkcsUtils.CreateSignerEncodeInfo(signer, silent);

            try {
                SafeLocalAllocHandle pSignerEncodeInfo = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(Marshal.SizeOf(typeof(CAPI.CMSG_SIGNER_ENCODE_INFO))));

                try {
                    // Marshal to unmanaged memory.
                    Marshal.StructureToPtr(signerEncodeInfo, pSignerEncodeInfo.DangerousGetHandle(), false);

                    // Add the signature.
                    if (!CAPI.CryptMsgControl(m_safeCryptMsgHandle,
                                              0,
                                              CAPI.CMSG_CTRL_ADD_SIGNER,
                                              pSignerEncodeInfo.DangerousGetHandle()))
                    {
                        throw new CryptographicException(Marshal.GetLastWin32Error());
                    }
                }
                finally {
                    Marshal.DestroyStructure(pSignerEncodeInfo.DangerousGetHandle(), typeof(CAPI.CMSG_SIGNER_ENCODE_INFO));
                    pSignerEncodeInfo.Dispose();
                }
            }
            finally {
                // and don't forget to dispose of resources allocated for the structure.
                signerEncodeInfo.Dispose();
            }

            // Finally, add certs to bag of certs.
            PkcsUtils.AddCertsToMessage(m_safeCryptMsgHandle, Certificates, PkcsUtils.CreateBagOfCertificates(signer));
        }
示例#4
0
 public unsafe void CheckHash()
 {
     if (!CAPI.CryptMsgControl(this.m_signedCms.GetCryptMsgHandle(), 0U, 19U, new IntPtr((void *)&new CAPI.CMSG_CTRL_VERIFY_SIGNATURE_EX_PARA(Marshal.SizeOf(typeof(CAPI.CMSG_CTRL_VERIFY_SIGNATURE_EX_PARA)))
     {
         dwSignerType = 4U,
         dwSignerIndex = (uint)PkcsUtils.GetSignerIndex(this.m_signedCms.GetCryptMsgHandle(), this, 0)
     })))
     {
         throw new CryptographicException(Marshal.GetLastWin32Error());
     }
 }
示例#5
0
        public void CheckHash()
        {
            int cvseSize = Marshal.SizeOf(typeof(CAPI.CMSG_CTRL_VERIFY_SIGNATURE_EX_PARA));

            CAPI.CMSG_CTRL_VERIFY_SIGNATURE_EX_PARA cvse = new CAPI.CMSG_CTRL_VERIFY_SIGNATURE_EX_PARA(cvseSize);
            cvse.dwSignerType  = CAPI.CMSG_VERIFY_SIGNER_NULL;
            cvse.dwSignerIndex = (uint)PkcsUtils.GetSignerIndex(m_signedCms.GetCryptMsgHandle(), this, 0);

            unsafe {
                if (!CAPI.CryptMsgControl(m_signedCms.GetCryptMsgHandle(),
                                          0,
                                          CAPI.CMSG_CTRL_VERIFY_SIGNATURE_EX,
                                          new IntPtr(&cvse)))
                {
                    throw new CryptographicException(Marshal.GetLastWin32Error());
                }
            }
        }
示例#6
0
        public unsafe void RemoveSignature(int index)
        {
            if (this.m_safeCryptMsgHandle == null || this.m_safeCryptMsgHandle.IsInvalid)
            {
                throw new InvalidOperationException(SecurityResources.GetResourceString("Cryptography_Cms_MessageNotSigned"));
            }
            uint num1 = 0U;
            uint num2 = (uint)Marshal.SizeOf(typeof(uint));

            if (!CAPI.CAPISafe.CryptMsgGetParam(this.m_safeCryptMsgHandle, 5U, 0U, new IntPtr((void *)&num1), new IntPtr((void *)&num2)))
            {
                throw new CryptographicException(Marshal.GetLastWin32Error());
            }
            if (index < 0 || index >= (int)num1)
            {
                throw new ArgumentOutOfRangeException("index", SecurityResources.GetResourceString("ArgumentOutOfRange_Index"));
            }
            if (!CAPI.CryptMsgControl(this.m_safeCryptMsgHandle, 0U, 7U, new IntPtr((void *)&index)))
            {
                throw new CryptographicException(Marshal.GetLastWin32Error());
            }
        }
示例#7
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);
        }
示例#8
0
        private unsafe void RemoveCounterSignature(int parentIndex, int childIndex)
        {
            // Just make sure this is non-negative.
            if (parentIndex < 0)
            {
                throw new ArgumentOutOfRangeException("parentIndex");
            }
            if (childIndex < 0)
            {
                throw new ArgumentOutOfRangeException("childIndex");
            }

            uint cbCmsgCmsSignerInfo = 0;
            SafeLocalAllocHandle pbCmsgCmsSignerInfo = SafeLocalAllocHandle.InvalidHandle;

            uint cbCmsgSignerInfo = 0;
            SafeLocalAllocHandle pbCmsgSignerInfo = SafeLocalAllocHandle.InvalidHandle;

            uint               index = 0;
            uint               cAttr = 0;
            IntPtr             pAttr = IntPtr.Zero;
            SafeCryptMsgHandle hMsg  = m_signedCms.GetCryptMsgHandle();

            if (PkcsUtils.CmsSupported())
            {
                PkcsUtils.GetParam(hMsg,
                                   CAPI.CMSG_CMS_SIGNER_INFO_PARAM,
                                   (uint)parentIndex,
                                   out pbCmsgCmsSignerInfo,
                                   out cbCmsgCmsSignerInfo);

                CAPI.CMSG_CMS_SIGNER_INFO cmsgCmsSignerInfo = (CAPI.CMSG_CMS_SIGNER_INFO)Marshal.PtrToStructure(pbCmsgCmsSignerInfo.DangerousGetHandle(), typeof(CAPI.CMSG_CMS_SIGNER_INFO));
                cAttr = cmsgCmsSignerInfo.UnauthAttrs.cAttr;
                pAttr = new IntPtr((long)cmsgCmsSignerInfo.UnauthAttrs.rgAttr);
            }
            else
            {
                PkcsUtils.GetParam(hMsg,
                                   CAPI.CMSG_SIGNER_INFO_PARAM,
                                   (uint)parentIndex,
                                   out pbCmsgSignerInfo,
                                   out cbCmsgSignerInfo);

                CAPI.CMSG_SIGNER_INFO cmsgSignerInfo = (CAPI.CMSG_SIGNER_INFO)Marshal.PtrToStructure(pbCmsgSignerInfo.DangerousGetHandle(), typeof(CAPI.CMSG_SIGNER_INFO));
                cAttr = cmsgSignerInfo.UnauthAttrs.cAttr;
                pAttr = new IntPtr((long)cmsgSignerInfo.UnauthAttrs.rgAttr);
            }

            // Find index for counter signature attribute.
            // Note: It is not guaranteed that CAPI will keep all counter signatures
            // in one single unauthenticated attribute. So we need to find the correct
            // unauthenticated attribute containing this counter signer which is
            // identified by index.
            for (index = 0; index < cAttr; index++)
            {
                checked {
                    CAPI.CRYPT_ATTRIBUTE attr = (CAPI.CRYPT_ATTRIBUTE)Marshal.PtrToStructure(pAttr, typeof(CAPI.CRYPT_ATTRIBUTE));
                    if (String.Compare(attr.pszObjId, CAPI.szOID_RSA_counterSign, StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        if (attr.cValue > 0)
                        {
                            // Is it in this attribute?
                            if (childIndex < (int)attr.cValue)
                            {
                                // Found the desired counter signature attribute. So, first remove the
                                // entire attribute, then remove just the counter signature from the
                                // retrieved attribute, and finally add back the modified attribute,
                                // if necessary.
                                CAPI.CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR_PARA delPara = new CAPI.CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR_PARA(Marshal.SizeOf(typeof(CAPI.CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR_PARA)));
                                delPara.dwSignerIndex     = (uint)parentIndex;
                                delPara.dwUnauthAttrIndex = index;

                                if (!CAPI.CryptMsgControl(hMsg,
                                                          0,
                                                          CAPI.CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR,
                                                          new IntPtr(&delPara)))
                                {
                                    throw new CryptographicException(Marshal.GetLastWin32Error());
                                }

                                // No need to add back if only one counter signature in this attribute.
                                if (attr.cValue > 1)
                                {
                                    try {
                                        // There were more than one counter signatures in this attribute, so
                                        // need to add back a new counter signature attribute which includes
                                        // the remaining counter signatures.
                                        uint cbCounterSignatureValue = (uint)((attr.cValue - 1) * Marshal.SizeOf(typeof(CAPI.CRYPTOAPI_BLOB)));
                                        SafeLocalAllocHandle pbCounterSignatureValue = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(cbCounterSignatureValue));

                                        // Copy everything except the one being removed.
                                        CAPI.CRYPTOAPI_BLOB *pOldValue = (CAPI.CRYPTOAPI_BLOB *)attr.rgValue;
                                        CAPI.CRYPTOAPI_BLOB *pNewValue = (CAPI.CRYPTOAPI_BLOB *)pbCounterSignatureValue.DangerousGetHandle();

                                        for (int i = 0; i < (int)attr.cValue; i++, pOldValue++, pNewValue++)
                                        {
                                            if (i != childIndex)
                                            {
                                                *pNewValue = *pOldValue;
                                            }
                                        }

                                        // Encode the new counter signature attribute.
                                        byte[] encodedNewAttribute;
                                        CAPI.CRYPT_ATTRIBUTE newAttr = new CAPI.CRYPT_ATTRIBUTE();
                                        newAttr.pszObjId = attr.pszObjId;
                                        newAttr.cValue   = attr.cValue - 1;
                                        newAttr.rgValue  = pbCounterSignatureValue.DangerousGetHandle();

                                        SafeLocalAllocHandle pNewAttr = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(Marshal.SizeOf(typeof(CAPI.CRYPT_ATTRIBUTE))));
                                        Marshal.StructureToPtr(newAttr, pNewAttr.DangerousGetHandle(), false);

                                        try {
                                            if (!CAPI.EncodeObject(new IntPtr(CAPI.PKCS_ATTRIBUTE),
                                                                   pNewAttr.DangerousGetHandle(),
                                                                   out encodedNewAttribute))
                                            {
                                                throw new CryptographicException(Marshal.GetLastWin32Error());
                                            }
                                        }
                                        finally {
                                            Marshal.DestroyStructure(pNewAttr.DangerousGetHandle(), typeof(CAPI.CRYPT_ATTRIBUTE));
                                            pNewAttr.Dispose();
                                        }

                                        // Finally, add it back.
                                        fixed(byte *pbData = &encodedNewAttribute[0])
                                        {
                                            CAPI.CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA addPara = new CAPI.CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA(Marshal.SizeOf(typeof(CAPI.CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA)));
                                            addPara.dwSignerIndex = (uint)parentIndex;
                                            addPara.blob.cbData   = (uint)encodedNewAttribute.Length;
                                            addPara.blob.pbData   = new IntPtr(pbData);

                                            if (!CAPI.CryptMsgControl(hMsg,
                                                                      0,
                                                                      CAPI.CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR,
                                                                      new IntPtr(&addPara)))
                                            {
                                                throw new CryptographicException(Marshal.GetLastWin32Error());
                                            }
                                        }

                                        // Keep alive.
                                        pbCounterSignatureValue.Dispose();
                                    }
                                    catch (CryptographicException) {
                                        // Roll back.
                                        byte[] encodedAttribute;
                                        if (CAPI.EncodeObject(new IntPtr(CAPI.PKCS_ATTRIBUTE),
                                                              pAttr,
                                                              out encodedAttribute))
                                        {
                                            fixed(byte *pbData = &encodedAttribute[0])
                                            {
                                                CAPI.CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA addPara = new CAPI.CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA(Marshal.SizeOf(typeof(CAPI.CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA)));
                                                addPara.dwSignerIndex = (uint)parentIndex;
                                                addPara.blob.cbData   = (uint)encodedAttribute.Length;
                                                addPara.blob.pbData   = new IntPtr(pbData);
                                                CAPI.CryptMsgControl(hMsg, 0, CAPI.CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR, new IntPtr(&addPara));
                                            }
                                        }
                                        throw;
                                    }
                                }

                                return;
                            }

                            childIndex -= (int)attr.cValue;
                        }
                    }

                    pAttr = new IntPtr((long)pAttr + (long)Marshal.SizeOf(typeof(CAPI.CRYPT_ATTRIBUTE)));
                }
            }

            // Keep alive.
            if (pbCmsgCmsSignerInfo != null && !pbCmsgCmsSignerInfo.IsInvalid)
            {
                pbCmsgCmsSignerInfo.Dispose();
            }
            if (pbCmsgSignerInfo != null && !pbCmsgSignerInfo.IsInvalid)
            {
                pbCmsgSignerInfo.Dispose();
            }

            throw new CryptographicException(CAPI.CRYPT_E_NO_SIGNER);
        }
示例#9
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();
            }
        }
示例#10
0
        private unsafe void RemoveCounterSignature(int parentIndex, int childIndex)
        {
            if (parentIndex < 0)
            {
                throw new ArgumentOutOfRangeException("parentIndex");
            }
            if (childIndex < 0)
            {
                throw new ArgumentOutOfRangeException("childIndex");
            }
            uint cbData1 = 0U;
            SafeLocalAllocHandle pvData1 = SafeLocalAllocHandle.InvalidHandle;
            uint cbData2 = 0U;
            SafeLocalAllocHandle pvData2      = SafeLocalAllocHandle.InvalidHandle;
            IntPtr             num1           = IntPtr.Zero;
            SafeCryptMsgHandle cryptMsgHandle = this.m_signedCms.GetCryptMsgHandle();
            uint num2;

            if (PkcsUtils.CmsSupported())
            {
                PkcsUtils.GetParam(cryptMsgHandle, 39U, (uint)parentIndex, out pvData1, out cbData1);
                CAPI.CMSG_CMS_SIGNER_INFO cmsgCmsSignerInfo = (CAPI.CMSG_CMS_SIGNER_INFO)Marshal.PtrToStructure(pvData1.DangerousGetHandle(), typeof(CAPI.CMSG_CMS_SIGNER_INFO));
                num2 = cmsgCmsSignerInfo.UnauthAttrs.cAttr;
                num1 = new IntPtr((long)cmsgCmsSignerInfo.UnauthAttrs.rgAttr);
            }
            else
            {
                PkcsUtils.GetParam(cryptMsgHandle, 6U, (uint)parentIndex, out pvData2, out cbData2);
                CAPI.CMSG_SIGNER_INFO cmsgSignerInfo = (CAPI.CMSG_SIGNER_INFO)Marshal.PtrToStructure(pvData2.DangerousGetHandle(), typeof(CAPI.CMSG_SIGNER_INFO));
                num2 = cmsgSignerInfo.UnauthAttrs.cAttr;
                num1 = new IntPtr((long)cmsgSignerInfo.UnauthAttrs.rgAttr);
            }
            for (uint index = 0U; index < num2; ++index)
            {
                CAPI.CRYPT_ATTRIBUTE cryptAttribute1 = (CAPI.CRYPT_ATTRIBUTE)Marshal.PtrToStructure(num1, typeof(CAPI.CRYPT_ATTRIBUTE));
                if (string.Compare(cryptAttribute1.pszObjId, "1.2.840.113549.1.9.6", StringComparison.OrdinalIgnoreCase) == 0 && cryptAttribute1.cValue > 0U)
                {
                    if (childIndex < (int)cryptAttribute1.cValue)
                    {
                        if (!CAPI.CryptMsgControl(cryptMsgHandle, 0U, 9U, new IntPtr((void *)&new CAPI.CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR_PARA(Marshal.SizeOf(typeof(CAPI.CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR_PARA)))
                        {
                            dwSignerIndex = (uint)parentIndex,
                            dwUnauthAttrIndex = index
                        })))
                        {
                            throw new CryptographicException(Marshal.GetLastWin32Error());
                        }
                        if (cryptAttribute1.cValue <= 1U)
                        {
                            return;
                        }
                        try
                        {
                            SafeLocalAllocHandle localAllocHandle1 = CAPI.LocalAlloc(64U, new IntPtr((long)(uint)((ulong)(cryptAttribute1.cValue - 1U) * (ulong)Marshal.SizeOf(typeof(CAPI.CRYPTOAPI_BLOB)))));
                            CAPI.CRYPTOAPI_BLOB *cryptoapiBlobPtr1 = (CAPI.CRYPTOAPI_BLOB *)(void *) cryptAttribute1.rgValue;
                            CAPI.CRYPTOAPI_BLOB *cryptoapiBlobPtr2 = (CAPI.CRYPTOAPI_BLOB *)(void *) localAllocHandle1.DangerousGetHandle();
                            int num3 = 0;
                            while (num3 < (int)cryptAttribute1.cValue)
                            {
                                if (num3 != childIndex)
                                {
                                    *cryptoapiBlobPtr2 = *cryptoapiBlobPtr1;
                                }
                                ++num3;
                                ++cryptoapiBlobPtr1;
                                ++cryptoapiBlobPtr2;
                            }
                            CAPI.CRYPT_ATTRIBUTE cryptAttribute2 = new CAPI.CRYPT_ATTRIBUTE();
                            cryptAttribute2.pszObjId = cryptAttribute1.pszObjId;
                            cryptAttribute2.cValue   = cryptAttribute1.cValue - 1U;
                            cryptAttribute2.rgValue  = localAllocHandle1.DangerousGetHandle();
                            SafeLocalAllocHandle localAllocHandle2 = CAPI.LocalAlloc(64U, new IntPtr(Marshal.SizeOf(typeof(CAPI.CRYPT_ATTRIBUTE))));
                            Marshal.StructureToPtr((object)cryptAttribute2, localAllocHandle2.DangerousGetHandle(), false);
                            byte[] encodedData;
                            try
                            {
                                if (!CAPI.EncodeObject(new IntPtr(22L), localAllocHandle2.DangerousGetHandle(), out encodedData))
                                {
                                    throw new CryptographicException(Marshal.GetLastWin32Error());
                                }
                            }
                            finally
                            {
                                Marshal.DestroyStructure(localAllocHandle2.DangerousGetHandle(), typeof(CAPI.CRYPT_ATTRIBUTE));
                                localAllocHandle2.Dispose();
                            }
                            fixed(byte *numPtr = &encodedData[0])
                            {
                                if (!CAPI.CryptMsgControl(cryptMsgHandle, 0U, 8U, new IntPtr((void *)&new CAPI.CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA(Marshal.SizeOf(typeof(CAPI.CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA)))
                                {
                                    dwSignerIndex = (uint)parentIndex,
                                    blob =
                                    {
                                        cbData = (uint)encodedData.Length,
                                        pbData = new IntPtr((void *)numPtr)
                                    }
                                })))
                                {
                                    throw new CryptographicException(Marshal.GetLastWin32Error());
                                }
                            }
                            localAllocHandle1.Dispose();
                            return;
                        }
                        catch (CryptographicException ex)
                        {
                            byte[] encodedData;
                            if (CAPI.EncodeObject(new IntPtr(22L), num1, out encodedData))
                            {
                                fixed(byte *numPtr = &encodedData[0])
                                CAPI.CryptMsgControl(cryptMsgHandle, 0U, 8U, new IntPtr((void *)&new CAPI.CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA(Marshal.SizeOf(typeof(CAPI.CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA)))
                                {
                                    dwSignerIndex = (uint)parentIndex,
                                    blob          =
                                    {
                                        cbData = (uint)encodedData.Length,
                                        pbData = new IntPtr((void *)numPtr)
                                    }
                                }));
                            }
                            throw;
                        }
                    }
                    else
                    {
                        childIndex -= (int)cryptAttribute1.cValue;
                    }
                }
                num1 = new IntPtr((long)num1 + (long)Marshal.SizeOf(typeof(CAPI.CRYPT_ATTRIBUTE)));
            }
            if (pvData1 != null && !pvData1.IsInvalid)
            {
                pvData1.Dispose();
            }
            if (pvData2 != null && !pvData2.IsInvalid)
            {
                pvData2.Dispose();
            }
            throw new CryptographicException(-2146885618);
        }
示例#11
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();
        }