Skip to content
Merged
Empty file.
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -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.*;
Expand Down Expand Up @@ -203,6 +204,9 @@ public class KeymanagerUtil {
@Autowired
KeyGenerator keyGenerator;

@Autowired
private KeyStore keyStore;

/**
* {@link CryptoCoreSpec} instance for cryptographic functionalities.
*/
Expand Down Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -298,7 +299,15 @@ private List<Certificate> 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);
Expand Down Expand Up @@ -388,6 +397,12 @@ private List<? extends Certificate> getCertificateTrustPath(X509Certificate reqX
return null;
}

public List<? extends Certificate> getCertificateTrustChain(X509Certificate reqX509Cert, String partnerDomain, Set<X509Certificate> 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<? extends Certificate> certList = getCertificateTrustPath(reqX509Cert, partnerDomain, null);
return Objects.nonNull(certList);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand Down Expand Up @@ -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<X509Certificate> intermediateCerts);
public boolean validateCertificatePathWithInterCertTrust(X509Certificate reqX509Cert, String domain, Set<X509Certificate> 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<? extends Certificate> getCertificateTrustChain(X509Certificate reqX509Cert, String partnerDomain, Set<X509Certificate> interCertsTrust);
}
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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<? extends Certificate> certificateChain = keymanagerUtil.getCertificateTrustPath(x509Certificate);
List<? extends Certificate> certificateChain = signatureUtil.getCertificateTrustChain(x509Certificate);
if (includeCertificate) {
X509Certificate[] certArray = certificateChain.stream()
.filter(cert -> cert instanceof X509Certificate)
Expand Down Expand Up @@ -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<Certificate> certChain = certificateExistsInHeaderV2(jwtTokens[0]);
Expand Down Expand Up @@ -1100,8 +1105,6 @@ private String validateTrustV2(JWTSignatureVerifyRequestDto jwtVerifyRequestDto,
.map(cert -> (X509Certificate) cert)
.toList();

X509Certificate rootCert = x509CertChain.getLast();

Set<X509Certificate> intermediateCerts = new HashSet<>();
intermediateCerts.addAll(x509CertChain.subList(0, x509CertChain.size() - 1));

Expand All @@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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();

Expand Down Expand Up @@ -234,7 +242,7 @@ public JWSHeader getJWSHeaderV2(String signAlgorithm, boolean b64JWSHeaderParam,
jwsHeaderBuilder = jwsHeaderBuilder.base64URLEncodePayload(false)
.criticalParams(Collections.singleton(SignatureConstant.B64));

List<? extends Certificate> certificateChain = keymanagerUtil.getCertificateTrustPath(x509Certificate);
List<? extends Certificate> certificateChain = getCertificateTrustChain(x509Certificate);

if (includeCertificateChain) {
List<Base64> x5c = buildX509CertChain((List<X509Certificate>) certificateChain);
Expand Down Expand Up @@ -333,6 +341,9 @@ private static String buildFinalKeyId(String uniqueIdentifier, boolean includeKe

private JWSHeader.Builder addRegisteredJWSHeaders(Map<String, String> 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)));
}
Expand All @@ -359,4 +370,17 @@ private JWSHeader.Builder addRegisteredJWSHeaders(Map<String, String> additional
}
return jwsHeaderBuilder;
}

public List<? extends Certificate> getCertificateTrustChain(X509Certificate x509Certificate) {
List<? extends Certificate> certificateChain = keymanagerUtil.getCertificateTrustPath(x509Certificate);
if (certificateChain == null) {
certificateChain = partnerCertificateManagerService.getCertificateTrustChain(x509Certificate, trustDomain, null);
}

if (certificateChain == null) {
certificateChain = Collections.singletonList(x509Certificate);
}

return certificateChain;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down