diff --git a/db_scripts/mosip_keymgr/ddl/keymgr-ca_cert_store.sql b/db_scripts/mosip_keymgr/ddl/keymgr-ca_cert_store.sql index b146f3d7..1da562e3 100644 --- a/db_scripts/mosip_keymgr/ddl/keymgr-ca_cert_store.sql +++ b/db_scripts/mosip_keymgr/ddl/keymgr-ca_cert_store.sql @@ -20,6 +20,7 @@ CREATE TABLE keymgr.ca_cert_store( upd_dtimes timestamp, is_deleted boolean DEFAULT FALSE, del_dtimes timestamp, + ca_cert_type character varying(25), CONSTRAINT pk_cacs_id PRIMARY KEY (cert_id), CONSTRAINT cert_thumbprint_unique UNIQUE (cert_thumbprint,partner_domain) @@ -61,3 +62,5 @@ COMMENT ON COLUMN keymgr.ca_cert_store.is_deleted IS 'IS_Deleted : Flag to mark -- ddl-end -- COMMENT ON COLUMN keymgr.ca_cert_store.del_dtimes IS 'Deleted DateTimestamp : Date and Timestamp when the record is soft deleted with is_deleted=TRUE'; -- ddl-end -- +COMMENT ON COLUMN keymgr.ca_cert_store.ca_cert_type IS 'CA Certificate Type : Indicates if the certificate is a ROOT or INTERMEDIATE CA certificate'; +-- ddl-end -- \ No newline at end of file diff --git a/db_upgrade_scripts/mosip_keymgr/sql/ca_cert_table_update.sql b/db_upgrade_scripts/mosip_keymgr/sql/ca_cert_table_update.sql new file mode 100644 index 00000000..073781de --- /dev/null +++ b/db_upgrade_scripts/mosip_keymgr/sql/ca_cert_table_update.sql @@ -0,0 +1,7 @@ +\c mosip_keymgr + +ALTER TABLE IF EXISTS keymgr.ca_cert_store + ADD COLUMN ca_cert_type character varying(25); + +COMMENT ON COLUMN keymgr.ca_cert_store.ca_cert_type + IS 'CA_Certificate Type: Specifies the type of CA_Certificate e.g., Root, Intermediate, end-entity'; diff --git a/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/keymanagerservice/entity/CACertificateStore.java b/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/keymanagerservice/entity/CACertificateStore.java index d12bdcd8..76f0e304 100644 --- a/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/keymanagerservice/entity/CACertificateStore.java +++ b/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/keymanagerservice/entity/CACertificateStore.java @@ -91,5 +91,10 @@ public class CACertificateStore extends BaseEntity { */ @Column(name = "partner_domain") private String partnerDomain; - + + /** + * The field CA Certificate Type + */ + @Column(name = "ca_cert_type") + private String caCertificateType; } \ No newline at end of file diff --git a/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/keymanagerservice/repository/CACertificateStoreRepository.java b/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/keymanagerservice/repository/CACertificateStoreRepository.java index dc3e4e99..b1178d60 100644 --- a/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/keymanagerservice/repository/CACertificateStoreRepository.java +++ b/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/keymanagerservice/repository/CACertificateStoreRepository.java @@ -5,6 +5,7 @@ import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; @@ -18,7 +19,7 @@ * */ @Repository -public interface CACertificateStoreRepository extends JpaRepository { +public interface CACertificateStoreRepository extends JpaRepository, JpaSpecificationExecutor { /** * Function to find CACertificates by Certificate Subject and Certificate Issuer. @@ -44,7 +45,14 @@ public interface CACertificateStoreRepository extends JpaRepository findAll(); - + + /** + * Function to fetch all certificate whose caCertificateType is null + * + * @return list of CACertificateStore + */ + List findByCaCertificateTypeIsNull(); + /** * Function to find CACertificates by Certificate Subject. * diff --git a/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/constant/CaCertificateTypeConsts.java b/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/constant/CaCertificateTypeConsts.java new file mode 100644 index 00000000..7b8034cd --- /dev/null +++ b/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/constant/CaCertificateTypeConsts.java @@ -0,0 +1,6 @@ +package io.mosip.kernel.partnercertservice.constant; + +public enum CaCertificateTypeConsts { + ROOT, + INTERMEDIATE +} diff --git a/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/constant/PartnerCertManagerConstants.java b/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/constant/PartnerCertManagerConstants.java index 9b4c49c3..11a0a773 100644 --- a/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/constant/PartnerCertManagerConstants.java +++ b/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/constant/PartnerCertManagerConstants.java @@ -96,4 +96,6 @@ public interface PartnerCertManagerConstants { String ROOT_APP_ID = "ROOT"; String AUTH_DOMAIN = "AUTH"; + + String PMS_APP_ID = "PMS"; } diff --git a/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/constant/PartnerCertManagerErrorConstants.java b/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/constant/PartnerCertManagerErrorConstants.java index 9d80c7ec..131067b9 100644 --- a/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/constant/PartnerCertManagerErrorConstants.java +++ b/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/constant/PartnerCertManagerErrorConstants.java @@ -42,6 +42,8 @@ public enum PartnerCertManagerErrorConstants { SIGN_CERT_NOT_ALLOWED("KER-PCM-016", "Sign Certificate not allowed for the authenticated token."), CERT_VALIDITY_LESS_THAN_MIN_VALIDITY_NOT_ALLOWED("KER-PCM-017","The CA Certificate validity is less than required minimum validity."), + + INVALID_CA_CERTIFICATE_TYPE("KER-PCM-017", "Invalid Certificate Type"); ; /** diff --git a/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/controller/PartnerCertManagerController.java b/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/controller/PartnerCertManagerController.java index fa55a3c8..793a4d10 100644 --- a/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/controller/PartnerCertManagerController.java +++ b/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/controller/PartnerCertManagerController.java @@ -1,5 +1,6 @@ package io.mosip.kernel.partnercertservice.controller; +import io.mosip.kernel.partnercertservice.dto.*; import jakarta.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; @@ -14,15 +15,6 @@ import io.mosip.kernel.core.http.RequestWrapper; import io.mosip.kernel.core.http.ResponseFilter; import io.mosip.kernel.core.http.ResponseWrapper; -import io.mosip.kernel.partnercertservice.dto.CACertificateRequestDto; -import io.mosip.kernel.partnercertservice.dto.PartnerSignedCertDownloadResponseDto; -import io.mosip.kernel.partnercertservice.dto.CACertificateResponseDto; -import io.mosip.kernel.partnercertservice.dto.CertificateTrustRequestDto; -import io.mosip.kernel.partnercertservice.dto.CertificateTrustResponeDto; -import io.mosip.kernel.partnercertservice.dto.PartnerCertDownloadRequestDto; -import io.mosip.kernel.partnercertservice.dto.PartnerCertDownloadResponeDto; -import io.mosip.kernel.partnercertservice.dto.PartnerCertificateRequestDto; -import io.mosip.kernel.partnercertservice.dto.PartnerCertificateResponseDto; import io.mosip.kernel.partnercertservice.service.spi.PartnerCertificateManagerService; import io.swagger.annotations.ApiParam; import io.swagger.v3.oas.annotations.Operation; @@ -180,5 +172,29 @@ public ResponseWrapper getPartnerSignedCer response.setResponse(partnerCertManagerService.getPartnerSignedCertificate(certDownloadRequestDto)); return response; } - + + /** + * To get the Previously uploaded CA and IntermediateCA Certificate + * + * @param certListRequestDto {@link CaCertTypeListRequestDto} request + * @return {@link CaCertTypeListRequestDto} Cetificate List data + */ + @Operation(summary = "To Download CA Type Certificate List.", + description = "To Download CA Type Certificate List.", tags = { "cacertmanager" }) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Success or you may find errors in error array in response"), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(schema = @Schema(hidden = true))), + @ApiResponse(responseCode = "403", description = "Forbidden", content = @Content(schema = @Schema(hidden = true))), + @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(schema = @Schema(hidden = true))) }) + + @ResponseFilter + @PreAuthorize("hasAnyRole(@keyManAuthRoles.getPostgetcacertificates())") + @PostMapping(value = "/getCaCertificates", produces = "application/json") + public ResponseWrapper getCaCertificateList( + @ApiParam("To get List of Certificate Based on CA certificate Type.") @RequestBody @Valid RequestWrapper certListRequestDto) { + + ResponseWrapper response = new ResponseWrapper<>(); + response.setResponse(partnerCertManagerService.getCaCertificateChain(certListRequestDto.getRequest())); + return response; + } } \ No newline at end of file diff --git a/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/dto/AuthorizedRolesDTO.java b/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/dto/AuthorizedRolesDTO.java index 57f9a8c7..98b7a2c7 100644 --- a/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/dto/AuthorizedRolesDTO.java +++ b/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/dto/AuthorizedRolesDTO.java @@ -26,4 +26,6 @@ public class AuthorizedRolesDTO { private List getgetpartnersignedcertificatepartnercertid; + private List postgetcacertificates; + } \ No newline at end of file diff --git a/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/dto/CaCertTypeListRequestDto.java b/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/dto/CaCertTypeListRequestDto.java new file mode 100644 index 00000000..8474f2e1 --- /dev/null +++ b/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/dto/CaCertTypeListRequestDto.java @@ -0,0 +1,106 @@ +package io.mosip.kernel.partnercertservice.dto; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.mosip.kernel.keymanagerservice.constant.KeymanagerConstant; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +/** + * Partner Certificate Download Request DTO + * + * @author Nagendra + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel(description = "Model representation request to list partner certificate based on certificate type.") +public class CaCertTypeListRequestDto { + + /** + * Certificate Type + */ + @ApiModelProperty(notes = "Partner Certificate Type", required = false) + String caCertificateType; + + /** + * Domain Name + */ + @ApiModelProperty(notes = "Domain Name", required = true) + @NotBlank(message = KeymanagerConstant.INVALID_REQUEST) + String partnerDomain; + + @ApiModelProperty(notes = "Flag to force exclude the mosip CA Certificates", example = "false", required = false) + private Boolean excludeMosipCA; + + /** + * Sort Direction: ASC, DESC + */ + @ApiModelProperty(notes = "Sort Direction", required = false) + String sortOrder; + /** + * Page Number + */ + @ApiModelProperty(notes = "Page Number", required = false) + @NotNull(message = KeymanagerConstant.INVALID_REQUEST) + int pageNumber; + + /** + * Number of Certificate + */ + @ApiModelProperty(notes = "Number of Certificate", required = false) + @NotNull(message = KeymanagerConstant.INVALID_REQUEST) + int pageSize; + + /** + * CA Certificate Id + */ + @ApiModelProperty(notes = "CA Certificate Id", required = false) + private String certId; + + /** + * Ca Certificate Issued To + */ + @ApiModelProperty(notes = "Issued To", required = false) + private String issuedTo; + + /** + * Ca Certificate Issued By + */ + @ApiModelProperty(notes = "Issued By", required = false) + private String issuedBy; + + /** + * Ca Certificate Valid From + */ + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") + @ApiModelProperty(notes = "Valid From", required = false) + private LocalDateTime validFromDate; + + /** + * Ca Certificate Valid Till + */ + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") + @ApiModelProperty(notes = "Valid Till", required = false) + private LocalDateTime validTillDate; + + /** + * Ca Certificate uploaded time + */ + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") + @ApiModelProperty(notes = "Upload Time", required = false) + private LocalDateTime uploadTime; + + /** + * Sort By Field Name + */ + @ApiModelProperty(notes = "Sort By Field", required = false) + private String sortByFieldName; +} \ No newline at end of file diff --git a/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/dto/CaCertTypeListResponseDto.java b/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/dto/CaCertTypeListResponseDto.java new file mode 100644 index 00000000..edb4b687 --- /dev/null +++ b/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/dto/CaCertTypeListResponseDto.java @@ -0,0 +1,78 @@ +package io.mosip.kernel.partnercertservice.dto; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +/** + * DTO class for List the CA Certificate Based on the Certificate Type. + * + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel(description = "certificate Dto class representation") +public class CaCertTypeListResponseDto { + + /** + * CA Certificate Type + */ + @ApiModelProperty(notes = "CA Certificate Type", required = true) + private String caCertificateType; + + /** + * Partner Domain. + */ + @ApiModelProperty(notes = "Partner Domain", required = true) + private String partnerDomain; + + /** + * CA Certificate Id + */ + @ApiModelProperty(notes = "CA Certificate Id", required = true) + private String certId; + + /** + * Ca Certificate Issued To + */ + @ApiModelProperty(notes = "Issued To", required = true) + private String issuedTo; + + /** + * Ca Certificate Issued By + */ + @ApiModelProperty(notes = "Issued By", required = true) + private String issuedBy; + + /** + * Ca Certificate Valid From + */ + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") + @ApiModelProperty(notes = "Valid From", required = true) + private LocalDateTime validFromDate; + + /** + * Ca Certificate Valid Till + */ + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") + @ApiModelProperty(notes = "Valid Till", required = true) + private LocalDateTime validTillDate; + + /** + * Ca Certificate uploaded time + */ + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") + @ApiModelProperty(notes = "Upload Time", required = true) + private LocalDateTime uploadTime; + + /** + * Ca certificate status + */ + @ApiModelProperty(notes = "status", required = true) + private boolean status; +} \ No newline at end of file diff --git a/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/dto/CaCertificateChainResponseDto.java b/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/dto/CaCertificateChainResponseDto.java new file mode 100644 index 00000000..e1fb29c1 --- /dev/null +++ b/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/dto/CaCertificateChainResponseDto.java @@ -0,0 +1,39 @@ +package io.mosip.kernel.partnercertservice.dto; + +import io.swagger.annotations.ApiModel; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel(description = "Class representing All Partner Certificate Data Response") +public class CaCertificateChainResponseDto { + + /** + * Page Number + */ + private int pageNumber; + + /** + * Number of records in the Page + */ + private int pageSize; + + /** + * Total Number of Records + */ + private long totalRecords; + + /** + * Total number of Pages + */ + private int totalPages; + + /** + * Field for CA Certificate + */ + private CaCertTypeListResponseDto[] allPartnerCertificates; + +} \ No newline at end of file diff --git a/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/helper/CACertificateStoreSpec.java b/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/helper/CACertificateStoreSpec.java new file mode 100644 index 00000000..4b03dd39 --- /dev/null +++ b/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/helper/CACertificateStoreSpec.java @@ -0,0 +1,58 @@ +package io.mosip.kernel.partnercertservice.helper; + +import io.mosip.kernel.keymanagerservice.entity.CACertificateStore; +import jakarta.persistence.criteria.Predicate; +import org.springframework.data.jpa.domain.Specification; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +public class CACertificateStoreSpec { + + public static Specification filterCertificates( + String caCertificateType, + String partnerDomain, + String certId, + String issuedTo, + String issuedBy, + LocalDateTime validFrom, + LocalDateTime validTill, + LocalDateTime uploadTime, + List certThumbprints) { + + return (root, query, criteriaBuilder) -> { + List predicates = new ArrayList<>(); + + if (caCertificateType != null) { + predicates.add(criteriaBuilder.equal(root.get("caCertificateType"), caCertificateType)); + } + if (partnerDomain != null) { + predicates.add(criteriaBuilder.equal(root.get("partnerDomain"), partnerDomain)); + } + if (certId != null) { + predicates.add(criteriaBuilder.equal(root.get("certId"), certId)); + } + if (issuedTo != null) { + predicates.add(criteriaBuilder.like(root.get("certSubject"), "%" + issuedTo + "%")); + } + if (issuedBy != null) { + predicates.add(criteriaBuilder.like(root.get("certIssuer"), "%" + issuedBy + "%")); + } + if (validFrom != null) { + predicates.add(criteriaBuilder.equal(root.get("certNotBefore"), validFrom)); + } + if (validTill != null) { + predicates.add(criteriaBuilder.equal(root.get("certNotAfter"), validTill)); + } + if (uploadTime != null) { + predicates.add(criteriaBuilder.equal(root.get("updatedtimes"), uploadTime)); + } + if(certThumbprints != null && !certThumbprints.isEmpty()) { + predicates.add(root.get("certThumbprint").in(certThumbprints).not()); + } + + return criteriaBuilder.and(predicates.toArray(new Predicate[0])); + }; + } +} \ No newline at end of file diff --git a/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/helper/PartnerCertManagerDBHelper.java b/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/helper/PartnerCertManagerDBHelper.java index 7293beeb..1e18d169 100644 --- a/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/helper/PartnerCertManagerDBHelper.java +++ b/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/helper/PartnerCertManagerDBHelper.java @@ -9,6 +9,7 @@ import java.util.Map; import java.util.Objects; import java.util.Set; +import java.util.*; import java.util.stream.Collectors; import org.springframework.beans.factory.annotation.Autowired; @@ -21,6 +22,8 @@ import io.mosip.kernel.keymanagerservice.logger.KeymanagerLogger; import io.mosip.kernel.keymanagerservice.repository.CACertificateStoreRepository; import io.mosip.kernel.keymanagerservice.repository.PartnerCertificateStoreRepository; +import io.mosip.kernel.keymanagerservice.dto.CertificateDataResponseDto; +import io.mosip.kernel.keymanagerservice.service.KeymanagerService; import io.mosip.kernel.keymanagerservice.util.KeymanagerUtil; import io.mosip.kernel.partnercertservice.constant.PartnerCertManagerConstants; import io.mosip.kernel.partnercertservice.util.PartnerCertificateManagerUtil; @@ -55,6 +58,9 @@ public class PartnerCertManagerDBHelper { */ @Autowired KeymanagerUtil keymanagerUtil; + + @Autowired + KeymanagerService keymanagerService; public boolean isCertificateExist(String certThumbprint, String partnerDomain){ CACertificateStore caCertificate = caCertificateStoreRepository @@ -75,7 +81,7 @@ public boolean isPartnerCertificateExist(String certThumbprint, String partnerDo } public void storeCACertificate(String certId, String certSubject, String certIssuer, String issuerId, - X509Certificate reqX509Cert, String certThumbprint, String partnerDomain) { + X509Certificate reqX509Cert, String certThumbprint, String partnerDomain, String caCertType) { String certSerialNo = reqX509Cert.getSerialNumber().toString(); LocalDateTime notBeforeDate = DateUtils.parseDateToLocalDateTime(reqX509Cert.getNotBefore()); @@ -92,6 +98,7 @@ public void storeCACertificate(String certId, String certSubject, String certIss certStoreObj.setCertThumbprint(certThumbprint); certStoreObj.setCertSerialNo(certSerialNo); certStoreObj.setPartnerDomain(partnerDomain); + certStoreObj.setCaCertificateType(caCertType); caCertificateStoreRepository.saveAndFlush(keymanagerUtil.setMetaData(certStoreObj)); } @@ -161,4 +168,13 @@ public void storePartnerCertificate(String certId, String certSubject, String ce public PartnerCertificateStore getPartnerCert(String certId) { return partnerCertificateStoreRepository.findByCertId(certId); } + + public void getCertThumbprints(String appId, Optional refId, List certThumbprints) { + CertificateDataResponseDto[] certificates = keymanagerService.getAllCertificates(appId, refId).getAllCertificates(); + for (CertificateDataResponseDto certData : certificates) { + X509Certificate certificate = (X509Certificate) keymanagerUtil.convertToCertificate(certData.getCertificateData()); + String certThumbprint = PartnerCertificateManagerUtil.getCertificateThumbprint(certificate); + certThumbprints.add(certThumbprint); + } + } } \ No newline at end of file diff --git a/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/service/impl/PartnerCertificateManagerServiceImpl.java b/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/service/impl/PartnerCertificateManagerServiceImpl.java index 82572bd3..b0adddd8 100644 --- a/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/service/impl/PartnerCertificateManagerServiceImpl.java +++ b/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/service/impl/PartnerCertificateManagerServiceImpl.java @@ -25,6 +25,7 @@ import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.*; import java.util.Objects; import java.util.Optional; import java.util.Set; @@ -67,6 +68,19 @@ import io.mosip.kernel.partnercertservice.dto.PartnerCertificateRequestDto; import io.mosip.kernel.partnercertservice.dto.PartnerCertificateResponseDto; import io.mosip.kernel.partnercertservice.dto.PartnerSignedCertDownloadResponseDto; +import io.mosip.kernel.keymanagerservice.dto.AllCertificatesDataResponseDto; +import io.mosip.kernel.keymanagerservice.dto.CertificateDataResponseDto; +import io.mosip.kernel.keymanagerservice.entity.CACertificateStore; +import io.mosip.kernel.keymanagerservice.entity.KeyAlias; +import io.mosip.kernel.keymanagerservice.repository.CACertificateStoreRepository; +import io.mosip.kernel.keymanagerservice.repository.KeyAliasRepository; +import io.mosip.kernel.partnercertservice.helper.CACertificateStoreSpec; +import io.mosip.kernel.partnercertservice.constant.CaCertificateTypeConsts; +import io.mosip.kernel.partnercertservice.dto.*; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Sort; +import org.springframework.data.jpa.domain.Specification; import io.mosip.kernel.partnercertservice.exception.PartnerCertManagerException; import io.mosip.kernel.partnercertservice.helper.PartnerCertManagerDBHelper; import io.mosip.kernel.partnercertservice.service.spi.PartnerCertificateManagerService; @@ -126,6 +140,12 @@ public class PartnerCertificateManagerServiceImpl implements PartnerCertificateM @Autowired PartnerCertManagerDBHelper certDBHelper; + /** + * Repository to get CA certificate + */ + @Autowired + CACertificateStoreRepository caCertificateStoreRepository; + /** * Keystore instance to handles and store cryptographic keys. */ @@ -140,11 +160,18 @@ public class PartnerCertificateManagerServiceImpl implements PartnerCertificateM @Autowired CryptomanagerUtils cryptomanagerUtil; + @Autowired + KeyAliasRepository keyAliasRepository; + + @Autowired + PartnerCertManagerDBHelper partnerCertManagerDBHelper; + @PostConstruct public void init() { // Added Cache2kBuilder in the postConstruct because expire value // configured in properties are getting injected after this object creation. // Cache2kBuilder constructor is throwing error. + checkAndUpdateCaCertificateTypeIsNull(); if (!disableTrustStoreCache) { caCertTrustStore = new Cache2kBuilder() {} // added hashcode because test case execution failing with IllegalStateException: Cache already created @@ -162,6 +189,24 @@ public void init() { } } + private void checkAndUpdateCaCertificateTypeIsNull() { + List certificates = caCertificateStoreRepository.findByCaCertificateTypeIsNull(); + String caCertificateType; + + for(CACertificateStore certificate : certificates) { + X509Certificate x509Cert = (X509Certificate) keymanagerUtil.convertToCertificate(certificate.getCertData()); + + if(PartnerCertificateManagerUtil.isSelfSignedCertificate(x509Cert)) { + caCertificateType = String.valueOf(CaCertificateTypeConsts.ROOT); + } else { + caCertificateType = String.valueOf(CaCertificateTypeConsts.INTERMEDIATE); + } + + certificate.setCaCertificateType(caCertificateType); + caCertificateStoreRepository.saveAndFlush(certificate); + } + } + @Override public CACertificateResponseDto uploadCACertificate(CACertificateRequestDto caCertRequestDto) { LOGGER.info(PartnerCertManagerConstants.SESSIONID, PartnerCertManagerConstants.UPLOAD_CA_CERT, @@ -201,8 +246,9 @@ public CACertificateResponseDto uploadCACertificate(CACertificateRequestDto caCe LOGGER.info(PartnerCertManagerConstants.SESSIONID, PartnerCertManagerConstants.UPLOAD_CA_CERT, PartnerCertManagerConstants.EMPTY, "Adding Self-signed Certificate in store."); String certId = UUID.randomUUID().toString(); + String caCertificateType = String.valueOf(CaCertificateTypeConsts.ROOT); certDBHelper.storeCACertificate(certId, certSubject, certIssuer, certId, reqX509Cert, certThumbprint, - partnerDomain); + partnerDomain, caCertificateType); uploadedCert = true; } else { @@ -223,8 +269,9 @@ public CACertificateResponseDto uploadCACertificate(CACertificateRequestDto caCe } String issuerId = certDBHelper.getIssuerCertId(certIssuer); String certId = UUID.randomUUID().toString(); + String caCertificateType = String.valueOf(CaCertificateTypeConsts.INTERMEDIATE); certDBHelper.storeCACertificate(certId, certSubject, certIssuer, issuerId, reqX509Cert, certThumbprint, - partnerDomain); + partnerDomain, caCertificateType); uploadedCert = true; } purgeCache(partnerDomain); @@ -279,6 +326,20 @@ private String validateAllowedDomains(String partnerDomain) { return validPartnerDomain.toUpperCase(); } + private String validateAllowedCaCertificateType(String caCertificateType) { + boolean isValidCaCertType = Arrays.stream(CaCertificateTypeConsts.values()).anyMatch((caCertType) -> caCertType.name() + .equalsIgnoreCase(caCertificateType)); + if(!isValidCaCertType) { + LOGGER.error(PartnerCertManagerConstants.SESSIONID, PartnerCertManagerConstants.EMPTY, caCertificateType, + "Invalid CA Certificate Type", PartnerCertManagerErrorConstants.INVALID_CA_CERTIFICATE_TYPE); + throw new PartnerCertManagerException( + PartnerCertManagerErrorConstants.INVALID_CA_CERTIFICATE_TYPE.getErrorCode(), + PartnerCertManagerErrorConstants.INVALID_CA_CERTIFICATE_TYPE.getErrorMessage() + ); + } + return caCertificateType.toUpperCase(); + } + @SuppressWarnings({"unchecked", "java:S2259"}) // added suppress for sonarcloud, not possibility of null pointer exception. private List getCertificateTrustPath(X509Certificate reqX509Cert, String partnerDomain) { @@ -673,4 +734,77 @@ private PartnerCertificateStore getPartnerCertificate(String partnetCertId) { } return partnerCertStore; } + + @Override + public CaCertificateChainResponseDto getCaCertificateChain(CaCertTypeListRequestDto requestDto) { + LOGGER.info(PartnerCertManagerConstants.SESSIONID, PartnerCertManagerConstants.GET_PARTNER_CERT, requestDto.getCaCertificateType(), + "Request to get Certificate for Domain and Certificate Type: " + requestDto.getPartnerDomain()); + + Boolean excludeMosipCert = requestDto.getExcludeMosipCA() == null ? Boolean.FALSE : requestDto.getExcludeMosipCA(); + String partnerDomain = validateAllowedDomains(requestDto.getPartnerDomain()); + String caCertificateType = PartnerCertificateManagerUtil.handleNullOrEmpty(requestDto.getCaCertificateType()) == null ? null : validateAllowedCaCertificateType(requestDto.getCaCertificateType()); + int offSet = requestDto.getPageNumber() < 1 ? 0 : requestDto.getPageNumber() - 1; + int pageSize = requestDto.getPageSize() < 1 ? 10 : requestDto.getPageSize(); + String certId = PartnerCertificateManagerUtil.handleNullOrEmpty(requestDto.getCertId()); + String issuedTo = PartnerCertificateManagerUtil.handleNullOrEmpty(requestDto.getIssuedTo()); + String issuedBy = PartnerCertificateManagerUtil.handleNullOrEmpty(requestDto.getIssuedBy()); + LocalDateTime validFrom = requestDto.getValidFromDate(); + LocalDateTime validTill = requestDto.getValidTillDate(); + LocalDateTime uploadTime = requestDto.getUploadTime(); + String sortFieldName = PartnerCertificateManagerUtil.handleNullOrEmpty(requestDto.getSortByFieldName()) == null ? "createdtimes" : requestDto.getSortByFieldName(); + + Sort.Direction direction = "DESC".equalsIgnoreCase(requestDto.getSortOrder()) ? Sort.Direction.DESC : Sort.Direction.ASC; + PageRequest pageRequest = PageRequest.of(offSet, pageSize, Sort.by(direction, sortFieldName)); + + List certThumbprints = getMosipCertThumbprints(excludeMosipCert); + + Specification spec = CACertificateStoreSpec.filterCertificates( + caCertificateType, partnerDomain, certId, issuedTo, issuedBy, validFrom, validTill, uploadTime, certThumbprints); + + Page partnerCertificateList = caCertificateStoreRepository.findAll(spec, pageRequest); + + CaCertTypeListResponseDto[] certificates = partnerCertificateList.getContent() + .stream() + .map(certificate -> { + CaCertTypeListResponseDto certResponseDto = new CaCertTypeListResponseDto(); + certResponseDto.setCaCertificateType(certificate.getCaCertificateType()); + certResponseDto.setPartnerDomain(certificate.getPartnerDomain()); + certResponseDto.setCertId(certificate.getCertId()); + certResponseDto.setIssuedTo(certificate.getCertSubject()); + certResponseDto.setIssuedBy(certificate.getCertIssuer()); + certResponseDto.setValidFromDate(certificate.getCertNotBefore()); + certResponseDto.setValidTillDate(certificate.getCertNotAfter()); + certResponseDto.setUploadTime(certificate.getCreatedtimes()); + certResponseDto.setStatus(isActiveCaCert(certificate)); + return certResponseDto; + }) + .toArray(CaCertTypeListResponseDto[]::new); + + CaCertificateChainResponseDto responseDto = new CaCertificateChainResponseDto(); + responseDto.setAllPartnerCertificates(certificates); + responseDto.setPageNumber(partnerCertificateList.getNumber() + 1); + responseDto.setPageSize(partnerCertificateList.getSize()); + responseDto.setTotalRecords(partnerCertificateList.getTotalElements()); + responseDto.setTotalPages(partnerCertificateList.getTotalPages()); + + return responseDto; + } + + private List getMosipCertThumbprints(boolean excludeMosipcert) { + List certThumbprints = new ArrayList<>(); + if (excludeMosipcert) { + partnerCertManagerDBHelper.getCertThumbprints(PartnerCertManagerConstants.ROOT_APP_ID, + Optional.of(PartnerCertManagerConstants.EMPTY), certThumbprints); + + partnerCertManagerDBHelper.getCertThumbprints(PartnerCertManagerConstants.PMS_APP_ID, + Optional.of(PartnerCertManagerConstants.EMPTY), certThumbprints); + } + return certThumbprints; + } + + private boolean isActiveCaCert(CACertificateStore certificate) { + LocalDateTime timeStamp = DateUtils.getUTCCurrentDateTime(); + return timeStamp.isEqual(certificate.getCertNotBefore()) || timeStamp.isEqual(certificate.getCertNotAfter()) + || (timeStamp.isAfter(certificate.getCertNotBefore()) && timeStamp.isBefore(certificate.getCertNotAfter())); + } } \ No newline at end of file diff --git a/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/service/spi/PartnerCertificateManagerService.java b/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/service/spi/PartnerCertificateManagerService.java index 247e5f6a..350e0e2e 100644 --- a/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/service/spi/PartnerCertificateManagerService.java +++ b/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/service/spi/PartnerCertificateManagerService.java @@ -9,6 +9,7 @@ import io.mosip.kernel.partnercertservice.dto.PartnerCertificateRequestDto; import io.mosip.kernel.partnercertservice.dto.PartnerCertificateResponseDto; import io.mosip.kernel.partnercertservice.dto.PartnerSignedCertDownloadResponseDto; +import io.mosip.kernel.partnercertservice.dto.*; /** * This interface provides the methods for Partner Certificate Management Service. @@ -68,4 +69,12 @@ public interface PartnerCertificateManagerService { * @return {@link PartnerCertDownloadResponeDto} instance */ public PartnerSignedCertDownloadResponseDto getPartnerSignedCertificate(PartnerCertDownloadRequestDto certDownloadRequestDto); + + /** + * Function to list the Certificate Based on certificate type. + * + * @param CaCertTypeListRequestDto certListRequestDto + * @return {@link CaCertificateChainResponseDto} response + */ + public CaCertificateChainResponseDto getCaCertificateChain(CaCertTypeListRequestDto certListRequestDto); } \ No newline at end of file diff --git a/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/util/PartnerCertificateManagerUtil.java b/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/util/PartnerCertificateManagerUtil.java index fb6ecf64..45ec2a2f 100644 --- a/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/util/PartnerCertificateManagerUtil.java +++ b/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/partnercertservice/util/PartnerCertificateManagerUtil.java @@ -257,5 +257,8 @@ private static String buildCertChain(Certificate[] chain) { PartnerCertManagerErrorConstants.CERTIFICATE_THUMBPRINT_ERROR.getErrorMessage(), e); } } - + + public static String handleNullOrEmpty(String value) { + return (value == null || value.trim().isEmpty()) ? null : value; + } } \ No newline at end of file diff --git a/kernel/kernel-keymanager-service/src/main/resources/application-local.properties b/kernel/kernel-keymanager-service/src/main/resources/application-local.properties index a1a2f1bd..9fa6d2c3 100644 --- a/kernel/kernel-keymanager-service/src/main/resources/application-local.properties +++ b/kernel/kernel-keymanager-service/src/main/resources/application-local.properties @@ -159,3 +159,4 @@ mosip.role.keymanager.getuinpartnercode=ZONAL_ADMIN,GLOBAL_ADMIN,ID_AUTHENTICATI mosip.role.keymanager.postzkencrypt=ZONAL_ADMIN,GLOBAL_ADMIN,INDIVIDUAL,ID_AUTHENTICATION,TEST,REGISTRATION_ADMIN,REGISTRATION_SUPERVISOR,REGISTRATION_OFFICER,REGISTRATION_PROCESSOR,PRE_REGISTRATION_ADMIN,RESIDENT mosip.role.keymanager.postzkdecrypt=ZONAL_ADMIN,GLOBAL_ADMIN,INDIVIDUAL,ID_AUTHENTICATION,TEST,REGISTRATION_ADMIN,REGISTRATION_SUPERVISOR,REGISTRATION_OFFICER,REGISTRATION_PROCESSOR,PRE_REGISTRATION_ADMIN,RESIDENT mosip.role.keymanager.postzkreencryptrandomkey=ZONAL_ADMIN,GLOBAL_ADMIN,INDIVIDUAL,ID_AUTHENTICATION,TEST,REGISTRATION_ADMIN,REGISTRATION_SUPERVISOR,REGISTRATION_OFFICER,REGISTRATION_PROCESSOR,PRE_REGISTRATION_ADMIN,RESIDENT +mosip.role.keymanager.postgetcacertificates=ZONAL_ADMIN,GLOBAL_ADMIN,PMS_ADMIN,PMS_USER \ No newline at end of file