From dc8587693201e34fe0f7a87b3e401fac4325ce04 Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Fri, 3 May 2019 06:59:13 +0200 Subject: update process finalization and update pendingReqIdGenerationStrategy --- .../SecurePendingRequestIdGenerationStrategy.java | 118 +++++++++++++-------- .../SimplePendingRequestIdGenerationStrategy.java | 21 +++- 2 files changed, 89 insertions(+), 50 deletions(-) (limited to 'eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils') diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/SecurePendingRequestIdGenerationStrategy.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/SecurePendingRequestIdGenerationStrategy.java index 0daa0eb7..f0ef9b38 100644 --- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/SecurePendingRequestIdGenerationStrategy.java +++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/SecurePendingRequestIdGenerationStrategy.java @@ -22,6 +22,8 @@ import org.joda.time.format.DateTimeFormatter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.lang.NonNull; +import org.springframework.lang.Nullable; import at.gv.egiz.eaaf.core.api.idp.IConfiguration; import at.gv.egiz.eaaf.core.api.utils.IPendingRequestIdGenerationStrategy; @@ -30,7 +32,12 @@ import at.gv.egiz.eaaf.core.exceptions.EAAFException; import at.gv.egiz.eaaf.core.exceptions.EAAFIllegalStateException; import at.gv.egiz.eaaf.core.exceptions.PendingReqIdValidationException; - +/** + * PendingRequestId generation strategy based on signed tokens that facilitates extended token validation + * + * @author tlenz + * + */ public class SecurePendingRequestIdGenerationStrategy implements IPendingRequestIdGenerationStrategy { private static final Logger log = LoggerFactory.getLogger(SecurePendingRequestIdGenerationStrategy.class); @@ -72,56 +79,43 @@ public class SecurePendingRequestIdGenerationStrategy implements IPendingRequest } @Override - public String validateAndGetPendingRequestId(String externalPendingReqId) throws PendingReqIdValidationException { - log.trace("RAW external pendingReqId: {}", externalPendingReqId); + public String getPendingRequestIdWithOutChecks(String externalPendingReqId) throws PendingReqIdValidationException { + final String[] tokenElements = extractTokens(externalPendingReqId); + return tokenElements[1]; + } + + @Override + public String validateAndGetPendingRequestId(String externalPendingReqId) throws PendingReqIdValidationException { try { - final byte[] externalPendingReqIdBytes = Base64.getUrlDecoder().decode(externalPendingReqId); - - if (externalPendingReqIdBytes.length > maxPendingReqIdSize) { - log.warn("pendingReqId size exceeds {}", maxPendingReqIdSize); - throw new PendingReqIdValidationException(null, "pendingReqId exceeds max.size: " + maxPendingReqIdSize); - - } - - final String stringToken = new String(externalPendingReqIdBytes); - if (StringUtils.countMatches(stringToken, TOKEN_SEPARATOR) == ENCODED_TOKEN_PARTS - 1) { - final String[] tokenElements = StringUtils.split(stringToken, - TOKEN_SEPARATOR, ENCODED_TOKEN_PARTS); - - final String internalPendingReqId = tokenElements[1]; - final DateTime timeStamp = TOKEN_TEXTUAL_DATE_FORMAT.parseDateTime(tokenElements[0]); + final String[] tokenElements = extractTokens(externalPendingReqId); + final String internalPendingReqId = tokenElements[1]; + final DateTime timeStamp = TOKEN_TEXTUAL_DATE_FORMAT.parseDateTime(tokenElements[0]); - log.trace("Checking HMAC from externalPendingReqId ... "); - final byte[] tokenDigest = Base64.getDecoder().decode(tokenElements[2]); - final byte[] refDigist = calculateHMAC(buildInternalToken(internalPendingReqId, timeStamp)); - if (!Arrays.equals(tokenDigest, refDigist)) { - log.warn("Digest of Token does NOT match"); - log.debug("Token: {} | Ref: {}", tokenDigest, refDigist); - throw new PendingReqIdValidationException(null, "Digest of pendingRequestId does NOT match"); - - } - log.debug("PendingRequestId HMAC digest check successful"); - - log.trace("Checking valid period ... "); - final DateTime now = DateTime.now(); - if (timeStamp.withFieldAdded( - DurationFieldType.seconds(), maxPendingRequestIdLifeTime).isBefore(now)) { - log.warn("Token exceeds the valid period"); - log.debug("Token: {} | Now: {}", timeStamp, now ); - throw new PendingReqIdValidationException(internalPendingReqId, "PendingRequestId exceeds the valid period"); - - } - log.debug("Token valid-period check successful"); + log.trace("Checking HMAC from externalPendingReqId ... "); + final byte[] tokenDigest = Base64.getDecoder().decode(tokenElements[2]); + final byte[] refDigist = calculateHMAC(buildInternalToken(internalPendingReqId, timeStamp)); + if (!Arrays.equals(tokenDigest, refDigist)) { + log.warn("Digest of Token does NOT match"); + log.debug("Token: {} | Ref: {}", tokenDigest, refDigist); + throw new PendingReqIdValidationException(null, "Digest of pendingRequestId does NOT match"); + + } + log.debug("PendingRequestId HMAC digest check successful"); + + log.trace("Checking valid period ... "); + final DateTime now = DateTime.now(); + if (timeStamp.withFieldAdded( + DurationFieldType.seconds(), maxPendingRequestIdLifeTime).isBefore(now)) { + log.warn("Token exceeds the valid period"); + log.debug("Token: {} | Now: {}", timeStamp, now ); + throw new PendingReqIdValidationException(internalPendingReqId, "PendingRequestId exceeds the valid period"); - return internalPendingReqId; - - } else { - log.warn("PendingRequestId has an unvalid format"); - log.debug("PendingRequestId: {}", stringToken); - throw new PendingReqIdValidationException(null, "PendingReqId has an unvalid format"); - } + log.debug("Token valid-period check successful"); + + return internalPendingReqId; + } catch (final IllegalArgumentException | EAAFIllegalStateException e) { log.warn("Token is NOT a valid String. Msg: {}", e.getMessage()); @@ -131,6 +125,38 @@ public class SecurePendingRequestIdGenerationStrategy implements IPendingRequest } } + @NonNull + private String[] extractTokens(@Nullable String externalPendingReqId) throws PendingReqIdValidationException { + if (StringUtils.isEmpty(externalPendingReqId)) { + log.info("PendingReqId is 'null' or empty"); + throw new PendingReqIdValidationException(null, "PendingReqId is 'null' or empty"); + + } + + log.trace("RAW external pendingReqId: {}", externalPendingReqId); + final byte[] externalPendingReqIdBytes = Base64.getUrlDecoder().decode(externalPendingReqId); + + if (externalPendingReqIdBytes.length > maxPendingReqIdSize) { + log.warn("pendingReqId size exceeds {}", maxPendingReqIdSize); + throw new PendingReqIdValidationException(null, "pendingReqId exceeds max.size: " + maxPendingReqIdSize); + + } + + final String stringToken = new String(externalPendingReqIdBytes); + if (StringUtils.countMatches(stringToken, TOKEN_SEPARATOR) == ENCODED_TOKEN_PARTS - 1) { + final String[] tokenElements = StringUtils.split(stringToken, + TOKEN_SEPARATOR, ENCODED_TOKEN_PARTS); + return tokenElements; + + } else { + log.warn("PendingRequestId has an unvalid format"); + log.debug("PendingRequestId: {}", stringToken); + throw new PendingReqIdValidationException(null, "PendingReqId has an unvalid format"); + + } + + } + @PostConstruct private void initialize() throws EAAFConfigurationException { diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/SimplePendingRequestIdGenerationStrategy.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/SimplePendingRequestIdGenerationStrategy.java index 59da3d06..6b8fe9b7 100644 --- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/SimplePendingRequestIdGenerationStrategy.java +++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/SimplePendingRequestIdGenerationStrategy.java @@ -5,6 +5,12 @@ import org.apache.commons.lang3.StringUtils; import at.gv.egiz.eaaf.core.api.utils.IPendingRequestIdGenerationStrategy; import at.gv.egiz.eaaf.core.exceptions.PendingReqIdValidationException; +/** + * Simple pendingRequestId generation strategy that facilitates no extended validation + * + * @author tlenz + * + */ public class SimplePendingRequestIdGenerationStrategy implements IPendingRequestIdGenerationStrategy { @Override @@ -15,11 +21,18 @@ public class SimplePendingRequestIdGenerationStrategy implements IPendingRequest @Override public String validateAndGetPendingRequestId(String pendingReqId) throws PendingReqIdValidationException { - if (StringUtils.isEmpty(pendingReqId)) - throw new PendingReqIdValidationException(pendingReqId, "PendingRequestId is empty or null"); - - return pendingReqId; + return getPendingRequestIdWithOutChecks(pendingReqId); } + @Override + public String getPendingRequestIdWithOutChecks(String externalPendingReqId) throws PendingReqIdValidationException { + if (StringUtils.isEmpty(externalPendingReqId)) + throw new PendingReqIdValidationException(externalPendingReqId, "PendingRequestId is empty or null"); + + + + return externalPendingReqId; + } + } -- cgit v1.2.3