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 CertPasswordProvider passwordProvider;
|
||||
private final CertificateProvider certificateProvider;
|
||||
|
||||
private static String buildSubjectArg(CertificateRequest request) {
|
||||
String certSubject = OPENSSL_CERT_SUBJECT_TEMPLATE
|
||||
|
@ -77,21 +78,23 @@ public class OpenSSLCertificateCreator {
|
|||
}
|
||||
|
||||
String certPassword = passwordProvider.generateNewPassword();
|
||||
Path keyFile = createKeyfile(request, tmpDir.resolve("root.key"), certPassword);
|
||||
Path rootCert = createCertificate(request, keyFile, tmpDir.resolve("root.crt"), certPassword);
|
||||
Path keyFile = createKeyfile(request, tmpDir.resolve("certificate.key"), certPassword);
|
||||
if (
|
||||
request.getType() == RequestType.ROOT_AUTHORITY || request.getType() == RequestType.STANDALONE_CERTIFICATE
|
||||
) {
|
||||
String fingerprint = getCertificateFingerprint(rootCert);
|
||||
return new OpenSSLCertificateResult(tmpDir, rootCert, keyFile, fingerprint);
|
||||
Path certificate = createCertificate(request, keyFile, tmpDir.resolve("certificate.crt"), certPassword);
|
||||
String fingerprint = getCertificateFingerprint(certificate);
|
||||
passwordProvider.setPasswordFor(fingerprint, certPassword);
|
||||
return new OpenSSLCertificateResult(tmpDir, certificate, keyFile, fingerprint);
|
||||
}
|
||||
|
||||
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);
|
||||
try (var certAuthority = certificateProvider.requestCertificateUsage(request.getTrustingAuthority())) {
|
||||
Path unsignedCert = createSigningRequest(request, keyFile, tmpDir.resolve("child.csr"), certPassword);
|
||||
Path signedCert = signCertificate(request, certAuthority.certificatePath(), certAuthority.certificateKeyPath(), unsignedCert, certPassword);
|
||||
String fingerprint = getCertificateFingerprint(signedCert);
|
||||
passwordProvider.setPasswordFor(fingerprint, certPassword);
|
||||
return new OpenSSLCertificateResult(tmpDir, signedCert, keyFile, fingerprint);
|
||||
}
|
||||
}
|
||||
|
||||
private Path createKeyfile(CertificateRequest request, Path outFile, String filePassword)
|
||||
|
|
|
@ -11,19 +11,24 @@ import org.junit.jupiter.api.Test;
|
|||
|
||||
class TestOpenSSLCertificateCreator {
|
||||
|
||||
private OpenSSLCertificateCreator openSSLCertificateCreator;
|
||||
private CertPasswordProvider passwordProvider;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
CertPasswordProvider passwordProvider = mock(CertPasswordProvider.class);
|
||||
passwordProvider = mock(CertPasswordProvider.class);
|
||||
when(passwordProvider.generateNewPassword()).thenReturn("ABC-123");
|
||||
|
||||
ExecutableResolver executableResolver = new ExecutableResolver();
|
||||
openSSLCertificateCreator = new OpenSSLCertificateCreator(executableResolver, passwordProvider);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCertificateCreation() throws Exception {
|
||||
CertificateProvider certificateProvider = mock(CertificateProvider.class);
|
||||
ExecutableResolver executableResolver = new ExecutableResolver();
|
||||
var certificateCreator = new OpenSSLCertificateCreator(
|
||||
executableResolver,
|
||||
passwordProvider,
|
||||
certificateProvider
|
||||
);
|
||||
|
||||
CertificateRequest certRequest = CertificateRequest
|
||||
.builder()
|
||||
.commonName("test.home")
|
||||
|
@ -32,8 +37,8 @@ class TestOpenSSLCertificateCreator {
|
|||
.extension(CertificateRequestExtension.builder().alternativeNames("test2.home", "test3.home"))
|
||||
.build();
|
||||
|
||||
try (var cert = openSSLCertificateCreator.createCertificate(certRequest)) {
|
||||
assertThat(openSSLCertificateCreator.verifyCertificate(cert.getCertificatePath())).isEqualTo(true);
|
||||
try (var cert = certificateCreator.createCertificate(certRequest)) {
|
||||
assertThat(certificateCreator.verifyCertificate(cert.getCertificatePath())).isEqualTo(true);
|
||||
System.out.println("Certificate created: " + cert);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue