CertificateGenerator implements CredentialGenerator<CertificateCredentialValue> { @Override public CertificateCredentialValue generateCredential(final GenerationParameters p) { final CertificateGenerationParameters params = (CertificateGenerationParameters) p; final KeyPair keyPair; final String privatePem; try { keyPair = keyGenerator.generateKeyPair(params.getKeyLength()); privatePem = CertificateFormatter.pemOf(keyPair.getPrivate()); } catch (final Exception e) { throw new RuntimeException(e); } if (params.isSelfSigned()) { try { final String cert = CertificateFormatter.pemOf(signedCertificateGenerator.getSelfSigned(keyPair, params)); return new CertificateCredentialValue(cert, cert, privatePem, null, params.isCa(), params.isSelfSigned(), true, false); } catch (final Exception e) { throw new RuntimeException(e); } } else { final String caName = params.getCaName(); final CertificateCredentialValue latestNonTransitionalCaVersion = certificateAuthorityService.findActiveVersion(caName); if (latestNonTransitionalCaVersion.getPrivateKey() == null) { throw new ParameterizedValidationException(ErrorMessages.CA_MISSING_PRIVATE_KEY); } final CertificateCredentialValue transitionalCaVersion = certificateAuthorityService.findTransitionalVersion(caName); String signingCaCertificate; String signingCaPrivateKey; String trustedCaCertificate = null; if (shouldUseTransitionalParentToSign(params.getAllowTransitionalParentToSign(), latestNonTransitionalCaVersion, transitionalCaVersion)) { signingCaCertificate = transitionalCaVersion.getCertificate(); signingCaPrivateKey = transitionalCaVersion.getPrivateKey(); trustedCaCertificate = latestNonTransitionalCaVersion.getCertificate(); } else { signingCaCertificate = latestNonTransitionalCaVersion.getCertificate(); signingCaPrivateKey = latestNonTransitionalCaVersion.getPrivateKey(); if (transitionalCaVersion != null) { trustedCaCertificate = transitionalCaVersion.getCertificate(); } } try { final CertificateReader certificateReader = new CertificateReader(signingCaCertificate); final X509Certificate cert = signedCertificateGenerator.getSignedByIssuer( keyPair, params, certificateReader.getCertificate(), PrivateKeyReader.getPrivateKey(signingCaPrivateKey) ); return new CertificateCredentialValue(signingCaCertificate, CertificateFormatter.pemOf(cert), privatePem, caName, trustedCaCertificate, params.isCa(), params.isSelfSigned(), true, false); } catch (final Exception e) { throw new RuntimeException(e); } } } @Autowired  CertificateGenerator(
    final RsaKeyPairGenerator keyGenerator,
    final SignedCertificateGenerator signedCertificateGenerator,
    final CertificateAuthorityService certificateAuthorityService); @Override CertificateCredentialValue generateCredential(final GenerationParameters p);  }
@Test public void whenCAExists_andItIsARootCA_aValidChildCertificateIsGenerated() throws Exception { final KeyPair childCertificateKeyPair = setupKeyPair(); setupMocksForRootCA(childCertificateKeyPair); final CertificateCredentialValue certificateSignedByRoot = subject.generateCredential(inputParameters); assertThat(certificateSignedByRoot.getCa(), equalTo(rootCa.getCertificate())); assertThat(certificateSignedByRoot.getPrivateKey(), equalTo(CertificateFormatter.pemOf(childCertificateKeyPair.getPrivate()))); assertThat(certificateSignedByRoot.getCertificate(), equalTo(CertificateFormatter.pemOf(childX509Certificate))); assertThat(certificateSignedByRoot.getCaName(), equalTo("/my-ca-name")); verify(keyGenerator, times(1)).generateKeyPair(2048); }
@Test public void whenCAExists_andItIsARootCA_aValidChildCertificateIsGeneratedWithTheProvidedKeyLength() throws Exception { final KeyPair childCertificateKeyPair = setupKeyPair(); setupMocksForRootCA(childCertificateKeyPair); generationParameters.setKeyLength(4096); final CertificateGenerationParameters params = new CertificateGenerationParameters(generationParameters); when( signedCertificateGenerator .getSignedByIssuer(childCertificateKeyPair, params, rootCaX509Certificate, rootCaKeyPair.getPrivate()) ).thenReturn(childX509Certificate); final CertificateCredentialValue certificate = subject.generateCredential(params); assertThat(certificate, notNullValue()); verify(keyGenerator, times(1)).generateKeyPair(4096); }
@Test public void whenCAExists_andItIsAIntermediateCA_aValidChildCertificateIsGenerated() throws Exception { final KeyPair childCertificateKeyPair = setupKeyPair(); final X500Name intermediateCaDn = new X500Name("O=foo,ST=bar,C=intermediate"); final KeyPair intermediateCaKeyPair = fakeKeyPairGenerator.generate(); final X509CertificateHolder intermediateCaCertificateHolder = makeCert(intermediateCaKeyPair, rootCaKeyPair.getPrivate(), rootCaDn, intermediateCaDn, true); final X509Certificate intermediateX509Certificate = new JcaX509CertificateConverter() .setProvider(BouncyCastleFipsProvider.PROVIDER_NAME) .getCertificate(intermediateCaCertificateHolder); final CertificateCredentialValue intermediateCa = new CertificateCredentialValue( null, CertificateFormatter.pemOf(intermediateX509Certificate), CertificateFormatter.pemOf(intermediateCaKeyPair.getPrivate()), null, true, false, false, false); when(certificateAuthorityService.findActiveVersion("/my-ca-name")).thenReturn(intermediateCa); when(keyGenerator.generateKeyPair(anyInt())).thenReturn(childCertificateKeyPair); final X509CertificateHolder childCertificateHolder = generateChildCertificateSignedByCa( childCertificateKeyPair, intermediateCaKeyPair.getPrivate(), intermediateCaDn ); childX509Certificate = new JcaX509CertificateConverter() .setProvider(BouncyCastleFipsProvider.PROVIDER_NAME) .getCertificate(childCertificateHolder); when( signedCertificateGenerator .getSignedByIssuer(childCertificateKeyPair, inputParameters, intermediateX509Certificate, intermediateCaKeyPair.getPrivate()) ).thenReturn(childX509Certificate); final CertificateCredentialValue certificateSignedByIntermediate = subject.generateCredential(inputParameters); assertThat(certificateSignedByIntermediate.getCa(), equalTo(intermediateCa.getCertificate())); assertThat(certificateSignedByIntermediate.getPrivateKey(), equalTo(CertificateFormatter.pemOf(childCertificateKeyPair.getPrivate()))); assertThat(certificateSignedByIntermediate.getCertificate(), equalTo(CertificateFormatter.pemOf(childX509Certificate))); verify(keyGenerator, times(1)).generateKeyPair(2048); }
@Test public void whenCAExists_andHasATransitionalVersion_aValidChildCertificateIsGenerated() throws Exception { final KeyPair childCertificateKeyPair = setupKeyPair(); setupMocksForRootCA(childCertificateKeyPair); KeyPair transitionalCaKeyPair = fakeKeyPairGenerator.generate(); final X509CertificateHolder caX509CertHolder = makeCert(transitionalCaKeyPair, transitionalCaKeyPair.getPrivate(), rootCaDn, rootCaDn, true); X509Certificate transitionalCaX509Certificate = new JcaX509CertificateConverter() .setProvider(BouncyCastleFipsProvider.PROVIDER_NAME).getCertificate(caX509CertHolder); CertificateCredentialValue transitionalCa = new CertificateCredentialValue( null, CertificateFormatter.pemOf(transitionalCaX509Certificate), CertificateFormatter.pemOf(transitionalCaKeyPair.getPrivate()), null, true, true, false, true); generationParameters.setKeyLength(4096); final CertificateGenerationParameters params = new CertificateGenerationParameters(generationParameters); when( signedCertificateGenerator .getSignedByIssuer(childCertificateKeyPair, params, rootCaX509Certificate, rootCaKeyPair.getPrivate()) ).thenReturn(childX509Certificate); when(certificateAuthorityService.findTransitionalVersion("/my-ca-name")).thenReturn(transitionalCa); final CertificateCredentialValue certificateWithTrustedCa = subject.generateCredential(inputParameters); assertThat(certificateWithTrustedCa.getCa(), equalTo(rootCa.getCertificate())); assertThat(certificateWithTrustedCa.getTrustedCa(), equalTo(transitionalCa.getCertificate())); }
@Test public void whenCAHasATransitionalVersionAsLatest_andAllowTransitionalParentToSignIsTrue_childCertificateIsSignedByTheTransitionalVersion() throws Exception { final KeyPair childCertificateKeyPair = setupKeyPair(); KeyPair transitionalCaKeyPair = fakeKeyPairGenerator.generate(); final X509CertificateHolder caX509CertHolder = makeCert(transitionalCaKeyPair, transitionalCaKeyPair.getPrivate(), rootCaDn, rootCaDn, true); X509Certificate transitionalCaX509Certificate = new JcaX509CertificateConverter() .setProvider(BouncyCastleFipsProvider.PROVIDER_NAME).getCertificate(caX509CertHolder); CertificateCredentialValue transitionalCa = new CertificateCredentialValue( CertificateFormatter.pemOf(transitionalCaX509Certificate), CertificateFormatter.pemOf(transitionalCaKeyPair.getPrivate()), true, true, false, true, Instant.now()); when(certificateAuthorityService.findActiveVersion("/my-ca-name")).thenReturn(rootCa); when(keyGenerator.generateKeyPair(anyInt())).thenReturn(childCertificateKeyPair); final X509CertificateHolder childCertificateHolder = generateChildCertificateSignedByCa( childCertificateKeyPair, transitionalCaKeyPair.getPrivate(), rootCaDn ); childX509Certificate = new JcaX509CertificateConverter() .setProvider(BouncyCastleFipsProvider.PROVIDER_NAME) .getCertificate(childCertificateHolder); inputParameters.setAllowTransitionalParentToSign(true); when(signedCertificateGenerator .getSignedByIssuer( childCertificateKeyPair, inputParameters, transitionalCaX509Certificate, transitionalCaKeyPair.getPrivate() ) ).thenReturn(childX509Certificate); when(certificateAuthorityService.findTransitionalVersion("/my-ca-name")).thenReturn(transitionalCa); final CertificateCredentialValue certificateWithTrustedCa = subject.generateCredential(inputParameters); assertThat(certificateWithTrustedCa.getCa(), equalTo(transitionalCa.getCertificate())); assertThat(certificateWithTrustedCa.getTrustedCa(), equalTo(rootCa.getCertificate())); }
@Test public void whenSelfSignIsTrue_itGeneratesAValidSelfSignedCertificate() throws Exception { final X509Certificate certificate = new JcaX509CertificateConverter().setProvider(BouncyCastleFipsProvider.PROVIDER_NAME) .getCertificate(generateX509SelfSignedCert()); generationParameters.setCaName(null); generationParameters.setSelfSigned(true); inputParameters = new CertificateGenerationParameters(generationParameters); when(keyGenerator.generateKeyPair(anyInt())).thenReturn(rootCaKeyPair); when(signedCertificateGenerator.getSelfSigned(rootCaKeyPair, inputParameters)) .thenReturn(certificate); final CertificateCredentialValue certificateCredential = subject.generateCredential(inputParameters); assertThat(certificateCredential.getPrivateKey(), equalTo(CertificateFormatter.pemOf(rootCaKeyPair.getPrivate()))); assertThat(certificateCredential.getCertificate(), equalTo(CertificateFormatter.pemOf(certificate))); assertThat(certificateCredential.getCa(), equalTo(CertificateFormatter.pemOf(certificate))); verify(signedCertificateGenerator, times(1)).getSelfSigned(rootCaKeyPair, inputParameters); }
@Test public void whenTheCADoesNotHaveAPrivateKey_itThrowsAnException() throws Exception { final CertificateGenerationRequestParameters parameters = new CertificateGenerationRequestParameters(); parameters.setCaName("/ca-without-private-key"); parameters.setKeyLength(2048); parameters.setSelfSigned(false); final CertificateCredentialValue caWithoutPrivateKey = mock(CertificateCredentialValue.class); when(certificateAuthorityService.findActiveVersion("/ca-without-private-key")) .thenReturn(caWithoutPrivateKey); when(caWithoutPrivateKey.getPrivateKey()).thenReturn(null); when(keyGenerator.generateKeyPair(anyInt())).thenReturn(rootCaKeyPair); try { subject.generateCredential(new CertificateGenerationParameters(parameters)); fail("Should throw exception"); } catch (final ParameterizedValidationException e) { assertThat(e.getMessage(), equalTo(ErrorMessages.CA_MISSING_PRIVATE_KEY)); } }