1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package es.accv.arangi.base.signature;
22
23 import java.io.ByteArrayInputStream;
24 import java.io.ByteArrayOutputStream;
25 import java.io.File;
26 import java.io.FileInputStream;
27 import java.io.FileNotFoundException;
28 import java.io.FileOutputStream;
29 import java.io.IOException;
30 import java.io.InputStream;
31 import java.io.OutputStream;
32 import java.io.StringWriter;
33 import java.lang.reflect.Constructor;
34 import java.net.MalformedURLException;
35 import java.net.URI;
36 import java.net.URISyntaxException;
37 import java.net.URL;
38 import java.nio.charset.Charset;
39 import java.security.MessageDigest;
40 import java.security.cert.CertificateEncodingException;
41 import java.security.cert.CertificateException;
42 import java.security.cert.X509Certificate;
43 import java.text.ParseException;
44 import java.text.SimpleDateFormat;
45 import java.util.ArrayList;
46 import java.util.Arrays;
47 import java.util.Date;
48 import java.util.GregorianCalendar;
49 import java.util.HashSet;
50 import java.util.Iterator;
51 import java.util.List;
52 import java.util.Locale;
53 import java.util.Set;
54
55 import javax.xml.parsers.DocumentBuilder;
56 import javax.xml.parsers.DocumentBuilderFactory;
57 import javax.xml.transform.OutputKeys;
58 import javax.xml.transform.Transformer;
59 import javax.xml.transform.TransformerConfigurationException;
60 import javax.xml.transform.TransformerException;
61 import javax.xml.transform.TransformerFactory;
62 import javax.xml.transform.dom.DOMSource;
63 import javax.xml.transform.stream.StreamResult;
64 import javax.xml.xpath.XPath;
65 import javax.xml.xpath.XPathConstants;
66 import javax.xml.xpath.XPathExpression;
67 import javax.xml.xpath.XPathExpressionException;
68 import javax.xml.xpath.XPathFactory;
69
70 import org.apache.log4j.Logger;
71 import org.apache.xml.security.exceptions.XMLSecurityException;
72 import org.apache.xml.security.signature.Reference;
73 import org.apache.xml.security.signature.SignedInfo;
74 import org.apache.xml.security.signature.XMLSignature;
75 import org.apache.xml.security.transforms.Transforms;
76 import org.bouncycastle.cert.ocsp.OCSPResp;
77 import org.w3c.dom.Attr;
78 import org.w3c.dom.Document;
79 import org.w3c.dom.Element;
80 import org.w3c.dom.NamedNodeMap;
81 import org.w3c.dom.Node;
82 import org.w3c.dom.NodeList;
83 import org.xml.sax.SAXException;
84
85 import es.accv.arangi.base.algorithm.HashingAlgorithm;
86 import es.accv.arangi.base.certificate.Certificate;
87 import es.accv.arangi.base.certificate.validation.CAList;
88 import es.accv.arangi.base.certificate.validation.CertificateValidationService;
89 import es.accv.arangi.base.certificate.validation.OCSPResponse;
90 import es.accv.arangi.base.device.DeviceManager;
91 import es.accv.arangi.base.document.FileDocument;
92 import es.accv.arangi.base.document.IDocument;
93 import es.accv.arangi.base.document.InputStreamDocument;
94 import es.accv.arangi.base.document.URLDocument;
95 import es.accv.arangi.base.exception.certificate.validation.MalformedOCSPResponseException;
96 import es.accv.arangi.base.exception.device.LoadingObjectException;
97 import es.accv.arangi.base.exception.device.SearchingException;
98 import es.accv.arangi.base.exception.document.HashingException;
99 import es.accv.arangi.base.exception.document.InitDocumentException;
100 import es.accv.arangi.base.exception.signature.AlgorithmNotSuitableException;
101 import es.accv.arangi.base.exception.signature.NoCoincidentDocumentException;
102 import es.accv.arangi.base.exception.signature.NoDocumentToSignException;
103 import es.accv.arangi.base.exception.signature.SignatureException;
104 import es.accv.arangi.base.exception.signature.SignatureNotFoundException;
105 import es.accv.arangi.base.exception.signature.XMLDocumentException;
106 import es.accv.arangi.base.exception.timestamp.MalformedTimeStampException;
107 import es.accv.arangi.base.mityc.ArangiDocumentPrivateData;
108 import es.accv.arangi.base.mityc.CAListCertStatusRecover;
109 import es.accv.arangi.base.mityc.FileResourceData;
110 import es.accv.arangi.base.mityc.ToxicResourceData;
111 import es.accv.arangi.base.mityc.URLResourceData;
112 import es.accv.arangi.base.mityc.UnknownFileResourceData;
113 import es.accv.arangi.base.mityc.ValidationServicesCertStatusRecover;
114 import es.accv.arangi.base.mityc.XAdESUtil;
115 import es.accv.arangi.base.signature.util.ArangiXAdESPolicyIdentifier;
116 import es.accv.arangi.base.signature.util.ArangiXAdESProductionPlace;
117 import es.accv.arangi.base.signature.util.ObjectIdentifier;
118 import es.accv.arangi.base.signature.util.TSAData;
119 import es.accv.arangi.base.signature.util.XAdESAttachedNodeToSign;
120 import es.accv.arangi.base.signature.util.XAdESAttachedNodeToSignEnveloped;
121 import es.accv.arangi.base.signature.util.XAdESAttachedNodeToSignObject;
122 import es.accv.arangi.base.signature.util.XAdESAttachedSignatureOptions;
123 import es.accv.arangi.base.signature.util.XAdESDataObjectFormat;
124 import es.accv.arangi.base.signature.util.XAdESDetachedSignatureOptions;
125 import es.accv.arangi.base.timestamp.TimeStamp;
126 import es.accv.arangi.base.util.Util;
127 import es.accv.arangi.base.util.validation.ValidationResult;
128 import es.mityc.firmaJava.libreria.ConstantesXADES;
129 import es.mityc.firmaJava.libreria.utilidades.Base64Coder;
130 import es.mityc.firmaJava.libreria.utilidades.NombreNodo;
131 import es.mityc.firmaJava.libreria.utilidades.UtilidadFechas;
132 import es.mityc.firmaJava.libreria.utilidades.UtilidadFirmaElectronica;
133 import es.mityc.firmaJava.libreria.utilidades.UtilidadTratarNodo;
134 import es.mityc.firmaJava.libreria.xades.CanonicalizationEnum;
135 import es.mityc.firmaJava.libreria.xades.DataToSign;
136 import es.mityc.firmaJava.libreria.xades.DatosFirma;
137 import es.mityc.firmaJava.libreria.xades.EnumFormatoFirma;
138 import es.mityc.firmaJava.libreria.xades.ExtraValidators;
139 import es.mityc.firmaJava.libreria.xades.FirmaXML;
140 import es.mityc.firmaJava.libreria.xades.RespYCerts;
141 import es.mityc.firmaJava.libreria.xades.ResultadoValidacion;
142 import es.mityc.firmaJava.libreria.xades.UtilidadXadesX;
143 import es.mityc.firmaJava.libreria.xades.ValidarFirmaXML;
144 import es.mityc.firmaJava.libreria.xades.XAdESSchemas;
145 import es.mityc.firmaJava.libreria.xades.elementos.xades.CRLRef;
146 import es.mityc.firmaJava.libreria.xades.elementos.xades.CRLRefs;
147 import es.mityc.firmaJava.libreria.xades.elementos.xades.CRLValues;
148 import es.mityc.firmaJava.libreria.xades.elementos.xades.CertificateValues;
149 import es.mityc.firmaJava.libreria.xades.elementos.xades.EncapsulatedX509Certificate;
150 import es.mityc.firmaJava.libreria.xades.errores.BadFormedSignatureException;
151 import es.mityc.firmaJava.libreria.xades.errores.FirmaXMLError;
152 import es.mityc.firmaJava.libreria.xades.errores.InvalidInfoNodeException;
153 import es.mityc.firmaJava.role.SimpleClaimedRole;
154 import es.mityc.firmaJava.ts.TSCliente;
155 import es.mityc.firmaJava.ts.TSClienteError;
156 import es.mityc.javasign.ConstantsXAdES;
157 import es.mityc.javasign.certificate.ICertStatus;
158 import es.mityc.javasign.certificate.ICertStatusRecoverer;
159 import es.mityc.javasign.certificate.IOCSPCertStatus;
160 import es.mityc.javasign.certificate.IX509CRLCertStatus;
161 import es.mityc.javasign.xml.refs.AllXMLToSign;
162 import es.mityc.javasign.xml.refs.InternObjectToSign;
163 import es.mityc.javasign.xml.refs.ObjectToSign;
164 import es.mityc.javasign.xml.refs.UnknownExternObjectToSign;
165
166
167
168
169
170
171 public abstract class XAdESSignature extends Signature {
172
173
174
175
176 static Logger logger = Logger.getLogger(XAdESSignature.class);
177
178
179
180
181 protected Document xadesDocument;
182
183
184
185
186 protected static final String DEFAULT_ID_TAG_DOCUMENT = "ArangiXadesDocument";
187
188
189
190
191 protected static final String DEFAULT_ROOT_TAG = "arangi-xades";
192
193
194
195
196 protected static final String TEMPLATE_ARANGI_XADES = "es/accv/arangi/base/template/arangi-xades_template.xml";
197
198
199
200
201 public static final XAdESSchemas DEFAULT_XADES_SCHEMA = XAdESSchemas.XAdES_132;
202
203
204
205
206 public static final String DEFAULT_XADES_SCHEMA_URI = DEFAULT_XADES_SCHEMA.getSchemaUri();
207
208
209
210
211 public static final String DEFAULT_XML_ENCODING = "UTF-8";
212
213
214
215
216 protected static String xadesNS = ConstantsXAdES.DEFAULT_NS_XADES;
217
218
219
220
221 protected static String xmldsigNS = ConstantsXAdES.DEFAULT_NS_XMLSIG;
222
223
224
225
226 protected static final SimpleDateFormat xsdDateTimeFormat = new SimpleDateFormat ("yyyy-MM-dd'T'HH:mm:ss");
227
228
229
230
231
232
233
234 protected abstract int tratarResultadoValidacion(ResultadoValidacion resultadoValidacion);
235
236
237
238
239
240
241 protected abstract EnumFormatoFirma getXAdESSignatureFormat ();
242
243
244
245
246
247
248
249
250
251
252 public Date[] getSigningTimes() {
253 logger.debug("[XAdESSignature.getSigningTimes]::Entrada");
254
255
256 XPathFactory factory = XPathFactory.newInstance();
257 XPath xpath = factory.newXPath();
258 ArrayList<Date> alDates = new ArrayList<Date>();
259 try {
260 XPathExpression expr = xpath.compile("//*[local-name()='Signature']");
261 NodeList signatureNodes = (NodeList) expr.evaluate (xadesDocument, XPathConstants.NODESET);
262 for (int i=0;i<signatureNodes.getLength();i++) {
263
264 Node signatureNode = signatureNodes.item(i);
265
266
267 if (signatureNode.getParentNode() == null || signatureNode.getParentNode().getLocalName() == null ||
268 !signatureNode.getParentNode().getLocalName().equals("CounterSignature")) {
269 expr = xpath.compile("*[local-name()='Object']/*[local-name()='QualifyingProperties']/*[local-name()='SignedProperties']/" +
270 "*[local-name()='SignedSignatureProperties']/*[local-name()='SigningTime']");
271 Element signingTimeNode = (Element) expr.evaluate (signatureNode, XPathConstants.NODE);
272 alDates.add(getXsdDateTimeParse(signingTimeNode.getTextContent()));
273 }
274 }
275
276 return alDates.toArray(new Date[0]);
277
278 } catch (Exception e) {
279 logger.info ("[XAdESSignature.getSigningTimes]::Error inesperado", e);
280 return null;
281 }
282
283 }
284
285
286
287
288
289
290
291 public String getDocumentDescription () {
292 return getDataObjectFormatValue("Description");
293 }
294
295
296
297
298
299
300
301 public String getDocumentMIMEType () {
302 return getDataObjectFormatValue("MimeType");
303 }
304
305
306
307
308
309
310
311 public String getDocumentEncoding () {
312 return getDataObjectFormatValue("Encoding");
313 }
314
315
316
317
318
319
320 public Document getDOM () {
321 return xadesDocument;
322 }
323
324
325
326
327
328
329
330
331
332
333
334
335 public static XAdESSignature getXAdESObject (File signature) throws SignatureException, XMLDocumentException, FileNotFoundException {
336 return XAdESSignature.getXAdESObject (getDocument(signature));
337 }
338
339
340
341
342
343
344
345
346
347
348
349 public static XAdESSignature getXAdESObject (InputStream isSignature) throws SignatureException, XMLDocumentException{
350 return XAdESSignature.getXAdESObject (getDocument(isSignature));
351 }
352
353
354
355
356
357
358
359
360
361
362
363 public static XAdESSignature getXAdESObject (byte[] signature) throws SignatureException, XMLDocumentException {
364 return XAdESSignature.getXAdESObject (getDocument(signature));
365 }
366
367
368
369
370
371
372
373
374
375
376
377
378 public static XAdESSignature getXAdESObject (Document signature) throws SignatureException {
379 logger.debug("[XAdESSignature.getXAdESObject]::Entrada::" + signature);
380
381
382 XPathFactory factory = XPathFactory.newInstance();
383 XPath xpath = factory.newXPath();
384 NodeList certificateNodes;
385 try {
386 XPathExpression expr = xpath.compile("//*[local-name()='RevocationValues']");
387 certificateNodes = (NodeList) expr.evaluate (signature, XPathConstants.NODESET);
388 if (certificateNodes != null && certificateNodes.getLength() > 0) {
389 logger.debug("[XAdESSignature.getXAdESObject]::La firma es un XAdES-X-L");
390 return new XAdESXLSignature (signature);
391 }
392 } catch (Exception e) {
393 logger.info ("[XAdESSignature.getXAdESObject]::Error buscando el nodo RevocationValues", e);
394 }
395
396
397 try {
398 XPathExpression expr = xpath.compile("//*[local-name()='SignatureTimeStamp']");
399 certificateNodes = (NodeList) expr.evaluate (signature, XPathConstants.NODESET);
400 if (certificateNodes != null && certificateNodes.getLength() > 0) {
401 logger.debug("[XAdESSignature.getXAdESObject]::La firma es un XAdES-T");
402 return new XAdESTSignature (signature);
403 }
404 } catch (Exception e) {
405 logger.info ("[XAdESSignature.getXAdESObject]::Error buscando el nodo SignatureTimeStamp", e);
406 }
407
408
409 try {
410 XPathExpression expr = xpath.compile("//*[local-name()='QualifyingProperties']");
411 certificateNodes = (NodeList) expr.evaluate (signature, XPathConstants.NODESET);
412 if (certificateNodes != null && certificateNodes.getLength() > 0) {
413 logger.debug("[XAdESSignature.getXAdESObject]::La firma es un XAdES-BES");
414 return new XAdESBESSignature(signature);
415 }
416 } catch (Exception e) {
417 logger.info ("[XAdESSignature.getXAdESObject]::Error buscando el nodo QualifyingProperties", e);
418 }
419
420
421 logger.info("[XAdESSignature.getXAdESObject]::El XML no es un XAdES");
422 throw new SignatureException("El XML no es un XAdES");
423
424 }
425
426
427
428
429
430
431
432
433
434
435
436 public static ISignature getSignatureInstance (byte[] bSignature) throws Exception {
437 return getXAdESObject(bSignature);
438 }
439
440
441
442
443
444
445
446
447 public Certificate[] getCertificates() {
448
449 logger.debug ("[XAdESSignature.getCertificates]::Entrada");
450
451
452 XPathFactory factory = XPathFactory.newInstance();
453 XPath xpath = factory.newXPath();
454 NodeList certificateNodes;
455 try {
456 XPathExpression expr = xpath.compile("//*[local-name()='Signature']/*[local-name()='KeyInfo']/*[local-name()='X509Data']/*[local-name()='X509Certificate']");
457 certificateNodes = (NodeList) expr.evaluate (this.xadesDocument, XPathConstants.NODESET);
458 } catch (Exception e) {
459 logger.info ("[XAdESSignature.getCertificates]::Error inesperado", e);
460 return null;
461 }
462
463 if (certificateNodes == null || certificateNodes.getLength() == 0) {
464 logger.info("[XAdESSignature.getCertificates]::Falta el elemento 'X509Certificate' de la firma");
465 return null;
466 }
467
468
469 Certificate[] certificates = new Certificate [certificateNodes.getLength()];
470 for (int i = 0; i < certificateNodes.getLength(); i++) {
471 try {
472 X509Certificate x509Cert = Util.getCertificate(Util.decodeBase64(certificateNodes.item(i).getTextContent()));
473 certificates[i] = new Certificate (x509Cert);
474 } catch (Exception e) {
475 logger.info ("[XAdESSignature.getCertificates]::Error inesperado", e);
476 return null;
477 }
478 }
479
480 return certificates;
481 }
482
483
484
485
486
487
488
489
490
491
492 public String getAttachedDocument() throws SignatureException, SignatureNotFoundException {
493
494 logger.debug ("[XAdESSignature.getAttachedDocument]::Entrada");
495
496
497
498 String uriXmlNS = "http://www.w3.org/2000/09/xmldsig#";
499 NodeList signatureList = xadesDocument.getElementsByTagNameNS(uriXmlNS, "Signature");
500 Node nodeSignature = null;
501 if (signatureList.getLength() < 1) {
502 logger.info("[XAdESSignature.getAttachedDocument]:: No existe ninguna firma en el XAdES");
503 throw new SignatureNotFoundException("No existe ninguna firma en el XAdES");
504 } else {
505 nodeSignature = signatureList.item(0);
506 }
507
508 logger.debug("[XAdESSignature.getAttachedDocument]:: Obtenido el nodo de firma");
509
510
511 try {
512 XMLSignature firmaDocumento = new XMLSignature((Element)nodeSignature, "./");
513 SignedInfo signedInfo = firmaDocumento.getSignedInfo();
514 for(int i = 0; i < signedInfo.getLength(); i++){
515 Reference ref = signedInfo.item(i);
516 if (ref.getId() != null && !ref.getId().startsWith("SignedProperties") && !ref.getId().equals("")) {
517 String uri = ref.getURI();
518 if (!uri.startsWith("#")) {
519
520 logger.debug("[XAdESSignature.getAttachedDocument]:: Se trata de una firma detached, el método devolverá un valor nulo");
521 return null;
522 } else {
523
524 logger.debug("[XAdESSignature.getAttachedDocument]:: Se trata de una firma attached");
525 uri = uri.substring(1);
526 XPathFactory factory = XPathFactory.newInstance();
527 XPath xpath = factory.newXPath();
528 Node node = null;
529 try {
530 XPathExpression expr = xpath.compile("//*[@id='" + uri + "'] | //*[@Id='" + uri + "'] | //*[@iD='" + uri + "'] | //*[@ID='" + uri + "']");
531 node = (Node) expr.evaluate (this.xadesDocument, XPathConstants.NODE);
532 } catch (Exception e) {
533 logger.info ("[XAdESSignature.getAttachedDocument]::Error inesperado", e);
534 return null;
535 }
536 if (node == null) {
537 logger.info ("[XAdESSignature.getAttachedDocument]::No se ha encontrado el elemento con ID=" + uri);
538 return null;
539 }
540
541 logger.debug("[XAdESSignature.getAttachedDocument]:: Encontrado documento en uri con ID=" + uri);
542 return node.getTextContent();
543 }
544 }
545 }
546
547 } catch (XMLSecurityException e) {
548 logger.info("[XAdESSignature.coSign]::Error buscando elementos en el fichero XAdES", e);
549 throw new SignatureException("Error buscando elementos en el fichero XAdES", e);
550 }
551
552
553 logger.debug("[XAdESSignature.getAttachedDocument]:: No se ha encontrado ninguna referencia con ID=Reference-ID...");
554 return null;
555
556 }
557
558
559
560
561 public ValidationResult[] isValid(CAList caList) throws SignatureException {
562
563 return isValid(null, caList);
564
565 }
566
567
568
569
570 public ValidationResult[] isValid(IDocument document, CAList caList)
571 throws SignatureException {
572
573 logger.debug("[XAdESSignature.isValid]::Entrada::" + Arrays.asList(new Object[] { document, caList }));
574
575 return isValidCommon(document, caList, null);
576 }
577
578
579
580
581 public ValidationResult[] isValid(List<CertificateValidationService> validationServices)
582 throws SignatureException {
583
584 return isValid(null, validationServices);
585
586 }
587
588
589
590
591 public ValidationResult[] isValid(IDocument document, List<CertificateValidationService> validationServices)
592 throws SignatureException {
593
594 logger.debug("[XAdESSignature.isValid]::Entrada::" + Arrays.asList(new Object[] { document, validationServices }));
595
596 return isValidCommon(document, null, validationServices);
597 }
598
599
600
601
602
603 public ValidationResult[] isValidSignatureOnly() throws SignatureException {
604 try {
605 return isValidSignatureOnly(null);
606 } catch (HashingException e) {
607
608 logger.info("[XAdESSignature.isValidSignatureOnly]::Error inesperado", e);
609 throw new SignatureException ("Error inesperado", e);
610 }
611 }
612
613
614
615
616 public ValidationResult[] isValidSignatureOnly(IDocument document) throws HashingException, SignatureException {
617
618 logger.debug("[XAdESSignature.isValidSignatureOnly]::Entrada");
619
620 ValidarFirmaXML validator = loadValidator (document);
621 List<ResultadoValidacion> results;
622 try {
623 results = validator.validar(this.xadesDocument, "./", null);
624 } catch (FirmaXMLError e) {
625 logger.info("[XAdESSignature.isValidSignatureOnly]::No ha sido posible validar la firma", e);
626 throw new SignatureException("No ha sido posible validar la firma", e);
627 }
628
629 ArrayList<ValidationResult> result = new ArrayList<ValidationResult>();
630 for (Iterator<ResultadoValidacion> iterator = results.iterator(); iterator.hasNext();) {
631 ResultadoValidacion resultadoValidacion = iterator.next();
632 ValidationResult validationResult = getValidationResultSignatureOnly(resultadoValidacion, false);
633 if (validationResult != null) {
634 result.add(validationResult);
635 }
636 }
637
638 return result.toArray(new ValidationResult[0]);
639
640 }
641
642
643
644
645
646
647 public String getEncoding() {
648 if(xadesDocument.getInputEncoding() != null) {
649 logger.debug("[XAdESSignature.getEncoding]:: Devolviendo " + xadesDocument.getInputEncoding());
650 return xadesDocument.getInputEncoding();
651 }
652 if(xadesDocument.getXmlEncoding() != null) {
653 logger.debug("[XAdESSignature.getEncoding]:: Devolviendo " + xadesDocument.getXmlEncoding());
654 return xadesDocument.getXmlEncoding();
655 }
656 logger.debug("[XAdESSignature.getEncoding]:: Devolviendo por defecto " + DEFAULT_XML_ENCODING);
657 return DEFAULT_XML_ENCODING;
658 }
659
660
661
662
663
664
665 public String getSignaturePolicyIdentifier () {
666 logger.debug("[XAdESSignature.getSignaturePolicyIdentifier]::Entrada");
667
668
669 XPathFactory factory = XPathFactory.newInstance();
670 XPath xpath = factory.newXPath();
671 try {
672 XPathExpression expr = xpath.compile("//*[local-name()='Object']/*[local-name()='QualifyingProperties']/*[local-name()='SignedProperties']/" +
673 "*[local-name()='SignedSignatureProperties']/*[local-name()='SignaturePolicyIdentifier']");
674 Node spiNode = (Node) expr.evaluate (xadesDocument, XPathConstants.NODE);
675 if (spiNode == null) {
676 logger.debug("[XAdESSignature.getSignaturePolicyIdentifier]::La firma no es EPES");
677 return null;
678 }
679
680 return nodeToString(spiNode);
681
682 } catch (Exception e) {
683 logger.info ("[XAdESSignature.getSignaturePolicyIdentifier]::Error inesperado", e);
684 return null;
685 }
686
687 }
688
689
690
691
692
693
694 public ArangiXAdESProductionPlace getSignatureProductionPlace () {
695 logger.debug("[XAdESSignature.getSignatureProductionPlace]::Entrada");
696
697
698 XPathFactory factory = XPathFactory.newInstance();
699 XPath xpath = factory.newXPath();
700 try {
701 XPathExpression expr = xpath.compile("//*[local-name()='Object']/*[local-name()='QualifyingProperties']/*[local-name()='SignedProperties']/" +
702 "*[local-name()='SignedSignatureProperties']/*[local-name()='SignatureProductionPlace']");
703 Node sppNode = (Node) expr.evaluate (xadesDocument, XPathConstants.NODE);
704 if (sppNode == null) {
705 logger.debug("[XAdESSignature.getSignatureProductionPlace]::La firma no no contiene el elemento SignatureProductionPlace");
706 return null;
707 }
708
709 String city = ((Node) xpath.compile("//*[local-name()='City']").evaluate (sppNode, XPathConstants.NODE)).getTextContent();
710 String state = ((Node) xpath.compile("//*[local-name()='StateOrProvince']").evaluate (sppNode, XPathConstants.NODE)).getTextContent();
711 String postalCode = ((Node) xpath.compile("//*[local-name()='PostalCode']").evaluate (sppNode, XPathConstants.NODE)).getTextContent();
712 String country = ((Node) xpath.compile("//*[local-name()='CountryName']").evaluate (sppNode, XPathConstants.NODE)).getTextContent();
713
714 return new ArangiXAdESProductionPlace(city, state, postalCode, country);
715
716 } catch (Exception e) {
717 logger.info ("[XAdESSignature.getSignatureProductionPlace]::Error inesperado", e);
718 return null;
719 }
720
721 }
722
723
724
725
726
727
728
729
730
731 public void save (File file) throws IOException {
732
733 logger.debug("[XAdESSignature.save]::Entrada::" + file);
734
735 FileOutputStream fos = null;
736 try {
737 fos = new FileOutputStream (file);
738 save(fos);
739 } finally {
740 if (fos != null) {
741 try {
742 fos.close();
743 } catch (IOException e) {
744 logger.info("[XAdESSignature.save]::No se puede cerrar el stream de escritura al fichero", e);
745 }
746 }
747 }
748 }
749
750
751
752
753
754
755
756 public void save (OutputStream out) throws IOException {
757 logger.debug("[XAdESSignature.save]::Entrada::" + out);
758
759 try {
760 TransformerFactory tf = TransformerFactory.newInstance();
761 Transformer trans = tf.newTransformer();
762 String encoding = xadesDocument.getXmlEncoding();
763 if (encoding == null) {
764 encoding = Charset.defaultCharset().displayName(Locale.getDefault());
765 }
766 trans.setOutputProperty(OutputKeys.ENCODING, encoding);
767 trans.transform(new DOMSource(xadesDocument), new StreamResult(out));
768 } catch (TransformerConfigurationException e) {
769 logger.info("[XAdESSignature.save]::No está disponible una implementación para transformar el árbol DOM", e);
770 throw new IOException ("No está disponible una implementación para transformar el árbol DOM" + e.getMessage());
771 } catch (TransformerException e) {
772 logger.info("[XAdESSignature.save]::No está disponible una implementación para transformar el árbol DOM", e);
773 throw new IOException ("No está disponible una implementación para transformar el árbol DOM" + e.getMessage());
774 }
775 }
776
777
778
779
780
781
782 public byte[] toByteArray () {
783 logger.debug("[XAdESSignature.toByteArray]::Entrada");
784 ByteArrayOutputStream baos = new ByteArrayOutputStream();
785 try {
786 save(baos);
787 } catch (IOException e) {
788
789 logger.info("[XAdESSignature.toByteArray]::No ha sido posible guardar en memoria", e);
790 return null;
791 }
792 return baos.toByteArray();
793
794 }
795
796
797
798
799
800
801
802
803
804 protected void initialize(Document xmlDocument) {
805
806 xadesDocument = xmlDocument;
807 }
808
809
810
811
812
813
814
815
816 protected void initialize(File xmlFile) throws FileNotFoundException, XMLDocumentException {
817 xadesDocument = getDocument(xmlFile);
818 }
819
820
821
822
823
824
825
826 protected void initialize(byte[] signature) throws XMLDocumentException {
827 xadesDocument = getDocument(signature);
828 }
829
830
831
832
833
834
835
836 protected void initialize(InputStream isSignature) throws XMLDocumentException {
837 xadesDocument = getDocument(isSignature);
838 }
839
840
841
842
843
844
845
846
847 private static Document getDocument (File xmlFile) throws FileNotFoundException, XMLDocumentException {
848 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
849 dbf.setNamespaceAware(true);
850 try {
851 return dbf.newDocumentBuilder().parse(new FileInputStream(xmlFile));
852 } catch (Exception e) {
853 logger.info("[XAdESSignature(file)]::El fichero no parece ser un XML válido", e);
854 throw new XMLDocumentException("El fichero no parece ser un XML válido", e);
855 }
856 }
857
858
859
860
861
862
863
864 private static Document getDocument(byte[] signature) throws XMLDocumentException {
865 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
866 dbf.setNamespaceAware(true);
867 try {
868 return dbf.newDocumentBuilder().parse(new ByteArrayInputStream(signature));
869 } catch (Exception e) {
870 logger.info("[XAdESSignature(byte[])]::La firma no parece ser un XML válido", e);
871 throw new XMLDocumentException("La firma no parece ser un XML válido", e);
872 }
873 }
874
875
876
877
878
879
880
881 private static Document getDocument(InputStream isSignature) throws XMLDocumentException {
882 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
883 dbf.setNamespaceAware(true);
884 try {
885 return dbf.newDocumentBuilder().parse(isSignature);
886 } catch (Exception e) {
887 logger.info("[XAdESSignature(byte[])]::La firma no parece ser un XML válido", e);
888 throw new XMLDocumentException("La firma no parece ser un XML válido", e);
889 }
890 }
891
892
893
894
895
896
897
898
899 protected Date getXAdESTimeStampTime () throws MalformedTimeStampException {
900 logger.debug("[XAdESSignature.getXAdESTimeStampTime]::Entrada");
901
902
903 XPathFactory factory = XPathFactory.newInstance();
904 XPath xpath = factory.newXPath();
905 Element tsNode = null;
906 try {
907 XPathExpression expr = xpath.compile("//*[local-name()='UnsignedSignatureProperties']/*[local-name()='SignatureTimeStamp']/*[local-name()='EncapsulatedTimeStamp']");
908 tsNode = (Element) expr.evaluate (xadesDocument, XPathConstants.NODE);
909 } catch (Exception e) {
910 logger.info ("[XAdESSignature.getXAdESTimeStampTime]::Error inesperado", e);
911 return null;
912 }
913
914
915 TimeStamp timeStamp = new TimeStamp(new ByteArrayInputStream (Util.decodeBase64(tsNode.getTextContent())));
916
917
918 return timeStamp.getTime();
919
920 }
921
922
923
924
925
926
927
928
929 protected static Certificate getXAdESTimeStampCertificate (Document xadesDocument) throws MalformedTimeStampException {
930 logger.debug("[XAdESSignature.getXAdESTimeStampCertificate]::Entrada");
931
932
933 XPathFactory factory = XPathFactory.newInstance();
934 XPath xpath = factory.newXPath();
935 Element tsNode = null;
936 try {
937 XPathExpression expr = xpath.compile("//*[local-name()='UnsignedSignatureProperties']/*[local-name()='SignatureTimeStamp']/*[local-name()='EncapsulatedTimeStamp']");
938 tsNode = (Element) expr.evaluate (xadesDocument, XPathConstants.NODE);
939 } catch (Exception e) {
940 logger.info ("[XAdESSignature.getXAdESTimeStampTime]::Error inesperado", e);
941 return null;
942 }
943
944
945 TimeStamp timeStamp = new TimeStamp(new ByteArrayInputStream (Util.decodeBase64(tsNode.getTextContent())));
946
947
948 return timeStamp.getSignatureCertificate();
949
950 }
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970 protected static DataToSign createDataToSignAtached(Document docToSign, XAdESAttachedNodeToSign nodeToSign,
971 String signatureParent, URI encoding, ICertStatusRecoverer certStatusRecover, EnumFormatoFirma tipoXAdES,
972 XAdESDataObjectFormat dof, String[] claimedRoles, ArangiXAdESPolicyIdentifier policyIdentifier,
973 ArangiXAdESProductionPlace productionPlace, String tsaHashingAlgorithm) {
974 DataToSign dataToSign = new DataToSign();
975 dataToSign.setXadesFormat(tipoXAdES);
976 if (certStatusRecover != null) {
977 dataToSign.setCertStatusManager (certStatusRecover);
978 }
979 dataToSign.setEsquema(DEFAULT_XADES_SCHEMA);
980 dataToSign.setXMLEncoding(DEFAULT_XML_ENCODING);
981 dataToSign.setEnveloped(true);
982 dataToSign.setDocument(docToSign);
983
984 if (policyIdentifier != null) {
985 dataToSign.setPolicy(policyIdentifier.getSignaturePolicyIdentifier());
986 }
987 if (productionPlace != null) {
988 dataToSign.setProductionPlace(productionPlace.getCity(), productionPlace.getState(),
989 productionPlace.getPostalCode(), productionPlace.getCountry());
990 }
991
992 String dofDescripcion = null;
993 ObjectIdentifier dofObjectIdentifier = null;
994 String dofMimeType = null;
995 URI dofEncoding = null;
996 if (dof != null) {
997 dofDescripcion = dof.getDescription();
998 dofObjectIdentifier = dof.getObjectIdentifier();
999 dofMimeType = dof.getMimeType();
1000 dofEncoding = dof.getEncoding();
1001 }
1002 if (nodeToSign instanceof XAdESAttachedNodeToSignEnveloped) {
1003 dataToSign.addObject(new ObjectToSign(new AllXMLToSign(), dofDescripcion, dofObjectIdentifier, dofMimeType, dofEncoding));
1004 } else {
1005 dataToSign.addObject(new ObjectToSign(new InternObjectToSign(((XAdESAttachedNodeToSignObject)nodeToSign).getIdToSign()), dofDescripcion, dofObjectIdentifier, dofMimeType, dofEncoding));
1006 }
1007 if (claimedRoles != null) {
1008 for(String claimedRole : claimedRoles) {
1009 dataToSign.addClaimedRol(new SimpleClaimedRole(claimedRole));
1010 }
1011 }
1012
1013 dataToSign.setParentSignNode(signatureParent);
1014 logger.debug("ParentSignNode: " + docToSign.getDocumentElement().getNodeName());
1015
1016 if (tsaHashingAlgorithm != null) {
1017 try {
1018 String tsaHashingAlgorithmXades = XAdESUtil.getXAdESHashingAlgorithm(tsaHashingAlgorithm);
1019 dataToSign.setAlgDigestTSA(tsaHashingAlgorithmXades);
1020 } catch (AlgorithmNotSuitableException e) {
1021 logger.info("No existe el algoritmo de hashing para la TSA");
1022 }
1023 }
1024
1025 return dataToSign;
1026 }
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045 protected static DataToSign createDataToSignDetached(IDocument document, String reference,
1046 ICertStatusRecoverer certStatusRecover, EnumFormatoFirma tipoXAdES, XAdESDataObjectFormat dof,
1047 String[] claimedRoles, ArangiXAdESPolicyIdentifier policyIdentifier,
1048 ArangiXAdESProductionPlace productionPlace, String tsaHashingAlgorithm) {
1049 DataToSign dataToSign = new DataToSign();
1050 dataToSign.setXadesFormat(tipoXAdES);
1051 if (certStatusRecover != null) {
1052 dataToSign.setCertStatusManager (certStatusRecover);
1053 }
1054 dataToSign.setEsquema(DEFAULT_XADES_SCHEMA);
1055 dataToSign.setXMLEncoding(DEFAULT_XML_ENCODING);
1056 dataToSign.setEnveloped(false);
1057 if (policyIdentifier != null) {
1058 dataToSign.setPolicy(policyIdentifier.getSignaturePolicyIdentifier());
1059 }
1060 if (productionPlace != null) {
1061 dataToSign.setProductionPlace(productionPlace.getCity(), productionPlace.getState(),
1062 productionPlace.getPostalCode(), productionPlace.getCountry());
1063 }
1064
1065 String dofDescripcion = null;
1066 ObjectIdentifier dofObjectIdentifier = null;
1067 String dofMimeType = null;
1068 URI dofEncoding = null;
1069 if (dof != null) {
1070 dofDescripcion = dof.getDescription();
1071 dofObjectIdentifier = dof.getObjectIdentifier();
1072 dofMimeType = dof.getMimeType();
1073 dofEncoding = dof.getEncoding();
1074 }
1075
1076 if (tsaHashingAlgorithm != null) {
1077 try {
1078 String tsaHashingAlgorithmXades = XAdESUtil.getXAdESHashingAlgorithm(tsaHashingAlgorithm);
1079 dataToSign.setAlgDigestTSA(tsaHashingAlgorithmXades);
1080 } catch (AlgorithmNotSuitableException e) {
1081 logger.info("No existe el algoritmo de hashing para la TSA");
1082 }
1083 }
1084
1085 dataToSign.addObject(new ObjectToSign(new UnknownExternObjectToSign(reference, new ArangiDocumentPrivateData(document)), dofDescripcion, dofObjectIdentifier, dofMimeType, dofEncoding));
1086
1087 if (claimedRoles != null) {
1088 for(String claimedRole : claimedRoles) {
1089 dataToSign.addClaimedRol(new SimpleClaimedRole(claimedRole));
1090 }
1091 }
1092 return dataToSign;
1093 }
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119 protected static XAdESSignature signDetached (DeviceManager manager, String alias, IDocument document,
1120 String reference, TSAData tsaData, ICertStatusRecoverer certStatusRecover,
1121 XAdESDetachedSignatureOptions options, EnumFormatoFirma tipoXAdES, Class<?> returnClassObject)
1122 throws LoadingObjectException, SignatureException {
1123
1124 logger.debug("[XAdESSignature.signDetached]::Entrada::" + Arrays.asList(new Object[] { manager, alias, document, reference, certStatusRecover, tipoXAdES, tsaData, options, returnClassObject }));
1125
1126 if (options == null) {
1127 options = new XAdESDetachedSignatureOptions();
1128 }
1129
1130
1131 X509Certificate certificate;
1132 try {
1133 logger.debug ("[XAdESSignature.signDetached]::obteniendo el certificado");
1134 certificate = manager.getCertificate(alias);
1135 } catch (SearchingException e) {
1136 logger.info("[XAdESSignature.signDetached]::Error buscando un certificado en el alias'" + alias + "'", e);
1137 throw new LoadingObjectException ("Error buscando un certificado en el alias'" + alias + "'", e);
1138 }
1139
1140 if (certificate == null) {
1141 logger.info("[XAdESSignature.signDetached]::No se ha podido encontrar un certificado en el alias'" + alias + "'");
1142 throw new LoadingObjectException ("No se ha podido encontrar un certificado en el alias'" + alias + "'");
1143 }
1144
1145
1146 logger.debug ("[XAdESSignature.signDetached]::obteniendo los datos a firmar");
1147 DataToSign dataToSign = createDataToSignDetached(document, reference, certStatusRecover, tipoXAdES,
1148 options.getDof(), options.getClaimedRoles(), options.getPolicyIdentifier(),
1149 options.getProductionPlace(), options.getTsaHashingAlgorithm());
1150 if (dataToSign == null) {
1151 logger.debug ("[XAdESSignature.signDetached]::El objeto a firmar no es un fichero ni una URL");
1152 throw new SignatureException ("El objeto a firmar no es un fichero ni una URL");
1153 }
1154
1155
1156 try {
1157 logger.debug ("[XAdESSignature.signDetached]::Firmando");
1158 FirmaXML firma = new FirmaXML();
1159 if (tsaData != null) {
1160 firma.setTSA(tsaData.getUrl().toString());
1161 }
1162 Object[] res = firma.signFile(certificate, dataToSign, manager.getPrivateKey(alias), XAdESUtil.getXAdESDigitalSignatureAlgorithm(options.getDigitalSignatureAlgorithm()), null);
1163 logger.debug ("[XAdESSignature.signDetached]::Firma realizada");
1164
1165
1166 Constructor<?> constructor = returnClassObject.getDeclaredConstructor(Document.class);
1167 return (XAdESSignature)constructor.newInstance((Document) res[0]);
1168
1169 } catch (Exception e) {
1170 logger.info("[XAdESSignature.signDetached]::No ha sido posible realizar la firma", e);
1171 throw new SignatureException ("No ha sido posible realizar la firma", e);
1172 }
1173
1174 }
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196 protected static XAdESSignature signAttached (DeviceManager manager, String alias, IDocument document,
1197 TSAData tsaData, ICertStatusRecoverer certStatusRecover, XAdESAttachedSignatureOptions options,
1198 EnumFormatoFirma tipoXAdES, Class<?> returnClassObject)
1199 throws XMLDocumentException, LoadingObjectException, SignatureException {
1200
1201 logger.debug("[XAdESSignature.signAttached]::Entrada::" + Arrays.asList(new Object[] { manager, alias, document, certStatusRecover, tipoXAdES, tsaData, options, returnClassObject }));
1202
1203 if (options == null) {
1204 options = new XAdESAttachedSignatureOptions();
1205 }
1206
1207
1208 X509Certificate certificate;
1209 try {
1210 logger.debug ("[XAdESSignature.signAttached]::obteniendo el certificado");
1211 certificate = manager.getCertificate(alias);
1212 } catch (SearchingException e) {
1213 logger.info("[XAdESSignature.signAttached]::Error buscando un certificado en el alias'" + alias + "'", e);
1214 throw new LoadingObjectException ("Error buscando un certificado en el alias'" + alias + "'", e);
1215 }
1216
1217 if (certificate == null) {
1218 logger.info("[XAdESSignature.signAttached]::No se ha podido encontrar un certificado en el alias'" + alias + "'");
1219 throw new LoadingObjectException ("No se ha podido encontrar un certificado en el alias'" + alias + "'");
1220 }
1221
1222
1223
1224 File tempFile;
1225 try {
1226 tempFile = saveTemporalFile(document.getInputStream());
1227 } catch (IOException e) {
1228 logger.info ("[XAdESSignature.signAttached]::No es posible guardar el fichero temporal con el documento a firmar", e);
1229 throw new LoadingObjectException ("No es posible guardar el fichero temporal con el documento a firmar", e);
1230 }
1231
1232 try {
1233 DocumentBuilder db = getDocumentBuilder ();
1234
1235
1236 Document documentToSign = null;
1237 try {
1238 documentToSign = db.parse(tempFile);
1239 } catch (SAXException e1) {
1240 logger.debug ("[XAdESSignature.signAttached]::El fichero no es un XML: " + e1.getMessage());
1241 } catch (IOException e1) {
1242 logger.debug ("[XAdESSignature.signAttached]::El fichero no es un XML: " + e1.getMessage());
1243 }
1244
1245 DataToSign dataToSign;
1246 if (options.getNodeToSign() != null && documentToSign != null) {
1247
1248
1249 logger.debug ("[XAdESSignature.signAttached]::Se firmará el XML del usuario");
1250 dataToSign = createDataToSignAtached(documentToSign, options.getNodeToSign(),
1251 options.getSignatureParent(), null, certStatusRecover, tipoXAdES,
1252 options.getDof(), options.getClaimedRoles(), options.getPolicyIdentifier(),
1253 options.getProductionPlace(), options.getTsaHashingAlgorithm());
1254
1255 } else {
1256
1257 logger.debug ("[XAdESSignature.signAttached]::Construir la plantilla por defecto de XAdES");
1258
1259
1260 URI uri = null;
1261
1262
1263 Document doc;
1264 try {
1265 doc = db.parse(new Util().getClass().getClassLoader().getResourceAsStream(TEMPLATE_ARANGI_XADES));
1266 } catch (SAXException e) {
1267 logger.info("[XAdESSignature.signAttached]::No ha sido posible obtener la plantilla de Arangí-XAdES", e);
1268 throw new XMLDocumentException ("No ha sido posible obtener la plantilla de Arangí-XAdES", e);
1269 } catch (IOException e) {
1270 logger.info("[XAdESSignature.signAttached]::No ha sido posible obtener la plantilla de Arangí-XAdES", e);
1271 throw new XMLDocumentException ("No ha sido posible obtener la plantilla de Arangí-XAdES", e);
1272 }
1273
1274
1275 XPathFactory factory = XPathFactory.newInstance();
1276 XPath xpath = factory.newXPath();
1277 NodeList signatureNodes;
1278 try {
1279 XPathExpression expr = xpath.compile("//*[@Id='" + DEFAULT_ID_TAG_DOCUMENT + "']");
1280 signatureNodes = (NodeList) expr.evaluate (doc, XPathConstants.NODESET);
1281 } catch (XPathExpressionException e) {
1282 logger.info("[XAdESSignature.signAttached]::No ha sido posible obtener el elemento documento dentro de la plantilla", e);
1283 throw new XMLDocumentException ("No ha sido posible obtener el elemento documento dentro de la plantilla", e);
1284 }
1285 Element eDocument = (Element) signatureNodes.item(0);
1286
1287
1288 logger.debug ("[XAdESSignature.signAttached]::Añadir fichero en base64 a la plantilla");
1289 try {
1290 eDocument.appendChild(doc.createTextNode(Util.encodeBase64(Util.loadFile(tempFile))));
1291 uri = new URI (ConstantesXADES.URI_BASE_64);
1292 } catch (IOException e) {
1293 logger.info ("[XAdESSignature.signAttached]::No es posible leer el fichero temporal con el documento a firmar", e);
1294 throw new XMLDocumentException ("No es posible leer el fichero temporal con el documento a firmar", e);
1295 } catch (URISyntaxException e) {
1296
1297 logger.info ("[XAdESSignature.signAttached]::No es posible obtener la URI: " + ConstantesXADES.URI_BASE_64, e);
1298 }
1299
1300
1301 XAdESAttachedNodeToSign nodeToSign = options.getNodeToSign();
1302 if (nodeToSign == null) {
1303 nodeToSign = new XAdESAttachedNodeToSignObject(DEFAULT_ID_TAG_DOCUMENT);
1304 }
1305 dataToSign = createDataToSignAtached(doc, nodeToSign, null, uri, certStatusRecover, tipoXAdES,
1306 options.getDof(), options.getClaimedRoles(), options.getPolicyIdentifier(),
1307 options.getProductionPlace(), options.getTsaHashingAlgorithm());
1308
1309 }
1310
1311
1312 try {
1313 FirmaXML firma = new FirmaXML();
1314 if (tsaData != null) {
1315 firma.setTSA(tsaData.getUrl().toString());
1316 }
1317 Object[] res = firma.signFile(certificate, dataToSign, manager.getPrivateKey(alias), XAdESUtil.getXAdESDigitalSignatureAlgorithm(options.getDigitalSignatureAlgorithm()), null);
1318
1319
1320 Constructor<?> constructor = returnClassObject.getDeclaredConstructor(Document.class);
1321 return (XAdESSignature)constructor.newInstance((Document) res[0]);
1322
1323 } catch (Exception e) {
1324 logger.info("[XAdESSignature.sign]::No ha sido posible realizar la firma", e);
1325 throw new SignatureException ("No ha sido posible realizar la firma", e);
1326 }
1327
1328 } finally {
1329
1330 tempFile.delete();
1331 }
1332 }
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358 protected void coSign (DeviceManager manager, String alias, IDocument documentToSign, String digitalSignatureAlgorithm,
1359 URL urlTSA, ICertStatusRecoverer certStatusRecover, EnumFormatoFirma tipoXAdES,
1360 Class<?> returnClassObject) throws SignatureNotFoundException, NoDocumentToSignException,
1361 HashingException, LoadingObjectException, SignatureException, NoCoincidentDocumentException {
1362
1363 logger.debug("[XAdESSignature.coSign]::Entrada::" + Arrays.asList(new Object[] { manager, alias, documentToSign }));
1364
1365
1366
1367 String uriXmlNS = "http://www.w3.org/2000/09/xmldsig#";
1368 NodeList signatureList = xadesDocument.getElementsByTagNameNS(uriXmlNS, "Signature");
1369 String signatureParent = null;
1370 Node nodeSignature = null;
1371 if (signatureList.getLength() < 1) {
1372 logger.info("[XAdESSignature.coSign]:: No existe ninguna firma en el XAdES");
1373 throw new SignatureNotFoundException("No existe ninguna firma en el XAdES");
1374 } else {
1375 nodeSignature = signatureList.item(0);
1376 signatureParent = nodeSignature.getParentNode().getLocalName();
1377 }
1378
1379 logger.debug("[XAdESSignature.coSign]:: Obtenido el nodo de firma");
1380
1381
1382 byte[] hashReference = null;
1383 boolean attached = false;
1384 XAdESAttachedNodeToSignObject idToSign = null;
1385 try {
1386 XMLSignature firmaDocumento = new XMLSignature((Element)nodeSignature, "./");
1387 SignedInfo signedInfo = firmaDocumento.getSignedInfo();
1388 for(int i = 0; i < signedInfo.getLength(); i++){
1389 Reference ref = signedInfo.item(i);
1390 if (ref.getId().startsWith("Reference-ID")) {
1391 String uri = ref.getURI();
1392 if (uri.startsWith("#")) {
1393
1394 logger.debug("[XAdESSignature.coSign]:: Se trata de una firma attached");
1395 attached = true;
1396
1397 idToSign = new XAdESAttachedNodeToSignObject(uri.substring(1, uri.length()));
1398
1399 } else {
1400
1401 logger.debug("[XAdESSignature.coSign]:: Se trata de una firma detached");
1402 if (documentToSign == null) {
1403
1404
1405 if (uri.startsWith("file:/")) {
1406 logger.debug("[XAdESSignature.coSign]:: Se trata de una firma detached referencia a un fichero: " + uri);
1407 File file = new File (uri.substring(6));
1408 if (file.exists()) {
1409 try {
1410 documentToSign = new FileDocument(file);
1411 logger.debug("[XAdESSignature.coSign]:: El fichero existe: " + file);
1412 } catch (InitDocumentException e) {
1413
1414 }
1415 } else {
1416 logger.debug("[XAdESSignature.coSign]:: El fichero no existe: " + file);
1417 }
1418 }
1419
1420 if (uri.startsWith("http://") || uri.startsWith("https://")) {
1421 logger.debug("[XAdESSignature.coSign]:: Se trata de una firma detached referencia a una URL: " + uri);
1422 try {
1423 documentToSign = new URLDocument(new URL (uri));
1424 } catch (InitDocumentException e) {
1425 logger.info("[XAdESSignature.coSign]:: No es posible conectarse a la URL: " + uri);
1426 } catch (MalformedURLException e) {
1427 logger.info("[XAdESSignature.coSign]:: La URL está mal formada: " + uri);
1428 }
1429 }
1430
1431
1432 if (documentToSign == null) {
1433 throw new NoDocumentToSignException("Es necesario proporcionar un documento ya que la referencia a este no es suficiente");
1434 }
1435 }
1436
1437 idToSign = new XAdESAttachedNodeToSignObject(uri);
1438 hashReference = ref.getDigestValue();
1439 }
1440 }
1441 }
1442 } catch (XMLSecurityException e) {
1443 logger.info("[XAdESSignature.coSign]::Error buscando elementos en el fichero XAdES", e);
1444 throw new SignatureException("Error buscando elementos en el fichero XAdES", e);
1445 }
1446
1447
1448 if (hashReference != null) {
1449 logger.debug("[XAdESSignature.coSign]:: La referencia es un path. Comprobamos que los documentos coincidan");
1450 try {
1451 byte[] hashDoc = documentToSign.getHash();
1452 if (!(new String(hashDoc)).equalsIgnoreCase(new String(hashReference))) {
1453 throw new NoCoincidentDocumentException("El hash del documento proporcionado no coincide con el de la firma existente");
1454 }
1455 } catch (HashingException e) {
1456 throw new HashingException("No se ha podido calcular el hash del documento");
1457 }
1458
1459 }
1460
1461 DataToSign dataToSign = null;
1462 if (attached) {
1463 dataToSign = createDataToSignAtached(xadesDocument, idToSign, null, null, certStatusRecover, tipoXAdES, null, null, null, null, null);
1464 } else {
1465 dataToSign = createDataToSignDetached(documentToSign, idToSign.getIdToSign(), certStatusRecover, tipoXAdES, null, null, null, null, null);
1466 }
1467
1468
1469 X509Certificate certificate;
1470 try {
1471 logger.debug ("[XAdESSignature.coSign]::obteniendo el certificado");
1472 certificate = manager.getCertificate(alias);
1473 } catch (SearchingException e) {
1474 logger.info("[XAdESSignature.coSign]::No se ha podido encontrar un certificado en el alias'" + alias + "'", e);
1475 throw new LoadingObjectException ("No se ha podido encontrar un certificado en el alias'" + alias + "'", e);
1476 }
1477
1478 try {
1479 FirmaXML firma = new FirmaXML();
1480 if (urlTSA != null) { firma.setTSA(urlTSA.toString()); }
1481
1482 logger.debug("[XAdESSignature.coSign]:: Realizando la firma");
1483 Object[] res = firma.signFile(certificate, dataToSign, manager.getPrivateKey(alias), XAdESUtil.getXAdESDigitalSignatureAlgorithm(digitalSignatureAlgorithm), null);
1484 Constructor<?> constructor = returnClassObject.getDeclaredConstructor(Document.class);
1485 XAdESSignature xades = (XAdESSignature)constructor.newInstance((Document) res[0]);
1486 logger.debug("[XAdESSignature.coSign]:: Firma realizada");
1487 if (attached) {
1488
1489 xadesDocument = xades.getDOM();
1490 } else {
1491 logger.debug("[XAdESSignature.coSign]:: Añadimos la nueva firma al XAdES");
1492
1493 NodeList signaturesList = xades.getDOM().getElementsByTagNameNS(uriXmlNS, "Signature");
1494
1495 Node signature = signaturesList.item(0);
1496
1497 Element rootDocument = xadesDocument.getDocumentElement();
1498 if (rootDocument.isEqualNode(xadesDocument.getElementsByTagNameNS(uriXmlNS, "Signature").item(0))) {
1499 logger.debug("[XAdESSignature.coSign]:: La firma es nodo raiz. Cramos un nuevo nodo raiz Signatures");
1500
1501
1502 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
1503 DocumentBuilder builder = dbf.newDocumentBuilder();
1504
1505
1506 Document doc = builder.newDocument();
1507
1508 Element root = doc.createElement("Signatures");
1509 doc.appendChild(root);
1510
1511
1512 Node oldSignature = doc.importNode((xadesDocument.getElementsByTagNameNS(uriXmlNS, "Signature").item(0)), true);
1513 root.appendChild(oldSignature);
1514 Node newSignature = doc.importNode(signature, true);
1515 root.appendChild(newSignature);
1516
1517 xadesDocument = doc;
1518
1519 } else {
1520
1521
1522 NodeList siganturesList = xadesDocument.getElementsByTagNameNS(uriXmlNS, "Signature");
1523 Node parentNode = siganturesList.item(0).getParentNode();
1524 Node newSignature = xadesDocument.importNode(signature, true);
1525 parentNode.appendChild(newSignature);
1526 }
1527
1528 }
1529
1530 } catch (Exception e) {
1531 logger.info("[XAdESSignature.coSign]::No ha sido posible realizar la firma", e);
1532 throw new SignatureException ("No ha sido posible realizar la firma", e);
1533 }
1534 }
1535
1536
1537
1538
1539 protected static Date getXsdDateTimeParse(String sDate) throws ParseException {
1540
1541 Date date = xsdDateTimeFormat.parse(sDate.substring (0,19));
1542
1543 GregorianCalendar cal = new GregorianCalendar();
1544 cal.setTime(date);
1545
1546 return cal.getTime();
1547 }
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561 protected static Document addXadesT(Element firma, String firmaID, byte[] selloTiempo,
1562 String namespace) throws Exception {
1563
1564 Document doc = firma.getOwnerDocument();
1565 Element elementoPrincipal = null ;
1566 NodeList nodos = firma.getElementsByTagNameNS(DEFAULT_XADES_SCHEMA_URI, ConstantesXADES.QUALIFYING_PROPERTIES);
1567 if(nodos.getLength() != 0)
1568 elementoPrincipal = (Element)nodos.item(0);
1569 else
1570 throw new Exception("El XML no parece un XAdES") ;
1571
1572 Element propiedadesElementosNoFirmados =
1573 doc.createElementNS(DEFAULT_XADES_SCHEMA_URI, namespace + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.UNSIGNED_PROPERTIES);
1574
1575
1576 Attr propiedadesNoFirmadasId = doc.createAttributeNS(null, ConstantesXADES.ID);
1577 propiedadesNoFirmadasId.setValue(UtilidadTratarNodo.newID(doc,
1578 firmaID + ConstantesXADES.GUION_UNSIGNED_PROPERTIES));
1579 NamedNodeMap atributosSinFirmarPropiedadesElemento =
1580 propiedadesElementosNoFirmados.getAttributes();
1581 atributosSinFirmarPropiedadesElemento.setNamedItem(propiedadesNoFirmadasId);
1582
1583 Element propiedadesSinFirmarFirmaElementos =
1584 doc.createElementNS(DEFAULT_XADES_SCHEMA_URI, namespace + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.UNSIGNED_SIGNATURE_PROPERTIES);
1585
1586
1587 NodeList sellosPreexistentes = doc.getElementsByTagNameNS(DEFAULT_XADES_SCHEMA_URI, ConstantesXADES.SIGNATURE_TIME_STAMP);
1588 int numSellos = sellosPreexistentes.getLength();
1589 ArrayList<String> idNodoSelloTiempo = new ArrayList<String>();
1590 for (int i = 0; i < numSellos; ++i) {
1591 Element sello = (Element) sellosPreexistentes.item(i);
1592 String selloId = sello.getAttribute(ConstantesXADES.ID);
1593 if (selloId == null) {
1594 Attr informacionElementoSigTimeStamp = doc.createAttributeNS(null, ConstantesXADES.ID);
1595 selloId = UtilidadTratarNodo.newID(doc, ConstantesXADES.SELLO_TIEMPO);
1596 informacionElementoSigTimeStamp.setValue(selloId);
1597 sello.getAttributes().setNamedItem(informacionElementoSigTimeStamp);
1598 }
1599
1600 idNodoSelloTiempo.add(selloId);
1601 }
1602
1603
1604 Element tiempoSelloElementoFirma =
1605 doc.createElementNS(DEFAULT_XADES_SCHEMA_URI, namespace + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.SIGNATURE_TIME_STAMP);
1606
1607
1608 Attr informacionElementoSigTimeStamp = doc.createAttributeNS(null, ConstantesXADES.ID);
1609 String idSelloTiempo = UtilidadTratarNodo.newID(doc, ConstantesXADES.SELLO_TIEMPO);
1610 informacionElementoSigTimeStamp.setValue(idSelloTiempo);
1611 idNodoSelloTiempo.add(idSelloTiempo);
1612 tiempoSelloElementoFirma.getAttributes().setNamedItem(informacionElementoSigTimeStamp);
1613
1614
1615 if (ConstantesXADES.SCHEMA_XADES_111.equals(DEFAULT_XADES_SCHEMA_URI)
1616 || ConstantesXADES.SCHEMA_XADES_122.equals(DEFAULT_XADES_SCHEMA_URI)) {
1617
1618 String nombreNodoUri = null;
1619 String tipoUri = null;
1620 if (ConstantesXADES.SCHEMA_XADES_111.equals(DEFAULT_XADES_SCHEMA_URI)) {
1621 nombreNodoUri = ConstantesXADES.HASH_DATA_INFO;
1622 tipoUri = ConstantesXADES.URI_MINUS;
1623 } else {
1624 nombreNodoUri = ConstantesXADES.INCLUDE;
1625 tipoUri = ConstantesXADES.URI_MAYUS;
1626 }
1627
1628 ArrayList<Element> listElements = UtilidadTratarNodo.obtenerNodos(firma, 2, new NombreNodo(ConstantesXADES.SCHEMA_DSIG, ConstantesXADES.SIGNATURE_VALUE));
1629 if (listElements.size() != 1) {
1630 logger.info("No se encuentra el tag de firma en el XML");
1631 throw new Exception("No se encuentra el tag de firma en el XML");
1632 }
1633 String idSignatureValue = listElements.get(0).getAttribute(ConstantesXADES.ID);
1634
1635
1636 Element informacionElementoHashDatos = doc.createElementNS(DEFAULT_XADES_SCHEMA_URI, namespace + ConstantesXADES.DOS_PUNTOS + nombreNodoUri);
1637
1638 Attr informacionElementoHashDatosUri = doc.createAttributeNS(null, tipoUri);
1639 informacionElementoHashDatosUri.setValue(ConstantesXADES.ALMOHADILLA + idSignatureValue);
1640
1641 NamedNodeMap informacionAtributosElementoHashDatos = informacionElementoHashDatos.getAttributes();
1642 informacionAtributosElementoHashDatos.setNamedItem(informacionElementoHashDatosUri);
1643
1644 tiempoSelloElementoFirma.appendChild(informacionElementoHashDatos) ;
1645 }
1646
1647
1648 if (!ConstantesXADES.SCHEMA_XADES_111.equals(DEFAULT_XADES_SCHEMA_URI)) {
1649 Element canonicalizationElemento = doc.createElementNS(ConstantesXADES.SCHEMA_DSIG, xmldsigNS + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.CANONICALIZATION_METHOD);
1650 Attr canonicalizationAttribute = doc.createAttributeNS(null, ConstantesXADES.ALGORITHM);
1651 canonicalizationAttribute.setValue(Transforms.TRANSFORM_C14N_OMIT_COMMENTS);
1652 canonicalizationElemento.getAttributes().setNamedItem(canonicalizationAttribute);
1653
1654 tiempoSelloElementoFirma.appendChild(canonicalizationElemento);
1655 }
1656
1657
1658 Element tiempoSelloEncapsulado =
1659 doc.createElementNS(DEFAULT_XADES_SCHEMA_URI, namespace + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.ENCAPSULATED_TIME_STAMP);
1660
1661 tiempoSelloEncapsulado.appendChild(
1662 doc.createTextNode(new String(Base64Coder.encode(selloTiempo))));
1663 Attr tiempoSelloEncapsuladoId = doc.createAttributeNS(null, ConstantesXADES.ID);
1664 String idEncapsulated = UtilidadTratarNodo.newID(doc, ConstantesXADES.SELLO_TIEMPO_TOKEN);
1665 tiempoSelloEncapsuladoId.setValue(idEncapsulated);
1666 tiempoSelloEncapsulado.getAttributes().setNamedItem(tiempoSelloEncapsuladoId);
1667
1668
1669 tiempoSelloElementoFirma.appendChild(tiempoSelloEncapsulado);
1670
1671 propiedadesSinFirmarFirmaElementos.appendChild(tiempoSelloElementoFirma);
1672 propiedadesElementosNoFirmados.appendChild(propiedadesSinFirmarFirmaElementos);
1673 elementoPrincipal.appendChild(propiedadesElementosNoFirmados);
1674 return doc;
1675 }
1676
1677
1678
1679
1680 protected static Document addXadesC(Element firma, ArrayList<RespYCerts> respuestasFirma,
1681 ArrayList<RespYCerts> respuestasSello, XAdESSchemas schema, String algDigestXML,
1682 String namespace) throws Exception {
1683 Document doc = firma.getOwnerDocument();
1684
1685
1686 Element elementoPrincipal = null ;
1687
1688 String tipoUri = null;
1689 if (ConstantesXADES.SCHEMA_XADES_111.equals(DEFAULT_XADES_SCHEMA_URI)) {
1690 tipoUri = ConstantesXADES.URI_MINUS;
1691 } else {
1692 tipoUri = ConstantesXADES.URI_MAYUS;
1693 }
1694
1695 NodeList nodos = firma.getElementsByTagNameNS(DEFAULT_XADES_SCHEMA_URI, ConstantesXADES.UNSIGNED_SIGNATURE_PROPERTIES);
1696 if(nodos.getLength() != 0)
1697 {
1698 elementoPrincipal = (Element)nodos.item(0);
1699 }
1700 else
1701 {
1702 throw new Exception("El XML no parece un XAdES") ;
1703 }
1704
1705
1706 Element certificadosElementosFirma =
1707 doc.createElementNS(DEFAULT_XADES_SCHEMA_URI, namespace + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.COMPLETE_CERTIFICATE_REFS);
1708 Element revocacionesElementoFirma =
1709 doc.createElementNS(DEFAULT_XADES_SCHEMA_URI, namespace + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.COMPLETE_REVOCATION_REFS);
1710
1711 if(respuestasFirma != null && !respuestasFirma.isEmpty()) {
1712
1713
1714 Attr informacionElementoCertRef = doc.createAttributeNS(null, ConstantesXADES.ID);
1715 String idNodoCertificateRefs = UtilidadTratarNodo.newID(doc, ConstantesXADES.COMPLETE_CERTIFICATE_REFS);
1716 informacionElementoCertRef.setValue(idNodoCertificateRefs);
1717 certificadosElementosFirma.getAttributes().setNamedItem(informacionElementoCertRef);
1718
1719 Element elementoCertRefs =
1720 doc.createElementNS(DEFAULT_XADES_SCHEMA_URI, namespace + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.CERT_REFS);
1721
1722 certificadosElementosFirma.appendChild(elementoCertRefs);
1723
1724 Set<X509Certificate> setCertificadosIncluidos = new HashSet<X509Certificate>();
1725 ArrayList[] listas = new ArrayList[] { respuestasFirma, respuestasSello };
1726 boolean primero = true;
1727 for (int x=0;x<2;x++) {
1728
1729 ArrayList<RespYCerts> respuestas = listas[x];
1730
1731 int i = -1;
1732 for (RespYCerts respYCerts : respuestas) {
1733 i++;
1734
1735
1736 String idNueva = UtilidadTratarNodo.newID(doc, ConstantesXADES.LIBRERIAXADES_CERT_PATH);
1737 respuestas.get(i).setIdCertificado(idNueva);
1738
1739 if (primero) {
1740 primero = false;
1741 continue;
1742 }
1743
1744 X509Certificate firmaCertificado = respYCerts.getCertstatus().getCertificate();
1745 if (setCertificadosIncluidos.contains(firmaCertificado)) {
1746 continue;
1747 }
1748 setCertificadosIncluidos.add(firmaCertificado);
1749
1750 Element elementCertRef = doc.createElementNS(DEFAULT_XADES_SCHEMA_URI, namespace + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.CERT);
1751
1752
1753 Attr uris = doc.createAttributeNS(null, tipoUri);
1754
1755 idNueva = UtilidadTratarNodo.newID(doc, ConstantesXADES.LIBRERIAXADES_CERT_PATH);
1756 uris.setValue( ConstantesXADES.ALMOHADILLA + idNueva );
1757 respuestas.get(i).setIdCertificado(idNueva);
1758 NamedNodeMap atributosURI = elementCertRef.getAttributes();
1759 atributosURI.setNamedItem(uris);
1760
1761 Element resumenElementoCert = doc.createElementNS(DEFAULT_XADES_SCHEMA_URI, namespace + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.CERT_DIGEST);
1762
1763
1764 Element metodoResumenElemento = doc.createElementNS(ConstantesXADES.SCHEMA_DSIG, xmldsigNS + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.DIGEST_METHOD);
1765
1766
1767 Attr propiedadesFirmaAlgoritmo = doc.createAttributeNS(null, ConstantesXADES.ALGORITHM);
1768 propiedadesFirmaAlgoritmo.setValue(algDigestXML);
1769 NamedNodeMap cualidadesMetodoResumenElemento =
1770 metodoResumenElemento.getAttributes();
1771 cualidadesMetodoResumenElemento.setNamedItem(propiedadesFirmaAlgoritmo);
1772
1773
1774 String resumenCertificado = ConstantesXADES.CADENA_VACIA;
1775 try
1776 {
1777 MessageDigest resumenCertificadoTemp = UtilidadFirmaElectronica.getMessageDigest(algDigestXML);
1778 if (resumenCertificadoTemp == null)
1779 throw new Exception("No se ha podido realizar el digest");
1780 byte[] resumenMensajeByte =resumenCertificadoTemp.digest(firmaCertificado.getEncoded());
1781 resumenCertificado = new String(Base64Coder.encode(resumenMensajeByte));
1782 } catch (CertificateEncodingException e) {
1783 logger.error(e);
1784 throw new Exception("Error obteniendo la huella del certificado");
1785 }
1786
1787 Element elementDigestValue =
1788 doc.createElementNS(ConstantesXADES.SCHEMA_DSIG, xmldsigNS + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.DIGEST_VALUE);
1789 elementDigestValue.appendChild(
1790 doc.createTextNode(resumenCertificado));
1791
1792
1793 Element elementoEmisorSerial =
1794 doc.createElementNS(DEFAULT_XADES_SCHEMA_URI, namespace + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.ISSUER_SERIAL);
1795
1796 Element elementoX509EmisorNombre =
1797 doc.createElementNS(ConstantesXADES.SCHEMA_DSIG, xmldsigNS + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.X_509_ISSUER_NAME);
1798 elementoX509EmisorNombre.appendChild(
1799 doc.createTextNode(firmaCertificado.getIssuerX500Principal().getName()));
1800
1801
1802 Element elementoX509NumeroSerial =
1803 doc.createElementNS(ConstantesXADES.SCHEMA_DSIG, xmldsigNS + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.X_509_SERIAL_NUMBER);
1804 elementoX509NumeroSerial.appendChild(
1805 doc.createTextNode(firmaCertificado.getSerialNumber().toString()));
1806
1807
1808 elementoEmisorSerial.appendChild(elementoX509EmisorNombre);
1809 elementoEmisorSerial.appendChild(elementoX509NumeroSerial);
1810
1811 resumenElementoCert.appendChild(metodoResumenElemento);
1812 resumenElementoCert.appendChild(elementDigestValue);
1813
1814 elementCertRef.appendChild(resumenElementoCert);
1815 elementCertRef.appendChild(elementoEmisorSerial);
1816
1817 elementoCertRefs.appendChild(elementCertRef);
1818 }
1819 }
1820 }
1821
1822
1823
1824 Element elementOCSPRef = null;
1825 String tiempoRespuesta = null;
1826 byte[] mensajeRespuesta = null;
1827
1828 if(respuestasFirma != null && !respuestasFirma.isEmpty()) {
1829
1830
1831 Attr informacionElementoCertRef = doc.createAttributeNS(null, ConstantesXADES.ID);
1832 String idNodoRevocationRefs = UtilidadTratarNodo.newID(doc, ConstantesXADES.COMPLETE_REVOCATION_REFS);
1833 informacionElementoCertRef.setValue(idNodoRevocationRefs);
1834 revocacionesElementoFirma.getAttributes().setNamedItem(informacionElementoCertRef);
1835
1836 int nOCSPRefs = 0;
1837 int nCRLRefs = 0;
1838
1839
1840
1841 Element elementOCSPRefs =
1842 doc.createElementNS(DEFAULT_XADES_SCHEMA_URI, namespace + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.OCSP_REFS);
1843 CRLRefs elementCRLRefs = new CRLRefs(schema);
1844
1845 Set<X509Certificate> setCertificadosIncluidos = new HashSet<X509Certificate>();
1846 ArrayList[] listas = new ArrayList[] { respuestasFirma, respuestasSello };
1847 for (int x=0;x<2;x++) {
1848
1849 ArrayList<RespYCerts> respuestas = listas[x];
1850
1851 for (RespYCerts respYCerts : respuestas) {
1852
1853 X509Certificate firmaCertificado = respYCerts.getCertstatus().getCertificate();
1854 if (setCertificadosIncluidos.contains(firmaCertificado)) {
1855 continue;
1856 }
1857 setCertificadosIncluidos.add(firmaCertificado);
1858
1859 ICertStatus certStatus = respYCerts.getCertstatus();
1860 if (certStatus instanceof IOCSPCertStatus) {
1861 nOCSPRefs++;
1862 IOCSPCertStatus respOcsp = (IOCSPCertStatus) certStatus;
1863
1864 tiempoRespuesta = UtilidadFechas.formatFechaXML(respOcsp.getResponseDate());
1865 IOCSPCertStatus.TYPE_RESPONDER tipoResponder = respOcsp.getResponderType();
1866 String valorResponder = respOcsp.getResponderID();
1867 mensajeRespuesta = respOcsp.getEncoded();
1868
1869 elementOCSPRef = doc.createElementNS(DEFAULT_XADES_SCHEMA_URI, namespace + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.OCSP_REF);
1870
1871
1872 String idNueva = UtilidadTratarNodo.newID(doc, ConstantesXADES.OCSP);
1873 respYCerts.setIdRespStatus(idNueva);
1874
1875 Element identificadorElementoOCSP = doc.createElementNS(DEFAULT_XADES_SCHEMA_URI, namespace + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.OCSP_IDENTIFIER);
1876 Attr uris = doc.createAttributeNS(null, tipoUri);
1877 uris.setValue( ConstantesXADES.ALMOHADILLA + idNueva );
1878 NamedNodeMap atributosURI = identificadorElementoOCSP.getAttributes();
1879 atributosURI.setNamedItem(uris);
1880
1881
1882 Element elementoRespondedorId = doc.createElementNS(DEFAULT_XADES_SCHEMA_URI, namespace + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.RESPONDER_ID);
1883
1884
1885 Element responderFinal = elementoRespondedorId;
1886 if (!(ConstantesXADES.SCHEMA_XADES_111.equals(DEFAULT_XADES_SCHEMA_URI)) && !(ConstantesXADES.SCHEMA_XADES_122.equals(DEFAULT_XADES_SCHEMA_URI))) {
1887 Element hijo = null;
1888 if (tipoResponder.equals(IOCSPCertStatus.TYPE_RESPONDER.BY_NAME)) {
1889 hijo = doc.createElementNS(DEFAULT_XADES_SCHEMA_URI, namespace + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.BY_NAME);
1890 }
1891 else {
1892 hijo = doc.createElementNS(DEFAULT_XADES_SCHEMA_URI, namespace + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.BY_KEY);
1893 }
1894
1895 elementoRespondedorId.appendChild(hijo);
1896 responderFinal = hijo;
1897 }
1898 responderFinal.appendChild(doc.createTextNode(valorResponder));
1899
1900
1901 Element elementoProdujoEn = doc.createElementNS(DEFAULT_XADES_SCHEMA_URI, namespace + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.PRODUCE_AT);
1902
1903
1904 elementoProdujoEn.appendChild(doc.createTextNode(tiempoRespuesta));
1905
1906 identificadorElementoOCSP.appendChild(elementoRespondedorId);
1907 identificadorElementoOCSP.appendChild(elementoProdujoEn);
1908 Element valorYResumenElemento = doc.createElementNS(DEFAULT_XADES_SCHEMA_URI, namespace + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.DIGEST_ALG_AND_VALUE);
1909
1910
1911 Element metodoResumenElemento = doc.createElementNS(ConstantesXADES.SCHEMA_DSIG, xmldsigNS + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.DIGEST_METHOD);
1912
1913
1914 Attr propiedadesAlgoritmoFirmado = doc.createAttributeNS(null, ConstantesXADES.ALGORITHM);
1915 propiedadesAlgoritmoFirmado.setValue(algDigestXML);
1916 NamedNodeMap atributosMetodoResumenElemento = metodoResumenElemento.getAttributes();
1917 atributosMetodoResumenElemento.setNamedItem(propiedadesAlgoritmoFirmado);
1918
1919
1920
1921 String digestCertificado =ConstantesXADES.CADENA_VACIA;
1922 MessageDigest resumenCertificadoTemp = UtilidadFirmaElectronica.getMessageDigest(algDigestXML);
1923 if (resumenCertificadoTemp == null)
1924 throw new Exception("No se ha podido generar el digest");
1925 byte[] resumenMensajeByte = resumenCertificadoTemp.digest(mensajeRespuesta);
1926 digestCertificado = new String(Base64Coder.encode(resumenMensajeByte));
1927
1928 Element valorResumenElemento = doc.createElementNS(ConstantesXADES.SCHEMA_DSIG, xmldsigNS + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.DIGEST_VALUE);
1929
1930 valorResumenElemento.appendChild(doc.createTextNode(digestCertificado));
1931
1932 valorYResumenElemento.appendChild(metodoResumenElemento);
1933 valorYResumenElemento.appendChild(valorResumenElemento);
1934
1935 elementOCSPRef.appendChild(identificadorElementoOCSP);
1936 elementOCSPRef.appendChild(valorYResumenElemento);
1937
1938 elementOCSPRefs.appendChild(elementOCSPRef);
1939 }
1940 else if (certStatus instanceof IX509CRLCertStatus) {
1941 nCRLRefs++;
1942 IX509CRLCertStatus respCRL = (IX509CRLCertStatus) certStatus;
1943 try {
1944 CRLRef crlRef = new CRLRef(schema, algDigestXML, respCRL.getX509CRL());
1945
1946 String idNueva = UtilidadTratarNodo.newID(doc, ConstantesXADES.CRL);
1947 crlRef.getCrlIdentifier().setUri(ConstantesXADES.ALMOHADILLA + idNueva);
1948 respYCerts.setIdRespStatus(idNueva);
1949
1950 elementCRLRefs.addCRLRef(crlRef);
1951 } catch (InvalidInfoNodeException ex) {
1952 throw new Exception("No se pudo construir las referencias a CRLs", ex);
1953 }
1954 }
1955 }
1956 }
1957
1958 if (nCRLRefs > 0) {
1959 try {
1960 Element el = elementCRLRefs.createElement(doc, xmldsigNS, namespace);
1961 revocacionesElementoFirma.appendChild(el);
1962 } catch (InvalidInfoNodeException ex) {
1963 throw new Exception("No se pudo construir las referencias a CRLs", ex);
1964 }
1965 }
1966
1967 if (nOCSPRefs > 0)
1968 revocacionesElementoFirma.appendChild(elementOCSPRefs);
1969
1970 }
1971
1972 elementoPrincipal.appendChild(certificadosElementosFirma);
1973 elementoPrincipal.appendChild(revocacionesElementoFirma);
1974
1975 return doc;
1976 }
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997 protected static Document addXadesX(Element unsignedSignatureProperties, URL servidorTSA,
1998 String algoritmoTSA, String namespace) throws Exception {
1999
2000
2001 Document doc = unsignedSignatureProperties.getOwnerDocument();
2002
2003
2004 Element sigAndRefsTimeStampElement =
2005 doc.createElementNS(DEFAULT_XADES_SCHEMA_URI, namespace + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.SIG_AND_REFS_TIME_STAMP);
2006
2007
2008 Attr informacionElementoSigTimeStamp = doc.createAttributeNS(null, ConstantesXADES.ID);
2009 String idSelloTiempo = UtilidadTratarNodo.newID(doc, ConstantesXADES.SELLO_TIEMPO);
2010 informacionElementoSigTimeStamp.setValue(idSelloTiempo);
2011 ArrayList<String> idNodoSelloTiempo = new ArrayList<String>();
2012 idNodoSelloTiempo.add(idSelloTiempo);
2013 sigAndRefsTimeStampElement.getAttributes().setNamedItem(informacionElementoSigTimeStamp);
2014
2015
2016 unsignedSignatureProperties.appendChild(sigAndRefsTimeStampElement);
2017
2018 return addXadesX(unsignedSignatureProperties, sigAndRefsTimeStampElement, servidorTSA, algoritmoTSA, namespace);
2019 }
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041 protected static Document addXadesX(Element unsignedSignatureProperties, Element sigAndRefsTimeStampElement,
2042 URL servidorTSA, String algoritmoTSA, String namespace) throws Exception {
2043
2044
2045 String tipoUri = null;
2046 String nombreNodoUri = null;
2047 if (ConstantesXADES.SCHEMA_XADES_111.equals(DEFAULT_XADES_SCHEMA_URI)){
2048 nombreNodoUri = ConstantesXADES.HASH_DATA_INFO;
2049 tipoUri = ConstantesXADES.URI_MINUS;
2050 } else {
2051 nombreNodoUri = ConstantesXADES.INCLUDE;
2052 tipoUri = ConstantesXADES.URI_MAYUS;
2053 }
2054
2055
2056 Document doc = unsignedSignatureProperties.getOwnerDocument();
2057
2058
2059 Node padre = unsignedSignatureProperties.getParentNode();
2060 for (int i = 0; i < 3; ++i) {
2061 if (padre != null)
2062 padre = padre.getParentNode();
2063 else
2064
2065 throw new Exception("No se encuentra el nodo signature");
2066 }
2067
2068 Element signatureElement = null;
2069 if (padre != null && ConstantesXADES.SIGNATURE.equals(padre.getLocalName()))
2070 signatureElement = (Element)padre;
2071 else
2072
2073 throw new Exception("No se encuentra el nodo signature");
2074
2075
2076
2077 ArrayList<Element> elementosSelloX = null;
2078 try {
2079 elementosSelloX = UtilidadXadesX.obtenerListadoXADESX1imp(DEFAULT_XADES_SCHEMA_URI, signatureElement, sigAndRefsTimeStampElement);
2080 } catch (BadFormedSignatureException e) {
2081 throw new Exception(e.getMessage(), e);
2082 } catch (FirmaXMLError e) {
2083 throw new Exception(e.getMessage(), e);
2084 }
2085
2086
2087 if (ConstantesXADES.SCHEMA_XADES_111.equals(DEFAULT_XADES_SCHEMA_URI) ||
2088 ConstantesXADES.SCHEMA_XADES_122.equals(DEFAULT_XADES_SCHEMA_URI)) {
2089
2090 ArrayList<String> elementosIdSelloX = UtilidadTratarNodo.obtenerIDs(elementosSelloX);
2091
2092
2093 ArrayList<Element> nodosUriReferencia = new ArrayList<Element> (elementosIdSelloX.size());
2094 Iterator<String> itIds = elementosIdSelloX.iterator();
2095 while (itIds.hasNext()) {
2096 String id = itIds.next();
2097 Element uriNode =
2098 doc.createElementNS(DEFAULT_XADES_SCHEMA_URI, namespace + ConstantesXADES.DOS_PUNTOS + nombreNodoUri);
2099 Attr includeNodeUri = doc.createAttributeNS(null, tipoUri);
2100 includeNodeUri.setValue(ConstantesXADES.ALMOHADILLA + id);
2101 NamedNodeMap atributosNodo = uriNode.getAttributes();
2102 atributosNodo.setNamedItem(includeNodeUri);
2103
2104 nodosUriReferencia.add(uriNode);
2105 }
2106
2107
2108 Iterator<Element> itUrisReferencia = nodosUriReferencia.iterator();
2109 while (itUrisReferencia.hasNext()) {
2110 Element includeNode = itUrisReferencia.next();
2111 sigAndRefsTimeStampElement.appendChild(includeNode);
2112 }
2113 }
2114
2115
2116 byte[] byteData = null;
2117 try {
2118 byteData = UtilidadTratarNodo.obtenerByte(elementosSelloX, CanonicalizationEnum.C14N_OMIT_COMMENTS);
2119 } catch (FirmaXMLError e) {
2120 throw new Exception(e.getMessage(), e);
2121 }
2122
2123
2124 TSCliente tsCli = null;
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136 TimeStamp timeStamp = TimeStamp.stampDocument(byteData, servidorTSA);
2137 String hashSelloX = Util.encodeBase64(timeStamp.toDER());
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150 if (!ConstantesXADES.SCHEMA_XADES_111.equals(DEFAULT_XADES_SCHEMA_URI)) {
2151 Element canonicalizationElemento = doc.createElementNS(ConstantesXADES.SCHEMA_DSIG, xmldsigNS + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.CANONICALIZATION_METHOD);
2152 Attr canonicalizationAttribute = doc.createAttributeNS(null, ConstantesXADES.ALGORITHM);
2153 canonicalizationAttribute.setValue(Transforms.TRANSFORM_C14N_OMIT_COMMENTS);
2154 canonicalizationElemento.getAttributes().setNamedItem(canonicalizationAttribute);
2155
2156 sigAndRefsTimeStampElement.appendChild(canonicalizationElemento);
2157 }
2158
2159
2160 Element encapsulatedTimeStampNode =
2161 doc.createElementNS(DEFAULT_XADES_SCHEMA_URI, namespace + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.ENCAPSULATED_TIME_STAMP);
2162 encapsulatedTimeStampNode.appendChild(doc.createTextNode(hashSelloX));
2163 sigAndRefsTimeStampElement.appendChild(encapsulatedTimeStampNode);
2164
2165 return doc;
2166 }
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182 protected static Document addXadesX2(Element UnsignedSignatureProperties, String servidorTSA,
2183 String algoritmoTSA, String namespace) throws Exception {
2184
2185 String tipoUri = null;
2186 String nombreNodoUri = null;
2187 if (ConstantesXADES.SCHEMA_XADES_111.equals(DEFAULT_XADES_SCHEMA_URI)){
2188 nombreNodoUri = ConstantesXADES.HASH_DATA_INFO;
2189 tipoUri = ConstantesXADES.URI_MINUS;
2190 } else {
2191 nombreNodoUri = ConstantesXADES.INCLUDE;
2192 tipoUri = ConstantesXADES.URI_MAYUS;
2193 }
2194
2195
2196 Document doc = UnsignedSignatureProperties.getOwnerDocument();
2197
2198
2199 Node padre = UnsignedSignatureProperties.getParentNode();
2200 for (int i = 0; i < 3; ++i) {
2201 if (padre != null)
2202 padre = padre.getParentNode();
2203 else
2204
2205 throw new Exception("No se encuentra el nodo Signature");
2206 }
2207
2208 Element signatureElement = null;
2209 if (padre != null && ConstantesXADES.SIGNATURE.equals(padre.getLocalName()))
2210 signatureElement = (Element)padre;
2211 else
2212
2213 throw new Exception("No se encuentra el nodo Signature");
2214
2215
2216 Element refsOnlyTimeStampElement =
2217 doc.createElementNS(DEFAULT_XADES_SCHEMA_URI, namespace + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.REFS_ONLY_TIME_STAMP);
2218
2219
2220 Attr informacionElementoSigTimeStamp = doc.createAttributeNS(null, ConstantesXADES.ID);
2221 String idSelloTiempo = UtilidadTratarNodo.newID(doc, ConstantesXADES.SELLO_TIEMPO);
2222 informacionElementoSigTimeStamp.setValue(idSelloTiempo);
2223 ArrayList<String> idNodoSelloTiempo = new ArrayList<String>();
2224 idNodoSelloTiempo.add(idSelloTiempo);
2225 refsOnlyTimeStampElement.getAttributes().setNamedItem(informacionElementoSigTimeStamp);
2226
2227
2228 UnsignedSignatureProperties.appendChild(refsOnlyTimeStampElement);
2229
2230
2231 ArrayList<Element> elementosSelloX = null;
2232 try {
2233 elementosSelloX = UtilidadXadesX.obtenerListadoXADESX2exp(DEFAULT_XADES_SCHEMA_URI, signatureElement, refsOnlyTimeStampElement);
2234 } catch (BadFormedSignatureException e) {
2235 throw new Exception(e.getMessage(), e);
2236 } catch (FirmaXMLError e) {
2237 throw new Exception(e.getMessage(), e);
2238 }
2239
2240
2241 if (ConstantesXADES.SCHEMA_XADES_111.equals(DEFAULT_XADES_SCHEMA_URI) ||
2242 ConstantesXADES.SCHEMA_XADES_122.equals(DEFAULT_XADES_SCHEMA_URI)) {
2243
2244 ArrayList<String> elementosIdSelloX = UtilidadTratarNodo.obtenerIDs(elementosSelloX);
2245
2246
2247 ArrayList<Element> nodosUriReferencia = new ArrayList<Element> (elementosIdSelloX.size());
2248 Iterator<String> itIds = elementosIdSelloX.iterator();
2249 while (itIds.hasNext()) {
2250 String id = itIds.next();
2251 Element uriNode =
2252 doc.createElementNS(DEFAULT_XADES_SCHEMA_URI, namespace + ConstantesXADES.DOS_PUNTOS + nombreNodoUri);
2253 Attr includeNodeUri = doc.createAttributeNS(null, tipoUri);
2254 includeNodeUri.setValue(ConstantesXADES.ALMOHADILLA + id);
2255 NamedNodeMap atributosNodo = uriNode.getAttributes();
2256 atributosNodo.setNamedItem(includeNodeUri);
2257
2258 nodosUriReferencia.add(uriNode);
2259 }
2260
2261
2262 Iterator<Element> itUrisReferencia = nodosUriReferencia.iterator();
2263 while (itUrisReferencia.hasNext()) {
2264 Element includeNode = itUrisReferencia.next();
2265 refsOnlyTimeStampElement.appendChild(includeNode);
2266 }
2267 }
2268
2269
2270 byte[] byteData = null;
2271 try {
2272 byteData = UtilidadTratarNodo.obtenerByte(elementosSelloX, CanonicalizationEnum.C14N_OMIT_COMMENTS);
2273 } catch (FirmaXMLError e) {
2274 throw new Exception(e.getMessage(), e);
2275 }
2276
2277
2278 TSCliente tsCli = null;
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289 tsCli = new TSCliente(servidorTSA,algoritmoTSA);
2290
2291 try {
2292 byteData = tsCli.generarSelloTiempo(byteData);
2293 } catch (TSClienteError e) {
2294 throw new Exception("No se puede generar el sello de tiempos", e) ;
2295 }
2296 String hashSelloX = new String(Base64Coder.encode(byteData));
2297
2298
2299 if (!ConstantesXADES.SCHEMA_XADES_111.equals(DEFAULT_XADES_SCHEMA_URI)) {
2300 Element canonicalizationElemento = doc.createElementNS(ConstantesXADES.SCHEMA_DSIG, xmldsigNS + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.CANONICALIZATION_METHOD);
2301 Attr canonicalizationAttribute = doc.createAttributeNS(null, ConstantesXADES.ALGORITHM);
2302 canonicalizationAttribute.setValue(Transforms.TRANSFORM_C14N_OMIT_COMMENTS);
2303 canonicalizationElemento.getAttributes().setNamedItem(canonicalizationAttribute);
2304
2305 refsOnlyTimeStampElement.appendChild(canonicalizationElemento);
2306 }
2307
2308
2309 Element encapsulatedTimeStampNode =
2310 doc.createElementNS(DEFAULT_XADES_SCHEMA_URI, namespace + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.ENCAPSULATED_TIME_STAMP);
2311 encapsulatedTimeStampNode.appendChild(doc.createTextNode(hashSelloX));
2312 refsOnlyTimeStampElement.appendChild(encapsulatedTimeStampNode);
2313
2314 return doc;
2315 }
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325 protected static Document addXadesXL(Element firma, ArrayList<RespYCerts> respuestasFirma,
2326 ArrayList<RespYCerts> respuestasSello, XAdESSchemas schema, String namespace)
2327 throws Exception {
2328
2329
2330
2331 Document doc = firma.getOwnerDocument();
2332 Element elementoPrincipal = null ;
2333
2334 NodeList nodosUnsignedSignatureProperties = firma.getElementsByTagNameNS(schema.getSchemaUri(), ConstantesXADES.UNSIGNED_SIGNATURE_PROPERTIES);
2335 if(nodosUnsignedSignatureProperties.getLength() != 0)
2336 elementoPrincipal = (Element)nodosUnsignedSignatureProperties.item(0);
2337 else
2338
2339 throw new Exception("No se encuentra el nodo UnsignedSignatureProperties");
2340
2341
2342 if(respuestasFirma != null) {
2343
2344 if (respuestasSello != null) {
2345 respuestasFirma.addAll(respuestasSello);
2346 }
2347
2348 EncapsulatedX509Certificate encapsulatedX509certificate = null;
2349 ArrayList<EncapsulatedX509Certificate> certs = new ArrayList<EncapsulatedX509Certificate> ();
2350 List<X509Certificate> lCertificadosIncluidos = new ArrayList<X509Certificate>();
2351 for(RespYCerts resp : respuestasFirma) {
2352
2353
2354 if (lCertificadosIncluidos.contains(resp.getCertstatus().getCertificate())) {
2355 continue;
2356 }
2357 lCertificadosIncluidos.add(resp.getCertstatus().getCertificate());
2358
2359 encapsulatedX509certificate = new EncapsulatedX509Certificate(schema, resp.getIdCertificado());
2360 try {
2361 encapsulatedX509certificate.setX509Certificate(resp.getCertstatus().getCertificate());
2362 } catch (CertificateException e) {
2363 logger.info(e.getMessage(), e);
2364 throw new Exception("No ha sido posible crear el elemento 'encapsulatedX509certificate' ");
2365 }
2366 certs.add(encapsulatedX509certificate);
2367 }
2368
2369 CertificateValues certificateValues = new CertificateValues(schema, certs);
2370 Element certificateValuesElement = null;
2371 try {
2372 certificateValuesElement = certificateValues.createElement(doc, namespace);
2373 } catch (InvalidInfoNodeException e) {
2374 logger.info(e.getMessage(), e);
2375 throw new Exception("No ha sido posible crear el elemento 'certificateValues'");
2376 }
2377
2378
2379 Attr atributoCertVal = doc.createAttributeNS(null, ConstantesXADES.ID);
2380 String idCertVal = UtilidadTratarNodo.newID(doc, ConstantesXADES.CERTIFICATE_VALUES);
2381 atributoCertVal.setValue(idCertVal);
2382 certificateValuesElement.getAttributes().setNamedItem(atributoCertVal);
2383
2384 elementoPrincipal.appendChild(certificateValuesElement);
2385
2386
2387 Element valoresElementosRevocados =
2388 doc.createElementNS(DEFAULT_XADES_SCHEMA_URI, namespace + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.REVOCATION_VALUES);
2389
2390 Element valorElementOCSP =
2391 doc.createElementNS(DEFAULT_XADES_SCHEMA_URI, namespace + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.OCSP_VALUES);
2392
2393 CRLValues valorElementoCRL = new CRLValues(schema);
2394
2395 lCertificadosIncluidos = new ArrayList<X509Certificate>();
2396 int nOcspResps = 0;
2397 int nCRLSResps = 0;
2398 for(int i=0;i<respuestasFirma.size();i++) {
2399 RespYCerts resp = respuestasFirma.get(i);
2400
2401
2402 if (lCertificadosIncluidos.contains(resp.getCertstatus().getCertificate())) {
2403 continue;
2404 }
2405 lCertificadosIncluidos.add(resp.getCertstatus().getCertificate());
2406
2407 if (i < respuestasFirma.size()-1) {
2408 ICertStatus respStatus = resp.getCertstatus();
2409 if (respStatus instanceof IOCSPCertStatus) {
2410 nOcspResps++;
2411 IOCSPCertStatus respOCSP = (IOCSPCertStatus) respStatus;
2412 Element valorElementoEncapsuladoOCSP = doc.createElementNS(DEFAULT_XADES_SCHEMA_URI, namespace + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.ENCAPSULATED_OCSP_VALUE);
2413 valorElementoEncapsuladoOCSP.appendChild(
2414 doc.createTextNode(new String(Base64Coder.encode(respOCSP.getEncoded()))));
2415 valorElementoEncapsuladoOCSP.setAttributeNS(null, ConstantesXADES.ID, resp.getIdRespStatus());
2416 valorElementOCSP.appendChild(valorElementoEncapsuladoOCSP);
2417 }
2418 else if (respStatus instanceof IX509CRLCertStatus) {
2419 nCRLSResps++;
2420 IX509CRLCertStatus respCRL = (IX509CRLCertStatus) respStatus;
2421 try {
2422 valorElementoCRL.addCRL(respCRL.getX509CRL(), resp.getIdRespStatus());
2423 } catch (InvalidInfoNodeException ex) {
2424 throw new Exception("No se pudo generar nodo EncapsulatedCRLValue", ex);
2425 }
2426 }
2427 }
2428 }
2429
2430 if (nCRLSResps > 0) {
2431 try {
2432 Element el = valorElementoCRL.createElement(doc, namespace);
2433 valoresElementosRevocados.appendChild(el);
2434 } catch (InvalidInfoNodeException ex) {
2435 throw new Exception("No se pudo generar nodo CRLValues", ex);
2436 }
2437 }
2438
2439 if (nOcspResps > 0)
2440 valoresElementosRevocados.appendChild(valorElementOCSP);
2441
2442
2443 Attr atributoRevVal = doc.createAttributeNS(null, ConstantesXADES.ID);
2444 String idRevVal = UtilidadTratarNodo.newID(doc, ConstantesXADES.REVOCATION_VALUES);
2445 atributoRevVal.setValue(idRevVal);
2446 valoresElementosRevocados.getAttributes().setNamedItem(atributoRevVal);
2447
2448 elementoPrincipal.appendChild(valoresElementosRevocados);
2449 }
2450
2451 return doc;
2452 }
2453
2454 protected static ArrayList<RespYCerts> convertICertStatus2RespYCerts(List<ICertStatus> status) {
2455 ArrayList<RespYCerts> resps = new ArrayList<RespYCerts>((status != null) ? status.size() : 0);
2456 if (status != null) {
2457 Iterator<ICertStatus> itStatus = status.iterator();
2458 while (itStatus.hasNext()) {
2459 RespYCerts resp = new RespYCerts();
2460 resp.setCertstatus(itStatus.next());
2461 resps.add(resp);
2462 }
2463 }
2464 return resps;
2465 }
2466
2467
2468
2469
2470
2471 private ValidationResult getValidationResult(ResultadoValidacion resultadoValidacion, boolean esContrafirma) {
2472 logger.debug("[XAdESSignature.getValidationResult]::Resultado validación: " + resultadoValidacion.getLog());
2473
2474
2475 if (!esContrafirma && resultadoValidacion.getDatosFirma().getContraFirma() != null &&
2476 !resultadoValidacion.getDatosFirma().getContraFirma().isEmpty()) {
2477 return null;
2478 }
2479
2480
2481
2482 int codigoResultadoValidacion = tratarResultadoValidacion (resultadoValidacion);
2483
2484
2485 DatosFirma datosFirma = resultadoValidacion.getDatosFirma();
2486 X509Certificate certificate = null;
2487 if (datosFirma.getCadenaFirma() != null) {
2488 certificate = (X509Certificate)datosFirma.getCadenaFirma().getCertificates().get(0);
2489 }
2490 TimeStamp ts = null;
2491 if (datosFirma.getDatosSelloTiempo() != null && !datosFirma.getDatosSelloTiempo().isEmpty()) {
2492 ts = new TimeStamp (datosFirma.getDatosSelloTiempo().get(0).getTst());
2493 }
2494 OCSPResponse[] ocspResponses = null;
2495 if (datosFirma.getDatosOCSP() != null && !datosFirma.getDatosOCSP().isEmpty()) {
2496 ocspResponses = new OCSPResponse [datosFirma.getDatosOCSP().size()];
2497 for (int j = 0; j < ocspResponses.length; j++) {
2498 try {
2499 OCSPResp oscpResp = new OCSPResp(datosFirma.getDatosOCSP().get(j).getRespuestaOCSP().getEncoded());
2500 ocspResponses[j] = new OCSPResponse(oscpResp);
2501 } catch (MalformedOCSPResponseException e) {
2502 logger.info("[XAdESSignature.getValidationResult]::Una de las respuestas OCSP está mal formada", e);
2503 } catch (IOException e) {
2504 logger.info("[XAdESSignature.getValidationResult]::Una de las respuestas OCSP está mal formada", e);
2505 }
2506 }
2507 }
2508
2509 ValidationResult result = new ValidationResult(codigoResultadoValidacion, certificate, ts==null?datosFirma.getFechaFirma():ts.getTime(), ts, ocspResponses);
2510
2511
2512 ArrayList<ResultadoValidacion> lContrafirmas = resultadoValidacion.getContrafirmadoPor();
2513 if (lContrafirmas != null && !lContrafirmas.isEmpty()) {
2514 ValidationResult[] arrayContrafirmas = new ValidationResult[lContrafirmas.size()];
2515 int i = 0;
2516 for (Iterator<ResultadoValidacion> iterator = lContrafirmas.iterator(); iterator.hasNext();) {
2517 ResultadoValidacion resultadoValidacionContrafirma = iterator.next();
2518 arrayContrafirmas[i] = getValidationResult (resultadoValidacionContrafirma, true);
2519 i++;
2520 }
2521 result.setCounterSignatures(arrayContrafirmas);
2522 }
2523
2524
2525 return result;
2526 }
2527
2528
2529
2530
2531
2532 private ValidationResult getValidationResultSignatureOnly(ResultadoValidacion resultadoValidacion, boolean esContrafirma) {
2533 logger.debug("[XAdESSignature.getValidationResultSignatureOnly]::Resultado validación: " + resultadoValidacion.getLog());
2534
2535
2536 if (!esContrafirma && resultadoValidacion.getDatosFirma().getContraFirma() != null &&
2537 !resultadoValidacion.getDatosFirma().getContraFirma().isEmpty()) {
2538 return null;
2539 }
2540
2541
2542
2543 int codigoResultadoValidacion = tratarResultadoValidacionSoloFirma (resultadoValidacion);
2544
2545
2546 DatosFirma datosFirma = resultadoValidacion.getDatosFirma();
2547 X509Certificate certificate = (X509Certificate)datosFirma.getCadenaFirma().getCertificates().get(0);
2548 TimeStamp ts = null;
2549 if (datosFirma.getDatosSelloTiempo() != null && !datosFirma.getDatosSelloTiempo().isEmpty()) {
2550 ts = new TimeStamp (datosFirma.getDatosSelloTiempo().get(0).getTst());
2551 }
2552 OCSPResponse[] ocspResponses = null;
2553 if (datosFirma.getDatosOCSP() != null && !datosFirma.getDatosOCSP().isEmpty()) {
2554 ocspResponses = new OCSPResponse [datosFirma.getDatosOCSP().size()];
2555 for (int j = 0; j < ocspResponses.length; j++) {
2556 try {
2557 OCSPResp oscpResp = new OCSPResp(datosFirma.getDatosOCSP().get(j).getRespuestaOCSP().getEncoded());
2558 ocspResponses[j] = new OCSPResponse(oscpResp);
2559 } catch (MalformedOCSPResponseException e) {
2560 logger.info("[XAdESSignature.getValidationResult]::Una de las respuestas OCSP está mal formada", e);
2561 } catch (IOException e) {
2562 logger.info("[XAdESSignature.getValidationResult]::Una de las respuestas OCSP está mal formada", e);
2563 }
2564 }
2565 }
2566
2567 ValidationResult result = new ValidationResult(codigoResultadoValidacion, certificate, ts==null?datosFirma.getFechaFirma():ts.getTime(), ts, ocspResponses);
2568
2569
2570 ArrayList<ResultadoValidacion> lContrafirmas = resultadoValidacion.getContrafirmadoPor();
2571 if (lContrafirmas != null && !lContrafirmas.isEmpty()) {
2572 ValidationResult[] arrayContrafirmas = new ValidationResult[lContrafirmas.size()];
2573 int i = 0;
2574 for (Iterator<ResultadoValidacion> iterator = lContrafirmas.iterator(); iterator.hasNext();) {
2575 ResultadoValidacion resultadoValidacionContrafirma = iterator.next();
2576 arrayContrafirmas[i] = getValidationResultSignatureOnly (resultadoValidacionContrafirma, true);
2577 i++;
2578 }
2579 result.setCounterSignatures(arrayContrafirmas);
2580 }
2581
2582
2583 return result;
2584 }
2585
2586
2587
2588
2589 private int tratarResultadoValidacionSoloFirma(ResultadoValidacion resultadoValidacion) {
2590 if (resultadoValidacion.getNivelValido() == null || resultadoValidacion.getNivelValido().equals("")) {
2591 if (resultadoValidacion.getLog().toLowerCase().indexOf("firma inválida") > -1) {
2592
2593 logger.debug("[XAdESBESSignature.tratarResultadoValidacionSoloFirma]::La firma no es válida");
2594 return ValidationResult.RESULT_SIGNATURE_NOT_MATCH_DATA;
2595 }
2596 }
2597
2598
2599 logger.debug("[XAdESSignature.tratarResultadoValidacionSoloFirma]::La firma ha pasado la validación");
2600 return ValidationResult.RESULT_VALID;
2601
2602 }
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625 private ValidarFirmaXML loadValidator (IDocument document) {
2626 ValidarFirmaXML validator = new ValidarFirmaXML();
2627 if (document == null) {
2628 validator.addResolver(new FileResourceData());
2629 validator.addResolver(new URLResourceData());
2630 } else {
2631 String attachedDocument = null;
2632 try {
2633 attachedDocument = getAttachedDocument();
2634 } catch (Exception e1) {
2635 logger.info("[XAdESSignature.loadValidator]::No se puede obtener el documento attached. En la validación se indicará que no existe");
2636 }
2637 if (attachedDocument == null) {
2638
2639 validator.addResolver(new UnknownFileResourceData(document));
2640 } else {
2641
2642 byte[] bAttachedDocument = Util.decodeBase64(attachedDocument);
2643 boolean documentsMatch = true;
2644 byte[] externalDocument;
2645 try {
2646 externalDocument = Util.readStream(document.getInputStream());
2647
2648 if (!attachedDocument.equals (new String (externalDocument, getEncoding()))) {
2649
2650 if (!Arrays.equals(bAttachedDocument, externalDocument)) {
2651
2652 ByteArrayInputStream bais = new ByteArrayInputStream (externalDocument);
2653 InputStreamDocument isd = new InputStreamDocument (bais);
2654 byte[] hash = null;
2655 try {
2656 hash = isd.getHash(HashingAlgorithm.SHA1);
2657 } catch (HashingException e) {
2658 logger.debug("[XAdESSignature.loadValidator]::No se puede obtener hash SHA-1", e);
2659 }
2660 if (hash == null || (!Arrays.equals(bAttachedDocument, hash) && !attachedDocument.equals (Util.toHexadecimal(hash)))) {
2661
2662 hash = null;
2663 bais = new ByteArrayInputStream (externalDocument);
2664 isd = new InputStreamDocument (bais);
2665 try {
2666 hash = isd.getHash(HashingAlgorithm.SHA256);
2667 } catch (HashingException e) {
2668 logger.debug("[XAdESSignature.loadValidator]::No se puede obtener hash SHA-256", e);
2669 }
2670 if (hash == null || (!Arrays.equals(bAttachedDocument, hash) && !attachedDocument.equals (Util.toHexadecimal(hash)))) {
2671 documentsMatch = false;
2672 }
2673 }
2674 }
2675 }
2676 } catch (IOException e) {
2677 logger.debug("[XAdESSignature.loadValidator]::No se puede obtener el documento externo", e);
2678 }
2679
2680
2681
2682 if (!documentsMatch) {
2683 validator.addResolver(new ToxicResourceData());
2684 }
2685 }
2686 }
2687
2688 return validator;
2689 }
2690
2691
2692
2693
2694
2695
2696
2697
2698 private String getDataObjectFormatValue (String tagName) {
2699 logger.debug("[XAdESSignature.getDataObjectFormatValue]::Entrada");
2700
2701
2702 XPathFactory factory = XPathFactory.newInstance();
2703 XPath xpath = factory.newXPath();
2704 try {
2705 XPathExpression expr = xpath.compile("//*[local-name()='Object']/*[local-name()='QualifyingProperties']/*[local-name()='SignedProperties']/" +
2706 "*[local-name()='SignedDataObjectProperties']/*[local-name()='DataObjectFormat']/*[local-name()='" + tagName + "']");
2707 NodeList descriptionNodes = (NodeList) expr.evaluate (xadesDocument, XPathConstants.NODESET);
2708 if (descriptionNodes == null || descriptionNodes.getLength() == 0) {
2709 logger.debug("[XAdESSignature.getDataObjectFormatValue]::No existe la descripción del documento en la firma");
2710 return null;
2711 }
2712
2713 return descriptionNodes.item(0).getTextContent();
2714
2715 } catch (Exception e) {
2716 logger.info ("[XAdESSignature.getDataObjectFormatValue]::Error inesperado", e);
2717 return null;
2718 }
2719
2720 }
2721
2722
2723
2724
2725
2726 private ValidationResult[] isValidCommon(IDocument document, CAList caList, List<CertificateValidationService> validationServices)
2727 throws SignatureException {
2728
2729 logger.debug("[XAdESSignature.isValid]::Entrada::" + Arrays.asList(new Object[] { document, caList, validationServices }));
2730
2731 ExtraValidators extraValidator;
2732 if (caList != null) {
2733 extraValidator = new ExtraValidators(null, new CAListCertStatusRecover(caList, true), null);
2734 } else {
2735 extraValidator = new ExtraValidators(null, new ValidationServicesCertStatusRecover(validationServices), null);
2736 }
2737 ValidarFirmaXML validator = loadValidator (document);
2738 List<ResultadoValidacion> results;
2739 try {
2740 results = validator.validar(this.xadesDocument, "./", extraValidator);
2741 } catch (FirmaXMLError e) {
2742 logger.info("[XAdESSignature.isValid]::No ha sido posible validar la firma", e);
2743 throw new SignatureException("No ha sido posible validar la firma", e);
2744 }
2745
2746 ArrayList<ValidationResult> result = new ArrayList<ValidationResult>();
2747 for (Iterator<ResultadoValidacion> iterator = results.iterator(); iterator.hasNext();) {
2748 ResultadoValidacion resultadoValidacion = iterator.next();
2749 ValidationResult validationResult = getValidationResult (resultadoValidacion, false);
2750 if (validationResult != null) {
2751 result.add(validationResult);
2752 }
2753
2754 }
2755
2756 return result.toArray(new ValidationResult[0]);
2757 }
2758
2759
2760
2761
2762
2763
2764
2765
2766 protected static String searchXAdESNamespace(Element element) {
2767
2768 XPathFactory factory = XPathFactory.newInstance();
2769 XPath xpath = factory.newXPath();
2770 try {
2771 XPathExpression expr = xpath.compile("//*[local-name()='SignedSignatureProperties']");
2772 Node sspNode = (Node) expr.evaluate (element, XPathConstants.NODE);
2773 if (sspNode != null && sspNode.getPrefix() != null) {
2774 return sspNode.getPrefix();
2775 }
2776 } catch (Exception e) {
2777 }
2778
2779 return xadesNS;
2780 }
2781
2782 protected String nodeToString(Node node) {
2783 StringWriter sw = new StringWriter();
2784 try {
2785 Transformer t = TransformerFactory.newInstance().newTransformer();
2786 t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
2787 t.setOutputProperty(OutputKeys.INDENT, "yes");
2788 t.transform(new DOMSource(node), new StreamResult(sw));
2789 } catch (TransformerException te) {
2790 System.out.println("nodeToString Transformer Exception");
2791 }
2792 return sw.toString();
2793 }
2794 }