0

I am trying to communicate with TSYS payment gateway which has an https server from my iOS application. My original code is given below.

-(void)postRequest:(NSString *)jsonBody{
  NSData *requestData = [NSData dataWithBytes:[jsonBody UTF8String] 
                            length:[jsonBody length]];
  NSURL *url = [NSURL URLWithString:TSYS_URL];
  NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL:url];
  [request setHTTPMethod:@"POST"];
  [request setValue:[NSString stringWithFormat:@"%d",[requestData length]]
                            forHTTPHeaderField:@"Content-Length"];
  [request setValue:@"*/*" forHTTPHeaderField:@"Accept"];
  [request setHTTPBody:requestData];

  [[NSURLConnection alloc]initCustomURLWithRequest:request delegate:self ];
}
- (void)connection:(NSURLConnection *)connection 
                     didReceiveResponse:(NSURLResponse *)response{
    NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
    int code = [httpResponse statusCode];
    NSLog(@"http error code : %d", code);

    [self.receivedData setLength:0];
}
- (void)connection:(NSURLConnection *)connection 
                      didReceiveData:(NSData *)data {
    [self.receivedData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    NSLog(@"receivedData.length : %d", [self.receivedData length]);
    connection = nil;
}

- (void)connection:(NSURLConnection *)connection 
                        didFailWithError:(NSError *)error {
    connection = nil;
}

The payment gateway url is

#define TSYS_URL @"https://stagegw.transnox.com/servlets/TransNox_API_Server"

And I get this in console

http error code : 404
receivedData.length : 0

When I saw the log, the first port of call was about HTTPS SSL authentication, so I wrote a android project that do POST by trusting all certificate (not ideal, I know), and hurray I was getting correct response. But when I removed the part that enables HttpClient to trust all certificates, I got empty response(in Android).

To make iOS trust all certificate, I added below code

- (BOOL)connection:(NSURLConnection *)connection 
     canAuthenticateAgainstProtectionSpace:
     (NSURLProtectionSpace *)protectionSpace {
   //This always returns true
   return [protectionSpace.authenticationMethod
       isEqualToString:NSURLAuthenticationMethodServerTrust];
}
- (void)connection:(NSURLConnection *)connection 
      didReceiveAuthenticationChallenge:
      (NSURLAuthenticationChallenge *)challenge {
    if([challenge.protectionSpace.authenticationMethod 
            isEqualToString:NSURLAuthenticationMethodServerTrust]){
        NSURLCredential *credential = [NSURLCredential 
                      credentialForTrust:challenge.protectionSpace.serverTrust];
        [challenge.sender useCredential:credential 
                     forAuthenticationChallenge:challenge];
    }
    [challenge.sender 
          continueWithoutCredentialForAuthenticationChallenge:challenge];
}

Still I get the same error.

Ok my questions are

  1. First and foremost, why is this not working? I need to get this working , so that I can move forward with project. Since my project is in beginning state, I don't mind if the solution is to trust all certificates. I somehow need to get server talking.
  2. The type of authentication challenge I am getting is NSURLAuthenticationMethodServerTrust. Ideally I should get the server issued certificate and make my NSURLConnection object trust it. How could I get the certificate file from server?
Community
  • 1
  • 1
Krishnabhadra
  • 34,169
  • 30
  • 118
  • 167

1 Answers1

0

I got it working at last. In the end, it was not an issue with authentication. Along with the all the code above, I had to pass a header field "User-Agent" with the request. When I passed it I started to get response from the server.

Krishnabhadra
  • 34,169
  • 30
  • 118
  • 167