From 61e95672a4a89e8356a231a0bb9d488d8cce8d3f Mon Sep 17 00:00:00 2001 From: Savindu Dimal Date: Sun, 17 Mar 2024 19:47:19 +0530 Subject: [PATCH] Add mutual ssl certificate validation test case Add mutual ssl certificate validation test case for head only exported client certificate Remove unnecessary user and application creation --- ...SSLCertificateChainValidationTestCase.java | 116 ++++++------------ .../mutualssl/cert_chain_client_head_only.jks | Bin 0 -> 2371 bytes .../mutualssl/cert_chain_intermediate.cer | 23 ++++ 3 files changed, 61 insertions(+), 78 deletions(-) create mode 100644 modules/integration/tests-integration/tests-backend/src/test/resources/artifacts/AM/lifecycletest/mutualssl/cert_chain_client_head_only.jks create mode 100644 modules/integration/tests-integration/tests-backend/src/test/resources/artifacts/AM/lifecycletest/mutualssl/cert_chain_intermediate.cer diff --git a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/api/lifecycle/APISecurityMutualSSLCertificateChainValidationTestCase.java b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/api/lifecycle/APISecurityMutualSSLCertificateChainValidationTestCase.java index ff50343ff6..41bc01cd91 100644 --- a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/api/lifecycle/APISecurityMutualSSLCertificateChainValidationTestCase.java +++ b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/api/lifecycle/APISecurityMutualSSLCertificateChainValidationTestCase.java @@ -26,24 +26,17 @@ import org.testng.annotations.Factory; import org.testng.annotations.Test; import org.wso2.am.integration.clients.publisher.api.ApiException; -import org.wso2.am.integration.clients.publisher.api.ApiResponse; import org.wso2.am.integration.clients.publisher.api.v1.dto.APIDTO; import org.wso2.am.integration.clients.publisher.api.v1.dto.APIOperationsDTO; -import org.wso2.am.integration.clients.store.api.v1.dto.ApplicationDTO; -import org.wso2.am.integration.clients.store.api.v1.dto.ApplicationKeyDTO; -import org.wso2.am.integration.clients.store.api.v1.dto.ApplicationKeyGenerateRequestDTO; import org.wso2.am.integration.test.utils.APIManagerIntegrationTestException; import org.wso2.am.integration.test.utils.base.APIMIntegrationConstants; -import org.wso2.am.integration.test.utils.bean.APILifeCycleAction; import org.wso2.am.integration.test.utils.bean.APIRequest; import org.wso2.am.integration.test.utils.http.HTTPSClientUtils; -import org.wso2.am.integration.test.utils.http.HttpRequestUtil; import org.wso2.carbon.automation.engine.annotations.ExecutionEnvironment; import org.wso2.carbon.automation.engine.annotations.SetEnvironment; import org.wso2.carbon.automation.engine.context.TestUserMode; import org.wso2.carbon.automation.test.utils.http.client.HttpResponse; import org.wso2.carbon.integration.common.utils.exceptions.AutomationUtilException; -import org.wso2.carbon.um.ws.api.stub.ClaimValue; import org.wso2.carbon.um.ws.api.stub.RemoteUserStoreManagerServiceUserStoreExceptionException; import org.wso2.carbon.user.core.UserStoreException; @@ -51,7 +44,6 @@ import java.io.File; import java.io.IOException; import java.net.URL; -import java.rmi.RemoteException; import java.security.KeyManagementException; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; @@ -65,16 +57,12 @@ public class APISecurityMutualSSLCertificateChainValidationTestCase extends APIManagerLifecycleBaseTest { private final String rootCertAPI = "rootCertAPI"; + private final String intermediateCertAPI = "intermediateCertAPI"; private final String API_END_POINT_METHOD = "/customers/123"; private final String API_VERSION_1_0_0 = "1.0.0"; - private final String APPLICATION_NAME = "APISecurityMutualSSLCertificateChainValidationTestCase"; - private String accessToken; private final String API_END_POINT_POSTFIX_URL = "jaxrs_basic/services/customers/customerservice/"; private String apiEndPointUrl; - private String applicationId; - private String apiId1; - String users[] = { "apisecUser", "apisecUser2@wso2.com", "apisecUser2@abc.com" }; - String endUserPassword = "password@123"; + private String apiId1, apiId2; @DataProvider public static Object[][] userModeDataProvider() { @@ -83,15 +71,6 @@ public static Object[][] userModeDataProvider() { new Object[] { TestUserMode.TENANT_ADMIN } }; } - private void createUser() - throws RemoteException, RemoteUserStoreManagerServiceUserStoreExceptionException, UserStoreException { - - for (String user : users) { - remoteUserStoreManagerServiceClient.addUser(user, endUserPassword, new String[] {}, new ClaimValue[] {}, - "default", false); - } - } - @Factory(dataProvider = "userModeDataProvider") public APISecurityMutualSSLCertificateChainValidationTestCase(TestUserMode userMode) { @@ -105,7 +84,6 @@ public void initialize() throws APIManagerIntegrationTestException, IOException, UserStoreException { super.init(userMode); - createUser(); apiEndPointUrl = backEndServerUrl.getWebAppURLHttp() + API_END_POINT_POSTFIX_URL; APIRequest apiRequest1 = new APIRequest(rootCertAPI, rootCertAPI, new URL(apiEndPointUrl)); @@ -136,60 +114,44 @@ public void initialize() throws APIManagerIntegrationTestException, IOException, HttpResponse response1 = restAPIPublisher.addAPI(apiRequest1); apiId1 = response1.getData(); - String certOne = getAMResourceLocation() + File.separator + "lifecycletest" + File.separator + "mutualssl" + String rootCertPath = getAMResourceLocation() + File.separator + "lifecycletest" + File.separator + "mutualssl" + File.separator + "cert_chain_root.cer"; - restAPIPublisher.uploadCertificate(new File(certOne), "example", apiId1, + restAPIPublisher.uploadCertificate(new File(rootCertPath), "cert_chain_root", apiId1, APIMIntegrationConstants.API_TIER.UNLIMITED); - } - - @Test(description = "This test case tests the behaviour of internal Key token on Created API with authentication " - + "types") - public void testCreateAndDeployRevisionWithInternalKeyTesting() - throws JSONException, ApiException, XPathExpressionException, APIManagerIntegrationTestException, - IOException, org.wso2.am.integration.clients.store.api.ApiException, InterruptedException { - createAPIRevisionAndDeployUsingRest(apiId1, restAPIPublisher); - APIDTO api1 = restAPIPublisher.getAPIByID(apiId1); - waitForAPIDeploymentSync(api1.getProvider(), api1.getName(), api1.getVersion(), - APIMIntegrationConstants.IS_API_EXISTS); - ApiResponse keyDTOApiResponse1 = restAPIPublisher.generateInternalApiKey( - apiId1); - Assert.assertEquals(keyDTOApiResponse1.getStatusCode(), 200); - HttpResponse httpResponse1 = invokeApiWithInternalKey(rootCertAPI, API_VERSION_1_0_0, API_END_POINT_METHOD, - keyDTOApiResponse1.getData().getApikey()); - Assert.assertEquals(httpResponse1.getResponseCode(), 200); - restAPIPublisher.changeAPILifeCycleStatus(apiId1, APILifeCycleAction.PUBLISH.getAction()); - - HttpResponse applicationResponse = restAPIStore.createApplication(APPLICATION_NAME, "Test Application", - APIMIntegrationConstants.APPLICATION_TIER.UNLIMITED, ApplicationDTO.TokenTypeEnum.JWT); - applicationId = applicationResponse.getData(); - ArrayList grantTypes = new ArrayList(); - grantTypes.add(APIMIntegrationConstants.GRANT_TYPE.PASSWORD); - grantTypes.add(APIMIntegrationConstants.GRANT_TYPE.CLIENT_CREDENTIAL); - ApplicationKeyDTO applicationKeyDTO = restAPIStore.generateKeys(applicationId, "36000", "", - ApplicationKeyGenerateRequestDTO.KeyTypeEnum.PRODUCTION, null, grantTypes); - //get access token - accessToken = applicationKeyDTO.getToken().getAccessToken(); + APIRequest apiRequest2 = new APIRequest(intermediateCertAPI, intermediateCertAPI, new URL(apiEndPointUrl)); + apiRequest2.setVersion(API_VERSION_1_0_0); + apiRequest2.setTiersCollection(APIMIntegrationConstants.API_TIER.UNLIMITED); + apiRequest2.setTier(APIMIntegrationConstants.API_TIER.UNLIMITED); + apiRequest2.setTags(API_TAGS); + apiRequest2.setVisibility(APIDTO.VisibilityEnum.PUBLIC.getValue()); + apiRequest2.setProvider(user.getUserName()); + apiRequest2.setOperationsDTOS(operationsDTOS); + apiRequest2.setSecurityScheme(securitySchemes); + apiRequest2.setDefault_version("true"); + apiRequest2.setHttps_checked("https"); + apiRequest2.setHttp_checked(null); + apiRequest2.setDefault_version_checked("true"); + HttpResponse response2 = restAPIPublisher.addAPI(apiRequest2); + apiId2 = response2.getData(); + + String intermediateCertPath = getAMResourceLocation() + File.separator + "lifecycletest" + File.separator + "mutualssl" + + File.separator + "cert_chain_intermediate.cer"; + restAPIPublisher.uploadCertificate(new File(intermediateCertPath), "cert_chain_intermediate", apiId2, + APIMIntegrationConstants.API_TIER.UNLIMITED); + createAPIRevisionAndDeployUsingRest(apiId2, restAPIPublisher); - HttpResponse httpResponseAfterPublish = invokeApiWithInternalKey(rootCertAPI, API_VERSION_1_0_0, - API_END_POINT_METHOD, keyDTOApiResponse1.getData().getApikey()); - Assert.assertEquals(httpResponseAfterPublish.getResponseCode(), 200); + waitForAPIDeploymentSync(user.getUserName(), rootCertAPI, API_VERSION_1_0_0, + APIMIntegrationConstants.IS_API_EXISTS); + waitForAPIDeploymentSync(user.getUserName(), intermediateCertAPI, API_VERSION_1_0_0, + APIMIntegrationConstants.IS_API_EXISTS); // wait until certificates loaded Thread.sleep(120000); } - private HttpResponse invokeApiWithInternalKey(String context, String version, String resource, String internalKey) - throws XPathExpressionException, IOException { - - Map requestHeaders = new HashMap<>(); - requestHeaders.put("accept", "application/json"); - requestHeaders.put("Internal-Key", internalKey); - return HttpRequestUtil.doGet(getAPIInvocationURLHttps(context, version) + resource, requestHeaders); - } - - @Test(description = "Invoke mutual SSL only API with not supported certificate", dependsOnMethods = "testCreateAndDeployRevisionWithInternalKeyTesting") + @Test(description = "Invoke mutual SSL only API with not supported certificate") public void testAPIInvocationWithMutualSSLOnlyAPINegative() throws IOException, XPathExpressionException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException, UnrecoverableKeyException { @@ -215,7 +177,6 @@ public void testAPIInvocationWithMutualSSLMandatory() Map requestHeaders = new HashMap<>(); requestHeaders.put("accept", "text/xml"); - requestHeaders.put("Authorization", "Bearer " + accessToken); // Using root certificate HttpResponse rootCertResponse = HTTPSClientUtils.doMutulSSLGet( @@ -231,6 +192,13 @@ public void testAPIInvocationWithMutualSSLMandatory() getAPIInvocationURLHttps(rootCertAPI, API_VERSION_1_0_0) + API_END_POINT_METHOD, requestHeaders); Assert.assertEquals(clientCertResponse.getResponseCode(), HttpStatus.SC_OK, "Mutual SSL Authentication has not succeed"); + // Using client certificate with head only exported certificate + HttpResponse headOnlyClientCertResponse = HTTPSClientUtils.doMutulSSLGet( + getAMResourceLocation() + File.separator + "lifecycletest" + File.separator + "mutualssl" + + File.separator + "cert_chain_client_head_only.jks", + getAPIInvocationURLHttps(rootCertAPI, API_VERSION_1_0_0) + API_END_POINT_METHOD, requestHeaders); + Assert.assertEquals(headOnlyClientCertResponse.getResponseCode(), HttpStatus.SC_OK, "Mutual SSL Authentication has not succeed"); + // For default API version with root certificate HttpResponse defaultRootCertResponse = HTTPSClientUtils.doMutulSSLGet( getAMResourceLocation() + File.separator + "lifecycletest" + File.separator + "mutualssl" @@ -251,15 +219,7 @@ public void testAPIInvocationWithMutualSSLMandatory() @AfterClass(alwaysRun = true) public void cleanUpArtifacts() throws Exception { - restAPIStore.deleteApplication(applicationId); restAPIPublisher.deleteAPI(apiId1); - removeUsers(); - } - - private void removeUsers() throws RemoteException, RemoteUserStoreManagerServiceUserStoreExceptionException { - - for (String user : users) { - remoteUserStoreManagerServiceClient.removeUser(user); - } + restAPIPublisher.deleteAPI(apiId2); } } diff --git a/modules/integration/tests-integration/tests-backend/src/test/resources/artifacts/AM/lifecycletest/mutualssl/cert_chain_client_head_only.jks b/modules/integration/tests-integration/tests-backend/src/test/resources/artifacts/AM/lifecycletest/mutualssl/cert_chain_client_head_only.jks new file mode 100644 index 0000000000000000000000000000000000000000..43d34b5a87a40ef2959b5ecfaf0da594f103b054 GIT binary patch literal 2371 zcmb`Ic{J4h7suy2i*;;~J!X)7`Hn4FOUc-`RMuh)jZlMZkzFyCD7zvaM44nSjY+l; z6-uT^i*<}$JQTm_dCv1Yo#*%O?~i*vpVz&g&pG$pd(VCEGIkjd2n5PB;4kCD;RAzJ zaOXV;0V+5@0zM#^8A)41Lt-Hi1PqLW?}6Mb97-$z98iSv0RRF5kAu_A+J3rAI_3Ml z9dAA^?`w%7n=}%oL!57ga~L?Da4&JClS?+Nw>`37iLSaJOmereYE`ShHc(DNkG zN|oC|oe*9+Smu5GoIqw8A_P8KTPiaMP4Jj`#(MpJRrOJ1nn(J~Db;w?bVob%lZgsi z;IyerD0^zUr%{Xg!Li*hJF?4sO5bnD-Y^}jpDg^*(3?sweZrW=uAO#MB+XzrfjDYdK=>^7Dvm6# z=noMs0ehrT_d?|n-TLW^?jG-+Nf)B_G@PT$d$y;V#U3#Ptmx=}Z2k-q{s-JAntB%W;_^Wo7Wj_2s3h=n-YUu&ZLD@S?bTxx;Qlm+R&i>$P`U zxh+msqo)5@=+WzXWNKgY!PWu}OVs}?aFvTE#)wdG*3iJ3y|=q46c%lCjE^pQUG3bR zu~98Cxz@AdKh^x_9R_0{sJaNwA`g<9)}b;EKv#s;zl$fi~70_8QaE+|F2=_+s|6O0ZEo_hf#xWd(JQ zt5a!Chb0J&wq8Lhfi!s36^8EC>TK-OROkMRXNGXbj^_|6RLlwyG%P7Bg%2LAGEQ#R ze>e{PwnW^MS7W2ROq;_qt*D-@m*=UkNC~B7YugW{Wh%!Oec9k4VdnJ&D;-%g z4L#>7i;EKmIk$iVB718>o!nNmwl}CF@(%0Wlo>BsMs@Z}2NgT=)n4x|gX~dsT^=TX zoXgE|Lg=mjWBMspC6WdAd2CyV&`|(_8dMN?^3mdpx>wEW&R6f@mW?gS$?EoSam!|{ zM}c)G6IR<7gtR|B*w7!E9e>2jS|h}r4H~gEfe&`SznL!L&rv-HR!PbeO5})U0sP5f zhJ1vV()^{vCsXau_);U6UTJKX&n(DkW>mCX@UN$L*mV$j+}_cWJIWlsUY3bYh?g(w z$4Y43IGu>l#nSu|v{wqH_8Aei>D)zR{uo9FiP~mRM>VlL)HKqkh$|E^ZIg z@U3`#U&Q4E*!P_Zg{|!mwx-WorwF*#So*A%_&LKejIWx##otOjqANj=YgtfdP5BTp zM-l#OOCrvwYJrC#5ZEFZ2b%}uphG1vC;){D_!-!aZDdV`bV$xH2-`r~lnw&}aYAXsx;6%*sSX}?W}*&8T?2#BQ9rD8*cl}Je-jb~ zh5t_If3*aR1EhX02U9*^aR3j5>F0pP0RW_C@t`&Dd#8_umycO|IaDYb_K|mQdq3Ol zu_aQ7s^!ik3PN!Z9OyajE@I;U<3ZhHM0Y`Xc$d^6?as%}(1?Pplse(t7q3=!P{RC_ z?~~*&(?_HGpPKR{51XG7g1a7z(#XXMcYEB`?Nc@OgZggjwY=BGE$qO*t#+?$;wKl=nhbLLbJ5QtMWK=%|j47aUDk8XYA+=pABev(ai|;6L@TB(~%+y?zd*nRzIZzMz zYG?k$gzJU)jEAjKFrq5Yby{T9$0eOs1{4NBfU?+lFg6C{VOH?~KLG5(5g?3tFol=t z;Q8f%Gp8*Hl>EigaA8m|M&LvxJB7-w+}h&sHE%hpRpD8yOBZzH+MkfkP~7T?Z$v zhpJt69_CDxy4uW_v>sQk+|`!G3YLDXFaN z^ITZx(=0am?sg