| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.apache.xml.security.algorithms.implementations; |
| |
| import java.security.InvalidAlgorithmParameterException; |
| import java.security.InvalidKeyException; |
| import java.security.Key; |
| import java.security.SecureRandom; |
| import java.security.spec.AlgorithmParameterSpec; |
| |
| import javax.crypto.Mac; |
| import javax.crypto.SecretKey; |
| |
| import org.apache.xml.security.algorithms.JCEMapper; |
| import org.apache.xml.security.algorithms.MessageDigestAlgorithm; |
| import org.apache.xml.security.algorithms.SignatureAlgorithmSpi; |
| import org.apache.xml.security.signature.XMLSignature; |
| import org.apache.xml.security.signature.XMLSignatureException; |
| import org.apache.xml.security.utils.Constants; |
| import org.apache.xml.security.utils.XMLUtils; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.Element; |
| import org.w3c.dom.Node; |
| import org.w3c.dom.Text; |
| |
| public abstract class IntegrityHmac extends SignatureAlgorithmSpi { |
| |
| private static final org.slf4j.Logger LOG = |
| org.slf4j.LoggerFactory.getLogger(IntegrityHmac.class); |
| |
| /** Field macAlgorithm */ |
| private Mac macAlgorithm; |
| |
| /** Field HMACOutputLength */ |
| private int HMACOutputLength; |
| private boolean HMACOutputLengthSet = false; |
| |
| /** |
| * Method engineGetURI |
| * |
| *{@inheritDoc} |
| */ |
| public abstract String engineGetURI(); |
| |
| /** |
| * Returns the output length of the hash/digest. |
| */ |
| abstract int getDigestLength(); |
| |
| /** |
| * Method IntegrityHmac |
| * |
| * @throws XMLSignatureException |
| */ |
| public IntegrityHmac() throws XMLSignatureException { |
| String algorithmID = JCEMapper.translateURItoJCEID(this.engineGetURI()); |
| LOG.debug("Created IntegrityHmacSHA1 using {}", algorithmID); |
| |
| try { |
| this.macAlgorithm = Mac.getInstance(algorithmID); |
| } catch (java.security.NoSuchAlgorithmException ex) { |
| Object[] exArgs = { algorithmID, ex.getLocalizedMessage() }; |
| |
| throw new XMLSignatureException("algorithms.NoSuchAlgorithm", exArgs); |
| } |
| } |
| |
| /** |
| * Proxy method for {@link java.security.Signature#setParameter( |
| * java.security.spec.AlgorithmParameterSpec)} |
| * which is executed on the internal {@link java.security.Signature} object. |
| * |
| * @param params |
| * @throws XMLSignatureException |
| */ |
| protected void engineSetParameter(AlgorithmParameterSpec params) throws XMLSignatureException { |
| throw new XMLSignatureException("empty", new Object[]{"Incorrect method call"}); |
| } |
| |
| public void reset() { |
| HMACOutputLength = 0; |
| HMACOutputLengthSet = false; |
| this.macAlgorithm.reset(); |
| } |
| |
| /** |
| * Proxy method for {@link java.security.Signature#verify(byte[])} |
| * which is executed on the internal {@link java.security.Signature} object. |
| * |
| * @param signature |
| * @return true if the signature is correct |
| * @throws XMLSignatureException |
| */ |
| protected boolean engineVerify(byte[] signature) throws XMLSignatureException { |
| try { |
| if (this.HMACOutputLengthSet && this.HMACOutputLength < getDigestLength()) { |
| LOG.debug("HMACOutputLength must not be less than {}", getDigestLength()); |
| Object[] exArgs = { String.valueOf(getDigestLength()) }; |
| throw new XMLSignatureException("algorithms.HMACOutputLengthMin", exArgs); |
| } else { |
| byte[] completeResult = this.macAlgorithm.doFinal(); |
| return MessageDigestAlgorithm.isEqual(completeResult, signature); |
| } |
| } catch (IllegalStateException ex) { |
| throw new XMLSignatureException(ex); |
| } |
| } |
| |
| /** |
| * Proxy method for {@link java.security.Signature#initVerify(java.security.PublicKey)} |
| * which is executed on the internal {@link java.security.Signature} object. |
| * |
| * @param secretKey |
| * @throws XMLSignatureException |
| */ |
| protected void engineInitVerify(Key secretKey) throws XMLSignatureException { |
| if (!(secretKey instanceof SecretKey)) { |
| String supplied = null; |
| if (secretKey != null) { |
| supplied = secretKey.getClass().getName(); |
| } |
| String needed = SecretKey.class.getName(); |
| Object[] exArgs = { supplied, needed }; |
| |
| throw new XMLSignatureException("algorithms.WrongKeyForThisOperation", exArgs); |
| } |
| |
| try { |
| this.macAlgorithm.init(secretKey); |
| } catch (InvalidKeyException ex) { |
| // reinstantiate Mac object to work around bug in JDK |
| // see: http://bugs.sun.com/view_bug.do?bug_id=4953555 |
| Mac mac = this.macAlgorithm; |
| try { |
| this.macAlgorithm = Mac.getInstance(macAlgorithm.getAlgorithm()); |
| } catch (Exception e) { |
| // this shouldn't occur, but if it does, restore previous Mac |
| LOG.debug("Exception when reinstantiating Mac: {}", e); |
| this.macAlgorithm = mac; |
| } |
| throw new XMLSignatureException(ex); |
| } |
| } |
| |
| /** |
| * Proxy method for {@link java.security.Signature#sign()} |
| * which is executed on the internal {@link java.security.Signature} object. |
| * |
| * @return the result of the {@link java.security.Signature#sign()} method |
| * @throws XMLSignatureException |
| */ |
| protected byte[] engineSign() throws XMLSignatureException { |
| try { |
| if (this.HMACOutputLengthSet && this.HMACOutputLength < getDigestLength()) { |
| LOG.debug("HMACOutputLength must not be less than {}", getDigestLength()); |
| Object[] exArgs = { String.valueOf(getDigestLength()) }; |
| throw new XMLSignatureException("algorithms.HMACOutputLengthMin", exArgs); |
| } else { |
| return this.macAlgorithm.doFinal(); |
| } |
| } catch (IllegalStateException ex) { |
| throw new XMLSignatureException(ex); |
| } |
| } |
| |
| /** |
| * Method engineInitSign |
| * |
| * @param secretKey |
| * @throws XMLSignatureException |
| */ |
| protected void engineInitSign(Key secretKey) throws XMLSignatureException { |
| engineInitSign(secretKey, (AlgorithmParameterSpec)null); |
| } |
| |
| /** |
| * Method engineInitSign |
| * |
| * @param secretKey |
| * @param algorithmParameterSpec |
| * @throws XMLSignatureException |
| */ |
| protected void engineInitSign( |
| Key secretKey, AlgorithmParameterSpec algorithmParameterSpec |
| ) throws XMLSignatureException { |
| if (!(secretKey instanceof SecretKey)) { |
| String supplied = null; |
| if (secretKey != null) { |
| supplied = secretKey.getClass().getName(); |
| } |
| String needed = SecretKey.class.getName(); |
| Object[] exArgs = { supplied, needed }; |
| |
| throw new XMLSignatureException("algorithms.WrongKeyForThisOperation", exArgs); |
| } |
| |
| try { |
| if (algorithmParameterSpec == null) { |
| this.macAlgorithm.init(secretKey); |
| } else { |
| this.macAlgorithm.init(secretKey, algorithmParameterSpec); |
| } |
| } catch (InvalidKeyException ex) { |
| throw new XMLSignatureException(ex); |
| } catch (InvalidAlgorithmParameterException ex) { |
| throw new XMLSignatureException(ex); |
| } |
| } |
| |
| /** |
| * Method engineInitSign |
| * |
| * @param secretKey |
| * @param secureRandom |
| * @throws XMLSignatureException |
| */ |
| protected void engineInitSign(Key secretKey, SecureRandom secureRandom) |
| throws XMLSignatureException { |
| throw new XMLSignatureException("algorithms.CannotUseSecureRandomOnMAC"); |
| } |
| |
| /** |
| * Proxy method for {@link java.security.Signature#update(byte[])} |
| * which is executed on the internal {@link java.security.Signature} object. |
| * |
| * @param input |
| * @throws XMLSignatureException |
| */ |
| protected void engineUpdate(byte[] input) throws XMLSignatureException { |
| try { |
| this.macAlgorithm.update(input); |
| } catch (IllegalStateException ex) { |
| throw new XMLSignatureException(ex); |
| } |
| } |
| |
| /** |
| * Proxy method for {@link java.security.Signature#update(byte)} |
| * which is executed on the internal {@link java.security.Signature} object. |
| * |
| * @param input |
| * @throws XMLSignatureException |
| */ |
| protected void engineUpdate(byte input) throws XMLSignatureException { |
| try { |
| this.macAlgorithm.update(input); |
| } catch (IllegalStateException ex) { |
| throw new XMLSignatureException(ex); |
| } |
| } |
| |
| /** |
| * Proxy method for {@link java.security.Signature#update(byte[], int, int)} |
| * which is executed on the internal {@link java.security.Signature} object. |
| * |
| * @param buf |
| * @param offset |
| * @param len |
| * @throws XMLSignatureException |
| */ |
| protected void engineUpdate(byte[] buf, int offset, int len) throws XMLSignatureException { |
| try { |
| this.macAlgorithm.update(buf, offset, len); |
| } catch (IllegalStateException ex) { |
| throw new XMLSignatureException(ex); |
| } |
| } |
| |
| /** |
| * Method engineGetJCEAlgorithmString |
| * {@inheritDoc} |
| * |
| */ |
| protected String engineGetJCEAlgorithmString() { |
| return this.macAlgorithm.getAlgorithm(); |
| } |
| |
| /** |
| * Method engineGetJCEAlgorithmString |
| * |
| * {@inheritDoc} |
| */ |
| protected String engineGetJCEProviderName() { |
| return this.macAlgorithm.getProvider().getName(); |
| } |
| |
| /** |
| * Method engineSetHMACOutputLength |
| * |
| * @param HMACOutputLength |
| */ |
| protected void engineSetHMACOutputLength(int HMACOutputLength) { |
| this.HMACOutputLength = HMACOutputLength; |
| this.HMACOutputLengthSet = true; |
| } |
| |
| /** |
| * Method engineGetContextFromElement |
| * |
| * @param element |
| */ |
| protected void engineGetContextFromElement(Element element) { |
| super.engineGetContextFromElement(element); |
| |
| if (element == null) { |
| throw new IllegalArgumentException("element null"); |
| } |
| |
| Node n = XMLUtils.selectDsNode(element.getFirstChild(), Constants._TAG_HMACOUTPUTLENGTH, 0); |
| if (n != null) { |
| String hmacLength = XMLUtils.getFullTextChildrenFromNode(n); |
| if (hmacLength != null && !"".equals(hmacLength)) { |
| this.HMACOutputLength = Integer.parseInt(hmacLength); |
| this.HMACOutputLengthSet = true; |
| } |
| } |
| } |
| |
| /** |
| * Method engineAddContextToElement |
| * |
| * @param element |
| */ |
| public void engineAddContextToElement(Element element) { |
| if (element == null) { |
| throw new IllegalArgumentException("null element"); |
| } |
| |
| if (this.HMACOutputLengthSet) { |
| Document doc = element.getOwnerDocument(); |
| Element HMElem = |
| XMLUtils.createElementInSignatureSpace(doc, Constants._TAG_HMACOUTPUTLENGTH); |
| Text HMText = |
| doc.createTextNode("" + this.HMACOutputLength); |
| |
| HMElem.appendChild(HMText); |
| XMLUtils.addReturnToElement(element); |
| element.appendChild(HMElem); |
| XMLUtils.addReturnToElement(element); |
| } |
| } |
| |
| /** |
| * Class IntegrityHmacSHA1 |
| */ |
| public static class IntegrityHmacSHA1 extends IntegrityHmac { |
| |
| /** |
| * Constructor IntegrityHmacSHA1 |
| * |
| * @throws XMLSignatureException |
| */ |
| public IntegrityHmacSHA1() throws XMLSignatureException { |
| super(); |
| } |
| |
| /** |
| * Method engineGetURI |
| * {@inheritDoc} |
| * |
| */ |
| public String engineGetURI() { |
| return XMLSignature.ALGO_ID_MAC_HMAC_SHA1; |
| } |
| |
| int getDigestLength() { |
| return 160; |
| } |
| } |
| |
| /** |
| * Class IntegrityHmacSHA224 |
| */ |
| public static class IntegrityHmacSHA224 extends IntegrityHmac { |
| |
| /** |
| * Constructor IntegrityHmacSHA224 |
| * |
| * @throws XMLSignatureException |
| */ |
| public IntegrityHmacSHA224() throws XMLSignatureException { |
| super(); |
| } |
| |
| /** |
| * Method engineGetURI |
| * |
| * {@inheritDoc} |
| */ |
| public String engineGetURI() { |
| return XMLSignature.ALGO_ID_MAC_HMAC_SHA224; |
| } |
| |
| int getDigestLength() { |
| return 224; |
| } |
| } |
| |
| /** |
| * Class IntegrityHmacSHA256 |
| */ |
| public static class IntegrityHmacSHA256 extends IntegrityHmac { |
| |
| /** |
| * Constructor IntegrityHmacSHA256 |
| * |
| * @throws XMLSignatureException |
| */ |
| public IntegrityHmacSHA256() throws XMLSignatureException { |
| super(); |
| } |
| |
| /** |
| * Method engineGetURI |
| * |
| * {@inheritDoc} |
| */ |
| public String engineGetURI() { |
| return XMLSignature.ALGO_ID_MAC_HMAC_SHA256; |
| } |
| |
| int getDigestLength() { |
| return 256; |
| } |
| } |
| |
| /** |
| * Class IntegrityHmacSHA384 |
| */ |
| public static class IntegrityHmacSHA384 extends IntegrityHmac { |
| |
| /** |
| * Constructor IntegrityHmacSHA384 |
| * |
| * @throws XMLSignatureException |
| */ |
| public IntegrityHmacSHA384() throws XMLSignatureException { |
| super(); |
| } |
| |
| /** |
| * Method engineGetURI |
| * {@inheritDoc} |
| * |
| */ |
| public String engineGetURI() { |
| return XMLSignature.ALGO_ID_MAC_HMAC_SHA384; |
| } |
| |
| int getDigestLength() { |
| return 384; |
| } |
| } |
| |
| /** |
| * Class IntegrityHmacSHA512 |
| */ |
| public static class IntegrityHmacSHA512 extends IntegrityHmac { |
| |
| /** |
| * Constructor IntegrityHmacSHA512 |
| * |
| * @throws XMLSignatureException |
| */ |
| public IntegrityHmacSHA512() throws XMLSignatureException { |
| super(); |
| } |
| |
| /** |
| * Method engineGetURI |
| * {@inheritDoc} |
| * |
| */ |
| public String engineGetURI() { |
| return XMLSignature.ALGO_ID_MAC_HMAC_SHA512; |
| } |
| |
| int getDigestLength() { |
| return 512; |
| } |
| } |
| |
| /** |
| * Class IntegrityHmacRIPEMD160 |
| */ |
| public static class IntegrityHmacRIPEMD160 extends IntegrityHmac { |
| |
| /** |
| * Constructor IntegrityHmacRIPEMD160 |
| * |
| * @throws XMLSignatureException |
| */ |
| public IntegrityHmacRIPEMD160() throws XMLSignatureException { |
| super(); |
| } |
| |
| /** |
| * Method engineGetURI |
| * |
| * {@inheritDoc} |
| */ |
| public String engineGetURI() { |
| return XMLSignature.ALGO_ID_MAC_HMAC_RIPEMD160; |
| } |
| |
| int getDigestLength() { |
| return 160; |
| } |
| } |
| |
| /** |
| * Class IntegrityHmacMD5 |
| */ |
| public static class IntegrityHmacMD5 extends IntegrityHmac { |
| |
| /** |
| * Constructor IntegrityHmacMD5 |
| * |
| * @throws XMLSignatureException |
| */ |
| public IntegrityHmacMD5() throws XMLSignatureException { |
| super(); |
| } |
| |
| /** |
| * Method engineGetURI |
| * |
| * {@inheritDoc} |
| */ |
| public String engineGetURI() { |
| return XMLSignature.ALGO_ID_MAC_HMAC_NOT_RECOMMENDED_MD5; |
| } |
| |
| int getDigestLength() { |
| return 128; |
| } |
| } |
| } |