From fe7c772a6605790b87e7fe65ad62283eb288ce65 Mon Sep 17 00:00:00 2001 From: megala21 Date: Fri, 13 Oct 2017 14:55:47 +0530 Subject: [PATCH] Adding additional test cases for certificate authenticator --- .../pom.xml | 3 +- .../mgt/core/impl/CertificateGenerator.java | 36 +-- .../CertificateAuthenticator.java | 36 ++- .../authenticator/JWTAuthenticator.java | 9 +- .../CertificateAuthenticatorTest.java | 271 ++++++++++++++++++ .../authenticator/JWTAuthenticatorTest.java | 6 +- .../util/TestCertificateGenerator.java | 120 ++++++++ .../repository/conf/cdm-config.xml | 96 +++++++ .../src/test/resources/sql-scripts/h2.sql | 25 ++ .../src/test/resources/testng.xml | 1 + 10 files changed, 564 insertions(+), 39 deletions(-) create mode 100644 components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/test/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/CertificateAuthenticatorTest.java create mode 100644 components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/test/java/org/wso2/carbon/webapp/authenticator/framework/util/TestCertificateGenerator.java create mode 100644 components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/test/resources/carbon-home/repository/conf/cdm-config.xml create mode 100644 components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/test/resources/sql-scripts/h2.sql diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.core/pom.xml b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.core/pom.xml index 4db036d18d..227023b304 100644 --- a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.core/pom.xml +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.core/pom.xml @@ -94,7 +94,8 @@ io.swagger.annotations.*;resolution:=optional, org.wso2.carbon.device.mgt.core.*, org.wso2.carbon.registry.indexing.*, - javax.cache.* + javax.cache.*, + javax.naming.ldap diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.core/src/main/java/org/wso2/carbon/certificate/mgt/core/impl/CertificateGenerator.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.core/src/main/java/org/wso2/carbon/certificate/mgt/core/impl/CertificateGenerator.java index f81539018b..877d606af8 100755 --- a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.core/src/main/java/org/wso2/carbon/certificate/mgt/core/impl/CertificateGenerator.java +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.core/src/main/java/org/wso2/carbon/certificate/mgt/core/impl/CertificateGenerator.java @@ -61,6 +61,9 @@ import org.wso2.carbon.certificate.mgt.core.util.CommonUtil; import org.wso2.carbon.certificate.mgt.core.util.Serializer; import org.wso2.carbon.context.PrivilegedCarbonContext; +import javax.naming.InvalidNameException; +import javax.naming.ldap.LdapName; +import javax.naming.ldap.Rdn; import javax.security.auth.x500.X500Principal; import javax.xml.bind.DatatypeConverter; import java.io.ByteArrayInputStream; @@ -112,7 +115,7 @@ public class CertificateGenerator { } } } catch (ClassNotFoundException | IOException e) { - String errorMsg = "Error while deserializing the certificate."; + String errorMsg = "Error while during deserialization of the certificate."; throw new CertificateManagementDAOException(errorMsg, e); } @@ -320,10 +323,20 @@ public class CertificateGenerator { CertificateResponse lookUpCertificate = null; KeyStoreReader keyStoreReader = new KeyStoreReader(); if (distinguishedName != null && !distinguishedName.isEmpty()) { - String[] dnSplits = distinguishedName.split("/CN="); - if (dnSplits != null) { - String commonNameExtracted = dnSplits[dnSplits.length - 1]; - lookUpCertificate = keyStoreReader.getCertificateBySerial(commonNameExtracted); + LdapName ldapName; + try { + ldapName = new LdapName(distinguishedName); + } catch (InvalidNameException e) { + throw new KeystoreException( + "Invalid name exception while trying to create a LDAP name using the distinguished name ", e); + } + for (Rdn relativeDistinuguishedNames : ldapName.getRdns()) { + if (relativeDistinuguishedNames.getType().equalsIgnoreCase("CN")) { + System.err.println("CN is: " + relativeDistinuguishedNames.getValue()); + lookUpCertificate = keyStoreReader + .getCertificateBySerial(String.valueOf(relativeDistinuguishedNames.getValue())); + break; + } } } return lookUpCertificate; @@ -409,21 +422,8 @@ public class CertificateGenerator { Date validityEndDate = commonUtil.getValidityEndDate(); X500Name certSubject = new X500Name(CertificateManagementConstants.DEFAULT_PRINCIPAL); - //X500Name certSubject = request.getSubject(); - Attribute attributes[] = request.getAttributes(); -// if (certSubject == null) { -// certSubject = new X500Name(ConfigurationUtil.DEFAULT_PRINCIPAL); -// } else { -// org.bouncycastle.asn1.x500.RDN[] rdn = certSubject.getRDNs(); -// -// if (rdn == null || rdn.length == 0) { -// certSubject = new X500Name(ConfigurationUtil.DEFAULT_PRINCIPAL); -// } -// } - - RDN[] certUniqueIdRDN; BigInteger certUniqueIdentifier; diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/CertificateAuthenticator.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/CertificateAuthenticator.java index 1a3ac9d18d..5a40a3a951 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/CertificateAuthenticator.java +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/CertificateAuthenticator.java @@ -1,3 +1,22 @@ +/* + * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + package org.wso2.carbon.webapp.authenticator.framework.authenticator; import org.apache.catalina.connector.Request; @@ -39,11 +58,8 @@ public class CertificateAuthenticator implements WebappAuthenticator { @Override public boolean canHandle(Request request) { - if (request.getHeader(CERTIFICATE_VERIFICATION_HEADER) != null || request.getHeader(MUTUAL_AUTH_HEADER) != null - || request.getHeader(PROXY_MUTUAL_AUTH_HEADER) != null) { - return true; - } - return false; + return request.getHeader(CERTIFICATE_VERIFICATION_HEADER) != null + || request.getHeader(MUTUAL_AUTH_HEADER) != null || request.getHeader(PROXY_MUTUAL_AUTH_HEADER) != null; } @Override @@ -64,8 +80,12 @@ public class CertificateAuthenticator implements WebappAuthenticator { authenticationInfo = checkCertificateResponse(certificateResponse); } else if (request.getHeader(MUTUAL_AUTH_HEADER) != null) { - X509Certificate[] clientCertificate = (X509Certificate[]) request. - getAttribute(CLIENT_CERTIFICATE_ATTRIBUTE); + Object object = request.getAttribute(CLIENT_CERTIFICATE_ATTRIBUTE); + X509Certificate[] clientCertificate = null; + if (object instanceof X509Certificate[]) { + clientCertificate = (X509Certificate[]) request. + getAttribute(CLIENT_CERTIFICATE_ATTRIBUTE); + } if (clientCertificate != null && clientCertificate[0] != null) { CertificateResponse certificateResponse = AuthenticatorFrameworkDataHolder.getInstance(). getCertificateManagementService().verifyPEMSignature(clientCertificate[0]); @@ -76,7 +96,6 @@ public class CertificateAuthenticator implements WebappAuthenticator { authenticationInfo.setMessage("No client certificate is present"); } } else if (request.getHeader(CERTIFICATE_VERIFICATION_HEADER) != null) { - String certHeader = request.getHeader(CERTIFICATE_VERIFICATION_HEADER); if (certHeader != null && AuthenticatorFrameworkDataHolder.getInstance().getCertificateManagementService(). @@ -105,7 +124,6 @@ public class CertificateAuthenticator implements WebappAuthenticator { EnrolmentInfo enrolmentInfo = tenantedDeviceWrapper.getDevice().getEnrolmentInfo(); authenticationInfo.setUsername(enrolmentInfo.getOwner()); } - authenticationInfo.setStatus(Status.CONTINUE); } } diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/JWTAuthenticator.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/JWTAuthenticator.java index 9176f461aa..48831a4d54 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/JWTAuthenticator.java +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/JWTAuthenticator.java @@ -27,7 +27,6 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.base.MultitenantConstants; import org.wso2.carbon.base.ServerConfiguration; -import org.wso2.carbon.certificate.mgt.core.bean.Certificate; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.core.util.KeyStoreManager; import org.wso2.carbon.registry.core.exceptions.RegistryException; @@ -44,11 +43,7 @@ import java.security.KeyStore; import java.security.PublicKey; import java.security.interfaces.RSAPublicKey; import java.text.ParseException; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; -import java.util.Properties; -import java.util.StringTokenizer; +import java.util.*; /** * This authenticator authenticates HTTP requests using JWT header. @@ -115,7 +110,7 @@ public class JWTAuthenticator implements WebappAuthenticator { issuer = jwsObject.getJWTClaimsSet().getIssuer(); } catch (ParseException e) { log.error("Error occurred while parsing JWT header.", e); - authenticationInfo.setMessage("Error occured while parsing JWT header"); + authenticationInfo.setMessage("Error occurred while parsing JWT header"); return authenticationInfo; } try { diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/test/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/CertificateAuthenticatorTest.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/test/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/CertificateAuthenticatorTest.java new file mode 100644 index 0000000000..511fe7be4d --- /dev/null +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/test/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/CertificateAuthenticatorTest.java @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.wso2.carbon.webapp.authenticator.framework.authenticator; + +import org.apache.catalina.Context; +import org.apache.catalina.connector.Request; +import org.apache.catalina.core.StandardContext; +import org.apache.tomcat.util.buf.MessageBytes; +import org.apache.tomcat.util.http.MimeHeaders; +import org.bouncycastle.cert.jcajce.JcaCertStore; +import org.bouncycastle.cms.CMSAbsentContent; +import org.bouncycastle.cms.CMSException; +import org.bouncycastle.cms.CMSSignedData; +import org.bouncycastle.cms.CMSSignedDataGenerator; +import org.h2.jdbcx.JdbcDataSource; +import org.mockito.Mockito; +import org.testng.Assert; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; +import org.wso2.carbon.base.MultitenantConstants; +import org.wso2.carbon.certificate.mgt.core.dao.CertificateManagementDAOFactory; +import org.wso2.carbon.certificate.mgt.core.exception.KeystoreException; +import org.wso2.carbon.certificate.mgt.core.impl.CertificateGenerator; +import org.wso2.carbon.certificate.mgt.core.impl.KeyStoreReader; +import org.wso2.carbon.certificate.mgt.core.scep.SCEPException; +import org.wso2.carbon.certificate.mgt.core.scep.SCEPManager; +import org.wso2.carbon.certificate.mgt.core.scep.SCEPManagerImpl; +import org.wso2.carbon.certificate.mgt.core.scep.TenantedDeviceWrapper; +import org.wso2.carbon.certificate.mgt.core.service.CertificateManagementService; +import org.wso2.carbon.certificate.mgt.core.service.CertificateManagementServiceImpl; +import org.wso2.carbon.device.mgt.common.Device; +import org.wso2.carbon.device.mgt.common.DeviceManagementException; +import org.wso2.carbon.device.mgt.common.EnrolmentInfo; +import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager; +import org.wso2.carbon.webapp.authenticator.framework.AuthenticationInfo; +import org.wso2.carbon.webapp.authenticator.framework.internal.AuthenticatorFrameworkDataHolder; +import org.wso2.carbon.webapp.authenticator.framework.util.TestCertificateGenerator; + +import javax.sql.DataSource; +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Field; +import java.net.URL; +import java.security.cert.CertificateEncodingException; +import java.security.cert.X509Certificate; +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.Base64; +import java.util.List; +import java.util.concurrent.atomic.AtomicReference; + +/** + * This is a test case for {@link CertificateAuthenticator}. + */ +public class CertificateAuthenticatorTest { + private CertificateAuthenticator certificateAuthenticator; + private Request certificationVerificationRequest; + private Request mutalAuthHeaderRequest; + private Request proxyMutalAuthHeaderRequest; + private Field headersField; + private static final String MUTUAL_AUTH_HEADER = "mutual-auth-header"; + private static final String PROXY_MUTUAL_AUTH_HEADER = "proxy-mutual-auth-header"; + private static final String CERTIFICATE_VERIFICATION_HEADER = "Mdm-Signature"; + private static final String CLIENT_CERTIFICATE_ATTRIBUTE = "javax.servlet.request.X509Certificate"; + private X509Certificate X509certificate; + + @BeforeClass + public void setup() throws KeystoreException, NoSuchFieldException, IllegalAccessException, SQLException, + DeviceManagementException, CertificateEncodingException, CMSException, IOException, SCEPException { + certificateAuthenticator = new CertificateAuthenticator(); + CertificateManagementService certificateManagementService = Mockito + .mock(CertificateManagementServiceImpl.class, Mockito.CALLS_REAL_METHODS); + headersField = org.apache.coyote.Request.class.getDeclaredField("headers"); + headersField.setAccessible(true); + + Field certificateManagementServiceImpl = CertificateManagementServiceImpl.class.getDeclaredField + ("certificateManagementServiceImpl"); + certificateManagementServiceImpl.setAccessible(true); + Field keyStoreReaderField = CertificateManagementServiceImpl.class.getDeclaredField("keyStoreReader"); + keyStoreReaderField.setAccessible(true); + Field certificateGeneratorField = CertificateManagementServiceImpl.class.getDeclaredField + ("certificateGenerator"); + certificateGeneratorField.setAccessible(true); + certificateManagementServiceImpl.set(null, certificateManagementService); + + // Create KeyStore Reader + Field dataSource = CertificateManagementDAOFactory.class.getDeclaredField("dataSource"); + dataSource.setAccessible(true); + dataSource.set(null, createDatabase()); + Field databaseEngine = CertificateManagementDAOFactory.class.getDeclaredField("databaseEngine"); + databaseEngine.setAccessible(true); + databaseEngine.set(null, "H2"); + KeyStoreReader keyStoreReader = new KeyStoreReader(); + keyStoreReaderField.set(null, keyStoreReader); + + CertificateGenerator certificateGenerator = new TestCertificateGenerator(); + certificateGeneratorField.set(null, certificateGenerator); + + AuthenticatorFrameworkDataHolder.getInstance(). + setCertificateManagementService(certificateManagementService); + X509certificate = certificateManagementService.generateX509Certificate(); + + proxyMutalAuthHeaderRequest = createRequest(PROXY_MUTUAL_AUTH_HEADER, String.valueOf(X509certificate)); + System.setProperty("carbon.config.dir.path", + System.getProperty("carbon.home") + File.separator + "repository" + File.separator + "conf"); + DeviceConfigurationManager.getInstance().initConfig(); + certificationVerificationRequest = createRequest(CERTIFICATE_VERIFICATION_HEADER, + createEncodedSignature(X509certificate)); + + mutalAuthHeaderRequest = createRequest(MUTUAL_AUTH_HEADER, "test"); + + SCEPManager scepManager = Mockito.mock(SCEPManagerImpl.class, Mockito.CALLS_REAL_METHODS); + TenantedDeviceWrapper tenantedDeviceWrapper = new TenantedDeviceWrapper(); + tenantedDeviceWrapper.setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME); + tenantedDeviceWrapper.setTenantId(MultitenantConstants.SUPER_TENANT_ID); + Device device = new Device(); + device.setEnrolmentInfo(new EnrolmentInfo("admin", null, null)); + tenantedDeviceWrapper.setDevice(device); + Mockito.doReturn(tenantedDeviceWrapper).when(scepManager).getValidatedDevice(Mockito.any()); + AuthenticatorFrameworkDataHolder.getInstance().setScepManager(scepManager); + } + + @Test(description = "This test case tests the behaviour of the CertificateAuthenticator for Proxy mutal Auth " + + "Header requests") + public void testRequestsWithProxyMutalAuthHeader() + throws KeystoreException, NoSuchFieldException, IllegalAccessException { + Assert.assertTrue(certificateAuthenticator.canHandle(proxyMutalAuthHeaderRequest), "canHandle method " + + "returned false for a request with all the required header"); + AuthenticationInfo authenticationInfo = certificateAuthenticator + .authenticate(proxyMutalAuthHeaderRequest, null); + Assert.assertNotNull(authenticationInfo, "Authentication Info from Certificate Authenticator is null"); + Assert.assertNull(authenticationInfo.getTenantDomain(), + "Authentication got succeeded without proper certificate"); + + proxyMutalAuthHeaderRequest = createRequest(PROXY_MUTUAL_AUTH_HEADER, + String.valueOf(X509certificate.getIssuerDN())); + authenticationInfo = certificateAuthenticator.authenticate(proxyMutalAuthHeaderRequest, null); + Assert.assertNotNull(authenticationInfo, "Authentication Info from Certificate Authenticator is null"); + Assert.assertNotNull(authenticationInfo.getTenantDomain(), + "Authentication got failed for a proper certificate"); + + CertificateGenerator tempCertificateGenerator = new CertificateGenerator(); + X509Certificate certificateWithOutCN = tempCertificateGenerator.generateX509Certificate(); + proxyMutalAuthHeaderRequest = createRequest(PROXY_MUTUAL_AUTH_HEADER, + String.valueOf(certificateWithOutCN.getIssuerDN())); + authenticationInfo = certificateAuthenticator.authenticate(proxyMutalAuthHeaderRequest, null); + Assert.assertNotNull(authenticationInfo, "Authentication Info from Certificate Authenticator is null"); + Assert.assertEquals(authenticationInfo.getStatus(), WebappAuthenticator.Status.FAILURE, + "Authentication got passed with a certificate without CN"); + + + } + + @Test(description = "This test case tests the behaviour of the CertificateAuthenticator for Certification " + + "Verification Header requests") + public void testRequestCertificateVerificationHeader() + throws CertificateEncodingException, IOException, CMSException, NoSuchFieldException, + IllegalAccessException { + Assert.assertTrue(certificateAuthenticator.canHandle(certificationVerificationRequest), + "canHandle method returned false for a request with all the required header"); + AuthenticationInfo authenticationInfo = certificateAuthenticator + .authenticate(certificationVerificationRequest, null); + Assert.assertNotNull(authenticationInfo, "Authentication Info from Certificate Authenticator is null"); + Assert.assertNull(authenticationInfo.getTenantDomain(), "Authentication got passed without proper certificate"); + authenticationInfo = certificateAuthenticator.authenticate(certificationVerificationRequest, null); + Assert.assertNotNull(authenticationInfo, "Authentication Info from Certificate Authenticator is null"); + Assert.assertEquals(authenticationInfo.getTenantDomain(), MultitenantConstants.SUPER_TENANT_DOMAIN_NAME, + "Authentication failed for a valid request with " + CERTIFICATE_VERIFICATION_HEADER + " header"); + } + + @Test(description = "This test case tests the behaviour of the Certificate Authenticator for the requests with " + + "Mutal Auth Header") + public void testMutalAuthHeaderRequest() { + Assert.assertTrue(certificateAuthenticator.canHandle(mutalAuthHeaderRequest), + "canHandle method returned false for a request with all the required header"); + + AuthenticationInfo authenticationInfo = certificateAuthenticator.authenticate(mutalAuthHeaderRequest, null); + Assert.assertNotNull(authenticationInfo, "Authentication Info from Certificate Authenticator is null"); + Assert.assertEquals(authenticationInfo.getMessage(), "No client certificate is present", + "Authentication got passed without proper certificate"); + + X509Certificate[] x509Certificates = new X509Certificate[1]; + x509Certificates[0] = X509certificate; + mutalAuthHeaderRequest.setAttribute(CLIENT_CERTIFICATE_ATTRIBUTE, x509Certificates); + authenticationInfo = certificateAuthenticator.authenticate(mutalAuthHeaderRequest, null); + Assert.assertNotNull(authenticationInfo, "Authentication Info from Certificate Authenticator is null"); + Assert.assertEquals(authenticationInfo.getTenantDomain(), MultitenantConstants.SUPER_TENANT_DOMAIN_NAME, + "Authentication failed even with proper certificate"); + } + /** + * To create a request that can be understandable by Certificate Authenticator. + * + * @param headerName Name of the header + * @param value Value for the header + * @return Request that is created. + * @throws IllegalAccessException Illegal Access Exception. + * @throws NoSuchFieldException No Such Field Exception. + */ + private Request createRequest(String headerName, String value) throws IllegalAccessException, NoSuchFieldException { + Request request = new Request(); + Context context = new StandardContext(); + request.setContext(context); + org.apache.coyote.Request coyoteRequest = new org.apache.coyote.Request(); + MimeHeaders mimeHeaders = new MimeHeaders(); + MessageBytes bytes = mimeHeaders.addValue(headerName); + bytes.setString(value); + headersField.set(coyoteRequest, mimeHeaders); + + request.setCoyoteRequest(coyoteRequest); + return request; + } + + private DataSource createDatabase() throws SQLException { + URL resourceURL = ClassLoader.getSystemResource("sql-scripts" + File.separator + "h2.sql"); + JdbcDataSource dataSource = new JdbcDataSource(); + dataSource.setURL("jdbc:h2:mem:cert;DB_CLOSE_DELAY=-1"); + dataSource.setUser("sa"); + dataSource.setPassword("sa"); + final String LOAD_DATA_QUERY = "RUNSCRIPT FROM '" + resourceURL.getPath() + "'"; + Connection conn = null; + Statement statement = null; + try { + conn = dataSource.getConnection(); + statement = conn.createStatement(); + statement.execute(LOAD_DATA_QUERY); + } finally { + if (conn != null) { + try { + conn.close(); + } catch (SQLException e) { + + } + } + if (statement != null) { + statement.close(); + } + } + return dataSource; + } + + private String createEncodedSignature(X509Certificate x509Certificate) + throws CertificateEncodingException, CMSException, IOException { + CMSSignedDataGenerator generator = new CMSSignedDataGenerator(); + List list = new ArrayList<>(); + list.add(x509Certificate); + JcaCertStore store = new JcaCertStore(list); + generator.addCertificates(store); + AtomicReference degenerateSd = new AtomicReference<>(generator.generate(new CMSAbsentContent())); + byte[] signature = degenerateSd.get().getEncoded(); + return Base64.getEncoder().encodeToString(signature); + } +} diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/test/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/JWTAuthenticatorTest.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/test/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/JWTAuthenticatorTest.java index e3e3cf22f7..a163afafde 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/test/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/JWTAuthenticatorTest.java +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/test/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/JWTAuthenticatorTest.java @@ -109,7 +109,7 @@ public class JWTAuthenticatorTest { } @Test(description = "This method tests authenticate method under the successful condition", dependsOnMethods = - {"testAuthentiateFailureScenarios"}) + { "testAuthenticateFailureScenarios" }) public void testAuthenticate() throws IllegalAccessException, NoSuchFieldException { Request request = createJWTRequest(jwtToken, "test"); AuthenticationInfo authenticationInfo = jwtAuthenticator.authenticate(request, null); @@ -118,7 +118,7 @@ public class JWTAuthenticatorTest { } @Test(description = "This method tests the authenticate method under failure conditions") - public void testAuthentiateFailureScenarios() throws NoSuchFieldException, IllegalAccessException { + public void testAuthenticateFailureScenarios() throws NoSuchFieldException, IllegalAccessException { Request request = createJWTRequest("test", ""); AuthenticationInfo authenticationInfo = jwtAuthenticator.authenticate(request, null); Assert.assertNotNull(authenticationInfo, "Returned authentication info was null"); @@ -178,6 +178,4 @@ public class JWTAuthenticatorTest { return request; } - - } diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/test/java/org/wso2/carbon/webapp/authenticator/framework/util/TestCertificateGenerator.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/test/java/org/wso2/carbon/webapp/authenticator/framework/util/TestCertificateGenerator.java new file mode 100644 index 0000000000..b532f5699c --- /dev/null +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/test/java/org/wso2/carbon/webapp/authenticator/framework/util/TestCertificateGenerator.java @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.wso2.carbon.webapp.authenticator.framework.util; + +import org.bouncycastle.cert.X509v3CertificateBuilder; +import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; +import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.operator.ContentSigner; +import org.bouncycastle.operator.OperatorCreationException; +import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; +import org.wso2.carbon.certificate.mgt.core.bean.Certificate; +import org.wso2.carbon.certificate.mgt.core.exception.KeystoreException; +import org.wso2.carbon.certificate.mgt.core.impl.CertificateGenerator; +import org.wso2.carbon.certificate.mgt.core.util.CertificateManagementConstants; +import org.wso2.carbon.certificate.mgt.core.util.CommonUtil; +import org.wso2.carbon.context.PrivilegedCarbonContext; + +import javax.security.auth.x500.X500Principal; +import java.math.BigInteger; +import java.security.*; +import java.security.cert.CertificateException; +import java.security.cert.CertificateExpiredException; +import java.security.cert.CertificateNotYetValidException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +public class TestCertificateGenerator extends CertificateGenerator { + private int count = 0; + + public X509Certificate generateX509Certificate() throws KeystoreException { + BigInteger serialNumber = CommonUtil.generateSerialNumber(); + String defaultPrinciple = "CN=" + serialNumber + ",O=WSO2,OU=Mobile,C=LK"; + + CommonUtil commonUtil = new CommonUtil(); + Date validityBeginDate = commonUtil.getValidityStartDate(); + Date validityEndDate = commonUtil.getValidityEndDate(); + + Security.addProvider(new BouncyCastleProvider()); + + try { + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance( + CertificateManagementConstants.RSA, CertificateManagementConstants.PROVIDER); + keyPairGenerator.initialize(CertificateManagementConstants.RSA_KEY_LENGTH, new SecureRandom()); + KeyPair pair = keyPairGenerator.generateKeyPair(); + X500Principal principal = new X500Principal(defaultPrinciple); + X509v3CertificateBuilder certificateBuilder = new JcaX509v3CertificateBuilder( + principal, serialNumber, validityBeginDate, validityEndDate, + principal, pair.getPublic()); + ContentSigner contentSigner = new JcaContentSignerBuilder(CertificateManagementConstants.SHA256_RSA) + .setProvider(CertificateManagementConstants.PROVIDER).build( + pair.getPrivate()); + X509Certificate certificate = new JcaX509CertificateConverter() + .setProvider(CertificateManagementConstants.PROVIDER).getCertificate( + certificateBuilder.build(contentSigner)); + certificate.verify(certificate.getPublicKey()); + List certificates = new ArrayList<>(); + org.wso2.carbon.certificate.mgt.core.bean.Certificate certificateToStore = + new org.wso2.carbon.certificate.mgt.core.bean.Certificate(); + certificateToStore.setTenantId(PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId()); + certificateToStore.setCertificate(certificate); + certificates.add(certificateToStore); + saveCertInKeyStore(certificates); + return certificate; + } catch (NoSuchAlgorithmException e) { + String errorMsg = "No such algorithm found when generating certificate"; + throw new KeystoreException(errorMsg, e); + } catch (NoSuchProviderException e) { + String errorMsg = "No such provider found when generating certificate"; + throw new KeystoreException(errorMsg, e); + } catch (OperatorCreationException e) { + String errorMsg = "Issue in operator creation when generating certificate"; + throw new KeystoreException(errorMsg, e); + } catch (CertificateExpiredException e) { + String errorMsg = "Certificate expired after generating certificate"; + throw new KeystoreException(errorMsg, e); + } catch (CertificateNotYetValidException e) { + String errorMsg = "Certificate not yet valid when generating certificate"; + throw new KeystoreException(errorMsg, e); + } catch (CertificateException e) { + String errorMsg = "Certificate issue occurred when generating certificate"; + throw new KeystoreException(errorMsg, e); + } catch (InvalidKeyException e) { + String errorMsg = "Invalid key used when generating certificate"; + throw new KeystoreException(errorMsg, e); + } catch (SignatureException e) { + String errorMsg = "Signature related issue occurred when generating certificate"; + throw new KeystoreException(errorMsg, e); + } + } + + public String extractChallengeToken(X509Certificate certificate) { + if (count != 0) { + return "WSO2 (Challenge)"; + } else { + count++; + return null; + } + } + +} diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/test/resources/carbon-home/repository/conf/cdm-config.xml b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/test/resources/carbon-home/repository/conf/cdm-config.xml new file mode 100644 index 0000000000..70ff0a6f41 --- /dev/null +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/test/resources/carbon-home/repository/conf/cdm-config.xml @@ -0,0 +1,96 @@ + + + + + + + + jdbc/DM_DS + + + + + 1000 + 60000 + 60000 + true + + org.wso2.carbon.device.mgt.extensions.push.notification.provider.fcm.FCMBasedPushNotificationProvider + + org.wso2.carbon.device.mgt.extensions.push.notification.provider.mqtt.MQTTBasedPushNotificationProvider + org.wso2.carbon.device.mgt.extensions.push.notification.provider.http.HTTPBasedPushNotificationProvider + org.wso2.carbon.device.mgt.extensions.push.notification.provider.xmpp.XMPPBasedPushNotificationProvider + + + + false + + + https://localhost:9443 + admin + admin + + + org.wso2.carbon.policy.mgt + true + 60000 + 5 + 8 + 20 + + + + Simple + + + + 20 + 20 + 20 + 20 + 20 + 20 + + + + true + + + + true + 600 + + 10000 + + + false + 86400 + + + false + false + + BYOD,COPE + + diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/test/resources/sql-scripts/h2.sql b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/test/resources/sql-scripts/h2.sql new file mode 100644 index 0000000000..7cf6882829 --- /dev/null +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/test/resources/sql-scripts/h2.sql @@ -0,0 +1,25 @@ +-- +-- Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +-- +-- WSO2 Inc. licenses this file to you under the Apache License, +-- Version 2.0 (the "License"); you may not use this file except +-- in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, +-- software distributed under the License is distributed on an +-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +-- KIND, either express or implied. See the License for the +-- specific language governing permissions and limitations +-- under the License. + +CREATE TABLE IF NOT EXISTS DM_DEVICE_CERTIFICATE ( + ID INTEGER auto_increment NOT NULL, + SERIAL_NUMBER VARCHAR(500) DEFAULT NULL, + CERTIFICATE BLOB DEFAULT NULL, + TENANT_ID INTEGER DEFAULT 0, + USERNAME VARCHAR(500) DEFAULT NULL, + PRIMARY KEY (ID) +); diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/test/resources/testng.xml b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/test/resources/testng.xml index adc6b26287..c9f3f8ad68 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/test/resources/testng.xml +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/test/resources/testng.xml @@ -32,6 +32,7 @@ +