From cc2ec010dd0cf3939a36d3f470d687a2d6d149f9 Mon Sep 17 00:00:00 2001 From: iroqueta Date: Fri, 7 Feb 2025 14:07:20 -0300 Subject: [PATCH] Remove Ajax implementation in Android module Issue: 88024 --- .../com/genexus/internet/HttpContext.java | 146 +----------------- .../java/com/genexus/util/Encryption.java | 86 ----------- .../com/genexus/internet/HttpAjaxContext.java | 96 +++++++++++- 3 files changed, 93 insertions(+), 235 deletions(-) diff --git a/android/src/main/java/com/genexus/internet/HttpContext.java b/android/src/main/java/com/genexus/internet/HttpContext.java index 3080bbf9a..ee384db0e 100644 --- a/android/src/main/java/com/genexus/internet/HttpContext.java +++ b/android/src/main/java/com/genexus/internet/HttpContext.java @@ -11,7 +11,6 @@ import com.artech.base.services.AndroidContext; import com.genexus.util.Codecs; -import com.genexus.util.Encryption; import org.json.JSONArray; import org.json.JSONException; @@ -19,42 +18,15 @@ public abstract class HttpContext extends HttpAjaxContext implements IHttpContext { - private static String GX_AJAX_REQUEST_HEADER = "GxAjaxRequest"; - protected boolean PortletMode = false; - protected boolean AjaxCallMode = false; - protected boolean AjaxEventMode = false; - protected boolean FullAjaxMode = false; public boolean drawingGrid = false; public void setPortletMode() { PortletMode = true; } - public void setAjaxCallMode() - { AjaxCallMode = true; } - - public void setFullAjaxMode() - { FullAjaxMode = true; } - - public void setAjaxEventMode() - { AjaxEventMode = true; } - public boolean isPortletMode() { return PortletMode; } - public boolean isAjaxCallMode() - { return AjaxCallMode; } - - public boolean isAjaxEventMode() - { return AjaxEventMode; } - - public boolean isFullAjaxMode() - { return FullAjaxMode; } - - public boolean isAjaxRequest() - { return isAjaxCallMode() || isAjaxEventMode() || isPortletMode() || isFullAjaxMode(); } - - public byte wbGlbDoneStart = 0; //nSOAPErr public HttpResponse GX_webresponse; @@ -385,7 +357,7 @@ public void windowClosed() public void pushCurrentUrl() { - if (getRequestMethod().equals("GET") && !isAjaxRequest()) + if (getRequestMethod().equals("GET")) { String sUrl = getRequestNavUrl().trim(); String topUrl = getNavigationHelper().peekUrl(sUrl); @@ -409,106 +381,9 @@ public void printReportAtClient(String reportFile, String printerRule) { addPrintReportCommand(getResource(reportFile), printerRule); } - - public boolean isGxAjaxRequest() - { - if (this.isMultipartContent()) - { - return true; - } - // String gxHeader = getRequest().getHeader(GX_AJAX_REQUEST_HEADER); - // if (gxHeader != null && gxHeader.trim().length() > 0) - // { - // return true; - // } - return false; - } - - private String getAjaxEncryptionKey() - { - if(getSessionValue(Encryption.AJAX_ENCRYPTION_KEY) == null) - { - if (!recoverEncryptionKey()) - { - webPutSessionValue(Encryption.AJAX_ENCRYPTION_KEY, Encryption.getRijndaelKey()); - } - } - return (String)getSessionValue(Encryption.AJAX_ENCRYPTION_KEY); - } - - private boolean recoverEncryptionKey() - { - if (getSessionValue(Encryption.AJAX_ENCRYPTION_KEY) == null) - { - // String clientKey = getRequest().getHeader(Encryption.AJAX_SECURITY_TOKEN); - // if (clientKey != null && clientKey.trim().length() > 0) - // { - // boolean candecrypt[]=new boolean[1]; - // clientKey = Encryption.decryptRijndael(clientKey, Encryption.GX_AJAX_PRIVATE_KEY, candecrypt); - // if (candecrypt[0]) - // { - // webPutSessionValue(Encryption.AJAX_ENCRYPTION_KEY, clientKey); - // return true; - // }else - // { - // return false; - // } - // } - } - return false; - } - - public String DecryptAjaxCall(String encrypted) - { - validEncryptedParm = false; - if (isGxAjaxRequest()) - { - String key = getAjaxEncryptionKey(); - boolean candecrypt[] = new boolean[1]; - String decrypted = Encryption.decryptRijndael(encrypted, key, candecrypt); - validEncryptedParm = candecrypt[0]; - if (!validEncryptedParm) - { - sendResponseStatus(403, "Forbidden action"); - return ""; - } - if (validEncryptedParm && !getRequestMethod().equalsIgnoreCase("post")) - { - setQueryString(decrypted); - decrypted = GetNextPar(); - } - return decrypted; - } - return encrypted; - } - - public boolean IsValidAjaxCall() - { - return IsValidAjaxCall(true); - } - - public boolean IsValidAjaxCall(boolean insideAjaxCall) - { - if (insideAjaxCall && !validEncryptedParm) - { - sendResponseStatus(403, "Forbidden action"); - return false; - } - else if (!insideAjaxCall && isGxAjaxRequest()) - { - sendResponseStatus(440, "Session timeout"); - return false; - } - return true; - } public void sendResponseStatus(int statusCode, String statusDescription) { - //getResponse().setStatus(statusCode); - //try { getResponse().sendError(statusCode, statusDescription); } - //catch(Exception e) {} - //setAjaxCallMode(); - //disableOutput(); } private void sendReferer() @@ -578,28 +453,11 @@ public String decrypt64(String value, String key) } return sRet; } - - public void SendAjaxEncryptionKey() - { - if(!encryptionKeySended) - { - String key = getAjaxEncryptionKey(); - ajax_rsp_assign_hidden(Encryption.AJAX_ENCRYPTION_KEY, key); - ajax_rsp_assign_hidden(Encryption.AJAX_ENCRYPTION_IV, Encryption.GX_AJAX_PRIVATE_IV); - - try - { - ajax_rsp_assign_hidden(Encryption.AJAX_SECURITY_TOKEN, Encryption.encryptRijndael(key, Encryption.GX_AJAX_PRIVATE_KEY)); - } - catch(Exception exc) {} - encryptionKeySended = true; - } - } public void SendServerCommands() { try { - if (!isAjaxRequest() && commands.getCount() > 0) + if (commands.getCount() > 0) { HiddenValues.put("GX_SRV_COMMANDS", commands.getJSONArray()); } diff --git a/common/src/main/java/com/genexus/util/Encryption.java b/common/src/main/java/com/genexus/util/Encryption.java index 47ecd0e14..8b6521866 100644 --- a/common/src/main/java/com/genexus/util/Encryption.java +++ b/common/src/main/java/com/genexus/util/Encryption.java @@ -3,21 +3,10 @@ import java.security.InvalidKeyException; import com.genexus.CommonUtil; import com.genexus.common.interfaces.SpecificImplementation; -import java.nio.charset.StandardCharsets; import com.genexus.diagnostics.core.ILogger; import com.genexus.diagnostics.core.LogManager; import org.apache.commons.codec.binary.Base64; -import org.bouncycastle.crypto.BlockCipher; -import org.bouncycastle.crypto.BufferedBlockCipher; -import org.bouncycastle.crypto.DataLengthException; -import org.bouncycastle.crypto.InvalidCipherTextException; -import org.bouncycastle.crypto.engines.RijndaelEngine; -import org.bouncycastle.crypto.modes.CBCBlockCipher; -import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher; -import org.bouncycastle.crypto.paddings.ZeroBytePadding; -import org.bouncycastle.crypto.params.KeyParameter; -import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.util.encoders.Hex; import java.io.UnsupportedEncodingException; @@ -29,8 +18,6 @@ public class Encryption public static String AJAX_ENCRYPTION_KEY = "GX_AJAX_KEY"; public static String AJAX_ENCRYPTION_IV = "GX_AJAX_IV"; public static String AJAX_SECURITY_TOKEN = "AJAX_SECURITY_TOKEN"; - public static String GX_AJAX_PRIVATE_KEY = "595D54FF4A612E69FF4F3FFFFF0B01FF"; - public static String GX_AJAX_PRIVATE_IV = "8722E2EA52FD44F599D35D1534485D8E"; private static int[] VALID_KEY_LENGHT_IN_BYTES = new int[]{32, 48, 64}; static public class InvalidGXKeyException extends RuntimeException @@ -344,77 +331,4 @@ public void nextBytes2(byte[] out) } } } - - public static String getRijndaelKey() - { - SecureRandom rdm = new SecureRandom(); - byte[] bytes = new byte[16]; - rdm.nextBytes(bytes); - StringBuffer buffer = new StringBuffer(32); - for (int i = 0; i < 16; i++) - { - buffer.append(CommonUtil.padl(Integer.toHexString((int)bytes[i]), 2, "0")); - } - return buffer.toString().toUpperCase(); - } - - public static String decryptRijndael(String ivEncrypted, String key, boolean[] candecrypt) { - - try { - candecrypt[0] = false; - String encrypted = ivEncrypted.length() >= GX_AJAX_PRIVATE_IV.length() ? ivEncrypted.substring(GX_AJAX_PRIVATE_IV.length()) : ivEncrypted; - byte[] inputBytes = Hex.decode(encrypted.trim().getBytes()); - byte[] outputBytes; - String decrypted = ""; - if (inputBytes != null) { - try { - outputBytes = aesCipher(inputBytes, false, key, GX_AJAX_PRIVATE_IV); - } catch (DataLengthException | IllegalStateException | InvalidCipherTextException e) { - return ivEncrypted; - } - - String result = new String(outputBytes, StandardCharsets.US_ASCII).replaceAll("[\ufffd]", ""); - if (result != null) { - candecrypt[0] = true; - decrypted = result.trim(); - } - } - return decrypted; - }catch(Exception ex){ - return ivEncrypted; - } - } - - public static String encryptRijndael(String plainText, String key) { - byte[] inputBytes = plainText.trim().getBytes(StandardCharsets.US_ASCII); - byte[] outputBytes; - try { - outputBytes = aesCipher(inputBytes, true, key, GX_AJAX_PRIVATE_IV); - } catch (DataLengthException | IllegalStateException | InvalidCipherTextException e) { - logger.error("encryptRijndael error", e); - return ""; - } - return Hex.toHexString(outputBytes); - } - - - private static byte[] aesCipher(byte[] inputBytes, boolean init, String key, String iv) - throws DataLengthException, IllegalStateException, InvalidCipherTextException { - byte[] byteKey = Hex.decode(key); - byte[] byteIV = Hex.decode(iv); - KeyParameter keyParam = new KeyParameter(byteKey); - ParametersWithIV keyParamWithIV = new ParametersWithIV(keyParam, byteIV); - - BlockCipher engineWithMode = new CBCBlockCipher(new RijndaelEngine()); - - BufferedBlockCipher bbc = new PaddedBufferedBlockCipher(engineWithMode, new ZeroBytePadding()); - bbc.init(init, keyParamWithIV); - byte[] outputBytes = new byte[bbc.getOutputSize(inputBytes.length)]; - if (inputBytes != null) { - int length = bbc.processBytes(inputBytes, 0, inputBytes.length, outputBytes, 0); - bbc.doFinal(outputBytes, length); - - } - return outputBytes; - } } \ No newline at end of file diff --git a/gxweb/src/main/java/com/genexus/internet/HttpAjaxContext.java b/gxweb/src/main/java/com/genexus/internet/HttpAjaxContext.java index 2a160d3eb..1a25cefb1 100644 --- a/gxweb/src/main/java/com/genexus/internet/HttpAjaxContext.java +++ b/gxweb/src/main/java/com/genexus/internet/HttpAjaxContext.java @@ -4,6 +4,8 @@ import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Array; +import java.nio.charset.StandardCharsets; +import java.security.SecureRandom; import java.util.*; import com.genexus.*; @@ -22,6 +24,17 @@ import com.genexus.webpanels.HttpContextWeb; import com.genexus.webpanels.WebUtils; +import org.bouncycastle.crypto.BlockCipher; +import org.bouncycastle.crypto.BufferedBlockCipher; +import org.bouncycastle.crypto.DataLengthException; +import org.bouncycastle.crypto.InvalidCipherTextException; +import org.bouncycastle.crypto.engines.RijndaelEngine; +import org.bouncycastle.crypto.modes.CBCBlockCipher; +import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher; +import org.bouncycastle.crypto.paddings.ZeroBytePadding; +import org.bouncycastle.crypto.params.KeyParameter; +import org.bouncycastle.crypto.params.ParametersWithIV; +import org.bouncycastle.util.encoders.Hex; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -30,6 +43,8 @@ public class HttpAjaxContext extends HttpContextWeb { private static String GX_AJAX_REQUEST_HEADER = "GxAjaxRequest"; + private static String GX_AJAX_PRIVATE_KEY = "595D54FF4A612E69FF4F3FFFFF0B01FF"; + private static String GX_AJAX_PRIVATE_IV = "8722E2EA52FD44F599D35D1534485D8E"; public static final int TYPE_RESET = 0; public static final int TYPE_SUBMIT = 1; @@ -363,7 +378,7 @@ private String getAjaxEncryptionKey() { if (!recoverEncryptionKey()) { - webPutSessionValue(Encryption.AJAX_ENCRYPTION_KEY, Encryption.getRijndaelKey()); + webPutSessionValue(Encryption.AJAX_ENCRYPTION_KEY, getRijndaelKey()); } } return (String)getSessionValue(Encryption.AJAX_ENCRYPTION_KEY); @@ -377,7 +392,7 @@ private boolean recoverEncryptionKey() if (clientKey != null && clientKey.trim().length() > 0) { boolean candecrypt[]=new boolean[1]; - clientKey = Encryption.decryptRijndael(Encryption.GX_AJAX_PRIVATE_IV + clientKey, Encryption.GX_AJAX_PRIVATE_KEY, candecrypt); + clientKey = decryptRijndael(GX_AJAX_PRIVATE_IV + clientKey, GX_AJAX_PRIVATE_KEY, candecrypt); if (candecrypt[0]) { webPutSessionValue(Encryption.AJAX_ENCRYPTION_KEY, clientKey); @@ -398,7 +413,7 @@ public String DecryptAjaxCall(String encrypted) { String key = getAjaxEncryptionKey(); boolean candecrypt[] = new boolean[1]; - String decrypted = Encryption.decryptRijndael(encrypted, key, candecrypt); + String decrypted = decryptRijndael(encrypted, key, candecrypt); validEncryptedParm = candecrypt[0]; if (!validEncryptedParm) { @@ -743,10 +758,10 @@ public void SendAjaxEncryptionKey() { String key = getAjaxEncryptionKey(); ajax_rsp_assign_hidden(Encryption.AJAX_ENCRYPTION_KEY, key); - ajax_rsp_assign_hidden(Encryption.AJAX_ENCRYPTION_IV, Encryption.GX_AJAX_PRIVATE_IV); + ajax_rsp_assign_hidden(Encryption.AJAX_ENCRYPTION_IV, GX_AJAX_PRIVATE_IV); try { - ajax_rsp_assign_hidden(Encryption.AJAX_SECURITY_TOKEN, Encryption.encryptRijndael(key, Encryption.GX_AJAX_PRIVATE_KEY)); + ajax_rsp_assign_hidden(Encryption.AJAX_SECURITY_TOKEN, encryptRijndael(key, GX_AJAX_PRIVATE_KEY)); } catch(Exception exc) {} encryptionKeySended = true; @@ -1784,4 +1799,75 @@ public JSONArray getJSONArray() return jArr; } } + + private static String getRijndaelKey() + { + SecureRandom rdm = new SecureRandom(); + byte[] bytes = new byte[16]; + rdm.nextBytes(bytes); + StringBuffer buffer = new StringBuffer(32); + for (int i = 0; i < 16; i++) + { + buffer.append(CommonUtil.padl(Integer.toHexString((int)bytes[i]), 2, "0")); + } + return buffer.toString().toUpperCase(); + } + + private static String decryptRijndael(String ivEncrypted, String key, boolean[] candecrypt) { + try { + candecrypt[0] = false; + String encrypted = ivEncrypted.length() >= GX_AJAX_PRIVATE_IV.length() ? ivEncrypted.substring(GX_AJAX_PRIVATE_IV.length()) : ivEncrypted; + byte[] inputBytes = Hex.decode(encrypted.trim().getBytes()); + byte[] outputBytes; + String decrypted = ""; + if (inputBytes != null) { + try { + outputBytes = aesCipher(inputBytes, false, key, GX_AJAX_PRIVATE_IV); + } catch (DataLengthException | IllegalStateException | InvalidCipherTextException e) { + return ivEncrypted; + } + + String result = new String(outputBytes, StandardCharsets.US_ASCII).replaceAll("[\ufffd]", ""); + if (result != null) { + candecrypt[0] = true; + decrypted = result.trim(); + } + } + return decrypted; + }catch(Exception ex){ + return ivEncrypted; + } + } + + private static String encryptRijndael(String plainText, String key) { + byte[] inputBytes = plainText.trim().getBytes(StandardCharsets.US_ASCII); + byte[] outputBytes; + try { + outputBytes = aesCipher(inputBytes, true, key, GX_AJAX_PRIVATE_IV); + } catch (DataLengthException | IllegalStateException | InvalidCipherTextException e) { + logger.error("encryptRijndael error", e); + return ""; + } + return Hex.toHexString(outputBytes); + } + + private static byte[] aesCipher(byte[] inputBytes, boolean init, String key, String iv) + throws DataLengthException, IllegalStateException, InvalidCipherTextException { + byte[] byteKey = Hex.decode(key); + byte[] byteIV = Hex.decode(iv); + KeyParameter keyParam = new KeyParameter(byteKey); + ParametersWithIV keyParamWithIV = new ParametersWithIV(keyParam, byteIV); + + BlockCipher engineWithMode = new CBCBlockCipher(new RijndaelEngine()); + + BufferedBlockCipher bbc = new PaddedBufferedBlockCipher(engineWithMode, new ZeroBytePadding()); + bbc.init(init, keyParamWithIV); + byte[] outputBytes = new byte[bbc.getOutputSize(inputBytes.length)]; + if (inputBytes != null) { + int length = bbc.processBytes(inputBytes, 0, inputBytes.length, outputBytes, 0); + bbc.doFinal(outputBytes, length); + + } + return outputBytes; + } }