127 lines
6 KiB
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");
|
|
}
|
|
}
|