diff --git a/README.md b/README.md index cd78a0c..5d647e0 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Simply add to your pom.xml: me.figo sdk - 1.4.6 + 1.5.0 ``` @@ -73,6 +73,9 @@ session.setTrustManager(trustManager); // now do your API calls ``` +To connect to the staging system of figo, you need to set the `FIGO_API_FINGERPRINTS` environment variable with the staging SHA256 fingerprint (`D0039EF08FBD48678671CE9DA554248163D7D94DEDF16A55F052C70AAB7BB89D`) + + A more detailed documentation of the figo connect API can be found at http://docs.figo.io. Demos diff --git a/pom.xml b/pom.xml index ffbb34c..458d5d9 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ me.figo sdk - 1.4.6 + 1.5.0 jar Figo Java SDK diff --git a/src/main/java/me/figo/FigoApi.java b/src/main/java/me/figo/FigoApi.java index e9a0299..4bd2545 100644 --- a/src/main/java/me/figo/FigoApi.java +++ b/src/main/java/me/figo/FigoApi.java @@ -41,6 +41,7 @@ import com.google.gson.Gson; +import me.figo.internal.FigoSocketFactory; import me.figo.internal.FigoTrustManager; import me.figo.internal.GsonAdapter; @@ -157,8 +158,9 @@ protected void setupTrustManager(HttpURLConnection connection, X509TrustManager try { final SSLContext sc = SSLContext.getInstance("SSL"); sc.init(null, new TrustManager[] { trustManager }, new java.security.SecureRandom()); - ((HttpsURLConnection) connection).setSSLSocketFactory(sc.getSocketFactory()); - } catch (NoSuchAlgorithmException e) { + FigoSocketFactory figoSocketFactory = new FigoSocketFactory(sc.getSocketFactory()); + ((HttpsURLConnection) connection).setSSLSocketFactory(figoSocketFactory); + } catch (NoSuchAlgorithmException e) { throw new IOException("Connection setup failed", e); } catch (KeyManagementException e) { throw new IOException("Connection setup failed", e); diff --git a/src/main/java/me/figo/internal/FigoSocketFactory.java b/src/main/java/me/figo/internal/FigoSocketFactory.java new file mode 100644 index 0000000..7ccc9d5 --- /dev/null +++ b/src/main/java/me/figo/internal/FigoSocketFactory.java @@ -0,0 +1,64 @@ +package me.figo.internal; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.Socket; +import java.net.UnknownHostException; + +import javax.net.ssl.SSLSocket; +import javax.net.ssl.SSLSocketFactory; + +public class FigoSocketFactory extends SSLSocketFactory { + + private static final String[] ENABLED_PROTOCOLS = { "TLSv1.2" }; + + private SSLSocketFactory isf; + + public FigoSocketFactory(SSLSocketFactory factory) { + isf = factory; + } + + @Override + public String[] getDefaultCipherSuites() { + return isf.getDefaultCipherSuites(); + } + + @Override + public String[] getSupportedCipherSuites() { + return isf.getSupportedCipherSuites(); + } + + @Override + public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException { + return enableProtocols(isf.createSocket(socket, host, port, autoClose)); + } + + @Override + public Socket createSocket(String host, int port) throws IOException, UnknownHostException { + return enableProtocols(isf.createSocket(host, port)); + } + + @Override + public Socket createSocket(String remoteHost, int remotePort, InetAddress localHost, int localPort) + throws IOException, UnknownHostException { + return enableProtocols(isf.createSocket(remoteHost, remotePort, localHost, localPort)); + } + + @Override + public Socket createSocket(InetAddress host, int port) throws IOException { + return enableProtocols(isf.createSocket(host, port)); + } + + @Override + public Socket createSocket(InetAddress remoteHost, int remotePort, InetAddress localHost, int localPort) + throws IOException { + return enableProtocols(isf.createSocket(remoteHost, remotePort, localHost, localPort)); + } + + private Socket enableProtocols(Socket socket) { + if (socket != null && socket instanceof SSLSocket) { + ((SSLSocket) socket).setEnabledProtocols(ENABLED_PROTOCOLS); + } + return socket; + } +} diff --git a/src/main/java/me/figo/internal/FigoTrustManager.java b/src/main/java/me/figo/internal/FigoTrustManager.java index 01ac332..95be89b 100644 --- a/src/main/java/me/figo/internal/FigoTrustManager.java +++ b/src/main/java/me/figo/internal/FigoTrustManager.java @@ -32,16 +32,16 @@ import java.util.List; import javax.net.ssl.X509TrustManager; + import org.apache.commons.codec.binary.Hex; public class FigoTrustManager implements X509TrustManager { private static final List VALID_FINGERPRINTS = new ArrayList(Arrays.asList( - "38AE4A326F16EA1581338BB0D8E4A635E727F107", - "DBE2E9158FC9903084FE36CAA61138D85A205D93")); + "070F14AEB94AFB3DF800E82B69A8515CEED2F5B1BA897BEF6432458F61CF9E33")); /** - * @return the list of trusted certificate fingerprints using SHA1 + * @return the list of trusted certificate fingerprints using SHA256 */ public static List getTrustedFingerprints() { return VALID_FINGERPRINTS; @@ -50,7 +50,7 @@ public static List getTrustedFingerprints() { /** * Add a fingerprint to the trusted list, e.g. when using a custom figo deployment. * - * @param fingerprint the SHA1 hash of the SSL certificate in upper case + * @param fingerprint the SHA256 hash of the SSL certificate in upper case */ public static void addTrustedFingerprint(String fingerprint) { VALID_FINGERPRINTS.add(fingerprint); @@ -71,15 +71,15 @@ public void checkServerTrusted(X509Certificate[] certs, String authType) throws throw new CertificateException("No certificate found"); } else { String thumbprint = getThumbPrint(certs[0]); - if (!VALID_FINGERPRINTS.contains(thumbprint) && !this.getFingerprintsFromEnv().contains(thumbprint)){ - throw new CertificateException(); + if (!VALID_FINGERPRINTS.contains(thumbprint) && !getFingerprintsFromEnv().contains(thumbprint)) { + throw new CertificateException("Fingerprint does not match certificate"); } } } private static String getThumbPrint(X509Certificate cert) { try { - MessageDigest md = MessageDigest.getInstance("SHA-1"); + MessageDigest md = MessageDigest.getInstance("SHA-256"); byte[] der = cert.getEncoded(); md.update(der); byte[] digest = md.digest(); @@ -93,6 +93,9 @@ private static String getThumbPrint(X509Certificate cert) { private static List getFingerprintsFromEnv() { String fingerprintList = System.getenv("FIGO_API_FINGERPRINTS"); - return Arrays.asList(fingerprintList.split(":")); + if(fingerprintList!=null) + return Arrays.asList(fingerprintList.split(":")); + else + return new ArrayList<>(); } } diff --git a/src/test/java/me/figo/SessionTest.java b/src/test/java/me/figo/SessionTest.java index b2d2bb8..6aa9665 100644 --- a/src/test/java/me/figo/SessionTest.java +++ b/src/test/java/me/figo/SessionTest.java @@ -31,9 +31,6 @@ import java.util.HashMap; import java.util.List; -import org.junit.Before; -import org.junit.Test; - import me.figo.internal.FakeTrustManager; import me.figo.models.Account; import me.figo.models.Notification; @@ -44,13 +41,18 @@ import me.figo.models.Transaction; import me.figo.models.User; +import org.junit.Before; +import org.junit.Test; + public class SessionTest { FigoSession sut = null; @Before public void setUp() throws Exception { - sut = new FigoSession("ASHWLIkouP2O6_bgA2wWReRhletgWKHYjLqDaqb0LFfamim9RjexTo22ujRIP_cjLiRiSyQXyt2kM1eXU2XLFZQ0Hro15HikJQT_eNeT_9XQ"); + sut = new FigoSession( + "ASHWLIkouP2O6_bgA2wWReRhletgWKHYjLqDaqb0LFfamim9RjexTo22ujRIP_cjLiRiSyQXyt2kM1eXU2XLFZQ0Hro15HikJQT_eNeT_9XQ", + 30000); } @Test @@ -140,7 +142,7 @@ public void testGetErrorMessage() throws IOException { fail(acc.getName()); } catch(FigoException e) { - assertEquals("Entry not found.", e.getErrorMessage()); + assertEquals("Entry not found.", e.getErrorMessage()); assertEquals(null, e.getErrorDescription()); } }