Skip to content

Commit 0211271

Browse files
committed
docker images security issues fixes
Signed-off-by: Md-Humair-KK <mdhumair.kankudti@gmail.com>
2 parents 768a606 + ae23920 commit 0211271

38 files changed

Lines changed: 788 additions & 72 deletions

api-test/src/main/java/io/mosip/testrig/apirig/esignet/testrunner/MosipTestRunner.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ public static void main(String[] arg) {
8686
}
8787
AdminTestUtil.init();
8888
EsignetConfigManager.init();
89+
EsignetUtil.getIdentityPluginNameFromEsignetActuator();
90+
EsignetUtil.getEsignetServerProfileFromActuator();
8991
suiteSetup(getRunType());
9092
SkipTestCaseHandler.loadTestcaseToBeSkippedList("testCaseSkippedList.txt");
9193
GlobalMethods.setModuleNameAndReCompilePattern(EsignetConfigManager.getproperty("moduleNamePattern"));

api-test/src/main/java/io/mosip/testrig/apirig/esignet/utils/EsignetConstants.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,12 @@ public class EsignetConstants {
3838
public static final String LANGUAGE = "language";
3939
public static final String VALUE = "value";
4040

41-
41+
public static final String MOSIP_ESIGNET_SERVER_PROFILE = "mosip.esignet.server.profile";
42+
43+
public static final String FAPI2_0_SERVER_PROFILE = "fapi2.0";
44+
45+
public static final String FAPI_TEST_CASE_PATH = "esignet/FAPI";
46+
47+
public static final String FAPI_PREREQUISITE_TEST_CASE_MARKER = "For_FAPI";
48+
4249
}

api-test/src/main/java/io/mosip/testrig/apirig/esignet/utils/EsignetUtil.java

Lines changed: 174 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ public class EsignetUtil extends AdminTestUtil {
8080

8181
private static final Logger logger = Logger.getLogger(EsignetUtil.class);
8282
public static String pluginName = null;
83+
public static String esignetServerProfile = null;
8384
private static Faker faker = new Faker();
8485
private static String fullNameForSunBirdR = generateFullNameForSunBirdR();
8586
private static String dobForSunBirdR = generateDobForSunBirdR();
@@ -135,6 +136,51 @@ public static String getIdentityPluginNameFromEsignetActuator() {
135136

136137
return pluginName;
137138
}
139+
140+
public static String getEsignetServerProfileFromActuator() {
141+
if (esignetServerProfile != null && !esignetServerProfile.isBlank()) {
142+
return esignetServerProfile;
143+
}
144+
esignetServerProfile = getValueFromEsignetActuator(EsignetConstants.CLASS_PATH_APPLICATION_PROPERTIES,
145+
EsignetConstants.MOSIP_ESIGNET_SERVER_PROFILE);
146+
if (esignetServerProfile == null) {
147+
esignetServerProfile = "";
148+
logger.warn("Esignet server profile not found from actuator; defaulting to empty");
149+
} else {
150+
logger.info("Esignet server profile from actuator = " + esignetServerProfile);
151+
}
152+
return esignetServerProfile;
153+
}
154+
155+
private static boolean isFapi2ServerProfile() {
156+
return EsignetConstants.FAPI2_0_SERVER_PROFILE.equalsIgnoreCase(getEsignetServerProfileFromActuator());
157+
}
158+
159+
private static boolean isFapiTestCase(TestCaseDTO testCaseDTO) {
160+
if (testCaseDTO == null) {
161+
return false;
162+
}
163+
String inputTemplate = testCaseDTO.getInputTemplate();
164+
if (inputTemplate != null && inputTemplate.contains(EsignetConstants.FAPI_TEST_CASE_PATH)) {
165+
return true;
166+
}
167+
String outputTemplate = testCaseDTO.getOutputTemplate();
168+
if (outputTemplate != null && outputTemplate.contains(EsignetConstants.FAPI_TEST_CASE_PATH)) {
169+
return true;
170+
}
171+
String uniqueIdentifier = testCaseDTO.getUniqueIdentifier();
172+
if (uniqueIdentifier != null && uniqueIdentifier.contains("_FAPI_")) {
173+
return true;
174+
}
175+
String testCaseName = testCaseDTO.getTestCaseName();
176+
if (testCaseName != null
177+
&& testCaseName.contains(EsignetConstants.FAPI_PREREQUISITE_TEST_CASE_MARKER)) {
178+
return true;
179+
}
180+
String description = testCaseDTO.getDescription();
181+
return description != null && description.toLowerCase().contains("for fapi");
182+
}
183+
138184
public static String getPluginName() {
139185
try {
140186
String pluginServiceName = EsignetUtil.getIdentityPluginNameFromEsignetActuator().toLowerCase();
@@ -196,7 +242,21 @@ public static String isTestCaseValidForExecution(TestCaseDTO testCaseDTO) {
196242
if (MosipTestRunner.skipAll == true) {
197243
throw new SkipException(GlobalConstants.PRE_REQUISITE_FAILED_MESSAGE);
198244
}
199-
245+
246+
if (isFapi2ServerProfile() && !isFapiTestCase(testCaseDTO)) {
247+
String pluginServiceName = getIdentityPluginNameFromEsignetActuator().toLowerCase();
248+
String endpoint = testCaseDTO.getEndPoint();
249+
if (pluginServiceName.contains("mockauthenticationservice")) {
250+
// mock + fapi2.0: skip all non-FAPI tests
251+
throw new SkipException(GlobalConstants.FEATURE_NOT_SUPPORTED_MESSAGE);
252+
}
253+
if (pluginServiceName.contains("idaauthenticatorimpl")
254+
&& endpoint != null
255+
&& (endpoint.contains("/esignet/") || endpoint.contains("$GETENDPOINTFROMWELLKNOWN$"))) {
256+
// mosipid + fapi2.0: skip non-FAPI esignet tests; allow setup endpoints (PMS/partner/identity)
257+
throw new SkipException(GlobalConstants.FEATURE_NOT_SUPPORTED_MESSAGE);
258+
}
259+
}
200260

201261
if (getIdentityPluginNameFromEsignetActuator().toLowerCase().contains("mockauthenticationservice")) {
202262
// TO DO - need to conform whether esignet distinguishes between UIN and VID. BAsed on that need to remove VID test case from YAML.
@@ -220,15 +280,16 @@ public static String isTestCaseValidForExecution(TestCaseDTO testCaseDTO) {
220280
|| testCaseName.contains("ESignet_CreateOIDCClient_StatusCode_Diff_Token_Neg"))) {
221281
throw new SkipException(GlobalConstants.FEATURE_NOT_SUPPORTED_MESSAGE);
222282
}
223-
if ((testCaseName.contains("_UpdateOIDCClientV3_MOSIPID_")
224-
|| testCaseName.contains("_OAuthDetailsRequest_V3_MOSIPID_")
225-
|| testCaseName.contains("_AuthenticateUser_V3_MOSIPID_")
226-
|| testCaseName.contains("_AuthorizationCode_MOSIPID_")
227-
|| testCaseName.contains("_GenerateToken_MOSIPID_")
228-
|| testCaseName.contains("_GetOidcUserInfo_MOSIPID_")
229-
|| testCaseName.contains("FAPIPatchClientConfig_MOSIPID_"))) {
230-
throw new SkipException(GlobalConstants.FEATURE_NOT_SUPPORTED_MESSAGE);
231-
}
283+
if ((testCaseName.contains("_UpdateOIDCClientV3_MOSIPID_")
284+
|| testCaseName.contains("_OAuthDetailsRequest_V3_MOSIPID_")
285+
|| testCaseName.contains("_AuthenticateUser_V3_MOSIPID_")
286+
|| testCaseName.contains("_AuthorizationCode_MOSIPID_")
287+
|| testCaseName.contains("_GenerateToken_MOSIPID_")
288+
|| testCaseName.contains("_GetOidcUserInfo_MOSIPID_")
289+
|| testCaseName.contains("FAPIPatchClientConfig_MOSIPID_")
290+
|| testCaseName.contains("PKCEPatchClientConfig_MOSIPID_"))) {
291+
throw new SkipException(GlobalConstants.FEATURE_NOT_SUPPORTED_MESSAGE);
292+
}
232293

233294
} else if (getIdentityPluginNameFromEsignetActuator().toLowerCase().contains("idaauthenticatorimpl")) {
234295
// Let run test cases eSignet & MOSIP API calls --- both UIN and VID
@@ -255,24 +316,25 @@ public static String isTestCaseValidForExecution(TestCaseDTO testCaseDTO) {
255316
|| testCaseName.equals("ESignet_PartialUpdateOIDCClient_MOCK_Missing_kid_value_Neg")
256317
|| testCaseName.equals("ESignet_PartialUpdateOIDCClient_MOCK_Duplicate_EncKey_forUserInfoUpdateJWE_Neg")
257318
|| testCaseName.equals("ESignet_PartialUpdateOIDCClient_MOCK_Different_Encryption_alg_value_Pos")
258-
|| testCaseName.equals("ESignet_CreateOIDCClientFAPI_all_Valid_Smoke_sid")
259-
|| testCaseName.equals("ESignet_CreateOIDCClientFAPI_all_Valid_forUserInfoJWE_Smoke_sid")
260-
|| testCaseName.equals("ESignet_FAPIPartialUpdateOIDCClient_all_Valid_forUserInfoJWE_Smoke_sid"))
319+
|| testCaseName.equals("ESignet_CreateOIDCClientFAPI_all_Valid_Smoke_sid")
320+
|| testCaseName.equals("ESignet_CreateOIDCClientFAPI_all_Valid_forUserInfoJWE_Smoke_sid")
321+
|| testCaseName.equals("ESignet_FAPIPartialUpdateOIDCClient_all_Valid_forUserInfoJWE_Smoke_sid")
322+
|| testCaseName.equals("ESignet_CreateOIDCClient_PKCE_JWE_Valid_Smoke_sid"))
261323
&& (endpoint.contains("/v1/esignet/client-mgmt/client")
262324
|| endpoint.contains("/v1/esignet/client-mgmt/client/{clientId}")
263325
|| endpoint.contains("/v1/esignet/client-mgmt/oauth-client")))) {
264326
throw new SkipException(GlobalConstants.FEATURE_NOT_SUPPORTED_MESSAGE);
265327
}
266328

267-
if ((testCaseName.contains("_CreateOIDCClientV3_MOCK_")
268-
|| testCaseName.contains("_UpdateOIDCClientV3_MOCK_")
269-
|| testCaseName.contains("_OAuthDetailsRequest_V3_MOCK_")
270-
|| testCaseName.contains("_AuthenticateUser_V3_MOCK_")
271-
|| testCaseName.contains("_AuthorizationCode_MOCK_")
272-
|| testCaseName.contains("_GenerateToken_MOCK_")
273-
|| testCaseName.contains("_GetOidcUserInfo_MOCK_"))) {
274-
throw new SkipException(GlobalConstants.FEATURE_NOT_SUPPORTED_MESSAGE);
275-
}
329+
if ((testCaseName.contains("_CreateOIDCClientV3_MOCK_")
330+
|| testCaseName.contains("_UpdateOIDCClientV3_MOCK_")
331+
|| testCaseName.contains("_OAuthDetailsRequest_V3_MOCK_")
332+
|| testCaseName.contains("_AuthenticateUser_V3_MOCK_")
333+
|| testCaseName.contains("_AuthorizationCode_MOCK_")
334+
|| testCaseName.contains("_GenerateToken_MOCK_")
335+
|| testCaseName.contains("_GetOidcUserInfo_MOCK_"))) {
336+
throw new SkipException(GlobalConstants.FEATURE_NOT_SUPPORTED_MESSAGE);
337+
}
276338

277339
JSONArray individualBiometricsArray = new JSONArray(
278340
getValueFromAuthActuator("json-property", "individualBiometrics"));
@@ -494,35 +556,11 @@ public static String inputstringKeyWordHandeler(String jsonString, String testCa
494556
}
495557
}
496558

497-
if (jsonString.contains("$CODE_CHALLENGE$")
498-
|| jsonString.contains("$CODE_VERIFIER$")
499-
|| jsonString.contains("$CODE_CHALLENGE_METHOD$")) {
500-
501-
Map<String, String> pkce;
502-
503-
String key = "GLOBAL_PKCE";
559+
jsonString = resolvePkceTokens(jsonString, "GLOBAL_PKCE",
560+
"$CODE_CHALLENGE$", "$CODE_VERIFIER$", "$CODE_CHALLENGE_METHOD$");
504561

505-
if (pkceCache.containsKey(key)) {
506-
pkce = pkceCache.get(key);
507-
logger.info("Reusing PKCE");
508-
} else {
509-
pkce = generatePKCE();
510-
pkceCache.put(key, pkce);
511-
logger.info("Generated new PKCE");
512-
}
513-
514-
if (jsonString.contains("$CODE_CHALLENGE$")) {
515-
jsonString = replaceKeywordValue(jsonString, "$CODE_CHALLENGE$", pkce.get("code_challenge"));
516-
}
517-
518-
if (jsonString.contains("$CODE_VERIFIER$")) {
519-
jsonString = replaceKeywordValue(jsonString, "$CODE_VERIFIER$", pkce.get("code_verifier"));
520-
}
521-
522-
if (jsonString.contains("$CODE_CHALLENGE_METHOD$")) {
523-
jsonString = replaceKeywordValue(jsonString, "$CODE_CHALLENGE_METHOD$", pkce.get("method"));
524-
}
525-
}
562+
jsonString = resolvePkceTokens(jsonString, "PKCE_JWE_FLOW",
563+
"$CODE_CHALLENGE_PKCE_JWE$", "$CODE_VERIFIER_PKCE_JWE$", "$CODE_CHALLENGE_METHOD_PKCE_JWE$");
526564

527565
if (jsonString.contains("$BINDINGJWKKEY$")) {
528566
String jwkKey = "";
@@ -825,6 +863,17 @@ public static String inputstringKeyWordHandeler(String jsonString, String testCa
825863
jsonString = replaceKeywordValue(jsonString, "$OIDC_JWK_KEY_FAPI_JWE$", jwkKey);
826864
}
827865

866+
if (jsonString.contains("$OIDC_JWK_KEY_PKCE_JWE$")) {
867+
String jwkKey = "";
868+
if (getTriggerESignetKeyGenForPKCEJWE()) {
869+
jwkKey = JWKKeyUtil.generateAndCacheJWKKey(OIDC_JWK_FOR_PKCE_JWE);
870+
setTriggerESignetKeyGenForPKCEJWE(false);
871+
} else {
872+
jwkKey = JWKKeyUtil.getJWKKey(OIDC_JWK_FOR_PKCE_JWE);
873+
}
874+
jsonString = replaceKeywordValue(jsonString, "$OIDC_JWK_KEY_PKCE_JWE$", jwkKey);
875+
}
876+
828877
if (jsonString.contains("$OIDC_JWK_KEY_FAPI$")) {
829878
String jwkKey = "";
830879
if (getTriggerESignetKeyGenForFAPI()) {
@@ -1088,6 +1137,36 @@ public static String inputstringKeyWordHandeler(String jsonString, String testCa
10881137
}
10891138
}
10901139

1140+
if (jsonString.contains("$CLIENT_ASSERTION_PKCE_JWE_JWT$")) {
1141+
String oidcJWKKeyString = JWKKeyUtil.getJWKKey(OIDC_JWK_FOR_PKCE_JWE);
1142+
logger.info("oidcJWKKeyString =" + oidcJWKKeyString);
1143+
try {
1144+
oidc_JWK_Key_For_PKCE_JWE = RSAKey.parse(oidcJWKKeyString);
1145+
logger.info("oidc_JWK_Key_For_PKCE_JWE =" + oidc_JWK_Key_For_PKCE_JWE);
1146+
} catch (java.text.ParseException e) {
1147+
logger.error(e.getMessage());
1148+
}
1149+
1150+
JSONObject root = new JSONObject(jsonString);
1151+
String clientId = root.optString("client_id", null);
1152+
String audKey = null;
1153+
1154+
if (root.has("aud_key")) {
1155+
audKey = root.optString("aud_key", null);
1156+
root.remove("aud_key");
1157+
jsonString = root.toString();
1158+
}
1159+
1160+
String tempUrl = getValueFromEsignetWellKnownEndPoint(audKey, EsignetConfigManager.getEsignetBaseUrl());
1161+
1162+
if (clientId != null) {
1163+
jsonString = replaceKeywordValue(jsonString, "$CLIENT_ASSERTION_PKCE_JWE_JWT$",
1164+
signJWKKey(clientId, oidc_JWK_Key_For_PKCE_JWE, tempUrl));
1165+
} else {
1166+
logger.error("Client ID not found in JSON for $CLIENT_ASSERTION_PKCE_JWE_JWT$.");
1167+
}
1168+
}
1169+
10911170
if (jsonString.contains("$CLIENT_ASSERTION_FAPI_JWT$")) {
10921171
String fapiJwkKeyName = getFapiJwkKeyName(testCaseName);
10931172
String oidcJWKKeyString = JWKKeyUtil.getJWKKey(fapiJwkKeyName);
@@ -2019,6 +2098,7 @@ public static String getValueFromEsignetWellKnownEndPoint(String key, String bas
20192098
protected static final String OIDC_JWK_FOR_DPoP = "oidcJWKForDPoP";
20202099
protected static final String OIDC_JWK_FOR_FAPI = "oidcJWKForFAPI";
20212100
protected static final String OIDC_JWK_FOR_FAPI_JWE = "oidcJWKForFAPIJWE";
2101+
protected static final String OIDC_JWK_FOR_PKCE_JWE = "oidcJWKForPKCEJWE";
20222102

20232103
protected static RSAKey oidcJWKKey1 = null;
20242104
protected static RSAKey oidcJWKKey3 = null;
@@ -2037,6 +2117,7 @@ public static String getValueFromEsignetWellKnownEndPoint(String key, String bas
20372117
protected static RSAKey oidc_JWK_Key_For_DPoP = null;
20382118
protected static RSAKey oidc_JWK_Key_For_FAPI = null;
20392119
protected static RSAKey oidc_JWK_Key_For_FAPI_JWE = null;
2120+
protected static RSAKey oidc_JWK_Key_For_PKCE_JWE = null;
20402121

20412122
protected static boolean triggerESignetKeyGen1 = true;
20422123
protected static boolean triggerESignetKeyGen2 = true;
@@ -2079,6 +2160,7 @@ public static String getValueFromEsignetWellKnownEndPoint(String key, String bas
20792160
protected static boolean triggerESignetKeyGenForDPoP = true;
20802161
protected static boolean triggerESignetKeyGenForFAPI = true;
20812162
protected static boolean triggerESignetKeyGenForFAPIJWE = true;
2163+
protected static boolean triggerESignetKeyGenForPKCEJWE = true;
20822164

20832165
private static String getFapiJwkKeyName(String testCaseName) {
20842166
if (testCaseName != null
@@ -2199,6 +2281,14 @@ private static boolean getTriggerESignetKeyGenForFAPIJWE() {
21992281
private static void setTriggerESignetKeyGenForFAPIJWE(boolean value) {
22002282
triggerESignetKeyGenForFAPIJWE = value;
22012283
}
2284+
2285+
private static boolean getTriggerESignetKeyGenForPKCEJWE() {
2286+
return triggerESignetKeyGenForPKCEJWE;
2287+
}
2288+
2289+
private static void setTriggerESignetKeyGenForPKCEJWE(boolean value) {
2290+
triggerESignetKeyGenForPKCEJWE = value;
2291+
}
22022292

22032293
private static void settriggerESignetKeyGen2(boolean value) {
22042294
triggerESignetKeyGen2 = value;
@@ -2807,6 +2897,40 @@ public static List<String> extractTokensFromResponse(String responseBody) throws
28072897
return tokens;
28082898
}
28092899

2900+
private static String resolvePkceTokens(String jsonString,
2901+
String cacheKey,
2902+
String challengeToken,
2903+
String verifierToken,
2904+
String methodToken) {
2905+
2906+
if (!jsonString.contains(challengeToken)
2907+
&& !jsonString.contains(verifierToken)
2908+
&& !jsonString.contains(methodToken)) {
2909+
return jsonString;
2910+
}
2911+
2912+
Map<String, String> pkce;
2913+
if (pkceCache.containsKey(cacheKey)) {
2914+
pkce = pkceCache.get(cacheKey);
2915+
logger.info("Reusing PKCE for " + cacheKey);
2916+
} else {
2917+
pkce = generatePKCE();
2918+
pkceCache.put(cacheKey, pkce);
2919+
logger.info("Generated new PKCE for " + cacheKey);
2920+
}
2921+
2922+
if (jsonString.contains(challengeToken)) {
2923+
jsonString = replaceKeywordValue(jsonString, challengeToken, pkce.get("code_challenge"));
2924+
}
2925+
if (jsonString.contains(verifierToken)) {
2926+
jsonString = replaceKeywordValue(jsonString, verifierToken, pkce.get("code_verifier"));
2927+
}
2928+
if (jsonString.contains(methodToken)) {
2929+
jsonString = replaceKeywordValue(jsonString, methodToken, pkce.get("method"));
2930+
}
2931+
return jsonString;
2932+
}
2933+
28102934
public static Map<String, String> generatePKCE() {
28112935
try {
28122936
byte[] randomBytes = new byte[32];

0 commit comments

Comments
 (0)