feat: Implement way of retrieving CAs in signing process
This commit is contained in:
parent
2608bca428
commit
fc34320ffd
4 changed files with 53 additions and 17 deletions
|
@ -0,0 +1,11 @@
|
||||||
|
package de.mlessmann.certassist.openssl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accessor interface to the certificate storage.
|
||||||
|
*/
|
||||||
|
public interface CertificateProvider {
|
||||||
|
/**
|
||||||
|
* A stored certificate is needed (e.g. for command line operations when signing sub certificates).
|
||||||
|
*/
|
||||||
|
CertificateUsage requestCertificateUsage(String fingerprint);
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package de.mlessmann.certassist.openssl;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instance of a certificate that is temporarily stored on disk to be available for use in command line calls.
|
||||||
|
* The instance implements AutoCloseable to enable cleanup after the stored files are no longer needed.
|
||||||
|
* @implSpec The files should be removed from disk when the instance is closed, UNLESS the provided paths are the permanent storage location for the certificate files.
|
||||||
|
*/
|
||||||
|
public interface CertificateUsage extends AutoCloseable {
|
||||||
|
Path certificatePath();
|
||||||
|
Path certificateKeyPath();
|
||||||
|
String fingerprint();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void close();
|
||||||
|
}
|
|
@ -47,6 +47,7 @@ public class OpenSSLCertificateCreator {
|
||||||
|
|
||||||
private final ExecutableResolver executableResolver;
|
private final ExecutableResolver executableResolver;
|
||||||
private final CertPasswordProvider passwordProvider;
|
private final CertPasswordProvider passwordProvider;
|
||||||
|
private final CertificateProvider certificateProvider;
|
||||||
|
|
||||||
private static String buildSubjectArg(CertificateRequest request) {
|
private static String buildSubjectArg(CertificateRequest request) {
|
||||||
String certSubject = OPENSSL_CERT_SUBJECT_TEMPLATE
|
String certSubject = OPENSSL_CERT_SUBJECT_TEMPLATE
|
||||||
|
@ -77,21 +78,23 @@ public class OpenSSLCertificateCreator {
|
||||||
}
|
}
|
||||||
|
|
||||||
String certPassword = passwordProvider.generateNewPassword();
|
String certPassword = passwordProvider.generateNewPassword();
|
||||||
Path keyFile = createKeyfile(request, tmpDir.resolve("root.key"), certPassword);
|
Path keyFile = createKeyfile(request, tmpDir.resolve("certificate.key"), certPassword);
|
||||||
Path rootCert = createCertificate(request, keyFile, tmpDir.resolve("root.crt"), certPassword);
|
|
||||||
if (
|
if (
|
||||||
request.getType() == RequestType.ROOT_AUTHORITY || request.getType() == RequestType.STANDALONE_CERTIFICATE
|
request.getType() == RequestType.ROOT_AUTHORITY || request.getType() == RequestType.STANDALONE_CERTIFICATE
|
||||||
) {
|
) {
|
||||||
String fingerprint = getCertificateFingerprint(rootCert);
|
Path certificate = createCertificate(request, keyFile, tmpDir.resolve("certificate.crt"), certPassword);
|
||||||
return new OpenSSLCertificateResult(tmpDir, rootCert, keyFile, fingerprint);
|
String fingerprint = getCertificateFingerprint(certificate);
|
||||||
|
passwordProvider.setPasswordFor(fingerprint, certPassword);
|
||||||
|
return new OpenSSLCertificateResult(tmpDir, certificate, keyFile, fingerprint);
|
||||||
}
|
}
|
||||||
|
|
||||||
Path childKey = createKeyfile(request, tmpDir.resolve("child.key"), certPassword);
|
try (var certAuthority = certificateProvider.requestCertificateUsage(request.getTrustingAuthority())) {
|
||||||
Path unsignedCert = createSigningRequest(request, childKey, tmpDir.resolve("child.csr"), certPassword);
|
Path unsignedCert = createSigningRequest(request, keyFile, tmpDir.resolve("child.csr"), certPassword);
|
||||||
Path signedCert = signCertificate(request, rootCert, keyFile, unsignedCert, certPassword);
|
Path signedCert = signCertificate(request, certAuthority.certificatePath(), certAuthority.certificateKeyPath(), unsignedCert, certPassword);
|
||||||
String fingerPrint = getCertificateFingerprint(signedCert);
|
String fingerprint = getCertificateFingerprint(signedCert);
|
||||||
passwordProvider.setPasswordFor(fingerPrint, certPassword);
|
passwordProvider.setPasswordFor(fingerprint, certPassword);
|
||||||
return new OpenSSLCertificateResult(tmpDir, signedCert, childKey, fingerPrint);
|
return new OpenSSLCertificateResult(tmpDir, signedCert, keyFile, fingerprint);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Path createKeyfile(CertificateRequest request, Path outFile, String filePassword)
|
private Path createKeyfile(CertificateRequest request, Path outFile, String filePassword)
|
||||||
|
|
|
@ -11,19 +11,24 @@ import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
class TestOpenSSLCertificateCreator {
|
class TestOpenSSLCertificateCreator {
|
||||||
|
|
||||||
private OpenSSLCertificateCreator openSSLCertificateCreator;
|
private CertPasswordProvider passwordProvider;
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void setUp() {
|
void setUp() {
|
||||||
CertPasswordProvider passwordProvider = mock(CertPasswordProvider.class);
|
passwordProvider = mock(CertPasswordProvider.class);
|
||||||
when(passwordProvider.generateNewPassword()).thenReturn("ABC-123");
|
when(passwordProvider.generateNewPassword()).thenReturn("ABC-123");
|
||||||
|
|
||||||
ExecutableResolver executableResolver = new ExecutableResolver();
|
|
||||||
openSSLCertificateCreator = new OpenSSLCertificateCreator(executableResolver, passwordProvider);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testCertificateCreation() throws Exception {
|
void testCertificateCreation() throws Exception {
|
||||||
|
CertificateProvider certificateProvider = mock(CertificateProvider.class);
|
||||||
|
ExecutableResolver executableResolver = new ExecutableResolver();
|
||||||
|
var certificateCreator = new OpenSSLCertificateCreator(
|
||||||
|
executableResolver,
|
||||||
|
passwordProvider,
|
||||||
|
certificateProvider
|
||||||
|
);
|
||||||
|
|
||||||
CertificateRequest certRequest = CertificateRequest
|
CertificateRequest certRequest = CertificateRequest
|
||||||
.builder()
|
.builder()
|
||||||
.commonName("test.home")
|
.commonName("test.home")
|
||||||
|
@ -32,8 +37,8 @@ class TestOpenSSLCertificateCreator {
|
||||||
.extension(CertificateRequestExtension.builder().alternativeNames("test2.home", "test3.home"))
|
.extension(CertificateRequestExtension.builder().alternativeNames("test2.home", "test3.home"))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
try (var cert = openSSLCertificateCreator.createCertificate(certRequest)) {
|
try (var cert = certificateCreator.createCertificate(certRequest)) {
|
||||||
assertThat(openSSLCertificateCreator.verifyCertificate(cert.getCertificatePath())).isEqualTo(true);
|
assertThat(certificateCreator.verifyCertificate(cert.getCertificatePath())).isEqualTo(true);
|
||||||
System.out.println("Certificate created: " + cert);
|
System.out.println("Certificate created: " + cert);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue