Наследование: Org.BouncyCastle.Asn1.Asn1Encodable
Пример #1
0
        /// <summary>
        /// Build a chain for the certificates and verifies the revocation (own implementation)
        /// </summary>
        /// <param name="cert">The certificate to validate</param>
        /// <param name="validationTime">The time upon wich the validate</param>
        /// <param name="extraStore">Extra certs to use when creating the chain</param>
        /// <param name="crls">Already known crl's, newly retrieved CRL's will be added here</param>
        /// <param name="ocsps">Already konwn ocsp's, newly retreived OCSP's will be added here</param>
        /// <returns>The chain with all the information about validity</returns>
        public static Chain BuildChain(this X509Certificate2 cert, DateTime validationTime, X509Certificate2Collection extraStore, IList <BCAX.CertificateList> crls, IList <BCAO.BasicOcspResponse> ocsps)
        {
            Chain chain = cert.BuildChain(validationTime, extraStore);

            if (cert.IsOcspNoCheck())
            {
                return(chain); //nothing to do
            }
            for (int i = 0; i < (chain.ChainElements.Count - 1); i++)
            {
                X509Certificate2 nextCert   = chain.ChainElements[i].Certificate;
                X509Certificate2 nextIssuer = chain.ChainElements[i + 1].Certificate;

                try
                {
                    //try OCSP
                    BCAO.BasicOcspResponse ocspResponse = nextCert.Verify(nextIssuer, validationTime, ocsps);
                    if (ocspResponse == null)
                    {
                        //try to fetch a new one
                        BCAO.OcspResponse ocspMsg = nextCert.GetOcspResponse(nextIssuer);
                        if (ocspMsg != null)
                        {
                            //new one fetched, try again
                            ocspResponse = BCAO.BasicOcspResponse.GetInstance(BCA.Asn1Object.FromByteArray(ocspMsg.ResponseBytes.Response.GetOctets()));
                            ocsps.Add(ocspResponse);
                            ocspResponse = nextCert.Verify(nextIssuer, validationTime, ocsps);
                        }
                    }

                    //TODO::ignore OCSP retreival errors and try CRL ;-)
                    if (ocspResponse == null)
                    {
                        //try CRL
                        BCAX.CertificateList crl = nextCert.Verify(nextIssuer, validationTime, crls);
                        if (crl == null)
                        {
                            //try to fetch a new one
                            crl = nextCert.GetCertificateList();
                            if (crl != null)
                            {
                                //new one fetched, try again
                                crls.Add(crl);
                                crl = nextCert.Verify(nextIssuer, validationTime, crls);
                            }
                        }
                    }
                }
                catch (RevocationException <BCAO.BasicOcspResponse> )
                {
                    AddErrorStatus(chain.ChainStatus, chain.ChainElements[i].ChainElementStatus, X509ChainStatusFlags.Revoked, "The certificate has been revoked");
                }
                catch
                {
                    AddErrorStatus(chain.ChainStatus, chain.ChainElements[i].ChainElementStatus, X509ChainStatusFlags.RevocationStatusUnknown, "Invalid OCSP/CRL found");
                }
            }
            return(chain);
        }
Пример #2
0
		public RevocationValues(
			CertificateList[]	crlVals,
			BasicOcspResponse[]	ocspVals,
			OtherRevVals		otherRevVals)
		{
			if (crlVals != null)
			{
				this.crlVals = new DerSequence(crlVals);
			}

			if (ocspVals != null)
			{
				this.ocspVals = new DerSequence(ocspVals);
			}

			this.otherRevVals = otherRevVals;
		}
Пример #3
0
        public RevocationValues(
            CertificateList[]	crlVals,
            BasicOcspResponse[]	ocspVals,
            OtherRevVals		otherRevVals)
        {
            //if (otherRevVals == null)
            //	throw new ArgumentNullException("otherRevVals");

            if (crlVals != null)
            {
                this.crlVals = new DerSequence(crlVals);
            }

            if (ocspVals != null)
            {
                this.ocspVals = new DerSequence(ocspVals);
            }

            this.otherRevVals = otherRevVals;
        }
Пример #4
0
		public BasicOcspResponse[] GetOcspVals()
		{
			BasicOcspResponse[] result = new BasicOcspResponse[ocspVals.Count];
			for (int i = 0; i < ocspVals.Count; ++i)
			{
				result[i] = BasicOcspResponse.GetInstance(ocspVals[i].ToAsn1Object());
			}
			return result;
		}
Пример #5
0
        /// <summary>
        /// Validates the cert with the provided ocsp responses.
        /// </summary>
        /// <param name="certificate">The cert to validate</param>
        /// <param name="issuer">The issuer of the cert to validate</param>
        /// <param name="validationTime">The time on which the cert was needed to validated</param>
        /// <param name="ocspResponses">The list of ocsp responses to use</param>
        /// <returns>The OCSP response that was used, <c>null</c> if none was found</returns>
        /// <exception cref="RevocationException{T}">When the certificate was revoked on the provided time</exception>
        /// <exception cref="RevocationUnknownException">When the certificate (or the OCSP) can't be validated</exception>
        public static BCAO.BasicOcspResponse Verify(this X509Certificate2 certificate, X509Certificate2 issuer, DateTime validationTime, IList <BCAO.BasicOcspResponse> ocspResponses)
        {
            DateTime minTime = validationTime - ClockSkewness;
            DateTime maxTime = validationTime + ClockSkewness;

            BCX.X509Certificate certificateBC = DotNetUtilities.FromX509Certificate(certificate);
            BCX.X509Certificate issuerBC      = DotNetUtilities.FromX509Certificate(issuer);

            ValueWithRef <BCO.SingleResp, ValueWithRef <BCO.BasicOcspResp, BCAO.BasicOcspResponse> > singleOcspRespLeaf = ocspResponses
                                                                                                                          .Select((rsp) => new ValueWithRef <BCO.BasicOcspResp, BCAO.BasicOcspResponse>(new BCO.BasicOcspResp(rsp), rsp))                                         //convert, but keep the original
                                                                                                                          .SelectMany((r) => r.Value.Responses.Select(sr => new ValueWithRef <BCO.SingleResp, ValueWithRef <BCO.BasicOcspResp, BCAO.BasicOcspResponse> >(sr, r))) //get the single respononses, but keep the parent
                                                                                                                          .Where((sr) => sr.Value.GetCertID().SerialNumber.Equals(certificateBC.SerialNumber) && sr.Value.GetCertID().MatchesIssuer(issuerBC))                    //is it for this cert?
                                                                                                                          .Where((sr) => sr.Value.ThisUpdate >= minTime || (sr.Value.NextUpdate != null && sr.Value.NextUpdate.Value >= minTime))                                 //was it issued on time?
                                                                                                                          .OrderByDescending((sr) => sr.Value.ThisUpdate)                                                                                                         //newest first
                                                                                                                          .FirstOrDefault();

            if (singleOcspRespLeaf == null)
            {
                return(null);
            }

            BCO.SingleResp         singleOcspResp    = singleOcspRespLeaf.Value;
            BCO.BasicOcspResp      basicOcspResp     = singleOcspRespLeaf.Reference.Value;
            BCAO.BasicOcspResponse basicOcspResponse = singleOcspRespLeaf.Reference.Reference;

            //get the signer name
            BCAX.X509Name responderName = basicOcspResp.ResponderId.ToAsn1Object().Name;
            if (responderName == null)
            {
                trace.TraceEvent(TraceEventType.Error, 0, "OCSP response for {0} does not have a ResponderID", certificate.Subject);
                throw new RevocationUnknownException("OCSP response for {0} does not have a ResponderID");
            }

            //Get the signer certificate
            var selector = new BCS.X509CertStoreSelector();

            selector.Subject = responderName;
            BCX.X509Certificate ocspSignerBc = (BCX.X509Certificate)basicOcspResp
                                               .GetCertificates("Collection").GetMatches(selector)
                                               .Cast <BCX.X509Certificate>().FirstOrDefault();
            if (ocspSignerBc == null)
            {
                throw new RevocationUnknownException("The OCSP is signed by a unknown certificate");
            }

            //verify the response signature
            if (!basicOcspResp.Verify(ocspSignerBc.GetPublicKey()))
            {
                throw new RevocationUnknownException("The OCSP has an invalid signature");
            }


            //OCSP must be issued by same issuer an the certificate that it validates.
            try
            {
                if (!ocspSignerBc.IssuerDN.Equals(issuerBC.SubjectDN))
                {
                    throw new ApplicationException();
                }
                ocspSignerBc.Verify(issuerBC.GetPublicKey());
            }
            catch (Exception e)
            {
                throw new RevocationUnknownException("The OCSP signer was not issued by the proper CA", e);
            }

            //verify if the OCSP signer certificate is stil valid
            if (!ocspSignerBc.IsValid(basicOcspResp.ProducedAt))
            {
                throw new RevocationUnknownException("The OCSP signer was not valid at the time the ocsp was issued");
            }


            //check if the signer may issue OCSP
            IList ocspSignerExtKeyUsage = ocspSignerBc.GetExtendedKeyUsage();

            if (!ocspSignerExtKeyUsage.Contains("1.3.6.1.5.5.7.3.9"))
            {
                throw new RevocationUnknownException("The OCSP is signed by a certificate that isn't allowed to sign OCSP");
            }

            //finally, check if the certificate is revoked or not
            var revokedStatus = (BCO.RevokedStatus)singleOcspResp.GetCertStatus();

            if (revokedStatus != null)
            {
                trace.TraceEvent(TraceEventType.Verbose, 0, "OCSP response for {0} indicates that the certificate is revoked on {1}", certificate.Subject, revokedStatus.RevocationTime);
                if (maxTime >= revokedStatus.RevocationTime)
                {
                    throw new RevocationException <BCAO.BasicOcspResponse>(basicOcspResponse, "The certificate was revoked on " + revokedStatus.RevocationTime.ToString("o"));
                }
            }

            return(basicOcspResponse);
        }
Пример #6
0
//		private readonly X509Certificate[]	chain;

		public BasicOcspResp(
			BasicOcspResponse resp)
		{
			this.resp = resp;
			this.data = resp.TbsResponseData;
		}
Пример #7
0
		/// <exception cref="System.IO.IOException"></exception>
        //private IDictionary<DerObjectIdentifier, Asn1Encodable> ExtendUnsignedAttributes(IDictionary
        //    <DerObjectIdentifier, Asn1Encodable> unsignedAttrs, X509Certificate signingCertificate
        //    , DateTime signingDate, CertificateSource optionalCertificateSource)
        private IDictionary ExtendUnsignedAttributes(IDictionary unsignedAttrs
            , X509Certificate signingCertificate, DateTime signingDate
            , CertificateSource optionalCertificateSource)
		{
			ValidationContext validationContext = certificateVerifier.ValidateCertificate(signingCertificate
				, signingDate, optionalCertificateSource, null, null);
			try
			{
				IList<X509CertificateStructure> certificateValues = new AList<X509CertificateStructure
					>();
				AList<CertificateList> crlValues = new AList<CertificateList>();
				AList<BasicOcspResponse> ocspValues = new AList<BasicOcspResponse>();
				foreach (CertificateAndContext c in validationContext.GetNeededCertificates())
				{
					if (!c.Equals(signingCertificate))
					{
                        certificateValues.AddItem(X509CertificateStructure.GetInstance(((Asn1Sequence)Asn1Object.FromByteArray
                            (c.GetCertificate().GetEncoded()))));
					}
				}
				foreach (X509Crl relatedcrl in validationContext.GetNeededCRL())
				{                    
					crlValues.AddItem(CertificateList.GetInstance((Asn1Sequence)Asn1Object.FromByteArray(((X509Crl
						)relatedcrl).GetEncoded())));
				}
				foreach (BasicOcspResp relatedocspresp in validationContext.GetNeededOCSPResp())
				{                    
					ocspValues.AddItem((BasicOcspResponse.GetInstance((Asn1Sequence)Asn1Object.FromByteArray(
						relatedocspresp.GetEncoded()))));
				}
				CertificateList[] crlValuesArray = new CertificateList[crlValues.Count];
				BasicOcspResponse[] ocspValuesArray = new BasicOcspResponse[ocspValues.Count];
				RevocationValues revocationValues = new RevocationValues(Sharpen.Collections.ToArray
					(crlValues, crlValuesArray), Sharpen.Collections.ToArray(ocspValues, ocspValuesArray
					), null);
				//unsignedAttrs.Put(PkcsObjectIdentifiers.IdAAEtsRevocationValues, new Attribute
                unsignedAttrs.Add(PkcsObjectIdentifiers.IdAAEtsRevocationValues, new BcCms.Attribute
					(PkcsObjectIdentifiers.IdAAEtsRevocationValues, new DerSet(revocationValues))
					);
				X509CertificateStructure[] certValuesArray = new X509CertificateStructure[certificateValues
					.Count];
				//unsignedAttrs.Put(PkcsObjectIdentifiers.IdAAEtsCertValues, new Attribute(PkcsObjectIdentifiers.IdAAEtsCertValues, new DerSet(new DerSequence(Sharpen.Collections.ToArray(certificateValues
                unsignedAttrs.Add(PkcsObjectIdentifiers.IdAAEtsCertValues, new BcCms.Attribute(PkcsObjectIdentifiers.IdAAEtsCertValues, new DerSet(new DerSequence(Sharpen.Collections.ToArray(certificateValues
					, certValuesArray)))));
			}
			catch (CertificateEncodingException e)
			{
				throw new RuntimeException(e);
			}
			catch (CrlException e)
			{
				throw new RuntimeException(e);
			}
			return unsignedAttrs;
		}
 private static List<X509Certificate2> CompleteOcspChain(BasicOcspResponse ocspResponse, IEnumerable<X509Certificate2> ocspChain)
 {
     var ocspCertificate = new X509Certificate2(ocspResponse.Certs[0].GetEncoded());
     return new List<X509Certificate2>(ocspChain) {ocspCertificate};
 }
Пример #9
0
 public static BasicOcspResponse GetInstance(Asn1TaggedObject obj, bool explicitly)
 {
     return(BasicOcspResponse.GetInstance(Asn1Sequence.GetInstance(obj, explicitly)));
 }
Пример #10
0
        public void Setup()
        {
            leafCert = new X509Certificate2("files/eid79021802145.crt");
            intCaCert = new X509Certificate2("files/Citizen201204.crt");

            intCaCrl = CertificateList.GetInstance(File.ReadAllBytes("files/Citizen201204.crl"));
            rootCaCrl = CertificateList.GetInstance(File.ReadAllBytes("files/rootca2.crl"));
            leafOcsp = BasicOcspResponse.GetInstance(Asn1Sequence.GetInstance(File.ReadAllBytes("files/eid79021802145.ocsp")));
            leafOcsp2 = BasicOcspResponse.GetInstance(Asn1Sequence.GetInstance(File.ReadAllBytes("files/eid79021802145-2.ocsp")));
        }