feat: Implement import of CA bundles to keystores
This commit is contained in:
parent
a4f495ab91
commit
6b1c969ce6
8 changed files with 207 additions and 7 deletions
|
|
@ -7,13 +7,20 @@ import de.mlessmann.certassist.repositories.CertificateRepository;
|
|||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.StreamSupport;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class CertificateCreationService {
|
||||
|
|
@ -21,12 +28,15 @@ public class CertificateCreationService {
|
|||
private final CertificateRepository certificateRepository;
|
||||
private final OpenSSLService openSSLService;
|
||||
private final PassphraseService passphraseService;
|
||||
private final Pattern CERT_START_PATTERN = Pattern.compile("-+BEGIN CERTIFICATE-+");
|
||||
private final Pattern CERT_END_PATTERN = Pattern.compile("-+END CERTIFICATE-+");
|
||||
|
||||
public Certificate createCertificate(final CertificateInfo certificateInfo) {
|
||||
final Certificate certificate = createEntityFromRequest(certificateInfo);
|
||||
|
||||
try (OpenSSLCertificateResult certificateCreatorResult = openSSLService.createCertificate(certificateInfo);) {
|
||||
Path keyPath = certificateCreatorResult.certificateKeyPath();
|
||||
certificate.setFingerprint(certificateCreatorResult.fingerprint());
|
||||
if (keyPath != null) {
|
||||
certificate.setPrivateKey(Files.readAllBytes(keyPath));
|
||||
}
|
||||
|
|
@ -74,6 +84,7 @@ public class CertificateCreationService {
|
|||
String fingerprint = openSSLService.getCertificateFingerprint(certificate);
|
||||
var generatedRequest = openSSLService.getCertificateInfo(certificate);
|
||||
Certificate entity = createEntityFromRequest(generatedRequest);
|
||||
entity.setFingerprint(fingerprint);
|
||||
entity.setCert(Files.readAllBytes(certificate));
|
||||
if (keyFile != null) {
|
||||
entity.setPrivateKey(Files.readAllBytes(keyFile));
|
||||
|
|
@ -87,6 +98,36 @@ public class CertificateCreationService {
|
|||
}
|
||||
}
|
||||
|
||||
public List<Certificate> importCertificateTrustBundle(@NonNull Path bundleFile) {
|
||||
try {
|
||||
Map<String, Certificate> certsInBundle = new HashMap<>();
|
||||
String pemContent = Files.readString(bundleFile);
|
||||
Matcher beginMatcher = CERT_START_PATTERN.matcher(pemContent);
|
||||
|
||||
while (beginMatcher.find()) {
|
||||
int startIdx = beginMatcher.start();
|
||||
Matcher endMatcher = CERT_END_PATTERN.matcher(pemContent);
|
||||
if (!endMatcher.find(startIdx)) {
|
||||
throw new IllegalStateException("Certificate has a startIdx but not an end??");
|
||||
}
|
||||
int endIdx = endMatcher.end();
|
||||
String singleCert = pemContent.substring(startIdx, endIdx);
|
||||
String fingerprint = openSSLService.getCertificateFingerprint(singleCert);
|
||||
var generatedRequest = openSSLService.getCertificateInfo(singleCert);
|
||||
Certificate entity = createEntityFromRequest(generatedRequest);
|
||||
entity.setFingerprint(fingerprint);
|
||||
entity.setCert(singleCert.getBytes());
|
||||
certsInBundle.put(fingerprint, entity);
|
||||
log.debug("Found certificate in bundle at {} to {}: {}", startIdx, endIdx, fingerprint);
|
||||
}
|
||||
|
||||
var saveResult = certificateRepository.saveAll(certsInBundle.values());
|
||||
return StreamSupport.stream(saveResult.spliterator(), false).toList();
|
||||
} catch (CommandLineOperationException | IOException e) {
|
||||
throw new RuntimeException("Unable to import certificate", e);
|
||||
}
|
||||
}
|
||||
|
||||
private CertificateType mapCertificateRequestType(CertificateInfo.RequestType requestType) {
|
||||
return switch (requestType) {
|
||||
case ROOT_AUTHORITY -> CertificateType.ROOT_CA;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue