From 32b2430bd69cb16d83b33ffc0eca0607ce63804e Mon Sep 17 00:00:00 2001 From: msm1992 Date: Thu, 3 Oct 2024 10:23:11 +0530 Subject: [PATCH] Fix backend JWT x5t inconsistencies --- .../common/gateway/dto/JWTConfigurationDto.java | 9 +++++++++ .../AbstractAPIMgtGatewayJWTGenerator.java | 2 +- .../carbon/apimgt/common/gateway/util/JWTUtil.java | 13 +++++++++---- .../apimgt/common/gateway/JWTUtilTestCase.java | 4 ++-- .../org/wso2/carbon/apimgt/impl/APIConstants.java | 1 + .../carbon/apimgt/impl/APIManagerConfiguration.java | 6 ++++++ .../org.wso2.carbon.apimgt.core.default.json | 1 + .../templates/repository/conf/api-manager.xml.j2 | 1 + 8 files changed, 30 insertions(+), 7 deletions(-) diff --git a/components/apimgt/org.wso2.carbon.apimgt.common.gateway/src/main/java/org/wso2/carbon/apimgt/common/gateway/dto/JWTConfigurationDto.java b/components/apimgt/org.wso2.carbon.apimgt.common.gateway/src/main/java/org/wso2/carbon/apimgt/common/gateway/dto/JWTConfigurationDto.java index b532ae09fc29..62355224eb5d 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.common.gateway/src/main/java/org/wso2/carbon/apimgt/common/gateway/dto/JWTConfigurationDto.java +++ b/components/apimgt/org.wso2.carbon.apimgt.common.gateway/src/main/java/org/wso2/carbon/apimgt/common/gateway/dto/JWTConfigurationDto.java @@ -47,6 +47,7 @@ public class JWTConfigurationDto { private boolean enableBase64Padding = false; private boolean useKid; + private boolean isEncodeX5tWithoutPadding; public boolean useKid() { return useKid; @@ -209,4 +210,12 @@ public void setEnableBase64Padding(boolean enableBase64Padding) { public boolean isEnableBase64Padding() { return enableBase64Padding; } + + public boolean isEncodeX5tWithoutPadding() { + return isEncodeX5tWithoutPadding; + } + + public void setEncodeX5tWithoutPadding(boolean encodeX5tWithoutPadding) { + isEncodeX5tWithoutPadding = encodeX5tWithoutPadding; + } } diff --git a/components/apimgt/org.wso2.carbon.apimgt.common.gateway/src/main/java/org/wso2/carbon/apimgt/common/gateway/jwtgenerator/AbstractAPIMgtGatewayJWTGenerator.java b/components/apimgt/org.wso2.carbon.apimgt.common.gateway/src/main/java/org/wso2/carbon/apimgt/common/gateway/jwtgenerator/AbstractAPIMgtGatewayJWTGenerator.java index e8565e794256..5f45a232dcb3 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.common.gateway/src/main/java/org/wso2/carbon/apimgt/common/gateway/jwtgenerator/AbstractAPIMgtGatewayJWTGenerator.java +++ b/components/apimgt/org.wso2.carbon.apimgt.common.gateway/src/main/java/org/wso2/carbon/apimgt/common/gateway/jwtgenerator/AbstractAPIMgtGatewayJWTGenerator.java @@ -150,7 +150,7 @@ protected String addCertToHeader() throws JWTGeneratorException { try { Certificate publicCert = jwtConfigurationDto.getPublicCert(); return JWTUtil.generateHeader(publicCert, signatureAlgorithm, jwtConfigurationDto.useKid(), - useSHA256Hash); + useSHA256Hash, jwtConfigurationDto.isEncodeX5tWithoutPadding()); } catch (Exception e) { String error = "Error in obtaining keystore"; throw new JWTGeneratorException(error, e); diff --git a/components/apimgt/org.wso2.carbon.apimgt.common.gateway/src/main/java/org/wso2/carbon/apimgt/common/gateway/util/JWTUtil.java b/components/apimgt/org.wso2.carbon.apimgt.common.gateway/src/main/java/org/wso2/carbon/apimgt/common/gateway/util/JWTUtil.java index 6fb77cea855c..f12fa6c76359 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.common.gateway/src/main/java/org/wso2/carbon/apimgt/common/gateway/util/JWTUtil.java +++ b/components/apimgt/org.wso2.carbon.apimgt.common.gateway/src/main/java/org/wso2/carbon/apimgt/common/gateway/util/JWTUtil.java @@ -79,7 +79,7 @@ public static String getJWSCompliantAlgorithmCode(String signatureAlgorithm) { public static String generateHeader(Certificate publicCert, String signatureAlgorithm) throws JWTGeneratorException { - return generateHeader(publicCert, signatureAlgorithm, false, false); + return generateHeader(publicCert, signatureAlgorithm, false, false, false); } /** @@ -93,7 +93,7 @@ public static String generateHeader(Certificate publicCert, String signatureAlgo */ public static String generateHeader(Certificate publicCert, String signatureAlgorithm, boolean useKid, - boolean useSHA256Hash) + boolean useSHA256Hash, boolean encodeX5tWithoutPadding) throws JWTGeneratorException { /* @@ -113,8 +113,13 @@ public static String generateHeader(Certificate publicCert, String signatureAlgo byte[] digestInBytes = digestValue.digest(); String publicCertThumbprint = hexify(digestInBytes); String base64UrlEncodedThumbPrint; - base64UrlEncodedThumbPrint = java.util.Base64.getUrlEncoder() - .encodeToString(publicCertThumbprint.getBytes("UTF-8")); + if (encodeX5tWithoutPadding) { + base64UrlEncodedThumbPrint = java.util.Base64.getUrlEncoder().withoutPadding() + .encodeToString(publicCertThumbprint.getBytes("UTF-8")); + } else { + base64UrlEncodedThumbPrint = java.util.Base64.getUrlEncoder() + .encodeToString(publicCertThumbprint.getBytes("UTF-8")); + } JSONObject jwtHeader = new JSONObject(); jwtHeader.put("typ", "JWT"); diff --git a/components/apimgt/org.wso2.carbon.apimgt.common.gateway/src/test/java/org/wso2/carbon/apimgt/common/gateway/JWTUtilTestCase.java b/components/apimgt/org.wso2.carbon.apimgt.common.gateway/src/test/java/org/wso2/carbon/apimgt/common/gateway/JWTUtilTestCase.java index 5ab22aa44fc3..c0d4624ca758 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.common.gateway/src/test/java/org/wso2/carbon/apimgt/common/gateway/JWTUtilTestCase.java +++ b/components/apimgt/org.wso2.carbon.apimgt.common.gateway/src/test/java/org/wso2/carbon/apimgt/common/gateway/JWTUtilTestCase.java @@ -64,7 +64,7 @@ public void testJWTHeader() throws Exception { String signatureAlgorithm = "SHA256withRSA"; //Use SHA-256 as the certificate hashing algorithm - String jwt = JWTUtil.generateHeader(cert, signatureAlgorithm, true, true); + String jwt = JWTUtil.generateHeader(cert, signatureAlgorithm, true, true, false); Assert.assertNotNull(jwt); Assert.assertTrue(jwt.contains("kid")); @@ -74,7 +74,7 @@ public void testJWTHeader() throws Exception { Assert.assertTrue(jwt.contains("x5t#S256")); //Use SHA-1 as the certificate hashing algorithm - jwt = JWTUtil.generateHeader(cert, signatureAlgorithm, false, false); + jwt = JWTUtil.generateHeader(cert, signatureAlgorithm, false, false, false); Assert.assertNotNull(jwt); Assert.assertFalse(jwt.contains("kid")); diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIConstants.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIConstants.java index 1371076d2c3e..59176e27803c 100755 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIConstants.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIConstants.java @@ -473,6 +473,7 @@ public final class APIConstants { public static final String X5T256_PARAMETER = "x5t#S256"; public static final String GATEWAY_JWT_GENERATOR = "GatewayJWTGeneration"; public static final String GATEWAY_JWT_GENERATOR_IMPL = "ImplClass"; + public static final String ENCODE_X5T_WITHOUT_PADDING = "EncodeX5tWithoutPadding"; public static final String TOKEN_ISSUERS = "TokenIssuers"; public static final String GATEWAY_JWT_CONFIGURATION = "Configuration"; public static final String GATEWAY_JWT_GENERATOR_CLAIMS = "ExcludedClaims"; diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIManagerConfiguration.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIManagerConfiguration.java index b0073e9a9bfb..e649aa4cf6d4 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIManagerConfiguration.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIManagerConfiguration.java @@ -1727,6 +1727,12 @@ private void setJWTConfiguration(OMElement omElement) { OMElement configurationElement = gatewayJWTConfigurationElement .getFirstChildWithName(new QName(APIConstants.GATEWAY_JWT_CONFIGURATION)); + OMElement encodeX5tWithoutPaddingElement = gatewayJWTConfigurationElement + .getFirstChildWithName(new QName(APIConstants.ENCODE_X5T_WITHOUT_PADDING)); + if (encodeX5tWithoutPaddingElement != null) { + jwtConfigurationDto.setEncodeX5tWithoutPadding(Boolean.parseBoolean( + encodeX5tWithoutPaddingElement.getText())); + } if (configurationElement != null) { OMElement claimsElement = configurationElement diff --git a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/conf_templates/org.wso2.carbon.apimgt.core.default.json b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/conf_templates/org.wso2.carbon.apimgt.core.default.json index 32d81b6d5173..4dffb2974c98 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/conf_templates/org.wso2.carbon.apimgt.core.default.json +++ b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/conf_templates/org.wso2.carbon.apimgt.core.default.json @@ -28,6 +28,7 @@ "apim.jwt.signing_algorithm": "SHA256withRSA", "apim.jwt.claims_extractor_impl": "org.wso2.carbon.apimgt.impl.token.ExtendedDefaultClaimsRetriever", "apim.jwt.gateway_generator.impl":"org.wso2.carbon.apimgt.common.gateway.jwtgenerator.APIMgtGatewayJWTGeneratorImpl", + "apim.jwt.encode_x5t_without_padding": false, "apim.jwt.enable_tenant_based_signing": false, "apim.jwt.gateway_generator.enable_claim_retrieval": false, "apim.jwt.binding_federated_user_claims": false, diff --git a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/conf_templates/templates/repository/conf/api-manager.xml.j2 b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/conf_templates/templates/repository/conf/api-manager.xml.j2 index 63a216951e14..7a234c5fbfda 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/conf_templates/templates/repository/conf/api-manager.xml.j2 +++ b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/conf_templates/templates/repository/conf/api-manager.xml.j2 @@ -89,6 +89,7 @@ {% endif %} {{apim.jwt.gateway_generator.impl}} + {{apim.jwt.encode_x5t_without_padding}} {%- for claim in apim.jwt.gateway_generator.excluded_claims -%}