Example #1
0
 public static byte[] ComputeHashValue(byte[] value, FirmaXadesNet.Crypto.DigestMethod digestMethod)
 {
     using (var alg = digestMethod.GetHashAlgorithm())
     {
         return(alg.ComputeHash(value));
     }
 }
Example #2
0
 public static void SetCertDigest(byte[] rawCert, FirmaXadesNet.Crypto.DigestMethod digestMethod, DigestAlgAndValueType destination)
 {
     using (var hashAlg = digestMethod.GetHashAlgorithm())
     {
         destination.DigestMethod.Algorithm = digestMethod.URI;
         destination.DigestValue            = hashAlg.ComputeHash(rawCert);
     }
 }
Example #3
0
        /// <summary>
        /// Insert the certificate in the certificate list and check the certificate validity.
        /// </summary>
        /// <param name="cert"></param>
        /// <param name="unsignedProperties"></param>
        /// <param name="addCert"></param>
        /// <param name="ocspServers"></param>
        /// <param name="crlList"></param>
        /// <param name="digestMethod"></param>
        /// <param name="addCertificateOcspUrl"></param>
        /// <param name="extraCerts"></param>
        /// <param name="useNonce">If true then nonce will be used. The ocsp server should support this. OCSP reposnder in Microsoft Windows must be configured explicitly to support nonce.</param>
        private void AddCertificate(X509Certificate2 cert, UnsignedProperties unsignedProperties, bool addCert, IEnumerable <OcspServer> ocspServers,
                                    IEnumerable <X509Crl> crlList, FirmaXadesNet.Crypto.DigestMethod digestMethod, bool addCertificateOcspUrl, X509Certificate2[] extraCerts = null, bool useNonce = true)
        {
            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 = cert.GetSerialNumberAsDecimalString();
                DigestUtil.SetCertDigest(cert.GetRawCertData(), digestMethod, chainCert.CertDigest);
                chainCert.URI = "#Cert" + guidCert;
                unsignedProperties.UnsignedSignatureProperties.CompleteCertificateRefs.CertRefs.CertCollection.Add(chainCert);

                EncapsulatedX509Certificate encapsulatedX509Certificate = new EncapsulatedX509Certificate
                {
                    Id      = "Cert" + guidCert,
                    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, crlList, digestMethod);

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

                    if (ocspCerts != null)
                    {
                        X509Certificate2 startOcspCert = DetermineStartCert(ocspCerts);

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

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

                AddCertificate(enumerator.Current.Certificate, unsignedProperties, true, ocspServers, crlList, digestMethod, addCertificateOcspUrl, extraCerts);
            }
        }
Example #4
0
        private bool ValidateCertificateByCRL(UnsignedProperties unsignedProperties, X509Certificate2 certificate, X509Certificate2 issuer,
                                              IEnumerable <X509Crl> crlList, FirmaXadesNet.Crypto.DigestMethod digestMethod)
        {
            Org.BouncyCastle.X509.X509Certificate clientCert = certificate.ToBouncyX509Certificate();
            Org.BouncyCastle.X509.X509Certificate issuerCert = issuer.ToBouncyX509Certificate();

            foreach (var crlEntry in crlList)
            {
                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, digestMethod, crlRef.CertDigest);

                            CRLValue crlValue = new CRLValue
                            {
                                PkiData = crlEncoded,
                                Id      = idCrlValue
                            };

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

                        return(true);
                    }
                    else
                    {
                        throw new Exception("Certificate revoked");
                    }
                }
            }

            return(false);
        }
        /// <summary>
        /// Inserta y valida los certificados del servidor de sellado de tiempo.
        /// </summary>
        /// <param name="unsignedProperties"></param>
        private void AddTSACertificates(UnsignedProperties unsignedProperties, IEnumerable <OcspServer> ocspServers, IEnumerable <X509Crl> crlList, FirmaXadesNet.Crypto.DigestMethod digestMethod, bool addCertificateOcspUrl)
        {
            TimeStampToken token = new TimeStampToken(new 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.ToArray());

            AddCertificate(startCert, unsignedProperties, true, ocspServers, crlList, digestMethod, addCertificateOcspUrl, tsaCerts.ToArray());
        }
        private X509Certificate2[] ValidateCertificateByOCSP(UnsignedProperties unsignedProperties, X509Certificate2 client, X509Certificate2 issuer,
                                                             IEnumerable <OcspServer> ocspServers, FirmaXadesNet.Crypto.DigestMethod digestMethod, bool addCertificateOcspUrl)
        {
            bool byKey = false;
            List <OcspServer> finalOcspServers = new List <OcspServer>();

            Org.BouncyCastle.X509.X509Certificate clientCert = client.ToBouncyX509Certificate();
            Org.BouncyCastle.X509.X509Certificate issuerCert = issuer.ToBouncyX509Certificate();

            OcspClient ocsp = new OcspClient();

            if (addCertificateOcspUrl)
            {
                string certOcspUrl = ocsp.GetAuthorityInformationAccessOcspUrl(issuerCert);

                if (!string.IsNullOrEmpty(certOcspUrl))
                {
                    finalOcspServers.Add(new OcspServer(certOcspUrl));
                }
            }

            foreach (var ocspServer in ocspServers)
            {
                finalOcspServers.Add(ocspServer);
            }

            foreach (var ocspServer in finalOcspServers)
            {
                byte[] resp = ocsp.QueryBinary(clientCert, issuerCert, ocspServer.Url, ocspServer.RequestorName,
                                               ocspServer.SignCertificate);

                FirmaXadesNet.Clients.CertificateStatus status = ocsp.ProcessOcspResponse(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, digestMethod, ocspRef.CertDigest);

                    ResponderID rpId = or.ResponderId.ToAsn1Object();
                    ocspRef.OCSPIdentifier.ResponderID = GetResponderName(rpId, ref byKey);
                    ocspRef.OCSPIdentifier.ByKey       = byKey;

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