1

MasterCard uses 2-legged OAuth. After preparation of OAuth payload, I add it to header in Authorization key. Then the request needs to be sent along with certificate. I am getting error at this step.

I have written my code based on the sample code available at https://developer.mastercard.com/portal/display/api/Locations+-+Sample+Code

and sample keys available at https://developer.mastercard.com/portal/display/api/OAuth+Validation,

Steps I followed to generate SSL Certificate :

1. Open the Firefox browser and enter the URL : https://sandbox.api.mastercard.com
2. Click on the lock icon on the bottom of the browser.
3. Click on View Certificate 
4. Click on the Details tab
5. Under "Certificate Hierarchy", click on the issuing CA (beside the arrow)
6. Click on Export..
7. Save the .PEM file (suppose with "openapi-sandbox.pem").
8. Then using Java's keytool, Load this into a JKS keystore using a command like this: 

keytool -import -alias openapi-samplecode-ssl-cert -file openapi-sandbox.pem -keystore openapi-samplecode.jks

Code to prepare request

  URL url = new URL(httpsURL);
  con = (HttpsURLConnection) url.openConnection();
  con.setRequestMethod(method);
  con.setSSLSocketFactory(getSocketFactory());
  con.setDoOutput(true);
  con.setDoInput(true);
  con.addRequestProperty("Authorization", buildAuthHeaderString(params));

And function to process the Cert file

  private SSLSocketFactory getSocketFactory() 
  {
    KeyStore ks = KeyStore.getInstance("JKS");
    // get user password and file input stream
    char[] password = "prince".toCharArray();
    ClassLoader cl = this.getClass().getClassLoader();
    String location =  "D:\\DEV_HOME\\openapi-samplecode6.jks";
  //  String location =  "openapi-samplecode1.jks";
    System.out.println("location =" + location );
    InputStream stream = cl.getResourceAsStream(location);
    ks.load(stream, password);
   // stream.close();

    SSLContext sc = SSLContext.getInstance("TLS");
    KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
    TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");

    kmf.init(ks, password);
    tmf.init(ks);

    sc.init(kmf.getKeyManagers(), tmf.getTrustManagers(),null);

    return sc.getSocketFactory();
  }

Thanks in advance for your time. :)

Error Message

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: No trusted certificate found at sun.security.ssl.Alerts.getSSLException(Unknown Source) at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source) at sun.security.ssl.Handshaker.fatalSE(Unknown Source) at sun.security.ssl.Handshaker.fatalSE(Unknown Source) at sun.security.ssl.ClientHandshaker.serverCertificate(Unknown Source) at sun.security.ssl.ClientHandshaker.processMessage(Unknown Source) at sun.security.ssl.Handshaker.processLoop(Unknown Source) at sun.security.ssl.Handshaker.process_record(Unknown Source) at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source) at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source) at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source) at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source) at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source) at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source) at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(Unknown Source) at mypack.MasterCardDemo.createOpenAPIConnection(MasterCardDemo.java:183) at mypack.MasterCardDemo.main(MasterCardDemo.java:64) Caused by: sun.security.validator.ValidatorException: No trusted certificate found at sun.security.validator.SimpleValidator.buildTrustedChain(Unknown Source) at sun.security.validator.SimpleValidator.engineValidate(Unknown Source) at sun.security.validator.Validator.validate(Unknown Source) at sun.security.ssl.X509TrustManagerImpl.validate(Unknown Source) at sun.security.ssl.X509TrustManagerImpl.checkTrusted(Unknown Source) at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)

1 Answers1

0

This is really an SSL issue, and has little to do with MasterCard's OAuth. You need to convince Java to trust the SSL certificate on https://api.mastercard.com. You put your OAuth certificate in the trust store, not the MasterCard cert. The better solution than putting a key in a trust store is trusting the root CAs. In Java you can do this by using the default socket factor. Replace this code:

con.setSSLSocketFactory(getSocketFactory());

With this:

con.setSSLSocketFactory((SSLSocketFactory)SSLSocketFactory.getDefault());
Dan
  • 2,733
  • 1
  • 17
  • 6