diff --git a/src/java/com/wolfssl/WolfSSL.java b/src/java/com/wolfssl/WolfSSL.java index 17b35196..486b463a 100644 --- a/src/java/com/wolfssl/WolfSSL.java +++ b/src/java/com/wolfssl/WolfSSL.java @@ -21,6 +21,11 @@ package com.wolfssl; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.FileNotFoundException; + /** * Base class which wraps the native WolfSSL embedded SSL library. * This class contains library init and cleanup methods, general callback @@ -707,6 +712,56 @@ public static void loadLibraryAbsolute(String libPath) System.load(libPath); } + /* ----------------- generic static helper functions ---------------- */ + + /** + * Read a File into byte array. + * + * This method can't use the java.nio package since we have users + * on Android API 24 which does not support java.nio. + * + * @param file File to read into byte array + * + * @return byte array representing input File, or null if file is null + */ + protected static byte[] fileToBytes(File file) + throws FileNotFoundException, IOException { + + int bytesRead = 0; + long fileLen = 0; + byte[] fileBytes = null; + FileInputStream fis = null; + + if (file == null) { + return null; + } + + fileLen = file.length(); + if (fileLen == 0) { + return new byte[0]; + } + + try { + fis = new FileInputStream(file); + if (fis != null) { + fileBytes = new byte[(int)fileLen]; + + bytesRead = fis.read(fileBytes); + + if (bytesRead != fileLen) { + throw new IOException("Unable to read entire file: " + + file.getAbsolutePath()); + } + } + } finally { + if (fis != null) { + fis.close(); + } + } + + return fileBytes; + } + /* --------------- native feature detection functions --------------- */ /** diff --git a/src/java/com/wolfssl/WolfSSLCertRequest.java b/src/java/com/wolfssl/WolfSSLCertRequest.java index 2f4310d3..5fca5877 100644 --- a/src/java/com/wolfssl/WolfSSLCertRequest.java +++ b/src/java/com/wolfssl/WolfSSLCertRequest.java @@ -22,7 +22,6 @@ import java.io.File; import java.io.IOException; -import java.nio.file.Files; import java.nio.charset.Charset; import java.security.PublicKey; import java.security.PrivateKey; @@ -243,6 +242,7 @@ public void setPublicKey(String filePath, int keyType, int format) int ret = 0; File keyFile = null; + byte[] fileBytes = null; confirmObjectIsActive(); @@ -256,7 +256,13 @@ public void setPublicKey(String filePath, int keyType, int format) filePath); } - setPublicKey(Files.readAllBytes(keyFile.toPath()), keyType, format); + fileBytes = WolfSSL.fileToBytes(keyFile); + if (fileBytes == null) { + throw new WolfSSLException("Failed to read bytes from file: " + + filePath); + } + + setPublicKey(fileBytes, keyType, format); } /** @@ -506,6 +512,7 @@ public void signRequest(String filePath, int keyType, int format, int ret = 0; File keyFile = null; + byte[] fileBytes = null; confirmObjectIsActive(); @@ -519,8 +526,13 @@ public void signRequest(String filePath, int keyType, int format, filePath); } - signRequest(Files.readAllBytes(keyFile.toPath()), keyType, - format, digestAlg); + fileBytes = WolfSSL.fileToBytes(keyFile); + if (fileBytes == null) { + throw new WolfSSLException("Failed to read bytes from file: " + + filePath); + } + + signRequest(fileBytes, keyType, format, digestAlg); } /** diff --git a/src/java/com/wolfssl/WolfSSLCertificate.java b/src/java/com/wolfssl/WolfSSLCertificate.java index 18bc143d..e6db3421 100644 --- a/src/java/com/wolfssl/WolfSSLCertificate.java +++ b/src/java/com/wolfssl/WolfSSLCertificate.java @@ -496,6 +496,7 @@ public void setPublicKey(String filePath, int keyType, int format) int ret = 0; File keyFile = null; + byte[] fileBytes = null; confirmObjectIsActive(); @@ -509,7 +510,13 @@ public void setPublicKey(String filePath, int keyType, int format) filePath); } - setPublicKey(Files.readAllBytes(keyFile.toPath()), keyType, format); + fileBytes = WolfSSL.fileToBytes(keyFile); + if (fileBytes == null) { + throw new WolfSSLException("Failed to read bytes from file: " + + filePath); + } + + setPublicKey(fileBytes, keyType, format); } /** @@ -882,6 +889,7 @@ public void signCert(String filePath, int keyType, int format, int ret = 0; File keyFile = null; + byte[] fileBytes = null; confirmObjectIsActive(); @@ -895,8 +903,13 @@ public void signCert(String filePath, int keyType, int format, filePath); } - signCert(Files.readAllBytes(keyFile.toPath()), keyType, format, - digestAlg); + fileBytes = WolfSSL.fileToBytes(keyFile); + if (fileBytes == null) { + throw new WolfSSLException("Failed to read bytes from file: " + + filePath); + } + + signCert(fileBytes, keyType, format, digestAlg); } /** diff --git a/src/java/com/wolfssl/provider/jsse/adapter/WolfSSLJDK8Helper.java b/src/java/com/wolfssl/provider/jsse/adapter/WolfSSLJDK8Helper.java index 4edea2bf..94bb99f1 100644 --- a/src/java/com/wolfssl/provider/jsse/adapter/WolfSSLJDK8Helper.java +++ b/src/java/com/wolfssl/provider/jsse/adapter/WolfSSLJDK8Helper.java @@ -23,6 +23,7 @@ import java.util.List; import java.util.ArrayList; import java.lang.reflect.Method; +import java.lang.reflect.InvocationTargetException; import java.security.AccessController; import java.security.PrivilegedAction; import javax.net.ssl.SSLParameters; @@ -162,10 +163,24 @@ protected static void getApplicationProtocols(final SSLParameters in, "WolfSSLJDK8Helper.getApplicationProtocols() cannot be null"); } - String[] appProtos = in.getApplicationProtocols(); - if (appProtos != null) { - /* call WolfSSLParameters.setApplicationProtocols() */ - out.setApplicationProtocols(appProtos); + try { + /* Android API < 29 does not support SSLParameters + * getApplicationProtocols(). Use reflection here to conditionally + * call it if available */ + Method meth = SSLParameters.class.getMethod( + "getApplicationProtocols"); + if (meth == null) { + return; + } + String[] appProtos = (String[])meth.invoke(in); + if (appProtos != null) { + /* call WolfSSLParameters.setApplicationProtocols() */ + out.setApplicationProtocols(appProtos); + } + } catch (NoSuchMethodException | IllegalAccessException | + InvocationTargetException e) { + /* getApplicationProtocols() not available, just return */ + return; } }