1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
/* * Copyright 2006 Sun Microsystems, Inc. All rights reserved. */ /* * $Id: DOMSignatureMethod.java,v 1.20.4.1 2005/08/12 14:23:49 mullan Exp $ */ package org.jcp.xml.dsig.internal.dom; import javax.xml.crypto.*; import javax.xml.crypto.dom.DOMCryptoContext; import javax.xml.crypto.dsig.*; import javax.xml.crypto.dsig.spec.SignatureMethodParameterSpec; import java.security.*; import java.security.spec.AlgorithmParameterSpec; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; /** * DOM-based abstract implementation of SignatureMethod. * * @author Sean Mullan */ public abstract class DOMSignatureMethod extends DOMStructure implements SignatureMethod { private String algorithm; private SignatureMethodParameterSpec params; /** * Creates a <code>DOMSignatureMethod</code>. * * @param algorithm the URI identifying the signature algorithm * @param params the algorithm-specific params (may be <code>null</code>) * @throws NullPointerException if <code>algorithm</code> is * <code>null</code> * @throws InvalidAlgorithmParameterException if the parameters are not * appropriate for this signature method */ protected DOMSignatureMethod(String algorithm, AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException { if (algorithm == null) { throw new NullPointerException("algorithm cannot be null"); } if (params != null && !(params instanceof SignatureMethodParameterSpec)) { throw new InvalidAlgorithmParameterException ("params must be of type SignatureMethodParameterSpec"); } checkParams((SignatureMethodParameterSpec) params); this.algorithm = algorithm; this.params = (SignatureMethodParameterSpec) params; } /** * Creates a <code>DOMSignatureMethod</code> from an element. This ctor * invokes the abstract {@link #unmarshalParams unmarshalParams} method to * unmarshal any algorithm-specific input parameters. * * @param smElem a SignatureMethod element */ protected DOMSignatureMethod(Element smElem) throws MarshalException { algorithm = DOMUtils.getAttributeValue(smElem, "Algorithm"); Element paramsElem = DOMUtils.getFirstChildElement(smElem); if (paramsElem != null) { params = unmarshalParams(paramsElem); } try { checkParams(params); } catch (InvalidAlgorithmParameterException iape) { throw new MarshalException(iape); } } static SignatureMethod unmarshal(Element smElem) throws MarshalException { String alg = DOMUtils.getAttributeValue(smElem, "Algorithm"); if (alg.equals(SignatureMethod.HMAC_SHA1)) { return new DOMHMACSignatureMethod(smElem); } else if (alg.equals(SignatureMethod.RSA_SHA1)) { return new DOMRSASignatureMethod(smElem); } else if (alg.equals(SignatureMethod.DSA_SHA1)) { return new DOMDSASignatureMethod(smElem); } else { throw new MarshalException("unsupported signature algorithm: " + alg); } } /** * Checks if the specified parameters are valid for this algorithm. * * @param params the algorithm-specific params (may be <code>null</code>) * @throws InvalidAlgorithmParameterException if the parameters are not * appropriate for this signature method */ protected abstract void checkParams(SignatureMethodParameterSpec params) throws InvalidAlgorithmParameterException; public final AlgorithmParameterSpec getParameterSpec() { return params; } public final String getAlgorithm() { return algorithm; } /** * Unmarshals <code>SignatureMethodParameterSpec</code> from the specified * <code>Element</code>. Subclasses should implement this to unmarshal * the algorithm-specific parameters. * * @param paramsElem the <code>Element</code> holding the input params * @return the algorithm-specific <code>SignatureMethodParameterSpec</code> * @throws MarshalException if the parameters cannot be unmarshalled */ protected abstract SignatureMethodParameterSpec unmarshalParams(Element paramsElem) throws MarshalException; /** * This method invokes the abstract {@link #marshalParams marshalParams} * method to marshal any algorithm-specific parameters. */ public void marshal(Node parent, String dsPrefix, DOMCryptoContext context) throws MarshalException { Document ownerDoc = DOMUtils.getOwnerDocument(parent); Element smElem = DOMUtils.createElement (ownerDoc, "SignatureMethod", XMLSignature.XMLNS, dsPrefix); DOMUtils.setAttribute(smElem, "Algorithm", algorithm); if (params != null) { marshalParams(smElem, dsPrefix); } parent.appendChild(smElem); } /** * Verifies the passed-in signature with the specified key, using the * underlying signature or MAC algorithm. * * @param key the verification key * @param si the DOMSignedInfo * @param signature the signature bytes to be verified * @param context the XMLValidateContext * @return <code>true</code> if the signature verified successfully, * <code>false</code> if not * @throws NullPointerException if <code>key</code>, <code>si</code> or * <code>signature</code> are <code>null</code> * @throws InvalidKeyException if the key is improperly encoded, of * the wrong type, or parameters are missing, etc * @throws SignatureException if an unexpected error occurs, such * as the passed in signature is improperly encoded * @throws XMLSignatureException if an unexpected error occurs */ public abstract boolean verify(Key key, DOMSignedInfo si, byte[] signature, XMLValidateContext context) throws InvalidKeyException, SignatureException, XMLSignatureException; /** * Signs the bytes with the specified key, using the underlying * signature or MAC algorithm. * * @param key the signing key * @param si the DOMSignedInfo * @param context the XMLSignContext * @return the signature * @throws NullPointerException if <code>key</code> or * <code>si</code> are <code>null</code> * @throws InvalidKeyException if the key is improperly encoded, of * the wrong type, or parameters are missing, etc * @throws XMLSignatureException if an unexpected error occurs */ public abstract byte[] sign(Key key, DOMSignedInfo si, XMLSignContext context) throws InvalidKeyException, XMLSignatureException; /** * Marshals the algorithm-specific parameters to an Element and * appends it to the specified parent element. * * @param parent the parent element to append the parameters to * @param paramsPrefix the algorithm parameters prefix to use * @throws MarshalException if the parameters cannot be marshalled */ protected abstract void marshalParams(Element parent, String paramsPrefix) throws MarshalException; /** * Returns true if parameters are equal; false otherwise. * * Subclasses should override this method to compare algorithm-specific * parameters. */ protected abstract boolean paramsEqual(AlgorithmParameterSpec spec); public boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof SignatureMethod)) { return false; } SignatureMethod osm = (SignatureMethod) o; return (algorithm.equals(osm.getAlgorithm()) && paramsEqual(osm.getParameterSpec())); } }