001: /*
002: * Reference.java
003: *
004: * Created on January 24, 2006, 2:43 PM
005: */
006:
007: /*
008: * The contents of this file are subject to the terms
009: * of the Common Development and Distribution License
010: * (the License). You may not use this file except in
011: * compliance with the License.
012: *
013: * You can obtain a copy of the license at
014: * https://glassfish.dev.java.net/public/CDDLv1.0.html.
015: * See the License for the specific language governing
016: * permissions and limitations under the License.
017: *
018: * When distributing Covered Code, include this CDDL
019: * Header Notice in each file and include the License file
020: * at https://glassfish.dev.java.net/public/CDDLv1.0.html.
021: * If applicable, add the following below the CDDL Header,
022: * with the fields enclosed by brackets [] replaced by
023: * you own identifying information:
024: * "Portions Copyrighted [year] [name of copyright owner]"
025: *
026: * Copyright 2006 Sun Microsystems Inc. All Rights Reserved
027: */
028:
029: package com.sun.xml.ws.security.opt.crypto.dsig;
030:
031: import com.sun.org.apache.xml.internal.security.utils.UnsyncBufferedOutputStream;
032: import com.sun.xml.security.core.dsig.TransformsType;
033: import com.sun.xml.ws.security.opt.impl.util.StreamUtil;
034: import com.sun.xml.wss.logging.LogDomainConstants;
035: import com.sun.xml.wss.logging.impl.opt.signature.LogStringsMessages;
036: import java.io.IOException;
037: import java.io.InputStream;
038: import java.io.OutputStream;
039: import java.security.MessageDigest;
040: import java.security.NoSuchAlgorithmException;
041: import java.util.Arrays;
042: import java.util.List;
043: import java.util.logging.Level;
044: import java.util.logging.Logger;
045: import javax.xml.bind.annotation.XmlRootElement;
046: import javax.xml.bind.annotation.XmlTransient;
047: import javax.xml.crypto.Data;
048: import javax.xml.crypto.URIDereferencer;
049: import javax.xml.crypto.URIReferenceException;
050: import javax.xml.crypto.XMLCryptoContext;
051: import javax.xml.crypto.dsig.TransformException;
052: import javax.xml.crypto.dsig.XMLSignatureException;
053: import javax.xml.crypto.dsig.XMLValidateContext;
054: import org.jcp.xml.dsig.internal.DigesterOutputStream;
055:
056: /**
057: *
058: * @author Abhijit Das
059: * @author K.Venugopal@sun.com
060: */
061: @XmlRootElement(name="Reference",namespace="http://www.w3.org/2000/09/xmldsig#")
062: public class Reference extends
063: com.sun.xml.security.core.dsig.ReferenceType implements
064: javax.xml.crypto.dsig.Reference {
065: @XmlTransient
066: private static final Logger logger = Logger.getLogger(
067: LogDomainConstants.IMPL_OPT_SIGNATURE_DOMAIN,
068: LogDomainConstants.IMPL_OPT_SIGNATURE_DOMAIN_BUNDLE);
069: @XmlTransient
070: private Data _appliedTransformData;
071: //@XmlTransient private boolean _digested = false;
072: @XmlTransient
073: private MessageDigest _md;
074:
075: @XmlTransient
076: private boolean _validated;
077: @XmlTransient
078: private boolean _validationStatus;
079: @XmlTransient
080: private byte[] _calcDigestValue;
081:
082: /** Creates a new instance of Reference */
083: public Reference() {
084: }
085:
086: public byte[] getCalculatedDigestValue() {
087: return _calcDigestValue;
088: }
089:
090: public boolean validate(XMLValidateContext xMLValidateContext)
091: throws XMLSignatureException {
092: if (xMLValidateContext == null) {
093: throw new NullPointerException(
094: "validateContext cannot be null");
095: }
096: if (_validated) {
097: return _validationStatus;
098: }
099: Data data = dereference(xMLValidateContext);
100: _calcDigestValue = transform(data, xMLValidateContext);
101: if (logger.isLoggable(Level.FINEST)) {
102: logger.log(Level.FINEST, "Calculated digest value is: "
103: + new String(_calcDigestValue));
104: }
105:
106: if (logger.isLoggable(Level.FINEST)) {
107: logger.log(Level.FINEST, " Expected digest value is: "
108: + new String(digestValue));
109: }
110:
111: _validationStatus = Arrays
112: .equals(digestValue, _calcDigestValue);
113: _validated = true;
114: return _validationStatus;
115: }
116:
117: public void digest(XMLCryptoContext signContext)
118: throws XMLSignatureException {
119: if (this .getDigestValue() == null) {
120: Data data = null;
121: if (_appliedTransformData == null) {
122: data = dereference(signContext);
123: } else {
124: data = _appliedTransformData;
125: }
126: byte[] digest = transform(data, signContext);
127: this .setDigestValue(digest);
128: }
129: // insert digestValue into DigestValue element
130: //String encodedDV = Base64.encode(digestValue);
131:
132: }
133:
134: public DigesterOutputStream getDigestOutputStream()
135: throws XMLSignatureException {
136: DigesterOutputStream dos;
137: try {
138: String algo = StreamUtil.convertDigestAlgorithm(this
139: .getDigestMethod().getAlgorithm());
140: if (logger.isLoggable(Level.FINE)) {
141: logger.log(Level.FINE, "Digest Algorithm is "
142: + this .getDigestMethod().getAlgorithm());
143: logger.log(Level.FINE, "Mapped Digest Algorithm is "
144: + algo);
145: }
146: _md = MessageDigest.getInstance(algo);
147: } catch (NoSuchAlgorithmException nsae) {
148: throw new XMLSignatureException(nsae);
149: }
150: dos = new DigesterOutputStream(_md);
151: return dos;
152: }
153:
154: private byte[] transform(Data dereferencedData,
155: XMLCryptoContext context) throws XMLSignatureException {
156:
157: if (_md == null) {
158: try {
159: String algo = StreamUtil.convertDigestAlgorithm(this
160: .getDigestMethod().getAlgorithm());
161: if (logger.isLoggable(Level.FINE)) {
162: logger.log(Level.FINE, "Digest Algorithm is "
163: + this .getDigestMethod().getAlgorithm());
164: logger.log(Level.FINE,
165: "Mapped Digest Algorithm is " + algo);
166: }
167: _md = MessageDigest.getInstance(algo);
168:
169: } catch (NoSuchAlgorithmException nsae) {
170: logger.log(Level.SEVERE, LogStringsMessages
171: .WSS_1760_DIGEST_INIT_ERROR(), nsae);
172: throw new XMLSignatureException(nsae);
173: }
174: }
175: _md.reset();
176: DigesterOutputStream dos;
177:
178: //Boolean cache = (Boolean)context.getProperty("javax.xml.crypto.dsig.cacheReference");
179:
180: dos = new DigesterOutputStream(_md);
181: OutputStream os = new UnsyncBufferedOutputStream(dos);
182: Data data = dereferencedData;
183: if (transforms != null) {
184: List<Transform> transformList = ((TransformsType) transforms)
185: .getTransform();
186: if (transformList != null) {
187: for (int i = 0, size = transformList.size(); i < size; i++) {
188: Transform transform = (Transform) transformList
189: .get(i);
190: try {
191: if (i < size - 1) {
192: data = transform.transform(data, context);
193: } else {
194: data = transform.transform(data, context,
195: os);
196: }
197: } catch (TransformException te) {
198: logger.log(Level.SEVERE, LogStringsMessages
199: .WSS_1759_TRANSFORM_ERROR(te
200: .getMessage()), te);
201: throw new XMLSignatureException(te);
202: }
203: }
204: }
205: }
206:
207: try {
208: os.flush();
209: dos.flush();
210: } catch (IOException ex) {
211: logger.log(Level.SEVERE, LogStringsMessages
212: .WSS_1761_TRANSFORM_IO_ERROR(), ex);
213: throw new XMLSignatureException(ex);
214: }
215:
216: return dos.getDigestValue();
217: }
218:
219: private Data dereference(XMLCryptoContext context)
220: throws XMLSignatureException {
221: Data data = null;
222:
223: // use user-specified URIDereferencer if specified; otherwise use deflt
224: URIDereferencer deref = context.getURIDereferencer();
225:
226: try {
227: data = deref.dereference(this , context);
228: } catch (URIReferenceException ure) {
229: throw new XMLSignatureException(ure);
230: }
231: return data;
232: }
233:
234: public Data getDereferencedData() {
235: return _appliedTransformData;
236: }
237:
238: public InputStream getDigestInputStream() {
239: throw new UnsupportedOperationException("Not supported");
240: }
241:
242: public boolean isFeatureSupported(String string) {
243: //TODO
244: return false;
245: }
246:
247: public DigestMethod getDigestMethod() {
248: return digestMethod;
249:
250: }
251:
252: public List getTransforms() {
253: return transforms.getTransform();
254: }
255:
256: }
|