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; } }
@org.junit.Test public void testLocalFilesystem() throws Exception { String file = "signature-external-c14n-xmlatrs.xml"; DOMValidateContext vc = validator.getValidateContext( file, new KeySelectors.SecretKeySelector("secret".getBytes("ASCII")) ); vc.setProperty("org.apache.jcp.xml.dsig.secureValidation", Boolean.FALSE); boolean coreValidity = validator.validate(vc); assertTrue("Signature failed core validation", coreValidity); vc.setProperty("org.apache.jcp.xml.dsig.secureValidation", Boolean.TRUE); try { validator.validate(vc); fail("Failure expected when secure validation is enabled"); } catch (XMLSignatureException ex) { assertTrue(ex.getMessage().contains("URIReferenceException")); } }
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(); }
/** * 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 }
public Envelope buildFault(String request) throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, MarshalException, XMLSignatureException { Envelope r = buildResponse(request, false); r.getBody().getUnknownXMLObjects().clear(); Fault fault = SAMLUtil.buildXMLObject(Fault.class); Detail detail = SAMLUtil.buildXMLObject(Detail.class); FaultString msg = SAMLUtil.buildXMLObject(FaultString.class); msg.setValue("test"); fault.setMessage(msg); fault.setDetail(detail); XSAny d = new XSAnyBuilder().buildObject("urn:test", "fault", "fa"); detail.getUnknownXMLObjects().add(d); r.getBody().getUnknownXMLObjects().add(fault); return r; }
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); }
public synchronized boolean validate() throws MarshalException, XMLSignatureException { // Find Signature element. NodeList list = document.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature"); if (list.getLength() == 0) { throw new RuntimeException("Cannot find Signature element"); } // Create a DOMValidateContext and specify a KeySelector // and document context. DOMValidateContext validateContext = new DOMValidateContext(new X509CertificateKeySelector(), list.item(0)); // Unmarshal the XMLSignature. XMLSignature signature = this.signatureFactory.unmarshalXMLSignature(validateContext); // Validate the XMLSignature. if (signature.validate(validateContext)) { return true; } else { Iterator<?> i = signature.getSignedInfo().getReferences().iterator(); for (int j = 0; i.hasNext(); j++) { System.out.print("ref[" + j + "] -> "); Reference ref = (Reference) i.next(); System.out.print(ref.getURI()); System.out.print(", "); System.out.print(ref.getDigestMethod().toString()); System.out.print(", "); System.out.print(ref.getId()); boolean refValid = ref.validate(validateContext); System.out.print(", validity status: " + refValid + "\r\n"); } return false; } }
public Document sign(FileInputStream fileStream, KeyPair keyPair) throws ParserConfigurationException, SAXException, IOException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, KeyException, MarshalException, XMLSignatureException { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); DocumentBuilder builder = factory.newDocumentBuilder(); Document document = builder.parse(fileStream); DOMSignContext signContext = new DOMSignContext(keyPair.getPrivate(), document.getDocumentElement()); XMLSignatureFactory signFactory = XMLSignatureFactory .getInstance("DOM"); Reference ref = signFactory.newReference("", signFactory .newDigestMethod(digestMethod, null), Collections .singletonList(signFactory.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null)), null, null); SignedInfo si = signFactory.newSignedInfo(signFactory .newCanonicalizationMethod( CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS, (C14NMethodParameterSpec) null), signFactory .newSignatureMethod(signatureMethod, null), Collections .singletonList(ref)); KeyInfoFactory kif = signFactory.getKeyInfoFactory(); KeyValue kv = kif.newKeyValue(keyPair.getPublic()); KeyInfo ki = kif.newKeyInfo(Collections.singletonList(kv)); XMLSignature signature = signFactory.newXMLSignature(si, ki); signature.sign(signContext); return document; }
private boolean validate(final DOMValidateContext validationContext) throws DigitalSignatureValidationException { try { // if (getLogger().isDebugLoggingEnabled()) { // enableReferenceCaching(validationContext); // } XMLSignatureFactory factory = XMLSignatureFactory .getInstance(XML_MECHANISM_TYPE); XMLSignature signature = factory .unmarshalXMLSignature(validationContext); boolean validationResult = signature.validate(validationContext); validationResult = workaroundOpenamBug(signature, validationContext, validationResult); // if (getLogger().isDebugLoggingEnabled()) { // debugLogReferences(signature, validationContext); // } return validationResult; } catch (XMLSignatureException | MarshalException exception) { throw new DigitalSignatureValidationException( "Error occurred during digital signature validation process", DigitalSignatureValidationException.ReasonEnum.EXCEPTION_OCCURRED, exception); } }
/** * The overall signature validation consists of two steps, one is the * validation of the signature itself and the other the validation of the * references digest values. Because of a canonicalization bug in openam, * which is not yet registered, the second verification cannot be done. * * @return true if the signature validation has not failed, even if the * reference validation failed. */ boolean workaroundOpenamBug(XMLSignature signature, DOMValidateContext validationContext, boolean validationResult) throws XMLSignatureException { if (!validationResult) { if (signature.getSignatureValue().validate(validationContext)) { return true; } } return validationResult; }
/** * Signs the Excel OOXML file and writes it to the final outputstream * * @param privateKey private Key for signing * @param x509 Certificate for private Key for signing * @param password optional password for encryption, if used * @param hashAlgorithm hash algorithm to be used * * @throws MarshalException * @throws XMLSignatureException * @throws IOException * @throws FormatNotUnderstoodException */ public void sign(Key privateKey, X509Certificate x509, String password, HashAlgorithm hashAlgorithm) throws XMLSignatureException, MarshalException, IOException, FormatNotUnderstoodException { if (this.tempSignFileOS!=null) { // close it we sign only a closed temporary file this.tempSignFileOS.close(); } SignatureConfig sc = new SignatureConfig(); sc.addSignatureFacet(new OOXMLSignatureFacet()); sc.addSignatureFacet(new KeyInfoSignatureFacet()); sc.addSignatureFacet(new XAdESSignatureFacet()); sc.addSignatureFacet(new Office2010SignatureFacet()); sc.setKey((PrivateKey)privateKey); sc.setSigningCertificateChain(Collections.singletonList(x509)); sc.setDigestAlgo(hashAlgorithm); FileInputStream tempSignFileIS = null; try { InputStream tmpFileInputStream = new FileInputStream(this.tempSignFile); if (password==null) { this.signUnencryptedOpcPackage(tmpFileInputStream, sc); } else { this.signEncryptedPackage(tmpFileInputStream, sc, password); } } catch (InvalidFormatException | IOException e) { LOG.error(e); } finally { if (this.finalOutputStream!=null) { this.finalOutputStream.close(); } if (tempSignFileIS!=null) { tempSignFileIS.close(); } } }
private void signUnencryptedOpcPackage(InputStream tmpFileInputStream, SignatureConfig sc) throws InvalidFormatException, IOException, XMLSignatureException, MarshalException { OPCPackage pkg = OPCPackage.open(tmpFileInputStream); sc.setOpcPackage(pkg); SignatureInfo si = new SignatureInfo(); si.setSignatureConfig(sc); si.confirmSignature(); pkg.save(this.finalOutputStream); pkg.close(); }
private void signEncryptedPackage(InputStream tmpFileInputStream, SignatureConfig sc, String password) throws IOException, InvalidFormatException, FormatNotUnderstoodException, XMLSignatureException, MarshalException { NPOIFSFileSystem poifsTemp = new NPOIFSFileSystem(tmpFileInputStream); EncryptionInfo info = new EncryptionInfo(poifsTemp); Decryptor d = Decryptor.getInstance(info); try { if (!d.verifyPassword(password)) { throw new FormatNotUnderstoodException("Error: Cannot decrypt new Excel file (.xlsx) for signing. Invalid password"); } // signing OPCPackage pkg = OPCPackage.open(d.getDataStream(poifsTemp)); sc.setOpcPackage(pkg); SignatureInfo si = new SignatureInfo(); si.setSignatureConfig(sc); si.confirmSignature(); // encrypt again Encryptor enc = info.getEncryptor(); enc.confirmPassword(password); NPOIFSFileSystem poifs = new NPOIFSFileSystem(); OutputStream os = enc.getDataStream(poifs); pkg.save(os); pkg.close(); if (os!=null) { os.close(); } poifs.writeFilesystem(this.finalOutputStream); if (poifs!=null) { poifs.close(); } if (poifsTemp!=null) { poifsTemp.close(); } } catch (GeneralSecurityException e) { LOG.error(e); throw new FormatNotUnderstoodException("Error: Cannot decrypt new Excel file (.xlsx) for signing."); } }
@org.junit.Test public void test_signature_enveloping_hmac_sha1_trunclen_0() throws Exception { try { validator.validate ("signature-enveloping-hmac-sha1-trunclen-0-attack.xml", new KeySelectors.SecretKeySelector("secret".getBytes("ASCII"))); fail("Expected HMACOutputLength exception"); } catch (XMLSignatureException xse) { // System.out.println(xse.getMessage()); // pass } }
@org.junit.Test public void test_signature_enveloping_hmac_sha1_trunclen_8() throws Exception { try { validator.validate ("signature-enveloping-hmac-sha1-trunclen-8-attack.xml", new KeySelectors.SecretKeySelector("secret".getBytes("ASCII"))); fail("Expected HMACOutputLength exception"); } catch (XMLSignatureException xse) { // System.out.println(xse.getMessage()); // pass } }
@org.junit.Test public void test_hmacShortSignature() throws Exception { String file = "hMACShortSignature.xml"; try { validator.validate(file, new KeySelectors.SecretKeySelector("secret".getBytes("ASCII"))); fail("Expected HMACOutputLength Exception"); } catch (XMLSignatureException xse) { // System.out.println(xse.getMessage()); // pass } }
@org.junit.Test public void test_signature_enveloping_hmac_sha1_40() throws Exception { String file = "signature-enveloping-hmac-sha1-40.xml"; KeySelector ks = new KeySelectors.SecretKeySelector ("secret".getBytes("ASCII") ); try { SignatureValidator validator = new SignatureValidator(dir); validator.validate(file, ks); fail("Expected HMACOutputLength exception"); } catch (XMLSignatureException xse) { System.out.println(xse.getMessage()); // pass } }
@org.junit.Test public void testWrappingAttack() throws Exception { String file = "manifestSignatureWrapping.xml"; Document doc = XMLUtils.createDocumentBuilder(false, false).parse(new File(dir, file)); Element sigElement = SignatureValidator.getSignatureElement(doc); if (sigElement == null) { throw new Exception("Couldn't find signature Element"); } DOMValidateContext vc = new DOMValidateContext(new KeySelectors.KeyValueKeySelector(), sigElement); vc.setBaseURI(dir.toURI().toString()); vc.setProperty("org.apache.jcp.xml.dsig.secureValidation", Boolean.FALSE); boolean coreValidity = validator.validate(vc); assertTrue("Signature failed core validation", coreValidity); vc.setProperty("org.apache.jcp.xml.dsig.secureValidation", Boolean.TRUE); Element manifestElement = (Element) doc.getElementsByTagName("Manifest").item(0); vc.setIdAttributeNS(manifestElement, null, "Id"); try { boolean valid = validator.validate(vc); System.out.println("Valid: " + valid); fail("Failure expected when secure validation is enabled"); } catch (XMLSignatureException ex) { assertTrue(ex.getMessage().contains("URIReferenceException")); } }
@org.junit.Test public void test_signature_hmac_sha1_40_c14n_comments_detached() throws Exception { String file = "signature-hmac-sha1-40-c14n-comments-detached.xml"; KeySelector ks = new KeySelectors.SecretKeySelector ("test".getBytes("ASCII") ); try { validator.validate(file, ks); fail("Expected HMACOutputLength Exception"); } catch (XMLSignatureException xse) { //System.out.println(xse.getMessage()); // pass } }
@org.junit.Test public void test_signature_hmac_sha1_40_exclusive_c14n_comments_detached() throws Exception { String file = "signature-hmac-sha1-40-exclusive-c14n-comments-detached.xml"; KeySelector ks = new KeySelectors.SecretKeySelector ("test".getBytes("ASCII") ); try { validator.validate(file, ks); fail("Expected HMACOutputLength Exception"); } catch (XMLSignatureException xse) { //System.out.println(xse.getMessage()); // pass } }
@org.junit.Test public void test_signature_rsa_detached_xslt_transform_bad_rm() throws Exception { String file = "signature-rsa-detached-xslt-transform-bad-retrieval-method.xml"; try { validator.validate(file, new KeySelectors.CollectionKeySelector(base)); fail("Should throw XMLSignatureException for using DSA key with " + "RSA algorithm"); } catch (XMLSignatureException xse) {} }
/** * Verifies that signed mark data contains a valid signature. * * <p>This method DOES NOT check if the SMD ID is revoked. It's only concerned with the * cryptographic stuff. * * @throws GeneralSecurityException for unsupported protocols, certs not signed by the TMCH, * incorrect keys, and for invalid, old, not-yet-valid or revoked certificates. * @throws IOException * @throws MarshalException * @throws ParserConfigurationException * @throws SAXException */ public void verify(byte[] smdXml) throws GeneralSecurityException, IOException, MarshalException, ParserConfigurationException, SAXException, XMLSignatureException { checkArgument(smdXml.length > 0); Document doc = parseSmdDocument(new ByteArrayInputStream(smdXml)); NodeList signatureNodes = doc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature"); if (signatureNodes.getLength() != 1) { throw new XMLSignatureException("Expected exactly one <ds:Signature> element."); } XMLSignatureFactory factory = XMLSignatureFactory.getInstance("DOM"); KeyValueKeySelector selector = new KeyValueKeySelector(tmchCertificateAuthority); DOMValidateContext context = new DOMValidateContext(selector, signatureNodes.item(0)); XMLSignature signature = factory.unmarshalXMLSignature(context); boolean isValid; try { isValid = signature.validate(context); } catch (XMLSignatureException e) { throwIfInstanceOf(getRootCause(e), GeneralSecurityException.class); throw e; } if (!isValid) { throw new XMLSignatureException(explainValidationProblem(context, signature)); } }
protected void checkSearchValueOfType(Class<?> cl, Input input) throws Exception { //NOPMD if (!cl.isAssignableFrom(input.getOutputNodeSearch().getClass())) { throw new XMLSignatureException(String.format( "Wrong configruation: Search value is of class %s, the output node search %s requires class %s.", input .getOutputNodeSearch().getClass().getName(), input.getOutputNodeSearchType(), cl.getName())); } }
protected void checkSearchValueNotNull(Input input) throws Exception { //NOPMD LOG.debug("Searching for output element with search value '{}' and sarch type {}", input.getOutputNodeSearch(), input.getOutputNodeSearchType()); if (input.getOutputNodeSearch() == null) { throw new XMLSignatureException(String.format("Wrong configruation: Value is missing for output node search %s.", input.getOutputNodeSearchType())); } }
@Override public Exception onXMLSignatureException(XMLSignatureException se) { if (se.getCause() instanceof InvalidKeyException) { return new XmlSignatureInvalidKeyException(se); } else { return new XmlSignatureException(se); } }
/** * return list of signers for the document available via the given URL. * * @param odfUrl * @return list of X509 certificates * @throws IOException * @throws ParserConfigurationException * @throws SAXException * @throws MarshalException * @throws XMLSignatureException */ public static List<X509Certificate> getSigners(URL odfUrl) throws IOException, ParserConfigurationException, SAXException, MarshalException, XMLSignatureException { List<X509Certificate> signers = new LinkedList<X509Certificate>(); if (null == odfUrl) { throw new IllegalArgumentException("odfUrl is null"); } ZipInputStream odfZipInputStream = new ZipInputStream(odfUrl.openStream()); ZipEntry zipEntry; while (null != (zipEntry = odfZipInputStream.getNextEntry())) { if (ODFUtil.isSignatureFile(zipEntry)) { Document documentSignatures = ODFUtil.loadDocument(odfZipInputStream); NodeList signatureNodeList = documentSignatures.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature"); for (int idx = 0; idx < signatureNodeList.getLength(); idx++) { Node signatureNode = signatureNodeList.item(idx); X509Certificate signer = getVerifiedSignatureSigner(odfUrl, signatureNode); if (null == signer) { LOG.debug("JSR105 says invalid signature"); } else { signers.add(signer); } } return signers; } } LOG.debug("no signature file present"); return signers; }
private static X509Certificate getVerifiedSignatureSigner(URL odfUrl, Node signatureNode) throws MarshalException, XMLSignatureException { if (null == odfUrl) { throw new IllegalArgumentException("odfUrl is null"); } KeyInfoKeySelector keySelector = new KeyInfoKeySelector(); DOMValidateContext domValidateContext = new DOMValidateContext(keySelector, 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); if (false == validity) { LOG.debug("invalid signature"); return null; } // TODO: check what has been signed. X509Certificate signer = keySelector.getCertificate(); if (null == signer) { throw new IllegalStateException("signer X509 certificate is null"); } LOG.debug("signer: " + signer.getSubjectX500Principal()); return signer; }
public List<X509Certificate> getSigners(URL url) throws IOException, ParserConfigurationException, SAXException, TransformerException, MarshalException, XMLSignatureException, JAXBException { List<X509Certificate> signers = new LinkedList<X509Certificate>(); List<String> signatureResourceNames = getSignatureResourceNames(url); for (String signatureResourceName : signatureResourceNames) { LOG.debug("signature resource name: " + signatureResourceName); Document signatureDocument = loadDocument(url, signatureResourceName); if (null == signatureDocument) { LOG.warn("signature resource not found: " + signatureResourceName); continue; } NodeList signatureNodeList = signatureDocument.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature"); if (0 == signatureNodeList.getLength()) { LOG.debug("no signature elements present"); continue; } Node signatureNode = signatureNodeList.item(0); OPCKeySelector keySelector = new OPCKeySelector(url, signatureResourceName); DOMValidateContext domValidateContext = new DOMValidateContext(keySelector, signatureNode); domValidateContext.setProperty("org.jcp.xml.dsig.validateManifests", Boolean.TRUE); OOXMLURIDereferencer dereferencer = new OOXMLURIDereferencer(url); domValidateContext.setURIDereferencer(dereferencer); XMLSignatureFactory xmlSignatureFactory = XMLSignatureFactory.getInstance(); XMLSignature xmlSignature = xmlSignatureFactory.unmarshalXMLSignature(domValidateContext); boolean validity = xmlSignature.validate(domValidateContext); if (false == validity) { LOG.debug("not a valid signature"); continue; } // TODO: check what has been signed. X509Certificate signer = keySelector.getCertificate(); signers.add(signer); } return signers; }
private boolean hasOdfSignature(URL odfUrl, int signatureCount) throws IOException, ParserConfigurationException, SAXException, org.apache.xml.security.signature.XMLSignatureException, XMLSecurityException, MarshalException, XMLSignatureException { InputStream odfInputStream = odfUrl.openStream(); if (null == odfInputStream) { return false; } ZipInputStream odfZipInputStream = new ZipInputStream(odfInputStream); ZipEntry zipEntry; while (null != (zipEntry = odfZipInputStream.getNextEntry())) { LOG.debug(zipEntry.getName()); if (true == "META-INF/documentsignatures.xml".equals(zipEntry.getName())) { Document documentSignatures = loadDocument(odfZipInputStream); NodeList signatureNodeList = documentSignatures.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature"); assertEquals(signatureCount, signatureNodeList.getLength()); for (int idx = 0; idx < signatureNodeList.getLength(); idx++) { Node signatureNode = signatureNodeList.item(idx); if (false == verifySignature(odfUrl, signatureNode)) { LOG.debug("JSR105 says invalid signature"); return false; } } return true; } } LOG.debug("no documentsignatures.xml entry present"); return false; }
/** * Sign assertions in SAML message * * @param document * Document in assertions should be signed * @param signAlgorithm * Signature algorithm in uri form, default if an unknown * algorithm is provided: * http://www.w3.org/2001/04/xmldsig-more#rsa-sha256 * @param digestAlgorithm * Digest algorithm in uri form, default if an unknown algorithm * is provided: http://www.w3.org/2001/04/xmlenc#sha256 */ public void signAssertion(Document document, String signAlgorithm, String digestAlgorithm, X509Certificate cert, PrivateKey key) throws CertificateException, FileNotFoundException, NoSuchAlgorithmException, InvalidKeySpecException, MarshalException, XMLSignatureException, IOException { try { if(Thread.currentThread().getContextClassLoader() == null){ Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); } setIDAttribute(document); XPath xpath = XPathFactory.newInstance().newXPath(); XPathExpression expr = xpath.compile("//*[local-name()='Assertion']/@ID"); NodeList nlURIs = (NodeList) expr.evaluate(document, XPathConstants.NODESET); String[] sigIDs = new String[nlURIs.getLength()]; for (int i = 0; i < nlURIs.getLength(); i++) { sigIDs[i] = nlURIs.item(i).getNodeValue(); } Init.init(); for (String id : sigIDs) { signElement(document, id, cert, key, signAlgorithm, digestAlgorithm); } } catch (XPathExpressionException e) { e.printStackTrace(); } }
/** * Sign whole SAML Message * * @param document * Document with the response to sign * @param signAlgorithm * Signature algorithm in uri form, default if an unknown * algorithm is provided: * http://www.w3.org/2001/04/xmldsig-more#rsa-sha256 * @param digestAlgorithm * Digest algorithm in uri form, default if an unknown algorithm * is provided: http://www.w3.org/2001/04/xmlenc#sha256 */ public void signMessage(Document document, String signAlgorithm, String digestAlgorithm, X509Certificate cert, PrivateKey key) throws CertificateException, FileNotFoundException, NoSuchAlgorithmException, InvalidKeySpecException, MarshalException, XMLSignatureException, IOException { try { if(Thread.currentThread().getContextClassLoader() == null){ Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); } setIDAttribute(document); XPath xpath = XPathFactory.newInstance().newXPath(); XPathExpression expr = xpath.compile("//*[local-name()='Response']/@ID"); NodeList nlURIs = (NodeList) expr.evaluate(document, XPathConstants.NODESET); String[] sigIDs = new String[nlURIs.getLength()]; for (int i = 0; i < nlURIs.getLength(); i++) { sigIDs[i] = nlURIs.item(i).getNodeValue(); } Init.init(); for (String id : sigIDs) { signElement(document, id, cert, key, signAlgorithm, digestAlgorithm); } } catch (XPathExpressionException e) { e.printStackTrace(); } }
private Element signSignature(String id, Element env, KeyInfoFactory keyInfoFactory, X509Credential credential) throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, MarshalException, XMLSignatureException { if (endorsingToken == null) return env; NodeList nl = env.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature"); for (int i = 0; i < nl.getLength(); i++) { Element e = (Element) nl.item(i); if (e.hasAttributeNS(null, "Id")) { e.setAttributeNS(WSSecurityConstants.WSU_NS, "Id", e.getAttribute("Id")); e.setIdAttributeNS(WSSecurityConstants.WSU_NS, "Id", true); } } env = SAMLUtil.loadElementFromString(XMLHelper.nodeToString(env)); DigestMethod digestMethod = xsf.newDigestMethod(DigestMethod.SHA1, null); List<Transform> transforms = new ArrayList<Transform>(2); transforms.add(xsf.newTransform("http://www.w3.org/2001/10/xml-exc-c14n#",new ExcC14NParameterSpec(Collections.singletonList("xsd")))); List<Reference> refs = new ArrayList<Reference>(); Reference r = xsf.newReference("#"+id, digestMethod, transforms, null, null); refs.add(r); CanonicalizationMethod canonicalizationMethod = xsf.newCanonicalizationMethod(CanonicalizationMethod.EXCLUSIVE, (C14NMethodParameterSpec) null); SignatureMethod signatureMethod = xsf.newSignatureMethod(SignatureMethod.RSA_SHA1, null); SignedInfo signedInfo = xsf.newSignedInfo(canonicalizationMethod, signatureMethod, refs); KeyInfo ki = generateKeyInfo(credential, keyInfoFactory, false); XMLSignature signature = xsf.newXMLSignature(signedInfo, ki); Node security = env.getElementsByTagNameNS(WSSecurityConstants.WSSE_NS, "Security").item(0); DOMSignContext signContext = new DOMSignContext(credential.getPrivateKey(), security); signContext.putNamespacePrefix(SAMLConstants.XMLSIG_NS, SAMLConstants.XMLSIG_PREFIX); signContext.putNamespacePrefix(SAMLConstants.XMLENC_NS, SAMLConstants.XMLENC_PREFIX); signature.sign(signContext); return env; }
private BinarySecurityToken createBinarySecurityToken(X509Credential credential) throws XMLSignatureException { BinarySecurityToken bst = SAMLUtil.buildXMLObject(BinarySecurityToken.class); bst.setEncodingType("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"); bst.getUnknownAttributes().put(TrustConstants.VALUE_TYPE, "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"); bst.setWSUId(Utils.generateUUID()); // assume that the first element is Timestamp (or the list is empty) int idx = -1; if (securityToken != null) { idx = security.getUnknownXMLObjects().indexOf(securityToken); } if (endorsingToken != null) { idx = Math.max(idx, security.getUnknownXMLObjects().indexOf(securityToken)); } if (idx > -1) { security.getUnknownXMLObjects().add(idx + 1, bst); } else { security.getUnknownXMLObjects().add(Math.min(1, security.getUnknownXMLObjects().size()), bst); } if (signingPolicy.sign(bst)) { references.put(bst, bst.getWSUId()); } try { bst.setValue(Base64.encodeBytes(credential.getEntityCertificate().getEncoded(), Base64.DONT_BREAK_LINES)); } catch (CertificateEncodingException e) { throw new XMLSignatureException(e); } return bst; }
private boolean verify(Document document, List<EbMSDataSource> dataSources) throws MarshalException, XMLSignatureException { NodeList nodeList = document.getElementsByTagNameNS(XMLSignature.XMLNS,"Signature"); if (nodeList.getLength() > 0) { XMLSignatureFactory signFactory = XMLSignatureFactory.getInstance(); DOMValidateContext validateContext = new DOMValidateContext(new XMLDSigKeySelector(),nodeList.item(0)); URIDereferencer dereferencer = new EbMSDataSourceURIDereferencer(dataSources); validateContext.setURIDereferencer(dereferencer); XMLSignature signature = signFactory.unmarshalXMLSignature(validateContext); return signature.validate(validateContext); } return true; }
private void sign(KeyStore keyStore, KeyPair keyPair, String alias, Document document, List<EbMSDataSource> dataSources) throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, IOException, KeyException, MarshalException, XMLSignatureException, KeyStoreException { //XMLSignatureFactory signFactory = XMLSignatureFactory.getInstance("DOM"); XMLSignatureFactory signFactory = XMLSignatureFactory.getInstance(); DigestMethod sha1DigestMethod = signFactory.newDigestMethod(DigestMethod.SHA1,null); List<Transform> transforms = new ArrayList<Transform>(); transforms.add(signFactory.newTransform(Transform.ENVELOPED,(TransformParameterSpec)null)); Map<String,String> m = new HashMap<String,String>(); m.put("soap","http://schemas.xmlsoap.org/soap/envelope/"); transforms.add(signFactory.newTransform(Transform.XPATH,new XPathFilterParameterSpec("not(ancestor-or-self::node()[@soap:actor=\"urn:oasis:names:tc:ebxml-msg:service:nextMSH\"]|ancestor-or-self::node()[@soap:actor=\"http://schemas.xmlsoap.org/soap/actor/next\"])",m))); transforms.add(signFactory.newTransform(CanonicalizationMethod.INCLUSIVE,(TransformParameterSpec)null)); List<Reference> references = new ArrayList<Reference>(); references.add(signFactory.newReference("",sha1DigestMethod,transforms,null,null)); for (EbMSDataSource dataSource : dataSources) references.add(signFactory.newReference("cid:" + dataSource.getContentId(),sha1DigestMethod,Collections.emptyList(),null,null,DigestUtils.sha(IOUtils.toByteArray(dataSource.getInputStream())))); SignedInfo signedInfo = signFactory.newSignedInfo(signFactory.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE,(C14NMethodParameterSpec)null),signFactory.newSignatureMethod(SignatureMethod.RSA_SHA1,null),references); List<XMLStructure> keyInfoElements = new ArrayList<XMLStructure>(); KeyInfoFactory keyInfoFactory = signFactory.getKeyInfoFactory(); keyInfoElements.add(keyInfoFactory.newKeyValue(keyPair.getPublic())); Certificate[] certificates = keyStore.getCertificateChain(alias); //keyInfoElements.add(keyInfoFactory.newX509Data(Arrays.asList(certificates))); keyInfoElements.add(keyInfoFactory.newX509Data(Collections.singletonList(certificates[0]))); KeyInfo keyInfo = keyInfoFactory.newKeyInfo(keyInfoElements); XMLSignature signature = signFactory.newXMLSignature(signedInfo,keyInfo); Element soapHeader = getFirstChildElement(document.getDocumentElement()); DOMSignContext signContext = new DOMSignContext(keyPair.getPrivate(),soapHeader); signContext.putNamespacePrefix(XMLSignature.XMLNS,"ds"); signature.sign(signContext); }
private void signRequest(Element requestElement, PrivateKey privateKey, X509Certificate certificate) throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, MarshalException, XMLSignatureException { DOMSignContext domSignContext = new DOMSignContext(privateKey, requestElement, requestElement.getFirstChild()); XMLSignatureFactory xmlSignatureFactory = XMLSignatureFactory .getInstance("DOM"); String requestId = requestElement.getAttribute("RequestID"); requestElement.setIdAttribute("RequestID", true); List<Transform> transforms = new LinkedList<>(); transforms.add(xmlSignatureFactory.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null)); transforms.add(xmlSignatureFactory.newTransform( CanonicalizationMethod.EXCLUSIVE, (C14NMethodParameterSpec) null)); Reference reference = xmlSignatureFactory.newReference("#" + requestId, xmlSignatureFactory.newDigestMethod(DigestMethod.SHA1, null), transforms, null, null); SignedInfo signedInfo = xmlSignatureFactory.newSignedInfo( xmlSignatureFactory.newCanonicalizationMethod( CanonicalizationMethod.EXCLUSIVE, (C14NMethodParameterSpec) null), xmlSignatureFactory .newSignatureMethod(SignatureMethod.RSA_SHA1, null), Collections.singletonList(reference)); KeyInfoFactory keyInfoFactory = xmlSignatureFactory.getKeyInfoFactory(); KeyInfo keyInfo = keyInfoFactory.newKeyInfo(Collections .singletonList(keyInfoFactory.newX509Data(Collections .singletonList(certificate)))); XMLSignature xmlSignature = xmlSignatureFactory.newXMLSignature( signedInfo, keyInfo); xmlSignature.sign(domSignContext); }