diff --git a/src/main/java/stirling/software/SPDF/config/Beans.java b/src/main/java/stirling/software/SPDF/config/Beans.java index 814fa653..e6b17a90 100644 --- a/src/main/java/stirling/software/SPDF/config/Beans.java +++ b/src/main/java/stirling/software/SPDF/config/Beans.java @@ -2,10 +2,8 @@ package stirling.software.SPDF.config; import java.util.Locale; -import org.springframework.context.MessageSource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.context.support.ReloadableResourceBundleMessageSource; import org.springframework.web.servlet.LocaleResolver; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @@ -51,16 +49,5 @@ public class Beans implements WebMvcConfigurer { slr.setDefaultLocale(defaultLocale); return slr; } - -// @Bean -// public MessageSource messageSource() { -// ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource(); -// //messageSource.setBasename("classpath:messages"); -// messageSource.setDefaultEncoding("UTF-8"); -// messageSource.setUseCodeAsDefaultMessage(true); -// messageSource.setDefaultLocale(Locale.UK); // setting default locale -// return messageSource; -// } - } diff --git a/src/main/java/stirling/software/SPDF/config/EndpointConfiguration.java b/src/main/java/stirling/software/SPDF/config/EndpointConfiguration.java index a98edbb2..749ae2ac 100644 --- a/src/main/java/stirling/software/SPDF/config/EndpointConfiguration.java +++ b/src/main/java/stirling/software/SPDF/config/EndpointConfiguration.java @@ -1,15 +1,13 @@ package stirling.software.SPDF.config; -import java.util.HashMap; import java.util.HashSet; import java.util.Map; -import java.util.Map.Entry; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; -import org.slf4j.Logger; @Service public class EndpointConfiguration { private static final Logger logger = LoggerFactory.getLogger(EndpointConfiguration.class); diff --git a/src/main/java/stirling/software/SPDF/config/MetricsConfig.java b/src/main/java/stirling/software/SPDF/config/MetricsConfig.java index 928a3868..25d6d8d6 100644 --- a/src/main/java/stirling/software/SPDF/config/MetricsConfig.java +++ b/src/main/java/stirling/software/SPDF/config/MetricsConfig.java @@ -1,12 +1,8 @@ package stirling.software.SPDF.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.stereotype.Component; -import org.springframework.web.filter.OncePerRequestFilter; -import io.micrometer.core.instrument.Counter; import io.micrometer.core.instrument.Meter; -import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.config.MeterFilter; import io.micrometer.core.instrument.config.MeterFilterReply; diff --git a/src/main/java/stirling/software/SPDF/config/MetricsFilter.java b/src/main/java/stirling/software/SPDF/config/MetricsFilter.java index 2407b649..d4f64596 100644 --- a/src/main/java/stirling/software/SPDF/config/MetricsFilter.java +++ b/src/main/java/stirling/software/SPDF/config/MetricsFilter.java @@ -3,15 +3,11 @@ package stirling.software.SPDF.config; import java.io.IOException; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter; import io.micrometer.core.instrument.Counter; -import io.micrometer.core.instrument.Meter; import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.config.MeterFilter; -import io.micrometer.core.instrument.config.MeterFilterReply; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; diff --git a/src/main/java/stirling/software/SPDF/controller/api/other/CompressController.java b/src/main/java/stirling/software/SPDF/controller/api/other/CompressController.java index 0c0ce77f..f410fe14 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/other/CompressController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/other/CompressController.java @@ -5,6 +5,12 @@ import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; + +import javax.imageio.ImageIO; import org.apache.commons.io.FileUtils; import org.apache.pdfbox.cos.COSName; @@ -13,15 +19,6 @@ import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDResources; import org.apache.pdfbox.pdmodel.graphics.PDXObject; import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject; - -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; - -import javax.imageio.ImageIO; -import javax.imageio.stream.MemoryCacheImageOutputStream; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.ResponseEntity; @@ -33,9 +30,9 @@ import org.springframework.web.multipart.MultipartFile; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; import stirling.software.SPDF.utils.PdfUtils; import stirling.software.SPDF.utils.ProcessExecutor; -import io.swagger.v3.oas.annotations.media.Schema; @RestController public class CompressController { diff --git a/src/main/java/stirling/software/SPDF/controller/api/security/CertSignController.java b/src/main/java/stirling/software/SPDF/controller/api/security/CertSignController.java index c6f9b1c6..3c948d19 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/security/CertSignController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/security/CertSignController.java @@ -1,64 +1,53 @@ package stirling.software.SPDF.controller.api.security; +import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; -import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import java.io.InputStreamReader; +import java.security.KeyFactory; import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; import java.security.Principal; import java.security.PrivateKey; import java.security.Security; -import java.security.UnrecoverableKeyException; import java.security.cert.Certificate; -import java.security.cert.CertificateEncodingException; -import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.security.spec.PKCS8EncodedKeySpec; +import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; import java.util.List; -import javax.naming.ldap.LdapName; -import javax.naming.ldap.Rdn; - -import org.apache.pdfbox.pdmodel.PDDocument; -import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature; -import org.apache.pdfbox.pdmodel.interactive.digitalsignature.SignatureInterface; -import org.apache.pdfbox.pdmodel.interactive.digitalsignature.SignatureOptions; -import org.apache.pdfbox.pdmodel.interactive.digitalsignature.visible.PDVisibleSigProperties; -import org.apache.pdfbox.pdmodel.interactive.digitalsignature.visible.PDVisibleSignDesigner; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.io.pem.PemReader; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; -import com.itextpdf.kernel.pdf.*; -import com.itextpdf.signatures.*; +import com.itextpdf.io.font.constants.StandardFonts; +import com.itextpdf.kernel.font.PdfFont; +import com.itextpdf.kernel.font.PdfFontFactory; +import com.itextpdf.kernel.geom.Rectangle; +import com.itextpdf.kernel.pdf.PdfDocument; +import com.itextpdf.kernel.pdf.PdfPage; +import com.itextpdf.kernel.pdf.PdfReader; +import com.itextpdf.kernel.pdf.StampingProperties; +import com.itextpdf.signatures.BouncyCastleDigest; +import com.itextpdf.signatures.DigestAlgorithms; +import com.itextpdf.signatures.IExternalDigest; +import com.itextpdf.signatures.IExternalSignature; +import com.itextpdf.signatures.PdfPKCS7; +import com.itextpdf.signatures.PdfSignatureAppearance; +import com.itextpdf.signatures.PdfSigner; +import com.itextpdf.signatures.PrivateKeySignature; +import com.itextpdf.signatures.SignatureUtil; import stirling.software.SPDF.utils.PdfUtils; - -import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; -import org.springframework.web.multipart.MultipartFile; - -import java.io.*; -import java.security.*; -import java.security.cert.Certificate; -import java.security.cert.CertificateFactory; -import java.security.cert.X509Certificate; - -import com.itextpdf.kernel.geom.Rectangle; @RestController public class CertSignController { @@ -121,6 +110,18 @@ public class CertSignController { } } + Principal principal = cert.getSubjectDN(); + String dn = principal.getName(); + + // Extract the "CN" (Common Name) field from the distinguished name (if it's present) + String cn = null; + for (String part : dn.split(",")) { + if (part.trim().startsWith("CN=")) { + cn = part.trim().substring("CN=".length()); + break; + } + } + // Set up the PDF reader and stamper PdfReader reader = new PdfReader(new ByteArrayInputStream(pdf.getBytes())); ByteArrayOutputStream signedPdf = new ByteArrayOutputStream(); @@ -132,36 +133,48 @@ public class CertSignController { .setLocation("TestLocation"); if (showSignature != null && showSignature) { - // Get the page size - PdfPage page = signer.getDocument().getPage(1); - Rectangle pageSize = page.getPageSize(); + float fontSize = 4; // the font size of the signature + float marginRight = 36; // Margin from the right + float marginBottom = 36; // Margin from the bottom + String signingDate = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss z").format(new Date()); - // Define the size of the signature rectangle - float sigWidth = 200; // adjust this as needed - float sigHeight = 100; // adjust this as needed + // Prepare the text for the digital signature + String layer2Text = String.format("Digitally signed by: %s\nDate: %s\nReason: %s\nLocation: %s", name, signingDate, reason, location); - // Define the margins from the page edges - float marginRight = 36; // adjust this as needed - float marginBottom = 36; // adjust this as needed + // Get the PDF font and measure the width and height of the text block + PdfFont font = PdfFontFactory.createFont(StandardFonts.HELVETICA_BOLD); + float textWidth = Arrays.stream(layer2Text.split("\n")) + .map(line -> font.getWidth(line, fontSize)) + .max(Float::compare) + .orElse(0f); + int numLines = layer2Text.split("\n").length; + float textHeight = numLines * fontSize; + + // Calculate the signature rectangle size + float sigWidth = textWidth + marginRight * 2; + float sigHeight = textHeight + marginBottom * 2; + + // Get the page size + PdfPage page = signer.getDocument().getPage(1); + Rectangle pageSize = page.getPageSize(); + + // Define the position and dimension of the signature field + Rectangle rect = new Rectangle( + pageSize.getRight() - sigWidth - marginRight, + pageSize.getBottom() + marginBottom, + sigWidth, + sigHeight + ); + + // Configure the appearance of the digital signature + appearance.setPageRect(rect) + .setContact(name) + .setPageNumber(pageNumber) + .setReason(reason) + .setLocation(location) + .setReuseAppearance(false) + .setLayer2Text(layer2Text); - // Define the position and dimension of the signature field - Rectangle rect = new Rectangle( - pageSize.getRight() - sigWidth - marginRight, - pageSize.getBottom() + marginBottom, - sigWidth, - sigHeight - ); - - // Creating the appearance - appearance - .setPageRect(rect) - .setPageNumber(pageNumber) - .setReason(reason) - .setLocation(location) - .setLayer2Text(name) // Set the signer name to be displayed in the signature field - .setReuseAppearance(false); - signer.setFieldName("sig"); - signer.setFieldName("sig"); } else { appearance.setRenderingMode(PdfSignatureAppearance.RenderingMode.DESCRIPTION); diff --git a/src/main/java/stirling/software/SPDF/controller/api/security/PasswordController.java b/src/main/java/stirling/software/SPDF/controller/api/security/PasswordController.java index 1872d6eb..585e41f3 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/security/PasswordController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/security/PasswordController.java @@ -16,8 +16,8 @@ import org.springframework.web.multipart.MultipartFile; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; -import stirling.software.SPDF.utils.PdfUtils; import io.swagger.v3.oas.annotations.media.Schema; +import stirling.software.SPDF.utils.PdfUtils; @RestController public class PasswordController { diff --git a/src/main/java/stirling/software/SPDF/controller/web/MetricsController.java b/src/main/java/stirling/software/SPDF/controller/web/MetricsController.java index 97d6db93..de73f9e2 100644 --- a/src/main/java/stirling/software/SPDF/controller/web/MetricsController.java +++ b/src/main/java/stirling/software/SPDF/controller/web/MetricsController.java @@ -1,9 +1,4 @@ package stirling.software.SPDF.controller.web; -import io.micrometer.core.instrument.Counter; -import io.micrometer.core.instrument.Meter; -import io.micrometer.core.instrument.MeterRegistry; -import io.swagger.v3.oas.annotations.Operation; - import java.util.HashMap; import java.util.Map; import java.util.Optional; @@ -13,6 +8,11 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import io.micrometer.core.instrument.Counter; +import io.micrometer.core.instrument.Meter; +import io.micrometer.core.instrument.MeterRegistry; +import io.swagger.v3.oas.annotations.Operation; + @RestController @RequestMapping("/api/v1") public class MetricsController { diff --git a/src/main/java/stirling/software/SPDF/utils/PdfUtils.java b/src/main/java/stirling/software/SPDF/utils/PdfUtils.java index 2787363d..337e0335 100644 --- a/src/main/java/stirling/software/SPDF/utils/PdfUtils.java +++ b/src/main/java/stirling/software/SPDF/utils/PdfUtils.java @@ -2,8 +2,6 @@ package stirling.software.SPDF.utils; import java.awt.Graphics; import java.awt.image.BufferedImage; -import java.awt.image.BufferedImageOp; -import java.awt.image.ColorConvertOp; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; @@ -22,7 +20,6 @@ import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.Locale; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream;