Skip to content

Commit 4f12737

Browse files
Fixing the validation of the SSL CA Certificate (#2346)
* Fixing the validation of the SSL CA Certificate * Update CachedSchemaRegistryClient.cs * Update RestService.cs --------- Co-authored-by: Daniel Bojczuk <[email protected]>
1 parent 74da56d commit 4f12737

File tree

2 files changed

+54
-18
lines changed

2 files changed

+54
-18
lines changed

src/Confluent.SchemaRegistry/CachedSchemaRegistryClient.cs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -351,8 +351,14 @@ public CachedSchemaRegistryClient(IEnumerable<KeyValuePair<string, string>> conf
351351
$"Configured value for {SchemaRegistryConfig.PropertyNames.EnableSslCertificateVerification} must be a bool.");
352352
}
353353

354-
this.restService = new RestService(schemaRegistryUris, timeoutMs, authenticationHeaderValueProvider,
355-
SetSslConfig(config), sslVerify);
354+
var sslCaLocation = config.FirstOrDefault(prop => prop.Key.ToLower() == SchemaRegistryConfig.PropertyNames.SslCaLocation).Value;
355+
if (string.IsNullOrEmpty(sslCaLocation))
356+
{
357+
this.restService = new RestService(schemaRegistryUris, timeoutMs, authenticationHeaderValueProvider, SetSslConfig(config), sslVerify);
358+
} else
359+
{
360+
this.restService = new RestService(schemaRegistryUris, timeoutMs, authenticationHeaderValueProvider, SetSslConfig(config), sslVerify, new X509Certificate2(sslCaLocation));
361+
}
356362
}
357363

358364
/// <summary>
@@ -408,14 +414,6 @@ private List<X509Certificate2> SetSslConfig(IEnumerable<KeyValuePair<string, str
408414
certificates.Add(new X509Certificate2(certificateLocation, certificatePassword));
409415
}
410416

411-
var caLocation =
412-
config.FirstOrDefault(prop => prop.Key.ToLower() == SchemaRegistryConfig.PropertyNames.SslCaLocation)
413-
.Value ?? "";
414-
if (!String.IsNullOrEmpty(caLocation))
415-
{
416-
certificates.Add(new X509Certificate2(caLocation));
417-
}
418-
419417
return certificates;
420418
}
421419

src/Confluent.SchemaRegistry/Rest/RestService.cs

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@
2222
using System.Net;
2323
using System.Net.Http;
2424
using System.Threading.Tasks;
25+
using X509Certificate2 = System.Security.Cryptography.X509Certificates.X509Certificate2;
26+
2527
using System.Security.Cryptography.X509Certificates;
28+
using System.Net.Security;
2629

2730
namespace Confluent.SchemaRegistry
2831
{
@@ -55,7 +58,7 @@ public class RestService : IRestService
5558
/// </summary>
5659
public RestService(string schemaRegistryUrl, int timeoutMs,
5760
IAuthenticationHeaderValueProvider authenticationHeaderValueProvider, List<X509Certificate2> certificates,
58-
bool enableSslCertificateVerification)
61+
bool enableSslCertificateVerification, X509Certificate2 sslCaCertificate = null)
5962
{
6063
this.authenticationHeaderValueProvider = authenticationHeaderValueProvider;
6164

@@ -67,7 +70,7 @@ public RestService(string schemaRegistryUrl, int timeoutMs,
6770
HttpClient client;
6871
if (certificates.Count > 0)
6972
{
70-
client = new HttpClient(CreateHandler(certificates, enableSslCertificateVerification))
73+
client = new HttpClient(CreateHandler(certificates, enableSslCertificateVerification, sslCaCertificate))
7174
{
7275
BaseAddress = new Uri(uri, UriKind.Absolute), Timeout = TimeSpan.FromMilliseconds(timeoutMs)
7376
};
@@ -92,19 +95,54 @@ private static string SanitizeUri(string uri)
9295
}
9396

9497
private static HttpClientHandler CreateHandler(List<X509Certificate2> certificates,
95-
bool enableSslCertificateVerification)
98+
bool enableSslCertificateVerification, X509Certificate2 sslCaCertificate)
9699
{
97100
var handler = new HttpClientHandler();
98101
handler.ClientCertificateOptions = ClientCertificateOption.Manual;
99102

103+
    certificates.ForEach(=> handler.ClientCertificates.Add(c));
104+
100105
if (!enableSslCertificateVerification)
101106
{
102-
handler.ServerCertificateCustomValidationCallback =
103-
(httpRequestMessage, cert, certChain, policyErrors) => { return true; };
104-
}
107+
handler.ServerCertificateCustomValidationCallback = (_, __, ___, ____) => { return true; };
108+
}
109+
else if (sslCaCertificate != null)
110+
{
111+
handler.ServerCertificateCustomValidationCallback = (_, __, chain, policyErrors) => {
112+
113+
if (policyErrors == SslPolicyErrors.None)
114+
{
115+
return true;
116+
}
117+
118+
119+
//The second element of the chain should be the issuer of the certificate
120+
if (chain.ChainElements.Count < 2)
121+
{
122+
return false;
123+
}
124+
var connectionCertHash = chain.ChainElements[1].Certificate.GetCertHash();
125+
126+
127+
var expectedCertHash = sslCaCertificate.GetCertHash();
105128

106-
certificates.ForEach(c => handler.ClientCertificates.Add(c));
107-
return handler;
129+
if (connectionCertHash.Length != expectedCertHash.Length)
130+
{
131+
return false;
132+
}
133+
134+
for (int i = 0; i < connectionCertHash.Length; i++)
135+
{
136+
if (connectionCertHash[i] != expectedCertHash[i])
137+
{
138+
return false;
139+
}
140+
}
141+
return true;
142+
};
143+
}
144+
145+
    return handler;
108146
}
109147

110148
private RegisteredSchema SanitizeRegisteredSchema(RegisteredSchema schema)

0 commit comments

Comments
 (0)