diff --git a/src/dk.gov.oiosi/security/validation/CertificateValidator.cs b/src/dk.gov.oiosi/security/validation/CertificateValidator.cs
index 7f2c99d86b98dcd009c259f14367cec9444abb8a..de54f23b6f8c24cd3ca6030b48ab9bda05c27d37 100644
--- a/src/dk.gov.oiosi/security/validation/CertificateValidator.cs
+++ b/src/dk.gov.oiosi/security/validation/CertificateValidator.cs
@@ -35,7 +35,6 @@ using System.Security.Cryptography.X509Certificates;
namespace dk.gov.oiosi.security.validation
{
-
///
/// Class to validate X509 certificates
///
@@ -58,28 +57,36 @@ namespace dk.gov.oiosi.security.validation
/// The certificate to be validated
public static void ValidateCertificate(X509Certificate2 certificate)
{
- // first we check the activation and expire date - those cast the most specifict errors
- CheckCertificateActivated(certificate);
- CheckCertificateExpired(certificate);
+ try
+ {
+ // first we check the activation and expire date - those cast the most specifict errors
+ CheckCertificateActivated(certificate);
+ CheckCertificateExpired(certificate);
- X509Chain chain = CreateChain(certificate);
+ X509Chain chain = CreateChain(certificate);
- //Modified chain validation of the certificate. We are not interested in Ctl lists
- foreach (X509ChainStatus status in chain.ChainStatus)
- {
- switch (status.Status)
+ //Modified chain validation of the certificate. We are not interested in Ctl lists
+ foreach (X509ChainStatus status in chain.ChainStatus)
{
- case X509ChainStatusFlags.CtlNotSignatureValid:
- case X509ChainStatusFlags.CtlNotTimeValid:
- case X509ChainStatusFlags.CtlNotValidForUsage:
- case X509ChainStatusFlags.NoError:
- case X509ChainStatusFlags.RevocationStatusUnknown:
- case X509ChainStatusFlags.OfflineRevocation:
- break;
- default:
- throw new CertificateFailedChainValidationException(status, certificate.Subject);
+ switch (status.Status)
+ {
+ case X509ChainStatusFlags.CtlNotSignatureValid:
+ case X509ChainStatusFlags.CtlNotTimeValid:
+ case X509ChainStatusFlags.CtlNotValidForUsage:
+ case X509ChainStatusFlags.NoError:
+ case X509ChainStatusFlags.RevocationStatusUnknown:
+ case X509ChainStatusFlags.OfflineRevocation:
+ break;
+ default:
+ throw new CertificateFailedChainValidationException(status, certificate.Subject);
+ }
}
}
+ catch (Exception ex)
+ {
+ ex.Data.Add("Certificate", certificate);
+ throw ex;
+ }
}
///
@@ -99,54 +106,61 @@ namespace dk.gov.oiosi.security.validation
/// that the root certificate exists in the certificate chain.
public static void ValidateCertificate(X509Certificate2 certificate, X509Certificate2 rootCertificate)
{
- CheckCertificateActivated(certificate);
- CheckCertificateExpired(certificate);
+ try
+ {
+ CheckCertificateActivated(certificate);
+ CheckCertificateExpired(certificate);
- X509Chain chain = CreateChain(certificate);
+ X509Chain chain = CreateChain(certificate);
- //Modified chain validation of the certificate. We are not interested in Ctl lists
- foreach (X509ChainStatus status in chain.ChainStatus)
- {
- switch (status.Status)
+ //Modified chain validation of the certificate. We are not interested in Ctl lists
+ foreach (X509ChainStatus status in chain.ChainStatus)
{
- case X509ChainStatusFlags.CtlNotSignatureValid:
- case X509ChainStatusFlags.CtlNotTimeValid:
- case X509ChainStatusFlags.CtlNotValidForUsage:
- case X509ChainStatusFlags.NoError:
- case X509ChainStatusFlags.RevocationStatusUnknown:
- case X509ChainStatusFlags.OfflineRevocation:
- break;
- default:
- throw new CertificateFailedChainValidationException(status, certificate.Subject);
+ switch (status.Status)
+ {
+ case X509ChainStatusFlags.CtlNotSignatureValid:
+ case X509ChainStatusFlags.CtlNotTimeValid:
+ case X509ChainStatusFlags.CtlNotValidForUsage:
+ case X509ChainStatusFlags.NoError:
+ case X509ChainStatusFlags.RevocationStatusUnknown:
+ case X509ChainStatusFlags.OfflineRevocation:
+ break;
+ default:
+ throw new CertificateFailedChainValidationException(status, certificate.Subject);
+ }
}
- }
- // Check if the certificate has the default root certificate as its root
- bool rootIsInChain = false;
- string rootThumbprint = rootCertificate.Thumbprint.ToLower();
+ // Check if the certificate has the default root certificate as its root
+ bool rootIsInChain = false;
+ string rootThumbprint = rootCertificate.Thumbprint.ToLower();
- if (certificate.Thumbprint.ToLower() != rootThumbprint)
- {
- foreach (X509ChainElement chainElem in chain.ChainElements)
+ if (certificate.Thumbprint.ToLower() != rootThumbprint)
{
- if (chainElem.Certificate.Thumbprint.ToLower() == rootThumbprint)
+ foreach (X509ChainElement chainElem in chain.ChainElements)
{
- rootIsInChain = true;
- break;
+ if (chainElem.Certificate.Thumbprint.ToLower() == rootThumbprint)
+ {
+ rootIsInChain = true;
+ break;
+ }
}
}
- }
- else
- {
- throw new CertificateFailedChainValidationException("The root certificate and certificate must be different", certificate.Subject);
- }
+ else
+ {
+ throw new CertificateFailedChainValidationException("The root certificate and certificate must be different", certificate.Subject);
+ }
- if (rootIsInChain == false)
+ if (rootIsInChain == false)
+ {
+ throw new CertificateFailedChainValidationException("The specified root certificate was not part of the certificate chain", certificate.Subject);
+ }
+ }
+ catch(Exception ex)
{
- throw new CertificateFailedChainValidationException("The specified root certificate was not part of the certificate chain", certificate.Subject);
+ ex.Data.Add("Certificate", certificate);
+ ex.Data.Add("RootCertificate", rootCertificate);
+ throw ex;
}
-
-
}
///
diff --git a/test/dk.gov.oiosi.test.unit/security/ldap/LdapCertificateLookupTest.cs b/test/dk.gov.oiosi.test.unit/security/ldap/LdapCertificateLookupTest.cs
index 3bcaf0435bb9f6750e9014e88d0d141b61138d2f..abfbdf0319626e70d5a65726932de2f057b65811 100644
--- a/test/dk.gov.oiosi.test.unit/security/ldap/LdapCertificateLookupTest.cs
+++ b/test/dk.gov.oiosi.test.unit/security/ldap/LdapCertificateLookupTest.cs
@@ -38,18 +38,28 @@ namespace dk.gov.oiosi.test.unit.security.ldap
}
[Test]
- [Ignore("Need ok certificate chain")]
public void TestLdapTestServerFoces2Subject()
{
- CertificateSubject certSubject = new CertificateSubject(TestConstants.TEST_CERTIFICATE_SUBJECT_FUNCTION);
-
var ldapCertificateLookup = new LdapCertificateLookup(this._ldapSettings);
- X509Certificate2 cert = ldapCertificateLookup.GetCertificate(certSubject);
+ var certSubject = new CertificateSubject(TestConstants.TEST_CERTIFICATE_SUBJECT_FUNCTION);
+
+ X509Certificate2 cert = null;
+
+ try
+ {
+ cert = ldapCertificateLookup.GetCertificate(certSubject);
+ }
+ catch (CertificateValidationException ex)
+ {
+ // We managed to connect and get a certificate. For some (possibly local) reason it didn't
+ // pass validation but that is not important for this test.
+ cert = (X509Certificate2)ex.Data["Certificate"];
+ }
// java: assertEquals("Wrong cert. found...", BigInteger.valueOf(1538079514), cert.getSerialNumber());
var expectedSerialNumber = new BigInteger("1538079514").ToString(16); // i.e. as hex-string
var actualSerialNumber = cert.GetSerialNumberString();
- Assert.AreEqual(expectedSerialNumber.ToUpperInvariant(), actualSerialNumber.ToUpperInvariant(),
+ Assert.AreEqual(expectedSerialNumber.ToUpperInvariant(), actualSerialNumber.ToUpperInvariant(),
message: "Wrong cert. found...");
// java: assertEquals("Wrong end date found...", "2022-12-16T14:31:07 UTC", DateUtil.formatDate(cert.getNotAfter()));
@@ -59,18 +69,28 @@ namespace dk.gov.oiosi.test.unit.security.ldap
}
[Test]
- [Ignore("Need ok certificate chain")]
public void TestGetMitIdCertificateFromTestLdap()
{
+ var ldapCertificateLookup = new LdapCertificateLookup(this._ldapSettings);
var certSubject = "C=DK, OID.2.5.4.97=NTRDK-90087822, O=Testorganisation nr. 90087822, SERIALNUMBER=UI:DK-8b230ff4-5f3d-4264-801a-7aac66bd51bd, CN=Nemhandel-DEV-OCES-cert-2";
- var ldapCertificateLookup = new LdapCertificateLookup(this._ldapSettings);
- X509Certificate2 cert = ldapCertificateLookup.GetCertificate(new CertificateSubject(certSubject));
+ X509Certificate2 cert = null;
+
+ try
+ {
+ cert = ldapCertificateLookup.GetCertificate(new CertificateSubject(certSubject));
+ }
+ catch (CertificateValidationException ex)
+ {
+ // We managed to connect and get a certificate. For some (possibly local) reason it didn't
+ // pass validation but that is not important for this test.
+ cert = (X509Certificate2)ex.Data["Certificate"];
+ }
// java: assertEquals("Wrong cert. found...", "344676415080031272949370873805706101461479077746", result.getSerialNumber().toString());
- var expectedSerialNumber = new BigInteger("3c5fd332f87ba522fd39e31ec5710d1009ec3772").ToString(16); // i.e. as hex-string
+ var expectedSerialNumber = new BigInteger("344676415080031272949370873805706101461479077746").ToString(16); // i.e. as hex-string
var actualSerialNumber = cert.GetSerialNumberString();
- Assert.AreEqual( expectedSerialNumber.ToUpperInvariant(), actualSerialNumber.ToUpperInvariant(),
+ Assert.AreEqual(expectedSerialNumber.ToUpperInvariant(), actualSerialNumber.ToUpperInvariant(),
message: "Wrong cert. found...");
// java: assertEquals("Wrong expire date found...", "2024-02-16T08:57:31 UTC", DateUtil.formatDate(result.getNotAfter()));