diff --git a/src/Security/Authentication/Certificate/ref/Microsoft.AspNetCore.Authentication.Certificate.netcoreapp.cs b/src/Security/Authentication/Certificate/ref/Microsoft.AspNetCore.Authentication.Certificate.netcoreapp.cs
index ecd78d5680..b158cdec1b 100644
--- a/src/Security/Authentication/Certificate/ref/Microsoft.AspNetCore.Authentication.Certificate.netcoreapp.cs
+++ b/src/Security/Authentication/Certificate/ref/Microsoft.AspNetCore.Authentication.Certificate.netcoreapp.cs
@@ -24,6 +24,8 @@ namespace Microsoft.AspNetCore.Authentication.Certificate
{
public CertificateAuthenticationOptions() { }
public Microsoft.AspNetCore.Authentication.Certificate.CertificateTypes AllowedCertificateTypes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
+ public System.Security.Cryptography.X509Certificates.X509ChainTrustMode ChainTrustValidationMode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
+ public System.Security.Cryptography.X509Certificates.X509Certificate2Collection CustomTrustStore { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
public new Microsoft.AspNetCore.Authentication.Certificate.CertificateAuthenticationEvents Events { get { throw null; } set { } }
public System.Security.Cryptography.X509Certificates.X509RevocationFlag RevocationFlag { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
public System.Security.Cryptography.X509Certificates.X509RevocationMode RevocationMode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
diff --git a/src/Security/Authentication/Certificate/src/CertificateAuthenticationHandler.cs b/src/Security/Authentication/Certificate/src/CertificateAuthenticationHandler.cs
index 68a7abdde0..a33b05ceb8 100644
--- a/src/Security/Authentication/Certificate/src/CertificateAuthenticationHandler.cs
+++ b/src/Security/Authentication/Certificate/src/CertificateAuthenticationHandler.cs
@@ -167,6 +167,15 @@ namespace Microsoft.AspNetCore.Authentication.Certificate
chainPolicy.VerificationFlags |= X509VerificationFlags.IgnoreEndRevocationUnknown;
chainPolicy.ExtraStore.Add(certificate);
}
+ else
+ {
+ if (Options.CustomTrustStore != null)
+ {
+ chainPolicy.CustomTrustStore.AddRange(Options.CustomTrustStore);
+ }
+
+ chainPolicy.TrustMode = Options.ChainTrustValidationMode;
+ }
if (!Options.ValidateValidityPeriod)
{
diff --git a/src/Security/Authentication/Certificate/src/CertificateAuthenticationOptions.cs b/src/Security/Authentication/Certificate/src/CertificateAuthenticationOptions.cs
index 1b8eebfa6f..70789514ac 100644
--- a/src/Security/Authentication/Certificate/src/CertificateAuthenticationOptions.cs
+++ b/src/Security/Authentication/Certificate/src/CertificateAuthenticationOptions.cs
@@ -15,10 +15,21 @@ namespace Microsoft.AspNetCore.Authentication.Certificate
///
public CertificateTypes AllowedCertificateTypes { get; set; } = CertificateTypes.Chained;
+ ///
+ /// Collection of X509 certificates which are trusted components of the certificate chain.
+ ///
+ public X509Certificate2Collection CustomTrustStore { get; set; } = new X509Certificate2Collection();
+
+ ///
+ /// Method used to validate certificate chains against .
+ ///
+ /// This property must be set to to enable to be used in certificate chain validation.
+ public X509ChainTrustMode ChainTrustValidationMode { get; set; } = X509ChainTrustMode.System;
+
///
/// Flag indicating whether the client certificate must be suitable for client
/// authentication, either via the Client Authentication EKU, or having no EKUs
- /// at all. If the certificate chains to a root CA all certificates in the chain must be validate
+ /// at all. If the certificate chains to a root CA all certificates in the chain must be validated
/// for the client authentication EKU.
///
public bool ValidateCertificateUse { get; set; } = true;
diff --git a/src/Security/Authentication/test/CertificateTests.cs b/src/Security/Authentication/test/CertificateTests.cs
index 1ff4ffa58a..bd395c33ff 100644
--- a/src/Security/Authentication/test/CertificateTests.cs
+++ b/src/Security/Authentication/test/CertificateTests.cs
@@ -255,6 +255,51 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);
}
+ [Fact]
+ public async Task VerifyUntrustedClientCertEndsUpInForbidden()
+ {
+ var server = CreateServer(
+ new CertificateAuthenticationOptions
+ {
+ Events = successfulValidationEvents
+ }, Certificates.SignedClient);
+
+ var response = await server.CreateClient().GetAsync("https://example.com/");
+ Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);
+ }
+
+ [Fact]
+ public async Task VerifyClientCertWithUntrustedRootAndTrustedChainEndsUpInForbidden()
+ {
+ var server = CreateServer(
+ new CertificateAuthenticationOptions
+ {
+ Events = successfulValidationEvents,
+ CustomTrustStore = new X509Certificate2Collection() { Certificates.SignedSecondaryRoot },
+ ChainTrustValidationMode = X509ChainTrustMode.CustomRootTrust,
+ RevocationMode = X509RevocationMode.NoCheck
+ }, Certificates.SignedClient);
+
+ var response = await server.CreateClient().GetAsync("https://example.com/");
+ Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);
+ }
+
+ [Fact]
+ public async Task VerifyValidClientCertWithTrustedChainAuthenticates()
+ {
+ var server = CreateServer(
+ new CertificateAuthenticationOptions
+ {
+ Events = successfulValidationEvents,
+ CustomTrustStore = new X509Certificate2Collection() { Certificates.SelfSignedPrimaryRoot, Certificates.SignedSecondaryRoot },
+ ChainTrustValidationMode = X509ChainTrustMode.CustomRootTrust,
+ RevocationMode = X509RevocationMode.NoCheck
+ }, Certificates.SignedClient);
+
+ var response = await server.CreateClient().GetAsync("https://example.com/");
+ Assert.Equal(HttpStatusCode.OK, response.StatusCode);
+ }
+
[Fact]
public async Task VerifyHeaderIsUsedIfCertIsNotPresent()
{
@@ -534,11 +579,13 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
{
services.AddAuthentication(CertificateAuthenticationDefaults.AuthenticationScheme).AddCertificate(options =>
{
+ options.CustomTrustStore = configureOptions.CustomTrustStore;
+ options.ChainTrustValidationMode = configureOptions.ChainTrustValidationMode;
options.AllowedCertificateTypes = configureOptions.AllowedCertificateTypes;
options.Events = configureOptions.Events;
options.ValidateCertificateUse = configureOptions.ValidateCertificateUse;
- options.RevocationFlag = options.RevocationFlag;
- options.RevocationMode = options.RevocationMode;
+ options.RevocationFlag = configureOptions.RevocationFlag;
+ options.RevocationMode = configureOptions.RevocationMode;
options.ValidateValidityPeriod = configureOptions.ValidateValidityPeriod;
});
}
@@ -599,6 +646,15 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
private static class Certificates
{
+ public static X509Certificate2 SelfSignedPrimaryRoot { get; private set; } =
+ new X509Certificate2(GetFullyQualifiedFilePath("validSelfSignedPrimaryRootCertificate.cer"));
+
+ public static X509Certificate2 SignedSecondaryRoot { get; private set; } =
+ new X509Certificate2(GetFullyQualifiedFilePath("validSignedSecondaryRootCertificate.cer"));
+
+ public static X509Certificate2 SignedClient { get; private set; } =
+ new X509Certificate2(GetFullyQualifiedFilePath("validSignedClientCertificate.cer"));
+
public static X509Certificate2 SelfSignedValidWithClientEku { get; private set; } =
new X509Certificate2(GetFullyQualifiedFilePath("validSelfSignedClientEkuCertificate.cer"));
@@ -626,3 +682,4 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
}
}
}
+
diff --git a/src/Security/Authentication/test/TestCertificates/validSelfSignedPrimaryRootCertificate.cer b/src/Security/Authentication/test/TestCertificates/validSelfSignedPrimaryRootCertificate.cer
new file mode 100644
index 0000000000..a7420c8493
--- /dev/null
+++ b/src/Security/Authentication/test/TestCertificates/validSelfSignedPrimaryRootCertificate.cer
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDPTCCAiWgAwIBAgIQTmWeCzG8SbRJ0y+osLWwDjANBgkqhkiG9w0BAQsFADAp
+MScwJQYDVQQDDB5WYWxpZCBTZWxmIFNpZ25lZCBQcmltYXJ5IFJvb3QwHhcNMjAw
+MTIxMDAwMDAwWhcNNDUwMTIxMDAwMDAwWjApMScwJQYDVQQDDB5WYWxpZCBTZWxm
+IFNpZ25lZCBQcmltYXJ5IFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
+AoIBAQDMK6v6HsJ19iRlXIRQVBJiy9xnJWBddLjm+2RRkyiiffEitBExiXVyrQ8L
+DlegQQH3oJR0xgXwisJctjpHHz54dfbw5LwC9j9EVtu/UgDgK4lo6X3WLNYMJ1pX
+xxjGfXcyzGGhcI0KATlyWhWgOrZNFzE+v0KY/LtZvcZ290Y4X7MQLge+V/09Lohx
+pj6vsHkpoK8tD8ksJp+O8jk45TXTxs4yo8BRXbIv0oMmuZ9+gVkiaGurCCe/o+nw
+vjEQre9oKNFI9KOgen6l1152BVQaXMDd22vemGIz738Scl9kcBQhy1D0dPuL6QV3
+rR8HoNG3i0cuYxB4xgFF5GY2fhQBAgMBAAGjYTBfMA4GA1UdDwEB/wQEAwIBhjAd
+BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDwYDVR0TAQH/BAUwAwEB/zAd
+BgNVHQ4EFgQU/cAC4CkVEtEj2UCYMVS/mlFCdBAwDQYJKoZIhvcNAQELBQADggEB
+AInTuEG8Kv2aWy7MJg/N/AvEmC7USMgTceFY+bKhVogYCE9m2VAa4Tz5DEEJwYQV
+IBnEamQN1eWP/R7dxcg+gIck8TevZC6r7wKMUATCcn9Ti0I0Hxdplts9+YIksJJ7
+GbgyPS3UWnXl2D0374KrqTKSRjEXPOzaNyJ0HB4Pr9bibuSZ6Qc0gSltz7xOPFYS
+7cedTqpABJXF6hZM7tDsxPfXmBHDy2sU84yXTQQghmU5S7fLWgy3so4g/DUqxffS
+hmYPagc9DsmRGc2CCZz8IHlVc7byZ/NF4FgqB3IATbqYBAw4S/RyKHfWpURie2hC
+OtYLcOTzVJG4uD3FGxyXP1k=
+-----END CERTIFICATE-----
diff --git a/src/Security/Authentication/test/TestCertificates/validSignedClientCertificate.cer b/src/Security/Authentication/test/TestCertificates/validSignedClientCertificate.cer
new file mode 100644
index 0000000000..a8034b05a8
--- /dev/null
+++ b/src/Security/Authentication/test/TestCertificates/validSignedClientCertificate.cer
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDTTCCAjWgAwIBAgIQaaZ/qIdm4K5JhFdDzzj53DANBgkqhkiG9w0BAQsFADAm
+MSQwIgYDVQQDDBtWYWxpZCBTaWduZWQgU2Vjb25kYXJ5IFJvb3QwHhcNMjAwMTIx
+MDAwMDAwWhcNMjIwMTIxMDAwMDAwWjAeMRwwGgYDVQQDDBNWYWxpZCBTaWduZWQg
+Q2xpZW50MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu3dVA8q1GewW
+i1K0Pw0gKqgv92RrX3JI6tTiLbU6FBpFdV63b1M3jgFhUSXJi7L8A/dxh2HwvKBJ
+p+4KW7V+aXQXOY8iShQwrIud5IExFdtEjyGVtfFSvfYmDgbfjFKIGswxsLenlfEt
+7mp303GH99JVFql1n7S+bib79vKkrjFBqixhnXisXjNlBlfH6kRBYiwQ1Gc5oyib
+fZQkfakXo896UwIvQjc0W27c0tiGY6xyGLSesLih2yECADiGa+cc5rnRc7R9/IMB
+N7o5gLpbe71WBopI1uq1VSuXwH9xy0bq307dZEMaX0b4SqhkuQHsBVtOV1mYAskE
+K3W8VUZy7QIDAQABo38wfTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYB
+BQUHAwEGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUx9BZtKX7
+/z2mmoO2Ec127GkibsAwHQYDVR0OBBYEFDmtlIR/fVwtDseOG/NNQ/QEv3/PMA0G
+CSqGSIb3DQEBCwUAA4IBAQBQMhsmlwF5JKEkfay7uLCH9IrJZGk1ZDxK/qcVaOk5
+mQ4IcCBq+Wp7Hg/D92b5diwlkXJDrYZZ7OHSEcD/PrxUKyZkoBQIvlNKDgmjp0wV
+lXYUISZHaXbWZ0XNFAS0KyqoLZ8c2xmhuI21L3hyOoRcoqKleO1kzYfb2seBaRHk
+Iu4la0opKGFoI/o7gC9uLrcizpj3SoPF9+vJz/FJmeBbKzKe1zA479a74tjfOODy
+LZVbsGDhKRQ02GftFqXRl257hVX+6etQiOePj7S++R1B/QXRjvKrOTMs/NpMLAeK
+8uWXSx+boL/8j/3u+65Udh614C5dXSrgDjMGJ7/OchC1
+-----END CERTIFICATE-----
diff --git a/src/Security/Authentication/test/TestCertificates/validSignedSecondaryRootCertificate.cer b/src/Security/Authentication/test/TestCertificates/validSignedSecondaryRootCertificate.cer
new file mode 100644
index 0000000000..ef31f31a98
--- /dev/null
+++ b/src/Security/Authentication/test/TestCertificates/validSignedSecondaryRootCertificate.cer
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIDXTCCAkWgAwIBAgIQE2HFYAdh7b5NSBsomRG9cjANBgkqhkiG9w0BAQsFADAp
+MScwJQYDVQQDDB5WYWxpZCBTZWxmIFNpZ25lZCBQcmltYXJ5IFJvb3QwHhcNMjAw
+MTIxMDAwMDAwWhcNMzUwMTIxMDAwMDAwWjAmMSQwIgYDVQQDDBtWYWxpZCBTaWdu
+ZWQgU2Vjb25kYXJ5IFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
+AQCw1Wvr8SeMdXM0ZMN3/NyZhGzXC/IcqJyI1tM1IQNpO9OxJWDkfxGh14ORRZ3f
+4pTdXOXRCcPYxHk8d3kuH9EEo78WRrLV4XHw31vGrQkHAPn3ZMl/Qre1mYvzkKbn
+DIpScfPYMuqydOvx1YSsTP2G37pNszOAXTkHPPH9smTo/W7Dv/1mnroAru/FU+Hv
+zOMqNirIz1EpCEopLeBS41lcohyuCMzHPKJJZOnNbV3wV3AnpEriRLQVNO9WiaGs
+Nwj8ffai9M4vncRQ9wLK866lx6iA7istjod9hourKQWC1284pv+RLtIeJaGrpXkV
+mSbk9ebabz1fPC2/WgPtd1JVAgMBAAGjgYMwgYAwDgYDVR0PAQH/BAQDAgGGMB0G
+A1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAPBgNVHRMBAf8EBTADAQH/MB8G
+A1UdIwQYMBaAFP3AAuApFRLRI9lAmDFUv5pRQnQQMB0GA1UdDgQWBBTH0Fm0pfv/
+Paaag7YRzXbsaSJuwDANBgkqhkiG9w0BAQsFAAOCAQEAT5fEUkVP3Allay2ODcjQ
+GzM135mV718DS84B4bVDBWr+CW9i89bzYgRZgClTABqddotHEqmLEan/bV4suBSt
+QuACy7m39Q8kj/S/ydBhvHx9fxqWnAsacQ+fuAPviBQ11UZB19zWj1zikw1/Xfow
+V9OIf4gYtY2aBPyygWN3HwpszhJWQIuFGl4rwqAxli7Wp2eUBXxDtYBHAscsclG4
+1rduhiV5eUZXZ11mbA7KBH9XwWKoFpRza049I0WC+V0PWqlK4H4P0QzCWUlXmTC8
+kN04cnPtyciOlP9J3Uro5xTXaDC0Cge82JmRxnCovGKGBEdjIxMC4nbPB4emmcth
+BA==
+-----END CERTIFICATE-----
diff --git a/src/Shared/test/Certificates/validSelfSignedPrimaryRootCertificate.cer b/src/Shared/test/Certificates/validSelfSignedPrimaryRootCertificate.cer
new file mode 100644
index 0000000000..a7420c8493
--- /dev/null
+++ b/src/Shared/test/Certificates/validSelfSignedPrimaryRootCertificate.cer
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDPTCCAiWgAwIBAgIQTmWeCzG8SbRJ0y+osLWwDjANBgkqhkiG9w0BAQsFADAp
+MScwJQYDVQQDDB5WYWxpZCBTZWxmIFNpZ25lZCBQcmltYXJ5IFJvb3QwHhcNMjAw
+MTIxMDAwMDAwWhcNNDUwMTIxMDAwMDAwWjApMScwJQYDVQQDDB5WYWxpZCBTZWxm
+IFNpZ25lZCBQcmltYXJ5IFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
+AoIBAQDMK6v6HsJ19iRlXIRQVBJiy9xnJWBddLjm+2RRkyiiffEitBExiXVyrQ8L
+DlegQQH3oJR0xgXwisJctjpHHz54dfbw5LwC9j9EVtu/UgDgK4lo6X3WLNYMJ1pX
+xxjGfXcyzGGhcI0KATlyWhWgOrZNFzE+v0KY/LtZvcZ290Y4X7MQLge+V/09Lohx
+pj6vsHkpoK8tD8ksJp+O8jk45TXTxs4yo8BRXbIv0oMmuZ9+gVkiaGurCCe/o+nw
+vjEQre9oKNFI9KOgen6l1152BVQaXMDd22vemGIz738Scl9kcBQhy1D0dPuL6QV3
+rR8HoNG3i0cuYxB4xgFF5GY2fhQBAgMBAAGjYTBfMA4GA1UdDwEB/wQEAwIBhjAd
+BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDwYDVR0TAQH/BAUwAwEB/zAd
+BgNVHQ4EFgQU/cAC4CkVEtEj2UCYMVS/mlFCdBAwDQYJKoZIhvcNAQELBQADggEB
+AInTuEG8Kv2aWy7MJg/N/AvEmC7USMgTceFY+bKhVogYCE9m2VAa4Tz5DEEJwYQV
+IBnEamQN1eWP/R7dxcg+gIck8TevZC6r7wKMUATCcn9Ti0I0Hxdplts9+YIksJJ7
+GbgyPS3UWnXl2D0374KrqTKSRjEXPOzaNyJ0HB4Pr9bibuSZ6Qc0gSltz7xOPFYS
+7cedTqpABJXF6hZM7tDsxPfXmBHDy2sU84yXTQQghmU5S7fLWgy3so4g/DUqxffS
+hmYPagc9DsmRGc2CCZz8IHlVc7byZ/NF4FgqB3IATbqYBAw4S/RyKHfWpURie2hC
+OtYLcOTzVJG4uD3FGxyXP1k=
+-----END CERTIFICATE-----
diff --git a/src/Shared/test/Certificates/validSignedClientCertificate.cer b/src/Shared/test/Certificates/validSignedClientCertificate.cer
new file mode 100644
index 0000000000..a8034b05a8
--- /dev/null
+++ b/src/Shared/test/Certificates/validSignedClientCertificate.cer
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDTTCCAjWgAwIBAgIQaaZ/qIdm4K5JhFdDzzj53DANBgkqhkiG9w0BAQsFADAm
+MSQwIgYDVQQDDBtWYWxpZCBTaWduZWQgU2Vjb25kYXJ5IFJvb3QwHhcNMjAwMTIx
+MDAwMDAwWhcNMjIwMTIxMDAwMDAwWjAeMRwwGgYDVQQDDBNWYWxpZCBTaWduZWQg
+Q2xpZW50MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu3dVA8q1GewW
+i1K0Pw0gKqgv92RrX3JI6tTiLbU6FBpFdV63b1M3jgFhUSXJi7L8A/dxh2HwvKBJ
+p+4KW7V+aXQXOY8iShQwrIud5IExFdtEjyGVtfFSvfYmDgbfjFKIGswxsLenlfEt
+7mp303GH99JVFql1n7S+bib79vKkrjFBqixhnXisXjNlBlfH6kRBYiwQ1Gc5oyib
+fZQkfakXo896UwIvQjc0W27c0tiGY6xyGLSesLih2yECADiGa+cc5rnRc7R9/IMB
+N7o5gLpbe71WBopI1uq1VSuXwH9xy0bq307dZEMaX0b4SqhkuQHsBVtOV1mYAskE
+K3W8VUZy7QIDAQABo38wfTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYB
+BQUHAwEGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUx9BZtKX7
+/z2mmoO2Ec127GkibsAwHQYDVR0OBBYEFDmtlIR/fVwtDseOG/NNQ/QEv3/PMA0G
+CSqGSIb3DQEBCwUAA4IBAQBQMhsmlwF5JKEkfay7uLCH9IrJZGk1ZDxK/qcVaOk5
+mQ4IcCBq+Wp7Hg/D92b5diwlkXJDrYZZ7OHSEcD/PrxUKyZkoBQIvlNKDgmjp0wV
+lXYUISZHaXbWZ0XNFAS0KyqoLZ8c2xmhuI21L3hyOoRcoqKleO1kzYfb2seBaRHk
+Iu4la0opKGFoI/o7gC9uLrcizpj3SoPF9+vJz/FJmeBbKzKe1zA479a74tjfOODy
+LZVbsGDhKRQ02GftFqXRl257hVX+6etQiOePj7S++R1B/QXRjvKrOTMs/NpMLAeK
+8uWXSx+boL/8j/3u+65Udh614C5dXSrgDjMGJ7/OchC1
+-----END CERTIFICATE-----
diff --git a/src/Shared/test/Certificates/validSignedSecondaryRootCertificate.cer b/src/Shared/test/Certificates/validSignedSecondaryRootCertificate.cer
new file mode 100644
index 0000000000..ef31f31a98
--- /dev/null
+++ b/src/Shared/test/Certificates/validSignedSecondaryRootCertificate.cer
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIDXTCCAkWgAwIBAgIQE2HFYAdh7b5NSBsomRG9cjANBgkqhkiG9w0BAQsFADAp
+MScwJQYDVQQDDB5WYWxpZCBTZWxmIFNpZ25lZCBQcmltYXJ5IFJvb3QwHhcNMjAw
+MTIxMDAwMDAwWhcNMzUwMTIxMDAwMDAwWjAmMSQwIgYDVQQDDBtWYWxpZCBTaWdu
+ZWQgU2Vjb25kYXJ5IFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
+AQCw1Wvr8SeMdXM0ZMN3/NyZhGzXC/IcqJyI1tM1IQNpO9OxJWDkfxGh14ORRZ3f
+4pTdXOXRCcPYxHk8d3kuH9EEo78WRrLV4XHw31vGrQkHAPn3ZMl/Qre1mYvzkKbn
+DIpScfPYMuqydOvx1YSsTP2G37pNszOAXTkHPPH9smTo/W7Dv/1mnroAru/FU+Hv
+zOMqNirIz1EpCEopLeBS41lcohyuCMzHPKJJZOnNbV3wV3AnpEriRLQVNO9WiaGs
+Nwj8ffai9M4vncRQ9wLK866lx6iA7istjod9hourKQWC1284pv+RLtIeJaGrpXkV
+mSbk9ebabz1fPC2/WgPtd1JVAgMBAAGjgYMwgYAwDgYDVR0PAQH/BAQDAgGGMB0G
+A1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAPBgNVHRMBAf8EBTADAQH/MB8G
+A1UdIwQYMBaAFP3AAuApFRLRI9lAmDFUv5pRQnQQMB0GA1UdDgQWBBTH0Fm0pfv/
+Paaag7YRzXbsaSJuwDANBgkqhkiG9w0BAQsFAAOCAQEAT5fEUkVP3Allay2ODcjQ
+GzM135mV718DS84B4bVDBWr+CW9i89bzYgRZgClTABqddotHEqmLEan/bV4suBSt
+QuACy7m39Q8kj/S/ydBhvHx9fxqWnAsacQ+fuAPviBQ11UZB19zWj1zikw1/Xfow
+V9OIf4gYtY2aBPyygWN3HwpszhJWQIuFGl4rwqAxli7Wp2eUBXxDtYBHAscsclG4
+1rduhiV5eUZXZ11mbA7KBH9XwWKoFpRza049I0WC+V0PWqlK4H4P0QzCWUlXmTC8
+kN04cnPtyciOlP9J3Uro5xTXaDC0Cge82JmRxnCovGKGBEdjIxMC4nbPB4emmcth
+BA==
+-----END CERTIFICATE-----