1 /* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5 /* 6 * Copyright 2005 The Apache Software Foundation. 7 * 8 * Licensed under the Apache License, Version 2.0 (the "License"); 9 * you may not use this file except in compliance with the License. 10 * You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 * 20 */ 21 /* 22 * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved. 23 */ 24 /* 25 * $Id: DOMDigestMethod.java,v 1.2 2008/07/24 15:20:32 mullan Exp $ 26 */ 27 package org.jcp.xml.dsig.internal.dom; 28 29 import javax.xml.crypto.*; 30 import javax.xml.crypto.dom.DOMCryptoContext; 31 import javax.xml.crypto.dsig.*; 32 import javax.xml.crypto.dsig.spec.DigestMethodParameterSpec; 33 34 import java.security.InvalidAlgorithmParameterException; 35 import java.security.spec.AlgorithmParameterSpec; 36 import org.w3c.dom.Document; 37 import org.w3c.dom.Element; 38 import org.w3c.dom.Node; 39 40 /** 41 * DOM-based abstract implementation of DigestMethod. 42 * 43 * @author Sean Mullan 44 */ 45 public abstract class DOMDigestMethod extends DOMStructure 46 implements DigestMethod { 47 48 final static String SHA384 = 49 "http://www.w3.org/2001/04/xmldsig-more#sha384"; // see RFC 4051 50 private DigestMethodParameterSpec params; 51 52 /** 53 * Creates a <code>DOMDigestMethod</code>. 54 * 55 * @param params the algorithm-specific params (may be <code>null</code>) 56 * @throws InvalidAlgorithmParameterException if the parameters are not 57 * appropriate for this digest method 58 */ 59 DOMDigestMethod(AlgorithmParameterSpec params) 60 throws InvalidAlgorithmParameterException { 61 if (params != null && !(params instanceof DigestMethodParameterSpec)) { 62 throw new InvalidAlgorithmParameterException 63 ("params must be of type DigestMethodParameterSpec"); 64 } 65 checkParams((DigestMethodParameterSpec) params); 66 this.params = (DigestMethodParameterSpec) params; 67 } 68 69 /** 70 * Creates a <code>DOMDigestMethod</code> from an element. This constructor 71 * invokes the abstract {@link #unmarshalParams unmarshalParams} method to 72 * unmarshal any algorithm-specific input parameters. 73 * 74 * @param dmElem a DigestMethod element 75 */ 76 DOMDigestMethod(Element dmElem) throws MarshalException { 77 Element paramsElem = DOMUtils.getFirstChildElement(dmElem); 78 if (paramsElem != null) { 79 params = unmarshalParams(paramsElem); 80 } 81 try { 82 checkParams(params); 83 } catch (InvalidAlgorithmParameterException iape) { 84 throw new MarshalException(iape); 85 } 86 } 87 88 static DigestMethod unmarshal(Element dmElem) throws MarshalException { 89 String alg = DOMUtils.getAttributeValue(dmElem, "Algorithm"); 90 if (alg.equals(DigestMethod.SHA1)) { 91 return new SHA1(dmElem); 92 } else if (alg.equals(DigestMethod.SHA256)) { 93 return new SHA256(dmElem); 94 } else if (alg.equals(SHA384)) { 95 return new SHA384(dmElem); 96 } else if (alg.equals(DigestMethod.SHA512)) { 97 return new SHA512(dmElem); 98 } else { 99 throw new MarshalException 100 ("unsupported DigestMethod algorithm: " + alg); 101 } 102 } 103 104 /** 105 * Checks if the specified parameters are valid for this algorithm. By 106 * default, this method throws an exception if parameters are specified 107 * since most DigestMethod algorithms do not have parameters. Subclasses 108 * should override it if they have parameters. 109 * 110 * @param params the algorithm-specific params (may be <code>null</code>) 111 * @throws InvalidAlgorithmParameterException if the parameters are not 112 * appropriate for this digest method 113 */ 114 void checkParams(DigestMethodParameterSpec params) 115 throws InvalidAlgorithmParameterException { 116 if (params != null) { 117 throw new InvalidAlgorithmParameterException("no parameters " + 118 "should be specified for the " + getMessageDigestAlgorithm() 119 + " DigestMethod algorithm"); 120 } 121 } 122 123 public final AlgorithmParameterSpec getParameterSpec() { 124 return params; 125 } 126 127 /** 128 * Unmarshals <code>DigestMethodParameterSpec</code> from the specified 129 * <code>Element</code>. By default, this method throws an exception since 130 * most DigestMethod algorithms do not have parameters. Subclasses should 131 * override it if they have parameters. 132 * 133 * @param paramsElem the <code>Element</code> holding the input params 134 * @return the algorithm-specific <code>DigestMethodParameterSpec</code> 135 * @throws MarshalException if the parameters cannot be unmarshalled 136 */ 137 DigestMethodParameterSpec 138 unmarshalParams(Element paramsElem) throws MarshalException { 139 throw new MarshalException("no parameters should " + 140 "be specified for the " + getMessageDigestAlgorithm() + 141 " DigestMethod algorithm"); 142 } 143 144 /** 145 * This method invokes the abstract {@link #marshalParams marshalParams} 146 * method to marshal any algorithm-specific parameters. 147 */ 148 public void marshal(Node parent, String prefix, DOMCryptoContext context) 149 throws MarshalException { 150 Document ownerDoc = DOMUtils.getOwnerDocument(parent); 151 152 Element dmElem = DOMUtils.createElement 153 (ownerDoc, "DigestMethod", XMLSignature.XMLNS, prefix); 154 DOMUtils.setAttribute(dmElem, "Algorithm", getAlgorithm()); 155 156 if (params != null) { 157 marshalParams(dmElem, prefix); 158 } 159 160 parent.appendChild(dmElem); 161 } 162 163 public boolean equals(Object o) { 164 if (this == o) { 165 return true; 166 } 167 168 if (!(o instanceof DigestMethod)) { 169 return false; 170 } 171 DigestMethod odm = (DigestMethod) o; 172 173 boolean paramsEqual = (params == null ? odm.getParameterSpec() == null : 174 params.equals(odm.getParameterSpec())); 175 176 return (getAlgorithm().equals(odm.getAlgorithm()) && paramsEqual); 177 } 178 179 /** 180 * Marshals the algorithm-specific parameters to an Element and 181 * appends it to the specified parent element. By default, this method 182 * throws an exception since most DigestMethod algorithms do not have 183 * parameters. Subclasses should override it if they have parameters. 184 * 185 * @param parent the parent element to append the parameters to 186 * @param the namespace prefix to use 187 * @throws MarshalException if the parameters cannot be marshalled 188 */ 189 void marshalParams(Element parent, String prefix) 190 throws MarshalException { 191 throw new MarshalException("no parameters should " + 192 "be specified for the " + getMessageDigestAlgorithm() + 193 " DigestMethod algorithm"); 194 } 195 196 /** 197 * Returns the MessageDigest standard algorithm name. 198 */ 199 abstract String getMessageDigestAlgorithm(); 200 201 static final class SHA1 extends DOMDigestMethod { 202 SHA1(AlgorithmParameterSpec params) 203 throws InvalidAlgorithmParameterException { 204 super(params); 205 } 206 SHA1(Element dmElem) throws MarshalException { 207 super(dmElem); 208 } 209 public String getAlgorithm() { 210 return DigestMethod.SHA1; 211 } 212 String getMessageDigestAlgorithm() { 213 return "SHA-1"; 214 } 215 } 216 217 static final class SHA256 extends DOMDigestMethod { 218 SHA256(AlgorithmParameterSpec params) 219 throws InvalidAlgorithmParameterException { 220 super(params); 221 } 222 SHA256(Element dmElem) throws MarshalException { 223 super(dmElem); 224 } 225 public String getAlgorithm() { 226 return DigestMethod.SHA256; 227 } 228 String getMessageDigestAlgorithm() { 229 return "SHA-256"; 230 } 231 } 232 233 static final class SHA384 extends DOMDigestMethod { 234 SHA384(AlgorithmParameterSpec params) 235 throws InvalidAlgorithmParameterException { 236 super(params); 237 } 238 SHA384(Element dmElem) throws MarshalException { 239 super(dmElem); 240 } 241 public String getAlgorithm() { 242 return SHA384; 243 } 244 String getMessageDigestAlgorithm() { 245 return "SHA-384"; 246 } 247 } 248 249 static final class SHA512 extends DOMDigestMethod { 250 SHA512(AlgorithmParameterSpec params) 251 throws InvalidAlgorithmParameterException { 252 super(params); 253 } 254 SHA512(Element dmElem) throws MarshalException { 255 super(dmElem); 256 } 257 public String getAlgorithm() { 258 return DigestMethod.SHA512; 259 } 260 String getMessageDigestAlgorithm() { 261 return "SHA-512"; 262 } 263 } 264 }