Recent

Author Topic: SSL with a financial company  (Read 6076 times)

Douglas Medeiros

  • Newbie
  • Posts: 6
SSL with a financial company
« on: December 13, 2017, 01:12:50 pm »
Hello,

We are developing a solution that needs consume an REST API from a Brazilian credit card company.

I tried connect to this rest api with FPHttpClient and now with HttpSend (Synapse package) with no success.

Every request return http error 403 (Access Denied), but I'm sending the correct information. I think :).

Bellow is my code with synapse:

Code: Pascal  [Select][+][-]
  1. // This method prepare HTTPSend object to be used
  2. function TRedeBO.ReturnHttpClient(AContent: Boolean): THTTPSend;
  3. var
  4.   HttpClient : THTTPSend;
  5. begin
  6.   HttpClient := THTTPSend.Create;
  7.  
  8.   if AContent then
  9.     HttpClient.MimeType := 'Application/json'
  10.   else
  11.     HttpClient.MimeType := EmptyStr;
  12.  
  13.   HttpClient.KeepAlive := False;
  14.  
  15.   HttpClient.UserName := FPVNumber;
  16.   HttpClient.Password := FToken;
  17.   HttpClient.Protocol := '1.1';
  18.  
  19.   Result := HttpClient;
  20. end;
  21.  
  22.  
  23. function TRedeBO.Pay(AValue: Double; out ATransactionID: String; out ARequestJSON: String; out AResponseJSON: String): Boolean;
  24. var
  25.   JSON          : String        ;
  26.   CreditCardDTO : TCreditCardDTO;
  27.   Response      : String        ;
  28.   HttpClient    : THTTPSend     ;
  29.   ID            : String        ;
  30.   Serializer    : ISerializer   ;
  31.   ReturnIO      : TRedeReturnIO ;
  32. begin
  33.   try
  34.     Result        := False;
  35.     ReturnIO      := nil;
  36.     Serializer    := GetAnObject(ISerializer) as ISerializer;
  37.     HttpClient    := ReturnHttpClient(True);
  38.     CreditCardDTO := LoadCreditCard;
  39.  
  40.     ID := 'c201709011647';
  41.  
  42.     JSON := '{'+
  43.             '"reference": "' + ID + '",'+
  44.             '"amount": "' + FormatValue(AValue) + '",'+
  45.             '"cardNumber": "' + CreditCardDTO.Card_Number + '",'+
  46.             '"expirationMonth": "' + FormatMonth(CreditCardDTO.Card_Expiration) + '",'+
  47.             '"expirationYear": "' + FormatYear(CreditCardDTO.Card_Expiration) + '",'+
  48.             '"cardHolderName": "' + CreditCardDTO.Holder_Name + '",'+
  49.             '"securityCode" : "' + CreditCardDTO.CVV +  '"}';
  50.  
  51.     WriteStrToStream(HttpClient.Document, JSON);
  52.     HttpClient.HTTPMethod('POST', REDE_URL + 'transactions');
  53.  
  54.     ATransactionID := EmptyStr;
  55.     ARequestJSON   := JSON    ;
  56.     AResponseJSON  := ReadStrFromStream(HttpClient.Document, HttpClient.Document.Size);
  57.  
  58.     if HttpClient.ResultCode <> 200 then;
  59.       Exit;  
  60.  
  61.     // When response code is 200, other codes are executed below here, but is no importante for this case
  62. end;

But if I make a test with curl is OK .

curl -u user:password --request POST   --url https://api.userede.com.br/desenvolvedores/v1/transactions  --header 'Content-Type: application/json'   --data '{ "reference": "c201709011644","amount": "100", "cardNumber": "5448280000000007", "expirationMonth": "12", "expirationYear": "2018" }'

I have used web api's with free pascal during a long time with no problem and because this I made this test with other webapi that I use every day and found this diferences on curl verbose output:

// Send Grid API with no problems with freepascal. (curl verbose output)
curl --request POST   --url https://api.sendgrid.com/v3/mail/send    --header 'Content-Type: application/json'   --data '{"personalizations": [{"to": [{"email": "rodrigo@vocepede.com.br"}]}],"from": {"email": "douglas@vocepede.com.br"},"subject": "Sending with SendGrid is Fun","content": [{"type": "text/plain", "value": "and easy to do anywhere, even with cURL"}]}' -v

Note: Unnecessary use of -X or --request, POST is already inferred.
*   Trying 108.168.183.162...
* TCP_NODELAY set
* Connected to api.sendgrid.com (108.168.183.162) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/cert.pem
  CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* NPN, negotiated HTTP1.1
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Unknown (67):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server did not agree to a protocol
* Server certificate:
*  subject: OU=Domain Control Validated; CN=*.sendgrid.com
*  start date: Feb 28 17:29:00 2017 GMT
*  expire date: Feb 28 17:29:00 2019 GMT
*  subjectAltName: host "api.sendgrid.com" matched cert's "*.sendgrid.com"
*  issuer: C=US; ST=Arizona; L=Scottsdale; O=GoDaddy.com, Inc.; OU=http://certs.godaddy.com/repository/; CN=Go Daddy Secure Certificate Authority - G2
*  SSL certificate verify ok.
> POST /v3/mail/send HTTP/1.1
> Host: api.sendgrid.com
> User-Agent: curl/7.54.0
> Accept: */*
> Authorization: Bearer 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
> Content-Type: application/json
> Content-Length: 245
>
* upload completely sent off: 245 out of 245 bytes
< HTTP/1.1 202 Accepted
< Server: nginx
< Date: Wed, 13 Dec 2017 12:03:43 GMT
< Content-Type: text/plain; charset=utf-8
< Content-Length: 0
< Connection: keep-alive
< X-Message-Id: oNaIgidISuWS2OO3YNCXFw
< Access-Control-Allow-Origin: https://sendgrid.api-docs.io
< Access-Control-Allow-Methods: POST
< Access-Control-Allow-Headers: Authorization, Content-Type, On-behalf-of, x-sg-elas-acl
< Access-Control-Max-Age: 600
< X-No-CORS-Reason: https://sendgrid.com/docs/Classroom/Basics/API/cors.html


Financial company with problems on freepascal (curl output)

curl --request POST -u username:password  --url https://api.userede.com.br/desenvolvedores/v1/transactions  --header 'Content-Type: application/json' -v --data '{ "reference": "c201709011649","amount": "100", "cardNumber": "5448280000000007", "expirationMonth": "12", "expirationYear": "2018" }' -v

Note: Unnecessary use of -X or --request, POST is already inferred.
*   Trying 23.77.114.253...
* TCP_NODELAY set
* Connected to api.userede.com.br (23.77.114.253) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/cert.pem
  CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
*  subject: C=BR; ST=Sao Paulo; L=Barueri; O=Redecard S/A; CN=ecommerce.userede.com.br
*  start date: Sep 15 00:00:00 2017 GMT
*  expire date: Sep 15 23:59:59 2018 GMT
*  subjectAltName: host "api.userede.com.br" matched cert's "*.userede.com.br"
*  issuer: C=US; O=Symantec Corporation; OU=Symantec Trust Network; CN=Symantec Class 3 Secure Server CA - G4
*  SSL certificate verify ok.
> POST /desenvolvedores/v1/transactions HTTP/1.1
> Host: api.userede.com.br
> User-Agent: curl/7.54.0
> Accept: */*
> Authorization: Basic MTAwMDAwOTQ6ZmY0MDJkNTVkYjBiNDhlNWIyZDQzNjIwNzM5NTM4ZDg=
> Content-Type: application/json
> Content-Length: 133
>
* upload completely sent off: 133 out of 133 bytes
< HTTP/1.1 422 Unprocessable Entity
< Content-Type: application/json; charset=utf-8
< Max-Forwards: 19
< Server: Microsoft-IIS/7.5
< Server: Microsoft-IIS/7.5
< X-AspNet-Version: 4.0.30319
< X-CorrelationID: Id-ee17315a212c8cb132662c7e 0; Id-ee17315a95a083a97cc8c66e 0
< X-Powered-By: ASP.NET
< X-Powered-By: ASP.NET
< Content-Length: 77
< Expires: Wed, 13 Dec 2017 12:07:11 GMT
< Cache-Control: max-age=0, no-cache, no-store
< Pragma: no-cache
< Date: Wed, 13 Dec 2017 12:07:11 GMT
< Connection: close
<
* Closing connection 0
* TLSv1.2 (OUT), TLS alert, Client hello (1):
{"returnCode":"42","returnMessage":"Reference: Order number already exists."}


In my opinion the diference is SSL cipher. There is no support for this on free pascal? There are any option for me?

I'm using Lazarus 1.6.4 with FPC 3.0.2 (all on 64 bits version). SO: Windows 10, I didn't try on Linux yet.

Sorry for my poor english.

Thanks
« Last Edit: December 13, 2017, 01:18:20 pm by Douglas Medeiros »

Almir.Bispo

  • Jr. Member
  • **
  • Posts: 91
  • CSV Comp DB is the Best NoSQL
    • CSV Comp DB (NoSQL)
Re: SSL with a financial company
« Reply #1 on: December 13, 2017, 01:24:09 pm »
Hi Medeiros.I'm brazilian too.
You must use Synapse lib and need you use the ssl unit.
Http request does'n work without ssl unit class.
To know my projeto: http://adltecnologia.blogspot.com.br
CSV Comp DB Developer {Pascal Lover}

Douglas Medeiros

  • Newbie
  • Posts: 6
Re: SSL with a financial company
« Reply #2 on: December 13, 2017, 01:36:39 pm »
Hi Medeiros.I'm brazilian too.
You must use Synapse lib and need you use the ssl unit.
Http request does'n work without ssl unit class.
To know my projeto: http://adltecnologia.blogspot.com.br

Hi, thanks for your help, I'm a pascal lover and try make all with pascal ;)

I put this units on my uses clause: httpsend, ssl_openssl, ssl_openssl_lib, sslsockets.

But the answer of server still the same. Are this the correct units?

turrican

  • Full Member
  • ***
  • Posts: 133
  • Pascal is my life.
    • Homepage
Re: SSL with a financial company
« Reply #3 on: December 13, 2017, 01:59:56 pm »
403 is an HTTP error not a certificate error. Can be an UserAgent restriction on the server. Switch UserAgent header on the client to a generic one : http://www.useragentstring.com/pages/useragentstring.php
« Last Edit: December 13, 2017, 02:01:43 pm by turrican »

Zoran

  • Hero Member
  • *****
  • Posts: 1829
    • http://wiki.lazarus.freepascal.org/User:Zoran
Re: SSL with a financial company
« Reply #4 on: December 13, 2017, 02:15:26 pm »
You must use Synapse lib and need you use the ssl unit.
But according to wiki, FPHttpclient also supports ssl, see http://wiki.freepascal.org/fphttpclient#HTTPS_.28TLS.2FSSL.29.

tudi_x

  • Hero Member
  • *****
  • Posts: 532
Re: SSL with a financial company
« Reply #5 on: December 13, 2017, 02:38:12 pm »
are you using the libraries from the below?
https://indy.fulgan.com/SSL/openssl-1.0.2l-x64_86-win64.zip
Lazarus 2.0.2 64b on Debian LXDE 10

Thaddy

  • Hero Member
  • *****
  • Posts: 14205
  • Probably until I exterminate Putin.
Re: SSL with a financial company
« Reply #6 on: December 13, 2017, 02:49:20 pm »
Note that current openssl for FPC can be configured to use TLS1.2 as a minimum, but the code is not - yet - configured to ignore anything below TLS1.2.
SSL 2.0, SSL 3.0, TLS 1.0 and TLS 1.1 are deprecated in modern browsers. You should force TSL 1.2. Some browsers, but not all, allow a fall-back to just SSL 2.0.
Everything in between is deemed insecure. For a banking application you should force TLS 1.2 and do not allow fall-backs.
Current OpenSSL does not even have the insecure protocols, unless you compile it yourself.
« Last Edit: December 13, 2017, 02:55:11 pm by Thaddy »
Specialize a type, not a var.

Douglas Medeiros

  • Newbie
  • Posts: 6
Re: SSL with a financial company
« Reply #7 on: December 13, 2017, 03:21:31 pm »
Hello

I discovered the problem, I just change de header of content-type from:

HttpClient.MimeType := 'Application/json'

to

HttpClient.MimeType := 'application/json'

Douglas Medeiros

  • Newbie
  • Posts: 6
Re: SSL with a financial company
« Reply #8 on: December 13, 2017, 03:23:57 pm »
Note that current openssl for FPC can be configured to use TLS1.2 as a minimum, but the code is not - yet - configured to ignore anything below TLS1.2.
SSL 2.0, SSL 3.0, TLS 1.0 and TLS 1.1 are deprecated in modern browsers. You should force TSL 1.2. Some browsers, but not all, allow a fall-back to just SSL 2.0.
Everything in between is deemed insecure. For a banking application you should force TLS 1.2 and do not allow fall-backs.
Current OpenSSL does not even have the insecure protocols, unless you compile it yourself.

Could you help-me to change it? I don't know how to do it.

turrican

  • Full Member
  • ***
  • Posts: 133
  • Pascal is my life.
    • Homepage
Re: SSL with a financial company
« Reply #9 on: December 13, 2017, 03:30:40 pm »
Hello

I discovered the problem, I just change de header of content-type from:

HttpClient.MimeType := 'Application/json'

to

HttpClient.MimeType := 'application/json'

Same thing as THTTPSend.Useragent . You have to watch invalid headers on your request.

 

TinyPortal © 2005-2018