Skip to content

Commit

Permalink
rmvapi auhtn from attestation mgt
Browse files Browse the repository at this point in the history
  • Loading branch information
Thumimku committed Nov 3, 2023
1 parent 9a3edb4 commit f935b6a
Show file tree
Hide file tree
Showing 9 changed files with 123 additions and 150 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ private IdentityApplicationConstants() {
public static final String ANDROID_PACKAGE_NAME_DISPLAY_NAME = "Android mobile application package name";
public static final String APPLICATION_SECRET_TYPE_ANDROID_ATTESTATION_CREDENTIALS
= "ANDROID_ATTESTATION_CREDENTIALS";
public static final String CLIENT_ATTESTATION = "CLIENT_ATTESTATION";
public static final String ANDROID = "ANDROID";

/**
* Config elements.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,11 @@
import static org.wso2.carbon.identity.application.common.util.IdentityApplicationConstants.ADVANCED_CONFIG;
import static org.wso2.carbon.identity.application.common.util.IdentityApplicationConstants.ALLOWED_ROLE_AUDIENCE_PROPERTY_NAME;
import static org.wso2.carbon.identity.application.common.util.IdentityApplicationConstants.ALLOWED_ROLE_AUDIENCE_REQUEST_ATTRIBUTE_NAME;
import static org.wso2.carbon.identity.application.common.util.IdentityApplicationConstants.ANDROID;
import static org.wso2.carbon.identity.application.common.util.IdentityApplicationConstants.ANDROID_PACKAGE_NAME_DISPLAY_NAME;
import static org.wso2.carbon.identity.application.common.util.IdentityApplicationConstants.ANDROID_PACKAGE_NAME_PROPERTY_NAME;
import static org.wso2.carbon.identity.application.common.util.IdentityApplicationConstants.APPLICATION_SECRET_TYPE_ANDROID_ATTESTATION_CREDENTIALS;
import static org.wso2.carbon.identity.application.common.util.IdentityApplicationConstants.CLIENT_ATTESTATION;
import static org.wso2.carbon.identity.application.common.util.IdentityApplicationConstants.CLIENT_ID_SP_PROPERTY_NAME;
import static org.wso2.carbon.identity.application.common.util.IdentityApplicationConstants.Error.APPLICATION_ALREADY_EXISTS;
import static org.wso2.carbon.identity.application.common.util.IdentityApplicationConstants.Error.APPLICATION_NOT_DISCOVERABLE;
Expand Down Expand Up @@ -2346,11 +2348,11 @@ private String getAndroidAttestationServiceCredentials(ServiceProvider servicePr
try {
if (ApplicationManagementServiceComponentHolder.getInstance()
.getSecretManager().isSecretExist(APPLICATION_SECRET_TYPE_ANDROID_ATTESTATION_CREDENTIALS,
serviceProvider.getApplicationResourceId())) {
getAndroidAttestationSecretName(serviceProvider.getApplicationResourceId()))) {
ResolvedSecret resolvedSecret = ApplicationManagementServiceComponentHolder.getInstance()
.getSecretResolveManager()
.getResolvedSecret(APPLICATION_SECRET_TYPE_ANDROID_ATTESTATION_CREDENTIALS,
serviceProvider.getApplicationResourceId());
getAndroidAttestationSecretName(serviceProvider.getApplicationResourceId()));
if (resolvedSecret != null) {
return resolvedSecret.getResolvedSecretValue();
}
Expand Down Expand Up @@ -4996,13 +4998,13 @@ private void storeAndroidAttestationServiceCredentialAsSecret(ServiceProvider sp
if (sp.getClientAttestationMetaData() != null &&
sp.getClientAttestationMetaData().getAndroidAttestationServiceCredentials() != null) {
SecretManager secretManager = ApplicationManagementServiceComponentHolder.getInstance().getSecretManager();
Secret secret = new Secret(sp.getApplicationResourceId());
Secret secret = new Secret(getAndroidAttestationSecretName(sp.getApplicationResourceId()));
secret.setSecretValue(sp.getClientAttestationMetaData().getAndroidAttestationServiceCredentials());
try {
if (secretManager.isSecretExist(APPLICATION_SECRET_TYPE_ANDROID_ATTESTATION_CREDENTIALS,
sp.getApplicationResourceId())) {
getAndroidAttestationSecretName(sp.getApplicationResourceId()))) {
secretManager.updateSecretValue(APPLICATION_SECRET_TYPE_ANDROID_ATTESTATION_CREDENTIALS,
sp.getApplicationResourceId(),
getAndroidAttestationSecretName(sp.getApplicationResourceId()),
sp.getClientAttestationMetaData().getAndroidAttestationServiceCredentials());

} else {
Expand All @@ -5018,6 +5020,11 @@ private void storeAndroidAttestationServiceCredentialAsSecret(ServiceProvider sp

}

private String getAndroidAttestationSecretName(String applicationResourceId) {

return applicationResourceId + ":" + CLIENT_ATTESTATION + ":" + ANDROID;
}

private ServiceProviderProperty buildIsManagementAppProperty(ServiceProvider sp) {

ServiceProviderProperty isManagementAppProperty = new ServiceProviderProperty();
Expand Down Expand Up @@ -5372,7 +5379,7 @@ private void deleteAndroidAttestationCredentials(ServiceProvider application)
try {
ApplicationManagementServiceComponentHolder.getInstance()
.getSecretManager().deleteSecret(APPLICATION_SECRET_TYPE_ANDROID_ATTESTATION_CREDENTIALS,
application.getApplicationResourceId());
getAndroidAttestationSecretName(application.getApplicationResourceId()));
} catch (SecretManagementException e) {
throw new IdentityApplicationManagementException("Failed to delete Android Attestation " +
"Service Credentials for service provider with id: " + application.getApplicationID(), e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ protected void activate(ComponentContext context) {
try {
context.getBundleContext().registerService(ClientAttestationService.class.getName(),
new ClientAttestationServiceImpl(), null);
log.info("Client Attestation metadata Service Component deployed.");
log.info("Client Attestation Service Component deployed.");

} catch (Throwable throwable) {
log.error("Error while activating Input Validation Service Component.", throwable);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,19 @@ public class ClientAttestationContext extends MessageContext {

private static final long serialVersionUID = 1995051819950410L;

private String clientId;
private String applicationResourceId;
private String tenantDomain;
private boolean apiBasedAuthenticationEnabled;
private boolean attestationEnabled;
private boolean isAttested;
private Constants.ClientTypes clientType;
private String errorMessage;
private String validationFailureMessage;

public String getClientId() {
return clientId;
public String getApplicationResourceId() {
return applicationResourceId;
}

public void setClientId(String clientId) {
this.clientId = clientId;
public void setApplicationResourceId(String applicationResourceId) {
this.applicationResourceId = applicationResourceId;
}

public String getTenantDomain() {
Expand All @@ -56,14 +55,6 @@ public void setTenantDomain(String tenantDomain) {
this.tenantDomain = tenantDomain;
}

public boolean isApiBasedAuthenticationEnabled() {
return apiBasedAuthenticationEnabled;
}

public void setApiBasedAuthenticationEnabled(boolean apiBasedAuthenticationEnabled) {
this.apiBasedAuthenticationEnabled = apiBasedAuthenticationEnabled;
}

public boolean isAttestationEnabled() {
return attestationEnabled;
}
Expand All @@ -88,24 +79,23 @@ public void setClientType(Constants.ClientTypes clientType) {
this.clientType = clientType;
}

public String getErrorMessage() {
return errorMessage;
public String getValidationFailureMessage() {
return validationFailureMessage;
}

public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
public void setValidationFailureMessage(String validationFailureMessage) {
this.validationFailureMessage = validationFailureMessage;
}

@Override
public String toString() {
return "ClientAttestationContext{" +
"clientId='" + clientId + '\'' +
"applicationResourceId='" + applicationResourceId + '\'' +
", tenantDomain='" + tenantDomain + '\'' +
", apiBasedAuthenticationEnabled=" + apiBasedAuthenticationEnabled +
", attestationEnabled=" + attestationEnabled +
", isAttested=" + isAttested +
", clientType=" + clientType +
", errorMessage='" + errorMessage + '\'' +
", errorMessage='" + validationFailureMessage + '\'' +
'}';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

package org.wso2.carbon.identity.client.attestation.mgt.services;

import org.wso2.carbon.identity.client.attestation.mgt.exceptions.ClientAttestationMgtException;
import org.wso2.carbon.identity.client.attestation.mgt.model.ClientAttestationContext;

/**
Expand All @@ -30,11 +31,13 @@ public interface ClientAttestationService {
/**
* Validates the attestation data for a client and tenant and returns a context with the validation result.
*
* @param attestationObject The attestation data to be validated.
* @param clientId The client ID.
* @param tenantDomain The tenant domain.
* @param attestationObject The attestation data to be validated.
* @param applicationResourceId The application Resource Id.
* @param tenantDomain The tenant domain.
* @return A context with the validation result.
* @throws ClientAttestationMgtException If an error occurs during the attestation validation process.
*/
public ClientAttestationContext validateAttestation(String attestationObject, String clientId, String tenantDomain);
public ClientAttestationContext validateAttestation(String attestationObject, String applicationResourceId,
String tenantDomain) throws ClientAttestationMgtException;
}

Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
* ```
* ClientAttestationService clientAttestationService = new ClientAttestationServiceImpl();
* ClientAttestationContext clientAttestationContext =
* clientAttestationService.validateAttestation(attestationObject, clientId, tenantDomain);
* clientAttestationService.validateAttestation(attestationObject, applicationResourceId, tenantDomain);
* // Check the validation result and obtain client attestation context.
* ```
*/
Expand All @@ -63,77 +63,56 @@ public class ClientAttestationServiceImpl implements ClientAttestationService {

@Override
public ClientAttestationContext validateAttestation(String attestationObject,
String clientId, String tenantDomain) {
String applicationResourceId, String tenantDomain)
throws ClientAttestationMgtException {

ClientAttestationContext clientAttestationContext = new ClientAttestationContext();
clientAttestationContext.setClientId(clientId);
clientAttestationContext.setApplicationResourceId(applicationResourceId);
clientAttestationContext.setTenantDomain(tenantDomain);

try {
ServiceProvider serviceProvider = getServiceProvider(clientId, tenantDomain);

// Check if the app is subscribed to API-Based Authentication.
if (!serviceProvider.isAPIBasedAuthenticationEnabled()) {
// App is not subscribed to API-Based Authentication but is calling for validation.
// This is a potential attack, so reject the request.
if (LOG.isDebugEnabled()) {
LOG.debug("App :" + serviceProvider.getApplicationResourceId() + " in tenant : " + tenantDomain +
" is not subscribed to API-Based Authentication.");
}
clientAttestationContext.setApiBasedAuthenticationEnabled(false);
clientAttestationContext.setAttestationEnabled(false);
clientAttestationContext.setAttested(false);
clientAttestationContext.setErrorMessage("App is not subscribed to API-Based Authentication.");
return clientAttestationContext;
}
ServiceProvider serviceProvider = getServiceProvider(applicationResourceId, tenantDomain);

// Check if the app is subscribed to client attestation validation.
if (serviceProvider.getClientAttestationMetaData() == null
|| !serviceProvider.getClientAttestationMetaData().isAttestationEnabled()) {
// App is not subscribed to client attestation validation, proceed without validation.
// This may be a testing scenario, so approve the request.
if (LOG.isDebugEnabled()) {
LOG.debug("App :" + serviceProvider.getApplicationResourceId() + " in tenant : " + tenantDomain +
" is not subscribed to Client Attestation Service.");
}
clientAttestationContext.setApiBasedAuthenticationEnabled(true);
clientAttestationContext.setAttestationEnabled(false);
clientAttestationContext.setAttested(true);
return clientAttestationContext;
// Check if the app is subscribed to client attestation validation.
if (serviceProvider.getClientAttestationMetaData() == null
|| !serviceProvider.getClientAttestationMetaData().isAttestationEnabled()) {
// App is not subscribed to client attestation validation, proceed without validation.
// This may be a testing scenario, so approve the request.
if (LOG.isDebugEnabled()) {
LOG.debug("App :" + serviceProvider.getApplicationResourceId() + " in tenant : " + tenantDomain +
" is not subscribed to Client Attestation Service.");
}
clientAttestationContext.setAttestationEnabled(false);
clientAttestationContext.setAttested(true);
return clientAttestationContext;
}

// Check if the attestation object is empty.
if (StringUtils.isEmpty(attestationObject)) {
// App is configured to validate attestation but attestation object is empty.
// This is a potential attack, so reject the request.
if (LOG.isDebugEnabled()) {
LOG.debug("App :" + serviceProvider.getApplicationResourceId() + " in tenant : " + tenantDomain +
" is requested with empty attestation object.");
}
clientAttestationContext.setApiBasedAuthenticationEnabled(true);
clientAttestationContext.setAttestationEnabled(true);
clientAttestationContext.setAttested(false);
clientAttestationContext.setErrorMessage("App is configured to validate attestation " +
"but attestation object is empty.");
return clientAttestationContext;
// Check if the attestation object is empty.
if (StringUtils.isEmpty(attestationObject)) {
// App is configured to validate attestation but attestation object is empty.
// This is a potential attack, so reject the request.
if (LOG.isDebugEnabled()) {
LOG.debug("App :" + serviceProvider.getApplicationResourceId() + " in tenant : " + tenantDomain +
" is requested with empty attestation object.");
}
clientAttestationContext.setAttestationEnabled(true);
clientAttestationContext.setAttested(false);
clientAttestationContext.setValidationFailureMessage("App is configured to validate attestation " +
"but attestation object is empty.");
return clientAttestationContext;
}

if (isAndroidAttestation(attestationObject)) {
if (isAndroidAttestation(attestationObject)) {

clientAttestationContext.setApiBasedAuthenticationEnabled(true);
clientAttestationContext.setAttestationEnabled(true);
clientAttestationContext.setClientType(Constants.ClientTypes.ANDROID);
clientAttestationContext.setAttestationEnabled(true);
clientAttestationContext.setClientType(Constants.ClientTypes.ANDROID);

ClientAttestationValidator androidAttestationValidator = new AndroidAttestationValidator(clientId,
tenantDomain, serviceProvider.getClientAttestationMetaData());
androidAttestationValidator.validateAttestation(attestationObject, clientAttestationContext);
return clientAttestationContext;
} else {
handleInvalidAttestationObject(clientAttestationContext);
return clientAttestationContext;
}
} catch (ClientAttestationMgtException e) {
handleClientAttestationException(e, clientAttestationContext);
ClientAttestationValidator androidAttestationValidator =
new AndroidAttestationValidator(applicationResourceId, tenantDomain,
serviceProvider.getClientAttestationMetaData());
androidAttestationValidator.validateAttestation(attestationObject, clientAttestationContext);
return clientAttestationContext;
} else {
handleInvalidAttestationObject(clientAttestationContext);
return clientAttestationContext;
}
}
Expand Down Expand Up @@ -162,7 +141,7 @@ private void setErrorToContext(String message, ClientAttestationContext clientAt
LOG.debug("Setting error to client attestation context : Error message : " + message);
}
clientAttestationContext.setAttested(false);
clientAttestationContext.setErrorMessage(message);
clientAttestationContext.setValidationFailureMessage(message);
}

private boolean isAndroidAttestation(String attestationObject) {
Expand All @@ -178,28 +157,27 @@ private boolean isAndroidAttestation(String attestationObject) {
}
}

private ServiceProvider getServiceProvider(String clientId, String tenantDomain)
private ServiceProvider getServiceProvider(String applicationId, String tenantDomain)
throws ClientAttestationMgtException {

ServiceProvider serviceProvider;
try {
serviceProvider = ClientAttestationMgtDataHolder.getInstance().getApplicationManagementService()
.getServiceProviderByClientId(clientId, OAUTH2, tenantDomain);
.getApplicationByResourceId(applicationId, tenantDomain);
} catch (IdentityApplicationManagementException e) {
throw new ClientAttestationMgtException("Error occurred while retrieving OAuth2 " +
"application data for client id " +
clientId, e);
"application data for application id " + applicationId, e);
}
if (serviceProvider == null) {
if (LOG.isDebugEnabled()) {
LOG.debug("Could not find an application for client id: " + clientId
+ ", scope: " + OAUTH2 + ", tenant: " + tenantDomain);
LOG.debug("Could not find an application for application id: " + applicationId
+ ", tenant: " + tenantDomain);
}
throw new ClientAttestationMgtException("Service Provider not found.");
}
if (LOG.isDebugEnabled()) {
LOG.debug("Retrieved service provider: " + serviceProvider.getApplicationName() + " for client: " +
clientId + ", scope: " + OAUTH2 + ", tenant: " +
applicationId + ", scope: " + OAUTH2 + ", tenant: " +
tenantDomain);
}
return serviceProvider;
Expand Down
Loading

0 comments on commit f935b6a

Please sign in to comment.