public void LookupTestOkayFoces2() { try { X509Certificate2 certificate = new X509Certificate2(LookupTest.foces2OkayCertificate, "Test1234"); Assert.IsNotNull(certificate, "Test certificate was null."); CrlLookup crlLookup = new CrlLookup(); RevocationResponse response = crlLookup.CheckCertificate(certificate); Assert.IsTrue(response.IsValid); Assert.IsNull(response.Exception, "The lookup return an exception."); Assert.AreEqual(RevocationCheckStatus.AllChecksPassed, response.RevocationCheckStatus, "Not all check was performed."); } catch (Exception exception) { Assert.Fail(exception.ToString()); } }
public void LookupTestRevokedFoces2() { try { X509Certificate2 certificate = new X509Certificate2(LookupTest.foces2RevokedCertificate, "Test1234"); Assert.IsNotNull(certificate, "Test certificate was null."); CrlLookup crlLookup = new CrlLookup(); RevocationResponse response = crlLookup.CheckCertificate(certificate); Assert.IsNull(response.Exception, "The lookup return an exception."); Assert.AreEqual(RevocationCheckStatus.CertificateRevoked, response.RevocationCheckStatus, "The revokation validation did not parse all check"); Assert.IsFalse(response.IsValid, "The revoked certifikate was valid"); } catch (Exception exception) { Assert.Fail(exception.ToString()); } }
public void LookTestMultiThread() { List <Thread> threads = new List <Thread>(); CrlLookup crlLookup = new CrlLookup(); for (int i = 0; i < 32; i++) { Thread thread = new Thread(ThreadCertificateCheck); thread.Start(); threads.Add(thread); } Predicate <Thread> isDead = delegate(Thread t) { return(!t.IsAlive); }; while (!threads.TrueForAll(isDead)) { Thread.Sleep(TimeSpan.FromSeconds(1)); } }
//private X509Certificate2 certificateMoces = new X509Certificate2(CrlLookupTest. medarbejdercertifikatRevoked, "Test1234"); private void ThreadCertificateCheck() { CrlLookup crlLookup = new CrlLookup(); for (int i = 0; i < 16; i++) { Random random = new Random(); int select = random.Next(2); if (select < 1) { Console.WriteLine("{0} ThreadCertificateCheck number:{1} foces1 allOkay", DateTime.Now, i); RevocationResponse response = crlLookup.CheckCertificate(certificateFoces); if (response.Exception != null) { Console.WriteLine("{0} ThreadCertificateCheck number:{1} foces1 Exception: " + response.Exception.ToString(), DateTime.Now, i); } if (response.IsValid) { // yes - certificate is valid if (response.RevocationCheckStatus == RevocationCheckStatus.AllChecksPassed) { // yes - check all parsed } else { Console.WriteLine("{0} ThreadCertificateCheck number:{1} foces1 not all checked parsed ", DateTime.Now, i); Assert.Fail("Foces2 certifiate should have been valid."); } } else { // arg - certificate is not valid Assert.IsTrue(response.IsValid, "Foces certifiate should have been valid."); Console.WriteLine("{0} ThreadCertificateCheck number:{1} foces1 not all checked parsed ", DateTime.Now, i); } } else { //// moces1 //Console.WriteLine("{0} ThreadCertificateCheck number:{1} moces1 revoked", DateTime.Now, i); //RevocationResponse response = crlLookup.CheckCertificate(certificateMoces); //if (response.Exception != null) //{ // Console.WriteLine("{0} ThreadCertificateCheck number:{1} foces1 Exception: " + response.Exception.ToString(), DateTime.Now, i); //} //if (!response.IsValid) //{ // // yes - certificate is revoked // if (response.RevocationCheckStatus == RevocationCheckStatus.CertificateRevoked) // { // // yes - check all parsed // } // else // { // Console.WriteLine("{0} ThreadCertificateCheck number:{1} moces1 RevocationCheckStatus is not revoked as expected.", DateTime.Now, i); // Assert.Fail("Moces2 RevocationCheckStatus is not revoked as expected"); // } //} //else //{ // // arg - certificate is valid // Assert.IsFalse(response.IsValid, "Moces certificate should have been revoked."); // Console.WriteLine("{0} ThreadCertificateCheck number:{1} moces1 certificate is not revoked as expected.", DateTime.Now, i); //} } Console.WriteLine("{0} ThreadCertificateCheck number:{1} done", DateTime.Now, i); } }
/// <summary> /// Checks a certificate status on a ocsp server /// </summary> /// <param name="x509Certificate2">The certificate to check</param> /// <returns>The RevocationResponse object that contains the result</returns> /// <exception cref="CheckCertificateOcspUnexpectedException">This exception is thrown, if an unexpected exception is thrown during the method</exception> private RevocationResponse RevocationResponseOnline(X509Certificate2 x509Certificate2) { RevocationResponse revocationResponse = new RevocationResponse(); if (x509Certificate2 == null) { throw new CheckCertificateOcspUnexpectedException(); } // http://bouncy-castle.1462172.n4.nabble.com/c-ocsp-verification-td3160243.html X509Certificate2 issuerX509Certificate2 = this.FindIssuerCertificate(x509Certificate2); if (issuerX509Certificate2 == null) { throw new CheckCertificateOcspUnexpectedException("Issuer certificate '" + x509Certificate2.Issuer + "' not found."); } if (issuerX509Certificate2.Thumbprint.Equals(x509Certificate2.Thumbprint, StringComparison.OrdinalIgnoreCase)) { // the certificate and the issuer certificace is the same // this mean that the root certificate is not trusted revocationResponse = null; } else { revocationResponse = this.RevocationResponseOnline(x509Certificate2, issuerX509Certificate2); if (revocationResponse != null) { if (revocationResponse.Exception == null) { // no exception recorded if (revocationResponse.IsValid) { // now we know the certificate is valid. // if the issuer is a trusted root certificate, all is good if (this.rootCertificateDirectory.ContainsKey(issuerX509Certificate2.Thumbprint.ToLowerInvariant())) { // the root certificate is trusted, so the RevocationResponse can be put on the cache this.ocspCache.Set(x509Certificate2.Thumbprint.ToLowerInvariant(), revocationResponse); } else { // we do not yet know if the certificate is valid. // the certificate migth be good, but if the issueing certificate is revoked, // then the certificate should also be revoked. // Validate the issuer certificate // this is required, because certificate can have a chain that is longer then 2 // The only problem is, that we can not ocsp validate the intermiddel certificate (the issuer certificate). // acording to DanID - that certificate can only be validated with CRL // Note : The crl list will be/should be very short. Only containing the issuer certificate that has been revoked. // A good guess is that there at all time will be most 10 issuer certificate, so the list of revoked issuer certificate is short. IList <string> issuerUrl = this.GetAuthorityInformationAccessOcspUrl(issuerX509Certificate2); RevocationResponse issuerRevocationResponse; if (issuerUrl.Count > 0) { // hey, wow some url exist - lets use that // don't thing this will ever happens anyway issuerRevocationResponse = this.RevocationResponse(issuerX509Certificate2); } else { // we need to validate with crl instead // It does not contain the Authority Info Access, containng the rl to where the certificate must be validated // We must therefore gues, that the certificate is valid. CrlLookup crlLookupClient = new CrlLookup(); issuerRevocationResponse = crlLookupClient.CheckCertificate(issuerX509Certificate2); } // now to handle the issuerRevocationResponse if (issuerRevocationResponse != null) { // the issuer certificate is validated, the validity of the issuer certificate // is copied to the revocationResponse revocationResponse.IsValid = issuerRevocationResponse.IsValid; revocationResponse.Exception = issuerRevocationResponse.Exception; } else { revocationResponse.IsValid = false; revocationResponse.Exception = new CheckCertificateOcspUnexpectedException("The issueing certificate could not be validated."); } // update the cache this.ocspCache.Set(x509Certificate2.Thumbprint.ToLowerInvariant(), revocationResponse); } } else { // the certificate is NOT valid // no need to check the issuer certificate this.ocspCache.Set(x509Certificate2.Thumbprint.ToLowerInvariant(), revocationResponse); } } else { // some exception returned. // do not add to cache } } } return(revocationResponse); }