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 */ 23 package com.sun.org.apache.xml.internal.security.algorithms.implementations; 24 25 import java.security.InvalidAlgorithmParameterException; 26 import java.security.InvalidKeyException; 27 import java.security.Key; 28 import java.security.SecureRandom; 29 import java.security.spec.AlgorithmParameterSpec; 30 31 import javax.crypto.Mac; 32 import javax.crypto.SecretKey; 33 34 import com.sun.org.apache.xml.internal.security.algorithms.JCEMapper; 35 import com.sun.org.apache.xml.internal.security.algorithms.MessageDigestAlgorithm; 36 import com.sun.org.apache.xml.internal.security.algorithms.SignatureAlgorithmSpi; 37 import com.sun.org.apache.xml.internal.security.signature.XMLSignature; 38 import com.sun.org.apache.xml.internal.security.signature.XMLSignatureException; 39 import com.sun.org.apache.xml.internal.security.utils.Constants; 40 import com.sun.org.apache.xml.internal.security.utils.XMLUtils; 41 import org.w3c.dom.Document; 42 import org.w3c.dom.Element; 43 import org.w3c.dom.Text; 44 45 public abstract class IntegrityHmac extends SignatureAlgorithmSpi { 46 47 /** {@link org.apache.commons.logging} logging facility */ 48 private static java.util.logging.Logger log = 49 java.util.logging.Logger.getLogger(IntegrityHmac.class.getName()); 50 51 /** Field macAlgorithm */ 52 private Mac macAlgorithm = null; 53 54 /** Field HMACOutputLength */ 55 private int HMACOutputLength = 0; 56 private boolean HMACOutputLengthSet = false; 57 58 /** 59 * Method engineGetURI 60 * 61 *@inheritDoc 62 */ 63 public abstract String engineGetURI(); 64 65 /** 66 * Returns the output length of the hash/digest. 67 */ 68 abstract int getDigestLength(); 69 70 /** 71 * Method IntegrityHmac 72 * 73 * @throws XMLSignatureException 74 */ 75 public IntegrityHmac() throws XMLSignatureException { 76 String algorithmID = JCEMapper.translateURItoJCEID(this.engineGetURI()); 77 if (log.isLoggable(java.util.logging.Level.FINE)) { 78 log.log(java.util.logging.Level.FINE, "Created IntegrityHmacSHA1 using " + algorithmID); 79 } 80 81 try { 82 this.macAlgorithm = Mac.getInstance(algorithmID); 83 } catch (java.security.NoSuchAlgorithmException ex) { 84 Object[] exArgs = { algorithmID, ex.getLocalizedMessage() }; 85 86 throw new XMLSignatureException("algorithms.NoSuchAlgorithm", exArgs); 87 } 88 } 89 90 /** 91 * Proxy method for {@link java.security.Signature#setParameter( 92 * java.security.spec.AlgorithmParameterSpec)} 93 * which is executed on the internal {@link java.security.Signature} object. 94 * 95 * @param params 96 * @throws XMLSignatureException 97 */ 98 protected void engineSetParameter(AlgorithmParameterSpec params) throws XMLSignatureException { 99 throw new XMLSignatureException("empty"); 100 } 101 102 public void reset() { 103 HMACOutputLength = 0; 104 HMACOutputLengthSet = false; 105 this.macAlgorithm.reset(); 106 } 107 108 /** 109 * Proxy method for {@link java.security.Signature#verify(byte[])} 110 * which is executed on the internal {@link java.security.Signature} object. 111 * 112 * @param signature 113 * @return true if the signature is correct 114 * @throws XMLSignatureException 115 */ 116 protected boolean engineVerify(byte[] signature) throws XMLSignatureException { 117 try { 118 if (this.HMACOutputLengthSet && this.HMACOutputLength < getDigestLength()) { 119 if (log.isLoggable(java.util.logging.Level.FINE)) { 120 log.log(java.util.logging.Level.FINE, "HMACOutputLength must not be less than " + getDigestLength()); 121 } 122 Object[] exArgs = { String.valueOf(getDigestLength()) }; 123 throw new XMLSignatureException("algorithms.HMACOutputLengthMin", exArgs); 124 } else { 125 byte[] completeResult = this.macAlgorithm.doFinal(); 126 return MessageDigestAlgorithm.isEqual(completeResult, signature); 127 } 128 } catch (IllegalStateException ex) { 129 throw new XMLSignatureException("empty", ex); 130 } 131 } 132 133 /** 134 * Proxy method for {@link java.security.Signature#initVerify(java.security.PublicKey)} 135 * which is executed on the internal {@link java.security.Signature} object. 136 * 137 * @param secretKey 138 * @throws XMLSignatureException 139 */ 140 protected void engineInitVerify(Key secretKey) throws XMLSignatureException { 141 if (!(secretKey instanceof SecretKey)) { 142 String supplied = secretKey.getClass().getName(); 143 String needed = SecretKey.class.getName(); 144 Object exArgs[] = { supplied, needed }; 145 146 throw new XMLSignatureException("algorithms.WrongKeyForThisOperation", exArgs); 147 } 148 149 try { 150 this.macAlgorithm.init(secretKey); 151 } catch (InvalidKeyException ex) { 152 // reinstantiate Mac object to work around bug in JDK 153 // see: http://bugs.sun.com/view_bug.do?bug_id=4953555 154 Mac mac = this.macAlgorithm; 155 try { 156 this.macAlgorithm = Mac.getInstance(macAlgorithm.getAlgorithm()); 157 } catch (Exception e) { 158 // this shouldn't occur, but if it does, restore previous Mac 159 if (log.isLoggable(java.util.logging.Level.FINE)) { 160 log.log(java.util.logging.Level.FINE, "Exception when reinstantiating Mac:" + e); 161 } 162 this.macAlgorithm = mac; 163 } 164 throw new XMLSignatureException("empty", ex); 165 } 166 } 167 168 /** 169 * Proxy method for {@link java.security.Signature#sign()} 170 * which is executed on the internal {@link java.security.Signature} object. 171 * 172 * @return the result of the {@link java.security.Signature#sign()} method 173 * @throws XMLSignatureException 174 */ 175 protected byte[] engineSign() throws XMLSignatureException { 176 try { 177 if (this.HMACOutputLengthSet && this.HMACOutputLength < getDigestLength()) { 178 if (log.isLoggable(java.util.logging.Level.FINE)) { 179 log.log(java.util.logging.Level.FINE, "HMACOutputLength must not be less than " + getDigestLength()); 180 } 181 Object[] exArgs = { String.valueOf(getDigestLength()) }; 182 throw new XMLSignatureException("algorithms.HMACOutputLengthMin", exArgs); 183 } else { 184 return this.macAlgorithm.doFinal(); 185 } 186 } catch (IllegalStateException ex) { 187 throw new XMLSignatureException("empty", ex); 188 } 189 } 190 191 /** 192 * Method engineInitSign 193 * 194 * @param secretKey 195 * @throws XMLSignatureException 196 */ 197 protected void engineInitSign(Key secretKey) throws XMLSignatureException { 198 if (!(secretKey instanceof SecretKey)) { 199 String supplied = secretKey.getClass().getName(); 200 String needed = SecretKey.class.getName(); 201 Object exArgs[] = { supplied, needed }; 202 203 throw new XMLSignatureException("algorithms.WrongKeyForThisOperation", exArgs); 204 } 205 206 try { 207 this.macAlgorithm.init(secretKey); 208 } catch (InvalidKeyException ex) { 209 throw new XMLSignatureException("empty", ex); 210 } 211 } 212 213 /** 214 * Method engineInitSign 215 * 216 * @param secretKey 217 * @param algorithmParameterSpec 218 * @throws XMLSignatureException 219 */ 220 protected void engineInitSign( 221 Key secretKey, AlgorithmParameterSpec algorithmParameterSpec 222 ) throws XMLSignatureException { 223 if (!(secretKey instanceof SecretKey)) { 224 String supplied = secretKey.getClass().getName(); 225 String needed = SecretKey.class.getName(); 226 Object exArgs[] = { supplied, needed }; 227 228 throw new XMLSignatureException("algorithms.WrongKeyForThisOperation", exArgs); 229 } 230 231 try { 232 this.macAlgorithm.init(secretKey, algorithmParameterSpec); 233 } catch (InvalidKeyException ex) { 234 throw new XMLSignatureException("empty", ex); 235 } catch (InvalidAlgorithmParameterException ex) { 236 throw new XMLSignatureException("empty", ex); 237 } 238 } 239 240 /** 241 * Method engineInitSign 242 * 243 * @param secretKey 244 * @param secureRandom 245 * @throws XMLSignatureException 246 */ 247 protected void engineInitSign(Key secretKey, SecureRandom secureRandom) 248 throws XMLSignatureException { 249 throw new XMLSignatureException("algorithms.CannotUseSecureRandomOnMAC"); 250 } 251 252 /** 253 * Proxy method for {@link java.security.Signature#update(byte[])} 254 * which is executed on the internal {@link java.security.Signature} object. 255 * 256 * @param input 257 * @throws XMLSignatureException 258 */ 259 protected void engineUpdate(byte[] input) throws XMLSignatureException { 260 try { 261 this.macAlgorithm.update(input); 262 } catch (IllegalStateException ex) { 263 throw new XMLSignatureException("empty", ex); 264 } 265 } 266 267 /** 268 * Proxy method for {@link java.security.Signature#update(byte)} 269 * which is executed on the internal {@link java.security.Signature} object. 270 * 271 * @param input 272 * @throws XMLSignatureException 273 */ 274 protected void engineUpdate(byte input) throws XMLSignatureException { 275 try { 276 this.macAlgorithm.update(input); 277 } catch (IllegalStateException ex) { 278 throw new XMLSignatureException("empty", ex); 279 } 280 } 281 282 /** 283 * Proxy method for {@link java.security.Signature#update(byte[], int, int)} 284 * which is executed on the internal {@link java.security.Signature} object. 285 * 286 * @param buf 287 * @param offset 288 * @param len 289 * @throws XMLSignatureException 290 */ 291 protected void engineUpdate(byte buf[], int offset, int len) throws XMLSignatureException { 292 try { 293 this.macAlgorithm.update(buf, offset, len); 294 } catch (IllegalStateException ex) { 295 throw new XMLSignatureException("empty", ex); 296 } 297 } 298 299 /** 300 * Method engineGetJCEAlgorithmString 301 * @inheritDoc 302 * 303 */ 304 protected String engineGetJCEAlgorithmString() { 305 return this.macAlgorithm.getAlgorithm(); 306 } 307 308 /** 309 * Method engineGetJCEAlgorithmString 310 * 311 * @inheritDoc 312 */ 313 protected String engineGetJCEProviderName() { 314 return this.macAlgorithm.getProvider().getName(); 315 } 316 317 /** 318 * Method engineSetHMACOutputLength 319 * 320 * @param HMACOutputLength 321 */ 322 protected void engineSetHMACOutputLength(int HMACOutputLength) { 323 this.HMACOutputLength = HMACOutputLength; 324 this.HMACOutputLengthSet = true; 325 } 326 327 /** 328 * Method engineGetContextFromElement 329 * 330 * @param element 331 */ 332 protected void engineGetContextFromElement(Element element) { 333 super.engineGetContextFromElement(element); 334 335 if (element == null) { 336 throw new IllegalArgumentException("element null"); 337 } 338 339 Text hmaclength = 340 XMLUtils.selectDsNodeText(element.getFirstChild(), Constants._TAG_HMACOUTPUTLENGTH, 0); 341 342 if (hmaclength != null) { 343 this.HMACOutputLength = Integer.parseInt(hmaclength.getData()); 344 this.HMACOutputLengthSet = true; 345 } 346 } 347 348 /** 349 * Method engineAddContextToElement 350 * 351 * @param element 352 */ 353 public void engineAddContextToElement(Element element) { 354 if (element == null) { 355 throw new IllegalArgumentException("null element"); 356 } 357 358 if (this.HMACOutputLengthSet) { 359 Document doc = element.getOwnerDocument(); 360 Element HMElem = 361 XMLUtils.createElementInSignatureSpace(doc, Constants._TAG_HMACOUTPUTLENGTH); 362 Text HMText = 363 doc.createTextNode(Integer.valueOf(this.HMACOutputLength).toString()); 364 365 HMElem.appendChild(HMText); 366 XMLUtils.addReturnToElement(element); 367 element.appendChild(HMElem); 368 XMLUtils.addReturnToElement(element); 369 } 370 } 371 372 /** 373 * Class IntegrityHmacSHA1 374 */ 375 public static class IntegrityHmacSHA1 extends IntegrityHmac { 376 377 /** 378 * Constructor IntegrityHmacSHA1 379 * 380 * @throws XMLSignatureException 381 */ 382 public IntegrityHmacSHA1() throws XMLSignatureException { 383 super(); 384 } 385 386 /** 387 * Method engineGetURI 388 * @inheritDoc 389 * 390 */ 391 public String engineGetURI() { 392 return XMLSignature.ALGO_ID_MAC_HMAC_SHA1; 393 } 394 395 int getDigestLength() { 396 return 160; 397 } 398 } 399 400 /** 401 * Class IntegrityHmacSHA256 402 */ 403 public static class IntegrityHmacSHA256 extends IntegrityHmac { 404 405 /** 406 * Constructor IntegrityHmacSHA256 407 * 408 * @throws XMLSignatureException 409 */ 410 public IntegrityHmacSHA256() throws XMLSignatureException { 411 super(); 412 } 413 414 /** 415 * Method engineGetURI 416 * 417 * @inheritDoc 418 */ 419 public String engineGetURI() { 420 return XMLSignature.ALGO_ID_MAC_HMAC_SHA256; 421 } 422 423 int getDigestLength() { 424 return 256; 425 } 426 } 427 428 /** 429 * Class IntegrityHmacSHA384 430 */ 431 public static class IntegrityHmacSHA384 extends IntegrityHmac { 432 433 /** 434 * Constructor IntegrityHmacSHA384 435 * 436 * @throws XMLSignatureException 437 */ 438 public IntegrityHmacSHA384() throws XMLSignatureException { 439 super(); 440 } 441 442 /** 443 * Method engineGetURI 444 * @inheritDoc 445 * 446 */ 447 public String engineGetURI() { 448 return XMLSignature.ALGO_ID_MAC_HMAC_SHA384; 449 } 450 451 int getDigestLength() { 452 return 384; 453 } 454 } 455 456 /** 457 * Class IntegrityHmacSHA512 458 */ 459 public static class IntegrityHmacSHA512 extends IntegrityHmac { 460 461 /** 462 * Constructor IntegrityHmacSHA512 463 * 464 * @throws XMLSignatureException 465 */ 466 public IntegrityHmacSHA512() throws XMLSignatureException { 467 super(); 468 } 469 470 /** 471 * Method engineGetURI 472 * @inheritDoc 473 * 474 */ 475 public String engineGetURI() { 476 return XMLSignature.ALGO_ID_MAC_HMAC_SHA512; 477 } 478 479 int getDigestLength() { 480 return 512; 481 } 482 } 483 484 /** 485 * Class IntegrityHmacRIPEMD160 486 */ 487 public static class IntegrityHmacRIPEMD160 extends IntegrityHmac { 488 489 /** 490 * Constructor IntegrityHmacRIPEMD160 491 * 492 * @throws XMLSignatureException 493 */ 494 public IntegrityHmacRIPEMD160() throws XMLSignatureException { 495 super(); 496 } 497 498 /** 499 * Method engineGetURI 500 * 501 * @inheritDoc 502 */ 503 public String engineGetURI() { 504 return XMLSignature.ALGO_ID_MAC_HMAC_RIPEMD160; 505 } 506 507 int getDigestLength() { 508 return 160; 509 } 510 } 511 512 /** 513 * Class IntegrityHmacMD5 514 */ 515 public static class IntegrityHmacMD5 extends IntegrityHmac { 516 517 /** 518 * Constructor IntegrityHmacMD5 519 * 520 * @throws XMLSignatureException 521 */ 522 public IntegrityHmacMD5() throws XMLSignatureException { 523 super(); 524 } 525 526 /** 527 * Method engineGetURI 528 * 529 * @inheritDoc 530 */ 531 public String engineGetURI() { 532 return XMLSignature.ALGO_ID_MAC_HMAC_NOT_RECOMMENDED_MD5; 533 } 534 535 int getDigestLength() { 536 return 128; 537 } 538 } 539 }