Skip to content

Commit

Permalink
Added extra testcase and additional assertions for improved testing
Browse files Browse the repository at this point in the history
The extra testcase to check CA renewal with key algorithm change and a change to Subject DN.
  • Loading branch information
Stueypoo authored Mar 4, 2024
1 parent 41ff941 commit e7e7fc4
Showing 1 changed file with 123 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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_ChangeKeyAlg()");
}


/** Test renewal of a CA using a different key algorithm and a different SubjectDN.
* Note: Can run these tests alone by using: ant test:runone -Dtest.runone=RenewCATest
**/
@Test
public void testrenewCA_ChangeKeyAlgWithNameChange() throws Exception {
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("<testrenewCA_ChangeKeyAlgWithNameChange()");
}


/** Test renewal of a subCA, using Renew CA Worker. */
@Test
Expand Down

0 comments on commit e7e7fc4

Please sign in to comment.