Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package stirling.software.SPDF.controller.api.security;

import java.awt.*;
import java.beans.PropertyEditorSupport;
import java.io.*;
import java.nio.file.Files;
import java.security.*;
Expand Down Expand Up @@ -53,7 +54,10 @@
import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo;
import org.bouncycastle.pkcs.PKCSException;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
Expand Down Expand Up @@ -82,6 +86,18 @@ public class CertSignController {
Security.addProvider(new BouncyCastleProvider());
}

@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(
MultipartFile.class,
new PropertyEditorSupport() {
@Override
public void setAsText(String text) throws IllegalArgumentException {
setValue(null);
}
});
}

private final CustomPDFDocumentFactory pdfDocumentFactory;

private static void sign(
Expand All @@ -103,8 +119,7 @@ private static void sign(
signature.setLocation(location);
signature.setReason(reason);
signature.setSignDate(Calendar.getInstance());

if (showSignature) {
if (Boolean.TRUE.equals(showSignature)) {
SignatureOptions signatureOptions = new SignatureOptions();
signatureOptions.setVisualSignature(
instance.createVisibleSignature(doc, signature, pageNumber, showLogo));
Expand All @@ -121,13 +136,18 @@ private static void sign(
}
}

@PostMapping(consumes = "multipart/form-data", value = "/cert-sign")
@PostMapping(
consumes = {
MediaType.MULTIPART_FORM_DATA_VALUE,
MediaType.APPLICATION_FORM_URLENCODED_VALUE
},
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")
+ " 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();
Expand All @@ -137,12 +157,13 @@ public ResponseEntity<byte[]> signPDFWithCert(@ModelAttribute SignPDFWithCertReq
MultipartFile p12File = request.getP12File();
MultipartFile jksfile = request.getJksFile();
String password = request.getPassword();
Boolean showSignature = request.isShowSignature();
Boolean showSignature = request.getShowSignature();
String reason = request.getReason();
String location = request.getLocation();
String name = request.getName();
Integer pageNumber = request.getPageNumber() - 1;
Boolean showLogo = request.isShowLogo();
// Convert 1-indexed page number (user input) to 0-indexed page number (API requirement)
Integer pageNumber = request.getPageNumber() != null ? (request.getPageNumber() - 1) : null;
Boolean showLogo = request.getShowLogo();

if (certType == null) {
throw new IllegalArgumentException("Cert type must be provided");
Expand Down Expand Up @@ -279,7 +300,7 @@ public InputStream createVisibleSignature(
widget.setAppearance(appearance);

try (PDPageContentStream cs = new PDPageContentStream(doc, appearanceStream)) {
if (showLogo) {
if (Boolean.TRUE.equals(showLogo)) {
cs.saveGraphicsState();
PDExtendedGraphicsState extState = new PDExtendedGraphicsState();
extState.setBlendMode(BlendMode.MULTIPLY);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ public class SignPDFWithCertRequest extends PDFFile {

@Schema(
description =
"The private key for the digital certificate (required for PEM type certificates)")
"The private key for the digital certificate (required for PEM type"
+ " certificates)")
private MultipartFile privateKeyFile;

@Schema(description = "The digital certificate (required for PEM type certificates)")
Expand All @@ -32,11 +33,11 @@ public class SignPDFWithCertRequest extends PDFFile {
@Schema(description = "The JKS keystore file (Java Key Store)")
private MultipartFile jksFile;

@Schema(description = "The password for the keystore or the private key")
@Schema(description = "The password for the keystore or the private key", format = "password")
private String password;

@Schema(description = "Whether to visually show the signature in the PDF file")
private boolean showSignature;
private Boolean showSignature;

@Schema(description = "The reason for signing the PDF")
private String reason;
Expand All @@ -49,9 +50,10 @@ public class SignPDFWithCertRequest extends PDFFile {

@Schema(
description =
"The page number where the signature should be visible. This is required if showSignature is set to true")
"The page number where the signature should be visible. This is required if"
+ " showSignature is set to true")
private Integer pageNumber;

@Schema(description = "Whether to visually show a signature logo along with the signature")
private boolean showLogo;
private Boolean showLogo;
}
Loading