This is an automated email from the ASF dual-hosted git repository.
pzampino pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/knox.git
The following commit(s) were added to refs/heads/master by this push:
new a43b1ff KNOX-2574 - Missing proper logging when hmac secret is short
(misconfigured) (#478)
a43b1ff is described below
commit a43b1ff1e304dcbcb90e277d998477fa3e5890d7
Author: Attila Magyar <[email protected]>
AuthorDate: Mon Aug 9 22:28:09 2021 +0200
KNOX-2574 - Missing proper logging when hmac secret is short
(misconfigured) (#478)
---
.../gateway/service/knoxtoken/TokenResource.java | 20 ++++++++++++---
.../knoxtoken/TokenServiceResourceTest.java | 29 +++++++++++++++++++++-
2 files changed, 45 insertions(+), 4 deletions(-)
diff --git
a/gateway-service-knoxtoken/src/main/java/org/apache/knox/gateway/service/knoxtoken/TokenResource.java
b/gateway-service-knoxtoken/src/main/java/org/apache/knox/gateway/service/knoxtoken/TokenResource.java
index d8b0441..244cbe9 100644
---
a/gateway-service-knoxtoken/src/main/java/org/apache/knox/gateway/service/knoxtoken/TokenResource.java
+++
b/gateway-service-knoxtoken/src/main/java/org/apache/knox/gateway/service/knoxtoken/TokenResource.java
@@ -48,6 +48,10 @@ import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
+import com.nimbusds.jose.JWSAlgorithm;
+import com.nimbusds.jose.KeyLengthException;
+import com.nimbusds.jose.crypto.MACSigner;
+import com.nimbusds.jose.util.ByteUtils;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.apache.knox.gateway.config.GatewayConfig;
@@ -152,7 +156,7 @@ public class TokenResource {
ServletContext context;
@PostConstruct
- public void init() throws AliasServiceException, ServiceLifecycleException {
+ public void init() throws AliasServiceException, ServiceLifecycleException,
KeyLengthException {
String audiences = context.getInitParameter(TOKEN_AUDIENCES_PARAM);
if (audiences != null) {
@@ -313,11 +317,21 @@ public class TokenResource {
}
}
- private void setSignatureAlogrithm() throws AliasServiceException {
+ private void setSignatureAlogrithm() throws AliasServiceException,
KeyLengthException {
final String configuredSigAlg = context.getInitParameter(TOKEN_SIG_ALG);
final GatewayConfig config = (GatewayConfig)
request.getServletContext().getAttribute(GatewayConfig.GATEWAY_CONFIG_ATTRIBUTE);
final GatewayServices services = (GatewayServices)
request.getServletContext().getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
- signatureAlgorithm = TokenUtils.getSignatureAlgorithm(configuredSigAlg,
(AliasService) services.getService(ServiceType.ALIAS_SERVICE),
config.getSigningKeystoreName());
+ AliasService aliasService = services.getService(ServiceType.ALIAS_SERVICE);
+ signatureAlgorithm = TokenUtils.getSignatureAlgorithm(configuredSigAlg,
aliasService, config.getSigningKeystoreName());
+ char[] hmacSecret =
aliasService.getPasswordFromAliasForGateway(TokenUtils.SIGNING_HMAC_SECRET_ALIAS);
+ if (hmacSecret != null && !isAlgCompatibleWithSecret(signatureAlgorithm,
hmacSecret)) {
+ throw new KeyLengthException(JWSAlgorithm.parse(signatureAlgorithm));
+ }
+ }
+
+ private boolean isAlgCompatibleWithSecret(String algName, char[] secret) {
+ return
MACSigner.getCompatibleAlgorithms(ByteUtils.bitLength(secret.length))
+ .contains(JWSAlgorithm.parse(algName));
}
private boolean isServerManagedTokenStateEnabled() {
diff --git
a/gateway-service-knoxtoken/src/test/java/org/apache/knox/gateway/service/knoxtoken/TokenServiceResourceTest.java
b/gateway-service-knoxtoken/src/test/java/org/apache/knox/gateway/service/knoxtoken/TokenServiceResourceTest.java
index 3a2f5bc..0069212 100644
---
a/gateway-service-knoxtoken/src/test/java/org/apache/knox/gateway/service/knoxtoken/TokenServiceResourceTest.java
+++
b/gateway-service-knoxtoken/src/test/java/org/apache/knox/gateway/service/knoxtoken/TokenServiceResourceTest.java
@@ -28,8 +28,10 @@ import static org.junit.Assert.fail;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
+import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.JWSSigner;
import com.nimbusds.jose.JWSVerifier;
+import com.nimbusds.jose.KeyLengthException;
import com.nimbusds.jose.crypto.RSASSASigner;
import com.nimbusds.jose.crypto.RSASSAVerifier;
@@ -108,6 +110,7 @@ public class TokenServiceResourceTest {
private HttpServletRequest request;
private JWTokenAuthority authority;
private TestTokenStateService tss;
+ private char[] hmacSecret;
private enum TokenLifecycleOperation {
Renew,
@@ -172,7 +175,7 @@ public class TokenServiceResourceTest {
AliasService aliasService = EasyMock.createNiceMock(AliasService.class);
EasyMock.expect(services.getService(ServiceType.ALIAS_SERVICE)).andReturn(aliasService).anyTimes();
-
EasyMock.expect(aliasService.getPasswordFromAliasForGateway(TokenUtils.SIGNING_HMAC_SECRET_ALIAS)).andReturn(null).anyTimes();
+
EasyMock.expect(aliasService.getPasswordFromAliasForGateway(TokenUtils.SIGNING_HMAC_SECRET_ALIAS)).andReturn(hmacSecret).anyTimes();
EasyMock.expect(aliasService.getPasswordFromAliasForGateway(TokenMAC.KNOX_TOKEN_HASH_KEY_ALIAS_NAME)).andReturn("sPj8FCgQhCEi6G18kBfpswxYSki33plbelGLs0hMSbk".toCharArray()).anyTimes();
authority = new TestJWTokenAuthority(publicKey, privateKey);
@@ -194,6 +197,30 @@ public class TokenServiceResourceTest {
EasyMock.replay(principal, services, context, request, aliasService,
config);
}
+ @Test(expected = KeyLengthException.class)
+ public void testInvalidHmacSecretThrowsException() throws Exception {
+ final Map<String, String> contextExpectations = new HashMap<>();
+ hmacSecret = "1234".toCharArray();
+ contextExpectations.put("knox.token.sigalg", JWSAlgorithm.HS256.getName());
+ configureCommonExpectations(contextExpectations);
+ TokenResource tr = new TokenResource();
+ tr.request = request;
+ tr.context = context;
+ tr.init();
+ }
+
+ @Test
+ public void testValidHmacSecretNoException() throws Exception {
+ final Map<String, String> contextExpectations = new HashMap<>();
+ hmacSecret = "12345678123456781234567812345678".toCharArray();
+ contextExpectations.put("knox.token.sigalg", JWSAlgorithm.HS256.getName());
+ configureCommonExpectations(contextExpectations);
+ TokenResource tr = new TokenResource();
+ tr.request = request;
+ tr.context = context;
+ tr.init();
+ }
+
@Test
public void testClientData() {
TokenResource tr = new TokenResource();