예제 #1
0
        /// <summary>
        /// Carga el documento XML especificado y establece para firmar el elemento especificado en elementId
        /// </summary>
        /// <param name="xmlDocument"></param>
        /// <param name="elementId"></param>
        /// <param name="mimeType"></param>
        public void SetContentInternallyDetached(XmlDocument xmlDocument, string elementId, string mimeType)
        {
            _document = (XmlDocument)xmlDocument.Clone();
            _document.PreserveWhitespace = true;

            Reference reference = new Reference();

            reference.Uri = "#" + elementId;
            reference.Id = "Reference-" + Guid.NewGuid().ToString();

            _objectReference = reference.Id;
            _mimeType = mimeType;

            if (mimeType == "text/xml")
            {
                XmlDsigC14NTransform transform = new XmlDsigC14NTransform();
                reference.AddTransform(transform);
            }
            else
            {
                XmlDsigBase64Transform transform = new XmlDsigBase64Transform();
                reference.AddTransform(transform);
            }

            _xadesSignedXml = new XadesSignedXml(_document);

            _xadesSignedXml.AddReference(reference);
        }
예제 #2
0
        /// <summary>
        /// Inserta un documento para generar una firma internally detached.
        /// </summary>
        /// <param name="content"></param>
        /// <param name="mimeType"></param>
        public void SetContentInternallyDetached(byte[] content, string mimeType, string fileName = null)
        {
            _document = new XmlDocument();

            XmlElement rootElement = _document.CreateElement("DOCFIRMA");
            _document.AppendChild(rootElement);

            string id = "CONTENT-" + Guid.NewGuid().ToString();

            Reference reference = new Reference();

            reference.Uri = "#" + id;
            reference.Id = "Reference-" + Guid.NewGuid().ToString();

            _objectReference = reference.Id;
            _mimeType = mimeType;

            XmlElement contentElement = _document.CreateElement("CONTENT");

            if (mimeType == "text/xml")
            {
                XmlDocument doc = new XmlDocument();
                doc.PreserveWhitespace = true;
                doc.Load(new MemoryStream(content));

                contentElement.InnerXml = doc.DocumentElement.OuterXml;

                XmlDsigC14NTransform transform = new XmlDsigC14NTransform();
                reference.AddTransform(transform);
            }
            else if (mimeType == "hash/sha256")
            {
                contentElement.SetAttribute("Encoding", "http://www.w3.org/2000/09/xmldsig#base64");
                contentElement.SetAttribute("MimeType", mimeType);

                if (!string.IsNullOrEmpty(fileName))
                {
                    contentElement.SetAttribute("URI", Path.GetFileName(fileName));
                }

                using (SHA256 sha2 = SHA256.Create())
                {
                    contentElement.InnerText = Convert.ToBase64String(sha2.ComputeHash(content));
                }

                XmlDsigBase64Transform transform = new XmlDsigBase64Transform();
                reference.AddTransform(transform);
            }
            else
            {
                contentElement.SetAttribute("Encoding", "http://www.w3.org/2000/09/xmldsig#base64");
                contentElement.InnerText = Convert.ToBase64String(content);

                XmlDsigBase64Transform transform = new XmlDsigBase64Transform();
                reference.AddTransform(transform);
            }

            contentElement.SetAttribute("Id", id);

            rootElement.AppendChild(contentElement);

            _xadesSignedXml = new XadesSignedXml(_document);

            _xadesSignedXml.AddReference(reference);
        }
예제 #3
0
        /// <summary>
        /// Inserta un contenido XML para generar una firma enveloping.
        /// </summary>
        /// <param name="xmlDocument"></param>
        public void SetContentEveloping(XmlDocument xmlDocument)
        {
            Reference reference = new Reference();

            _xadesSignedXml = new XadesSignedXml();

            XmlDocument doc = (XmlDocument)xmlDocument.Clone();
            doc.PreserveWhitespace = true;

            if (doc.ChildNodes[0].NodeType == XmlNodeType.XmlDeclaration)
            {
                doc.RemoveChild(doc.ChildNodes[0]);
            }

            //Add an object
            string dataObjectId = "DataObject-" + Guid.NewGuid().ToString();
            System.Security.Cryptography.Xml.DataObject dataObject = new System.Security.Cryptography.Xml.DataObject();
            dataObject.Data = doc.ChildNodes;
            dataObject.Id = dataObjectId;
            _xadesSignedXml.AddObject(dataObject);

            reference.Id = "Reference-" + Guid.NewGuid().ToString();
            reference.Uri = "#" + dataObjectId;
            reference.Type = SignedXml.XmlDsigNamespaceUrl + "Object";

            XmlDsigC14NTransform transform = new XmlDsigC14NTransform();
            reference.AddTransform(transform);

            _objectReference = reference.Id;
            _mimeType = "text/xml";

            _xadesSignedXml.AddReference(reference);

            _document = null;
        }
예제 #4
0
        /// <summary>
        /// Inserta un documento para generar una firma externally detached.
        /// </summary>
        /// <param name="fileName"></param>
        public void SetContentExternallyDetached(string fileName)
        {
            Reference reference = new Reference();

            _document = new XmlDocument();
            _xadesSignedXml = new XadesSignedXml();

            reference.Uri = "file://" + fileName.Replace("\\", "/");
            reference.Id = "Reference-" + Guid.NewGuid().ToString();

            if (reference.Uri.EndsWith(".xml") || reference.Uri.EndsWith(".XML"))
            {
                _mimeType = "text/xml";
                reference.AddTransform(new XmlDsigC14NTransform());
            }

            _objectReference = reference.Id;

            _xadesSignedXml.AddReference(reference);
        }
예제 #5
0
        /// <summary>
        /// Realiza la contrafirma de la firma actual
        /// </summary>
        /// <param name="certificate"></param>
        /// <param name="signMethod"></param>
        public void CounterSign(X509Certificate2 certificate, SignMethod? signMethod = null)
        {
            SetSignatureId();

            if (_xadesSignedXml == null)
            {
                throw new Exception("No hay ninguna firma XADES cargada previamente.");
            }

            if (certificate == null)
            {
                throw new Exception("Es necesario un certificado válido para la firma.");
            }

            if (signMethod.HasValue)
            {
                this.SignMethod = signMethod.Value;
            }

            _signCertificate = certificate;

            XadesSignedXml counterSignature = new XadesSignedXml(_document);

            SetCryptoServiceProvider();

            counterSignature.SigningKey = _rsaKey;

            Reference reference = new Reference();
            reference.Uri = "#" + _xadesSignedXml.SignatureValueId;
            reference.Id = "Reference-" + Guid.NewGuid().ToString();
            reference.Type = "http://uri.etsi.org/01903#CountersignedSignature";
            reference.AddTransform(new XmlDsigC14NTransform());
            counterSignature.AddReference(reference);
            _objectReference = reference.Id;

            KeyInfo keyInfo = new KeyInfo();
            keyInfo.Id = "KeyInfoId-" + _signatureId;
            keyInfo.AddClause(new KeyInfoX509Data((X509Certificate)_signCertificate));
            keyInfo.AddClause(new RSAKeyValue((RSA)_rsaKey));
            counterSignature.KeyInfo = keyInfo;

            Reference referenceKeyInfo = new Reference();
            referenceKeyInfo.Id = "ReferenceKeyInfo-" + _signatureId;
            referenceKeyInfo.Uri = "#KeyInfoId-" + _signatureId;
            counterSignature.AddReference(referenceKeyInfo);

            counterSignature.Signature.Id = _signatureId;
            counterSignature.SignatureValueId = _signatureValueId;

            XadesObject counterSignatureXadesObject = new XadesObject();
            counterSignatureXadesObject.Id = "CounterSignatureXadesObject-" + Guid.NewGuid().ToString();
            counterSignatureXadesObject.QualifyingProperties.Target = "#" + _signatureId;
            counterSignatureXadesObject.QualifyingProperties.SignedProperties.Id = "SignedProperties-" + _signatureId;

            AddSignatureProperties(counterSignatureXadesObject.QualifyingProperties.SignedProperties.SignedSignatureProperties,
                counterSignatureXadesObject.QualifyingProperties.SignedProperties.SignedDataObjectProperties,
                counterSignatureXadesObject.QualifyingProperties.UnsignedProperties.UnsignedSignatureProperties,
                "text/xml", _signCertificate);

            counterSignature.AddXadesObject(counterSignatureXadesObject);

            foreach (Reference signReference in counterSignature.SignedInfo.References)
            {
                signReference.DigestMethod = _refsMethodUri;
            }

            counterSignature.AddXadesNamespace = true;
            counterSignature.ComputeSignature();

            UnsignedProperties unsignedProperties = _xadesSignedXml.UnsignedProperties;
            unsignedProperties.UnsignedSignatureProperties.CounterSignatureCollection.Add(counterSignature);
            _xadesSignedXml.UnsignedProperties = unsignedProperties;

            UpdateDocument();

            _xadesSignedXml = new XadesSignedXml(_document);

            XmlNode xmlNode = _document.SelectSingleNode("//*[@Id='" + _signatureId + "']");

            _xadesSignedXml.LoadXml((XmlElement)xmlNode);
        }
예제 #6
0
        /// <summary>
        /// Añade una firma al documento
        /// </summary>
        /// <param name="certificate"></param>
        /// <param name="signMethod"></param>
        public void CoSign(X509Certificate2 certificate, SignMethod? signMethod = null)
        {
            if (_xadesSignedXml == null)
            {
                throw new Exception("No hay ninguna firma XADES creada previamente.");
            }

            if (certificate == null)
            {
                throw new Exception("Es necesario un certificado válido para la firma.");
            }

            Reference refContent = _xadesSignedXml.SignedInfo.References[0] as Reference;

            if (refContent == null)
            {
                throw new Exception("No se ha podido encontrar la referencia del contenido firmado.");
            }

            if (_xadesSignedXml.XadesObject.QualifyingProperties.SignedProperties.SignedDataObjectProperties.DataObjectFormatCollection.Count > 0)
            {
                foreach (DataObjectFormat dof in _xadesSignedXml.XadesObject.QualifyingProperties.SignedProperties.SignedDataObjectProperties.DataObjectFormatCollection)
                {
                    if (dof.ObjectReferenceAttribute == ("#" + refContent.Id))
                    {
                        _mimeType = dof.MimeType;
                        break;
                    }
                }
            }

            var destination = _xadesSignedXml.GetSignatureElement().ParentNode;

            _xadesSignedXml = new XadesSignedXml(_document);

            refContent.Id = "Reference-" + Guid.NewGuid().ToString();
            _xadesSignedXml.AddReference(refContent);

            if (destination.NodeType != XmlNodeType.Document)
            {
                _xadesSignedXml.SignatureNodeDestination = (XmlElement)destination;
            }
            else
            {
                _xadesSignedXml.SignatureNodeDestination = ((XmlDocument)destination).DocumentElement;
            }

            _objectReference = refContent.Id;

            SetSignatureId();

            Sign(certificate, signMethod);
        }
예제 #7
0
        /// <summary>
        /// Construye el documento enveloped
        /// </summary>
        private void CreateEnvelopedDocument()
        {
            Reference reference = new Reference();

            _xadesSignedXml = new XadesSignedXml(_document);

            reference.Id = "Reference-" + Guid.NewGuid().ToString();
            reference.Uri = "";

            for (int i = 0; i < _document.DocumentElement.Attributes.Count; i++)
            {
                if (_document.DocumentElement.Attributes[i].Name.Equals("id", StringComparison.InvariantCultureIgnoreCase))
                {
                    reference.Uri = "#" + _document.DocumentElement.Attributes[i].Value;
                    break;
                }
            }

            XmlDsigEnvelopedSignatureTransform xmlDsigEnvelopedSignatureTransform = new XmlDsigEnvelopedSignatureTransform();
            reference.AddTransform(xmlDsigEnvelopedSignatureTransform);

            _objectReference = reference.Id;

            _xadesSignedXml.AddReference(reference);
        }
예제 #8
0
        private void addCounterSignatureButton_Click(object sender, System.EventArgs e)
        {
            X509Certificate2 certificateForCounterSignature = this.LetUserChooseCertificate();
            if (certificateForCounterSignature != null)
            {
                this.xadesSignedXml.SignatureValueId = this.signatureValueIdTextBox.Text;

                XmlElement parentSignatureXmlElement = this.xadesSignedXml.GetXml();
                XmlDocument parentSignatureXmlDocument = new XmlDocument();
                parentSignatureXmlDocument.AppendChild(parentSignatureXmlDocument.ImportNode(parentSignatureXmlElement, true));

                XadesSignedXml counterSignature = new XadesSignedXml(parentSignatureXmlDocument);
                RSACryptoServiceProvider rsaKey = (RSACryptoServiceProvider) this.Certificate.PrivateKey;
                counterSignature.SigningKey = rsaKey;

                KeyInfo keyInfo = new KeyInfo();
                keyInfo.AddClause(new KeyInfoX509Data((X509Certificate) certificateForCounterSignature));
                keyInfo.AddClause(new RSAKeyValue(rsaKey));
                counterSignature.KeyInfo = keyInfo;

                Cert cert = new Cert();
                cert.IssuerSerial.X509IssuerName = certificateForCounterSignature.IssuerName.Name;
                cert.IssuerSerial.X509SerialNumber = certificateForCounterSignature.SerialNumber;
                cert.CertDigest.DigestMethod.Algorithm = SignedXml.XmlDsigSHA1Url;
                cert.CertDigest.DigestValue = certificateForCounterSignature.GetCertHash();

                counterSignature.Signature.Id = "CounterSignatureId";
                XadesObject counterSignatureXadesObject = new XadesObject();
                counterSignatureXadesObject.Id = "CounterSignatureXadesObjectId";
                counterSignatureXadesObject.QualifyingProperties.Target = "#CounterSignatureId";
                counterSignatureXadesObject.QualifyingProperties.SignedProperties.Id = "CounterSignatureSignedProperiesId";

                Reference newReference = new Reference();
                newReference.Uri = "#" + this.xadesSignedXml.SignatureValueId;
                counterSignature.AddReference(newReference);

                SignedSignatureProperties signedSignatureProperties = counterSignatureXadesObject.QualifyingProperties.SignedProperties.SignedSignatureProperties;
                signedSignatureProperties.SigningCertificate.CertCollection.Add(cert);
                signedSignatureProperties.SigningTime = DateTime.Parse(this.signingTimeTextBox.Text);
                signedSignatureProperties.SignaturePolicyIdentifier.SignaturePolicyImplied = true;
                counterSignature.AddXadesObject(counterSignatureXadesObject);

                counterSignature.ComputeSignature();

                UnsignedProperties unsignedProperties = this.xadesSignedXml.UnsignedProperties;
                unsignedProperties.UnsignedSignatureProperties.CounterSignatureCollection.Add(counterSignature);
                this.xadesSignedXml.UnsignedProperties = unsignedProperties;

                this.ShowSignature();
            }
        }
예제 #9
0
        private static XadesSignedXml CreateFromXmlDocument(XmlDocument envelopedSignatureXmlDocument)
        {
            XmlDsigEnvelopedSignatureTransform xmlDsigEnvelopedSignatureTransform;
            Reference reference;

            reference = new Reference();

            var xadesSignedXml = new XadesSignedXml(envelopedSignatureXmlDocument);

            reference.Uri = "";
            reference.Id = "xml_ref_id";

            //TODO jbonilla - Parameter?
            //reference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";
            reference.DigestMethod = SignedXml.XmlDsigSHA1Url;

            // ETSI TS 103 171 V2.1.1
            // 6.2.4 Transforms within ds:Reference element 
            {
                //XmlDsigC14NTransform xmlDsigC14NTransform = new XmlDsigC14NTransform();
                //reference.AddTransform(xmlDsigC14NTransform);
                xmlDsigEnvelopedSignatureTransform = new XmlDsigEnvelopedSignatureTransform();
                reference.AddTransform(xmlDsigEnvelopedSignatureTransform);

                //jbonilla - Para permitir multifirmas (co-firmas)            
                Dictionary<string, string> namespaces = new Dictionary<string, string>();
                namespaces.Add("ds", "http://www.w3.org/2000/09/xmldsig#");
                var xmlDsigXPathTransform = CreateXPathTransform("not(ancestor-or-self::ds:Signature)", namespaces);
                reference.AddTransform(xmlDsigXPathTransform);
            }
            xadesSignedXml.AddReference(reference);

            // ETSI TS 103 171 V2.1.1
            // 6.2.2 Canonicalization of ds:SignedInfo element            
            xadesSignedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigC14NTransformUrl;//"http://www.w3.org/2001/10/xml-exc-c14n#";

            //xadesSignedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
            xadesSignedXml.SignedInfo.SignatureMethod = SignedXml.XmlDsigRSASHA1Url;

            return xadesSignedXml;
        }