public Result validate ( final Document doc ) throws Exception { final NodeList nl = doc.getElementsByTagNameNS ( XMLSignature.XMLNS, "Signature" ); //$NON-NLS-1$ if ( nl.getLength () == 0 ) { return new Result ( StatusCodes.VALIDATE_NO_SIGNATURE_DATA, "No signature data found" ); } final DOMValidateContext dvc = new DOMValidateContext ( this.keySelector, nl.item ( 0 ) ); final XMLSignature signature = this.factory.unmarshalXMLSignature ( dvc ); try { final boolean result = signature.validate ( dvc ); return new Result ( result, signature ); } catch ( final XMLSignatureException e ) { logger.debug ( "Failed to perform validation", e ); return Result.INVALID; } }
@Test public void newKeySelector_keyinfoEmpty() throws Exception { // given String response = Strings .textFileToString("javares/openamResponse.xml"); response = response.replaceAll(System.lineSeparator(), "").replaceAll( "<ds:KeyInfo>.*</ds:KeyInfo>", "<ds:KeyInfo></ds:KeyInfo>"); Document document = XMLConverter.convertToDocument(response, true); NodeList nl = document.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature"); // when try { factory.newKeySelector(nl.item(0)); fail(); } catch (DigitalSignatureValidationException e) { assertTrue(e.getMessage().contains( "Only RSA/DSA KeyValue and are X509Data supported")); } }
public void compare ( final Document sourceDoc, final Document signedDoc ) throws Exception { final Document d1 = cloneDoc ( sourceDoc ); final Document d2 = cloneDoc ( signedDoc ); final NodeList nl = d2.getElementsByTagNameNS ( XMLSignature.XMLNS, "Signature" ); while ( nl.getLength () > 0 ) { final Node item = nl.item ( 0 ); item.getParentNode ().removeChild ( item ); } d1.normalizeDocument (); d2.normalizeDocument (); final Element root1 = d1.getDocumentElement (); final Element root2 = d2.getDocumentElement (); compareNode ( root1, root2 ); }
@Test public void newKeySelector_keyinfoMissing() throws Exception { // given String response = Strings .textFileToString("javares/openamResponse.xml"); response = response.replaceAll(System.lineSeparator(), "").replaceAll( "<ds:KeyInfo>.*</ds:KeyInfo>", ""); Document document = XMLConverter.convertToDocument(response, true); NodeList nl = document.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature"); try { // when factory.newKeySelector(nl.item(0)); fail(); } catch (DigitalSignatureValidationException e) { // then assertTrue(e.getMessage().contains( "No KeyInfo element found in SAML assertion")); } }
@Test public void newKeySelector_keyValue() throws Exception { // given String response = Strings .textFileToString("javares/openamResponse.xml"); Document document = XMLConverter.convertToDocument( replaceX509WithKeyValueData(response), true); NodeList nl = document.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature"); // when KeySelector keySelector = factory.newKeySelector(nl.item(0)); // then assertTrue(keySelector instanceof KeyValueKeySelector); }
@Test public void newKeySelector_firstFound() throws Exception { // given String response = Strings .textFileToString("javares/openamResponse.xml"); Document document = XMLConverter.convertToDocument( addKeyValueAfterX509Data(response), true); NodeList nl = document.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature"); // when KeySelector keySelector = factory.newKeySelector(nl.item(0)); // then assertTrue(keySelector instanceof X509KeySelector); }
/** * This method invokes the {@link #marshalParams marshalParams} * method to marshal any algorithm-specific parameters. */ public void marshal(Node parent, String dsPrefix, DOMCryptoContext context) throws MarshalException { Document ownerDoc = DOMUtils.getOwnerDocument(parent); Element smElem = DOMUtils.createElement(ownerDoc, "SignatureMethod", XMLSignature.XMLNS, dsPrefix); DOMUtils.setAttribute(smElem, "Algorithm", getAlgorithm()); if (getParameterSpec() != null) { marshalParams(smElem, dsPrefix); } parent.appendChild(smElem); }
/** * Marshals a {@link PGPData} * * @param xwriter * @param pgpData * @param dsPrefix * @param context * @throws MarshalException */ public static void marshalPGPData(XmlWriter xwriter, PGPData pgpData, String dsPrefix, XMLCryptoContext context) throws MarshalException { xwriter.writeStartElement(dsPrefix, "PGPData", XMLSignature.XMLNS); // create and append PGPKeyID element byte[] keyId = pgpData.getKeyId(); if (keyId != null) { xwriter.writeTextElement(dsPrefix, "PGPKeyID", XMLSignature.XMLNS, Base64.encode(keyId)); } // create and append PGPKeyPacket element byte[] keyPacket = pgpData.getKeyPacket(); if (keyPacket != null) { xwriter.writeTextElement(dsPrefix, "XMLSignature.XMLNS", XMLSignature.XMLNS, Base64.encode(keyPacket)); } // create and append any elements @SuppressWarnings("unchecked") List<XMLStructure> externalElements = pgpData.getExternalElements(); for (XMLStructure externalItem : externalElements) { xwriter.marshalStructure(externalItem, dsPrefix, context); } xwriter.writeEndElement(); // "PGPData" }
@Override public void marshal(XmlWriter xwriter, String dsPrefix, XMLCryptoContext context) throws MarshalException { xwriter.writeStartElement(dsPrefix, "RetrievalMethod", XMLSignature.XMLNS); // TODO - see whether it is important to capture the "here" attribute as part of the // marshalling - do any of the tests fail? // add URI and Type attributes here = xwriter.writeAttribute("", "", "URI", uri); xwriter.writeAttribute("", "", "Type", type); // add Transforms elements if (!transforms.isEmpty()) { xwriter.writeStartElement(dsPrefix, "Transforms", XMLSignature.XMLNS); for (Transform transform : transforms) { ((DOMTransform)transform).marshal(xwriter, dsPrefix, context); } xwriter.writeEndElement(); // "Transforms" } xwriter.writeEndElement(); // "RetrievalMethod" }
public XMLStructure dereferenceAsXMLStructure(XMLCryptoContext context) throws URIReferenceException { DocumentBuilder db = null; boolean secVal = Utils.secureValidation(context); try { ApacheData data = (ApacheData)dereference(context); db = XMLUtils.createDocumentBuilder(false, secVal); Document doc = db.parse(new ByteArrayInputStream (data.getXMLSignatureInput().getBytes())); Element kiElem = doc.getDocumentElement(); if (kiElem.getLocalName().equals("X509Data") && XMLSignature.XMLNS.equals(kiElem.getNamespaceURI())) { return new DOMX509Data(kiElem); } else { return null; // unsupported } } catch (Exception e) { throw new URIReferenceException(e); } finally { if (db != null) { XMLUtils.repoolDocumentBuilder(db); } } }
private static void marshalInternal(XmlWriter xwriter, KeyInfo ki, String dsPrefix, XMLCryptoContext context, boolean declareNamespace) throws MarshalException { xwriter.writeStartElement(dsPrefix, "KeyInfo", XMLSignature.XMLNS); if (declareNamespace) { xwriter.writeNamespace(dsPrefix, XMLSignature.XMLNS); } xwriter.writeIdAttribute("", "", "Id", ki.getId()); // create and append KeyInfoType elements List<XMLStructure> keyInfoTypes = getContent(ki); for (XMLStructure kiType : keyInfoTypes) { xwriter.marshalStructure(kiType, dsPrefix, context); } xwriter.writeEndElement(); // "KeyInfo" }
@SuppressWarnings("rawtypes") private static boolean isSignatureGlobal(XMLSignature signature, String rootID) { LOG.debug("Starting signature globality check..."); LOG.debug("Signature: {}", signature); LOG.debug("Root ID: {}", rootID); boolean isGlobal = false; // We check each Reference. One must be the rootId or be "" String refRootID = "#" + rootID; for (Object o : signature.getSignedInfo().getReferences()) { String uri = ((Reference) o).getURI(); if ("".equals(uri) || refRootID.equals(uri)) { isGlobal = true; break; } } LOG.debug("Signature globality check result: {}", isGlobal); return isGlobal; }
private static String explainValidationProblem( DOMValidateContext context, XMLSignature signature) throws XMLSignatureException { @SuppressWarnings("unchecked") // Safe by specification. List<Reference> references = signature.getSignedInfo().getReferences(); StringBuilder builder = new StringBuilder(); builder.append("Signature failed core validation\n"); boolean sv = signature.getSignatureValue().validate(context); builder.append("Signature validation status: " + sv + "\n"); for (Reference ref : references) { builder.append("references["); builder.append(ref.getURI()); builder.append("] validity status: "); builder.append(ref.validate(context)); builder.append("\n"); } return builder.toString(); }
/** * Removes the Signature elements from the document. * * @param doc * document */ protected void removeSignatureElements(Node node) { Document doc = XmlSignatureHelper.getDocument(node); NodeList nl = doc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature"); List<Node> nodesToBeRemoved = new ArrayList<Node>(nl.getLength()); for (int i = 0; i < nl.getLength(); i++) { // you cannot remove the nodes within this loop, because nl list would change nodesToBeRemoved.add(nl.item(i)); } for (Node n : nodesToBeRemoved) { Node parent = n.getParentNode(); if (parent != null) { parent.removeChild(n); } } }
protected void replacePrefix(Element el, Input input) { replacePrefixForNode(el, input); NamedNodeMap nnm = el.getAttributes(); List<Attr> xmlnsToBeRemoved = new ArrayList<Attr>(2); int length = nnm.getLength(); for (int i = 0; i < length; i++) { Node attr = nnm.item(i); replacePrefixForNode(attr, input); if (attr.getNodeType() == Node.ATTRIBUTE_NODE) { if ("xmlns".equals(attr.getLocalName()) || "xmlns".equals(attr.getPrefix())) { if (XMLSignature.XMLNS.equals(attr.getTextContent()) || findNamespace(input.getMessage()).equals(attr.getTextContent())) { xmlnsToBeRemoved.add((Attr) attr); } } } } // remove xml namespace declaration for XML signature and XAdES namespace for (Attr toBeRemoved : xmlnsToBeRemoved) { el.removeAttributeNode(toBeRemoved); } }
private Element testDetachedSignatureInternal(Map<String, Object> headers) throws InterruptedException, XPathExpressionException, SAXException, IOException, ParserConfigurationException { String detachedPayload = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + (includeNewLine ? "\n" : "") + "<ns:root xmlns:ns=\"http://test\"><a ID=\"myID\"><b>bValue</b></a></ns:root>"; MockEndpoint mock = getMockEndpoint("mock:result"); mock.expectedMessageCount(1); MockEndpoint mockVerified = getMockEndpoint("mock:verified"); mockVerified.expectedBodiesReceived(detachedPayload); sendBody("direct:detached", detachedPayload, headers); assertMockEndpointsSatisfied(); Map<String, String> namespaceMap = new TreeMap<String, String>(); namespaceMap.put("ns", "http://test"); namespaceMap.put("ds", XMLSignature.XMLNS); Object obj = checkXpath(mock, "ns:root/ds:Signature", namespaceMap); Element sigEle = (Element) obj; return sigEle; }
/** * Verification via the default JSR105 implementation triggers some * canonicalization errors. * * @param odfUrl * @param signatureNode * @throws MarshalException * @throws XMLSignatureException */ private boolean verifySignature(URL odfUrl, Node signatureNode) throws MarshalException, XMLSignatureException { // work-around for Java 7 Element signedPropertiesElement = (Element) ((Element) signatureNode) .getElementsByTagNameNS(XAdESXLSignatureFacet.XADES_NAMESPACE, "SignedProperties").item(0); if (null != signedPropertiesElement) { signedPropertiesElement.setIdAttribute("Id", true); } DOMValidateContext domValidateContext = new DOMValidateContext(new KeyInfoKeySelector(), signatureNode); ODFURIDereferencer dereferencer = new ODFURIDereferencer(odfUrl); domValidateContext.setURIDereferencer(dereferencer); XMLSignatureFactory xmlSignatureFactory = XMLSignatureFactory.getInstance(); LOG.debug("java version: " + System.getProperty("java.version")); /* * Requires Java 6u10 because of a bug. See also: * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6696582 */ XMLSignature xmlSignature = xmlSignatureFactory.unmarshalXMLSignature(domValidateContext); boolean validity = xmlSignature.validate(domValidateContext); return validity; }
@Test(expected = DigitalSignatureValidationException.class) public void validate_error() throws Exception { // given FileInputStream in = null; Document document = null; try { in = new FileInputStream(FILE_OPENAM_RESPONSE); document = XMLConverter.convertToDocument(in); } finally { if (in != null) { in.close(); } } NodeList nl = document.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature"); doThrow(new XMLSignatureException("")).when(validator) .workaroundOpenamBug(any(XMLSignature.class), any(DOMValidateContext.class), anyBoolean()); // when validator.validate(nl.item(0)); // then exception expected }
@Test public void validate_x509_openamResponse() throws Exception { // given FileInputStream in = null; Document document = null; try { in = new FileInputStream(FILE_OPENAM_RESPONSE); document = XMLConverter.convertToDocument(in); } finally { if (in != null) { in.close(); } } Element assertion = (Element) document.getElementsByTagNameNS( "urn:oasis:names:tc:SAML:2.0:assertion", "Assertion").item(0); assertion.setIdAttribute("ID", true); NodeList nl = document.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature"); // when boolean valid = validator.validate(nl.item(0)); // then assertTrue(valid); }
@Test public void validate_rsa_publicKey() throws Exception { // given XMLSignatureBuilder builder = new XMLSignatureBuilder(); KeyPair keyPair = generateKeyPair("RSA"); FileInputStream in = null; Document document = null; try { in = new FileInputStream(FILE_UNSIGNED_ASSERTION); document = builder.sign(in, keyPair); } finally { if (in != null) { in.close(); } } NodeList nl = document.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature"); // when boolean valid = validator.validate(nl.item(0), keyPair.getPublic()); // then assertTrue(valid); }
@Test public void validate_rsa_keySelector() throws Exception { // given XMLSignatureBuilder builder = new XMLSignatureBuilder(); KeyPair keyPair = generateKeyPair("RSA"); FileInputStream in = null; Document document = null; try { in = new FileInputStream(FILE_UNSIGNED_ASSERTION); document = builder.sign(in, keyPair); } finally { if (in != null) { in.close(); } } NodeList nl = document.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature"); // when boolean valid = validator.validate(nl.item(0)); // then assertTrue(valid); }
@Test public void validate_dsa_publicKey() throws Exception { // given XMLSignatureBuilder builder = new XMLSignatureBuilder( SignatureMethod.DSA_SHA1); KeyPair keyPair = generateKeyPair("DSA"); FileInputStream in = null; Document document = null; try { in = new FileInputStream(FILE_UNSIGNED_ASSERTION); document = builder.sign(in, keyPair); } finally { if (in != null) { in.close(); } } NodeList nl = document.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature"); // when boolean valid = validator.validate(nl.item(0), keyPair.getPublic()); // then assertTrue(valid); }
@Test public void validate_dsa_keySelector() throws Exception { // given XMLSignatureBuilder builder = new XMLSignatureBuilder( SignatureMethod.DSA_SHA1); KeyPair keyPair = generateKeyPair("DSA"); FileInputStream in = null; Document document = null; try { in = new FileInputStream(FILE_UNSIGNED_ASSERTION); document = builder.sign(in, keyPair); } finally { if (in != null) { in.close(); } } NodeList nl = document.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature"); // when boolean valid = validator.validate(nl.item(0)); // then assertTrue(valid); }
@Test public void newKeySelector_x509() throws Exception { // given FileInputStream in = null; Document document = null; try { in = new FileInputStream(FILE_OPENAM_RESPONSE); document = XMLConverter.convertToDocument(in); } finally { if (in != null) { in.close(); } } NodeList nl = document.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature"); // when KeySelector keySelector = factory.newKeySelector(nl.item(0)); // then assertTrue(keySelector instanceof X509KeySelector); }
protected void addDataObjectReference(final Document documentDom, final Element asicManifestDom, DSSDocument document, DigestAlgorithm digestAlgorithm) { final Element dataObjectReferenceDom = DomUtils.addElement(documentDom, asicManifestDom, ASiCNamespace.NS, ASiCNamespace.DATA_OBJECT_REFERENCE); dataObjectReferenceDom.setAttribute("URI", document.getName()); MimeType mimeType = document.getMimeType(); if (mimeType != null) { dataObjectReferenceDom.setAttribute("MimeType", mimeType.getMimeTypeString()); } final Element digestMethodDom = DomUtils.addElement(documentDom, dataObjectReferenceDom, XMLSignature.XMLNS, "DigestMethod"); digestMethodDom.setAttribute("Algorithm", digestAlgorithm.getXmlId()); final Element digestValueDom = DomUtils.addElement(documentDom, dataObjectReferenceDom, XMLSignature.XMLNS, "DigestValue"); final Text textNode = documentDom.createTextNode(document.getDigest(digestAlgorithm)); digestValueDom.appendChild(textNode); }
public SignatureElement( Element signature ) { this.signature = signature; List<Element> signedInfo = DomUtilities.findChildren( signature, "SignedInfo", XMLSignature.XMLNS ); if ( signedInfo.size() == 1 ) { log().trace( "Searching for Reference Elements" ); List<Element> list = DomUtilities.findChildren( signedInfo.get( 0 ), "Reference", XMLSignature.XMLNS ); references = new ArrayList<ReferenceElement>(); for ( Element ele : list ) { references.add( new ReferenceElement( ele ) ); } log().trace( "Found: " + references ); } }
public boolean isValid() throws Exception { NodeList nodes = xmlDoc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature"); if (nodes == null || nodes.getLength() == 0) { throw new Exception("Can't find signature in document."); } if (setIdAttributeExists()) { tagIdAttributes(xmlDoc); } X509Certificate cert = samlSettings.getCertificate(); DOMValidateContext ctx = new DOMValidateContext(cert.getPublicKey(), nodes.item(0)); XMLSignatureFactory sigF = XMLSignatureFactory.getInstance("DOM"); XMLSignature xmlSignature = sigF.unmarshalXMLSignature(ctx); return xmlSignature.validate(ctx); }
public synchronized void sign() throws MarshalException, XMLSignatureException, KeyException { if (this.document == null) throw new RuntimeException("Can't sign a NULL document"); Reference reference = this.signatureFactory.newReference( referenceUri, this.digestMethod, this.transformList, null, null); SignedInfo signedInfo = this.signatureFactory.newSignedInfo( this.canonicalizationMethod, this.signatureMethod, Collections.singletonList(reference)); // Create the KeyInfo containing the X509Data. X509Data xd = this.keyInfoFactory.newX509Data( Collections.singletonList(this.certificateWithKey.certificate)); KeyInfo keyInfo = this.keyInfoFactory.newKeyInfo(Collections.singletonList(xd)); XMLSignature signature = this.signatureFactory.newXMLSignature( signedInfo, keyInfo); DOMSignContext signingContext = new DOMSignContext( this.certificateWithKey.privateKey, document.getDocumentElement()); signature.sign(signingContext); }