1/* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5/** 6 * Licensed to the Apache Software Foundation (ASF) under one 7 * or more contributor license agreements. See the NOTICE file 8 * distributed with this work for additional information 9 * regarding copyright ownership. The ASF licenses this file 10 * to you under the Apache License, Version 2.0 (the 11 * "License"); you may not use this file except in compliance 12 * with the License. You may obtain a copy of the License at 13 * 14 * http://www.apache.org/licenses/LICENSE-2.0 15 * 16 * Unless required by applicable law or agreed to in writing, 17 * software distributed under the License is distributed on an 18 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 19 * KIND, either express or implied. See the License for the 20 * specific language governing permissions and limitations 21 * under the License. 22 */ 23package com.sun.org.apache.xml.internal.security.algorithms.implementations; 24 25import java.io.IOException; 26import java.security.InvalidAlgorithmParameterException; 27import java.security.InvalidKeyException; 28import java.security.Key; 29import java.security.PrivateKey; 30import java.security.PublicKey; 31import java.security.SecureRandom; 32import java.security.Signature; 33import java.security.SignatureException; 34import java.security.interfaces.DSAKey; 35import java.security.spec.AlgorithmParameterSpec; 36 37import com.sun.org.apache.xml.internal.security.algorithms.JCEMapper; 38import com.sun.org.apache.xml.internal.security.algorithms.SignatureAlgorithmSpi; 39import com.sun.org.apache.xml.internal.security.signature.XMLSignature; 40import com.sun.org.apache.xml.internal.security.signature.XMLSignatureException; 41import com.sun.org.apache.xml.internal.security.utils.Base64; 42import com.sun.org.apache.xml.internal.security.utils.JavaUtils; 43 44public class SignatureDSA extends SignatureAlgorithmSpi { 45 46 /** {@link org.apache.commons.logging} logging facility */ 47 private static java.util.logging.Logger log = 48 java.util.logging.Logger.getLogger(SignatureDSA.class.getName()); 49 50 /** Field algorithm */ 51 private java.security.Signature signatureAlgorithm = null; 52 53 /** size of Q */ 54 private int size; 55 56 /** 57 * Method engineGetURI 58 * 59 * @inheritDoc 60 */ 61 protected String engineGetURI() { 62 return XMLSignature.ALGO_ID_SIGNATURE_DSA; 63 } 64 65 /** 66 * Constructor SignatureDSA 67 * 68 * @throws XMLSignatureException 69 */ 70 public SignatureDSA() throws XMLSignatureException { 71 String algorithmID = JCEMapper.translateURItoJCEID(engineGetURI()); 72 if (log.isLoggable(java.util.logging.Level.FINE)) { 73 log.log(java.util.logging.Level.FINE, "Created SignatureDSA using " + algorithmID); 74 } 75 76 String provider = JCEMapper.getProviderId(); 77 try { 78 if (provider == null) { 79 this.signatureAlgorithm = Signature.getInstance(algorithmID); 80 } else { 81 this.signatureAlgorithm = 82 Signature.getInstance(algorithmID, provider); 83 } 84 } catch (java.security.NoSuchAlgorithmException ex) { 85 Object[] exArgs = { algorithmID, ex.getLocalizedMessage() }; 86 throw new XMLSignatureException("algorithms.NoSuchAlgorithm", exArgs); 87 } catch (java.security.NoSuchProviderException ex) { 88 Object[] exArgs = { algorithmID, ex.getLocalizedMessage() }; 89 throw new XMLSignatureException("algorithms.NoSuchAlgorithm", exArgs); 90 } 91 } 92 93 /** 94 * @inheritDoc 95 */ 96 protected void engineSetParameter(AlgorithmParameterSpec params) 97 throws XMLSignatureException { 98 try { 99 this.signatureAlgorithm.setParameter(params); 100 } catch (InvalidAlgorithmParameterException ex) { 101 throw new XMLSignatureException("empty", ex); 102 } 103 } 104 105 /** 106 * @inheritDoc 107 */ 108 protected boolean engineVerify(byte[] signature) 109 throws XMLSignatureException { 110 try { 111 if (log.isLoggable(java.util.logging.Level.FINE)) { 112 log.log(java.util.logging.Level.FINE, "Called DSA.verify() on " + Base64.encode(signature)); 113 } 114 115 byte[] jcebytes = JavaUtils.convertDsaXMLDSIGtoASN1(signature, 116 size/8); 117 118 return this.signatureAlgorithm.verify(jcebytes); 119 } catch (SignatureException ex) { 120 throw new XMLSignatureException("empty", ex); 121 } catch (IOException ex) { 122 throw new XMLSignatureException("empty", ex); 123 } 124 } 125 126 /** 127 * @inheritDoc 128 */ 129 protected void engineInitVerify(Key publicKey) throws XMLSignatureException { 130 if (!(publicKey instanceof PublicKey)) { 131 String supplied = publicKey.getClass().getName(); 132 String needed = PublicKey.class.getName(); 133 Object exArgs[] = { supplied, needed }; 134 135 throw new XMLSignatureException("algorithms.WrongKeyForThisOperation", exArgs); 136 } 137 138 try { 139 this.signatureAlgorithm.initVerify((PublicKey) publicKey); 140 } catch (InvalidKeyException ex) { 141 // reinstantiate Signature object to work around bug in JDK 142 // see: http://bugs.java.com/view_bug.do?bug_id=4953555 143 Signature sig = this.signatureAlgorithm; 144 try { 145 this.signatureAlgorithm = Signature.getInstance(signatureAlgorithm.getAlgorithm()); 146 } catch (Exception e) { 147 // this shouldn't occur, but if it does, restore previous 148 // Signature 149 if (log.isLoggable(java.util.logging.Level.FINE)) { 150 log.log(java.util.logging.Level.FINE, "Exception when reinstantiating Signature:" + e); 151 } 152 this.signatureAlgorithm = sig; 153 } 154 throw new XMLSignatureException("empty", ex); 155 } 156 size = ((DSAKey)publicKey).getParams().getQ().bitLength(); 157 } 158 159 /** 160 * @inheritDoc 161 */ 162 protected byte[] engineSign() throws XMLSignatureException { 163 try { 164 byte jcebytes[] = this.signatureAlgorithm.sign(); 165 166 return JavaUtils.convertDsaASN1toXMLDSIG(jcebytes, size/8); 167 } catch (IOException ex) { 168 throw new XMLSignatureException("empty", ex); 169 } catch (SignatureException ex) { 170 throw new XMLSignatureException("empty", ex); 171 } 172 } 173 174 /** 175 * @inheritDoc 176 */ 177 protected void engineInitSign(Key privateKey, SecureRandom secureRandom) 178 throws XMLSignatureException { 179 if (!(privateKey instanceof PrivateKey)) { 180 String supplied = privateKey.getClass().getName(); 181 String needed = PrivateKey.class.getName(); 182 Object exArgs[] = { supplied, needed }; 183 184 throw new XMLSignatureException("algorithms.WrongKeyForThisOperation", exArgs); 185 } 186 187 try { 188 this.signatureAlgorithm.initSign((PrivateKey) privateKey, secureRandom); 189 } catch (InvalidKeyException ex) { 190 throw new XMLSignatureException("empty", ex); 191 } 192 size = ((DSAKey)privateKey).getParams().getQ().bitLength(); 193 } 194 195 /** 196 * @inheritDoc 197 */ 198 protected void engineInitSign(Key privateKey) throws XMLSignatureException { 199 if (!(privateKey instanceof PrivateKey)) { 200 String supplied = privateKey.getClass().getName(); 201 String needed = PrivateKey.class.getName(); 202 Object exArgs[] = { supplied, needed }; 203 204 throw new XMLSignatureException("algorithms.WrongKeyForThisOperation", exArgs); 205 } 206 207 try { 208 this.signatureAlgorithm.initSign((PrivateKey) privateKey); 209 } catch (InvalidKeyException ex) { 210 throw new XMLSignatureException("empty", ex); 211 } 212 size = ((DSAKey)privateKey).getParams().getQ().bitLength(); 213 } 214 215 /** 216 * @inheritDoc 217 */ 218 protected void engineUpdate(byte[] input) throws XMLSignatureException { 219 try { 220 this.signatureAlgorithm.update(input); 221 } catch (SignatureException ex) { 222 throw new XMLSignatureException("empty", ex); 223 } 224 } 225 226 /** 227 * @inheritDoc 228 */ 229 protected void engineUpdate(byte input) throws XMLSignatureException { 230 try { 231 this.signatureAlgorithm.update(input); 232 } catch (SignatureException ex) { 233 throw new XMLSignatureException("empty", ex); 234 } 235 } 236 237 /** 238 * @inheritDoc 239 */ 240 protected void engineUpdate(byte buf[], int offset, int len) throws XMLSignatureException { 241 try { 242 this.signatureAlgorithm.update(buf, offset, len); 243 } catch (SignatureException ex) { 244 throw new XMLSignatureException("empty", ex); 245 } 246 } 247 248 /** 249 * Method engineGetJCEAlgorithmString 250 * 251 * @inheritDoc 252 */ 253 protected String engineGetJCEAlgorithmString() { 254 return this.signatureAlgorithm.getAlgorithm(); 255 } 256 257 /** 258 * Method engineGetJCEProviderName 259 * 260 * @inheritDoc 261 */ 262 protected String engineGetJCEProviderName() { 263 return this.signatureAlgorithm.getProvider().getName(); 264 } 265 266 /** 267 * Method engineSetHMACOutputLength 268 * 269 * @param HMACOutputLength 270 * @throws XMLSignatureException 271 */ 272 protected void engineSetHMACOutputLength(int HMACOutputLength) throws XMLSignatureException { 273 throw new XMLSignatureException("algorithms.HMACOutputLengthOnlyForHMAC"); 274 } 275 276 /** 277 * Method engineInitSign 278 * 279 * @param signingKey 280 * @param algorithmParameterSpec 281 * @throws XMLSignatureException 282 */ 283 protected void engineInitSign( 284 Key signingKey, AlgorithmParameterSpec algorithmParameterSpec 285 ) throws XMLSignatureException { 286 throw new XMLSignatureException("algorithms.CannotUseAlgorithmParameterSpecOnDSA"); 287 } 288 289 public static class SHA256 extends SignatureDSA { 290 291 public SHA256() throws XMLSignatureException { 292 super(); 293 } 294 295 public String engineGetURI() { 296 return XMLSignature.ALGO_ID_SIGNATURE_DSA_SHA256; 297 } 298 } 299} 300