blob: c77ba559cd9cc829cca96252559ec391a21d1962 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25/*
26 * $Id: DOMDigestMethod.java,v 1.17 2005/05/10 18:15:32 mullan Exp $
27 */
28package org.jcp.xml.dsig.internal.dom;
29
30import javax.xml.crypto.*;
31import javax.xml.crypto.dom.DOMCryptoContext;
32import javax.xml.crypto.dsig.*;
33import javax.xml.crypto.dsig.spec.DigestMethodParameterSpec;
34
35import java.security.InvalidAlgorithmParameterException;
36import java.security.spec.AlgorithmParameterSpec;
37import org.w3c.dom.Document;
38import org.w3c.dom.Element;
39import org.w3c.dom.Node;
40
41/**
42 * DOM-based abstract implementation of DigestMethod.
43 *
44 * @author Sean Mullan
45 */
46public abstract class DOMDigestMethod extends DOMStructure
47 implements DigestMethod {
48
49 final static String SHA384 =
50 "http://www.w3.org/2001/04/xmldsig-more#sha384"; // see RFC 4051
51 private DigestMethodParameterSpec params;
52
53 /**
54 * Creates a <code>DOMDigestMethod</code>.
55 *
56 * @param params the algorithm-specific params (may be <code>null</code>)
57 * @throws InvalidAlgorithmParameterException if the parameters are not
58 * appropriate for this digest method
59 */
60 DOMDigestMethod(AlgorithmParameterSpec params)
61 throws InvalidAlgorithmParameterException {
62 if (params != null && !(params instanceof DigestMethodParameterSpec)) {
63 throw new InvalidAlgorithmParameterException
64 ("params must be of type DigestMethodParameterSpec");
65 }
66 checkParams((DigestMethodParameterSpec) params);
67 this.params = (DigestMethodParameterSpec) params;
68 }
69
70 /**
71 * Creates a <code>DOMDigestMethod</code> from an element. This constructor
72 * invokes the abstract {@link #unmarshalParams unmarshalParams} method to
73 * unmarshal any algorithm-specific input parameters.
74 *
75 * @param dmElem a DigestMethod element
76 */
77 DOMDigestMethod(Element dmElem) throws MarshalException {
78 Element paramsElem = DOMUtils.getFirstChildElement(dmElem);
79 if (paramsElem != null) {
80 params = unmarshalParams(paramsElem);
81 }
82 try {
83 checkParams(params);
84 } catch (InvalidAlgorithmParameterException iape) {
85 throw new MarshalException(iape);
86 }
87 }
88
89 static DigestMethod unmarshal(Element dmElem) throws MarshalException {
90 String alg = DOMUtils.getAttributeValue(dmElem, "Algorithm");
91 if (alg.equals(DigestMethod.SHA1)) {
92 return new SHA1(dmElem);
93 } else if (alg.equals(DigestMethod.SHA256)) {
94 return new SHA256(dmElem);
95 } else if (alg.equals(SHA384)) {
96 return new SHA384(dmElem);
97 } else if (alg.equals(DigestMethod.SHA512)) {
98 return new SHA512(dmElem);
99 } else {
100 throw new MarshalException
101 ("unsupported DigestMethod algorithm: " + alg);
102 }
103 }
104
105 /**
106 * Checks if the specified parameters are valid for this algorithm. By
107 * default, this method throws an exception if parameters are specified
108 * since most DigestMethod algorithms do not have parameters. Subclasses
109 * should override it if they have parameters.
110 *
111 * @param params the algorithm-specific params (may be <code>null</code>)
112 * @throws InvalidAlgorithmParameterException if the parameters are not
113 * appropriate for this digest method
114 */
115 void checkParams(DigestMethodParameterSpec params)
116 throws InvalidAlgorithmParameterException {
117 if (params != null) {
118 throw new InvalidAlgorithmParameterException("no parameters " +
119 "should be specified for the " + getMessageDigestAlgorithm()
120 + " DigestMethod algorithm");
121 }
122 }
123
124 public final AlgorithmParameterSpec getParameterSpec() {
125 return params;
126 }
127
128 /**
129 * Unmarshals <code>DigestMethodParameterSpec</code> from the specified
130 * <code>Element</code>. By default, this method throws an exception since
131 * most DigestMethod algorithms do not have parameters. Subclasses should
132 * override it if they have parameters.
133 *
134 * @param paramsElem the <code>Element</code> holding the input params
135 * @return the algorithm-specific <code>DigestMethodParameterSpec</code>
136 * @throws MarshalException if the parameters cannot be unmarshalled
137 */
138 DigestMethodParameterSpec
139 unmarshalParams(Element paramsElem) throws MarshalException {
140 throw new MarshalException("no parameters should " +
141 "be specified for the " + getMessageDigestAlgorithm() +
142 " DigestMethod algorithm");
143 }
144
145 /**
146 * This method invokes the abstract {@link #marshalParams marshalParams}
147 * method to marshal any algorithm-specific parameters.
148 */
149 public void marshal(Node parent, String prefix, DOMCryptoContext context)
150 throws MarshalException {
151 Document ownerDoc = DOMUtils.getOwnerDocument(parent);
152
153 Element dmElem = DOMUtils.createElement
154 (ownerDoc, "DigestMethod", XMLSignature.XMLNS, prefix);
155 DOMUtils.setAttribute(dmElem, "Algorithm", getAlgorithm());
156
157 if (params != null) {
158 marshalParams(dmElem, prefix);
159 }
160
161 parent.appendChild(dmElem);
162 }
163
164 public boolean equals(Object o) {
165 if (this == o) {
166 return true;
167 }
168
169 if (!(o instanceof DigestMethod)) {
170 return false;
171 }
172 DigestMethod odm = (DigestMethod) o;
173
174 boolean paramsEqual = (params == null ? odm.getParameterSpec() == null :
175 params.equals(odm.getParameterSpec()));
176
177 return (getAlgorithm().equals(odm.getAlgorithm()) && paramsEqual);
178 }
179
180 /**
181 * Marshals the algorithm-specific parameters to an Element and
182 * appends it to the specified parent element. By default, this method
183 * throws an exception since most DigestMethod algorithms do not have
184 * parameters. Subclasses should override it if they have parameters.
185 *
186 * @param parent the parent element to append the parameters to
187 * @param the namespace prefix to use
188 * @throws MarshalException if the parameters cannot be marshalled
189 */
190 void marshalParams(Element parent, String prefix)
191 throws MarshalException {
192 throw new MarshalException("no parameters should " +
193 "be specified for the " + getMessageDigestAlgorithm() +
194 " DigestMethod algorithm");
195 }
196
197 /**
198 * Returns the MessageDigest standard algorithm name.
199 */
200 abstract String getMessageDigestAlgorithm();
201
202 static final class SHA1 extends DOMDigestMethod {
203 SHA1(AlgorithmParameterSpec params)
204 throws InvalidAlgorithmParameterException {
205 super(params);
206 }
207 SHA1(Element dmElem) throws MarshalException {
208 super(dmElem);
209 }
210 public String getAlgorithm() {
211 return DigestMethod.SHA1;
212 }
213 String getMessageDigestAlgorithm() {
214 return "SHA-1";
215 }
216 }
217
218 static final class SHA256 extends DOMDigestMethod {
219 SHA256(AlgorithmParameterSpec params)
220 throws InvalidAlgorithmParameterException {
221 super(params);
222 }
223 SHA256(Element dmElem) throws MarshalException {
224 super(dmElem);
225 }
226 public String getAlgorithm() {
227 return DigestMethod.SHA256;
228 }
229 String getMessageDigestAlgorithm() {
230 return "SHA-256";
231 }
232 }
233
234 static final class SHA384 extends DOMDigestMethod {
235 SHA384(AlgorithmParameterSpec params)
236 throws InvalidAlgorithmParameterException {
237 super(params);
238 }
239 SHA384(Element dmElem) throws MarshalException {
240 super(dmElem);
241 }
242 public String getAlgorithm() {
243 return SHA384;
244 }
245 String getMessageDigestAlgorithm() {
246 return "SHA-384";
247 }
248 }
249
250 static final class SHA512 extends DOMDigestMethod {
251 SHA512(AlgorithmParameterSpec params)
252 throws InvalidAlgorithmParameterException {
253 super(params);
254 }
255 SHA512(Element dmElem) throws MarshalException {
256 super(dmElem);
257 }
258 public String getAlgorithm() {
259 return DigestMethod.SHA512;
260 }
261 String getMessageDigestAlgorithm() {
262 return "SHA-512";
263 }
264 }
265}