diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/CertificateManagementAdminService.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/CertificateManagementAdminService.java index b867998c189..a273a52fd20 100644 --- a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/CertificateManagementAdminService.java +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/CertificateManagementAdminService.java @@ -316,4 +316,79 @@ public interface CertificateManagementAdminService { defaultValue = "12438035315552875930") @PathParam("serialNumber") String serialNumber); + /** + * Verify IOS Certificate for the API security filter + * + * @param certificate to be verified as a String + * @return Status of the certificate verification. + */ + @POST + @Path("/verify/ios") + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Verify IOS SSL certificate", + notes = "Verify IOS Certificate for the API security filter.\n", + tags = "Certificate Management") + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "Return the status of the IOS certificate verification.", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body")}), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class) + }) + @Permission(name = "Manage certificates", permission = "/device-mgt/certificates/manage") + Response verifyIOSCertificate( + @ApiParam( + name = "certificate", + value = "The properties to verify certificate. It includes the following: \n" + + "serial: The unique ID of the certificate. (optional) \n" + + "pem: mdm-signature of the certificate", + required = true) EnrollmentCertificate certificate); + + /** + * Verify Android Certificate for the API security filter + * + * @param certificate to be verified as a String + * @return Status of the certificate verification. + */ + @POST + @Path("/verify/android") + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Verify Android SSL certificate", + notes = "Verify Android Certificate for the API security filter.\n", + tags = "Certificate Management") + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "Return the status of the Android certificate verification.", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body")}), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class) + }) + @Permission(name = "Manage certificates", permission = "/device-mgt/certificates/manage") + Response verifyAndroidCertificate( + @ApiParam( + name = "certificate", + value = "The properties to verify certificate. It includes the following: \n" + + "serial: The unique ID of the certificate. (optional) \n" + + "pem: pem String of the certificate", + required = true) EnrollmentCertificate certificate); } diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/impl/CertificateManagementAdminServiceImpl.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/impl/CertificateManagementAdminServiceImpl.java index e0f0852787c..0b7b7210e88 100644 --- a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/impl/CertificateManagementAdminServiceImpl.java +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/impl/CertificateManagementAdminServiceImpl.java @@ -1,5 +1,6 @@ package org.wso2.carbon.certificate.mgt.cert.jaxrs.api.impl; +import io.swagger.annotations.ApiParam; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.CertificateManagementAdminService; @@ -11,9 +12,14 @@ import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.util.RequestValidationUtil import org.wso2.carbon.certificate.mgt.core.dto.CertificateResponse; import org.wso2.carbon.certificate.mgt.core.exception.CertificateManagementException; import org.wso2.carbon.certificate.mgt.core.exception.KeystoreException; +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.TenantedDeviceWrapper; import org.wso2.carbon.certificate.mgt.core.service.CertificateManagementService; import org.wso2.carbon.certificate.mgt.core.service.PaginationResult; import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.device.mgt.common.DeviceManagementConstants; import javax.ws.rs.*; import javax.ws.rs.core.Response; @@ -25,6 +31,7 @@ import java.util.List; public class CertificateManagementAdminServiceImpl implements CertificateManagementAdminService { private static Log log = LogFactory.getLog(CertificateManagementAdminServiceImpl.class); + private static final String PROXY_AUTH_MUTUAL_HEADER = "proxy-mutual-auth-header"; /** * Save a list of certificates and relevant information in the database. @@ -138,4 +145,68 @@ public class CertificateManagementAdminServiceImpl implements CertificateManagem } } + @POST + @Path("/verify/ios") + public Response verifyIOSCertificate(@ApiParam(name = "certificate", value = "Mdm-Signature of the " + + "certificate that needs to be verified", required = true) EnrollmentCertificate certificate) { + try { + CertificateManagementService certMgtService = CertificateMgtAPIUtils.getCertificateManagementService(); + X509Certificate cert = certMgtService.extractCertificateFromSignature(certificate.getPem()); + String challengeToken = certMgtService.extractChallengeToken(cert); + + if (challengeToken != null) { + challengeToken = challengeToken.substring(challengeToken.indexOf("(") + 1).trim(); + + SCEPManager scepManager = CertificateMgtAPIUtils.getSCEPManagerService(); + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(); + deviceIdentifier.setId(challengeToken); + deviceIdentifier.setType(DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_IOS); + TenantedDeviceWrapper tenantedDeviceWrapper = scepManager.getValidatedDevice(deviceIdentifier); + + if (tenantedDeviceWrapper != null) { + return Response.status(Response.Status.OK).entity("valid").build(); + } + } + } catch (SCEPException e) { + String msg = "Error occurred while extracting information from certificate."; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build()).build(); + } catch (KeystoreException e) { + String msg = "Error occurred while converting PEM file to X509Certificate."; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build()).build(); + } + return Response.status(Response.Status.OK).entity("invalid").build(); + } + + @POST + @Path("/verify/android") + public Response verifyAndroidCertificate(@ApiParam(name = "certificate", value = "Base64 encoded .pem file of the " + + "certificate that needs to be verified", required = true) EnrollmentCertificate certificate) { + CertificateResponse certificateResponse = null; + try { + CertificateManagementService certMgtService = CertificateMgtAPIUtils.getCertificateManagementService(); + if (certificate.getSerial().toLowerCase().contains(PROXY_AUTH_MUTUAL_HEADER)) { + certificateResponse = certMgtService.verifySubjectDN(certificate.getPem()); + } else { + X509Certificate clientCertificate = certMgtService.pemToX509Certificate(certificate.getPem()); + if (clientCertificate != null) { + certificateResponse = certMgtService.verifyPEMSignature(clientCertificate); + } + } + + if (certificateResponse != null && certificateResponse.getCommonName() != null && !certificateResponse + .getCommonName().isEmpty()) { + return Response.status(Response.Status.OK).entity("valid").build(); + } + } catch (KeystoreException e) { + String msg = "Error occurred while converting PEM file to X509Certificate."; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build()).build(); + } + return Response.status(Response.Status.OK).entity("invalid").build(); + } } \ No newline at end of file diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/util/CertificateMgtAPIUtils.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/util/CertificateMgtAPIUtils.java index a96b013b7b5..06bc3169fea 100644 --- a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/util/CertificateMgtAPIUtils.java +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/util/CertificateMgtAPIUtils.java @@ -20,6 +20,7 @@ package org.wso2.carbon.certificate.mgt.cert.jaxrs.api.util; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.certificate.mgt.core.scep.SCEPManager; import org.wso2.carbon.certificate.mgt.core.service.CertificateManagementService; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.device.mgt.core.search.mgt.SearchManagerService; @@ -50,6 +51,22 @@ public class CertificateMgtAPIUtils { } + public static SCEPManager getSCEPManagerService() { + + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + SCEPManager scepManagerService = (SCEPManager) + ctx.getOSGiService(SCEPManager.class, null); + + if (scepManagerService == null) { + String msg = "SCEPManagerImpl Management service not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + + return scepManagerService; + } + + public static MediaType getResponseMediaType(String acceptHeader) { MediaType responseMediaType; if (acceptHeader == null || MediaType.WILDCARD.equals(acceptHeader)) {