Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
import java.io.File
import java.time.Instant
import java.sql.Timestamp
import java.util._
import java.security.KeyStore.PasswordProtection
import java.security.spec.DSAParameterSpec
import java.math.BigInteger
import org.slf4j.LoggerFactory
import eu.europa.esig.dss.enumerations._
import eu.europa.esig.dss.validation.CommonCertificateVerifier
import eu.europa.esig.dss.model.x509.CertificateToken
import eu.europa.esig.dss.model._
import eu.europa.esig.dss.pades._
import eu.europa.esig.dss.pades.signature.PAdESService
import eu.europa.esig.dss.token._
import eu.europa.esig.dss.spi.x509.CommonCertificateSource
import com.fts.cp.esign.utils.{Configuration, Utils, SignatureType}
import com.fts.cp.esign.grpc._
import com.fts.cp.esign.exceptions.DSRException
import com.fts.cp.esign.storage.azblob.CAFilesDAO
import com.fts.cp.esign.model.{SignActionResponse, VisualSignatureDimensions}
@throws(classOf[DSRException])
def signPDF(
dsr: DSR,
idres: IDRes,
fileToSign: File,
oc: com.fts.cp.esign.model.OperationalContext,
sr: com.fts.cp.esign.grpc.SignatureRequest,
dsc: String
): Option[SignActionResponse] = {
import collection.JavaConverters._
var result: Option[SignActionResponse] = None
var pfxPath: String = "" // to be populated later
try{
// Conversion to DSS File
val docToSign: FileDocument = new FileDocument(fileToSign)
val parameters: PAdESSignatureParameters = new PAdESSignatureParameters()
// Some types of signatures have to be visual
val makeVisual: Boolean = if(
!sr.`type`.equalsIgnoreCase(SignatureType.RELEASE) &&
!sr.`type`.equalsIgnoreCase(SignatureType.ETERMS) &&
!sr.`type`.equalsIgnoreCase(SignatureType.CERTIFICATEDOCUMENT) &&
sr.representation &&
!sr.visualRepresentation.get.fieldId.isEmpty
) true else false
val reference = idres.userId.get.piiid + idres.userId.get.entityId
// Get the Digital Identity from our Identity Manager
val (certToken: CertificateToken, path: String, password: String) = SignatureUtils.getIDItemsFromIDPack(reference, idres.pack.get)
pfxPath = path
// Set a password protection for the Pkcs12 Signature Token
val a = BigInteger.valueOf(passwordParam1)
val b = BigInteger.valueOf(passwordParam2)
val c = BigInteger.valueOf(passwordParam3)
val pp = new PasswordProtection(password.toCharArray(), encryptionAlg, new DSAParameterSpec(a, b, c))
val signatureToken: Pkcs12SignatureToken = new Pkcs12SignatureToken(pfxPath, pp)
val privateKey: DSSPrivateKeyEntry = signatureToken.getKeys.get(0)
val keys: List[DSSPrivateKeyEntry] = signatureToken.getKeys()
//parameters.setSigningCertificate(certToken) // OR..
parameters.setSigningCertificate(keys.get(0).getCertificate)
/*
PaDES Signature level. E.g. LTA: Long Term
You can get this parameter from the Digital Signatrue Request or from teh Configuration
*/
parameters.setSignatureLevel(SignatureLevel.PAdES_BASELINE_LT)
// Configure the rest of the signature process
parameters.setDigestAlgorithm(DigestAlgorithm.valueOf(digestAlg))
parameters.setSignaturePackaging(SignaturePackaging.valueOf(packagingType))
parameters.setCertificateChain(keys.get(0).getCertificateChain.toList.asJava)
parameters.setEncryptionAlgorithm(EncryptionAlgorithm.valueOf(encryptionAlg))
parameters.bLevel.setSigningDate(Date.from(Instant.now))
parameters.setSignatureSize(signSize * 2) // bytes
if (makeVisual) {
parameters.setSignatureFieldId(sr.visualRepresentation.get.fieldId)
}
// The DSS Certificate Verifier allows you to add whay you need to ensure ther certificate is validated properly
val commonCertificateVerifier: CommonCertificateVerifier = new CommonCertificateVerifier()
commonCertificateVerifier.setTrustedCertSource(new CommonCertificateSource())
commonCertificateVerifier.setDataLoader(SignatureUtils.getDataLoader())
commonCertificateVerifier.setCrlSource(SignatureUtils.getCRLSource())
commonCertificateVerifier.setOcspSource(SignatureUtils.getOcspDataSource())
// The Timestamp authority can be public and online or private with restricted access
val service: PAdESService = new PAdESService(commonCertificateVerifier)
service.setTspSource(SignatureUtils.getOnlineTSP())
// Get timestamp for the signature
val tsToken = service.getContentTimestamp(docToSign, parameters)
val signatureDate = tsToken.getGenerationTime
val signatureTS: Timestamp = new Timestamp(signatureDate.getTime())
if (makeVisual) {
val dimensions = new VisualSignatureDimensions(sr.visualRepresentation.get.fieldId, 0, 0, 0, sr.visualRepresentation.get.width, sr.visualRepresentation.get.length)
parameters.setSignatureImageParameters(SignatureUtils.getVisualSignatureParams(dsr, idres, oc, dsc, signatureTS.toString, certToken.getSubjectX500Principal.toString, dimensions))
}
certToken.getSubjectX500Principal
val dataToSign: ToBeSigned = service.getDataToSign(docToSign, parameters)
val digestAlgorithm: DigestAlgorithm = parameters.getDigestAlgorithm()
// Yes, at last this action signs the document
val signatureValue: SignatureValue = signatureToken.sign(dataToSign, digestAlgorithm, privateKey)
result = Some(new SignActionResponse(
service.signDocument(docToSign, parameters, signatureValue),
signatureTS,
certToken.getSubjectX500Principal.toString
))
// Delete the password protection as it is not needed anymore
pp.destroy()
}catch{
case e: Exception => {
val msg = s"Error in DSS Signature process - Reason: ${e}"
logger.error(msg)
throw new DSRException(msg)
}
}
// Clean up temporary files from the file system
Utils.cleanUp()
result
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.