/// <param name="ocspResp"></param> /// <returns></returns> public virtual bool Match(BasicOcspResp ocspResp) { try { IDigest digest = DigestUtilities.GetDigest(algorithm); byte[] oscpBytes; if (matchOnlyBasicOCSPResponse) { oscpBytes = ocspResp.GetEncoded(); } else { oscpBytes = OCSPUtils.FromBasicToResp(ocspResp).GetEncoded(); } digest.BlockUpdate(oscpBytes, 0, oscpBytes.Length); byte[] computedValue = DigestUtilities.DoFinal(digest); LOG.Info("Compare " + Hex.ToHexString(digestValue) + " to computed value " + Hex.ToHexString(computedValue) + " of BasicOcspResp produced at " + ocspResp .ProducedAt); return Arrays.Equals(digestValue, computedValue); } catch (NoSuchAlgorithmException ex) { throw new RuntimeException("Maybe BouncyCastle provider is not installed ?", ex); } catch (IOException ex) { throw new RuntimeException(ex); } }
public const int Unauthorized = 6; // Request unauthorized public OcspResp Generate( int status, object response) { if (response == null) { return(new OcspResp(new OcspResponse(new OcspResponseStatus(status), null))); } if (response is BasicOcspResp) { BasicOcspResp r = (BasicOcspResp)response; Asn1OctetString octs; try { octs = new DerOctetString(r.GetEncoded()); } catch (Exception e) { throw new OcspException("can't encode object.", e); } ResponseBytes rb = new ResponseBytes( OcspObjectIdentifiers.PkixOcspBasic, octs); return(new OcspResp(new OcspResponse( new OcspResponseStatus(status), rb))); } throw new OcspException("unknown response object"); }
public override bool Equals(object obj) { if (obj == this) { return(true); } BasicOcspResp basicOcspResp = obj as BasicOcspResp; return(basicOcspResp != null && this.resp.Equals(basicOcspResp.resp)); }
/// <summary>Convert a BasicOcspResp in OcspResp (connection status is set to SUCCESSFUL). /// </summary> /// <remarks>Convert a BasicOcspResp in OcspResp (connection status is set to SUCCESSFUL). /// </remarks> /// <param name="basicOCSPResp"></param> /// <returns></returns> public static OcspResp FromBasicToResp(BasicOcspResp basicOCSPResp) { try { return FromBasicToResp(basicOCSPResp.GetEncoded()); } catch (IOException e) { throw new RuntimeException(e); } }
public BouncyCastleOCSP.BasicOcspResp getOCSPCertFromResponse() { if (ocspResponse == null) { return(null); } else { Org.BouncyCastle.Ocsp.OcspResp resp = new BouncyCastleOCSP.OcspResp(ocspResponse); BouncyCastleOCSP.BasicOcspResp bresp = resp.GetResponseObject() as BouncyCastleOCSP.BasicOcspResp; return(bresp); } }
public override bool Equals(object obj) { if (obj == this) { return(true); } BasicOcspResp basicOcspResp = obj as BasicOcspResp; if (basicOcspResp == null) { return(false); } return(resp.Equals(basicOcspResp.resp)); }
/// <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); }
public OcspResp Generate(int status, object response) { if (response == null) { return(new OcspResp(new OcspResponse(new OcspResponseStatus(status), null))); } if (response is BasicOcspResp) { BasicOcspResp basicOcspResp = (BasicOcspResp)response; Asn1OctetString response2; try { response2 = new DerOctetString(basicOcspResp.GetEncoded()); } catch (global::System.Exception e) { throw new OcspException("can't encode object.", e); } ResponseBytes responseBytes = new ResponseBytes(OcspObjectIdentifiers.PkixOcspBasic, response2); return(new OcspResp(new OcspResponse(new OcspResponseStatus(status), responseBytes))); } throw new OcspException("unknown response object"); }
/** * Verifies if an OCSP response is genuine * If it doesn't verify against the issuer certificate and response's certificates, it may verify * using a trusted anchor or cert. * @param ocspResp the OCSP response * @param issuerCert the issuer certificate * @throws GeneralSecurityException * @throws IOException */ virtual public void IsValidResponse(BasicOcspResp ocspResp, X509Certificate issuerCert) { //OCSP response might be signed by the issuer certificate or //the Authorized OCSP responder certificate containing the id-kp-OCSPSigning extended key usage extension X509Certificate responderCert = null; //first check if the issuer certificate signed the response //since it is expected to be the most common case if (IsSignatureValid(ocspResp, issuerCert)) { responderCert = issuerCert; } //if the issuer certificate didn't sign the ocsp response, look for authorized ocsp responses // from properties or from certificate chain received with response if (responderCert == null) { if (ocspResp.GetCerts() != null) { //look for existence of Authorized OCSP responder inside the cert chain in ocsp response X509Certificate[] certs = ocspResp.GetCerts(); foreach (X509Certificate cert in certs) { X509Certificate tempCert; try { tempCert = cert; } catch (Exception ex) { continue; } IList keyPurposes = null; try { keyPurposes = tempCert.GetExtendedKeyUsage(); if ((keyPurposes != null) && keyPurposes.Contains(id_kp_OCSPSigning) && IsSignatureValid(ocspResp, tempCert)) { responderCert = tempCert; break; } } catch (CertificateParsingException ignored) { } } // Certificate signing the ocsp response is not found in ocsp response's certificate chain received // and is not signed by the issuer certificate. if (responderCert == null) { throw new VerificationException(issuerCert, "OCSP response could not be verified"); } } else { //certificate chain is not present in response received //try to verify using rootStore if (certificates != null) { foreach (X509Certificate anchor in certificates) { try { if (IsSignatureValid(ocspResp, anchor)) { responderCert = anchor; break; } } catch (GeneralSecurityException ignored) { } } } // OCSP Response does not contain certificate chain, and response is not signed by any // of the rootStore or the issuer certificate. if (responderCert == null) { throw new VerificationException(issuerCert, "OCSP response could not be verified"); } } } //check "This certificate MUST be issued directly by the CA that issued the certificate in question". responderCert.Verify(issuerCert.GetPublicKey()); // validating ocsp signers certificate // Check if responders certificate has id-pkix-ocsp-nocheck extension, // in which case we do not validate (perform revocation check on) ocsp certs for lifetime of certificate if (responderCert.GetExtensionValue(OcspObjectIdentifiers.PkixOcspNocheck.Id) == null) { X509Crl crl; try { X509CrlParser crlParser = new X509CrlParser(); // Creates the CRL Stream url = WebRequest.Create(CertificateUtil.GetCRLURL(responderCert)).GetResponse().GetResponseStream(); crl = crlParser.ReadCrl(url); } catch (Exception ignored) { crl = null; } if (crl != null) { CrlVerifier crlVerifier = new CrlVerifier(null, null); crlVerifier.Certificates = certificates; crlVerifier.OnlineCheckingAllowed = onlineCheckingAllowed; crlVerifier.Verify(crl, responderCert, issuerCert, DateTime.UtcNow); return; } } //check if lifetime of certificate is ok responderCert.CheckValidity(); }
private static void CheckBasicOcspResp(CertID id, BasicOcspResp basicResp, OcesCertificate ocspCertificate, Ca ca) { DateTime nowInGmt = DateTime.Now.ToUniversalTime(); /* check condition: The certificate identified in a received response corresponds to that which was identified in the corresponding request; */ SingleResp[] responses = basicResp.Responses; if (responses.Length != 1) { throw new OcspException("unexpected number of responses received"); } if (!id.SerialNumber.Value.Equals(responses[0].GetCertID().SerialNumber)) { throw new OcspException("Serial number mismatch problem"); } /* check condition The signature on the response is valid; */ try { ChainVerifier.VerifyTrust(ocspCertificate.ExportCertificate(), ca); } catch(ChainVerificationException e) { throw new OcspException("OCSP response certificate chain is invalid", e); } /* check the signature on the ocsp response */ var ocspBcCertificate = new X509CertificateParser().ReadCertificate(ocspCertificate.ExportCertificate().RawData); if (!basicResp.Verify(ocspBcCertificate.GetPublicKey())) { throw new OcspException("signature validation failed for ocsp response"); } if (!CanSignOcspResponses(ocspBcCertificate)) { throw new OcspException("ocsp signing certificate has not been cleared for ocsp response signing"); } /* check expiry of the signing certificate */ if (ocspCertificate.ValidityStatus() != CertificateStatus.Valid) { throw new OcspException("OCSP certificate expired or not yet valid"); } /* check condition The time at which the status being indicated is known to be correct (thisUpdate) is sufficiently recent. */ SingleResp response = responses[0]; var diff = response.ThisUpdate - nowInGmt; if (diff > new TimeSpan(0, 1, 0)) { throw new OcspException("OCSP response signature is from the future. Timestamp of thisUpdate field: " + response.ThisUpdate); } if (response.NextUpdate != null && response.NextUpdate.Value < nowInGmt) { throw new OcspException("OCSP response is no longer valid"); } }
//2. The signature on the response is valid; private void ValidateResponseSignature(BasicOcspResp or, Org.BouncyCastle.Crypto.AsymmetricKeyParameter asymmetricKeyParameter) { if (!or.Verify(asymmetricKeyParameter)) { throw new Exception("Invalid OCSP signature"); } }
/// <summary>The default constructor for OCSPRespCertificateSource.</summary> /// <remarks>The default constructor for OCSPRespCertificateSource.</remarks> public OCSPRespCertificateSource(BasicOcspResp ocspResp) { this.ocspResp = ocspResp; }
virtual public bool VerifyResponse(BasicOcspResp ocspResp, X509Certificate issuerCert) { try { IsValidResponse(ocspResp, issuerCert); return true; } catch (Exception e) { return false; } }
private void ValidateResponse(BasicOcspResp or, X509Certificate issuerCert) { ValidateResponseSignature(or, issuerCert.GetPublicKey()); ValidateSignerAuthorization(issuerCert, or.GetCerts()[0]); }
/// <summary>The default constructor for OCSPRespToken.</summary> /// <remarks>The default constructor for OCSPRespToken.</remarks> /// <param name="ocspResp"></param> public OCSPRespToken(BasicOcspResp ocspResp) { this.ocspResp = ocspResp; }
public override IList<BasicOcspResp> GetOCSPResponsesFromSignature() { IList<BasicOcspResp> list = new AList<BasicOcspResp>(); // Add certificates in CAdES-XL certificate-values inside SignerInfo attribute if present SignerInformation si = cmsSignedData.GetSignerInfos().GetFirstSigner(signerId); if (si != null && si.UnsignedAttributes != null && si.UnsignedAttributes[PkcsObjectIdentifiers.IdAAEtsRevocationValues] != null) { RevocationValues revValues = RevocationValues.GetInstance(si.UnsignedAttributes[PkcsObjectIdentifiers.IdAAEtsRevocationValues].AttrValues[0]); foreach (BasicOcspResponse ocspObj in revValues.GetOcspVals()) { BasicOcspResp bOcspObj = new BasicOcspResp(ocspObj); list.AddItem(bOcspObj); } } return list; }
/** * Checks if an OCSP response is genuine * @param ocspResp the OCSP response * @param responderCert the responder certificate * @return true if the OCSP response verifies against the responder certificate */ public bool IsSignatureValid(BasicOcspResp ocspResp, X509Certificate responderCert) { try { return ocspResp.Verify(responderCert.GetPublicKey()); } catch (OcspException) { return false; } }
/** * Verifies if an OCSP response is genuine * @param ocspResp the OCSP response * @param issuerCert the issuer certificate * @throws GeneralSecurityException * @throws IOException */ public void IsValidResponse(BasicOcspResp ocspResp, X509Certificate issuerCert) { // by default the OCSP responder certificate is the issuer certificate X509Certificate responderCert = issuerCert; // check if there's a responder certificate X509Certificate[] certs = ocspResp.GetCerts(); if (certs.Length > 0) { responderCert = certs[0]; try { responderCert.Verify(issuerCert.GetPublicKey()); } catch (GeneralSecurityException) { if (base.Verify(responderCert, issuerCert, DateTime.MaxValue).Count == 0) throw new VerificationException(responderCert, String.Format("{0} Responder certificate couldn't be verified", responderCert)); } } // verify if the signature of the response is valid if (!VerifyResponse(ocspResp, responderCert)) throw new VerificationException(responderCert, String.Format("{0} OCSP response could not be verified", responderCert)); }
private void FindOcsp(Asn1Sequence seq) { basicResp = null; bool ret = false; while (true) { if ((seq[0] is DerObjectIdentifier) && ((DerObjectIdentifier)seq[0]).Id.Equals(OcspObjectIdentifiers.PkixOcspBasic.Id)) { break; } ret = true; for (int k = 0; k < seq.Count; ++k) { if (seq[k] is Asn1Sequence) { seq = (Asn1Sequence)seq[0]; ret = false; break; } if (seq[k] is Asn1TaggedObject) { Asn1TaggedObject tag = (Asn1TaggedObject)seq[k]; if (tag.GetObject() is Asn1Sequence) { seq = (Asn1Sequence)tag.GetObject(); ret = false; break; } else return; } } if (ret) return; } DerOctetString os = (DerOctetString)seq[1]; Asn1InputStream inp = new Asn1InputStream(os.GetOctets()); BasicOcspResponse resp = BasicOcspResponse.GetInstance(inp.ReadObject()); basicResp = new BasicOcspResp(resp); }
static bool SerialNumberInResponseIsNotRevoked(BasicOcspResp response, string serialNumber) { var responseElements = new List<SingleResp>(response.Responses); return responseElements .Exists(r => r.GetCertStatus() == null && r.GetCertID().SerialNumber.ToString() == serialNumber); }
static void CheckValidityOfResponse(CertID id, BasicOcspResp responseObject, Ca ca) { var inputStream = new MemoryStream(responseObject.GetEncoded()); var asn1Sequence = (Asn1Sequence)new Asn1InputStream(inputStream).ReadObject(); var response = BasicOcspResponse.GetInstance(asn1Sequence); var ocspChain = CreateOcspCertificateChain(ca); if(ocspChain.Length == 0) { throw new OcspException("OCSP certificate chain is invalid"); } var ocesOcspCertificate = OcesCertificateFactory.Instance.Generate(CompleteOcspChain(response, ocspChain)); CheckBasicOcspResp(id, responseObject, ocesOcspCertificate, ca); var signingCertificate = new X509CertificateParser().ReadCertificate(response.Certs[0].GetEncoded()); var issuingCertificate = new X509CertificateParser().ReadCertificate(ocspChain[0].GetRawCertData()); signingCertificate.Verify(issuingCertificate.GetPublicKey()); if (!responseObject.Verify(signingCertificate.GetPublicKey())) { throw new OcspException("Signature is invalid"); } }
/** * Verifies a certificate against a single OCSP response * @param ocspResp the OCSP response * @param issuerCert * @param signDate * @return * @throws GeneralSecurityException * @throws IOException */ public bool Verify(BasicOcspResp ocspResp, X509Certificate signCert, X509Certificate issuerCert, DateTime signDate) { if (ocspResp == null) return false; // Getting the responses SingleResp[] resp = ocspResp.Responses; for (int i = 0; i < resp.Length; ++i) { // check if the serial number corresponds if (!signCert.SerialNumber.Equals(resp[i].GetCertID().SerialNumber)) continue; // check if the issuer matches try { if (issuerCert == null) issuerCert = signCert; if (!resp[i].GetCertID().MatchesIssuer(issuerCert)) { LOGGER.Info("OCSP: Issuers doesn't match."); continue; } } catch (OcspException) { continue; } // check if the OCSP response was valid at the time of signing if (signDate.CompareTo(resp[i].NextUpdate.Value) > 0) { LOGGER.Info(String.Format("OCSP no longer valid: {0} after {1}", signDate, resp[i].NextUpdate)); continue; } // check the status of the certificate Object status = resp[i].GetCertStatus(); if (status == CertificateStatus.Good) { // check if the OCSP response was genuine IsValidResponse(ocspResp, issuerCert); return true; } } return false; }
private void ValidarResponseSignature(BasicOcspResp in_OcspResp, Org.BouncyCastle.Crypto.AsymmetricKeyParameter in_PublicKey) { if (!in_OcspResp.Verify(in_PublicKey)) { throw new Exception("Firma OCSP Invalida"); } }
/** * Verifies if the signature of the response is valid. * If it doesn't verify against the responder certificate, it may verify * using a trusted anchor. * @param ocspResp the response object * @param responderCert the certificate that may be used to sign the response * @return true if the response can be trusted */ public bool VerifyResponse(BasicOcspResp ocspResp, X509Certificate responderCert) { // testing using the responder certificate if (IsSignatureValid(ocspResp, responderCert)) return true; // testing using trusted anchors if (certificates == null) return false; try { // loop over the certificates in the root store foreach (X509Certificate anchor in certificates) { try { if (IsSignatureValid(ocspResp, anchor)) return true; } catch (GeneralSecurityException) {} } } catch (GeneralSecurityException) { return false; } return false; }
private void ValidateResponse(BasicOcspResp in_OcspResp, X509Certificate in_CertificadoEmisor) { ValidarResponseSignature(in_OcspResp, in_CertificadoEmisor.GetPublicKey()); ValidarSignerAuthorization(in_CertificadoEmisor, in_OcspResp.GetCerts()[0]); }
/** * Verifies an OCSP response against a KeyStore. * @param ocsp the OCSP response * @param keystore the <CODE>KeyStore</CODE> * @param provider the provider or <CODE>null</CODE> to use the BouncyCastle provider * @return <CODE>true</CODE> is a certificate was found */ public static bool VerifyOcspCertificates(BasicOcspResp ocsp, ICollection<X509Certificate> keystore) { try { foreach (X509Certificate certStoreX509 in keystore) { try { if (ocsp.Verify(certStoreX509.GetPublicKey())) return true; } catch { } } } catch { } return false; }
/// <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); }