/*
* eID Applet Project.
* Copyright (C) 2009-2010 FedICT.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License version
* 3.0 as published by the Free Software Foundation.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, see
* http://www.gnu.org/licenses/.
*/
package be.fedict.eid.applet.service.signer;
import java.security.InvalidKeyException;
import java.security.InvalidParameterException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.bouncycastle.util.Arrays;
/**
* A signature proxy implementation for SHA1withRSA signatures.
*
* @author Frank Cornelis
*
*/
public class SHA1WithRSAProxySignature extends Signature {
private static final Log LOG = LogFactory.getLog(SHA1WithRSAProxySignature.class);
private static final ThreadLocal<byte[]> digestValues = new ThreadLocal<byte[]>();
private static final ThreadLocal<byte[]> signatureValues = new ThreadLocal<byte[]>();
private final MessageDigest messageDigest;
public SHA1WithRSAProxySignature() throws NoSuchAlgorithmException {
super("SHA1withRSA");
LOG.debug("constructor");
this.messageDigest = MessageDigest.getInstance("SHA1");
}
public static void reset() {
SHA1WithRSAProxySignature.digestValues.set(null);
SHA1WithRSAProxySignature.signatureValues.set(null);
}
@Override
protected Object engineGetParameter(String param) throws InvalidParameterException {
throw new UnsupportedOperationException();
}
@Override
protected void engineInitSign(PrivateKey privateKey) throws InvalidKeyException {
LOG.debug("engineInitSign: " + privateKey.getAlgorithm());
}
@Override
protected void engineInitVerify(PublicKey publicKey) throws InvalidKeyException {
throw new UnsupportedOperationException();
}
@Override
protected void engineSetParameter(String param, Object value) throws InvalidParameterException {
throw new UnsupportedOperationException();
}
@Override
protected byte[] engineSign() throws SignatureException {
LOG.debug("engineSign");
byte[] signatureValue = SHA1WithRSAProxySignature.signatureValues.get();
if (null != signatureValue) {
LOG.debug("injecting signature value: " + Hex.encodeHexString(signatureValue));
reset();
return signatureValue;
}
LOG.debug("returning a dummy signature value");
return "dummy".getBytes();
}
@Override
protected void engineUpdate(byte b) throws SignatureException {
throw new UnsupportedOperationException();
}
@Override
protected void engineUpdate(byte[] b, int off, int len) throws SignatureException {
LOG.debug("engineUpdate(b,off,len): off=" + off + "; len=" + len);
this.messageDigest.update(b, off, len);
byte[] digestValue = this.messageDigest.digest();
byte[] expectedDigestValue = SHA1WithRSAProxySignature.digestValues.get();
if (null == expectedDigestValue) {
SHA1WithRSAProxySignature.digestValues.set(digestValue);
} else {
if (false == Arrays.areEqual(expectedDigestValue, digestValue)) {
throw new IllegalStateException("digest value has changed");
}
}
LOG.debug("digest value: " + Hex.encodeHexString(digestValue));
}
@Override
protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
throw new UnsupportedOperationException();
}
public static byte[] getDigestValue() {
return SHA1WithRSAProxySignature.digestValues.get();
}
public static void setSignatureValue(byte[] signatureValue) {
SHA1WithRSAProxySignature.signatureValues.set(signatureValue);
}
public static void setDigestSignatureValue(byte[] digestValue, byte[] signatureValue) {
SHA1WithRSAProxySignature.digestValues.set(digestValue);
SHA1WithRSAProxySignature.signatureValues.set(signatureValue);
}
}