|
4 | 4 | using System.Linq;
|
5 | 5 | using System.Threading.Tasks;
|
6 | 6 | using System.Security.Cryptography.X509Certificates;
|
| 7 | +using System.Net.Security; |
7 | 8 |
|
8 | 9 | using Google.Protobuf.WellKnownTypes;
|
9 | 10 | using Grpc.Core;
|
@@ -539,30 +540,49 @@ private Service.ServiceClient BuildClientForPlatform(Uri url)
|
539 | 540 |
|
540 | 541 | if (!useUnixSocket)
|
541 | 542 | {
|
542 |
| -#if NET462 |
| 543 | +#if NET462_OR_GREATER |
543 | 544 | var handler = new WinHttpHandler();
|
544 | 545 | #else
|
545 | 546 | var handler = new HttpClientHandler();
|
546 | 547 | #endif
|
547 | 548 | if (_config.UseCertificate)
|
548 | 549 | {
|
549 |
| -#if NET5_0_OR_GREATER |
550 |
| - if (File.Exists(_config.CertificatePath)) { |
| 550 | + if (File.Exists(_config.CertificatePath)) |
| 551 | + { |
551 | 552 | X509Certificate2 certificate = new X509Certificate2(_config.CertificatePath);
|
| 553 | +#if NET5_0_OR_GREATER |
552 | 554 | handler.ServerCertificateCustomValidationCallback = (message, cert, chain, _) => {
|
553 | 555 | // the the custom cert to the chain, Build returns a bool if valid.
|
554 | 556 | chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust;
|
555 | 557 | chain.ChainPolicy.CustomTrustStore.Add(certificate);
|
556 | 558 | return chain.Build(cert);
|
557 | 559 | };
|
558 |
| - } else { |
559 |
| - throw new ArgumentException("Specified certificate cannot be found."); |
560 |
| - } |
| 560 | +#elif NET462_OR_GREATER |
| 561 | + handler.ServerCertificateValidationCallback = (message, cert, chain, errors) => { |
| 562 | + if (errors == SslPolicyErrors.None) { return true; } |
| 563 | + |
| 564 | + chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority; |
| 565 | + |
| 566 | + chain.ChainPolicy.ExtraStore.Add(certificate); |
| 567 | + |
| 568 | + var isChainValid = chain.Build(cert); |
| 569 | + |
| 570 | + if (!isChainValid) { return false; } |
| 571 | + |
| 572 | + var isValid = chain.ChainElements |
| 573 | + .Cast<X509ChainElement>() |
| 574 | + .Any(x => x.Certificate.RawData.SequenceEqual(certificate.GetRawCertData())); |
| 575 | + |
| 576 | + return isValid; |
| 577 | + }; |
561 | 578 | #else
|
562 |
| - // Pre-NET5.0 APIs for custom CA validation are cumbersome. |
563 |
| - // Looking for additional contributions here. |
564 |
| - throw new ArgumentException("Custom certificate authorities not supported on this platform."); |
| 579 | + throw new ArgumentException("Custom Certificates are not supported on your platform"); |
565 | 580 | #endif
|
| 581 | + } |
| 582 | + else |
| 583 | + { |
| 584 | + throw new ArgumentException("Specified certificate cannot be found."); |
| 585 | + } |
566 | 586 | }
|
567 | 587 | return new Service.ServiceClient(GrpcChannel.ForAddress(url, new GrpcChannelOptions
|
568 | 588 | {
|
|
0 commit comments