Inheritance: Org.BouncyCastle.X509.X509ExtensionBase
コード例 #1
0
ファイル: OcspClient.cs プロジェクト: benediktkr/nexusauth
 /// <summary>
 /// Check if the response is too old.
 /// </summary>
 /// <param name="resp">OCSP response</param>
 private void ValidateThisUpdate(BouncyCastleOCSP.SingleResp resp)
 {
     if (Math.Abs(resp.ThisUpdate.Ticks - DateTime.Now.Ticks) > MaxClockSkew)
     {
         throw new HttpException(401, "Resonpse too old.");
     }
 }
コード例 #2
0
ファイル: OcspClient.cs プロジェクト: benediktkr/nexusauth
        /// <summary>
        /// Checks if Next Update value is not null. If not null next update must not be older then current time.
        /// </summary>
        /// <param name="resp">OCSP response</param>

        private void ValidateNextUpdate(BouncyCastleOCSP.SingleResp resp)
        {
            if (resp.NextUpdate != null && resp.NextUpdate.Value != null && resp.NextUpdate.Value.Ticks <= DateTime.Now.Ticks)
            {
                //log.LogError(Logger.LogLevel.ERROR, "ValidateNextUpdate", "Invalid Next Update");
                throw new HttpException(401, "Invalid Next Update");
            }
        }
コード例 #3
0
        public SingleResp[] GetResponses()
        {
            Asn1Sequence responses = this.data.Responses;

            SingleResp[] array = new SingleResp[responses.Count];
            for (int num = 0; num != array.Length; num++)
            {
                array[num] = new SingleResp(SingleResponse.GetInstance(responses[num]));
            }
            return(array);
        }
コード例 #4
0
ファイル: RespData.cs プロジェクト: smdx24/CPI-Source-Code
        public SingleResp[] GetResponses()
        {
            Asn1Sequence responses = data.Responses;

            SingleResp[] array = new SingleResp[responses.Count];
            for (int i = 0; i != array.Length; i++)
            {
                array[i] = new SingleResp(SingleResponse.GetInstance(responses[i]));
            }
            return(array);
        }
コード例 #5
0
ファイル: RespData.cs プロジェクト: htlp/itextsharp
		public SingleResp[] GetResponses()
		{
			Asn1Sequence s = data.Responses;
			SingleResp[] rs = new SingleResp[s.Count];

			for (int i = 0; i != rs.Length; i++)
			{
				rs[i] = new SingleResp(SingleResponse.GetInstance(s[i]));
			}

			return rs;
		}
コード例 #6
0
        public SingleResp[] GetResponses()
        {
            Asn1Sequence s = data.Responses;

            SingleResp[] rs = new SingleResp[s.Count];

            for (int i = 0; i != rs.Length; i++)
            {
                rs[i] = new SingleResp(SingleResponse.GetInstance(s[i]));
            }

            return(rs);
        }
コード例 #7
0
ファイル: OcspClient.cs プロジェクト: benediktkr/nexusauth
        /// <summary>
        /// Checks if the OCSP response from the OCSP responder. Returns the validity of the certificate used to sign the ocsp response and also
        /// if the client certificate is valid, revoked or unknown.
        /// </summary>
        /// <param name="clientCert">Client certificate</param>
        /// <param name="issuerCert">Issuer certificate of the client certificate</param>
        /// <param name="binaryResp">OCSP response</param>
        /// <returns>CertificateStatus</returns>
        private CertificateStatus CheckOcspResponse(X509Certificate clientCert, X509Certificate issuerCert, byte[] binaryResp)
        {
            BouncyCastleOCSP.OcspResp ocspResponse = new BouncyCastleOCSP.OcspResp(binaryResp);
            CertificateStatus         certStatus   = CertificateStatus.Unknown;


            switch (ocspResponse.Status)
            {
            case BouncyCastleOCSP.OcspRespStatus.Successful:
                BouncyCastleOCSP.BasicOcspResp response = (BouncyCastleOCSP.BasicOcspResp)ocspResponse.GetResponseObject();

                if (response.Responses.Length == 1)
                {
                    BouncyCastleOCSP.SingleResp singleResponse = response.Responses[0];

                    ValidateCertificateId(issuerCert, clientCert, singleResponse.GetCertID());
                    ValidateThisUpdate(singleResponse);
                    ValidateNextUpdate(singleResponse);

                    Object certificateStatus = singleResponse.GetCertStatus();

                    if (certificateStatus == Org.BouncyCastle.Ocsp.CertificateStatus.Good)
                    {
                        certStatus = CertificateStatus.Good;
                    }
                    else if (certificateStatus is Org.BouncyCastle.Ocsp.RevokedStatus)
                    {
                        certStatus = CertificateStatus.Revoked;
                    }
                    else if (certificateStatus is Org.BouncyCastle.Ocsp.UnknownStatus)
                    {
                        certStatus = CertificateStatus.Unknown;
                    }
                }
                break;

            default:
            {
                throw new BouncyCastleOCSP.OcspException("Error status: " + this.GetOCSPResponseStatus(ocspResponse.Status));
            }
            }

            return(certStatus);
        }
コード例 #8
0
 //5. The time at which the status being indicated is known to be
 //correct (thisUpdate) is sufficiently recent.
 private void ValidateThisUpdate(SingleResp resp)
 {
     if (Math.Abs(resp.ThisUpdate.Ticks - DateTime.Now.Ticks) > MaxClockSkew)
     {
         throw new Exception("Max clock skew reached.");
     }
 }
コード例 #9
0
 //6. When available, the time at or before which newer information will
 //be available about the status of the certificate (nextUpdate) is
 //greater than the current time.
 private void ValidateNextUpdate(SingleResp resp)
 {
     if( resp.NextUpdate != null && resp.NextUpdate.Value != null && resp.NextUpdate.Value.Ticks <= DateTime.Now.Ticks) {
         throw new Exception("Invalid next update.");
      }
 }
コード例 #10
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);
        }