Exemple #1
0
        public void ComputeCounterSignature(CmsSigner signer)
        {
            if (_parentSignerInfo != null)
            {
                throw new CryptographicException(SR.Cryptography_Cms_NoCounterCounterSigner);
            }
            if (signer == null)
            {
                throw new ArgumentNullException(nameof(signer));
            }

            signer.CheckCertificateValue();

            int myIdx = _document.SignerInfos.FindIndexForSigner(this);

            if (myIdx < 0)
            {
                throw new CryptographicException(SR.Cryptography_Cms_SignerNotFound);
            }

            // Make sure that we're using the most up-to-date version of this that we can.
            SignerInfo effectiveThis = _document.SignerInfos[myIdx];
            X509Certificate2Collection chain;
            SignerInfoAsn newSignerInfo = signer.Sign(effectiveThis._signature, null, false, out chain);

            AttributeAsn newUnsignedAttr;

            using (AsnWriter writer = new AsnWriter(AsnEncodingRules.DER))
            {
                writer.PushSetOf();
                AsnSerializer.Serialize(newSignerInfo, writer);
                writer.PopSetOf();

                newUnsignedAttr = new AttributeAsn
                {
                    AttrType   = new Oid(Oids.CounterSigner, Oids.CounterSigner),
                    AttrValues = writer.Encode(),
                };
            }

            ref SignedDataAsn signedData = ref _document.GetRawData();
Exemple #2
0
        public void ComputeSignature(CmsSigner signer, bool silent)
        {
            if (signer == null)
            {
                throw new ArgumentNullException(nameof(signer));
            }

            // While it shouldn't be possible to change the length of ContentInfo.Content
            // after it's built, use the property at this stage, then use the saved value
            // (if applicable) after this point.
            if (ContentInfo.Content.Length == 0)
            {
                throw new CryptographicException(SR.Cryptography_Cms_Sign_Empty_Content);
            }

            if (_hasData && signer.SignerIdentifierType == SubjectIdentifierType.NoSignature)
            {
                // Even if all signers have been removed, throw if doing a NoSignature signature
                // on a loaded (from file, or from first signature) document.
                //
                // This matches the .NET Framework behavior.
                throw new CryptographicException(SR.Cryptography_Cms_Sign_No_Signature_First_Signer);
            }

            if (signer.Certificate == null && signer.SignerIdentifierType != SubjectIdentifierType.NoSignature)
            {
                if (silent)
                {
                    // .NET Framework compatibility, silent disallows prompting, so throws InvalidOperationException
                    // in this state.
                    //
                    // The message is different than on NetFX, because the resource string was for
                    // enveloped CMS recipients (and the other site which would use that resource
                    // is unreachable code due to CmsRecipient's ctor guarding against null certificates)
                    throw new InvalidOperationException(SR.Cryptography_Cms_NoSignerCertSilent);
                }

                // Otherwise, PNSE. .NET Core doesn't support launching the cert picker UI.
                throw new PlatformNotSupportedException(SR.Cryptography_Cms_NoSignerCert);
            }

            // If we had content already, use that now.
            // (The second signer doesn't inherit edits to signedCms.ContentInfo.Content)
            ReadOnlyMemory <byte> content = _heldContent ?? ContentInfo.Content;
            string contentType            = _contentType ?? ContentInfo.ContentType.Value ?? Oids.Pkcs7Data;

            X509Certificate2Collection chainCerts;
            SignerInfoAsn newSigner   = signer.Sign(content, contentType, silent, out chainCerts);
            bool          firstSigner = false;

            if (!_hasData)
            {
                firstSigner = true;

                _signedData = new SignedDataAsn
                {
                    DigestAlgorithms = Array.Empty <AlgorithmIdentifierAsn>(),
                    SignerInfos      = Array.Empty <SignerInfoAsn>(),
                    EncapContentInfo = new EncapsulatedContentInfoAsn {
                        ContentType = contentType
                    },
                };

                // Since we're going to call Decode before this method exits we don't need to save
                // the copy of _heldContent or _contentType here if we're attached.
                if (!Detached)
                {
                    using (AsnWriter writer = new AsnWriter(AsnEncodingRules.DER))
                    {
                        writer.WriteOctetString(content.Span);

                        _signedData.EncapContentInfo.Content = writer.Encode();
                    }
                }

                _hasData = true;
            }

            int newIdx = _signedData.SignerInfos.Length;

            Array.Resize(ref _signedData.SignerInfos, newIdx + 1);
            _signedData.SignerInfos[newIdx] = newSigner;
            UpdateCertificatesFromAddition(chainCerts);
            ConsiderDigestAddition(newSigner.DigestAlgorithm);
            UpdateMetadata();

            if (firstSigner)
            {
                Reencode();

                Debug.Assert(_heldContent != null);
                Debug.Assert(_contentType == contentType);
            }
        }
Exemple #3
0
        public void ComputeSignature(CmsSigner signer, bool silent)
        {
            if (signer == null)
            {
                throw new ArgumentNullException(nameof(signer));
            }

            // While it shouldn't be possible to change the length of ContentInfo.Content
            // after it's built, use the property at this stage, then use the saved value
            // (if applicable) after this point.
            if (ContentInfo.Content.Length == 0)
            {
                throw new CryptographicException(SR.Cryptography_Cms_Sign_Empty_Content);
            }

            // If we had content already, use that now.
            // (The second signer doesn't inherit edits to signedCms.ContentInfo.Content)
            ReadOnlyMemory <byte> content = _heldContent ?? ContentInfo.Content;
            string contentType            = _contentType ?? ContentInfo.ContentType.Value ?? Oids.Pkcs7Data;

            X509Certificate2Collection chainCerts;
            SignerInfoAsn newSigner   = signer.Sign(content, contentType, silent, out chainCerts);
            bool          firstSigner = false;

            if (!_hasData)
            {
                firstSigner = true;

                _signedData = new SignedDataAsn
                {
                    DigestAlgorithms = Array.Empty <AlgorithmIdentifierAsn>(),
                    SignerInfos      = Array.Empty <SignerInfoAsn>(),
                    EncapContentInfo = new EncapsulatedContentInfoAsn {
                        ContentType = contentType
                    },
                };

                // Since we're going to call Decode before this method exits we don't need to save
                // the copy of _heldContent or _contentType here if we're attached.
                if (!Detached)
                {
                    using (AsnWriter writer = new AsnWriter(AsnEncodingRules.DER))
                    {
                        writer.WriteOctetString(content.Span);

                        _signedData.EncapContentInfo.Content = writer.Encode();
                    }
                }

                _hasData = true;
            }

            int newIdx = _signedData.SignerInfos.Length;

            Array.Resize(ref _signedData.SignerInfos, newIdx + 1);
            _signedData.SignerInfos[newIdx] = newSigner;
            UpdateCertificatesFromAddition(chainCerts);
            ConsiderDigestAddition(newSigner.DigestAlgorithm);
            UpdateMetadata();

            if (firstSigner)
            {
                Reencode();

                Debug.Assert(_heldContent != null);
                Debug.Assert(_contentType == contentType);
            }
        }