diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9b63320..f7f5bc1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -20,6 +20,18 @@ jobs: with: distribution: 'temurin' java-version: 21 + - name: Update environment variables based on PR labels + id: pr-env + uses: actions/github-script@v7 + with: + script: | + const labels = context.payload.pull_request.labels.map(label => label.name); + console.log('PR labels:', labels); + const springDebug = labels.includes('pr-debug'); + return { SPRING_DEBUG: '' + springDebug }; + result-encoding: json - uses: gradle/actions/setup-gradle@v4 - name: Build gradle project - run: ./gradlew build \ No newline at end of file + run: ./gradlew build + env: + ORG_GRADLE_PROJECT_SPRING_DEBUG: ${{ fromJSON(steps.pr-env.outputs.result).SPRING_DEBUG }} \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 12fdfda..0ad924f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -7,6 +7,7 @@ plugins { group = "io.github.markl4yg.hca" version = "0.0.1-SNAPSHOT" +val springDebugLogging = providers.gradleProperty("SPRING_DEBUG").orNull == "true" apply( from = file("./gradle/spotless.gradle") @@ -57,6 +58,13 @@ dependencies { tasks.withType { useJUnitPlatform() + if (springDebugLogging) { + // Additional Hibernate logging + jvmArgs("-Dlogging.level.org.sqlite=DEBUG") + jvmArgs("-Dlogging.level.org.hibernate=DEBUG") + jvmArgs("-Dhibernate.show_sql=true") + jvmArgs("-Dhibernate.format_sql=true") + } systemProperty("spring.profiles.active", "test") jvmArgs("-XX:+EnableDynamicAgentLoading") // DynamicAgentLoading for byteBuddy within Mockito diff --git a/src/main/java/de/mlessmann/certassist/keystore/AutoBootKeyStoreManagement.java b/src/main/java/de/mlessmann/certassist/keystore/AutoBootKeyStoreManagement.java new file mode 100644 index 0000000..b1a4035 --- /dev/null +++ b/src/main/java/de/mlessmann/certassist/keystore/AutoBootKeyStoreManagement.java @@ -0,0 +1,26 @@ +package de.mlessmann.certassist.keystore; + +import de.mlessmann.certassist.openssl.CertificatePasswordProvider; +import de.mlessmann.certassist.openssl.OpenSSLService; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class AutoBootKeyStoreManagement { + + @Bean + @ConditionalOnMissingBean(KeyStoreManager.class) + public KeyStoreManager keystoreProvider( + OpenSSLService certificateCreator, + CertificatePasswordProvider passwordProvider + ) { + return new KeyStoreManager(certificateCreator, passwordProvider); + } + + @Bean + @ConditionalOnMissingBean(TruststoreManager.class) + public TruststoreManager truststoreProvider() { + return new TruststoreManager(); + } +} diff --git a/src/main/java/de/mlessmann/certassist/keystore/KeyStoreManager.java b/src/main/java/de/mlessmann/certassist/keystore/KeyStoreManager.java index 95a4719..93da782 100644 --- a/src/main/java/de/mlessmann/certassist/keystore/KeyStoreManager.java +++ b/src/main/java/de/mlessmann/certassist/keystore/KeyStoreManager.java @@ -3,7 +3,7 @@ package de.mlessmann.certassist.keystore; import de.mlessmann.certassist.except.JavaSecurityException; import de.mlessmann.certassist.openssl.CertificatePasswordProvider; import de.mlessmann.certassist.openssl.CertificateUsage; -import de.mlessmann.certassist.openssl.OpenSSLCertificateCreator; +import de.mlessmann.certassist.openssl.OpenSSLService; import java.io.IOException; import java.nio.file.Files; import java.nio.file.OpenOption; @@ -27,7 +27,7 @@ public class KeyStoreManager { StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, }; - private final OpenSSLCertificateCreator certificateCreator; + private final OpenSSLService certificateCreator; private final CertificatePasswordProvider passwordProvider; public KeystoreUsage createKeyStore(String keyStorePassphrase, CertificateUsage... serverCerts) diff --git a/src/main/java/de/mlessmann/certassist/openssl/CertificateRequest.java b/src/main/java/de/mlessmann/certassist/models/CertificateInfo.java similarity index 50% rename from src/main/java/de/mlessmann/certassist/openssl/CertificateRequest.java rename to src/main/java/de/mlessmann/certassist/models/CertificateInfo.java index 4b519d1..a870b27 100644 --- a/src/main/java/de/mlessmann/certassist/openssl/CertificateRequest.java +++ b/src/main/java/de/mlessmann/certassist/models/CertificateInfo.java @@ -1,11 +1,11 @@ -package de.mlessmann.certassist.openssl; +package de.mlessmann.certassist.models; import lombok.Builder; import lombok.Data; @Data @Builder -public class CertificateRequest { +public class CertificateInfo { private RequestType type; private String trustingAuthority; @@ -16,9 +16,9 @@ public class CertificateRequest { @Builder.Default private int requestedValidityDays = 365; - private CertificateSubject subject; - private CertificateSubject issuer; - private CertificateRequestExtension extension; + private CertificateInfoSubject subject; + private CertificateInfoSubject issuer; + private CertificateInfoExtension extension; public enum RequestType { ROOT_AUTHORITY, @@ -26,21 +26,19 @@ public class CertificateRequest { NORMAL_CERTIFICATE, } - public static class CertificateRequestBuilder { + public static class CertificateInfoBuilder { - public CertificateRequestBuilder subject(CertificateSubject.CertificateSubjectBuilder builder) { + public CertificateInfoBuilder subject(CertificateInfoSubject.CertificateInfoSubjectBuilder builder) { this.subject = builder.build(); return this; } - public CertificateRequestBuilder issuer(CertificateSubject.CertificateSubjectBuilder builder) { + public CertificateInfoBuilder issuer(CertificateInfoSubject.CertificateInfoSubjectBuilder builder) { this.issuer = builder.build(); return this; } - public CertificateRequestBuilder extension( - CertificateRequestExtension.CertificateRequestExtensionBuilder builder - ) { + public CertificateInfoBuilder extension(CertificateInfoExtension.CertificateInfoExtensionBuilder builder) { this.extension = builder.build(); return this; } diff --git a/src/main/java/de/mlessmann/certassist/openssl/CertificateRequestExtension.java b/src/main/java/de/mlessmann/certassist/models/CertificateInfoExtension.java similarity index 64% rename from src/main/java/de/mlessmann/certassist/openssl/CertificateRequestExtension.java rename to src/main/java/de/mlessmann/certassist/models/CertificateInfoExtension.java index 853dbeb..d90f27b 100644 --- a/src/main/java/de/mlessmann/certassist/openssl/CertificateRequestExtension.java +++ b/src/main/java/de/mlessmann/certassist/models/CertificateInfoExtension.java @@ -1,4 +1,4 @@ -package de.mlessmann.certassist.openssl; +package de.mlessmann.certassist.models; import java.util.List; import java.util.Objects; @@ -8,15 +8,15 @@ import lombok.Getter; @Getter @Builder -public class CertificateRequestExtension { +public class CertificateInfoExtension { - private List alternativeNames; + private List alternativeDnsNames; - public static class CertificateRequestExtensionBuilder { + public static class CertificateInfoExtensionBuilder { - public CertificateRequestExtensionBuilder alternativeNames(String... altNames) { + public CertificateInfoExtensionBuilder alternativeDnsNames(String... altNames) { Objects.requireNonNull(altNames, "Alternative names must not be null (but can be empty)"); - this.alternativeNames = + this.alternativeDnsNames = Stream .of(altNames) .filter(Objects::nonNull) diff --git a/src/main/java/de/mlessmann/certassist/openssl/CertificateSubject.java b/src/main/java/de/mlessmann/certassist/models/CertificateInfoSubject.java similarity index 56% rename from src/main/java/de/mlessmann/certassist/openssl/CertificateSubject.java rename to src/main/java/de/mlessmann/certassist/models/CertificateInfoSubject.java index 4d5f302..48ec520 100644 --- a/src/main/java/de/mlessmann/certassist/openssl/CertificateSubject.java +++ b/src/main/java/de/mlessmann/certassist/models/CertificateInfoSubject.java @@ -1,11 +1,11 @@ -package de.mlessmann.certassist.openssl; +package de.mlessmann.certassist.models; import lombok.Builder; import lombok.Getter; @Getter @Builder -public class CertificateSubject { +public class CertificateInfoSubject { private String commonName; private String emailAddress; @@ -15,5 +15,7 @@ public class CertificateSubject { private String state; private String locality; - public static class CertificateSubjectBuilder {} + public static class CertificateInfoSubjectBuilder { + // Class only exists to allow the builder to be statically imported. + } } diff --git a/src/main/java/de/mlessmann/certassist/openssl/AutoBootOpenSSL.java b/src/main/java/de/mlessmann/certassist/openssl/AutoBootOpenSSL.java new file mode 100644 index 0000000..1b5ad0f --- /dev/null +++ b/src/main/java/de/mlessmann/certassist/openssl/AutoBootOpenSSL.java @@ -0,0 +1,26 @@ +package de.mlessmann.certassist.openssl; + +import de.mlessmann.certassist.service.ExecutableResolver; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class AutoBootOpenSSL { + + @Bean + @ConditionalOnMissingBean(CertificatePasswordProvider.class) + public CertificatePasswordProvider usageProvider() { + return new InMemoryCertificatePasswordProvider(); + } + + @Bean + @ConditionalOnMissingBean(CertificatePasswordProvider.class) + public OpenSSLService openSSLProvider( + ExecutableResolver executableResolver, + CertificatePasswordProvider passwordProvider, + CertificateProvider usageProvider + ) { + return new OpenSSLService(executableResolver, passwordProvider, usageProvider); + } +} diff --git a/src/test/java/de/mlessmann/certassist/service/InMemoryCertificatePasswordProvider.java b/src/main/java/de/mlessmann/certassist/openssl/InMemoryCertificatePasswordProvider.java similarity index 73% rename from src/test/java/de/mlessmann/certassist/service/InMemoryCertificatePasswordProvider.java rename to src/main/java/de/mlessmann/certassist/openssl/InMemoryCertificatePasswordProvider.java index cecc028..58a2c59 100644 --- a/src/test/java/de/mlessmann/certassist/service/InMemoryCertificatePasswordProvider.java +++ b/src/main/java/de/mlessmann/certassist/openssl/InMemoryCertificatePasswordProvider.java @@ -1,15 +1,13 @@ -package de.mlessmann.certassist.service; +package de.mlessmann.certassist.openssl; -import de.mlessmann.certassist.openssl.CertificatePasswordProvider; +import de.mlessmann.certassist.service.PassphraseService; import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.stereotype.Service; +import lombok.extern.slf4j.Slf4j; -@Service -@ConditionalOnMissingBean(CertificatePasswordProvider.class) +@Slf4j public class InMemoryCertificatePasswordProvider implements CertificatePasswordProvider { private final Map passwords = new ConcurrentHashMap<>(); @@ -22,11 +20,13 @@ public class InMemoryCertificatePasswordProvider implements CertificatePasswordP @Override public String getPasswordFor(String certificateFingerprint) { + log.trace("Getting password for certificate fingerprint: {}", certificateFingerprint); return Optional.ofNullable(passwords.get(certificateFingerprint)).orElseThrow(); } @Override public void setPasswordFor(String certificateFingerprint, String password) { + log.trace("Setting password for certificate fingerprint: {}", certificateFingerprint); Objects.requireNonNull(certificateFingerprint); Objects.requireNonNull(password); passwords.put(certificateFingerprint, password); diff --git a/src/main/java/de/mlessmann/certassist/openssl/OpenSSLCertificateCreator.java b/src/main/java/de/mlessmann/certassist/openssl/OpenSSLService.java similarity index 94% rename from src/main/java/de/mlessmann/certassist/openssl/OpenSSLCertificateCreator.java rename to src/main/java/de/mlessmann/certassist/openssl/OpenSSLService.java index 060e73c..eb5aa94 100644 --- a/src/main/java/de/mlessmann/certassist/openssl/OpenSSLCertificateCreator.java +++ b/src/main/java/de/mlessmann/certassist/openssl/OpenSSLService.java @@ -5,11 +5,14 @@ import static java.util.concurrent.TimeUnit.*; import static org.slf4j.LoggerFactory.getLogger; import de.mlessmann.certassist.DeleteRecursiveFileVisitor; -import de.mlessmann.certassist.ExecutableResolver; import de.mlessmann.certassist.except.CommandLineOperationException; import de.mlessmann.certassist.except.UnresolvableCLIDependency; -import de.mlessmann.certassist.openssl.CertificateRequest.RequestType; -import de.mlessmann.certassist.openssl.CertificateSubject.CertificateSubjectBuilder; +import de.mlessmann.certassist.models.CertificateInfo; +import de.mlessmann.certassist.models.CertificateInfo.RequestType; +import de.mlessmann.certassist.models.CertificateInfoExtension; +import de.mlessmann.certassist.models.CertificateInfoSubject; +import de.mlessmann.certassist.models.CertificateInfoSubject.CertificateInfoSubjectBuilder; +import de.mlessmann.certassist.service.ExecutableResolver; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; @@ -40,7 +43,7 @@ import org.zeroturnaround.exec.stream.slf4j.Slf4jStream; @Service @RequiredArgsConstructor @Slf4j -public class OpenSSLCertificateCreator { +public class OpenSSLService { private static final Logger openSSLLogger = getLogger("OpenSSL-Logger"); public static final String OPENSSL_CERT_SUBJECT_TEMPLATE = @@ -65,7 +68,7 @@ public class OpenSSLCertificateCreator { private final CertificatePasswordProvider passwordProvider; private final CertificateProvider certificateProvider; - private static String buildSubjectArg(CertificateRequest request) { + private static String buildSubjectArg(CertificateInfo request) { String certSubject = OPENSSL_CERT_SUBJECT_TEMPLATE .replace("ISO-COUNTRY", request.getSubject().getCountry()) .replace("STATE", request.getSubject().getState()) @@ -103,7 +106,7 @@ public class OpenSSLCertificateCreator { } @NonNull - public OpenSSLCertificateResult createCertificate(CertificateRequest request) throws CommandLineOperationException { + public OpenSSLCertificateResult createCertificate(CertificateInfo request) throws CommandLineOperationException { Path tmpDir; try { tmpDir = Files.createTempDirectory(CERTASSIST_TMP_PREFIX); @@ -150,7 +153,7 @@ public class OpenSSLCertificateCreator { } } - private Path createKeyfile(CertificateRequest request, Path outFile, String filePassword) + private Path createKeyfile(CertificateInfo request, Path outFile, String filePassword) throws CommandLineOperationException { Path keyFile = outFile.toAbsolutePath(); log.debug("Writing new certificate key to {}", keyFile); @@ -182,7 +185,7 @@ public class OpenSSLCertificateCreator { return keyFile; } - private Path createCertificate(CertificateRequest request, Path keyFile, Path outFile, String keyPassphrase) + private Path createCertificate(CertificateInfo request, Path keyFile, Path outFile, String keyPassphrase) throws CommandLineOperationException { log.debug("Writing new certificate file {}", outFile); @@ -222,7 +225,7 @@ public class OpenSSLCertificateCreator { return outFile; } - private Path createSigningRequest(CertificateRequest request, Path keyFile, Path outFile, String certPassword) + private Path createSigningRequest(CertificateInfo request, Path keyFile, Path outFile, String certPassword) throws CommandLineOperationException { log.atDebug().log("Writing new certificate signing request file {}", outFile); @@ -363,7 +366,7 @@ public class OpenSSLCertificateCreator { } private Path signCertificate( - CertificateRequest request, + CertificateInfo request, Path caCert, Path caKey, String caKeyPassphrase, @@ -377,7 +380,7 @@ public class OpenSSLCertificateCreator { String extContent = CSR_EXT_TEMPLATE; List altNames = Optional .ofNullable(request.getExtension()) - .map(CertificateRequestExtension::getAlternativeNames) + .map(CertificateInfoExtension::getAlternativeDnsNames) .orElse(List.of()); if (!altNames.isEmpty()) { AtomicInteger counter = new AtomicInteger(1); @@ -489,7 +492,7 @@ public class OpenSSLCertificateCreator { } } - public CertificateRequest getCertificateInfo(Path path) throws CommandLineOperationException { + public CertificateInfo getCertificateInfo(Path path) throws CommandLineOperationException { StartedProcess infoProc = null; try { infoProc = @@ -563,14 +566,14 @@ public class OpenSSLCertificateCreator { } } - private CertificateRequest getCertificateInfo(String[] lines) { - var builder = CertificateRequest.builder(); + private CertificateInfo getCertificateInfo(String[] lines) { + var builder = CertificateInfo.builder(); boolean hasIssuer = false; for (int i = 0; i < lines.length; i++) { String line = lines[i]; if (line.startsWith("subject=")) { - CertificateSubjectBuilder subjectBuilder = CertificateSubject.builder(); + var subjectBuilder = CertificateInfoSubject.builder(); line = lines[++i]; while (line.startsWith(" ")) { @@ -580,7 +583,7 @@ public class OpenSSLCertificateCreator { builder = builder.subject(subjectBuilder); } else if (line.startsWith("issuer=")) { hasIssuer = true; - CertificateSubjectBuilder issuerBuilder = CertificateSubject.builder(); + var issuerBuilder = CertificateInfoSubject.builder(); line = lines[++i]; while (line.startsWith(" ")) { @@ -591,7 +594,7 @@ public class OpenSSLCertificateCreator { builder = builder.issuer(issuerBuilder); } else if (line.startsWith("X509v3 Subject Alternative Name")) { String[] altNames = lines[++i].split(","); - builder = builder.extension(CertificateRequestExtension.builder().alternativeNames(altNames)); + builder = builder.extension(CertificateInfoExtension.builder().alternativeDnsNames(altNames)); } } @@ -599,7 +602,7 @@ public class OpenSSLCertificateCreator { return builder.build(); } - private CertificateSubjectBuilder readSubjectInfo(String line, CertificateSubjectBuilder builder) { + private CertificateInfoSubjectBuilder readSubjectInfo(String line, CertificateInfoSubjectBuilder builder) { String[] parts = line.split("=", 2); if (parts.length != 2) { return builder; diff --git a/src/main/java/de/mlessmann/certassist/service/CertificateCreationService.java b/src/main/java/de/mlessmann/certassist/service/CertificateCreationService.java index 429efe3..a9e37c4 100644 --- a/src/main/java/de/mlessmann/certassist/service/CertificateCreationService.java +++ b/src/main/java/de/mlessmann/certassist/service/CertificateCreationService.java @@ -1,9 +1,7 @@ package de.mlessmann.certassist.service; import de.mlessmann.certassist.except.CommandLineOperationException; -import de.mlessmann.certassist.models.Certificate; -import de.mlessmann.certassist.models.CertificateExtension; -import de.mlessmann.certassist.models.CertificateType; +import de.mlessmann.certassist.models.*; import de.mlessmann.certassist.openssl.*; import de.mlessmann.certassist.repositories.CertificateRepository; import java.io.IOException; @@ -19,17 +17,13 @@ import org.springframework.stereotype.Service; public class CertificateCreationService { private final CertificateRepository certificateRepository; - private final OpenSSLCertificateCreator openSSLCertificateCreator; + private final OpenSSLService openSSLService; private final PassphraseService passphraseService; - public Certificate createCertificate(final CertificateRequest certificateRequest) { - final Certificate certificate = createEntityFromRequest(certificateRequest); + public Certificate createCertificate(final CertificateInfo certificateInfo) { + final Certificate certificate = createEntityFromRequest(certificateInfo); - try ( - OpenSSLCertificateResult certificateCreatorResult = openSSLCertificateCreator.createCertificate( - certificateRequest - ); - ) { + try (OpenSSLCertificateResult certificateCreatorResult = openSSLService.createCertificate(certificateInfo);) { certificate.setPrivateKey(Files.readAllBytes(certificateCreatorResult.certificateKeyPath())); certificate.setCert(Files.readAllBytes(certificateCreatorResult.certificatePath())); } catch (CommandLineOperationException | IOException e) { @@ -40,26 +34,26 @@ public class CertificateCreationService { return certificate; } - private Certificate createEntityFromRequest(CertificateRequest certificateRequest) { + private Certificate createEntityFromRequest(CertificateInfo certificateInfo) { final Certificate certificate = new Certificate(); - certificate.setType(mapCertificateRequestType(certificateRequest.getType())); - certificate.setSubjectCommonName(certificateRequest.getSubject().getCommonName()); - certificate.setTrustingAuthority(certificateRequest.getTrustingAuthority()); - certificate.setRequestedKeyLength(certificateRequest.getRequestedKeyLength()); - certificate.setRequestedValidityDays(certificateRequest.getRequestedValidityDays()); - final CertificateSubject certificateSubject = certificateRequest.getSubject(); - certificate.setSubjectEmailAddress(certificateSubject.getEmailAddress()); - certificate.setSubjectOrganization(certificateSubject.getOrganization()); - certificate.setSubjectOrganizationalUnit(certificateSubject.getOrganizationalUnit()); - certificate.setSubjectCountry(certificateSubject.getCountry()); - certificate.setSubjectState(certificateSubject.getState()); - certificate.setSubjectLocality(certificateSubject.getLocality()); + certificate.setType(mapCertificateRequestType(certificateInfo.getType())); + certificate.setSubjectCommonName(certificateInfo.getSubject().getCommonName()); + certificate.setTrustingAuthority(certificateInfo.getTrustingAuthority()); + certificate.setRequestedKeyLength(certificateInfo.getRequestedKeyLength()); + certificate.setRequestedValidityDays(certificateInfo.getRequestedValidityDays()); + final CertificateInfoSubject subjectInfo = certificateInfo.getSubject(); + certificate.setSubjectEmailAddress(subjectInfo.getEmailAddress()); + certificate.setSubjectOrganization(subjectInfo.getOrganization()); + certificate.setSubjectOrganizationalUnit(subjectInfo.getOrganizationalUnit()); + certificate.setSubjectCountry(subjectInfo.getCountry()); + certificate.setSubjectState(subjectInfo.getState()); + certificate.setSubjectLocality(subjectInfo.getLocality()); - final CertificateRequestExtension extension = certificateRequest.getExtension(); + final CertificateInfoExtension extension = certificateInfo.getExtension(); if (extension != null) { final CertificateExtension certificateExtension = new CertificateExtension(); certificateExtension.setIdentifier("alternativeNames"); - certificateExtension.setValue(String.join(",", extension.getAlternativeNames())); + certificateExtension.setValue(String.join(",", extension.getAlternativeDnsNames())); certificate.setCertificateExtension(List.of(certificateExtension)); } return certificate; @@ -67,8 +61,8 @@ public class CertificateCreationService { public Certificate importCertificate(Path certificate, Path keyFile, String passphrase) { try { - String fingerprint = openSSLCertificateCreator.getCertificateFingerprint(certificate); - var generatedRequest = openSSLCertificateCreator.getCertificateInfo(certificate); + String fingerprint = openSSLService.getCertificateFingerprint(certificate); + var generatedRequest = openSSLService.getCertificateInfo(certificate); Certificate entity = createEntityFromRequest(generatedRequest); entity.setCert(Files.readAllBytes(certificate)); entity.setPrivateKey(Files.readAllBytes(keyFile)); @@ -81,7 +75,7 @@ public class CertificateCreationService { } } - private CertificateType mapCertificateRequestType(CertificateRequest.RequestType requestType) { + private CertificateType mapCertificateRequestType(CertificateInfo.RequestType requestType) { return switch (requestType) { case ROOT_AUTHORITY -> CertificateType.ROOT_CA; case STANDALONE_CERTIFICATE -> CertificateType.STANDALONE_CERT; diff --git a/src/main/java/de/mlessmann/certassist/ExecutableResolver.java b/src/main/java/de/mlessmann/certassist/service/ExecutableResolver.java similarity index 98% rename from src/main/java/de/mlessmann/certassist/ExecutableResolver.java rename to src/main/java/de/mlessmann/certassist/service/ExecutableResolver.java index b6322c4..1c02b57 100644 --- a/src/main/java/de/mlessmann/certassist/ExecutableResolver.java +++ b/src/main/java/de/mlessmann/certassist/service/ExecutableResolver.java @@ -1,4 +1,4 @@ -package de.mlessmann.certassist; +package de.mlessmann.certassist.service; import de.mlessmann.certassist.except.UnresolvableCLIDependency; import java.io.File; diff --git a/src/test/java/de/mlessmann/certassist/CertificateServiceTest.java b/src/test/java/de/mlessmann/certassist/CertificateServiceTest.java index 4c95ded..38f00f0 100644 --- a/src/test/java/de/mlessmann/certassist/CertificateServiceTest.java +++ b/src/test/java/de/mlessmann/certassist/CertificateServiceTest.java @@ -2,9 +2,9 @@ package de.mlessmann.certassist; import static org.assertj.core.api.Assertions.assertThat; -import de.mlessmann.certassist.openssl.CertificateRequest; -import de.mlessmann.certassist.openssl.CertificateRequestExtension; -import de.mlessmann.certassist.openssl.CertificateSubject; +import de.mlessmann.certassist.models.CertificateInfo; +import de.mlessmann.certassist.models.CertificateInfoExtension; +import de.mlessmann.certassist.models.CertificateInfoSubject; import de.mlessmann.certassist.service.CertificateCreationService; import java.nio.file.Path; import org.junit.jupiter.api.Test; @@ -19,11 +19,11 @@ public class CertificateServiceTest { @Test void testCanCreateCertificate() { - var request = CertificateRequest + var request = CertificateInfo .builder() - .type(CertificateRequest.RequestType.STANDALONE_CERTIFICATE) + .type(CertificateInfo.RequestType.STANDALONE_CERTIFICATE) .subject( - CertificateSubject + CertificateInfoSubject .builder() .commonName("cert.creation") .country("DE") @@ -31,7 +31,7 @@ public class CertificateServiceTest { .locality("HH") .organization("Crazy-Cats") ) - .extension(CertificateRequestExtension.builder().alternativeNames("test2.home", "test3.home")) + .extension(CertificateInfoExtension.builder().alternativeDnsNames("test2.home", "test3.home")) .build(); var cert = certificateService.createCertificate(request); assertThat(cert).isNotNull(); @@ -40,11 +40,11 @@ public class CertificateServiceTest { @Test void testCanImportCertificate() { - Path certDir = TestOpenSSLCertificateCreator.TEST_CERT_PATH; + Path certDir = TestOpenSSLService.TEST_CERT_PATH; var importedCert = certificateService.importCertificate( certDir.resolve("x509forImport.pem"), certDir.resolve("x509forImport.key.pem"), - TestOpenSSLCertificateCreator.TEST_CERT_PASSPHRASE + TestOpenSSLService.TEST_CERT_PASSPHRASE ); assertThat(importedCert).isNotNull(); assertThat(importedCert.getId()).isGreaterThan("0"); diff --git a/src/test/java/de/mlessmann/certassist/TestKeystoreCreation.java b/src/test/java/de/mlessmann/certassist/TestKeystoreCreation.java index 71037ff..d8b657a 100644 --- a/src/test/java/de/mlessmann/certassist/TestKeystoreCreation.java +++ b/src/test/java/de/mlessmann/certassist/TestKeystoreCreation.java @@ -6,8 +6,9 @@ import de.mlessmann.certassist.keystore.KeyStoreManager; import de.mlessmann.certassist.keystore.TruststoreManager; import de.mlessmann.certassist.openssl.CertificateProvider; import de.mlessmann.certassist.openssl.CertificateUsage; -import de.mlessmann.certassist.openssl.OpenSSLCertificateCreator; -import de.mlessmann.certassist.service.InMemoryCertificatePasswordProvider; +import de.mlessmann.certassist.openssl.InMemoryCertificatePasswordProvider; +import de.mlessmann.certassist.openssl.OpenSSLService; +import de.mlessmann.certassist.service.ExecutableResolver; import java.io.IOException; import java.net.ServerSocket; import java.nio.file.Path; @@ -26,36 +27,32 @@ public class TestKeystoreCreation { private final CertificateUsage dummyCert = new CertificateUsage() { @Override public String fingerprint() { - return TestOpenSSLCertificateCreator.TEST_CERT_FINGERPRINT; + return TestOpenSSLService.TEST_CERT_FINGERPRINT; } @Override public Path certificatePath() { - return TestOpenSSLCertificateCreator.TEST_CERT_PATH.resolve("x509forImport.pem"); + return TestOpenSSLService.TEST_CERT_PATH.resolve("x509forImport.pem"); } @Override public Path certificateKeyPath() { - return TestOpenSSLCertificateCreator.TEST_CERT_PATH.resolve("x509forImport.key.pem"); + return TestOpenSSLService.TEST_CERT_PATH.resolve("x509forImport.key.pem"); } @Override public Path fullchainPath() { - return TestOpenSSLCertificateCreator.TEST_CERT_PATH.resolve("x509forImport.fullchain.pem"); + return TestOpenSSLService.TEST_CERT_PATH.resolve("x509forImport.fullchain.pem"); } }; @Test void testTruststore() throws Exception { var passwordProvider = new InMemoryCertificatePasswordProvider(); - passwordProvider.setPasswordFor(dummyCert.fingerprint(), TestOpenSSLCertificateCreator.TEST_CERT_PASSPHRASE); + passwordProvider.setPasswordFor(dummyCert.fingerprint(), TestOpenSSLService.TEST_CERT_PASSPHRASE); var certificateProvider = Mockito.mock(CertificateProvider.class); - var opensslCertCreator = new OpenSSLCertificateCreator( - new ExecutableResolver(), - passwordProvider, - certificateProvider - ); + var opensslCertCreator = new OpenSSLService(new ExecutableResolver(), passwordProvider, certificateProvider); var truststoreManager = new TruststoreManager(); var keyStoreManager = new KeyStoreManager(opensslCertCreator, passwordProvider); AtomicBoolean serverAccepted = new AtomicBoolean(false); diff --git a/src/test/java/de/mlessmann/certassist/TestOpenSSLCertificateCreator.java b/src/test/java/de/mlessmann/certassist/TestOpenSSLService.java similarity index 81% rename from src/test/java/de/mlessmann/certassist/TestOpenSSLCertificateCreator.java rename to src/test/java/de/mlessmann/certassist/TestOpenSSLService.java index 456da58..2055b4f 100644 --- a/src/test/java/de/mlessmann/certassist/TestOpenSSLCertificateCreator.java +++ b/src/test/java/de/mlessmann/certassist/TestOpenSSLService.java @@ -3,8 +3,12 @@ package de.mlessmann.certassist; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.*; +import de.mlessmann.certassist.models.CertificateInfo; +import de.mlessmann.certassist.models.CertificateInfo.RequestType; +import de.mlessmann.certassist.models.CertificateInfoExtension; +import de.mlessmann.certassist.models.CertificateInfoSubject; import de.mlessmann.certassist.openssl.*; -import de.mlessmann.certassist.openssl.CertificateRequest.RequestType; +import de.mlessmann.certassist.service.ExecutableResolver; import java.nio.file.Path; import java.util.Objects; import org.junit.jupiter.api.BeforeEach; @@ -13,7 +17,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; @SpringBootTest -class TestOpenSSLCertificateCreator { +class TestOpenSSLService { public static final String TEST_CERT_PASSPHRASE = "ABC-123"; public static final Path TEST_CERT_PATH = Path.of("src/test/resources/openssl"); @@ -35,17 +39,13 @@ class TestOpenSSLCertificateCreator { void testCertificateCreation() throws Exception { CertificateProvider certificateProvider = mock(CertificateProvider.class); ExecutableResolver executableResolver = new ExecutableResolver(); - var certificateCreator = new OpenSSLCertificateCreator( - executableResolver, - passwordProvider, - certificateProvider - ); + var certificateCreator = new OpenSSLService(executableResolver, passwordProvider, certificateProvider); - CertificateRequest certRequest = CertificateRequest + CertificateInfo certRequest = CertificateInfo .builder() .type(RequestType.STANDALONE_CERTIFICATE) .subject( - CertificateSubject + CertificateInfoSubject .builder() .commonName("test.home") .country("DE") @@ -53,7 +53,7 @@ class TestOpenSSLCertificateCreator { .locality("HH") .organization("Crazy-Cats") ) - .extension(CertificateRequestExtension.builder().alternativeNames("test2.home", "test3.home")) + .extension(CertificateInfoExtension.builder().alternativeDnsNames("test2.home", "test3.home")) .build(); try (var cert = certificateCreator.createCertificate(certRequest)) { @@ -64,12 +64,12 @@ class TestOpenSSLCertificateCreator { .withFailMessage(ERR_NOT_ENCRYPTED) .isTrue(); - CertificateRequest childRequest = CertificateRequest + CertificateInfo childRequest = CertificateInfo .builder() .type(RequestType.NORMAL_CERTIFICATE) .trustingAuthority(cert.fingerprint()) .subject( - CertificateSubject + CertificateInfoSubject .builder() .commonName("test.local") .country("DE") @@ -77,7 +77,7 @@ class TestOpenSSLCertificateCreator { .locality("HH") .organization("Crazy-Cats") ) - .extension(CertificateRequestExtension.builder().alternativeNames("test2.local", "test3.local")) + .extension(CertificateInfoExtension.builder().alternativeDnsNames("test2.local", "test3.local")) .build(); var spiedCert = spy(cert); @@ -101,11 +101,7 @@ class TestOpenSSLCertificateCreator { void testCertificateImport() throws Exception { CertificateProvider certificateProvider = mock(CertificateProvider.class); ExecutableResolver executableResolver = new ExecutableResolver(); - var certificateCreator = new OpenSSLCertificateCreator( - executableResolver, - passwordProvider, - certificateProvider - ); + var certificateCreator = new OpenSSLService(executableResolver, passwordProvider, certificateProvider); var request = certificateCreator.getCertificateInfo(TEST_CERT_PATH.resolve("x509forImportCA.pem")); assertThat(request).isNotNull(); @@ -123,6 +119,6 @@ class TestOpenSSLCertificateCreator { assertThat(request.getSubject().getState()).isEqualTo("SH"); assertThat(request.getSubject().getLocality()).isEqualTo("HH"); assertThat(request.getSubject().getOrganization()).isEqualTo("Crazy-Cats"); - assertThat(request.getExtension().getAlternativeNames()).containsExactly("test2.local", "test3.local"); + assertThat(request.getExtension().getAlternativeDnsNames()).containsExactly("test2.local", "test3.local"); } }