/// <summary> /// Method that performs the signing process /// </summary> /// <param name="input"></param> /// <param name="parameters"></param> /// <param name="signedData"></param> /// <returns></returns> private SignatureDocument ComputeSignature(CmsProcessableByteArray content, SignatureParameters parameters, CmsSignedData signedData) { byte[] toBeSigned = ToBeSigned(content, parameters, signedData, false); byte[] signature = parameters.Signer.SignData(toBeSigned, parameters.DigestMethod); PreComputedSigner preComputedSigner = new PreComputedSigner(signature); CustomCMSSignedDataGenerator generator = CreateSignedGenerator(preComputedSigner, parameters, signedData); CmsSignedData newSignedData = null; if (parameters.SignaturePackaging == SignaturePackaging.ATTACHED_IMPLICIT && parameters.PreCalculatedDigest == null) { newSignedData = generator.Generate(content, true); } else { if (parameters.PreCalculatedDigest != null) { generator.PreCalculatedDigest = parameters.PreCalculatedDigest; newSignedData = generator.Generate(null, false); } else if (content != null) { newSignedData = generator.Generate(content, false); } else { generator.PreCalculatedDigest = GetDigestValue(signedData.GetSignerInfos(), parameters.DigestMethod); newSignedData = generator.Generate(null, false); } } return(new SignatureDocument(new CmsSignedData(newSignedData.GetEncoded()))); }
/// <summary> /// Método para crear el generador de firmas /// </summary> /// <param name="signerProvider"></param> /// <param name="parameters"></param> /// <param name="originalSignedData"></param> /// <returns></returns> private CustomCMSSignedDataGenerator CreateSignedGenerator(ISigner signerProvider, SignatureParameters parameters, CmsSignedData originalSignedData) { X509CertificateParser parser = new X509CertificateParser(); var signerCertificate = parser.ReadCertificate(parameters.Certificate.GetRawCertData()); CustomCMSSignedDataGenerator generator = new CustomCMSSignedDataGenerator(); Dictionary <DerObjectIdentifier, Asn1Encodable> signedAttrDic = GetSignedAttributes(parameters); if (!signedAttrDic.ContainsKey(PkcsObjectIdentifiers.IdAAContentHint) && originalSignedData != null) { var attrContentHint = GetContentHintAttribute(originalSignedData.GetSignerInfos()); if (attrContentHint != null) { signedAttrDic.Add(PkcsObjectIdentifiers.IdAAContentHint, attrContentHint); } } CmsAttributeTableGenerator signedAttrGen = new DefaultSignedAttributeTableGenerator (new Org.BouncyCastle.Asn1.Cms.AttributeTable(signedAttrDic)); generator.SignerProvider = signerProvider; generator.AddSigner(new NullPrivateKey(), signerCertificate, PkcsObjectIdentifiers.RsaEncryption.Id, parameters.DigestMethod.Oid, signedAttrGen, null); if (originalSignedData != null) { generator.AddSigners(originalSignedData.GetSignerInfos()); } bool addSignerCert = true; if (originalSignedData != null) { IX509Store originalCertStore = originalSignedData.GetCertificates("Collection"); generator.AddCertificates(originalCertStore); addSignerCert = !CheckCertExists(signerCertificate, originalCertStore); } if (addSignerCert) { List <X509Certificate> certs = new List <X509Certificate>(); certs.Add(signerCertificate); IX509Store certStore = X509StoreFactory.Create("Certificate/Collection", new X509CollectionStoreParameters(certs)); generator.AddCertificates(certStore); } return(generator); }
/// <summary> /// Realiza la contrafirma de una firma CAdES existente /// </summary> /// <param name="sigDocument"></param> /// <param name="signerInfoNode"></param> /// <param name="parameters"></param> /// <returns></returns> public SignatureDocument CounterSign(SignatureDocument sigDocument, SignerInfoNode signerInfoNode, SignatureParameters parameters) { if (sigDocument == null) { throw new Exception("Se necesita una firma previa para poder realizar la cofirma"); } if (signerInfoNode == null) { throw new Exception("Se necesita especificar el nodo de firma para aplicar la contrafirma"); } CheckParameters(parameters); byte[] signature = null; using (MemoryStream ms = new MemoryStream(signerInfoNode.SignerInformation.GetSignature())) { byte[] toBeSigned = ToBeSigned(new CmsProcessableInputStream(ms), parameters, null, true); signature = parameters.Signer.SignData(toBeSigned, parameters.DigestMethod); } CustomCMSSignedDataGenerator generator = CreateSignedGenerator(new PreComputedSigner(signature), parameters, null); var result = generator.GenerateCounterSigners(signerInfoNode.SignerInformation); SignerInformation updatedSI = SignerInformation.AddCounterSigners(signerInfoNode.SignerInformation, result); List <X509Certificate> certs = new List <X509Certificate>(); IX509Store originalCertStore = sigDocument.SignedData.GetCertificates("Collection"); signerInfoNode.SignerInformation = updatedSI; CollectionUtilities.AddRange(certs, GetCertificatesFromStore(originalCertStore)); X509CertificateParser parser = new X509CertificateParser(); var signerCertificate = parser.ReadCertificate(parameters.Certificate.GetRawCertData()); if (!CheckCertExists(signerCertificate, originalCertStore)) { certs.Add(signerCertificate); } IX509Store certStore = X509StoreFactory.Create("Certificate/Collection", new X509CollectionStoreParameters(certs)); CmsSignedData newSignedData = CmsSignedData.ReplaceCertificatesAndCrls(sigDocument.SignedData, certStore, sigDocument.SignedData.GetCrls("Collection"), null); return(new SignatureDocument(newSignedData)); }
/// <summary> /// Devuelve los datos finales que deberán ser firmados /// </summary> /// <param name="content"></param> /// <param name="parameters"></param> /// <param name="signedData"></param> /// <param name="isCounterSignature"></param> /// <returns></returns> private byte[] ToBeSigned(CmsProcessable content, SignatureParameters parameters, CmsSignedData signedData, bool isCounterSignature) { PreComputedSigner preComputedSigner = new PreComputedSigner(); CustomCMSSignedDataGenerator generator = CreateSignedGenerator(preComputedSigner, parameters, signedData); if (parameters.PreCalculatedDigest != null) { generator.PreCalculatedDigest = parameters.PreCalculatedDigest; } else if (content == null) { // Si el contenido es nulo se intenta buscar el valor de la huella del contenido en las otras firmas generator.PreCalculatedDigest = GetDigestValue(signedData.GetSignerInfos(), parameters.DigestMethod); if (generator.PreCalculatedDigest == null) { throw new Exception("No se ha podido obtener la huella del contenido"); } } generator.PreGenerate(!isCounterSignature ? CmsObjectIdentifiers.Data.Id : null, content); return(preComputedSigner.CurrentSignature()); }
/// <summary> /// Returns the final data that must be signed /// </summary> /// <param name="content"></param> /// <param name="parameters"></param> /// <param name="signedData"></param> /// <param name="isCounterSignature"></param> /// <returns></returns> private byte[] ToBeSigned(CmsProcessable content, SignatureParameters parameters, CmsSignedData signedData, bool isCounterSignature) { PreComputedSigner preComputedSigner = new PreComputedSigner(); CustomCMSSignedDataGenerator generator = CreateSignedGenerator(preComputedSigner, parameters, signedData); if (parameters.PreCalculatedDigest != null) { generator.PreCalculatedDigest = parameters.PreCalculatedDigest; } else if (content == null) { // If the content is null, try to find the value of the content footprint in the other firms generator.PreCalculatedDigest = GetDigestValue(signedData.GetSignerInfos(), parameters.DigestMethod); if (generator.PreCalculatedDigest == null) { throw new Exception("Could not get the footprint of the content"); } } generator.PreGenerate(!isCounterSignature ? CmsObjectIdentifiers.Data.Id : null, content); return(preComputedSigner.CurrentSignature()); }