Home / Class/ SslInfoTests Class — spring-boot Architecture

SslInfoTests Class — spring-boot Architecture

Architecture documentation for the SslInfoTests class in SslInfoTests.java from the spring-boot codebase.

Entity Profile

Relationship Graph

Source Code

core/spring-boot/src/test/java/org/springframework/boot/info/SslInfoTests.java lines 46–266

class SslInfoTests {

	private static final Clock CLOCK = Clock.fixed(Instant.parse("2025-06-18T13:00:00Z"), ZoneId.of("UTC"));

	@Test
	@WithPackageResources("test.p12")
	void validCertificatesShouldProvideSslInfo() {
		SslInfo sslInfo = createSslInfo("classpath:test.p12");
		assertThat(sslInfo.getBundles()).hasSize(1);
		BundleInfo bundle = sslInfo.getBundles().get(0);
		assertThat(bundle.getName()).isEqualTo("test-0");
		assertThat(bundle.getCertificateChains()).hasSize(4);
		assertThat(bundle.getCertificateChains().get(0).getAlias()).isEqualTo("spring-boot");
		assertThat(bundle.getCertificateChains().get(0).getCertificates()).hasSize(1);
		assertThat(bundle.getCertificateChains().get(1).getAlias()).isEqualTo("test-alias");
		assertThat(bundle.getCertificateChains().get(1).getCertificates()).hasSize(1);
		assertThat(bundle.getCertificateChains().get(2).getAlias()).isEqualTo("spring-boot-cert");
		assertThat(bundle.getCertificateChains().get(2).getCertificates()).hasSize(1);
		assertThat(bundle.getCertificateChains().get(3).getAlias()).isEqualTo("test-alias-cert");
		assertThat(bundle.getCertificateChains().get(3).getCertificates()).hasSize(1);
		CertificateInfo cert1 = bundle.getCertificateChains().get(0).getCertificates().get(0);
		assertThat(cert1.getSubject()).isEqualTo("CN=localhost,OU=Spring,O=VMware,L=Palo Alto,ST=California,C=US");
		assertThat(cert1.getIssuer()).isEqualTo(cert1.getSubject());
		assertThat(cert1.getSerialNumber()).isNotEmpty();
		assertThat(cert1.getVersion()).isEqualTo("V3");
		assertThat(cert1.getSignatureAlgorithmName()).isEqualTo("SHA256withRSA");
		assertThat(cert1.getValidityStarts()).isBefore(CLOCK.instant());
		assertThat(cert1.getValidityEnds()).isAfter(CLOCK.instant());
		assertThat(cert1.getValidity()).isNotNull();
		assertThat(cert1.getValidity().getStatus()).isSameAs(Status.VALID);
		assertThat(cert1.getValidity().getMessage()).isNull();
		CertificateInfo cert2 = bundle.getCertificateChains().get(1).getCertificates().get(0);
		assertThat(cert2.getSubject()).isEqualTo("CN=localhost,OU=Spring,O=VMware,L=Palo Alto,ST=California,C=US");
		assertThat(cert2.getIssuer()).isEqualTo(cert2.getSubject());
		assertThat(cert2.getSerialNumber()).isNotEmpty();
		assertThat(cert2.getVersion()).isEqualTo("V3");
		assertThat(cert2.getSignatureAlgorithmName()).isEqualTo("SHA256withRSA");
		assertThat(cert2.getValidityStarts()).isBefore(CLOCK.instant());
		assertThat(cert2.getValidityEnds()).isAfter(CLOCK.instant());
		assertThat(cert2.getValidity()).isNotNull();
		assertThat(cert2.getValidity().getStatus()).isSameAs(Status.VALID);
		assertThat(cert2.getValidity().getMessage()).isNull();
		assertThat(bundle.getTrustStoreCertificateChains()).isEmpty();
	}

	@Test
	@WithPackageResources("test-not-yet-valid.p12")
	void notYetValidCertificateShouldProvideSslInfo() {
		SslInfo sslInfo = createSslInfo("classpath:test-not-yet-valid.p12");
		assertThat(sslInfo.getBundles()).hasSize(1);
		BundleInfo bundle = sslInfo.getBundles().get(0);
		assertThat(bundle.getName()).isEqualTo("test-0");
		assertThat(bundle.getCertificateChains()).hasSize(1);
		CertificateChainInfo certificateChain = bundle.getCertificateChains().get(0);
		assertThat(certificateChain.getAlias()).isEqualTo("spring-boot");
		List<CertificateInfo> certs = certificateChain.getCertificates();
		assertThat(certs).hasSize(1);
		CertificateInfo cert = certs.get(0);
		assertThat(cert.getSubject()).isEqualTo("CN=localhost,OU=Spring,O=VMware,L=Palo Alto,ST=California,C=US");
		assertThat(cert.getIssuer()).isEqualTo(cert.getSubject());
		assertThat(cert.getSerialNumber()).isNotEmpty();
		assertThat(cert.getVersion()).isEqualTo("V3");
		assertThat(cert.getSignatureAlgorithmName()).isEqualTo("SHA256withRSA");
		assertThat(cert.getValidityStarts()).isAfter(CLOCK.instant());
		assertThat(cert.getValidityEnds()).isAfter(CLOCK.instant());
		assertThat(cert.getValidity()).isNotNull();
		assertThat(cert.getValidity().getStatus()).isSameAs(Status.NOT_YET_VALID);
		assertThat(cert.getValidity().getMessage()).startsWith("Not valid before");
	}

	@Test
	@WithPackageResources("test-expired.p12")
	void expiredCertificateShouldProvideSslInfo() {
		SslInfo sslInfo = createSslInfo("classpath:test-expired.p12");
		assertThat(sslInfo.getBundles()).hasSize(1);
		BundleInfo bundle = sslInfo.getBundles().get(0);
		assertThat(bundle.getName()).isEqualTo("test-0");
		assertThat(bundle.getCertificateChains()).hasSize(1);
		CertificateChainInfo certificateChain = bundle.getCertificateChains().get(0);
		assertThat(certificateChain.getAlias()).isEqualTo("spring-boot");
		List<CertificateInfo> certs = certificateChain.getCertificates();
		assertThat(certs).hasSize(1);
		CertificateInfo cert = certs.get(0);
		assertThat(cert.getSubject()).isEqualTo("CN=localhost,OU=Spring,O=VMware,L=Palo Alto,ST=California,C=US");
		assertThat(cert.getIssuer()).isEqualTo(cert.getSubject());
		assertThat(cert.getSerialNumber()).isNotEmpty();
		assertThat(cert.getVersion()).isEqualTo("V3");
		assertThat(cert.getSignatureAlgorithmName()).isEqualTo("SHA256withRSA");
		assertThat(cert.getValidityStarts()).isBefore(CLOCK.instant());
		assertThat(cert.getValidityEnds()).isBefore(CLOCK.instant());
		assertThat(cert.getValidity()).isNotNull();
		assertThat(cert.getValidity().getStatus()).isSameAs(Status.EXPIRED);
		assertThat(cert.getValidity().getMessage()).startsWith("Not valid after");
	}

	@Test
	@WithPackageResources({ "test.p12", "test-not-yet-valid.p12", "test-expired.p12", "will-expire-soon.p12" })
	void multipleBundlesShouldProvideSslInfo() {
		SslInfo sslInfo = createSslInfo("classpath:test.p12", "classpath:test-not-yet-valid.p12",
				"classpath:test-expired.p12", "classpath:will-expire-soon.p12");
		assertThat(sslInfo.getBundles()).hasSize(4);
		assertThat(sslInfo.getBundles()).allSatisfy((bundle) -> assertThat(bundle.getName()).startsWith("test-"));
		List<CertificateInfo> certs = sslInfo.getBundles()
			.stream()
			.flatMap((bundle) -> bundle.getCertificateChains().stream())
			.flatMap((certificateChain) -> certificateChain.getCertificates().stream())
			.toList();
		assertThat(certs).hasSize(7);
		assertThat(certs).allSatisfy((cert) -> {
			assertThat(cert.getSubject()).isEqualTo("CN=localhost,OU=Spring,O=VMware,L=Palo Alto,ST=California,C=US");
			assertThat(cert.getIssuer()).isEqualTo(cert.getSubject());
			assertThat(cert.getSerialNumber()).isNotEmpty();
			assertThat(cert.getVersion()).isEqualTo("V3");
			assertThat(cert.getSignatureAlgorithmName()).isNotEmpty();
			assertThat(cert.getValidity()).isNotNull();
		});
		assertThat(certs).anySatisfy((cert) -> {
			assertThat(cert.getValidityStarts()).isBefore(CLOCK.instant());
			assertThat(cert.getValidityEnds()).isAfter(CLOCK.instant());
			assertThat(cert.getValidity()).isNotNull();
			assertThat(cert.getValidity().getStatus()).isSameAs(Status.VALID);
			assertThat(cert.getValidity().getMessage()).isNull();
		});
		assertThat(certs).satisfiesOnlyOnce((cert) -> {
			assertThat(cert.getValidityStarts()).isAfter(CLOCK.instant());
			assertThat(cert.getValidityEnds()).isAfter(CLOCK.instant());
			assertThat(cert.getValidity()).isNotNull();
			assertThat(cert.getValidity().getStatus()).isSameAs(Status.NOT_YET_VALID);
			assertThat(cert.getValidity().getMessage()).startsWith("Not valid before");
		});
		assertThat(certs).satisfiesOnlyOnce((cert) -> {
			assertThat(cert.getValidityStarts()).isBefore(CLOCK.instant());
			assertThat(cert.getValidityEnds()).isBefore(CLOCK.instant());
			assertThat(cert.getValidity()).isNotNull();
			assertThat(cert.getValidity().getStatus()).isSameAs(Status.EXPIRED);
			assertThat(cert.getValidity().getMessage()).startsWith("Not valid after");
		});
	}

	@Test
	void nullKeyStore() {
		DefaultSslBundleRegistry sslBundleRegistry = new DefaultSslBundleRegistry();
		sslBundleRegistry.registerBundle("test", SslBundle.of(SslStoreBundle.NONE, SslBundleKey.NONE));
		SslInfo sslInfo = new SslInfo(sslBundleRegistry, CLOCK);
		assertThat(sslInfo.getBundles()).hasSize(1);
		assertThat(sslInfo.getBundles().get(0).getCertificateChains()).isEmpty();
		assertThat(sslInfo.getBundles().get(0).getTrustStoreCertificateChains()).isEmpty();
	}

	@Test
	@WithPackageResources("test.p12")
	void trustStoreCertificatesShouldProvideSslInfo() {
		DefaultSslBundleRegistry sslBundleRegistry = new DefaultSslBundleRegistry();
		JksSslStoreDetails trustStoreDetails = JksSslStoreDetails.forLocation("classpath:test.p12")
			.withPassword("secret");
		SslStoreBundle sslStoreBundle = new JksSslStoreBundle(null, trustStoreDetails);
		sslBundleRegistry.registerBundle("test-trust", SslBundle.of(sslStoreBundle));
		SslInfo sslInfo = new SslInfo(sslBundleRegistry, CLOCK);
		assertThat(sslInfo.getBundles()).hasSize(1);
		BundleInfo bundle = sslInfo.getBundles().get(0);
		assertThat(bundle.getName()).isEqualTo("test-trust");
		assertThat(bundle.getCertificateChains()).isEmpty();
		assertThat(bundle.getTrustStoreCertificateChains()).hasSize(4);
		assertThat(bundle.getTrustStoreCertificateChains().get(0).getAlias()).isEqualTo("spring-boot");
		assertThat(bundle.getTrustStoreCertificateChains().get(1).getAlias()).isEqualTo("test-alias");
	}

	@Test
	@WithPackageResources("test.p12")
	void bothKeyStoreAndTrustStoreCertificatesShouldProvideSslInfo() {
		DefaultSslBundleRegistry sslBundleRegistry = new DefaultSslBundleRegistry();
		JksSslStoreDetails storeDetails = JksSslStoreDetails.forLocation("classpath:test.p12").withPassword("secret");
		SslStoreBundle sslStoreBundle = new JksSslStoreBundle(storeDetails, storeDetails);
		sslBundleRegistry.registerBundle("test-both", SslBundle.of(sslStoreBundle));
		SslInfo sslInfo = new SslInfo(sslBundleRegistry, CLOCK);
		assertThat(sslInfo.getBundles()).hasSize(1);
		BundleInfo bundle = sslInfo.getBundles().get(0);
		assertThat(bundle.getName()).isEqualTo("test-both");
		assertThat(bundle.getCertificateChains()).hasSize(4);
		assertThat(bundle.getTrustStoreCertificateChains()).hasSize(4);
	}

	@Test
	@WithPackageResources({ "keystore.jks", "truststore.jks" })
	void separateKeyStoreAndTrustStoreShouldProvideSslInfo() {
		DefaultSslBundleRegistry sslBundleRegistry = new DefaultSslBundleRegistry();
		JksSslStoreDetails keyStoreDetails = JksSslStoreDetails.forLocation("classpath:keystore.jks")
			.withPassword("secret");
		JksSslStoreDetails trustStoreDetails = JksSslStoreDetails.forLocation("classpath:truststore.jks")
			.withPassword("secret");
		SslStoreBundle sslStoreBundle = new JksSslStoreBundle(keyStoreDetails, trustStoreDetails);
		sslBundleRegistry.registerBundle("test-separate", SslBundle.of(sslStoreBundle));
		SslInfo sslInfo = new SslInfo(sslBundleRegistry, CLOCK);
		assertThat(sslInfo.getBundles()).hasSize(1);
		BundleInfo bundle = sslInfo.getBundles().get(0);
		assertThat(bundle.getName()).isEqualTo("test-separate");
		// Keystore has 2 PrivateKeyEntry entries
		assertThat(bundle.getCertificateChains()).hasSize(2);
		assertThat(bundle.getCertificateChains()).allSatisfy((chain) -> {
			assertThat(chain.getCertificates()).hasSize(1);
			assertThat(chain.getCertificates().get(0).getSubject()).startsWith("CN=localhost");
		});
		// Truststore has 3 trustedCertEntry entries
		assertThat(bundle.getTrustStoreCertificateChains()).hasSize(3);
		assertThat(bundle.getTrustStoreCertificateChains()).allSatisfy((chain) -> {
			assertThat(chain.getCertificates()).hasSize(1);
			assertThat(chain.getCertificates().get(0).getSubject()).startsWith("CN=localhost");
		});
	}

	private SslInfo createSslInfo(String... locations) {
		DefaultSslBundleRegistry sslBundleRegistry = new DefaultSslBundleRegistry();
		for (int i = 0; i < locations.length; i++) {
			JksSslStoreDetails keyStoreDetails = JksSslStoreDetails.forLocation(locations[i]).withPassword("secret");
			SslStoreBundle sslStoreBundle = new JksSslStoreBundle(keyStoreDetails, null);
			sslBundleRegistry.registerBundle("test-%d".formatted(i), SslBundle.of(sslStoreBundle));
		}
		return new SslInfo(sslBundleRegistry, CLOCK);
	}

}

Domain

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free