From 94539b8fd8e69b1034f6d6f7d811d8f73fc2aca0 Mon Sep 17 00:00:00 2001 From: Thomas <> Date: Thu, 22 Sep 2022 12:54:43 +0200 Subject: fix(sl20): refactor signature and encryption validation because it can be skipped - SBA Pentest finds a pattern that skip security validation SBA(202209-10.2) --- .../modules/auth/sl20/data/VerificationResult.java | 2 +- .../auth/sl20/utils/SL20JsonExtractorUtils.java | 132 +++++++++++++-------- 2 files changed, 84 insertions(+), 50 deletions(-) diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/data/VerificationResult.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/data/VerificationResult.java index 0f88e251..169dee40 100644 --- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/data/VerificationResult.java +++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/data/VerificationResult.java @@ -7,7 +7,7 @@ import com.fasterxml.jackson.databind.JsonNode; public class VerificationResult { - private Boolean validSigned = null; + private Boolean validSigned = false; private List certs = null; private JsonNode header = null; private JsonNode payload = null; diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20JsonExtractorUtils.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20JsonExtractorUtils.java index 4da46235..3e7577f7 100644 --- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20JsonExtractorUtils.java +++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20JsonExtractorUtils.java @@ -214,46 +214,66 @@ public class SL20JsonExtractorUtils { final boolean mustBeEncrypted) throws SL20Exception { final JsonNode result = command.get(SL20Constants.SL20_COMMAND_CONTAINER_RESULT); final JsonNode encryptedResult = command.get(SL20Constants.SL20_COMMAND_CONTAINER_ENCRYPTEDRESULT); + + if (result == null ^ encryptedResult == null) { + if (encryptedResult != null) { + if (decrypter == null) { + throw new SlCommandoParserException("'joseTools' MUST be set in case of encrypted content"); + + } + + if (encryptedResult.isTextual()) { + return internelJweDecrypt(encryptedResult.asText(), mustBeEncrypted, decrypter); + + } else { + throw new SlCommandoParserException("encrypted payload has wrong format"); + + } + + } else { + if (mustBeEncrypted) { + throw new SlCommandoParserException("result MUST be encrypted."); + + } else { + return result; + + } + } + + } else { + throw new SlCommandoParserException("NO/BOTH result/encryptedResult elements FOUND."); + + } + } - if (result == null && encryptedResult == null) { - throw new SlCommandoParserException("NO result OR encryptedResult FOUND."); - } else if (encryptedResult == null && mustBeEncrypted) { - throw new SlCommandoParserException("result MUST be encrypted."); - } else if (encryptedResult != null && encryptedResult.isTextual()) { - try { - return decrypter.decryptPayload(encryptedResult.asText()); - - } catch (final Exception e) { - log.info("Can NOT decrypt SL20 result. Reason:" + e.getMessage()); - if (!mustBeEncrypted) { - log.warn("Decrypted results are disabled by configuration. Parse result in plain if it is possible"); - - // dummy code - try { - final String[] signedPayload = encryptedResult.toString().split("\\."); - final JsonNode payLoad = JsonMapper.getMapper() - .readTree(new String(Base64.getUrlDecoder().decode(signedPayload[1]), "UTF-8")); - return payLoad; - - } catch (final Exception e1) { - log.debug("DummyCode FAILED, Reason: " + e1.getMessage() + " Ignore it ..."); - throw new SL20Exception(e.getMessage(), null, e); + private static JsonNode internelJweDecrypt(String jwe, boolean mustBeEncrypted, IJoseTools decrypter) + throws SL20Exception { + try { + return decrypter.decryptPayload(jwe); - } - - } else { - throw e; - } + } catch (final Exception e) { + log.info("Can NOT decrypt SL20 result. Reason:" + e.getMessage()); + if (!mustBeEncrypted) { + log.warn("Decrypted results are disabled by configuration. Parse result in plain if it is possible"); - } + // dummy code + try { + final String[] signedPayload = jwe.split("\\."); + final JsonNode payLoad = JsonMapper.getMapper() + .readTree(new String(Base64.getUrlDecoder().decode(signedPayload[1]), "UTF-8")); + return payLoad; - } else if (result != null) { - return result; + } catch (final Exception e1) { + log.debug("DummyCode FAILED, Reason: " + e1.getMessage() + " Ignore it ..."); + throw new SL20Exception(e.getMessage(), null, e); - } else { - throw new SlCommandoParserException("Internal build error"); + } + + } else { + throw e; + + } } - } /** @@ -267,27 +287,41 @@ public class SL20JsonExtractorUtils { */ public static VerificationResult extractSL20PayLoad(final JsonNode container, final IJoseTools joseTools, final boolean mustBeSigned) throws SL20Exception { - + final JsonNode sl20Payload = container.get(SL20Constants.SL20_PAYLOAD); final JsonNode sl20SignedPayload = container.get(SL20Constants.SL20_SIGNEDPAYLOAD); - if (mustBeSigned && joseTools == null) { - throw new SlCommandoParserException("'joseTools' MUST be set if 'mustBeSigned' is 'true'"); - } - - if (sl20Payload == null && sl20SignedPayload == null) { - throw new SlCommandoParserException("NO payLoad OR signedPayload FOUND."); - } else if (sl20SignedPayload == null && mustBeSigned) { - throw new SlCommandoParserException("payLoad MUST be signed."); - } else if (joseTools != null && sl20SignedPayload != null && sl20SignedPayload.isTextual()) { - return joseTools.validateSignature(sl20SignedPayload.asText()); + if (sl20Payload == null ^ sl20SignedPayload == null) { + if (sl20SignedPayload != null) { + // check signed payload + if (joseTools == null) { + throw new SlCommandoParserException("'joseTools' MUST be set in case of signed content"); + + } - } else if (sl20Payload != null) { - return new VerificationResult(sl20Payload); + if (sl20SignedPayload.isTextual()) { + return joseTools.validateSignature(sl20SignedPayload.asText()); + + } else { + throw new SlCommandoParserException("signed payload has wrong format"); + + } + + + } else { + // check unsigned payload + if (mustBeSigned) { + throw new SlCommandoParserException("payLoad MUST be signed."); + + } + return new VerificationResult(sl20Payload); + + } + } else { - throw new SlCommandoParserException("Internal build error"); + throw new SlCommandoParserException("NO/BOTH payLoad/signedPayload elementes FOUND."); + } - } private static JsonNode getAndCheck(final JsonNode input, final String keyID, final boolean isRequired) -- cgit v1.2.3