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();
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); } }
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); } }