/** * Recupera los signedInfo de una firma XML, excluyendo los de las firmas indicadas a * través de su Id. * * @param xmlSign XML del que se * @param pk Clave publicada usada en las firmas de las que se desea obtener los signedInfo. * @param excludedIds Identificadores de las firmas excluidas. * @return Listado de signedInfos. * @throws SAXException Si hay problemas durante el análisis XML. * @throws IOException Si hay problemas en el tratamiento de datos. * @throws ParserConfigurationException Si hay problemas con el analizador por defecto para XML. * @throws MarshalException Si hay problemas con el empaquetado XML. * @throws XMLSignatureException Si hay problemas en la propia firma XMLDSig. * @throws XmlPreSignException Cuando no se ha encontrado ningún signedInfo que devolver. */ private static List<byte[]> getSignedInfos( final byte[] xmlSign, final PublicKey pk, final List<String> excludedIds) throws SAXException, IOException, ParserConfigurationException, MarshalException, XMLSignatureException, XmlPreSignException { final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); final NodeList signatureNodeList = dbf.newDocumentBuilder() .parse(new ByteArrayInputStream(xmlSign)) .getElementsByTagNameNS(XMLSignature.XMLNS, AOXAdESSigner.SIGNATURE_TAG); if (signatureNodeList.getLength() == 0) { throw new IllegalArgumentException("Se ha proporcionado un XML sin firmas"); // $NON-NLS-1$ } // Recogemos el signedInfo de cada firma cuyo identificador no este en la lista de excluidos // (excludedIds) final List<byte[]> signedInfos = new ArrayList<byte[]>(); for (int i = 0; i < signatureNodeList.getLength(); i++) { final Node currentNode = signatureNodeList.item(i); // Saltamos las firmas sin identificador if (currentNode.getAttributes() == null || currentNode.getAttributes().getNamedItem(XML_NODE_ID) == null) { Logger.getLogger("es.gob.afirma") .warning( "El documento contiene firmas sin identificador reconocido"); //$NON-NLS-1$//$NON-NLS-2$ continue; } // Saltamos las firmas excluidas (las que estaban antes) final String id = currentNode.getAttributes().getNamedItem(XML_NODE_ID).getNodeValue(); if (excludedIds != null && excludedIds.contains(id)) { continue; } // Agregamos el signed indo de la firma al listado final XMLValidateContext valContext = new DOMValidateContext(new SimpleKeySelector(pk), currentNode); valContext.setProperty("javax.xml.crypto.dsig.cacheReference", Boolean.TRUE); // $NON-NLS-1$ final XMLSignature signature = Utils.getDOMFactory().unmarshalXMLSignature(valContext); signature.validate(valContext); signedInfos.add( AOUtil.getDataFromInputStream(signature.getSignedInfo().getCanonicalizedData())); } if (signedInfos.isEmpty()) { throw new XmlPreSignException( "Se ha creado un nodo firma, pero no se ha encontrado en el postproceso"); //$NON-NLS-1$ } return signedInfos; }
/** * Validate a signed document with the given public key * * @param signedDoc * @param publicKey * @return * @throws MarshalException * @throws XMLSignatureException */ @SuppressWarnings("unchecked") public static boolean validate(Document signedDoc, Key publicKey) throws MarshalException, XMLSignatureException { if (signedDoc == null) throw logger.nullArgumentError("Signed Document"); propagateIDAttributeSetup(signedDoc.getDocumentElement(), signedDoc.getDocumentElement()); NodeList nl = signedDoc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature"); if (nl == null || nl.getLength() == 0) { throw logger.nullValueError("Cannot find Signature element"); } if (publicKey == null) throw logger.nullValueError("Public Key"); for (int i = 0; i < nl.getLength(); i++) { DOMValidateContext valContext = new DOMValidateContext(publicKey, nl.item(i)); XMLSignature signature = fac.unmarshalXMLSignature(valContext); boolean coreValidity = signature.validate(valContext); if (!coreValidity) { if (logger.isTraceEnabled()) { boolean sv = signature.getSignatureValue().validate(valContext); logger.trace("Signature validation status: " + sv); List<Reference> references = signature.getSignedInfo().getReferences(); for (Reference ref : references) { logger.trace( "[Ref id=" + ref.getId() + ":uri=" + ref.getURI() + "]validity status:" + ref.validate(valContext)); } } return false; } } return true; }