feat(security): add PFX alias for PKCS12; accept .crt/.cer/.der certs & .key keys; add certificate-signing tests (#4297)

This commit is contained in:
Ludy
2025-09-04 15:30:32 +01:00
committed by GitHub
parent 0d7649bee8
commit 02d096d622
14 changed files with 476 additions and 6 deletions
@@ -186,6 +186,7 @@ public class CertSignController {
"alias", privateKey, password.toCharArray(), new Certificate[] {cert});
break;
case "PKCS12":
case "PFX":
ks = KeyStore.getInstance("PKCS12");
ks.load(p12File.getInputStream(), password.toCharArray());
break;
@@ -15,20 +15,25 @@ public class SignPDFWithCertRequest extends PDFFile {
@Schema(
description = "The type of the digital certificate",
allowableValues = {"PEM", "PKCS12", "JKS"},
allowableValues = {"PEM", "PKCS12", "PFX", "JKS"},
requiredMode = Schema.RequiredMode.REQUIRED)
private String certType;
@Schema(
description =
"The private key for the digital certificate (required for PEM type"
+ " certificates)")
+ " certificates, supports .pem, .der, or .key files)")
private MultipartFile privateKeyFile;
@Schema(description = "The digital certificate (required for PEM type certificates)")
@Schema(
description =
"The digital certificate (required for PEM type certificates, supports"
+ " .pem, .der, .crt, or .cer files)")
private MultipartFile certFile;
@Schema(description = "The PKCS12 keystore file (required for PKCS12 type certificates)")
@Schema(
description =
"The PKCS12/PFX keystore file (required for PKCS12 or PFX type certificates)")
private MultipartFile p12File;
@Schema(description = "The JKS keystore file (Java Key Store)")
@@ -31,17 +31,18 @@
<option value="" th:text="#{selectFilter}"></option>
<option value="PEM">PEM</option>
<option value="PKCS12">PKCS12</option>
<option value="PFX">PFX</option>
<option value="JKS">JKS</option>
</select>
</div>
<div id="pemGroup" style="display: none;">
<div class="mb-3">
<label th:text="#{certSign.selectKey}"></label>
<div th:replace="~{fragments/common :: fileSelector(name='privateKeyFile', multipleInputsForSingleRequest=false, notRequired=true, accept='.pem,.der')}"></div>
<div th:replace="~{fragments/common :: fileSelector(name='privateKeyFile', multipleInputsForSingleRequest=false, notRequired=true, accept='.pem,.der,.key')}"></div>
</div>
<div class="mb-3">
<label th:text="#{certSign.selectCert}"></label>
<div th:replace="~{fragments/common :: fileSelector(name='certFile', multipleInputsForSingleRequest=false, notRequired=true, accept='.pem,.der')}"></div>
<div th:replace="~{fragments/common :: fileSelector(name='certFile', multipleInputsForSingleRequest=false, notRequired=true, accept='.pem,.der,.crt,.cer')}"></div>
</div>
</div>
<div class="mb-3" id="p12Group" style="display: none;">
@@ -96,6 +97,7 @@
var valueToGroupMap = {
'PEM': pemGroup,
'PKCS12': p12Group,
'PFX': p12Group,
'JKS': jksGroup
};
for (var key in valueToGroupMap) {