Merge pull request #1063 from Megala21/authenticator_framework

Adding test cases to improve Authenticator framework coverage
revert-70aa11f8
sinthuja 7 years ago committed by GitHub
commit 63b0e7d3f5

@ -94,7 +94,8 @@
io.swagger.annotations.*;resolution:=optional, io.swagger.annotations.*;resolution:=optional,
org.wso2.carbon.device.mgt.core.*, org.wso2.carbon.device.mgt.core.*,
org.wso2.carbon.registry.indexing.*, org.wso2.carbon.registry.indexing.*,
javax.cache.* javax.cache.*,
javax.naming.ldap
<!--org.bouncycastle.pkcs.jcajce--> <!--org.bouncycastle.pkcs.jcajce-->
</Import-Package> </Import-Package>
<Export-Package> <Export-Package>

@ -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.certificate.mgt.core.util.Serializer;
import org.wso2.carbon.context.PrivilegedCarbonContext; 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.security.auth.x500.X500Principal;
import javax.xml.bind.DatatypeConverter; import javax.xml.bind.DatatypeConverter;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
@ -112,7 +115,7 @@ public class CertificateGenerator {
} }
} }
} catch (ClassNotFoundException | IOException e) { } 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); throw new CertificateManagementDAOException(errorMsg, e);
} }
@ -320,10 +323,20 @@ public class CertificateGenerator {
CertificateResponse lookUpCertificate = null; CertificateResponse lookUpCertificate = null;
KeyStoreReader keyStoreReader = new KeyStoreReader(); KeyStoreReader keyStoreReader = new KeyStoreReader();
if (distinguishedName != null && !distinguishedName.isEmpty()) { if (distinguishedName != null && !distinguishedName.isEmpty()) {
String[] dnSplits = distinguishedName.split("/CN="); LdapName ldapName;
if (dnSplits != null) { try {
String commonNameExtracted = dnSplits[dnSplits.length - 1]; ldapName = new LdapName(distinguishedName);
lookUpCertificate = keyStoreReader.getCertificateBySerial(commonNameExtracted); } 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; return lookUpCertificate;
@ -409,21 +422,8 @@ public class CertificateGenerator {
Date validityEndDate = commonUtil.getValidityEndDate(); Date validityEndDate = commonUtil.getValidityEndDate();
X500Name certSubject = new X500Name(CertificateManagementConstants.DEFAULT_PRINCIPAL); X500Name certSubject = new X500Name(CertificateManagementConstants.DEFAULT_PRINCIPAL);
//X500Name certSubject = request.getSubject();
Attribute attributes[] = request.getAttributes(); 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; RDN[] certUniqueIdRDN;
BigInteger certUniqueIdentifier; BigInteger certUniqueIdentifier;

@ -167,21 +167,19 @@
<groupId>org.wso2.tomcat</groupId> <groupId>org.wso2.tomcat</groupId>
<artifactId>tomcat-servlet-api</artifactId> <artifactId>tomcat-servlet-api</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.logging</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.wso2.carbon</groupId> <groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.tomcat.ext</artifactId> <artifactId>org.wso2.carbon.tomcat.ext</artifactId>
</dependency> </dependency>
<!--dependency>
<groupId>org.apache.ws.commons.axiom.wso2</groupId>
<artifactId>axiom</artifactId>
</dependency-->
<dependency> <dependency>
<groupId>org.wso2.carbon.identity.framework</groupId> <groupId>org.wso2.carbon.identity.framework</groupId>
<artifactId>org.wso2.carbon.identity.base</artifactId> <artifactId>org.wso2.carbon.identity.base</artifactId>
<exclusions>
<exclusion>
<groupId>org.opensaml</groupId>
<artifactId>xmltooling</artifactId>
</exclusion>
</exclusions>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.wso2.carbon.identity.framework</groupId> <groupId>org.wso2.carbon.identity.framework</groupId>
@ -253,6 +251,21 @@
<artifactId>powermock-api-mockito</artifactId> <artifactId>powermock-api-mockito</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.identity.jwt.client.extension</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.testing.osgi-mock</artifactId>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
</project> </project>

@ -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; package org.wso2.carbon.webapp.authenticator.framework.authenticator;
import org.apache.catalina.connector.Request; import org.apache.catalina.connector.Request;
@ -39,11 +58,8 @@ public class CertificateAuthenticator implements WebappAuthenticator {
@Override @Override
public boolean canHandle(Request request) { public boolean canHandle(Request request) {
if (request.getHeader(CERTIFICATE_VERIFICATION_HEADER) != null || request.getHeader(MUTUAL_AUTH_HEADER) != null return request.getHeader(CERTIFICATE_VERIFICATION_HEADER) != null
|| request.getHeader(PROXY_MUTUAL_AUTH_HEADER) != null) { || request.getHeader(MUTUAL_AUTH_HEADER) != null || request.getHeader(PROXY_MUTUAL_AUTH_HEADER) != null;
return true;
}
return false;
} }
@Override @Override
@ -64,8 +80,12 @@ public class CertificateAuthenticator implements WebappAuthenticator {
authenticationInfo = checkCertificateResponse(certificateResponse); authenticationInfo = checkCertificateResponse(certificateResponse);
} }
else if (request.getHeader(MUTUAL_AUTH_HEADER) != null) { else if (request.getHeader(MUTUAL_AUTH_HEADER) != null) {
X509Certificate[] clientCertificate = (X509Certificate[]) request. Object object = request.getAttribute(CLIENT_CERTIFICATE_ATTRIBUTE);
X509Certificate[] clientCertificate = null;
if (object instanceof X509Certificate[]) {
clientCertificate = (X509Certificate[]) request.
getAttribute(CLIENT_CERTIFICATE_ATTRIBUTE); getAttribute(CLIENT_CERTIFICATE_ATTRIBUTE);
}
if (clientCertificate != null && clientCertificate[0] != null) { if (clientCertificate != null && clientCertificate[0] != null) {
CertificateResponse certificateResponse = AuthenticatorFrameworkDataHolder.getInstance(). CertificateResponse certificateResponse = AuthenticatorFrameworkDataHolder.getInstance().
getCertificateManagementService().verifyPEMSignature(clientCertificate[0]); getCertificateManagementService().verifyPEMSignature(clientCertificate[0]);
@ -76,7 +96,6 @@ public class CertificateAuthenticator implements WebappAuthenticator {
authenticationInfo.setMessage("No client certificate is present"); authenticationInfo.setMessage("No client certificate is present");
} }
} else if (request.getHeader(CERTIFICATE_VERIFICATION_HEADER) != null) { } else if (request.getHeader(CERTIFICATE_VERIFICATION_HEADER) != null) {
String certHeader = request.getHeader(CERTIFICATE_VERIFICATION_HEADER); String certHeader = request.getHeader(CERTIFICATE_VERIFICATION_HEADER);
if (certHeader != null && if (certHeader != null &&
AuthenticatorFrameworkDataHolder.getInstance().getCertificateManagementService(). AuthenticatorFrameworkDataHolder.getInstance().getCertificateManagementService().
@ -105,7 +124,6 @@ public class CertificateAuthenticator implements WebappAuthenticator {
EnrolmentInfo enrolmentInfo = tenantedDeviceWrapper.getDevice().getEnrolmentInfo(); EnrolmentInfo enrolmentInfo = tenantedDeviceWrapper.getDevice().getEnrolmentInfo();
authenticationInfo.setUsername(enrolmentInfo.getOwner()); authenticationInfo.setUsername(enrolmentInfo.getOwner());
} }
authenticationInfo.setStatus(Status.CONTINUE); authenticationInfo.setStatus(Status.CONTINUE);
} }
} }

@ -86,6 +86,12 @@ public class JWTAuthenticator implements WebappAuthenticator {
@Override @Override
public AuthenticationInfo authenticate(Request request, Response response) { public AuthenticationInfo authenticate(Request request, Response response) {
String requestUri = request.getRequestURI(); String requestUri = request.getRequestURI();
SignedJWT jwsObject;
String username;
String tenantDomain;
int tenantId;
String issuer;
AuthenticationInfo authenticationInfo = new AuthenticationInfo(); AuthenticationInfo authenticationInfo = new AuthenticationInfo();
if (requestUri == null || "".equals(requestUri)) { if (requestUri == null || "".equals(requestUri)) {
authenticationInfo.setStatus(Status.CONTINUE); authenticationInfo.setStatus(Status.CONTINUE);
@ -94,19 +100,25 @@ public class JWTAuthenticator implements WebappAuthenticator {
requestUri = ""; requestUri = "";
} }
StringTokenizer tokenizer = new StringTokenizer(requestUri, "/"); StringTokenizer tokenizer = new StringTokenizer(requestUri, "/");
String context = tokenizer.nextToken(); String context = tokenizer.hasMoreTokens() ? tokenizer.nextToken() : null;
if (context == null || "".equals(context)) { if (context == null || "".equals(context)) {
authenticationInfo.setStatus(Status.CONTINUE); authenticationInfo.setStatus(Status.CONTINUE);
} }
try { try {
String authorizationHeader = request.getHeader(JWT_ASSERTION_HEADER); String authorizationHeader = request.getHeader(JWT_ASSERTION_HEADER);
jwsObject = SignedJWT.parse(authorizationHeader);
username = jwsObject.getJWTClaimsSet().getStringClaim(SIGNED_JWT_AUTH_USERNAME);
tenantDomain = MultitenantUtils.getTenantDomain(username);
tenantId = Integer.parseInt(jwsObject.getJWTClaimsSet().getStringClaim(SIGNED_JWT_AUTH_TENANT_ID));
issuer = jwsObject.getJWTClaimsSet().getIssuer();
} catch (ParseException e) {
log.error("Error occurred while parsing JWT header.", e);
authenticationInfo.setMessage("Error occurred while parsing JWT header");
return authenticationInfo;
}
try {
SignedJWT jwsObject = SignedJWT.parse(authorizationHeader);
String username = jwsObject.getJWTClaimsSet().getStringClaim(SIGNED_JWT_AUTH_USERNAME);
String tenantDomain = MultitenantUtils.getTenantDomain(username);
int tenantId = Integer.parseInt(jwsObject.getJWTClaimsSet().getStringClaim(SIGNED_JWT_AUTH_TENANT_ID));
String issuer = jwsObject.getJWTClaimsSet().getIssuer();
PrivilegedCarbonContext.startTenantFlow(); PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain); PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain);
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenantId); PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenantId);
@ -116,7 +128,7 @@ public class JWTAuthenticator implements WebappAuthenticator {
loadTenantRegistry(tenantId); loadTenantRegistry(tenantId);
KeyStoreManager keyStoreManager = KeyStoreManager.getInstance(tenantId); KeyStoreManager keyStoreManager = KeyStoreManager.getInstance(tenantId);
if (MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) { if (MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) {
String alias = properties.getProperty(issuer); String alias = properties == null ? null : properties.getProperty(issuer);
if (alias != null && !alias.isEmpty()) { if (alias != null && !alias.isEmpty()) {
ServerConfiguration serverConfig = CarbonUtils.getServerConfiguration(); ServerConfiguration serverConfig = CarbonUtils.getServerConfiguration();
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
@ -124,7 +136,8 @@ public class JWTAuthenticator implements WebappAuthenticator {
String trustStorePassword = serverConfig.getFirstProperty( String trustStorePassword = serverConfig.getFirstProperty(
DEFAULT_TRUST_STORE_PASSWORD); DEFAULT_TRUST_STORE_PASSWORD);
keyStore.load(new FileInputStream(trustStorePath), trustStorePassword.toCharArray()); keyStore.load(new FileInputStream(trustStorePath), trustStorePassword.toCharArray());
publicKey = keyStore.getCertificate(alias).getPublicKey(); java.security.cert.Certificate certificate = keyStore.getCertificate(alias);
publicKey = certificate == null ? null : certificate.getPublicKey();
} else { } else {
authenticationInfo.setStatus(Status.FAILURE); authenticationInfo.setStatus(Status.FAILURE);
return authenticationInfo; return authenticationInfo;
@ -139,15 +152,13 @@ public class JWTAuthenticator implements WebappAuthenticator {
publicKeyHolder.put(issuerAlias, publicKey); publicKeyHolder.put(issuerAlias, publicKey);
} }
} }
//Get the filesystem keystore default primary certificate //Get the filesystem keystore default primary certificate
JWSVerifier verifier = new RSASSAVerifier((RSAPublicKey) publicKey); JWSVerifier verifier = null;
if (jwsObject.verify(verifier)) { if (publicKey != null) {
verifier = new RSASSAVerifier((RSAPublicKey) publicKey);
}
if (verifier != null && jwsObject.verify(verifier)) {
username = MultitenantUtils.getTenantAwareUsername(username); username = MultitenantUtils.getTenantAwareUsername(username);
if (tenantId == -1) {
log.error("tenantDomain is not valid. username : " + username + ", tenantDomain " +
": " + tenantDomain);
} else {
UserStoreManager userStore = AuthenticatorFrameworkDataHolder.getInstance().getRealmService(). UserStoreManager userStore = AuthenticatorFrameworkDataHolder.getInstance().getRealmService().
getTenantUserRealm(tenantId).getUserStoreManager(); getTenantUserRealm(tenantId).getUserStoreManager();
if (userStore.isExistingUser(username)) { if (userStore.isExistingUser(username)) {
@ -155,17 +166,18 @@ public class JWTAuthenticator implements WebappAuthenticator {
authenticationInfo.setUsername(username); authenticationInfo.setUsername(username);
authenticationInfo.setTenantDomain(tenantDomain); authenticationInfo.setTenantDomain(tenantDomain);
authenticationInfo.setStatus(Status.CONTINUE); authenticationInfo.setStatus(Status.CONTINUE);
} } else {
authenticationInfo.setStatus(Status.FAILURE);
} }
} else { } else {
authenticationInfo.setStatus(Status.FAILURE); authenticationInfo.setStatus(Status.FAILURE);
} }
} catch (UserStoreException e) { } catch (UserStoreException e) {
log.error("Error occurred while obtaining the user.", e); log.error("Error occurred while obtaining the user.", e);
} catch (ParseException e) { authenticationInfo.setStatus(Status.FAILURE);
log.error("Error occurred while parsing the JWT header.", e);
} catch (Exception e) { } catch (Exception e) {
log.error("Error occurred while verifying the JWT header.", e); log.error("Error occurred while verifying the JWT header.", e);
authenticationInfo.setStatus(Status.FAILURE);
} finally { } finally {
PrivilegedCarbonContext.endTenantFlow(); PrivilegedCarbonContext.endTenantFlow();
} }

@ -21,18 +21,25 @@ package org.wso2.carbon.webapp.authenticator.framework;
import org.testng.annotations.BeforeSuite; import org.testng.annotations.BeforeSuite;
import org.wso2.carbon.CarbonConstants; import org.wso2.carbon.CarbonConstants;
import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.core.internal.CarbonCoreDataHolder;
import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder; import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder;
import org.wso2.carbon.device.mgt.core.permission.mgt.PermissionUtils; import org.wso2.carbon.device.mgt.core.permission.mgt.PermissionUtils;
import org.wso2.carbon.registry.core.config.RegistryContext;
import org.wso2.carbon.registry.core.exceptions.RegistryException; import org.wso2.carbon.registry.core.exceptions.RegistryException;
import org.wso2.carbon.registry.core.internal.RegistryDataHolder;
import org.wso2.carbon.registry.core.jdbc.realm.InMemoryRealmService; import org.wso2.carbon.registry.core.jdbc.realm.InMemoryRealmService;
import org.wso2.carbon.registry.core.service.RegistryService;
import org.wso2.carbon.user.api.Permission; import org.wso2.carbon.user.api.Permission;
import org.wso2.carbon.user.api.UserStoreException; import org.wso2.carbon.user.api.UserStoreException;
import org.wso2.carbon.user.api.UserStoreManager; import org.wso2.carbon.user.api.UserStoreManager;
import org.wso2.carbon.user.core.service.RealmService; import org.wso2.carbon.user.core.service.RealmService;
import org.wso2.carbon.utils.multitenancy.MultitenantConstants; import org.wso2.carbon.utils.multitenancy.MultitenantConstants;
import org.wso2.carbon.webapp.authenticator.framework.internal.AuthenticatorFrameworkDataHolder; import org.wso2.carbon.webapp.authenticator.framework.internal.AuthenticatorFrameworkDataHolder;
import org.wso2.carbon.webapp.authenticator.framework.util.TestTenantIndexingLoader;
import org.wso2.carbon.webapp.authenticator.framework.util.TestTenantRegistryLoader;
import java.io.File; import java.io.File;
import java.io.InputStream;
import java.net.URL; import java.net.URL;
import static org.wso2.carbon.security.SecurityConstants.ADMIN_USER; import static org.wso2.carbon.security.SecurityConstants.ADMIN_USER;
@ -56,6 +63,17 @@ public class BaseWebAppAuthenticatorFrameworkTest {
.setTenantDomain(org.wso2.carbon.base.MultitenantConstants.SUPER_TENANT_DOMAIN_NAME); .setTenantDomain(org.wso2.carbon.base.MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);
PrivilegedCarbonContext.getThreadLocalCarbonContext() PrivilegedCarbonContext.getThreadLocalCarbonContext()
.setTenantId(org.wso2.carbon.base.MultitenantConstants.SUPER_TENANT_ID); .setTenantId(org.wso2.carbon.base.MultitenantConstants.SUPER_TENANT_ID);
CarbonCoreDataHolder.getInstance().setRegistryService(getRegistryService());
AuthenticatorFrameworkDataHolder.getInstance().setTenantRegistryLoader(new TestTenantRegistryLoader());
AuthenticatorFrameworkDataHolder.getInstance().setTenantIndexingLoader(new TestTenantIndexingLoader());
}
/**
* To get the registry service.
* @return RegistryService
* @throws RegistryException Registry Exception
*/
private RegistryService getRegistryService() throws RegistryException, UserStoreException {
RealmService realmService = new InMemoryRealmService(); RealmService realmService = new InMemoryRealmService();
AuthenticatorFrameworkDataHolder.getInstance().setRealmService(realmService); AuthenticatorFrameworkDataHolder.getInstance().setRealmService(realmService);
UserStoreManager userStoreManager = AuthenticatorFrameworkDataHolder.getInstance().getRealmService() UserStoreManager userStoreManager = AuthenticatorFrameworkDataHolder.getInstance().getRealmService()
@ -63,5 +81,12 @@ public class BaseWebAppAuthenticatorFrameworkTest {
Permission adminPermission = new Permission(PermissionUtils.ADMIN_PERMISSION_REGISTRY_PATH, Permission adminPermission = new Permission(PermissionUtils.ADMIN_PERMISSION_REGISTRY_PATH,
CarbonConstants.UI_PERMISSION_ACTION); CarbonConstants.UI_PERMISSION_ACTION);
userStoreManager.addRole(ADMIN_ROLE + "t", new String[] { ADMIN_USER }, new Permission[] { adminPermission }); userStoreManager.addRole(ADMIN_ROLE + "t", new String[] { ADMIN_USER }, new Permission[] { adminPermission });
RegistryDataHolder.getInstance().setRealmService(realmService);
DeviceManagementDataHolder.getInstance().setRealmService(realmService);
InputStream is = BaseWebAppAuthenticatorFrameworkTest.class.getClassLoader()
.getResourceAsStream("carbon-home/repository/conf/registry.xml");
RegistryContext context = RegistryContext.getBaseInstance(is, realmService);
context.setSetup(true);
return context.getEmbeddedRegistryService();
} }
} }

@ -0,0 +1,284 @@
/*
* 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;
}
/**
* To create certificate management database.
*
* @return Datasource.
* @throws SQLException SQL Exception.
*/
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;
}
/**
* To create a encoded signature from certificate.
*
* @param x509Certificate Certificate that need to be encoded.
* @return Encoded signature.
* @throws CertificateEncodingException Certificate Encoding Exception.
* @throws CMSException CMS Exception.
* @throws IOException IO Exception.
*/
private String createEncodedSignature(X509Certificate x509Certificate) throws CertificateEncodingException,
CMSException, IOException {
CMSSignedDataGenerator generator = new CMSSignedDataGenerator();
List<X509Certificate> list = new ArrayList<>();
list.add(x509Certificate);
JcaCertStore store = new JcaCertStore(list);
generator.addCertificates(store);
AtomicReference<CMSSignedData> degenerateSd = new AtomicReference<>(generator.generate(new CMSAbsentContent()));
byte[] signature = degenerateSd.get().getEncoded();
return Base64.getEncoder().encodeToString(signature);
}
}

@ -0,0 +1,177 @@
/*
* 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;
import org.apache.tomcat.util.buf.MessageBytes;
import org.apache.tomcat.util.http.MimeHeaders;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.wso2.carbon.base.MultitenantConstants;
import org.wso2.carbon.identity.jwt.client.extension.dto.JWTConfig;
import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException;
import org.wso2.carbon.identity.jwt.client.extension.util.JWTClientUtil;
import org.wso2.carbon.webapp.authenticator.framework.AuthenticationInfo;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
/**
* This is a test class for {@link JWTAuthenticator}.
*/
public class JWTAuthenticatorTest {
private JWTAuthenticator jwtAuthenticator;
private Field headersField;
private final String JWT_HEADER = "X-JWT-Assertion";
private String jwtToken;
private String wrongJwtToken;
private String jwtTokenWithWrongUser;
private static final String SIGNED_JWT_AUTH_USERNAME = "http://wso2.org/claims/enduser";
private static final String SIGNED_JWT_AUTH_TENANT_ID = "http://wso2.org/claims/enduserTenantId";
private Properties properties;
private final String ISSUER = "wso2.org/products/iot";
private final String ALIAS = "wso2carbon";
@BeforeClass
public void setup() throws NoSuchFieldException, IOException, JWTClientException {
jwtAuthenticator = new JWTAuthenticator();
headersField = org.apache.coyote.Request.class.getDeclaredField("headers");
headersField.setAccessible(true);
ClassLoader classLoader = getClass().getClassLoader();
URL resourceUrl = classLoader.getResource("jwt.properties");
File jwtPropertyFile;
JWTConfig jwtConfig = null;
if (resourceUrl != null) {
jwtPropertyFile = new File(resourceUrl.getFile());
Properties jwtConfigProperties = new Properties();
jwtConfigProperties.load(new FileInputStream(jwtPropertyFile));
jwtConfig = new JWTConfig(jwtConfigProperties);
}
Map<String, String> customClaims = new HashMap<>();
customClaims.put(SIGNED_JWT_AUTH_USERNAME, "admin");
customClaims.put(SIGNED_JWT_AUTH_TENANT_ID, String.valueOf(MultitenantConstants.SUPER_TENANT_ID));
jwtToken = JWTClientUtil.generateSignedJWTAssertion("admin", jwtConfig, false, customClaims);
customClaims = new HashMap<>();
customClaims.put(SIGNED_JWT_AUTH_USERNAME, "admin");
customClaims.put(SIGNED_JWT_AUTH_TENANT_ID, "-1");
wrongJwtToken = JWTClientUtil.generateSignedJWTAssertion("admin", jwtConfig, false, customClaims);
customClaims = new HashMap<>();
customClaims.put(SIGNED_JWT_AUTH_USERNAME, "notexisting");
customClaims.put(SIGNED_JWT_AUTH_TENANT_ID, String.valueOf(MultitenantConstants.SUPER_TENANT_ID));
jwtTokenWithWrongUser = JWTClientUtil.generateSignedJWTAssertion("notexisting", jwtConfig, false, customClaims);
}
@Test(description = "This method tests the get methods in the JWTAuthenticator",
dependsOnMethods = "testAuthenticate")
public void testGetMethods() {
Assert.assertEquals(jwtAuthenticator.getName(), "JWT", "GetName method returns wrong value");
Assert.assertNotNull(jwtAuthenticator.getProperties(), "Properties are not properly added to JWT "
+ "Authenticator");
Assert.assertEquals(jwtAuthenticator.getProperties().size(), properties.size(),
"Added properties do not match with retrieved properties");
Assert.assertNull(jwtAuthenticator.getProperty("test"), "Retrieved a propety that was never added");
Assert.assertNotNull(jwtAuthenticator.getProperty(ISSUER), ALIAS);
}
@Test(description = "This method tests the canHandle method under different conditions of request")
public void testHandle() throws IllegalAccessException, NoSuchFieldException {
Request request = new Request();
org.apache.coyote.Request coyoteRequest = new org.apache.coyote.Request();
request.setCoyoteRequest(coyoteRequest);
Assert.assertFalse(jwtAuthenticator.canHandle(request));
MimeHeaders mimeHeaders = new MimeHeaders();
MessageBytes bytes = mimeHeaders.addValue(JWT_HEADER);
bytes.setString("test");
headersField.set(coyoteRequest, mimeHeaders);
request.setCoyoteRequest(coyoteRequest);
Assert.assertTrue(jwtAuthenticator.canHandle(request));
}
@Test(description = "This method tests authenticate method under the successful condition", dependsOnMethods =
{ "testAuthenticateFailureScenarios" })
public void testAuthenticate() throws IllegalAccessException, NoSuchFieldException {
Request request = createJWTRequest(jwtToken, "test");
AuthenticationInfo authenticationInfo = jwtAuthenticator.authenticate(request, null);
Assert.assertNotNull(authenticationInfo.getUsername(), "Proper authentication request is not properly "
+ "authenticated by the JWTAuthenticator");
}
@Test(description = "This method tests the authenticate method under failure conditions")
public void testAuthenticateFailureScenarios() throws NoSuchFieldException, IllegalAccessException {
Request request = createJWTRequest("test", "");
AuthenticationInfo authenticationInfo = jwtAuthenticator.authenticate(request, null);
Assert.assertNotNull(authenticationInfo, "Returned authentication info was null");
Assert.assertNull(authenticationInfo.getUsername(), "Un-authenticated request contain username");
request = createJWTRequest(jwtToken, "");
authenticationInfo = jwtAuthenticator.authenticate(request, null);
Assert.assertNotNull(authenticationInfo, "Returned authentication info was null");
Assert.assertNull(authenticationInfo.getUsername(), "Un-authenticated request contain username");
properties = new Properties();
properties.setProperty(ISSUER, "test");
jwtAuthenticator.setProperties(properties);
request = createJWTRequest(jwtToken, "");
authenticationInfo = jwtAuthenticator.authenticate(request, null);
Assert.assertNotNull(authenticationInfo, "Returned authentication info was null");
Assert.assertEquals(authenticationInfo.getStatus(), WebappAuthenticator.Status.FAILURE,
"Un authenticated request does not contain status as failure");
properties = new Properties();
properties.setProperty(ISSUER, ALIAS);
jwtAuthenticator.setProperties(properties);
request = createJWTRequest(wrongJwtToken, "");
authenticationInfo = jwtAuthenticator.authenticate(request, null);
Assert.assertNotNull(authenticationInfo, "Returned authentication info was null");
Assert.assertEquals(authenticationInfo.getStatus(), WebappAuthenticator.Status.FAILURE,
"Un authenticated request does not contain status as failure");
request = createJWTRequest(jwtTokenWithWrongUser, "");
authenticationInfo = jwtAuthenticator.authenticate(request, null);
Assert.assertNotNull(authenticationInfo, "Returned authentication info was null");
Assert.assertEquals(authenticationInfo.getStatus(), WebappAuthenticator.Status.FAILURE,
"Un authenticated request does not contain status as failure");
}
/**
* To create a JWT request with the given jwt header.
* @param jwtToken JWT token to be added to the header
* @param requestUri Request URI to be added to the request.
*/
private Request createJWTRequest(String jwtToken, String requestUri)
throws IllegalAccessException, NoSuchFieldException {
Request request = new Request();
org.apache.coyote.Request coyoteRequest = new org.apache.coyote.Request();
MimeHeaders mimeHeaders = new MimeHeaders();
MessageBytes bytes = mimeHeaders.addValue(JWT_HEADER);
bytes.setString(jwtToken);
headersField.set(coyoteRequest, mimeHeaders);
Field uriMB = org.apache.coyote.Request.class.getDeclaredField("uriMB");
uriMB.setAccessible(true);
bytes = MessageBytes.newInstance();
bytes.setString(requestUri);
uriMB.set(coyoteRequest, bytes);
request.setCoyoteRequest(coyoteRequest);
return request;
}
}

@ -0,0 +1,43 @@
/*
* 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.internal;
import org.apache.sling.testing.mock.osgi.MockOsgi;
import org.testng.annotations.Test;
/**
* This is a test class for {@link WebappAuthenticatorFrameworkServiceComponent}
*/
public class WebappAuthenticatorFrameworkServiceComponentTest {
@Test(description = "This method tests whether the bundle activator does not throw any exceptions, even under "
+ "possible exception scenarios")
public void testActivateWithException() {
WebappAuthenticatorFrameworkServiceComponent webappAuthenticatorFrameworkServiceComponent = new
WebappAuthenticatorFrameworkServiceComponent();
webappAuthenticatorFrameworkServiceComponent.activate(null);
}
@Test(description = "This method tests whether bundle activation succeed with the proper confitions.")
public void testActivateWithoutExceptions() {
WebappAuthenticatorFrameworkServiceComponent webappAuthenticatorFrameworkServiceComponent = new
WebappAuthenticatorFrameworkServiceComponent();
webappAuthenticatorFrameworkServiceComponent.activate(MockOsgi.newComponentContext());
}
}

@ -0,0 +1,125 @@
/*
* 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.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.security.Security;
import java.security.SignatureException;
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;
/**
* This is a mock implementation of {@link CertificateGenerator}.
*/
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<Certificate> 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;
}
}
}

@ -0,0 +1,30 @@
/*
* 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.wso2.carbon.registry.indexing.service.TenantIndexingLoader;
/**
* This is a mock implementation of {@link TenantIndexingLoader}
*/
public class TestTenantIndexingLoader implements TenantIndexingLoader {
@Override
public void loadTenantIndex(int i) { }
}

@ -0,0 +1,30 @@
/*
* 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.wso2.carbon.registry.core.exceptions.RegistryException;
import org.wso2.carbon.registry.core.service.TenantRegistryLoader;
/**
* This is a mock implementation of {@link TenantRegistryLoader} for the test cases.
*/
public class TestTenantRegistryLoader implements TenantRegistryLoader {
@Override
public void loadTenantRegistry(int i) throws RegistryException { }
}

@ -0,0 +1,96 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
~ 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.
-->
<DeviceMgtConfiguration>
<ManagementRepository>
<DataSourceConfiguration>
<JndiLookupDefinition>
<Name>jdbc/DM_DS</Name>
</JndiLookupDefinition>
</DataSourceConfiguration>
</ManagementRepository>
<PushNotificationConfiguration>
<SchedulerBatchSize>1000</SchedulerBatchSize>
<SchedulerBatchDelayMills>60000</SchedulerBatchDelayMills>
<SchedulerTaskInitialDelay>60000</SchedulerTaskInitialDelay>
<SchedulerTaskEnabled>true</SchedulerTaskEnabled>
<PushNotificationProviders>
<Provider>org.wso2.carbon.device.mgt.extensions.push.notification.provider.fcm.FCMBasedPushNotificationProvider</Provider>
<!--<Provider>org.wso2.carbon.device.mgt.mobile.impl.ios.apns.APNSBasedPushNotificationProvider</Provider>-->
<Provider>org.wso2.carbon.device.mgt.extensions.push.notification.provider.mqtt.MQTTBasedPushNotificationProvider</Provider>
<Provider>org.wso2.carbon.device.mgt.extensions.push.notification.provider.http.HTTPBasedPushNotificationProvider</Provider>
<Provider>org.wso2.carbon.device.mgt.extensions.push.notification.provider.xmpp.XMPPBasedPushNotificationProvider</Provider>
</PushNotificationProviders>
</PushNotificationConfiguration>
<PullNotificationConfiguration>
<Enabled>false</Enabled>
</PullNotificationConfiguration>
<IdentityConfiguration>
<ServerUrl>https://localhost:9443</ServerUrl>
<AdminUsername>admin</AdminUsername>
<AdminPassword>admin</AdminPassword>
</IdentityConfiguration>
<PolicyConfiguration>
<MonitoringClass>org.wso2.carbon.policy.mgt</MonitoringClass>
<MonitoringEnable>true</MonitoringEnable>
<MonitoringFrequency>60000</MonitoringFrequency>
<MaxRetries>5</MaxRetries>
<MinRetriesToMarkUnreachable>8</MinRetriesToMarkUnreachable>
<MinRetriesToMarkInactive>20</MinRetriesToMarkInactive>
<!--Set the policy evaluation point name-->
<!--Simple -> Simple policy evaluation point-->
<!--Merged -> Merged policy evaluation point -->
<PolicyEvaluationPoint>Simple</PolicyEvaluationPoint>
</PolicyConfiguration>
<!-- Default Page size configuration for paginated DM APIs-->
<PaginationConfiguration>
<DeviceListPageSize>20</DeviceListPageSize>
<GroupListPageSize>20</GroupListPageSize>
<NotificationListPageSize>20</NotificationListPageSize>
<ActivityListPageSize>20</ActivityListPageSize>
<OperationListPageSize>20</OperationListPageSize>
<TopicListPageSize>20</TopicListPageSize>
</PaginationConfiguration>
<!--This specifies whether to enable the DeviceStatus Task in this node. In clustered setup only master node
should have to run this task.-->
<DeviceStatusTaskConfig>
<Enable>true</Enable>
</DeviceStatusTaskConfig>
<!--This controls the in-memory device cache which is local to this node. Setting it enable will activate the
device caching for upto configured expiry-time in seconds. In clustered setup all worker nodes can enable the
device-cache to improve performance. -->
<DeviceCacheConfiguration>
<Enable>true</Enable>
<ExpiryTime>600</ExpiryTime>
<!--This configuration specifies the number of cache entries in device cache. default capacity is 10000 entries.
This can be configured to higher number if cache eviction happens due to large number of devices in the
server environment-->
<Capacity>10000</Capacity>
</DeviceCacheConfiguration>
<CertificateCacheConfiguration>
<Enable>false</Enable>
<ExpiryTime>86400</ExpiryTime>
</CertificateCacheConfiguration>
<GeoLocationConfiguration>
<isEnabled>false</isEnabled>
<PublishLocationOperationResponse>false</PublishLocationOperationResponse>
</GeoLocationConfiguration>
<DefaultGroupsConfiguration>BYOD,COPE</DefaultGroupsConfiguration>
</DeviceMgtConfiguration>

@ -0,0 +1,57 @@
#
# 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.
#
#issuer of the JWT
iss=wso2.org/products/iot
TokenEndpoint=https://${iot.gateway.host}:${iot.gateway.https.port}/token?tenantDomain=carbon.super
#audience of JWT claim
#comma seperated values
aud=devicemgt
#expiration time of JWT (number of minutes from the current time)
exp=1000
#issued at time of JWT (number of minutes from the current time)
iat=0
#nbf time of JWT (number of minutes from current time)
nbf=0
#skew between IDP and issuer(seconds)
skew=0
# JWT Id
#jti=token123
#KeyStore to cryptographic credentials
KeyStore=target/test-classes/carbon-home/repository/resources/security/wso2carbon.jks
#Password of the KeyStore
KeyStorePassword=wso2carbon
#Alias of the SP's private key
PrivateKeyAlias=wso2carbon
#Private key password to retrieve the private key used to sign
#AuthnRequest and LogoutRequest messages
PrivateKeyPassword=wso2carbon
#this will be used as the default IDP config if there isn't any config available for tenants.
default-jwt-client=false

@ -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)
);

@ -22,7 +22,7 @@
<suite name="WebappAuthenticatorFramework"> <suite name="WebappAuthenticatorFramework">
<parameter name="useDefaultListeners" value="false"/> <parameter name="useDefaultListeners" value="false"/>
<test name="WebappAuthenticatorTests" preserve-order="true"> <test name="WebappAuthenticatorTests" parallel="false">
<classes> <classes>
<class name="org.wso2.carbon.webapp.authenticator.framework.BaseWebAppAuthenticatorFrameworkTest"/> <class name="org.wso2.carbon.webapp.authenticator.framework.BaseWebAppAuthenticatorFrameworkTest"/>
<class name="org.wso2.carbon.webapp.authenticator.framework.WebappAuthenticatorConfigTest"/> <class name="org.wso2.carbon.webapp.authenticator.framework.WebappAuthenticatorConfigTest"/>
@ -31,6 +31,9 @@
<class name="org.wso2.carbon.webapp.authenticator.framework.authenticator.BasicAuthAuthenticatorTest" /> <class name="org.wso2.carbon.webapp.authenticator.framework.authenticator.BasicAuthAuthenticatorTest" />
<class name="org.wso2.carbon.webapp.authenticator.framework.authenticator.BSTAuthenticatorTest" /> <class name="org.wso2.carbon.webapp.authenticator.framework.authenticator.BSTAuthenticatorTest" />
<class name="org.wso2.carbon.webapp.authenticator.framework.authenticator.OauthAuthenticatorTest" /> <class name="org.wso2.carbon.webapp.authenticator.framework.authenticator.OauthAuthenticatorTest" />
<class name="org.wso2.carbon.webapp.authenticator.framework.authenticator.JWTAuthenticatorTest" />
<class name="org.wso2.carbon.webapp.authenticator.framework.authenticator.CertificateAuthenticatorTest" />
<class name="org.wso2.carbon.webapp.authenticator.framework.internal.WebappAuthenticatorFrameworkServiceComponentTest"/>
</classes> </classes>
</test> </test>

@ -1568,6 +1568,12 @@
</exclusion> </exclusion>
</exclusions> </exclusions>
</dependency> </dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
<scope>test</scope>
<version>${slf4j.nop.version}</version>
</dependency>
</dependencies> </dependencies>
</dependencyManagement> </dependencyManagement>
@ -2005,6 +2011,7 @@
<ant.contrib.version>1.0b3</ant.contrib.version> <ant.contrib.version>1.0b3</ant.contrib.version>
<power.mock.version>1.7.0</power.mock.version> <power.mock.version>1.7.0</power.mock.version>
<commons.dbcp.version>1.4.0.wso2v1</commons.dbcp.version> <commons.dbcp.version>1.4.0.wso2v1</commons.dbcp.version>
<slf4j.nop.version>1.7.25</slf4j.nop.version>
</properties> </properties>

Loading…
Cancel
Save