Feature/save signs (#2127)
* apply fix * Fixes empty th:action * Update build.gradle * fix * formatting * Save signatures * Fix code scanning alert no. 42: Uncontrolled data used in path expression Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> * fix UserServiceInterface * Merge branch 'feature/saveSigns' of git@github.com:Stirling-Tools/Stirling-PDF.git into feature/saveSigns * 0.31.0 bump and further csrf * formatting * preview name * add * sign doc * Update translation files (#2128) Signed-off-by: GitHub Action <action@github.com> Co-authored-by: GitHub Action <action@github.com> --------- Signed-off-by: GitHub Action <action@github.com> Co-authored-by: Dimitrios Kaitantzidis <james_k23@hotmail.gr> Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> Co-authored-by: a <a> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: GitHub Action <action@github.com>
This commit is contained in:
@@ -96,17 +96,18 @@ public class CertSignController {
|
||||
|
||||
public CreateSignature(KeyStore keystore, char[] pin)
|
||||
throws KeyStoreException,
|
||||
UnrecoverableKeyException,
|
||||
NoSuchAlgorithmException,
|
||||
IOException,
|
||||
CertificateException {
|
||||
UnrecoverableKeyException,
|
||||
NoSuchAlgorithmException,
|
||||
IOException,
|
||||
CertificateException {
|
||||
super(keystore, pin);
|
||||
ClassPathResource resource = new ClassPathResource("static/images/signature.png");
|
||||
imageFile = resource.getFile();
|
||||
}
|
||||
|
||||
public InputStream createVisibleSignature(PDDocument srcDoc, PDSignature signature, Integer pageNumber,
|
||||
Boolean showImage) throws IOException {
|
||||
public InputStream createVisibleSignature(
|
||||
PDDocument srcDoc, PDSignature signature, Integer pageNumber, Boolean showImage)
|
||||
throws IOException {
|
||||
// modified from org.apache.pdfbox.examples.signature.CreateVisibleSignature2
|
||||
try (PDDocument doc = new PDDocument()) {
|
||||
PDPage page = new PDPage(srcDoc.getPage(pageNumber).getMediaBox());
|
||||
@@ -151,8 +152,8 @@ public class CertSignController {
|
||||
extState.setNonStrokingAlphaConstant(0.5f);
|
||||
cs.setGraphicsStateParameters(extState);
|
||||
cs.transform(Matrix.getScaleInstance(0.08f, 0.08f));
|
||||
PDImageXObject img = PDImageXObject.createFromFileByExtension(imageFile,
|
||||
doc);
|
||||
PDImageXObject img =
|
||||
PDImageXObject.createFromFileByExtension(imageFile, doc);
|
||||
cs.drawImage(img, 100, 0);
|
||||
cs.restoreGraphicsState();
|
||||
}
|
||||
@@ -200,7 +201,10 @@ public class CertSignController {
|
||||
}
|
||||
|
||||
@PostMapping(consumes = "multipart/form-data", value = "/cert-sign")
|
||||
@Operation(summary = "Sign PDF with a Digital Certificate", description = "This endpoint accepts a PDF file, a digital certificate and related information to sign the PDF. It then returns the digitally signed PDF file. Input:PDF Output:PDF Type:SISO")
|
||||
@Operation(
|
||||
summary = "Sign PDF with a Digital Certificate",
|
||||
description =
|
||||
"This endpoint accepts a PDF file, a digital certificate and related information to sign the PDF. It then returns the digitally signed PDF file. Input:PDF Output:PDF Type:SISO")
|
||||
public ResponseEntity<byte[]> signPDFWithCert(@ModelAttribute SignPDFWithCertRequest request)
|
||||
throws Exception {
|
||||
MultipartFile pdf = request.getFileInput();
|
||||
@@ -229,7 +233,7 @@ public class CertSignController {
|
||||
PrivateKey privateKey = getPrivateKeyFromPEM(privateKeyFile.getBytes(), password);
|
||||
Certificate cert = (Certificate) getCertificateFromPEM(certFile.getBytes());
|
||||
ks.setKeyEntry(
|
||||
"alias", privateKey, password.toCharArray(), new Certificate[] { cert });
|
||||
"alias", privateKey, password.toCharArray(), new Certificate[] {cert});
|
||||
break;
|
||||
case "PKCS12":
|
||||
ks = KeyStore.getInstance("PKCS12");
|
||||
@@ -245,7 +249,15 @@ public class CertSignController {
|
||||
|
||||
CreateSignature createSignature = new CreateSignature(ks, password.toCharArray());
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
sign(pdfDocumentFactory, pdf.getBytes(), baos, createSignature, showSignature, pageNumber, name, location,
|
||||
sign(
|
||||
pdfDocumentFactory,
|
||||
pdf.getBytes(),
|
||||
baos,
|
||||
createSignature,
|
||||
showSignature,
|
||||
pageNumber,
|
||||
name,
|
||||
location,
|
||||
reason);
|
||||
return WebResponseUtils.boasToWebResponse(
|
||||
baos,
|
||||
@@ -274,8 +286,8 @@ public class CertSignController {
|
||||
|
||||
if (showSignature) {
|
||||
SignatureOptions signatureOptions = new SignatureOptions();
|
||||
signatureOptions
|
||||
.setVisualSignature(instance.createVisibleSignature(doc, signature, pageNumber, true));
|
||||
signatureOptions.setVisualSignature(
|
||||
instance.createVisibleSignature(doc, signature, pageNumber, true));
|
||||
signatureOptions.setPage(pageNumber);
|
||||
|
||||
doc.addSignature(signature, instance, signatureOptions);
|
||||
@@ -291,19 +303,22 @@ public class CertSignController {
|
||||
|
||||
private PrivateKey getPrivateKeyFromPEM(byte[] pemBytes, String password)
|
||||
throws IOException, OperatorCreationException, PKCSException {
|
||||
try (PEMParser pemParser = new PEMParser(new InputStreamReader(new ByteArrayInputStream(pemBytes)))) {
|
||||
try (PEMParser pemParser =
|
||||
new PEMParser(new InputStreamReader(new ByteArrayInputStream(pemBytes)))) {
|
||||
Object pemObject = pemParser.readObject();
|
||||
JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
|
||||
PrivateKeyInfo pkInfo;
|
||||
if (pemObject instanceof PKCS8EncryptedPrivateKeyInfo) {
|
||||
InputDecryptorProvider decProv = new JceOpenSSLPKCS8DecryptorProviderBuilder()
|
||||
.build(password.toCharArray());
|
||||
InputDecryptorProvider decProv =
|
||||
new JceOpenSSLPKCS8DecryptorProviderBuilder().build(password.toCharArray());
|
||||
pkInfo = ((PKCS8EncryptedPrivateKeyInfo) pemObject).decryptPrivateKeyInfo(decProv);
|
||||
} else if (pemObject instanceof PEMEncryptedKeyPair) {
|
||||
PEMDecryptorProvider decProv = new JcePEMDecryptorProviderBuilder().build(password.toCharArray());
|
||||
pkInfo = ((PEMEncryptedKeyPair) pemObject)
|
||||
.decryptKeyPair(decProv)
|
||||
.getPrivateKeyInfo();
|
||||
PEMDecryptorProvider decProv =
|
||||
new JcePEMDecryptorProviderBuilder().build(password.toCharArray());
|
||||
pkInfo =
|
||||
((PEMEncryptedKeyPair) pemObject)
|
||||
.decryptKeyPair(decProv)
|
||||
.getPrivateKeyInfo();
|
||||
} else {
|
||||
pkInfo = ((PEMKeyPair) pemObject).getPrivateKeyInfo();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user