diff --git a/modules/systemtests/src-test/org/ejbca/core/ejb/ca/caadmin/RenewCATest.java b/modules/systemtests/src-test/org/ejbca/core/ejb/ca/caadmin/RenewCATest.java index db48781805..0e282694ed 100644 --- a/modules/systemtests/src-test/org/ejbca/core/ejb/ca/caadmin/RenewCATest.java +++ b/modules/systemtests/src-test/org/ejbca/core/ejb/ca/caadmin/RenewCATest.java @@ -28,6 +28,7 @@ import org.cesecore.certificates.ca.CaSessionRemote; import org.cesecore.certificates.ca.X509CAInfo; import org.cesecore.certificates.ca.catoken.CAToken; +import org.cesecore.certificates.certificate.InternalCertificateStoreSessionRemote; import org.cesecore.certificates.certificateprofile.CertificateProfileConstants; import org.cesecore.certificates.certificateprofile.CertificateProfileSessionRemote; import org.cesecore.keys.token.CryptoTokenManagementSessionRemote; @@ -60,7 +61,8 @@ public class RenewCATest extends CaTestCase { private ServiceSessionRemote serviceSession = EjbRemoteHelper.INSTANCE.getRemoteSession(ServiceSessionRemote.class); private final CryptoTokenManagementSessionRemote cryptoTokenManagementSession = EjbRemoteHelper.INSTANCE.getRemoteSession(CryptoTokenManagementSessionRemote.class); private final CertificateProfileSessionRemote certificateProfileSession = EjbRemoteHelper.INSTANCE.getRemoteSession(CertificateProfileSessionRemote.class); - + private static GlobalConfigurationSessionRemote globalConfigSession = EjbRemoteHelper.INSTANCE.getRemoteSession(GlobalConfigurationSessionRemote.class); + private final InternalCertificateStoreSessionRemote internalCertificateStoreSession = EjbRemoteHelper.INSTANCE.getRemoteSession(InternalCertificateStoreSessionRemote.class, EjbRemoteHelper.MODULE_TEST); @Before public void setUp() throws Exception { @@ -168,14 +170,131 @@ public void testrenewCA_ChangeKeyAlg() throws Exception { byte[] linkCertificateAfterRenewal1Bytes = caAdminSession.getLatestLinkCertificate(newinfo.getCAId()); assertTrue("There is no available link certificate after CA renewal with EC key", linkCertificateAfterRenewal1Bytes != null); @SuppressWarnings("deprecation") - X509Certificate linkCertificateAfterRenewal1 = (X509Certificate) com.keyfactor.util.CertTools.getCertfromByteArray(linkCertificateAfterRenewal1Bytes); - assertTrue("The Link certificate should be signed by the CA's previous signing algorithm, not "+linkCertificateAfterRenewal1.getSigAlgName(), - linkCertificateAfterRenewal1.getSigAlgName().equalsIgnoreCase(sPreviousSigAlg) ); + X509Certificate linkCertificateAfterRenewal = (X509Certificate) com.keyfactor.util.CertTools.getCertfromByteArray(linkCertificateAfterRenewal1Bytes); + assertTrue("The Link certificate should be signed by the CA's previous signing algorithm, not "+linkCertificateAfterRenewal.getSigAlgName(), linkCertificateAfterRenewal.getSigAlgName().equalsIgnoreCase(sPreviousSigAlg) ); + + // Check the SignatureAlgorithm on the CA's Token is still set correctly + assertTrue("The signature algorithm on the CA's token was changed and should not be "+caToken.getSignatureAlgorithm(), caToken.getSignatureAlgorithm().equals(AlgorithmConstants.SIGALG_SHA256_WITH_ECDSA)); + + // Check the Signature Algorithm on the CertPolicy is still set correctly + assertTrue("The signature algorithm on the CA's certificate profile was changed and should not be "+cpCA.getSignatureAlgorithm(), cpCA.getSignatureAlgorithm().equals(AlgorithmConstants.SIGALG_SHA256_WITH_ECDSA)); + + // Check the Link cert's IssuerDN matches the original CA's SubjectDN + assertTrue("The IssuerDN of the Link certificate does not match the SubjectDN of the original CA certificate.", linkCertificateAfterRenewal.getIssuerDN().equals( orgcert.getSubjectDN())); + + // Check the Link cert's SubjectDN matches the original CA's SubjectDN + // Note: There was not a Name change occurring + assertTrue("The SubjectDN of the Link certificate does not match the SubjectDN of the original CA certificate.", linkCertificateAfterRenewal.getSubjectDN().equals( orgcert.getSubjectDN())); // Test done! log.trace("testrenewCA_ChangeKeyAlgWithNameChange()"); + + // Ensure the NameChange setting is true + GlobalConfiguration globalConfiguration = (GlobalConfiguration) globalConfigSession + .getCachedConfiguration(GlobalConfiguration.GLOBAL_CONFIGURATION_ID); + boolean backupEnableIcaoCANameChangeValue = globalConfiguration.getEnableIcaoCANameChange(); + globalConfiguration.setEnableIcaoCANameChange(true); + globalConfigSession.saveConfiguration(internalAdmin, globalConfiguration); + + X509CAInfo info = (X509CAInfo) caSession.getCAInfo(internalAdmin, getTestCAName()); + X509Certificate orgcert = (X509Certificate) info.getCertificateChain().iterator().next(); + // Sleep at least for one second so we are not so fast that we create a new cert with the same time + Thread.sleep(2000); + + // Prepare to renew CA but with an EC key + + // Get the CA's token + final CAToken caToken = info.getCAToken(); + + // The current Signing Algorithm should be RSA-based + String sPreviousSigAlg = ((X509Certificate)orgcert).getSigAlgName(); + assertTrue("Current CA's Signature Algorithm should include RSA", sPreviousSigAlg.contains("RSA")); + + // Set the next key alias for the token + String sNextKeyAlias = "TestEC"; + + // Create an EC key. Need the CryptoTokeManagementSession for this + cryptoTokenManagementSession.createKeyPair(internalAdmin, caToken.getCryptoTokenId(), sNextKeyAlias, com.keyfactor.util.keys.token.KeyGenParams.builder("prime256v1").build()); + + // To get EJBCA to renew a CA with a different key algorithm, we need to: + // 1. set up the signing algorithm in the CA's token to support EC, + // 2. ensure the certificate profile has an appropriate signature algorithm to support EC. + + // Set the signature algorithm of the token + caToken.setSignatureAlgorithm( AlgorithmConstants.SIGALG_SHA256_WITH_ECDSA); + + // Need to set the Certificate Profile to use ECDSA based signature algorithm + // Lets copy the current profile, change it, and save a new profile (as we can't edit the current profile) + int iCP = info.getCertificateProfileId(); + org.cesecore.certificates.certificateprofile.CertificateProfile cpCA = certificateProfileSession.getCertificateProfile(iCP); + cpCA.setSignatureAlgorithm( AlgorithmConstants.SIGALG_SHA256_WITH_ECDSA); + + // We are all set and now ready to renew the CA + // Lets do a name change too + final String newSubjectDN = "CN=NewName,o=Test"; + final String newCAName = "NewName"; + + try { + iCP = certificateProfileSession.addCertificateProfile(internalAdmin, "TESTRENEWALWITHEC", cpCA); + // Update the CA + info.setCertificateProfileId(iCP); + caSession.editCA(internalAdmin, info); + + // Renew the CA with name change + caAdminSession.renewCANewSubjectDn(internalAdmin, info.getCAId(), sNextKeyAlias, null, /*CreateLinkCert*/true, newSubjectDN); + + // Let check the CA's new certificate has the ECDSA based signature algorithm + X509CAInfo newinfo = (X509CAInfo) caSession.getCAInfo(internalAdmin, newCAName); + X509Certificate newcert = (X509Certificate) newinfo.getCertificateChain().iterator().next(); + String sNewSigAlg = ((X509Certificate) newcert).getSigAlgName(); + assertTrue("Previous Signing Algorithm was " + sPreviousSigAlg + " and new Signing Algorithm was " + sNewSigAlg + ". Was expecting it to be ECDSA based.", sNewSigAlg.contains("ECDSA")); + + // Check the Link certificate was signed using the previous Signing Algorithm + byte[] linkCertificateAfterRenewal1Bytes = caAdminSession.getLatestLinkCertificate(newinfo.getCAId()); + assertTrue("There is no available link certificate after CA renewal with EC key", linkCertificateAfterRenewal1Bytes != null); + @SuppressWarnings("deprecation") + X509Certificate linkCertificateAfterRenewal = (X509Certificate) com.keyfactor.util.CertTools.getCertfromByteArray(linkCertificateAfterRenewal1Bytes); + assertTrue("The Link certificate should be signed by the CA's previous signing algorithm, not "+ linkCertificateAfterRenewal.getSigAlgName(), linkCertificateAfterRenewal.getSigAlgName().equalsIgnoreCase(sPreviousSigAlg)); + + // Check the SignatureAlgorithm on the CA's Token is still set correctly + assertTrue("The signature algorithm on the CA's token was changed and should not be " + caToken.getSignatureAlgorithm(), caToken.getSignatureAlgorithm().equals(AlgorithmConstants.SIGALG_SHA256_WITH_ECDSA)); + + // Check the Signature Algorithm on the CertPolicy is still set correctly + assertTrue("The signature algorithm on the CA's certificate profile was changed and should not be " + cpCA.getSignatureAlgorithm(), cpCA.getSignatureAlgorithm().equals(AlgorithmConstants.SIGALG_SHA256_WITH_ECDSA)); + + // Check the Link cert's IssuerDN matches the original CA's SubjectDN + assertTrue("The IssuerDN of the Link certificate does not match the SubjectDN of the original CA certificate.", linkCertificateAfterRenewal.getIssuerDN().equals(orgcert.getSubjectDN())); + + // Check the Link cert's SubjectDN doesn't matches the original CA's SubjectDN + // Note: There is a Name change occurring + assertTrue("The SubjectDN of the Link certificate should not match the SubjectDN of the original CA certificate.", !linkCertificateAfterRenewal.getSubjectDN().equals(orgcert.getSubjectDN())); + assertTrue("The SubjectDN of the Link certificate should match the SubjectDN of the renewed CA certificate.", linkCertificateAfterRenewal.getSubjectDN().equals(newcert.getSubjectDN())); + } finally { + // Remove the certificate profile we just created. + certificateProfileSession.removeCertificateProfile(internalAdmin, "TESTRENEWALWITHEC"); + + // Clean up the renewed CA with name change + removeTestCA(newCAName); + internalCertificateStoreSession.removeCRLs(internalAdmin, newSubjectDN); + + // Ensure the global configuration is reverted. + globalConfiguration.setEnableIcaoCANameChange(backupEnableIcaoCANameChangeValue); + globalConfigSession.saveConfiguration(internalAdmin, globalConfiguration); + } + + // Test done! + log.trace("