001: /*
002: * Signature.java
003: *
004: * Created on January 24, 2006, 3:59 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.xml.ws.security.opt.impl.util.JAXBUtil;
032: import com.sun.xml.ws.security.opt.crypto.dsig.keyinfo.KeyInfo;
033: import com.sun.xml.wss.logging.LogDomainConstants;
034: import java.security.InvalidKeyException;
035: import java.security.Key;
036: import java.security.SignatureException;
037: import java.util.ArrayList;
038: import java.util.Arrays;
039: import java.util.List;
040: import java.util.logging.Logger;
041: import java.util.logging.Level;
042: import javax.xml.bind.JAXBContext;
043: import javax.xml.bind.annotation.XmlRootElement;
044: import javax.xml.bind.annotation.XmlTransient;
045: import javax.xml.crypto.KeySelector;
046: import javax.xml.crypto.KeySelectorException;
047: import javax.xml.crypto.KeySelectorResult;
048: import javax.xml.crypto.MarshalException;
049: import javax.xml.crypto.dsig.XMLSignContext;
050: import javax.xml.crypto.dsig.XMLSignatureException;
051: import javax.xml.crypto.dsig.XMLValidateContext;
052: import org.jvnet.staxex.XMLStreamReaderEx;
053: import javax.xml.crypto.dsig.spec.SignatureMethodParameterSpec;
054: import javax.xml.crypto.dsig.spec.HMACParameterSpec;
055: import com.sun.xml.wss.logging.impl.opt.signature.LogStringsMessages;
056:
057: /**
058: *
059: * @author Abhijit Das
060: * @author K.Venugopal@sun.com
061: */
062:
063: @XmlRootElement(name="Signature",namespace="http://www.w3.org/2000/09/xmldsig#")
064: public class Signature extends
065: com.sun.xml.security.core.dsig.SignatureType implements
066: javax.xml.crypto.dsig.XMLSignature {
067: @XmlTransient
068: private static final Logger logger = Logger.getLogger(
069: LogDomainConstants.IMPL_OPT_SIGNATURE_DOMAIN,
070: LogDomainConstants.IMPL_OPT_SIGNATURE_DOMAIN_BUNDLE);
071:
072: @XmlTransient
073: private XMLStreamReaderEx _streamSI = null;
074: @XmlTransient
075: private String type = null;
076: @XmlTransient
077: private List<XMLObject> objects = null;
078: @XmlTransient
079: private SignatureProcessor _sp;
080: @XmlTransient
081: private Key verificationKey = null;
082: @XmlTransient
083: private byte[] signedInfoBytes = null;
084:
085: /**
086: * Creates a new instance of Signature
087: */
088:
089: public Signature() {
090: }
091:
092: public void setSignedInfo(XMLStreamReaderEx streamReader) {
093: this ._streamSI = streamReader;
094: }
095:
096: public void setSignedInfo(byte[] si) {
097: this .signedInfoBytes = si;
098: }
099:
100: public void setVerificationKey(Key key) {
101: this .verificationKey = key;
102: }
103:
104: public Key getVerificationKey() {
105: return verificationKey;
106:
107: }
108:
109: public boolean validate(XMLValidateContext xMLValidateContext)
110: throws XMLSignatureException {
111:
112: SignatureMethod sm;
113: if (xMLValidateContext == null) {
114: throw new NullPointerException(
115: "validateContext cannot be null");
116: }
117:
118: //List allReferences = new ArrayList(signedInfo.getReferences());
119:
120: SignedInfo si = getSignedInfo();
121: List refList = si.getReferences();
122: for (int i = 0, size = refList.size(); i < size; i++) {
123: Reference ref = (Reference) refList.get(i);
124: byte[] originalDigest = ref.getDigestValue();
125: ref.digest(xMLValidateContext);
126: byte[] calculatedDigest = ref.getDigestValue();
127: if (!Arrays.equals(originalDigest, calculatedDigest)) {
128: logger
129: .log(
130: Level.SEVERE,
131: LogStringsMessages
132: .WSS_1713_SIGNATURE_VERIFICATION_EXCEPTION("Signature digest values mismatch"));
133: throw new XMLSignatureException(
134: LogStringsMessages
135: .WSS_1713_SIGNATURE_VERIFICATION_EXCEPTION("Signature digest values mismatch"));
136:
137: }
138: }
139: si.setSignedInfo(_streamSI);
140:
141: // si.setCanonicalizedSI(signedInfoBytes);
142:
143: KeySelectorResult keySelectoResult = null;
144: try {
145: sm = si.getSignatureMethod();
146: if (verificationKey == null) {
147: keySelectoResult = xMLValidateContext.getKeySelector()
148: .select(getKeyInfo(),
149: KeySelector.Purpose.VERIFY, sm,
150: xMLValidateContext);
151: verificationKey = keySelectoResult.getKey();
152: }
153: if (verificationKey == null) {
154: throw new XMLSignatureException(
155: "The KeySelector"
156: + xMLValidateContext.getKeySelector()
157: + " did not "
158: + "find the key used for signature verification");
159: }
160:
161: if (_sp == null) {
162: _sp = new SignatureProcessor();
163: }
164:
165: try {
166: String signatureAlgo = sm.getAlgorithm();
167: if (signatureAlgo.equals(SignatureMethod.RSA_SHA1)) {
168: return _sp.verifyRSASignature(verificationKey, si,
169: getSignatureValue().getValue());
170: } else if (signatureAlgo
171: .equals(SignatureMethod.DSA_SHA1)) {
172: return _sp.verifyDSASignature(verificationKey, si,
173: getSignatureValue().getValue());
174: } else if (signatureAlgo
175: .equals(SignatureMethod.HMAC_SHA1)) {
176: SignatureMethodParameterSpec params = (SignatureMethodParameterSpec) sm
177: .getParameterSpec();
178:
179: int outputLength = -1;
180:
181: if (params != null) {
182: if (!(params instanceof HMACParameterSpec)) {
183: throw new XMLSignatureException(
184: "SignatureMethodParameterSpec must be of type HMACParameterSpec");
185:
186: }
187: outputLength = ((HMACParameterSpec) params)
188: .getOutputLength();
189: }
190: return _sp.verifyHMACSignature(verificationKey, si,
191: getSignatureValue().getValue(),
192: outputLength);
193: } else {
194: throw new XMLSignatureException(
195: "Unsupported signature algorithm found");
196: }
197: } catch (InvalidKeyException ex) {
198: logger.log(Level.SEVERE, LogStringsMessages
199: .WSS_1713_SIGNATURE_VERIFICATION_EXCEPTION(ex));
200: throw new XMLSignatureException(LogStringsMessages
201: .WSS_1713_SIGNATURE_VERIFICATION_EXCEPTION(ex));
202: } catch (SignatureException ex) {
203: logger
204: .log(
205: Level.SEVERE,
206: LogStringsMessages
207: .WSS_1713_SIGNATURE_VERIFICATION_EXCEPTION("Signature digest values mismatch"));
208: throw new XMLSignatureException(LogStringsMessages
209: .WSS_1713_SIGNATURE_VERIFICATION_EXCEPTION(ex));
210: }
211: } catch (KeySelectorException kse) {
212: throw new XMLSignatureException(
213: "Cannot find verification key", kse);
214: }
215: //return false;
216: }
217:
218: public List getObjects() {
219: return null;
220: }
221:
222: public void sign(XMLSignContext xMLSignContext)
223: throws MarshalException, XMLSignatureException {
224: SignatureMethod sm;
225: if (xMLSignContext == null) {
226: throw new NullPointerException("signContext cannot be null");
227: }
228:
229: //List allReferences = new ArrayList(signedInfo.getReferences());
230: SignedInfo si = getSignedInfo();
231: List refList = si.getReferences();
232: for (int i = 0, size = refList.size(); i < size; i++) {
233: Reference ref = (Reference) refList.get(i);
234: ref.digest(xMLSignContext);
235: }
236:
237: Key signingKey = null;
238: KeySelectorResult keySelectoResult = null;
239: try {
240: sm = si.getSignatureMethod();
241: keySelectoResult = xMLSignContext.getKeySelector().select(
242: getKeyInfo(), KeySelector.Purpose.SIGN, sm,
243: xMLSignContext);
244: signingKey = keySelectoResult.getKey();
245: if (signingKey == null) {
246: throw new XMLSignatureException("The KeySelector"
247: + xMLSignContext.getKeySelector() + " did not "
248: + "find the key used for signing");
249: }
250: } catch (KeySelectorException kse) {
251: throw new XMLSignatureException("Cannot find signing key",
252: kse);
253: }
254:
255: if (_sp == null) {
256: try {
257: JAXBContext jc = JAXBUtil.getJAXBContext();
258: _sp = new SignatureProcessor();
259: _sp.setJAXBContext(jc);
260: _sp.setCryptoContext(xMLSignContext);
261: } catch (Exception ex) {
262: throw new XMLSignatureException(ex);
263: }
264: }
265:
266: String signatureAlgo = sm.getAlgorithm();
267: //SignatureValue sv=getSignatureValue();
268:
269: if (signatureAlgo == SignatureMethod.RSA_SHA1) {
270: try {
271: com.sun.xml.ws.security.opt.crypto.dsig.SignatureValue sigValue = new com.sun.xml.ws.security.opt.crypto.dsig.SignatureValue();
272: sigValue.setValue(_sp.performRSASign(signingKey,
273: signedInfo));
274: setSignatureValue(sigValue);
275: //((SignatureValueType)getSignatureValue()).setValue(_sp.performRSASign(signingKey,signedInfo));
276: //((SignatureValueType)sv).setValue(_sp.performRSASign(signingKey,signedInfo));
277: } catch (InvalidKeyException ex) {
278: throw new XMLSignatureException(ex);
279: }
280: } else if (signatureAlgo == SignatureMethod.DSA_SHA1) {
281: try {
282: com.sun.xml.ws.security.opt.crypto.dsig.SignatureValue sigValue = new com.sun.xml.ws.security.opt.crypto.dsig.SignatureValue();
283: sigValue.setValue(_sp.performDSASign(signingKey,
284: signedInfo));
285: setSignatureValue(sigValue);
286:
287: //((SignatureValueType)sv).setValue(_sp.performDSASign(signingKey,signedInfo));
288:
289: } catch (InvalidKeyException ex) {
290: throw new XMLSignatureException(ex);
291: }
292:
293: } else if (signatureAlgo.equals(SignatureMethod.HMAC_SHA1)) {
294: SignatureMethodParameterSpec params = (SignatureMethodParameterSpec) sm
295: .getParameterSpec();
296: int outputLength = -1;
297: if (params != null) {
298: if (!(params instanceof HMACParameterSpec)) {
299: throw new XMLSignatureException(
300: "SignatureMethodParameterSpec must be of type HMACParameterSpec");
301: }
302: outputLength = ((HMACParameterSpec) params)
303: .getOutputLength();
304: }
305:
306: try {
307: com.sun.xml.ws.security.opt.crypto.dsig.SignatureValue sigValue = new com.sun.xml.ws.security.opt.crypto.dsig.SignatureValue();
308: sigValue.setValue(_sp.performHMACSign(signingKey,
309: signedInfo, outputLength));
310: setSignatureValue(sigValue);
311: } catch (InvalidKeyException ex) {
312: throw new XMLSignatureException(ex);
313: }
314: } else {
315: throw new XMLSignatureException(
316: "Unsupported signature algorithm found");
317: }
318: }
319:
320: public KeySelectorResult getKeySelectorResult() {
321: return null;
322: }
323:
324: public boolean isFeatureSupported(String string) {
325: return false;
326: }
327:
328: public SignatureValue getSignatureValue() {
329: return signatureValue;
330: }
331:
332: public SignedInfo getSignedInfo() {
333: return this .signedInfo;
334: }
335:
336: public KeyInfo getKeyInfo() {
337: return keyInfo;
338: }
339:
340: public void setObjects(List<XMLObject> objects) {
341: this .objects = objects;
342: }
343:
344: public String getType() {
345: return type;
346: }
347:
348: public void setType(String type) {
349: this.type = type;
350: }
351:
352: }
|