The UnsignedProperties element contains a number of properties that are not signed by the XMLDSIG signature
        /// <summary>
        /// Load state from an XML element
        /// </summary>
        /// <param name="xmlElement">XML element containing new state</param>
        /// <param name="counterSignedXmlElement">Element containing parent signature (needed if there are counter signatures)</param>
        public void LoadXml(XmlElement xmlElement, XmlElement counterSignedXmlElement)
        {
            XmlNamespaceManager xmlNamespaceManager;
            XmlNodeList         xmlNodeList;

            if (xmlElement == null)
            {
                throw new ArgumentNullException("xmlElement");
            }
            if (xmlElement.HasAttribute("Id"))
            {
                this.id = xmlElement.GetAttribute("Id");
            }
            else
            {
                this.id = "";
            }

            if (xmlElement.HasAttribute("Target"))
            {
                this.target = xmlElement.GetAttribute("Target");
            }
            else
            {
                this.target = "";
                throw new CryptographicException("Target attribute missing");
            }

            xmlNamespaceManager = new XmlNamespaceManager(xmlElement.OwnerDocument.NameTable);
            xmlNamespaceManager.AddNamespace("xsd", XadesSignedXml.XadesNamespaceUri);

            xmlNodeList = xmlElement.SelectNodes("xsd:SignedProperties", xmlNamespaceManager);
            if (xmlNodeList.Count == 0)
            {
                throw new CryptographicException("SignedProperties missing");
            }
            this.signedProperties = new SignedProperties();
            this.signedProperties.LoadXml((XmlElement)xmlNodeList.Item(0));

            xmlNodeList = xmlElement.SelectNodes("xsd:UnsignedProperties", xmlNamespaceManager);
            if (xmlNodeList.Count != 0)
            {
                this.unsignedProperties = new UnsignedProperties();
                this.unsignedProperties.LoadXml((XmlElement)xmlNodeList.Item(0), counterSignedXmlElement);
            }
        }
예제 #2
0
        private X509Certificate2[] ValidateCertificateByOCSP(UnsignedProperties unsignedProperties, X509Certificate2 client, X509Certificate2 issuer)
        {
            bool byKey = false;
            List<string> ocspServers = new List<string>();
            Org.BouncyCastle.X509.X509Certificate clientCert = CertUtil.ConvertToX509Certificate(client);
            Org.BouncyCastle.X509.X509Certificate issuerCert = CertUtil.ConvertToX509Certificate(issuer);

            OcspClient ocsp = new OcspClient();
            string certOcspUrl = ocsp.GetAuthorityInformationAccessOcspUrl(issuerCert);

            if (!string.IsNullOrEmpty(certOcspUrl))
            {
                ocspServers.Add(certOcspUrl);
            }

            foreach (var ocspUrl in _firma.OCSPServers)
            {
                ocspServers.Add(ocspUrl);
            }

            foreach (var ocspUrl in ocspServers)
            {
                byte[] resp = ocsp.QueryBinary(clientCert, issuerCert, ocspUrl);

                FirmaXadesNet.Clients.CertificateStatus status = ocsp.ProcessOcspResponse(clientCert, issuerCert, resp);

                if (status == FirmaXadesNet.Clients.CertificateStatus.Revoked)
                {
                    throw new Exception("Certificado revocado");
                }
                else if (status == FirmaXadesNet.Clients.CertificateStatus.Good)
                {
                    Org.BouncyCastle.Ocsp.OcspResp r = new OcspResp(resp);
                    byte[] rEncoded = r.GetEncoded();
                    BasicOcspResp or = (BasicOcspResp)r.GetResponseObject();

                    string guidOcsp = Guid.NewGuid().ToString();

                    OCSPRef ocspRef = new OCSPRef();
                    ocspRef.OCSPIdentifier.UriAttribute = "#OcspValue" + guidOcsp;
                    DigestUtil.SetCertDigest(rEncoded, _firma.RefsDigestMethod, ocspRef.CertDigest);

                    Org.BouncyCastle.Asn1.Ocsp.ResponderID rpId = or.ResponderId.ToAsn1Object();
                    string name = GetResponderName(rpId, ref byKey);

                    if (!byKey)
                    {
                        ocspRef.OCSPIdentifier.ResponderID = RevertIssuerName(name);
                    }
                    else
                    {
                        ocspRef.OCSPIdentifier.ResponderID = name;
                        ocspRef.OCSPIdentifier.ByKey = true;
                    }

                    ocspRef.OCSPIdentifier.ProducedAt = or.ProducedAt.ToLocalTime();
                    unsignedProperties.UnsignedSignatureProperties.CompleteRevocationRefs.OCSPRefs.OCSPRefCollection.Add(ocspRef);

                    OCSPValue ocspValue = new OCSPValue();
                    ocspValue.PkiData = rEncoded;
                    ocspValue.Id = "OcspValue" + guidOcsp;
                    unsignedProperties.UnsignedSignatureProperties.RevocationValues.OCSPValues.OCSPValueCollection.Add(ocspValue);

                    return (from cert in or.GetCerts()
                            select new X509Certificate2(cert.GetEncoded())).ToArray();
                }
            }

            throw new Exception("El certificado no ha podido ser validado");
        }
예제 #3
0
        private bool ValidateCertificateByCRL(UnsignedProperties unsignedProperties, X509Certificate2 certificate, X509Certificate2 issuer)
        {
            Org.BouncyCastle.X509.X509Certificate clientCert = CertUtil.ConvertToX509Certificate(certificate);
            Org.BouncyCastle.X509.X509Certificate issuerCert = CertUtil.ConvertToX509Certificate(issuer);

            foreach (var crlEntry in _firma.CRLEntries)
            {
                if (crlEntry.IssuerDN.Equivalent(issuerCert.SubjectDN) && crlEntry.NextUpdate.Value > DateTime.Now)
                {
                    if (!crlEntry.IsRevoked(clientCert))
                    {
                        if (!ExistsCRL(unsignedProperties.UnsignedSignatureProperties.CompleteRevocationRefs.CRLRefs.CRLRefCollection,
                            issuer.Subject))
                        {
                            string idCrlValue = "CRLValue-" + Guid.NewGuid().ToString();

                            CRLRef crlRef = new CRLRef();
                            crlRef.CRLIdentifier.UriAttribute = "#" + idCrlValue;
                            crlRef.CRLIdentifier.Issuer = issuer.Subject;
                            crlRef.CRLIdentifier.IssueTime = crlEntry.ThisUpdate.ToLocalTime();

                            var crlNumber = GetCRLNumber(crlEntry);
                            if (crlNumber.HasValue)
                            {
                                crlRef.CRLIdentifier.Number = crlNumber.Value;
                            }

                            byte[] crlEncoded = crlEntry.GetEncoded();
                            DigestUtil.SetCertDigest(crlEncoded, _firma.RefsDigestMethod, crlRef.CertDigest);

                            CRLValue crlValue = new CRLValue();
                            crlValue.PkiData = crlEncoded;
                            crlValue.Id = idCrlValue;

                            unsignedProperties.UnsignedSignatureProperties.CompleteRevocationRefs.CRLRefs.CRLRefCollection.Add(crlRef);
                            unsignedProperties.UnsignedSignatureProperties.RevocationValues.CRLValues.CRLValueCollection.Add(crlValue);
                        }

                        return true;
                    }
                    else
                    {
                        throw new Exception("Certificado revocado");
                    }
                }
            }

            return false;
        }
예제 #4
0
        /// <summary>
        /// Determina si un certificado ya ha sido añadido a la colección de certificados
        /// </summary>
        /// <param name="cert"></param>
        /// <param name="unsignedProperties"></param>
        /// <returns></returns>
        private bool CertificateChecked(X509Certificate2 cert, UnsignedProperties unsignedProperties)
        {
            string certHash = null;

            using (var hashAlg = DigestUtil.GetHashAlg(_firma.RefsDigestMethod))
            {
                certHash = Convert.ToBase64String(hashAlg.ComputeHash(cert.GetRawCertData()));
            }

            foreach (Cert item in unsignedProperties.UnsignedSignatureProperties.CompleteCertificateRefs.CertRefs.CertCollection)
            {
                if (Convert.ToBase64String(item.CertDigest.DigestValue) == certHash)
                {
                    return true;
                }
            }

            return false;
        }
예제 #5
0
        /// <summary>
        /// Inserta y valida los certificados del servidor de sellado de tiempo.
        /// </summary>
        /// <param name="unsignedProperties"></param>
        private void AddTSACertificates(UnsignedProperties unsignedProperties)
        {
            TimeStampToken token = new TimeStampToken(new Org.BouncyCastle.Cms.CmsSignedData(unsignedProperties.UnsignedSignatureProperties.SignatureTimeStampCollection[0].EncapsulatedTimeStamp.PkiData));
            IX509Store store = token.GetCertificates("Collection");

            Org.BouncyCastle.Cms.SignerID signerId = token.SignerID;

            List<X509Certificate2> tsaCerts = new List<X509Certificate2>();
            foreach (var tsaCert in store.GetMatches(null))
            {
                X509Certificate2 cert = new X509Certificate2(((Org.BouncyCastle.X509.X509Certificate)tsaCert).GetEncoded());
                tsaCerts.Add(cert);
            }

            X509Certificate2 startCert = DetermineStartCert(tsaCerts);
            AddCertificate(startCert, unsignedProperties, true, tsaCerts.ToArray());
        }
예제 #6
0
        /// <summary>
        /// Inserta en la lista de certificados el certificado y comprueba la valided del certificado.
        /// </summary>
        /// <param name="cert"></param>
        /// <param name="unsignedProperties"></param>
        /// <param name="addCertValue"></param>
        /// <param name="extraCerts"></param>
        private void AddCertificate(X509Certificate2 cert, UnsignedProperties unsignedProperties, bool addCert, X509Certificate2[] extraCerts = null)
        {
            if (addCert)
            {
                if (CertificateChecked(cert, unsignedProperties))
                {
                    return;
                }

                string guidCert = Guid.NewGuid().ToString();

                Cert chainCert = new Cert();
                chainCert.IssuerSerial.X509IssuerName = cert.IssuerName.Name;
                chainCert.IssuerSerial.X509SerialNumber = CertUtil.HexToDecimal(cert.SerialNumber);
                DigestUtil.SetCertDigest(cert.GetRawCertData(), _firma.RefsDigestMethod, chainCert.CertDigest);
                chainCert.URI = "#Cert" + guidCert;
                unsignedProperties.UnsignedSignatureProperties.CompleteCertificateRefs.CertRefs.CertCollection.Add(chainCert);

                EncapsulatedX509Certificate encapsulatedX509Certificate = new EncapsulatedX509Certificate();
                encapsulatedX509Certificate.Id = "Cert" + guidCert;
                encapsulatedX509Certificate.PkiData = cert.GetRawCertData();
                unsignedProperties.UnsignedSignatureProperties.CertificateValues.EncapsulatedX509CertificateCollection.Add(encapsulatedX509Certificate);
            }

            var chain = CertUtil.GetCertChain(cert, extraCerts).ChainElements;

            if (chain.Count > 1)
            {
                X509ChainElementEnumerator enumerator = chain.GetEnumerator();
                enumerator.MoveNext(); // el mismo certificado que el pasado por parametro

                enumerator.MoveNext();

                bool valid = ValidateCertificateByCRL(unsignedProperties, cert, enumerator.Current.Certificate);

                if (!valid)
                {
                    var ocspCerts = ValidateCertificateByOCSP(unsignedProperties, cert, enumerator.Current.Certificate);

                    if (ocspCerts != null)
                    {
                        X509Certificate2 startOcspCert = DetermineStartCert(new List<X509Certificate2>(ocspCerts));

                        if (startOcspCert.IssuerName.Name != enumerator.Current.Certificate.SubjectName.Name)
                        {
                            var chainOcsp = CertUtil.GetCertChain(startOcspCert, ocspCerts);

                            AddCertificate(chainOcsp.ChainElements[1].Certificate, unsignedProperties, true, ocspCerts);
                        }
                    }
                }

                AddCertificate(enumerator.Current.Certificate, unsignedProperties, true, extraCerts);
            }
        }
 /// <summary>
 /// Default constructor
 /// </summary>
 public QualifyingProperties()
 {
     this.signedProperties   = new SignedProperties();
     this.unsignedProperties = new UnsignedProperties();
 }
예제 #8
0
		/// <summary>
		/// Load state from an XML element
		/// </summary>
		/// <param name="xmlElement">XML element containing new state</param>
		/// <param name="counterSignedXmlElement">Element containing parent signature (needed if there are counter signatures)</param>
		public void LoadXml(XmlElement xmlElement, XmlElement counterSignedXmlElement)
		{
			XmlNamespaceManager xmlNamespaceManager;
			XmlNodeList xmlNodeList;
			
			if (xmlElement == null)
			{
				throw new ArgumentNullException("xmlElement");
			}
			if (xmlElement.HasAttribute("Id"))
			{
				this.id = xmlElement.GetAttribute("Id");
			}
			else
			{
				this.id = "";
			}

			if (xmlElement.HasAttribute("Target"))
			{
				this.target = xmlElement.GetAttribute("Target");
			}
			else
			{
				this.target = "";
				throw new CryptographicException("Target attribute missing");
			}

			xmlNamespaceManager = new XmlNamespaceManager(xmlElement.OwnerDocument.NameTable);
			xmlNamespaceManager.AddNamespace("xsd", XadesSignedXml.XadesNamespaceUri);

			xmlNodeList = xmlElement.SelectNodes("xsd:SignedProperties", xmlNamespaceManager);
			if (xmlNodeList.Count == 0)
			{
				throw new CryptographicException("SignedProperties missing");
			}
			this.signedProperties = new SignedProperties();
			this.signedProperties.LoadXml((XmlElement)xmlNodeList.Item(0));

			xmlNodeList = xmlElement.SelectNodes("xsd:UnsignedProperties", xmlNamespaceManager);
			if (xmlNodeList.Count != 0)
			{
				this.unsignedProperties = new UnsignedProperties();
				this.unsignedProperties.LoadXml((XmlElement)xmlNodeList.Item(0), counterSignedXmlElement);
			}
		}
예제 #9
0
		/// <summary>
		/// Default constructor
		/// </summary>
		public QualifyingProperties()
		{
			this.signedProperties = new SignedProperties();
			this.unsignedProperties = new UnsignedProperties();
		}