home-cert-assistant/src/test/java/de/mlessmann/certassist/TestOpenSSLService.java

127 lines
6 KiB
Java

package de.mlessmann.certassist;
import static java.util.Objects.requireNonNull;
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.CertificatePasswordProvider;
import de.mlessmann.certassist.openssl.CertificateProvider;
import de.mlessmann.certassist.openssl.OpenSSLService;
import de.mlessmann.certassist.service.ExecutableResolver;
import java.nio.file.Path;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
@SpringBootTest
class TestOpenSSLService {
public static final String TEST_CERT_PASSPHRASE = "ABC-123";
public static final Path TEST_CERT_PATH = Path.of("src/test/resources/openssl");
public static final String TEST_CERT_FINGERPRINT =
"SHA1;4E:D6:0A:47:F0:63:AD:96:26:83:16:28:32:F5:E8:36:5A:62:91:95";
private static final String ERR_NOT_ENCRYPTED = "Private key not encrypted";
private static final String ERR_VERIFY_FAILED = "Certificate verification failed";
@MockBean
CertificatePasswordProvider passwordProvider;
@BeforeEach
void setUp() {
when(passwordProvider.generateNewPassword()).thenReturn(TEST_CERT_PASSPHRASE);
when(passwordProvider.getPasswordFor(anyString())).thenReturn(TEST_CERT_PASSPHRASE);
}
@Test
void testCertificateCreation() throws Exception {
CertificateProvider certificateProvider = mock(CertificateProvider.class);
ExecutableResolver executableResolver = new ExecutableResolver();
var certificateCreator = new OpenSSLService(executableResolver, passwordProvider, certificateProvider);
CertificateInfo certRequest = CertificateInfo
.builder()
.type(RequestType.STANDALONE_CERTIFICATE)
.subject(
CertificateInfoSubject
.builder()
.commonName("test.home")
.country("DE")
.state("SH")
.locality("HH")
.organization("Crazy-Cats")
)
.extension(CertificateInfoExtension.builder().alternativeDnsNames("test2.home", "test3.home"))
.build();
try (var cert = certificateCreator.createCertificate(certRequest)) {
assertThat(certificateCreator.verifyCertificate(cert.certificatePath(), cert.certificatePath()))
.withFailMessage(ERR_VERIFY_FAILED)
.isTrue();
assertThat(certificateCreator.isKeyEncrypted(requireNonNull(cert.certificateKeyPath())))
.withFailMessage(ERR_NOT_ENCRYPTED)
.isTrue();
CertificateInfo childRequest = CertificateInfo
.builder()
.type(RequestType.NORMAL_CERTIFICATE)
.trustingAuthority(cert.fingerprint())
.subject(
CertificateInfoSubject
.builder()
.commonName("test.local")
.country("DE")
.state("SH")
.locality("HH")
.organization("Crazy-Cats")
)
.extension(CertificateInfoExtension.builder().alternativeDnsNames("test2.local", "test3.local"))
.build();
var spiedCert = spy(cert);
doNothing().when(spiedCert).close();
when(certificateProvider.requestCertificateUsage(cert.fingerprint())).thenReturn(spiedCert);
try (var childCert = certificateCreator.createCertificate(childRequest)) {
Path fullchain = childCert.fullchainPath();
assertThat(certificateCreator.verifyCertificate(requireNonNull(fullchain), cert.certificatePath()))
.withFailMessage(ERR_VERIFY_FAILED)
.isTrue();
assertThat(certificateCreator.isKeyEncrypted(requireNonNull(childCert.certificateKeyPath())))
.withFailMessage(ERR_NOT_ENCRYPTED)
.isTrue();
}
}
}
@Test
void testCertificateImport() throws Exception {
CertificateProvider certificateProvider = mock(CertificateProvider.class);
ExecutableResolver executableResolver = new ExecutableResolver();
var certificateCreator = new OpenSSLService(executableResolver, passwordProvider, certificateProvider);
var request = certificateCreator.getCertificateInfo(TEST_CERT_PATH.resolve("x509forImportCA.pem"));
assertThat(request).isNotNull();
assertThat(request.subject().getCommonName()).isEqualTo("test.home");
assertThat(request.subject().getCountry()).isEqualTo("DE");
assertThat(request.subject().getState()).isEqualTo("SH");
assertThat(request.subject().getLocality()).isEqualTo("HH");
assertThat(request.subject().getOrganization()).isEqualTo("Crazy-Cats");
assertThat(request.notBefore()).isEqualTo("2024-11-22T18:57:40Z");
assertThat(request.notAfter()).isEqualTo("2025-11-22T18:57:40Z");
assertThat(request.extensions()).isEmpty();
request = certificateCreator.getCertificateInfo(TEST_CERT_PATH.resolve("x509forImport.pem"));
assertThat(request).isNotNull();
assertThat(request.subject().getCommonName()).isEqualTo("test.local");
assertThat(request.subject().getCountry()).isEqualTo("DE");
assertThat(request.subject().getState()).isEqualTo("SH");
assertThat(request.subject().getLocality()).isEqualTo("HH");
assertThat(request.subject().getOrganization()).isEqualTo("Crazy-Cats");
assertThat(request.extensions().getFirst().getAlternativeDnsNames())
.containsExactly("test2.local", "test3.local");
}
}