public void SetTransportOptions(TransportCustomizations customizations, string sessionId) { var timeoutSpan = TimeSpan.FromSeconds(600); // this will look a bit strange until we take care of #3488 due to the fact that this AllowAutoRedirect customizable from two places if (!string.IsNullOrWhiteSpace(sessionId)) { var customizedClientHandler = GetTransport(customizations.AllowAutoRedirect, customizations); RecordingSessions[sessionId].Client = new HttpClient(customizedClientHandler) { Timeout = timeoutSpan }; } else { // after #3488 we will swap to a single client instead of both of these var redirectableCustomizedHandler = GetTransport(true, customizations, Startup.Insecure); var redirectlessCustomizedHandler = GetTransport(false, customizations, Startup.Insecure); RedirectableClient = new HttpClient(redirectableCustomizedHandler) { Timeout = timeoutSpan }; RedirectlessClient = new HttpClient(redirectlessCustomizedHandler) { Timeout = timeoutSpan }; } }
public HttpClientHandler GetTransport(bool allowAutoRedirect, TransportCustomizations customizations, bool insecure = false) { var clientHandler = new HttpClientHandler() { AllowAutoRedirect = allowAutoRedirect }; if (customizations.Certificates != null) { foreach (var certPair in customizations.Certificates) { try { var cert = X509Certificate2.CreateFromPem(certPair.PemValue, certPair.PemKey); cert = new X509Certificate2(cert.Export(X509ContentType.Pfx)); clientHandler.ClientCertificates.Add(cert); } catch (Exception e) { throw new HttpException(HttpStatusCode.BadRequest, $"Unable to instantiate a new X509 certificate from the provided value and key. Failure Message: \"{e.Message}\"."); } } } if (customizations.TLSValidationCert != null && !insecure) { var ledgerCert = GetValidationCert(customizations); X509Chain certificateChain = new(); certificateChain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; certificateChain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot; certificateChain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority; certificateChain.ChainPolicy.VerificationTime = DateTime.Now; certificateChain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 0, 0); certificateChain.ChainPolicy.ExtraStore.Add(ledgerCert); clientHandler.ServerCertificateCustomValidationCallback = (HttpRequestMessage httpRequestMessage, X509Certificate2 cert, X509Chain x509Chain, SslPolicyErrors sslPolicyErrors) => { bool isChainValid = certificateChain.Build(cert); if (!isChainValid) { return(false); } var isCertSignedByTheTlsCert = certificateChain.ChainElements.Cast <X509ChainElement>() .Any(x => x.Certificate.Thumbprint == ledgerCert.Thumbprint); return(isCertSignedByTheTlsCert); }; } else if (insecure) { clientHandler.ServerCertificateCustomValidationCallback = (_, _, _, _) => true; } return(clientHandler); }
public X509Certificate2 GetValidationCert(TransportCustomizations settings) { try { var fields = PemEncoding.Find(settings.TLSValidationCert); var base64Data = settings.TLSValidationCert[fields.Base64Data]; return(new X509Certificate2(Encoding.ASCII.GetBytes(base64Data))); } catch (Exception e) { throw new HttpException(HttpStatusCode.BadRequest, $"Unable to instantiate a valid cert from the value provided in Transport settings key \"TLSValidationCert\". Value: \"{settings.TLSValidationCert}\". Message: \"{e.Message}\"."); } }