Example #1
0
        private unsafe void CounterSign(CmsSigner signer)
        {
            // Sanity check.
            Debug.Assert(signer != null);

            //


            CspParameters parameters = new CspParameters();

            if (X509Utils.GetPrivateKeyInfo(X509Utils.GetCertContext(signer.Certificate), ref parameters) == false)
            {
                throw new CryptographicException(Marshal.GetLastWin32Error());
            }

            KeyContainerPermission            kp    = new KeyContainerPermission(KeyContainerPermissionFlags.NoFlags);
            KeyContainerPermissionAccessEntry entry = new KeyContainerPermissionAccessEntry(parameters, KeyContainerPermissionFlags.Open | KeyContainerPermissionFlags.Sign);

            kp.AccessEntries.Add(entry);
            kp.Demand();

            // Get the signer's index.
            uint index = (uint)PkcsUtils.GetSignerIndex(m_signedCms.GetCryptMsgHandle(), this, 0);

            // Create CMSG_SIGNER_ENCODE_INFO structure.
            SafeLocalAllocHandle pSignerEncodeInfo = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(Marshal.SizeOf(typeof(CAPI.CMSG_SIGNER_ENCODE_INFO))));

            CAPI.CMSG_SIGNER_ENCODE_INFO signerEncodeInfo = PkcsUtils.CreateSignerEncodeInfo(signer);

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

                // Counter sign.
                if (!CAPI.CryptMsgCountersign(m_signedCms.GetCryptMsgHandle(),
                                              index,
                                              1,
                                              pSignerEncodeInfo.DangerousGetHandle()))
                {
                    throw new CryptographicException(Marshal.GetLastWin32Error());
                }

                // CAPI requires that the messge be re-encoded if any unauthenticated
                // attribute has been added. So, let's re-open it to decode to work
                // around this limitation.
                m_signedCms.ReopenToDecode();
            }
            finally {
                Marshal.DestroyStructure(pSignerEncodeInfo.DangerousGetHandle(), typeof(CAPI.CMSG_SIGNER_ENCODE_INFO));
                pSignerEncodeInfo.Dispose();

                // and don't forget to dispose of resources allocated for the structure.
                signerEncodeInfo.Dispose();
            }

            // Finally, add certs to bag of certs.
            PkcsUtils.AddCertsToMessage(m_signedCms.GetCryptMsgHandle(), m_signedCms.Certificates, PkcsUtils.CreateBagOfCertificates(signer));

            return;
        }
Example #2
0
        public void ComputeSignature(CmsSigner signer, bool silent)
        {
            if (signer == null)
            {
                throw new ArgumentNullException("signer");
            }
            if (ContentInfo.Content.Length == 0)
            {
                throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Sign_Empty_Content"));
            }

            if (SubjectIdentifierType.NoSignature == signer.SignerIdentifierType)
            {
                if (m_safeCryptMsgHandle != null && !m_safeCryptMsgHandle.IsInvalid)
                {
                    throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Sign_No_Signature_First_Signer"));
                }

                // First signer.
                Sign(signer, silent);
                return;
            }

            if (signer.Certificate == null)
            {
                if (silent)
                {
                    throw new InvalidOperationException(SecurityResources.GetResourceString("Cryptography_Cms_RecipientCertificateNotFound"));
                }
                else
                {
                    signer.Certificate = PkcsUtils.SelectSignerCertificate();
                }
            }

            if (!signer.Certificate.HasPrivateKey)
            {
                throw new CryptographicException(CAPI.NTE_NO_KEY);
            }

            //



            CspParameters parameters = new CspParameters();

            if (X509Utils.GetPrivateKeyInfo(X509Utils.GetCertContext(signer.Certificate), ref parameters))
            {
                KeyContainerPermission            kp    = new KeyContainerPermission(KeyContainerPermissionFlags.NoFlags);
                KeyContainerPermissionAccessEntry entry = new KeyContainerPermissionAccessEntry(parameters, KeyContainerPermissionFlags.Open | KeyContainerPermissionFlags.Sign);
                kp.AccessEntries.Add(entry);
                kp.Demand();
            }

            if (m_safeCryptMsgHandle == null || m_safeCryptMsgHandle.IsInvalid)
            {
                // First signer.
                Sign(signer, silent);
            }
            else
            {
                // Co-signing.
                CoSign(signer, silent);
            }
        }