diff --git a/db_upgrade_scripts/mosip_keymgr/sql/1.3.0-B4_to_1.3.0-B5_rollback.sql b/db_upgrade_scripts/mosip_keymgr/sql/1.3.0-B4_to_1.3.0-B5_rollback.sql new file mode 100644 index 00000000..e69de29b diff --git a/db_upgrade_scripts/mosip_keymgr/sql/1.3.0-B4_to_1.3.0-B5_upgrade.sql b/db_upgrade_scripts/mosip_keymgr/sql/1.3.0-B4_to_1.3.0-B5_upgrade.sql new file mode 100644 index 00000000..e69de29b diff --git a/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/keymanagerservice/util/KeymanagerUtil.java b/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/keymanagerservice/util/KeymanagerUtil.java index 42c9988c..5cb9d4f8 100644 --- a/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/keymanagerservice/util/KeymanagerUtil.java +++ b/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/keymanagerservice/util/KeymanagerUtil.java @@ -45,6 +45,7 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; +import io.mosip.kernel.core.keymanager.spi.KeyStore; import io.mosip.kernel.keymanagerservice.dto.ExtendedCertificateParameters; import io.mosip.kernel.keymanagerservice.dto.SubjectAlternativeNamesDto; import io.mosip.kernel.keymanagerservice.dto.*; @@ -203,6 +204,9 @@ public class KeymanagerUtil { @Autowired KeyGenerator keyGenerator; + @Autowired + private KeyStore keyStore; + /** * {@link CryptoCoreSpec} instance for cryptographic functionalities. */ @@ -587,12 +591,17 @@ public String getCSR(PrivateKey privateKey, PublicKey publicKey, CertificatePara try { X500Principal csrSubject = new X500Principal("CN=" + certParams.getCommonName() + ", OU=" + certParams.getOrganizationUnit() + - ", O=" + certParams.getOrganization() + ", L=" + certParams.getLocation() + + ", O=" + certParams.getOrganization() + ", L=" + certParams.getLocation() + ", S=" + certParams.getState() + ", C=" + certParams.getCountry()); - ContentSigner contentSigner = new JcaContentSignerBuilder(getSignatureAlgorithm(keyAlgorithm)).build(privateKey); - PKCS10CertificationRequestBuilder pcks10Builder = new JcaPKCS10CertificationRequestBuilder(csrSubject, publicKey); - PKCS10CertificationRequest csrObject = pcks10Builder.build(contentSigner); - return getPEMFormatedData(csrObject); + ContentSigner contentSigner; + if (privateKey.getAlgorithm().equals(KeymanagerConstant.ED25519_KEY_TYPE)) { + contentSigner = new JcaContentSignerBuilder(edSignAlgorithm).build(privateKey); + } else { + contentSigner = new JcaContentSignerBuilder(getSignatureAlgorithm(keyAlgorithm)).setProvider(keyStore.getKeystoreProviderName()).build(privateKey); + } + PKCS10CertificationRequestBuilder pcks10Builder = new JcaPKCS10CertificationRequestBuilder(csrSubject, publicKey); + PKCS10CertificationRequest csrObject = pcks10Builder.build(contentSigner); + return getPEMFormatedData(csrObject); } catch (OperatorCreationException exp) { throw new KeymanagerServiceException(KeymanagerErrorConstant.INTERNAL_SERVER_ERROR.getErrorCode(), KeymanagerErrorConstant.INTERNAL_SERVER_ERROR.getErrorMessage(), exp); 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 b52565d9..93e2c24d 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 @@ -33,6 +33,7 @@ import java.util.stream.Stream; import java.util.concurrent.TimeUnit; +import io.mosip.kernel.keymanagerservice.constant.KeymanagerErrorConstant; import jakarta.annotation.PostConstruct; import javax.security.auth.x500.X500Principal; @@ -298,7 +299,15 @@ private List parseCertificateData(String certificateData) { + " able to parse, may be p7b certificate data inputed."); } // Try to Parse as P7B file. - byte[] p7bBytes = CryptoUtil.decodeURLSafeBase64(certificateData); + byte[] p7bBytes; + try { + p7bBytes = CryptoUtil.decodeURLSafeBase64(certificateData); + } catch (Exception e) { + LOGGER.error(PartnerCertManagerConstants.SESSIONID, PartnerCertManagerConstants.UPLOAD_CA_CERT, + PartnerCertManagerConstants.EMPTY, "Invalid Certificate Data provided to upload the ca/sub-ca certificate."); + throw new PartnerCertManagerException(KeymanagerErrorConstant.CERTIFICATE_PARSING_ERROR.getErrorCode(), + KeymanagerErrorConstant.CERTIFICATE_PARSING_ERROR.getErrorMessage()); + } try (ByteArrayInputStream certStream = new ByteArrayInputStream(p7bBytes)) { CertificateFactory cf = CertificateFactory.getInstance("X.509"); Collection p7bCertList = cf.generateCertificates(certStream); @@ -388,6 +397,12 @@ private List getCertificateTrustPath(X509Certificate reqX return null; } + public List getCertificateTrustChain(X509Certificate reqX509Cert, String partnerDomain, Set interCertsTrust) { + LOGGER.info(PartnerCertManagerConstants.SESSIONID, PartnerCertManagerConstants.CERT_TRUST_VALIDATION, + PartnerCertManagerConstants.EMPTY, "Certificate Trust chain for domain: " + partnerDomain); + return getCertificateTrustPath(reqX509Cert, partnerDomain, interCertsTrust); + } + private boolean validateCertificatePath(X509Certificate reqX509Cert, String partnerDomain) { List certList = getCertificateTrustPath(reqX509Cert, partnerDomain, null); return Objects.nonNull(certList); 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 099eb270..cad26d7f 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 @@ -11,7 +11,9 @@ import io.mosip.kernel.partnercertservice.dto.PartnerSignedCertDownloadResponseDto; import io.mosip.kernel.partnercertservice.dto.*; +import java.security.cert.Certificate; import java.security.cert.X509Certificate; +import java.util.List; import java.util.Set; /** @@ -96,6 +98,15 @@ public interface PartnerCertificateManagerService { * @param domain Partner Domain of the CA Certificate Trust * @param intermediateCerts intermediate certificate trust */ - boolean validateCertificatePathWithInterCertTrust(X509Certificate reqX509Cert, String domain, Set intermediateCerts); + public boolean validateCertificatePathWithInterCertTrust(X509Certificate reqX509Cert, String domain, Set intermediateCerts); + /** + * Function to get the certificate trust path by passing the req X509Certificate + * + * @param reqX509Cert X509Certificate to get the certificate trust path + * @param partnerDomain Partner Domain of the CA Certificate Trust + * @param interCertsTrust Intermediate Certificate Trust + * @return List of Certificate + */ + public List getCertificateTrustChain(X509Certificate reqX509Cert, String partnerDomain, Set interCertsTrust); } \ No newline at end of file diff --git a/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/signature/service/impl/SignatureServiceImpl.java b/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/signature/service/impl/SignatureServiceImpl.java index 237a9f96..0c1d2c32 100644 --- a/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/signature/service/impl/SignatureServiceImpl.java +++ b/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/signature/service/impl/SignatureServiceImpl.java @@ -409,6 +409,7 @@ public JWTSignatureVerifyResponseDto jwtVerify(JWTSignatureVerifyRequestDto jwtV } else { Certificate reqCertToVerify = getCertificateToVerify(reqCertData, applicationId, referenceId); signatureValid = verifySignature(jwtTokens, encodedActualData, reqCertToVerify); + reqCertData = keymanagerUtil.getPEMFormatedData(reqCertToVerify); } JWTSignatureVerifyResponseDto responseDto = new JWTSignatureVerifyResponseDto(); @@ -526,17 +527,20 @@ private String validateTrust(JWTSignatureVerifyRequestDto jwtVerifyRequestDto, C if (trustCertData == null) return SignatureConstant.TRUST_NOT_VERIFIED; - + CertificateTrustRequestDto trustRequestDto = new CertificateTrustRequestDto(); trustRequestDto.setCertificateData(trustCertData); trustRequestDto.setPartnerDomain(domain); CertificateTrustResponeDto responseDto = partnerCertManagerService.verifyCertificateTrust(trustRequestDto); if (responseDto.getStatus()){ + LOGGER.info(SignatureConstant.SESSIONID, SignatureConstant.JWT_SIGN, SignatureConstant.BLANK, + "JWT Signature Verification Request - Trust Validation - Success."); return SignatureConstant.TRUST_VALID; } + String certThumbprint = cryptomanagerUtil.getCertificateThumbprintInHex(keymanagerUtil.convertToCertificate(trustCertData)); LOGGER.info(SignatureConstant.SESSIONID, SignatureConstant.JWT_SIGN, SignatureConstant.BLANK, - "JWT Signature Verification Request - Trust Validation - Completed."); + "JWT Signature Verification Request - Trust Validation - Failed. Certificate Thumbprint: " + certThumbprint); return SignatureConstant.TRUST_NOT_VALID; } @@ -841,7 +845,7 @@ private String signV2(String dataToSign, SignatureCertificate certificateRespons JsonWebSignature jwSign = new JsonWebSignature(); PrivateKey privateKey = certificateResponse.getCertificateEntry().getPrivateKey(); X509Certificate x509Certificate = certificateResponse.getCertificateEntry().getChain()[0]; - List certificateChain = keymanagerUtil.getCertificateTrustPath(x509Certificate); + List certificateChain = signatureUtil.getCertificateTrustChain(x509Certificate); if (includeCertificate) { X509Certificate[] certArray = certificateChain.stream() .filter(cert -> cert instanceof X509Certificate) @@ -1047,6 +1051,7 @@ public JWTSignatureVerifyResponseDto jwtVerifyV2(JWTSignatureVerifyRequestDto jw } else { Certificate reqCertToVerify = getCertificateToVerify(reqCertData, applicationId, referenceId); signatureValid = verifySignature(jwtTokens, encodedActualData, reqCertToVerify); + reqCertData = keymanagerUtil.getPEMFormatedData(reqCertToVerify); } List certChain = certificateExistsInHeaderV2(jwtTokens[0]); @@ -1100,8 +1105,6 @@ private String validateTrustV2(JWTSignatureVerifyRequestDto jwtVerifyRequestDto, .map(cert -> (X509Certificate) cert) .toList(); - X509Certificate rootCert = x509CertChain.getLast(); - Set intermediateCerts = new HashSet<>(); intermediateCerts.addAll(x509CertChain.subList(0, x509CertChain.size() - 1)); @@ -1117,11 +1120,14 @@ private String validateTrustV2(JWTSignatureVerifyRequestDto jwtVerifyRequestDto, boolean isTrustValid = partnerCertManagerService.validateCertificatePathWithInterCertTrust(trustCertData, domain, intermediateCerts); if (isTrustValid) { + LOGGER.info(SignatureConstant.SESSIONID, SignatureConstant.JWT_SIGN, SignatureConstant.BLANK, + "JWT Signature Verification Request - Trust Validation - Successful."); return SignatureConstant.TRUST_VALID; } + String certThumbprint = cryptomanagerUtil.getCertificateThumbprintInHex(trustCertData); LOGGER.info(SignatureConstant.SESSIONID, SignatureConstant.JWT_SIGN, SignatureConstant.BLANK, - "JWT Signature Verification Request - Trust Validation - Completed."); + "JWT Signature Verification Request - Trust Validation - Failed. Certificate Thumbprint: " + certThumbprint); return SignatureConstant.TRUST_NOT_VALID; } } diff --git a/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/signature/util/SignatureUtil.java b/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/signature/util/SignatureUtil.java index d9b1a6c0..cc2e2713 100644 --- a/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/signature/util/SignatureUtil.java +++ b/kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/signature/util/SignatureUtil.java @@ -28,6 +28,7 @@ import com.nimbusds.jose.util.Base64URL; import io.mosip.kernel.keymanagerservice.util.KeymanagerUtil; +import io.mosip.kernel.partnercertservice.service.spi.PartnerCertificateManagerService; import org.apache.commons.codec.DecoderException; import org.apache.commons.codec.binary.Hex; import org.apache.commons.codec.digest.DigestUtils; @@ -39,6 +40,7 @@ import io.mosip.kernel.keymanagerservice.logger.KeymanagerLogger; import io.mosip.kernel.signature.constant.SignatureConstant; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import java.util.Set; import java.util.stream.Collectors; @@ -58,6 +60,12 @@ public class SignatureUtil { @Autowired KeymanagerUtil keymanagerUtil; + @Autowired + PartnerCertificateManagerService partnerCertificateManagerService; + + @Value("${mosip.kernel.partner.trust.validate.domain.name:TRUST_CA}") + private String trustDomain; + private static final Logger LOGGER = KeymanagerLogger.getLogger(SignatureUtil.class); private static ObjectMapper mapper = JsonMapper.builder().addModule(new AfterburnerModule()).build(); @@ -234,7 +242,7 @@ public JWSHeader getJWSHeaderV2(String signAlgorithm, boolean b64JWSHeaderParam, jwsHeaderBuilder = jwsHeaderBuilder.base64URLEncodePayload(false) .criticalParams(Collections.singleton(SignatureConstant.B64)); - List certificateChain = keymanagerUtil.getCertificateTrustPath(x509Certificate); + List certificateChain = getCertificateTrustChain(x509Certificate); if (includeCertificateChain) { List x5c = buildX509CertChain((List) certificateChain); @@ -333,6 +341,9 @@ private static String buildFinalKeyId(String uniqueIdentifier, boolean includeKe private JWSHeader.Builder addRegisteredJWSHeaders(Map additionalHeaders, JWSHeader.Builder jwsHeaderBuilder) { + if (additionalHeaders == null) + return jwsHeaderBuilder; + if (additionalHeaders.containsKey(SignatureConstant.JWS_HEADER_TYPE_KEY)) { jwsHeaderBuilder.type(new JOSEObjectType(additionalHeaders.get(SignatureConstant.JWS_HEADER_TYPE_KEY))); } @@ -359,4 +370,17 @@ private JWSHeader.Builder addRegisteredJWSHeaders(Map additional } return jwsHeaderBuilder; } + + public List getCertificateTrustChain(X509Certificate x509Certificate) { + List certificateChain = keymanagerUtil.getCertificateTrustPath(x509Certificate); + if (certificateChain == null) { + certificateChain = partnerCertificateManagerService.getCertificateTrustChain(x509Certificate, trustDomain, null); + } + + if (certificateChain == null) { + certificateChain = Collections.singletonList(x509Certificate); + } + + return certificateChain; + } } 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 492f61e2..53a9ad59 100644 --- a/kernel/kernel-keymanager-service/src/main/resources/application-local.properties +++ b/kernel/kernel-keymanager-service/src/main/resources/application-local.properties @@ -105,7 +105,7 @@ mosip.kernel.zkcrypto.derive.encrypt.algorithm-name=AES/ECB/PKCS5Padding mosip.kernel.partner.sign.masterkey.application.id=PMS -mosip.kernel.partner.allowed.domains=AUTH,DEVICE,FTM +mosip.kernel.partner.allowed.domains=AUTH,DEVICE,FTM,TRUST_CA mosip.iam.impl.basepackage=io.mosip.kernel.auth.defaultimpl mosip.auth.adapter.impl.basepackage=io.mosip.kernel.auth.defaultadapter @@ -121,6 +121,8 @@ mosip.kernel.keymanager.hsm.jce.cuPassword= mosip.kernel.keymanager.113nothumbprint.support=false +mosip.kernel.partner.trust.validate.domain.name=TRUST_CA + ##Adding controller props to local prop file mosip.role.keymanager.postcssign=ZONAL_ADMIN,GLOBAL_ADMIN,INDIVIDUAL,ID_AUTHENTICATION,TEST,REGISTRATION_ADMIN,REGISTRATION_SUPERVISOR,REGISTRATION_OFFICER,REGISTRATION_PROCESSOR,PRE_REGISTRATION_ADMIN,RESIDENT mosip.role.keymanager.postcsverifysign=ZONAL_ADMIN,GLOBAL_ADMIN,INDIVIDUAL,ID_AUTHENTICATION,TEST,REGISTRATION_ADMIN,REGISTRATION_SUPERVISOR,REGISTRATION_OFFICER,REGISTRATION_PROCESSOR,PRE_REGISTRATION_ADMIN,RESIDENT