ENI (7) ENI Expedient for Sedipualba: Signing content
0. Introduction
In a previous post we saw how to create the "Expediente" in ENI format. But the signature of the content was not accepted by Valide
After analyzing the ENI format of the "Expedient" generated in Sedipualba that has no problem with Valide there are some differences in the signature:
- Sedipualba uses the TF03 signatures format (XAdES Enveloped)
- Sedipualba does not use the binary FirmaBase64 field. Sedipualba uses ds:Signature field instead.
- Marshall the content("indice.indiceContenido" attribute) of the "Expedient" into an XML file (for instance contenidoYEAR.xml where YEAR is the year of the resolutions for instance 2022).
- Use Autofirma and sign the previous XML file in XAdES Enveloped format
- Get the "xadesEnveloped.xsd" schema from this URL from Liquid Technologies and adapt the schema
- Get the class eni.xades.enveloped.IndiceContenido
- Unmarshall the signature obtained by Autofirma into the previous class and extract the Signature class.
- Assign this Signature class to the nested attribute "indice.firmas.firma.contenidoFirma.firmaConCertificado.signature" of the class "TipoExpediente"
- Marshall the "Expediente" object whose class is "TipoExpediente"
1. Marshalling the "indice.indiceContenido" field
We need a class for marshalling and unmarshalling. This class uses these dependencies:
'javax.xml.bind:jaxb-api:2.4.0-b180830.0359'
'org.glassfish:javax.xml.bind:10.0-b28
1.1 A Marshalling utility class JAXBEduImp.class
package openadmin.utils.jaxb; import javax.xml.XMLConstants; import javax.xml.transform.stream.StreamSource; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; import javax.xml.validation.Validator; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.StringReader; import java.io.StringWriter; import org.apache.commons.io.IOUtils; import org.xml.sax.SAXException; import jakarta.xml.bind.JAXBContext; import jakarta.xml.bind.JAXBElement; import jakarta.xml.bind.JAXBException; import jakarta.xml.bind.Marshaller; import jakarta.xml.bind.Unmarshaller; import openadmin.utils.jackson.IJacksonEdu; public class JAXBEduImp implements IJacksonEdu{ public JAXBEduImp() { } public Marshaller getMarshaller(Class myClass) throws JAXBException { JAXBContext context = JAXBContext.newInstance(myClass); Marshaller m = context.createMarshaller(); m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); return m; } public Unmarshaller getUnmarshaller(Class myClass) throws JAXBException { JAXBContext context = JAXBContext.newInstance(myClass); Unmarshaller jaxbUnmarshaller = context.createUnmarshaller(); return jaxbUnmarshaller; } public String ObjectToString (Object obj) throws Exception { Marshaller m = getMarshaller(obj.getClass()); StringWriter sw = new StringWriter(); m.marshal(obj, sw); String result = sw.toString(); return result; } public void ObjectToFile (Object obj, String fileName) throws Exception { Marshaller m = getMarshaller(obj.getClass()); m.marshal(obj, new FileOutputStream(fileName)); } public StringWriter ObjectToStringWriter (Object obj) throws Exception { Marshaller m = getMarshaller(obj.getClass()); StringWriter sw = new StringWriter(); m.marshal(obj, sw); return sw; } public InputStream ObjectToIputStream(Object obj) throws Exception { return IOUtils.toInputStream(this.ObjectToString(obj), "UTF-8"); } public <T extends Object> T InputStreamToObject(InputStream in, Class<T> valueType) throws Exception { Unmarshaller unM = getUnmarshaller(valueType); T obj = (T) unM.unmarshal(in); return obj; //JAXBElement<T> root = (JAXBElement<T>) unM.unmarshal(in); //return root.getValue(); } public <T extends Object> T StringToObject (String content, Class<T> valueType) throws Exception { Unmarshaller unM = getUnmarshaller(valueType); StringReader reader = new StringReader(content); T obj = (T) unM.unmarshal(reader); return obj; //JAXBElement<T> root = (JAXBElement<T>) unM.unmarshal(reader); //return root.getValue(); } public <T extends Object> T ByteArrayToObject (byte[] content, Class<T> valueType) throws Exception{ Unmarshaller unM = getUnmarshaller(valueType); InputStream inStrm = new ByteArrayInputStream(content); T obj = (T) unM.unmarshal(inStrm); return obj; //JAXBElement<T> root = (JAXBElement<T>) unM.unmarshal(inStrm); //return root.getValue(); } public <T extends Object> T FileToObject (File src, Class<T> valueType) throws Exception { Unmarshaller unM = getUnmarshaller(valueType); //T obj= (T) unM.unmarshal(src); //Peta!! //return obj; JAXBElement<T> root = (JAXBElement<T>) unM.unmarshal(src); return root.getValue(); } public <T extends Object> T FileToObject (InputStream src, Class<T> valueType) throws Exception { Unmarshaller unM = getUnmarshaller(valueType); T obj = (T) unM.unmarshal(src); return obj; //T obj= (T) unM.unmarshal(src); //return obj; } /** * * @param xmlFile * @param schemaFile is relative from resource folder * @return */ public boolean validateXML(String xmlFile, String schemaFile) { SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); Schema schema = null; try { try { schema = schemaFactory.newSchema( new File(Thread.currentThread().getContextClassLoader().getResource(schemaFile).getPath())); } catch (Exception e1) { schema = schemaFactory.newSchema(new File(schemaFile)); } Validator validator = schema.newValidator(); validator.validate(new StreamSource(new File(xmlFile))); return true; } catch (SAXException | IOException e) { e.printStackTrace(); return false; } } public static void main (String[] args) { boolean ok= new JAXBEduImp().validateXML( "/mnt/NASDADES_DOCS/X19-DOCS-ESSENCIALS/LlibreDecrets/ENI2019/0ES_L01462384_2019_EXP_LLIBRE_RESOLUCIONS.ENI.xml", "/home/eduard/WORKSPACES/WS_GRDL05/Ajuntament/A10-xsd2Pojo/src/main/resources/xsd/expedienteEni.xsd"); /* boolean ok= new JAXBEduImp().validateXML( "/home/eduard/SEGRA2022/0ES_L01462384_2022_EXP_LLIBRE_RESOLUCIONS.ENI.xml", "/home/eduard/WORKSPACES/WS_GRDL05/Ajuntament/A10-xsd2Pojo/src/main/resources/xsd/expedienteEni.xsd"); boolean ok= new JAXBEduImp().validateXML("/home/eduard/DOCUMENTACIO/INSIDE/DECRETS_SENSE_EXPEDIENT/ES_L01462384_2023_EXP_1355414W_638136030389984806/ES_L01462384_2023_EXP_1355414W.xml", "/home/eduard/WORKSPACES/WS_GRDL05/Ajuntament/A10-xsd2Pojo/src/main/resources/xsd/TipoExpedienteInsideConMAdicionales.xsd"); boolean ok= new JAXBEduImp().validateXML("/home/eduard/SEGRA2022/ES_L01462384_2022_DOC_RESOLUCIO_00005_17557433.xml", "/home/eduard/WORKSPACES/WS_GRDL05/Ajuntament/A10-xsd2Pojo/src/main/resources/xsd/documentoEni.xsd"); ok= new JAXBEduImp().validateXML("/home/eduard/prova_decrets/V1/2021/0ES_L01462384_2021_EXP_LLIBRE_RESOLUCIONS.ENI.xml", "/home/eduard/WORKSPACES/WS_GRDL01/Ajuntament/A10-xsd2Pojo/src/main/resources/xsd/expedienteEni.xsd"); boolean ok= new JAXBEduImp().validateXML("/home/eduard/prova_decrets/V1/2021/ES_L01462384_2021_DOC_RESOLUCIO_0005_ENI.xml", "/home/eduard/WORKSPACES/WS_GRDL01/Ajuntament/A10-xsd2Pojo/src/main/resources/xsd/documentoEni.xsd"); boolean ok1= new JAXBEduImp().validateXML("/home/eduard/Baixades/ES_L01462384_2022_DOC_12473165_0000_Pressupostampl.xml", "/home/eduard/WORKSPACES/WS_GRDL01/Ajuntament/A10-xsd2Pojo/src/main/resources/xsd/documentoEni.xsd"); */ if (ok) System.out.println("OK"); else System.out.println("ERROR!"); } }
1.2 Marshalling its "indice.indiceContenido" attribute from TIpoExpediente class
JAXBEduImp xmlMapper= new JAXBEduImp(); String expContenidoFileName=outputFolder+"/contenido"+YEAR+".xml"; xmlMapper.ObjectToFile(expENI.getIndice().getIndiceContenido(),expContenidoFileName );
2. Signing the content with Autofirma using XAdES enveloped
3. Getting the xadesEnveloped.xsd schema from LiquidTechmologies URL
<xs:import schemaLocation="schema1.xsd" namespace="http://www.w3.org/2000/09/xmldsig#" />
<xs:import schemaLocation="xmldsig-core-schema.xsd" namespace="http://www.w3.org/2000/09/xmldsig#" />
3.1 xadesEnveloped.xml
<?xml version="1.0" encoding="utf-8"?> <!-- Created with Liquid Technologies Online Tools 1.0 (https://www.liquid-technologies.com) --> <xs:schema xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xades="http://uri.etsi.org/01903/v1.3.2#" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://administracionelectronica.gob.es/ENI/XSD/v1.0/expediente-e/indice-e/contenido" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <!-- <xs:import schemaLocation="schema1.xsd" namespace="http://www.w3.org/2000/09/xmldsig#" />--> <xs:import schemaLocation="xmldsig-core-schema.xsd" namespace="http://www.w3.org/2000/09/xmldsig#" /> <xs:element name="IndiceContenido"> <xs:complexType> <xs:sequence> <xs:element name="FechaIndiceElectronico" type="xs:dateTime" /> <xs:element maxOccurs="unbounded" name="DocumentoIndizado"> <xs:complexType> <xs:sequence> <xs:element name="IdentificadorDocumento" type="xs:string" /> <xs:element name="ValorHuella" type="xs:string" /> <xs:element name="FuncionResumen" type="xs:string" /> <xs:element name="FechaIncorporacionExpediente" type="xs:dateTime" /> <xs:element name="OrdenDocumentoExpediente" type="xs:unsignedByte" /> </xs:sequence> <xs:attribute name="Id" type="xs:string" use="required" /> </xs:complexType> </xs:element> <xs:element ref="ds:Signature" /> </xs:sequence> <xs:attribute name="Id" type="xs:string" use="required" /> </xs:complexType> </xs:element> </xs:schema>
3.2 xxmldsig-core-schema.xsd
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE schema PUBLIC "-//W3C//DTD XMLSchema 200102//EN" "http://www.w3.org/2001/XMLSchema.dtd" [ <!ATTLIST schema xmlns:ds CDATA #FIXED "http://www.w3.org/2000/09/xmldsig#"> <!ENTITY dsig 'http://www.w3.org/2000/09/xmldsig#'> <!ENTITY % p ''> <!ENTITY % s ''> ]> <!-- Schema for XML Signatures http://www.w3.org/2000/09/xmldsig# $Revision: 1.2 $ on $Date: 2013-04-16 12:48:49 $ by $Author: denis $ Copyright 2001 The Internet Society and W3C (Massachusetts Institute of Technology, Institut National de Recherche en Informatique et en Automatique, Keio University). All Rights Reserved. http://www.w3.org/Consortium/Legal/ This document is governed by the W3C Software License [1] as described in the FAQ [2]. [1] http://www.w3.org/Consortium/Legal/copyright-software-19980720 [2] http://www.w3.org/Consortium/Legal/IPR-FAQ-20000620.html#DTD --> <schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" targetNamespace="http://www.w3.org/2000/09/xmldsig#" version="0.1" elementFormDefault="qualified"> <!-- Basic Types Defined for Signatures --> <simpleType name="CryptoBinary"> <restriction base="base64Binary"> </restriction> </simpleType> <!-- Start Signature --> <element name="Signature" type="ds:SignatureType"/> <complexType name="SignatureType"> <sequence> <element ref="ds:SignedInfo"/> <element ref="ds:SignatureValue"/> <element ref="ds:KeyInfo" minOccurs="0"/> <element ref="ds:Object" minOccurs="0" maxOccurs="unbounded"/> </sequence> <attribute name="Id" type="ID" use="optional"/> </complexType> <element name="SignatureValue" type="ds:SignatureValueType"/> <complexType name="SignatureValueType"> <simpleContent> <extension base="base64Binary"> <attribute name="Id" type="ID" use="optional"/> </extension> </simpleContent> </complexType> <!-- Start SignedInfo --> <element name="SignedInfo" type="ds:SignedInfoType"/> <complexType name="SignedInfoType"> <sequence> <element ref="ds:CanonicalizationMethod"/> <element ref="ds:SignatureMethod"/> <element ref="ds:Reference" maxOccurs="unbounded"/> </sequence> <attribute name="Id" type="ID" use="optional"/> </complexType> <element name="CanonicalizationMethod" type="ds:CanonicalizationMethodType"/> <complexType name="CanonicalizationMethodType" mixed="true"> <sequence> <any namespace="##any" minOccurs="0" maxOccurs="unbounded"/> <!-- (0,unbounded) elements from (1,1) namespace --> </sequence> <attribute name="Algorithm" type="anyURI" use="required"/> </complexType> <element name="SignatureMethod" type="ds:SignatureMethodType"/> <complexType name="SignatureMethodType" mixed="true"> <sequence> <element name="HMACOutputLength" minOccurs="0" type="ds:HMACOutputLengthType"/> <any namespace="##other" minOccurs="0" maxOccurs="unbounded"/> <!-- (0,unbounded) elements from (1,1) external namespace --> </sequence> <attribute name="Algorithm" type="anyURI" use="required"/> </complexType> <!-- Start Reference --> <element name="Reference" type="ds:ReferenceType"/> <complexType name="ReferenceType"> <sequence> <element ref="ds:Transforms" minOccurs="0"/> <element ref="ds:DigestMethod"/> <element ref="ds:DigestValue"/> </sequence> <attribute name="Id" type="ID" use="optional"/> <attribute name="URI" type="anyURI" use="optional"/> <attribute name="Type" type="anyURI" use="optional"/> </complexType> <element name="Transforms" type="ds:TransformsType"/> <complexType name="TransformsType"> <sequence> <element ref="ds:Transform" maxOccurs="unbounded"/> </sequence> </complexType> <element name="Transform" type="ds:TransformType"/> <complexType name="TransformType" mixed="true"> <choice minOccurs="0" maxOccurs="unbounded"> <any namespace="##other" processContents="lax"/> <!-- (1,1) elements from (0,unbounded) namespaces --> <element name="XPath" type="string"/> </choice> <attribute name="Algorithm" type="anyURI" use="required"/> </complexType> <!-- End Reference --> <element name="DigestMethod" type="ds:DigestMethodType"/> <complexType name="DigestMethodType" mixed="true"> <sequence> <any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/> </sequence> <attribute name="Algorithm" type="anyURI" use="required"/> </complexType> <element name="DigestValue" type="ds:DigestValueType"/> <simpleType name="DigestValueType"> <restriction base="base64Binary"/> </simpleType> <!-- End SignedInfo --> <!-- Start KeyInfo --> <element name="KeyInfo" type="ds:KeyInfoType"/> <complexType name="KeyInfoType" mixed="true"> <choice maxOccurs="unbounded"> <element ref="ds:KeyName"/> <element ref="ds:KeyValue"/> <element ref="ds:RetrievalMethod"/> <element ref="ds:X509Data"/> <element ref="ds:PGPData"/> <element ref="ds:SPKIData"/> <element ref="ds:MgmtData"/> <any processContents="lax" namespace="##other"/> <!-- (1,1) elements from (0,unbounded) namespaces --> </choice> <attribute name="Id" type="ID" use="optional"/> </complexType> <element name="KeyName" type="string"/> <element name="MgmtData" type="string"/> <element name="KeyValue" type="ds:KeyValueType"/> <complexType name="KeyValueType" mixed="true"> <choice> <element ref="ds:DSAKeyValue"/> <element ref="ds:RSAKeyValue"/> <any namespace="##other" processContents="lax"/> </choice> </complexType> <element name="RetrievalMethod" type="ds:RetrievalMethodType"/> <complexType name="RetrievalMethodType"> <sequence> <element ref="ds:Transforms" minOccurs="0"/> </sequence> <attribute name="URI" type="anyURI"/> <attribute name="Type" type="anyURI" use="optional"/> </complexType> <!-- Start X509Data --> <element name="X509Data" type="ds:X509DataType"/> <complexType name="X509DataType"> <sequence maxOccurs="unbounded"> <choice> <element name="X509IssuerSerial" type="ds:X509IssuerSerialType"/> <element name="X509SKI" type="base64Binary"/> <element name="X509SubjectName" type="string"/> <element name="X509Certificate" type="base64Binary"/> <element name="X509CRL" type="base64Binary"/> <any namespace="##other" processContents="lax"/> </choice> </sequence> </complexType> <complexType name="X509IssuerSerialType"> <sequence> <element name="X509IssuerName" type="string"/> <element name="X509SerialNumber" type="integer"/> </sequence> </complexType> <!-- End X509Data --> <!-- Begin PGPData --> <element name="PGPData" type="ds:PGPDataType"/> <complexType name="PGPDataType"> <choice> <sequence> <element name="PGPKeyID" type="base64Binary"/> <element name="PGPKeyPacket" type="base64Binary" minOccurs="0"/> <any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/> </sequence> <sequence> <element name="PGPKeyPacket" type="base64Binary"/> <any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/> </sequence> </choice> </complexType> <!-- End PGPData --> <!-- Begin SPKIData --> <element name="SPKIData" type="ds:SPKIDataType"/> <complexType name="SPKIDataType"> <sequence maxOccurs="unbounded"> <element name="SPKISexp" type="base64Binary"/> <any namespace="##other" processContents="lax" minOccurs="0"/> </sequence> </complexType> <!-- End SPKIData --> <!-- End KeyInfo --> <!-- Start Object (Manifest, SignatureProperty) --> <element name="Object" type="ds:ObjectType"/> <complexType name="ObjectType" mixed="true"> <sequence minOccurs="0" maxOccurs="unbounded"> <any namespace="##any" processContents="lax"/> </sequence> <attribute name="Id" type="ID" use="optional"/> <attribute name="MimeType" type="string" use="optional"/> <!-- add a grep facet --> <attribute name="Encoding" type="anyURI" use="optional"/> </complexType> <element name="Manifest" type="ds:ManifestType"/> <complexType name="ManifestType"> <sequence> <element ref="ds:Reference" maxOccurs="unbounded"/> </sequence> <attribute name="Id" type="ID" use="optional"/> </complexType> <element name="SignatureProperties" type="ds:SignaturePropertiesType"/> <complexType name="SignaturePropertiesType"> <sequence> <element ref="ds:SignatureProperty" maxOccurs="unbounded"/> </sequence> <attribute name="Id" type="ID" use="optional"/> </complexType> <element name="SignatureProperty" type="ds:SignaturePropertyType"/> <complexType name="SignaturePropertyType" mixed="true"> <choice maxOccurs="unbounded"> <any namespace="##other" processContents="lax"/> <!-- (1,1) elements from (1,unbounded) namespaces --> </choice> <attribute name="Target" type="anyURI" use="required"/> <attribute name="Id" type="ID" use="optional"/> </complexType> <!-- End Object (Manifest, SignatureProperty) --> <!-- Start Algorithm Parameters --> <simpleType name="HMACOutputLengthType"> <restriction base="integer"/> </simpleType> <!-- Start KeyValue Element-types --> <element name="DSAKeyValue" type="ds:DSAKeyValueType"/> <complexType name="DSAKeyValueType"> <sequence> <sequence minOccurs="0"> <element name="P" type="ds:CryptoBinary"/> <element name="Q" type="ds:CryptoBinary"/> </sequence> <element name="G" type="ds:CryptoBinary" minOccurs="0"/> <element name="Y" type="ds:CryptoBinary"/> <element name="J" type="ds:CryptoBinary" minOccurs="0"/> <sequence minOccurs="0"> <element name="Seed" type="ds:CryptoBinary"/> <element name="PgenCounter" type="ds:CryptoBinary"/> </sequence> </sequence> </complexType> <element name="RSAKeyValue" type="ds:RSAKeyValueType"/> <complexType name="RSAKeyValueType"> <sequence> <element name="Modulus" type="ds:CryptoBinary"/> <element name="Exponent" type="ds:CryptoBinary"/> </sequence> </complexType> <!-- End KeyValue Element-types --> <!-- End Signature --> </schema>
4. Getting the class eni.xades.enveloped.IndiceContenido
4.1 build.gradle file
sourceCompatibility = 12 targetCompatibility = 12 configurations { jaxb } dependencies { jaxb ( 'com.sun.xml.bind:jaxb-xjc:4.0.1', 'com.sun.xml.bind:jaxb-impl:4.0.1', 'org.glassfish.jaxb:jaxb-runtime:4.0.1' ) api libs.jakarta.xml.bind.api compileOnly libs.lombok // use version catalog in the file "settings.gradle" annotationProcessor libs.lombok // use version catalog in the file "settings.gradle" testCompileOnly libs.lombok // use version catalog in the file "settings.gradle" testAnnotationProcessor libs.lombok // use version catalog in the file "settings.gradle" } task jaxb { System.setProperty('javax.xml.accessExternalSchema', 'all') def jaxbTargetDir = file("src/generated-sources/jaxb") doLast { jaxbTargetDir.mkdirs() ant.taskdef( name: 'xjc', classname: 'com.sun.tools.xjc.XJCTask', classpath: configurations.jaxb.asPath ) ant.jaxbTargetDir = jaxbTargetDir ant.xjc( destdir: '${jaxbTargetDir}', //package: 'eni.documento', //package: 'eni.expediente', //package: 'eni.xmldsig', //package: 'eni.xades', //package: 'eni.afirma', //package: 'eni.inside', package: 'eni.xades.enveloped', //schema: 'src/main/resources/xsd/documentoEni.xsd' //schema: 'src/main/resources/xsd/expedienteEni.xsd' //schema: 'src/main/resources/xsd/xmldsig-core-schema.xsd' //schema: 'src/main/resources/xsd/xades.xsd' //schema: 'src/main/resources/xsd/TipoExpedienteInsideConMAdicionales.xsd' schema: 'src/main/resources/xsd/xadesEnveloped.xsd' ) } } jar { from sourceSets.main.allSource //Include java sources duplicatesStrategy = DuplicatesStrategy.EXCLUDE } compileJava.dependsOn jaxb
5. Unmarshal the signature obtained by Autofirma into the previous class and extract the Signature class.
IndiceContenido indxContent=xmlMapper.FileToObject(new File(expContenidoFirmaFileNameXades),IndiceContenido.class);
6. Assign this Signature class to the nested attribute "indice.firmas.firma.contenidoFirma.firmaConCertificado.signature" of the class "TipoExpediente"
expENI=ENIExpSedipualba.firmarContenidoV2(expENI, indxContent.getSignature(), year, expContenidoFirmaFileNameXades);
public static TipoExpediente firmarContenidoV2(TipoExpediente expENI, SignatureType firmaXsdesEnveloped, int any, String tipo) { FirmaConCertificado unaFrmCCert= new FirmaConCertificado(); //unaFrmCCert.setFirmaBase64(Base64.getEncoder().encodeToString(firmaContent)); //unaFrmCCert.setReferenciaFirma(null); // unaFrmCCert.setSignature(firmaXsdesEnveloped); ContenidoFirma unContenido=new ContenidoFirma(); unContenido.setFirmaConCertificado(unaFrmCCert); TipoFirmasElectronicas unaFirma=new TipoFirmasElectronicas(); unaFirma.setId("Contenido_"+ any); unaFirma.setTipoFirma("TF03"); //Xades enveloped unaFirma.setContenidoFirma(unContenido); unaFirma.setRef("#"+getIdentificadorDocIndexContenido(any)); expENI.getIndice().setFirmas(new Firmas()); expENI.getIndice().getFirmas().getFirma().add(unaFirma); return expENI; }
7. Marshall the "Expediente" object whose class is "TipoExpediente"
xmlMapper.ObjectToFile(expENI,expEniJaxbFNameSigned);
Comments
Post a Comment