🚧 Create method to generate x509 certs

This commit is contained in:
Magnus Leßmann (@MarkL4YG) 2024-11-17 16:51:11 +01:00
parent 24a4e32855
commit 98a6556bf9
3 changed files with 88 additions and 1 deletions

View file

@ -32,6 +32,16 @@ public class CertificateRequest {
@Builder.Default
private int requestedKeyLength = 4096;
@Getter
@Setter
@Builder.Default
private int requestedValidityDays = 365;
@Getter
@Setter
@Builder.Default
private CertificateSubject subject = CertificateSubject.builder().build();
public enum RequestType {
ROOT_AUTHORITY,
STANDALONE_CERTIFICATE,

View file

@ -0,0 +1,16 @@
package de.mlessmann.certassist.openssl;
import lombok.Builder;
import lombok.Getter;
@Getter
@Builder
public class CertificateSubject {
private String emailAddress;
private String organization;
private String organizationalUnit;
private String country;
private String state;
private String locality;
}

View file

@ -3,6 +3,7 @@ package de.mlessmann.certassist.openssl;
import de.mlessmann.certassist.ExecutableResolver;
import de.mlessmann.certassist.except.CommandLineOperationException;
import de.mlessmann.certassist.except.UnresolvableCLIDependency;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.Nullable;
@ -21,8 +22,8 @@ import static org.slf4j.LoggerFactory.getLogger;
@Service
public class OpenSSLCertificateCreator {
public static final String OPENSSL_CERT_SUBJECT_TEMPLATE = "/C=ISO-COUNTRY/ST=STATE/L=LOCALITY/O=ORGANIZATION/CN=COMMON-NAME";
private static final Logger LOGGER = getLogger(OpenSSLCertificateCreator.class);
private final ExecutableResolver executableResolver;
@Autowired
@ -30,6 +31,31 @@ public class OpenSSLCertificateCreator {
this.executableResolver = executableResolver;
}
private static String buildSubjectArg(CertificateRequest request) {
String certSubject = OPENSSL_CERT_SUBJECT_TEMPLATE.replace("ISO-COUNTRY", request.getSubject()
.getCountry())
.replace("STATE", request.getSubject()
.getState())
.replace("LOCALITY", request.getSubject()
.getLocality())
.replace("ORGANIZATION", request.getSubject()
.getOrganization())
.replace("COMMON-NAME", request.getCommonName());
if (StringUtils.isNotBlank(request.getSubject()
.getOrganizationalUnit())) {
certSubject += "/OU=" + request.getSubject()
.getOrganizationalUnit();
}
if (StringUtils.isNotBlank(request.getSubject()
.getEmailAddress())) {
certSubject += "/emailAddress=" + request.getSubject()
.getEmailAddress();
}
return certSubject;
}
@Nullable
public OpenSSLCertificateResult createCertificate(CertificateRequest request) throws CommandLineOperationException, InterruptedException {
Path tmpDir;
@ -40,6 +66,7 @@ public class OpenSSLCertificateCreator {
}
createKeyfile(request, tmpDir);
createCertificate(request, tmpDir);
return new OpenSSLCertificateResult(tmpDir);
}
@ -70,6 +97,40 @@ public class OpenSSLCertificateCreator {
return keyFile;
}
private Path createCertificate(CertificateRequest request, Path tmpDir) throws CommandLineOperationException, InterruptedException {
Path keyFile = tmpDir.resolve("root.key")
.toAbsolutePath();
Path certFile = tmpDir.resolve("root.crt")
.toAbsolutePath();
LOGGER.atDebug()
.log("Writing new certificate file {}", certFile);
String certSubject = buildSubjectArg(request);
try {
StartedProcess keygenProc = new ProcessExecutor().command(resolveOpenSSL(), "req", "x509", "-new", "-nodes",
"-key", keyFile.toString(), "-sha256", "-days",
Integer.toString(
request.getRequestedValidityDays()),
"-out",
certFile.toString(),
"-passout", "env:KEY_PASS", "-utf8", "-subj",
certSubject)
.environment("KEY_PASS", request.getOid())
.redirectOutput(Slf4jStream.ofCaller()
.asDebug())
.redirectError(Slf4jStream.ofCaller()
.asError())
.start();
keygenProc.getFuture()
.get();
} catch (IOException e) {
throw new CommandLineOperationException("Failure running OpenSSL req command.", e);
} catch (ExecutionException e) {
throw new RuntimeException(e);
}
return certFile;
}
private String resolveOpenSSL() throws CommandLineOperationException {
try {
return executableResolver.getOpenSSLPath();