|
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