Removal of Ghostscript to use qpdf and tesseract directly (#2338)

* navbar fix multi tool and compress location

* release notes and ghostscript removal

* cleanups

* formatting

* update docs

* more

* more

* docs

* release bump

* Hardening suggestions for Stirling-PDF / ghostscript (#2339)

* Protect `readLine()` against DoS

* Sanitized user-provided file names in HTTP multipart uploads

---------

Co-authored-by: pixeebot[bot] <104101892+pixeebot[bot]@users.noreply.github.com>

---------

Co-authored-by: pixeebot[bot] <104101892+pixeebot[bot]@users.noreply.github.com>
This commit is contained in:
Anthony Stirling
2024-11-26 20:50:35 +00:00
committed by GitHub
co-authored by pixeebot[bot] <104101892+pixeebot[bot]@users.noreply.github.com>
parent 654bc94d44
commit 833b3c45c6
69 changed files with 1106 additions and 665 deletions
@@ -98,10 +98,10 @@ 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");
try (InputStream is = resource.getInputStream()) {
@@ -160,7 +160,8 @@ public class CertSignController {
extState.setNonStrokingAlphaConstant(0.5f);
cs.setGraphicsStateParameters(extState);
cs.transform(Matrix.getScaleInstance(0.08f, 0.08f));
PDImageXObject img = PDImageXObject.createFromFileByExtension(logoFile, doc);
PDImageXObject img =
PDImageXObject.createFromFileByExtension(logoFile, doc);
cs.drawImage(img, 100, 0);
cs.restoreGraphicsState();
}
@@ -208,7 +209,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();
@@ -238,7 +242,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");
@@ -310,19 +314,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();
}