feat: Use password provider to store certificates encrypted

This commit is contained in:
Magnus Leßmann (@MarkL4YG) 2024-11-19 22:23:40 +01:00
parent 40111b4e03
commit ef141568b7
Signed by: Mark.TwoFive
GPG key ID: 5B5EBCBE331F1E6F
3 changed files with 41 additions and 19 deletions

View file

@ -0,0 +1,9 @@
package de.mlessmann.certassist.openssl;
public interface CertPasswordProvider {
String generateNewPassword();
String getPasswordFor(String certificateFingerprint);
void setPasswordFor(String certificateFingerprint, String password);
}

View file

@ -46,6 +46,7 @@ public class OpenSSLCertificateCreator {
);
private final ExecutableResolver executableResolver;
private final CertPasswordProvider passwordProvider;
private static String buildSubjectArg(CertificateRequest request) {
String certSubject = OPENSSL_CERT_SUBJECT_TEMPLATE
@ -75,8 +76,9 @@ public class OpenSSLCertificateCreator {
throw new CommandLineOperationException("Could not create temporary directory for certificate creation", e);
}
Path keyFile = createKeyfile(request, tmpDir.resolve("root.key"));
Path rootCert = createCertificate(request, keyFile, tmpDir.resolve("root.crt"));
String certPassword = passwordProvider.generateNewPassword();
Path keyFile = createKeyfile(request, tmpDir.resolve("root.key"), certPassword);
Path rootCert = createCertificate(request, keyFile, tmpDir.resolve("root.crt"), certPassword);
if (
request.getType() == RequestType.ROOT_AUTHORITY || request.getType() == RequestType.STANDALONE_CERTIFICATE
) {
@ -84,14 +86,15 @@ public class OpenSSLCertificateCreator {
return new OpenSSLCertificateResult(tmpDir, rootCert, keyFile, fingerprint);
}
Path childKey = createKeyfile(request, tmpDir.resolve("child.key"));
Path unsignedCert = createSigningRequest(request, childKey, tmpDir.resolve("child.csr"));
Path signedCert = signCertificate(request, rootCert, keyFile, unsignedCert);
Path childKey = createKeyfile(request, tmpDir.resolve("child.key"), certPassword);
Path unsignedCert = createSigningRequest(request, childKey, tmpDir.resolve("child.csr"), certPassword);
Path signedCert = signCertificate(request, rootCert, keyFile, unsignedCert, certPassword);
String fingerPrint = getCertificateFingerprint(signedCert);
passwordProvider.setPasswordFor(fingerPrint, certPassword);
return new OpenSSLCertificateResult(tmpDir, signedCert, childKey, fingerPrint);
}
private Path createKeyfile(CertificateRequest request, Path outFile)
private Path createKeyfile(CertificateRequest request, Path outFile, String filePassword)
throws CommandLineOperationException, InterruptedException {
Path keyFile = outFile.toAbsolutePath();
log.atDebug().log("Writing new certificate key to {}", keyFile);
@ -107,7 +110,7 @@ public class OpenSSLCertificateCreator {
"env:KEY_PASS",
Integer.toString(request.getRequestedKeyLength())
)
.environment("KEY_PASS", request.getOid())
.environment("KEY_PASS", filePassword)
.redirectOutput(Slf4jStream.ofCaller().asDebug())
.redirectError(Slf4jStream.ofCaller().asError())
.start();
@ -120,7 +123,7 @@ public class OpenSSLCertificateCreator {
return keyFile;
}
private Path createCertificate(CertificateRequest request, Path keyFile, Path outFile)
private Path createCertificate(CertificateRequest request, Path keyFile, Path outFile, String certPassword)
throws CommandLineOperationException, InterruptedException {
log.atDebug().log("Writing new certificate file {}", outFile);
@ -147,7 +150,7 @@ public class OpenSSLCertificateCreator {
"-subj",
certSubject
)
.environment("KEY_PASS", request.getOid())
.environment("KEY_PASS", certPassword)
.redirectOutput(Slf4jStream.ofCaller().asDebug())
.redirectError(Slf4jStream.ofCaller().asError())
.start();
@ -160,7 +163,7 @@ public class OpenSSLCertificateCreator {
return outFile;
}
private Path createSigningRequest(CertificateRequest request, Path keyFile, Path outFile)
private Path createSigningRequest(CertificateRequest request, Path keyFile, Path outFile, String certPassword)
throws CommandLineOperationException, InterruptedException {
log.atDebug().log("Writing new certificate signing request file {}", outFile);
@ -184,7 +187,7 @@ public class OpenSSLCertificateCreator {
"-subj",
certSubject
)
.environment("KEY_PASS", request.getOid())
.environment("KEY_PASS", certPassword)
.redirectOutput(Slf4jStream.ofCaller().asDebug())
.redirectError(Slf4jStream.ofCaller().asError())
.start();
@ -211,8 +214,13 @@ public class OpenSSLCertificateCreator {
}
}
private Path signCertificate(CertificateRequest request, Path caCert, Path caKey, Path csrFile)
throws CommandLineOperationException, InterruptedException {
private Path signCertificate(
CertificateRequest request,
Path caCert,
Path caKey,
Path csrFile,
String certPassword
) throws CommandLineOperationException, InterruptedException {
Path outFile = csrFile.resolveSibling(csrFile.getFileName().toString().replace(".csr", ".crt"));
log.atDebug().log("Writing new signed certificate file {}", outFile);
Path extFile = csrFile.resolveSibling(csrFile.getFileName().toString().replace(".csr", ".ext"));
@ -265,8 +273,11 @@ public class OpenSSLCertificateCreator {
"-out",
outFile.toString(),
"-extfile",
extFile.toString()
extFile.toString(),
"-passout",
"env:KEY_PASS"
)
.environment("KEY_PASS", certPassword)
.redirectOutput(Slf4jStream.ofCaller().asDebug())
.redirectError(Slf4jStream.ofCaller().asError())
.start();

View file

@ -1,12 +1,11 @@
package de.mlessmann.certassist;
import static org.assertj.core.api.Assertions.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import de.mlessmann.certassist.openssl.CertificateRequest;
import de.mlessmann.certassist.openssl.*;
import de.mlessmann.certassist.openssl.CertificateRequest.RequestType;
import de.mlessmann.certassist.openssl.CertificateRequestExtension;
import de.mlessmann.certassist.openssl.CertificateSubject;
import de.mlessmann.certassist.openssl.OpenSSLCertificateCreator;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@ -16,8 +15,11 @@ class TestOpenSSLCertificateCreator {
@BeforeEach
void setUp() {
CertPasswordProvider passwordProvider = mock(CertPasswordProvider.class);
when(passwordProvider.generateNewPassword()).thenReturn("ABC-123");
ExecutableResolver executableResolver = new ExecutableResolver();
openSSLCertificateCreator = new OpenSSLCertificateCreator(executableResolver);
openSSLCertificateCreator = new OpenSSLCertificateCreator(executableResolver, passwordProvider);
}
@Test