HTTPS REST request viaproxy using "System.Net.WebClient

Posted by cSocaciu on 12-Jul-2017 11:38

Hello All,

I'm using OE 1.5.1. 

I need to get the data from a rest service that that uses https. 

USING System.*. 

DEFINE VARIABLE HttpClient      AS CLASS System.Net.WebClient. 
DEFINE VARIABLE webResponse AS LONGCHAR NO-UNDO. 
FIX-CODEPAGE (webResponse) = "UTF-8". 

HttpClient = NEW System.Net.WebClient(). 
HttpClient:Proxy:Credentials = System.Net.CredentialCache:DefaultNetworkCredentials.

/* call CashPro Flow - guaranteed FX Rates REST API*/
webResponse = HttpClient:DownloadString("SomeCompanyURL/.../10").

HttpClient:Dispose(). 
DELETE OBJECT HttpClient. 

/* save as local file*/
COPY-LOB FROM webResponse  TO FILE ('c:/temp/webResponse.txt') NO-CONVERT.

I get the following error: "System.Net.WebException: The request was aborted: Could not create SSL/TLS secure channel."

I have received a certificate and a password certificate from the company and imported that certificate into "Trusted root certification authorities".

Using the export option I have exported all the required certificates in the certificate chain and imported them via "certutil" utility in the OpenEdge certs folder.
When I enter the same URL in my browser I'm able to see the requested data. If I make a call to another https rest service from openedge I can download the data "webResponse = HttpClient:DownloadString("https://postman-echo.com/time/now")."

Can anyone give me some suggestions on how to debug the SSL connection?
I have tried Fiddler with no success.
I cannot "openssl s_client connect" because I'm behind a corporate proxy that requires NTLM authorization.
I can only access this https URL from a determined list of Ip addresses all within the corporate network.

Any help is greatly appreciated!

All Replies

Posted by garansysarno on 12-Jul-2017 11:46

Probably the service is TLS 1.1. or higer. Only from 11.6+ TLS 1.1 and higher are supported. See knowledgebase.progress.com/.../What-version-of-SSL-and-or-TLS-does-Progress-OpenEdge-use

Posted by tbergman on 12-Jul-2017 12:05

The problem may be that the system you're talking to requires a higher lever of SSL (TLS) than is supported by the WebClient by default

When using System.Net.WebClient, code similar to the following is needed to enable higher levels of TLS.

Note that this change is global to your session so could possibly impact other uses of WebClient in your session.

The code below should work in 11.5. In 11.6 it can be simplified because of the built in support for enums.


DEFINE VARIABLE protocolType AS System.Net.SecurityProtocolType NO-UNDO.  

    protocolType = CAST(
      Progress.Util.EnumHelper:Or(
      System.Net.SecurityProtocolType:Tls12, System.Net.SecurityProtocolType:Tls11),
      System.Net.SecurityProtocolType).
    protocolType = CAST(
      Progress.Util.EnumHelper:Or(protocolType, System.Net.SecurityProtocolType:Tls),
      System.Net.SecurityProtocolType).
    System.Net.ServicePointManager:SecurityProtocol = protocolType.
     

Posted by cSocaciu on 12-Jul-2017 12:31

The connection information displayed by the Chrome browser are this.

Your connection to "company-endpoint.url" is encrypted with 256-bit encryption.
The connection uses TLS 1.2
The connection is encrypted using AES_256_CBC with SHA1 for message Authentication and RSA as the key exchange mechanism.

Setting the "System.Net.ServicePointManager:SecurityProtocol" to Tls12 does not help I get the same error.

I've also tried the same code posted in the first post using OpenEdge 11.7 and I'm getting the same error.

Posted by tbergman on 12-Jul-2017 13:24

When using System.Net.WebClient, the Progress version, Progress certificate cache and the use of Certutil are irrelevant.

In my experience, if you can get to the site using IE, you should be able to get to it using WebClient. The same may be true when using Chrome but I'm less certain of this. While using IE, it might be worth adjusting the TLS options under Internet Options/Advanced to see what's actually required for the site. If you can connect with only TLS1.2 enabled, then the same should be true in the WebClient. If not, you may need to enable more than one TLS version as shown in the code I sent. When testing with IE, be sure to clear the cache between tests.

I'm not at all sure what, if any, impact the proxy might have on all this.

Posted by cSocaciu on 12-Jul-2017 14:56

Thank you confirming that "System.Net.WebClient" does not use Openedge certificate store. The main challenge is how to figure what the problem is since While using IE I can also access REST endpoint URL.

Posted by cSocaciu on 27-Jul-2017 10:14

Hello,

I'm using OpenEdge 11.7  in order to test an https connection using OpenEdge.Net library.

Here is the code:

USING OpenEdge.Net.HTTP.IHttpRequest.
USING OpenEdge.Net.HTTP.IHttpResponse.
USING OpenEdge.Net.HTTP.ClientBuilder.
USING OpenEdge.Net.HTTP.IHttpClientLibrary.
USING OpenEdge.Net.HTTP.lib.ClientLibraryBuilder.
USING OpenEdge.Net.HTTP.RequestBuilder.
using OpenEdge.Net.HTTP.Cookie.
using OpenEdge.Net.URI.

DEFINE VARIABLE oLib        AS OpenEdge.Net.HTTP.IHttpClientLibrary NO-UNDO.
DEFINE VARIABLE oHttpClient AS OpenEdge.Net.HTTP.IHttpClient        NO-UNDO.
DEFINE VARIABLE oRequest    AS IHttpRequest                         NO-UNDO.
DEFINE VARIABLE oResponse   AS IHttpResponse                        NO-UNDO.
DEFINE VARIABLE oUri        AS URI                                  NO-UNDO.

DEFINE VARIABLE cAuth AS CHARACTER NO-UNDO.

LOG-MANAGER:logfile-name = 'mylog1.log'.
LOG-MANAGER:logging-level = 6.
MESSAGE "session:temp-dir" SESSION:TEMP-DIR VIEW-AS ALERT-BOX.


ASSIGN oUri = new URI('http', 'appproxy.bank.com', 8080).

ASSIGN
     oLib        = ClientLibraryBuilder:Build():sslVerifyHost(NO):library
     oHttpClient = ClientBuilder:Build():UsingLibrary(oLib):Client
     oRequest    = RequestBuilder:Get("https://registry.npmjs.org"):AddHeader("Proxy-Connection", 'Keep-Alive'):ViaProxy(oUri):Request
     oResponse   = oHttpClient:Execute(oRequest).


MESSAGE /*got 407 Proxy Authentication Required*/
    oResponse:StatusCode SKIP   
    oResponse:StatusReason SKIP
   VIEW-AS ALERT-BOX.

cAuth = "Basic base64_encoded_user:password".
oRequest    = RequestBuilder:Get("https://registry.npmjs.org/")
                                           :AddHeader("Proxy-Connection", 'Keep-Alive')
                                           :AddHeader("Proxy-Authorization", cAuth)
                                           :AddHeader("Accept-Encoding", "gzip,deflate")
                                           :AddHeader("Connection", "Keep-Alive")
                                           :ViaProxy(oUri):Request.

oResponse   = oHttpClient:Execute(oRequest).


MESSAGE /* got 400  bad request */
    oResponse:StatusCode SKIP   
    oResponse:StatusReason SKIP
    oResponse:ContentType SKIP
    oResponse:GetHeader("Set-Cookie")
    STRING(oResponse:Entity)   /* this is the response */
    VIEW-AS ALERT-BOX. 

CATCH oError as Progress.Lang.Error :
    MESSAGE  "Progress.Lang.Error " SKIP 
        oError:GetMessage(1) SKIP(2)
        oError:CallStack
    VIEW-AS ALERT-BOX.		
END CATCH. 



The raw request looks like this.

GET https://registry.npmjs.org/ HTTP/1.1

User-Agent: OpenEdge-HttpClient/0.4.0 (WIN32/32) OpenEdge/11.7.0.0.1388 Lib-ABLSockets/0.4.0

Proxy-Connection: Keep-Alive

Proxy-Authorization: Basic base64_encoded_user:password

Host: registry.npmjs.org

Connection: Keep-Alive

Accept: */*

Accept-Encoding: gzip,deflate

Using the same code to make an HTTP request works. Does anyone have any idea why is not working?

I've tried with curl (openSSL 1.1.0f) to get the data from the same endpoint and I get a response back.

Can anyone confirm that "Two-way SSL authentication (server <-> client)" is supported with OpenEdge.Net client?

Posted by Peter Judge on 07-Aug-2017 11:59

Sadly client-side certs are not supported yet in ABL (and the OpenEdge.Net client uses an ABL socket ). There's an idea at community.progress.com/.../improve_abl_sockets_to_support_client-side_certificate_authentication  for this.

This thread is closed