|
4 | 4 | import java.security.NoSuchAlgorithmException; |
5 | 5 | import java.security.PrivateKey; |
6 | 6 | import java.security.PublicKey; |
7 | | -import java.security.cert.CertPathBuilder; |
8 | | -import java.security.cert.CertPathBuilderException; |
9 | | -import java.security.cert.CertStore; |
10 | | -import java.security.cert.CollectionCertStoreParameters; |
11 | | -import java.security.cert.PKIXBuilderParameters; |
12 | | -import java.security.cert.TrustAnchor; |
13 | | -import java.security.cert.X509CertSelector; |
14 | | -import java.security.cert.X509Certificate; |
| 7 | +import java.security.cert.*; |
15 | 8 | import java.time.LocalDateTime; |
16 | 9 | import java.time.temporal.ChronoUnit; |
17 | | -import java.util.Map; |
18 | | -import java.util.Objects; |
19 | | -import java.util.Optional; |
20 | | -import java.util.Set; |
21 | | -import java.util.UUID; |
| 10 | +import java.util.*; |
22 | 11 | import java.util.stream.Stream; |
23 | 12 | import java.util.concurrent.TimeUnit; |
24 | 13 |
|
@@ -90,6 +79,9 @@ public class PartnerCertificateManagerServiceImpl implements PartnerCertificateM |
90 | 79 |
|
91 | 80 | @Value("${mosip.kernel.partner.issuer.certificate.allowed.grace.duration:30}") |
92 | 81 | private int gracePeriod; |
| 82 | + |
| 83 | + @Value("${mosip.kernel.partner.resign.ftm.domain.certs:false}") |
| 84 | + private boolean resignFTMDomainCerts; |
93 | 85 |
|
94 | 86 | /** |
95 | 87 | * Utility to generate Metadata |
@@ -254,6 +246,45 @@ private boolean validateCertificatePath(X509Certificate reqX509Cert, String part |
254 | 246 | return false; |
255 | 247 | } |
256 | 248 |
|
| 249 | + private List<? extends Certificate> getCertificateTrustPath(X509Certificate reqX509Cert, String partnerDomain) { |
| 250 | + |
| 251 | + try { |
| 252 | + Map<String, Set<?>> trustStoreMap = (Map<String, Set<?>>) caCertTrustStore.get(partnerDomain); //certDBHelper.getTrustAnchors(partnerDomain); |
| 253 | + Set<TrustAnchor> rootTrustAnchors = (Set<TrustAnchor>) trustStoreMap |
| 254 | + .get(PartnerCertManagerConstants.TRUST_ROOT); |
| 255 | + Set<X509Certificate> interCerts = (Set<X509Certificate>) trustStoreMap |
| 256 | + .get(PartnerCertManagerConstants.TRUST_INTER); |
| 257 | + |
| 258 | + X509CertSelector certToVerify = new X509CertSelector(); |
| 259 | + certToVerify.setCertificate(reqX509Cert); |
| 260 | + |
| 261 | + PKIXBuilderParameters pkixBuilderParams = new PKIXBuilderParameters(rootTrustAnchors, certToVerify); |
| 262 | + pkixBuilderParams.setRevocationEnabled(false); |
| 263 | + |
| 264 | + CertStore interCertStore = CertStore.getInstance("Collection", |
| 265 | + new CollectionCertStoreParameters(interCerts)); |
| 266 | + pkixBuilderParams.addCertStore(interCertStore); |
| 267 | + |
| 268 | + // Building the cert path and verifying the certification chain |
| 269 | + CertPathBuilder certPathBuilder = CertPathBuilder.getInstance("PKIX"); |
| 270 | + //certPathBuilder.build(pkixBuilderParams); |
| 271 | + PKIXCertPathBuilderResult result = (PKIXCertPathBuilderResult) certPathBuilder.build(pkixBuilderParams); |
| 272 | + X509Certificate rootCert = result.getTrustAnchor().getTrustedCert(); |
| 273 | + List<? extends Certificate> certList = result.getCertPath().getCertificates(); |
| 274 | + List<Certificate> trustCertList = new ArrayList<>(); |
| 275 | + certList.stream().forEach(cert -> { |
| 276 | + trustCertList.add(cert); |
| 277 | + }); |
| 278 | + trustCertList.add(rootCert); |
| 279 | + return trustCertList; |
| 280 | + } catch (CertPathBuilderException | InvalidAlgorithmParameterException | NoSuchAlgorithmException exp) { |
| 281 | + LOGGER.info(PartnerCertManagerConstants.SESSIONID, PartnerCertManagerConstants.UPLOAD_CA_CERT, |
| 282 | + PartnerCertManagerConstants.EMPTY, |
| 283 | + "Ignore this exception, the exception thrown when trust validation failed."); |
| 284 | + } |
| 285 | + return null; |
| 286 | + } |
| 287 | + |
257 | 288 | @Override |
258 | 289 | public PartnerCertificateResponseDto uploadPartnerCertificate(PartnerCertificateRequestDto partnerCertRequesteDto) { |
259 | 290 |
|
@@ -290,6 +321,63 @@ public PartnerCertificateResponseDto uploadPartnerCertificate(PartnerCertificate |
290 | 321 | return responseDto; |
291 | 322 | } |
292 | 323 |
|
| 324 | + @Override |
| 325 | + public PartnerCertificateResponseDto uploadPartnerCertificateV2(PartnerCertificateRequestDto partnerCertRequesteDto) { |
| 326 | + |
| 327 | + String certificateData = partnerCertRequesteDto.getCertificateData(); |
| 328 | + if (!keymanagerUtil.isValidCertificateData(certificateData)) { |
| 329 | + LOGGER.error(PartnerCertManagerConstants.SESSIONID, PartnerCertManagerConstants.UPLOAD_PARTNER_CERT, |
| 330 | + PartnerCertManagerConstants.EMPTY, |
| 331 | + "Invalid Certificate Data provided to upload the partner certificate."); |
| 332 | + throw new PartnerCertManagerException(PartnerCertManagerErrorConstants.INVALID_CERTIFICATE.getErrorCode(), |
| 333 | + PartnerCertManagerErrorConstants.INVALID_CERTIFICATE.getErrorMessage()); |
| 334 | + } |
| 335 | + X509Certificate reqX509Cert = (X509Certificate) keymanagerUtil.convertToCertificate(certificateData); |
| 336 | + String certThumbprint = PartnerCertificateManagerUtil.getCertificateThumbprint(reqX509Cert); |
| 337 | + String reqOrgName = partnerCertRequesteDto.getOrganizationName(); |
| 338 | + String partnerDomain = validateAllowedDomains(partnerCertRequesteDto.getPartnerDomain()); |
| 339 | + |
| 340 | + validateBasicPartnerCertParams(reqX509Cert, certThumbprint, reqOrgName, partnerDomain); |
| 341 | + |
| 342 | + List<? extends Certificate>certList = getCertificateTrustPath(reqX509Cert, partnerDomain); |
| 343 | + if (Objects.isNull(certList)) { |
| 344 | + LOGGER.error(PartnerCertManagerConstants.SESSIONID, PartnerCertManagerConstants.UPLOAD_PARTNER_CERT, |
| 345 | + PartnerCertManagerConstants.EMPTY, |
| 346 | + "Partner Certificate not allowed to upload as root CA/Intermediate CAs are not found in trust cert path."); |
| 347 | + throw new PartnerCertManagerException( |
| 348 | + PartnerCertManagerErrorConstants.ROOT_INTER_CA_NOT_FOUND.getErrorCode(), |
| 349 | + PartnerCertManagerErrorConstants.ROOT_INTER_CA_NOT_FOUND.getErrorMessage()); |
| 350 | + } |
| 351 | + |
| 352 | + String certSubject = PartnerCertificateManagerUtil |
| 353 | + .formatCertificateDN(reqX509Cert.getSubjectX500Principal().getName()); |
| 354 | + String certIssuer = PartnerCertificateManagerUtil |
| 355 | + .formatCertificateDN(reqX509Cert.getIssuerX500Principal().getName()); |
| 356 | + String issuerId = certDBHelper.getIssuerCertId(certIssuer); |
| 357 | + String certId = UUID.randomUUID().toString(); |
| 358 | + |
| 359 | + X509Certificate rootCert = (X509Certificate) keymanagerUtil.convertToCertificate( |
| 360 | + keymanagerService.getCertificate(PartnerCertManagerConstants.ROOT_APP_ID, |
| 361 | + Optional.of(PartnerCertManagerConstants.EMPTY)).getCertificate()); |
| 362 | + String timestamp = DateUtils.getUTCCurrentDateTimeString(); |
| 363 | + SignatureCertificate certificateResponse = keymanagerService.getSignatureCertificate(masterSignKeyAppId, |
| 364 | + Optional.of(PartnerCertManagerConstants.EMPTY), timestamp); |
| 365 | + X509Certificate pmsCert = certificateResponse.getCertificateEntry().getChain()[0]; |
| 366 | + |
| 367 | + X509Certificate resignedCert = reSignPartnerKey(reqX509Cert); |
| 368 | + String signedCertData = keymanagerUtil.getPEMFormatedData(resignedCert); |
| 369 | + certDBHelper.storePartnerCertificate(certId, certSubject, certIssuer, issuerId, reqX509Cert, certThumbprint, |
| 370 | + reqOrgName, partnerDomain, signedCertData); |
| 371 | + |
| 372 | + String p7bCertChain = PartnerCertificateManagerUtil.buildP7BCertificateChain(certList, resignedCert, |
| 373 | + partnerDomain, resignFTMDomainCerts, rootCert, pmsCert); |
| 374 | + PartnerCertificateResponseDto responseDto = new PartnerCertificateResponseDto(); |
| 375 | + responseDto.setCertificateId(certId); |
| 376 | + responseDto.setSignedCertificateData(p7bCertChain); |
| 377 | + responseDto.setTimestamp(DateUtils.getUTCCurrentDateTime()); |
| 378 | + return responseDto; |
| 379 | + } |
| 380 | + |
293 | 381 | private void validateBasicPartnerCertParams(X509Certificate reqX509Cert, String certThumbprint, String reqOrgName, |
294 | 382 | String partnerDomain) { |
295 | 383 | boolean certExist = certDBHelper.isPartnerCertificateExist(certThumbprint, partnerDomain); |
|
0 commit comments