1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.opensaml.xml.signature.impl;
18
19 import javax.xml.parsers.DocumentBuilderFactory;
20 import javax.xml.parsers.ParserConfigurationException;
21
22 import org.apache.xml.security.Init;
23 import org.apache.xml.security.exceptions.XMLSecurityException;
24 import org.apache.xml.security.signature.XMLSignature;
25 import org.opensaml.xml.Configuration;
26 import org.opensaml.xml.XMLObject;
27 import org.opensaml.xml.io.Marshaller;
28 import org.opensaml.xml.io.MarshallingException;
29 import org.opensaml.xml.security.SecurityHelper;
30 import org.opensaml.xml.signature.ContentReference;
31 import org.opensaml.xml.signature.KeyInfo;
32 import org.opensaml.xml.signature.Signature;
33 import org.opensaml.xml.util.XMLHelper;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
36 import org.w3c.dom.Document;
37 import org.w3c.dom.Element;
38
39
40
41
42
43
44 public class SignatureMarshaller implements Marshaller {
45
46
47 private final Logger log = LoggerFactory.getLogger(SignatureMarshaller.class);
48
49
50 public SignatureMarshaller() {
51 if (!Init.isInitialized()) {
52 log.debug("Initializing XML security library");
53 Init.init();
54 }
55 }
56
57
58 public Element marshall(XMLObject xmlObject) throws MarshallingException {
59 try {
60 Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
61 return marshall(xmlObject, document);
62 } catch (ParserConfigurationException e) {
63 throw new MarshallingException("Unable to create Document to place marshalled elements in", e);
64 }
65 }
66
67
68 public Element marshall(XMLObject xmlObject, Element parentElement) throws MarshallingException {
69 Element signatureElement = createSignatureElement((SignatureImpl) xmlObject, parentElement.getOwnerDocument());
70 XMLHelper.appendChildElement(parentElement, signatureElement);
71 return signatureElement;
72 }
73
74
75 public Element marshall(XMLObject xmlObject, Document document) throws MarshallingException {
76 Element signatureElement = createSignatureElement((SignatureImpl) xmlObject, document);
77
78 Element documentRoot = document.getDocumentElement();
79 if (documentRoot != null) {
80 document.replaceChild(signatureElement, documentRoot);
81 } else {
82 document.appendChild(signatureElement);
83 }
84
85 return signatureElement;
86 }
87
88
89
90
91
92
93
94
95
96
97
98 private Element createSignatureElement(Signature signature, Document document) throws MarshallingException {
99 log.debug("Starting to marshall {}", signature.getElementQName());
100
101 try {
102 log.debug("Creating XMLSignature object");
103 XMLSignature dsig = null;
104 if (signature.getHMACOutputLength() != null && SecurityHelper.isHMAC(signature.getSignatureAlgorithm())) {
105 dsig = new XMLSignature(document, "", signature.getSignatureAlgorithm(), signature
106 .getHMACOutputLength(), signature.getCanonicalizationAlgorithm());
107 } else {
108 dsig = new XMLSignature(document, "", signature.getSignatureAlgorithm(), signature
109 .getCanonicalizationAlgorithm());
110 }
111
112 log.debug("Adding content to XMLSignature.");
113 for (ContentReference contentReference : signature.getContentReferences()) {
114 contentReference.createReference(dsig);
115 }
116
117 log.debug("Creating Signature DOM element");
118 Element signatureElement = dsig.getElement();
119
120 if (signature.getKeyInfo() != null) {
121 Marshaller keyInfoMarshaller = Configuration.getMarshallerFactory().getMarshaller(
122 KeyInfo.DEFAULT_ELEMENT_NAME);
123 keyInfoMarshaller.marshall(signature.getKeyInfo(), signatureElement);
124 }
125
126 ((SignatureImpl) signature).setXMLSignature(dsig);
127 signature.setDOM(signatureElement);
128 signature.releaseParentDOM(true);
129 return signatureElement;
130
131 } catch (XMLSecurityException e) {
132 log.error("Unable to construct signature Element " + signature.getElementQName(), e);
133 throw new MarshallingException("Unable to construct signature Element " + signature.getElementQName(), e);
134 }
135 }
136
137 }