diff options
Diffstat (limited to 'bcprov/src/main/java/org/bouncycastle/crypto/signers')
13 files changed, 9 insertions, 3021 deletions
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/signers/DSADigestSigner.java b/bcprov/src/main/java/org/bouncycastle/crypto/signers/DSADigestSigner.java deleted file mode 100644 index 684eb9c..0000000 --- a/bcprov/src/main/java/org/bouncycastle/crypto/signers/DSADigestSigner.java +++ /dev/null @@ -1,163 +0,0 @@ -package org.bouncycastle.crypto.signers; - -import java.io.IOException; -import java.math.BigInteger; - -import org.bouncycastle.asn1.ASN1EncodableVector; -import org.bouncycastle.asn1.ASN1Encoding; -import org.bouncycastle.asn1.ASN1Integer; -import org.bouncycastle.asn1.ASN1Primitive; -import org.bouncycastle.asn1.ASN1Sequence; -import org.bouncycastle.asn1.DERSequence; -import org.bouncycastle.crypto.CipherParameters; -import org.bouncycastle.crypto.DSA; -import org.bouncycastle.crypto.Digest; -import org.bouncycastle.crypto.Signer; -import org.bouncycastle.crypto.params.AsymmetricKeyParameter; -import org.bouncycastle.crypto.params.ParametersWithRandom; - -public class DSADigestSigner - implements Signer -{ - private final Digest digest; - private final DSA dsaSigner; - private boolean forSigning; - - public DSADigestSigner( - DSA signer, - Digest digest) - { - this.digest = digest; - this.dsaSigner = signer; - } - - public void init( - boolean forSigning, - CipherParameters parameters) - { - this.forSigning = forSigning; - - AsymmetricKeyParameter k; - - if (parameters instanceof ParametersWithRandom) - { - k = (AsymmetricKeyParameter)((ParametersWithRandom)parameters).getParameters(); - } - else - { - k = (AsymmetricKeyParameter)parameters; - } - - if (forSigning && !k.isPrivate()) - { - throw new IllegalArgumentException("Signing Requires Private Key."); - } - - if (!forSigning && k.isPrivate()) - { - throw new IllegalArgumentException("Verification Requires Public Key."); - } - - reset(); - - dsaSigner.init(forSigning, parameters); - } - - /** - * update the internal digest with the byte b - */ - public void update( - byte input) - { - digest.update(input); - } - - /** - * update the internal digest with the byte array in - */ - public void update( - byte[] input, - int inOff, - int length) - { - digest.update(input, inOff, length); - } - - /** - * Generate a signature for the message we've been loaded with using - * the key we were initialised with. - */ - public byte[] generateSignature() - { - if (!forSigning) - { - throw new IllegalStateException("DSADigestSigner not initialised for signature generation."); - } - - byte[] hash = new byte[digest.getDigestSize()]; - digest.doFinal(hash, 0); - - BigInteger[] sig = dsaSigner.generateSignature(hash); - - try - { - return derEncode(sig[0], sig[1]); - } - catch (IOException e) - { - throw new IllegalStateException("unable to encode signature"); - } - } - - public boolean verifySignature( - byte[] signature) - { - if (forSigning) - { - throw new IllegalStateException("DSADigestSigner not initialised for verification"); - } - - byte[] hash = new byte[digest.getDigestSize()]; - digest.doFinal(hash, 0); - - try - { - BigInteger[] sig = derDecode(signature); - return dsaSigner.verifySignature(hash, sig[0], sig[1]); - } - catch (IOException e) - { - return false; - } - } - - public void reset() - { - digest.reset(); - } - - private byte[] derEncode( - BigInteger r, - BigInteger s) - throws IOException - { - ASN1EncodableVector v = new ASN1EncodableVector(); - v.add(new ASN1Integer(r)); - v.add(new ASN1Integer(s)); - - return new DERSequence(v).getEncoded(ASN1Encoding.DER); - } - - private BigInteger[] derDecode( - byte[] encoding) - throws IOException - { - ASN1Sequence s = (ASN1Sequence)ASN1Primitive.fromByteArray(encoding); - - return new BigInteger[] - { - ((ASN1Integer)s.getObjectAt(0)).getValue(), - ((ASN1Integer)s.getObjectAt(1)).getValue() - }; - } -} diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/signers/DSTU4145Signer.java b/bcprov/src/main/java/org/bouncycastle/crypto/signers/DSTU4145Signer.java deleted file mode 100644 index bceb822..0000000 --- a/bcprov/src/main/java/org/bouncycastle/crypto/signers/DSTU4145Signer.java +++ /dev/null @@ -1,170 +0,0 @@ -package org.bouncycastle.crypto.signers; - -import java.math.BigInteger; -import java.security.SecureRandom; - -import org.bouncycastle.crypto.CipherParameters; -import org.bouncycastle.crypto.DSA; -import org.bouncycastle.crypto.params.ECDomainParameters; -import org.bouncycastle.crypto.params.ECKeyParameters; -import org.bouncycastle.crypto.params.ECPrivateKeyParameters; -import org.bouncycastle.crypto.params.ECPublicKeyParameters; -import org.bouncycastle.crypto.params.ParametersWithRandom; -import org.bouncycastle.math.ec.ECAlgorithms; -import org.bouncycastle.math.ec.ECCurve; -import org.bouncycastle.math.ec.ECFieldElement; -import org.bouncycastle.math.ec.ECMultiplier; -import org.bouncycastle.math.ec.ECPoint; -import org.bouncycastle.math.ec.FixedPointCombMultiplier; -import org.bouncycastle.util.Arrays; - -/** - * DSTU 4145-2002 - * <p> - * National Ukrainian standard of digital signature based on elliptic curves (DSTU 4145-2002). - * </p> - */ -public class DSTU4145Signer - implements DSA -{ - private static final BigInteger ONE = BigInteger.valueOf(1); - - private ECKeyParameters key; - private SecureRandom random; - - public void init(boolean forSigning, CipherParameters param) - { - if (forSigning) - { - if (param instanceof ParametersWithRandom) - { - ParametersWithRandom rParam = (ParametersWithRandom)param; - - this.random = rParam.getRandom(); - param = rParam.getParameters(); - } - else - { - this.random = new SecureRandom(); - } - - this.key = (ECPrivateKeyParameters)param; - } - else - { - this.key = (ECPublicKeyParameters)param; - } - - } - - public BigInteger[] generateSignature(byte[] message) - { - ECDomainParameters ec = key.getParameters(); - - ECCurve curve = ec.getCurve(); - - ECFieldElement h = hash2FieldElement(curve, message); - if (h.isZero()) - { - h = curve.fromBigInteger(ONE); - } - - BigInteger n = ec.getN(); - BigInteger e, r, s; - ECFieldElement Fe, y; - - BigInteger d = ((ECPrivateKeyParameters)key).getD(); - - ECMultiplier basePointMultiplier = createBasePointMultiplier(); - - do - { - do - { - do - { - e = generateRandomInteger(n, random); - Fe = basePointMultiplier.multiply(ec.getG(), e).normalize().getAffineXCoord(); - } - while (Fe.isZero()); - - y = h.multiply(Fe); - r = fieldElement2Integer(n, y); - } - while (r.signum() == 0); - - s = r.multiply(d).add(e).mod(n); - } - while (s.signum() == 0); - - return new BigInteger[]{r, s}; - } - - public boolean verifySignature(byte[] message, BigInteger r, BigInteger s) - { - if (r.signum() <= 0 || s.signum() <= 0) - { - return false; - } - - ECDomainParameters parameters = key.getParameters(); - - BigInteger n = parameters.getN(); - if (r.compareTo(n) >= 0 || s.compareTo(n) >= 0) - { - return false; - } - - ECCurve curve = parameters.getCurve(); - - ECFieldElement h = hash2FieldElement(curve, message); - if (h.isZero()) - { - h = curve.fromBigInteger(ONE); - } - - ECPoint R = ECAlgorithms.sumOfTwoMultiplies(parameters.getG(), s, ((ECPublicKeyParameters)key).getQ(), r).normalize(); - - // components must be bogus. - if (R.isInfinity()) - { - return false; - } - - ECFieldElement y = h.multiply(R.getAffineXCoord()); - return fieldElement2Integer(n, y).compareTo(r) == 0; - } - - protected ECMultiplier createBasePointMultiplier() - { - return new FixedPointCombMultiplier(); - } - - /** - * Generates random integer such, than its bit length is less than that of n - */ - private static BigInteger generateRandomInteger(BigInteger n, SecureRandom random) - { - return new BigInteger(n.bitLength() - 1, random); - } - - private static ECFieldElement hash2FieldElement(ECCurve curve, byte[] hash) - { - byte[] data = Arrays.reverse(hash); - return curve.fromBigInteger(truncate(new BigInteger(1, data), curve.getFieldSize())); - } - - private static BigInteger fieldElement2Integer(BigInteger n, ECFieldElement fe) - { - return truncate(fe.toBigInteger(), n.bitLength() - 1); - } - - private static BigInteger truncate(BigInteger x, int bitLength) - { - if (x.bitLength() > bitLength) - { - x = x.mod(ONE.shiftLeft(bitLength)); - } - return x; - } -} diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/signers/ECGOST3410Signer.java b/bcprov/src/main/java/org/bouncycastle/crypto/signers/ECGOST3410Signer.java deleted file mode 100644 index 0ef8876..0000000 --- a/bcprov/src/main/java/org/bouncycastle/crypto/signers/ECGOST3410Signer.java +++ /dev/null @@ -1,160 +0,0 @@ -package org.bouncycastle.crypto.signers; - -import org.bouncycastle.crypto.CipherParameters; -import org.bouncycastle.crypto.DSA; -import org.bouncycastle.crypto.params.ECDomainParameters; -import org.bouncycastle.crypto.params.ECKeyParameters; -import org.bouncycastle.crypto.params.ECPrivateKeyParameters; -import org.bouncycastle.crypto.params.ECPublicKeyParameters; -import org.bouncycastle.crypto.params.ParametersWithRandom; -import org.bouncycastle.math.ec.ECAlgorithms; -import org.bouncycastle.math.ec.ECConstants; -import org.bouncycastle.math.ec.ECMultiplier; -import org.bouncycastle.math.ec.ECPoint; -import org.bouncycastle.math.ec.FixedPointCombMultiplier; - -import java.math.BigInteger; -import java.security.SecureRandom; - -/** - * GOST R 34.10-2001 Signature Algorithm - */ -public class ECGOST3410Signer - implements DSA -{ - ECKeyParameters key; - - SecureRandom random; - - public void init( - boolean forSigning, - CipherParameters param) - { - if (forSigning) - { - if (param instanceof ParametersWithRandom) - { - ParametersWithRandom rParam = (ParametersWithRandom)param; - - this.random = rParam.getRandom(); - this.key = (ECPrivateKeyParameters)rParam.getParameters(); - } - else - { - this.random = new SecureRandom(); - this.key = (ECPrivateKeyParameters)param; - } - } - else - { - this.key = (ECPublicKeyParameters)param; - } - } - - /** - * generate a signature for the given message using the key we were - * initialised with. For conventional GOST3410 the message should be a GOST3411 - * hash of the message of interest. - * - * @param message the message that will be verified later. - */ - public BigInteger[] generateSignature( - byte[] message) - { - byte[] mRev = new byte[message.length]; // conversion is little-endian - for (int i = 0; i != mRev.length; i++) - { - mRev[i] = message[mRev.length - 1 - i]; - } - - BigInteger e = new BigInteger(1, mRev); - - ECDomainParameters ec = key.getParameters(); - BigInteger n = ec.getN(); - BigInteger d = ((ECPrivateKeyParameters)key).getD(); - - BigInteger r, s; - - ECMultiplier basePointMultiplier = createBasePointMultiplier(); - - do // generate s - { - BigInteger k; - do // generate r - { - do - { - k = new BigInteger(n.bitLength(), random); - } - while (k.equals(ECConstants.ZERO)); - - ECPoint p = basePointMultiplier.multiply(ec.getG(), k).normalize(); - - r = p.getAffineXCoord().toBigInteger().mod(n); - } - while (r.equals(ECConstants.ZERO)); - - s = (k.multiply(e)).add(d.multiply(r)).mod(n); - } - while (s.equals(ECConstants.ZERO)); - - return new BigInteger[]{ r, s }; - } - - /** - * return true if the value r and s represent a GOST3410 signature for - * the passed in message (for standard GOST3410 the message should be - * a GOST3411 hash of the real message to be verified). - */ - public boolean verifySignature( - byte[] message, - BigInteger r, - BigInteger s) - { - byte[] mRev = new byte[message.length]; // conversion is little-endian - for (int i = 0; i != mRev.length; i++) - { - mRev[i] = message[mRev.length - 1 - i]; - } - - BigInteger e = new BigInteger(1, mRev); - BigInteger n = key.getParameters().getN(); - - // r in the range [1,n-1] - if (r.compareTo(ECConstants.ONE) < 0 || r.compareTo(n) >= 0) - { - return false; - } - - // s in the range [1,n-1] - if (s.compareTo(ECConstants.ONE) < 0 || s.compareTo(n) >= 0) - { - return false; - } - - BigInteger v = e.modInverse(n); - - BigInteger z1 = s.multiply(v).mod(n); - BigInteger z2 = (n.subtract(r)).multiply(v).mod(n); - - ECPoint G = key.getParameters().getG(); // P - ECPoint Q = ((ECPublicKeyParameters)key).getQ(); - - ECPoint point = ECAlgorithms.sumOfTwoMultiplies(G, z1, Q, z2).normalize(); - - // components must be bogus. - if (point.isInfinity()) - { - return false; - } - - BigInteger R = point.getAffineXCoord().toBigInteger().mod(n); - - return R.equals(r); - } - - protected ECMultiplier createBasePointMultiplier() - { - return new FixedPointCombMultiplier(); - } -} diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/signers/ECNRSigner.java b/bcprov/src/main/java/org/bouncycastle/crypto/signers/ECNRSigner.java deleted file mode 100644 index 3e83916..0000000 --- a/bcprov/src/main/java/org/bouncycastle/crypto/signers/ECNRSigner.java +++ /dev/null @@ -1,188 +0,0 @@ -package org.bouncycastle.crypto.signers; - -import org.bouncycastle.crypto.AsymmetricCipherKeyPair; -import org.bouncycastle.crypto.CipherParameters; -import org.bouncycastle.crypto.DSA; -import org.bouncycastle.crypto.DataLengthException; -import org.bouncycastle.crypto.generators.ECKeyPairGenerator; -import org.bouncycastle.crypto.params.ECKeyGenerationParameters; -import org.bouncycastle.crypto.params.ECKeyParameters; -import org.bouncycastle.crypto.params.ECPrivateKeyParameters; -import org.bouncycastle.crypto.params.ECPublicKeyParameters; -import org.bouncycastle.crypto.params.ParametersWithRandom; -import org.bouncycastle.math.ec.ECAlgorithms; -import org.bouncycastle.math.ec.ECConstants; -import org.bouncycastle.math.ec.ECPoint; - -import java.math.BigInteger; -import java.security.SecureRandom; - -/** - * EC-NR as described in IEEE 1363-2000 - */ -public class ECNRSigner - implements DSA -{ - private boolean forSigning; - private ECKeyParameters key; - private SecureRandom random; - - public void init( - boolean forSigning, - CipherParameters param) - { - this.forSigning = forSigning; - - if (forSigning) - { - if (param instanceof ParametersWithRandom) - { - ParametersWithRandom rParam = (ParametersWithRandom)param; - - this.random = rParam.getRandom(); - this.key = (ECPrivateKeyParameters)rParam.getParameters(); - } - else - { - this.random = new SecureRandom(); - this.key = (ECPrivateKeyParameters)param; - } - } - else - { - this.key = (ECPublicKeyParameters)param; - } - } - - // Section 7.2.5 ECSP-NR, pg 34 - /** - * generate a signature for the given message using the key we were - * initialised with. Generally, the order of the curve should be at - * least as long as the hash of the message of interest, and with - * ECNR it *must* be at least as long. - * - * @param digest the digest to be signed. - * @exception DataLengthException if the digest is longer than the key allows - */ - public BigInteger[] generateSignature( - byte[] digest) - { - if (! this.forSigning) - { - throw new IllegalStateException("not initialised for signing"); - } - - BigInteger n = ((ECPrivateKeyParameters)this.key).getParameters().getN(); - int nBitLength = n.bitLength(); - - BigInteger e = new BigInteger(1, digest); - int eBitLength = e.bitLength(); - - ECPrivateKeyParameters privKey = (ECPrivateKeyParameters)key; - - if (eBitLength > nBitLength) - { - throw new DataLengthException("input too large for ECNR key."); - } - - BigInteger r = null; - BigInteger s = null; - - AsymmetricCipherKeyPair tempPair; - do // generate r - { - // generate another, but very temporary, key pair using - // the same EC parameters - ECKeyPairGenerator keyGen = new ECKeyPairGenerator(); - - keyGen.init(new ECKeyGenerationParameters(privKey.getParameters(), this.random)); - - tempPair = keyGen.generateKeyPair(); - - // BigInteger Vx = tempPair.getPublic().getW().getAffineX(); - ECPublicKeyParameters V = (ECPublicKeyParameters)tempPair.getPublic(); // get temp's public key - BigInteger Vx = V.getQ().getAffineXCoord().toBigInteger(); // get the point's x coordinate - - r = Vx.add(e).mod(n); - } - while (r.equals(ECConstants.ZERO)); - - // generate s - BigInteger x = privKey.getD(); // private key value - BigInteger u = ((ECPrivateKeyParameters)tempPair.getPrivate()).getD(); // temp's private key value - s = u.subtract(r.multiply(x)).mod(n); - - BigInteger[] res = new BigInteger[2]; - res[0] = r; - res[1] = s; - - return res; - } - - // Section 7.2.6 ECVP-NR, pg 35 - /** - * return true if the value r and s represent a signature for the - * message passed in. Generally, the order of the curve should be at - * least as long as the hash of the message of interest, and with - * ECNR, it *must* be at least as long. But just in case the signer - * applied mod(n) to the longer digest, this implementation will - * apply mod(n) during verification. - * - * @param digest the digest to be verified. - * @param r the r value of the signature. - * @param s the s value of the signature. - * @exception DataLengthException if the digest is longer than the key allows - */ - public boolean verifySignature( - byte[] digest, - BigInteger r, - BigInteger s) - { - if (this.forSigning) - { - throw new IllegalStateException("not initialised for verifying"); - } - - ECPublicKeyParameters pubKey = (ECPublicKeyParameters)key; - BigInteger n = pubKey.getParameters().getN(); - int nBitLength = n.bitLength(); - - BigInteger e = new BigInteger(1, digest); - int eBitLength = e.bitLength(); - - if (eBitLength > nBitLength) - { - throw new DataLengthException("input too large for ECNR key."); - } - - // r in the range [1,n-1] - if (r.compareTo(ECConstants.ONE) < 0 || r.compareTo(n) >= 0) - { - return false; - } - - // s in the range [0,n-1] NB: ECNR spec says 0 - if (s.compareTo(ECConstants.ZERO) < 0 || s.compareTo(n) >= 0) - { - return false; - } - - // compute P = sG + rW - - ECPoint G = pubKey.getParameters().getG(); - ECPoint W = pubKey.getQ(); - // calculate P using Bouncy math - ECPoint P = ECAlgorithms.sumOfTwoMultiplies(G, s, W, r).normalize(); - - // components must be bogus. - if (P.isInfinity()) - { - return false; - } - - BigInteger x = P.getAffineXCoord().toBigInteger(); - BigInteger t = r.subtract(x).mod(n); - - return t.equals(e); - } -} diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/signers/GOST3410Signer.java b/bcprov/src/main/java/org/bouncycastle/crypto/signers/GOST3410Signer.java deleted file mode 100644 index 135f185..0000000 --- a/bcprov/src/main/java/org/bouncycastle/crypto/signers/GOST3410Signer.java +++ /dev/null @@ -1,131 +0,0 @@ -package org.bouncycastle.crypto.signers; - -import java.math.BigInteger; -import java.security.SecureRandom; - -import org.bouncycastle.crypto.CipherParameters; -import org.bouncycastle.crypto.DSA; -import org.bouncycastle.crypto.params.GOST3410KeyParameters; -import org.bouncycastle.crypto.params.GOST3410Parameters; -import org.bouncycastle.crypto.params.GOST3410PrivateKeyParameters; -import org.bouncycastle.crypto.params.GOST3410PublicKeyParameters; -import org.bouncycastle.crypto.params.ParametersWithRandom; - -/** - * GOST R 34.10-94 Signature Algorithm - */ -public class GOST3410Signer - implements DSA -{ - GOST3410KeyParameters key; - - SecureRandom random; - - public void init( - boolean forSigning, - CipherParameters param) - { - if (forSigning) - { - if (param instanceof ParametersWithRandom) - { - ParametersWithRandom rParam = (ParametersWithRandom)param; - - this.random = rParam.getRandom(); - this.key = (GOST3410PrivateKeyParameters)rParam.getParameters(); - } - else - { - this.random = new SecureRandom(); - this.key = (GOST3410PrivateKeyParameters)param; - } - } - else - { - this.key = (GOST3410PublicKeyParameters)param; - } - } - - /** - * generate a signature for the given message using the key we were - * initialised with. For conventional GOST3410 the message should be a GOST3411 - * hash of the message of interest. - * - * @param message the message that will be verified later. - */ - public BigInteger[] generateSignature( - byte[] message) - { - byte[] mRev = new byte[message.length]; // conversion is little-endian - for (int i = 0; i != mRev.length; i++) - { - mRev[i] = message[mRev.length - 1 - i]; - } - - BigInteger m = new BigInteger(1, mRev); - GOST3410Parameters params = key.getParameters(); - BigInteger k; - - do - { - k = new BigInteger(params.getQ().bitLength(), random); - } - while (k.compareTo(params.getQ()) >= 0); - - BigInteger r = params.getA().modPow(k, params.getP()).mod(params.getQ()); - - BigInteger s = k.multiply(m). - add(((GOST3410PrivateKeyParameters)key).getX().multiply(r)). - mod(params.getQ()); - - BigInteger[] res = new BigInteger[2]; - - res[0] = r; - res[1] = s; - - return res; - } - - /** - * return true if the value r and s represent a GOST3410 signature for - * the passed in message for standard GOST3410 the message should be a - * GOST3411 hash of the real message to be verified. - */ - public boolean verifySignature( - byte[] message, - BigInteger r, - BigInteger s) - { - byte[] mRev = new byte[message.length]; // conversion is little-endian - for (int i = 0; i != mRev.length; i++) - { - mRev[i] = message[mRev.length - 1 - i]; - } - - BigInteger m = new BigInteger(1, mRev); - GOST3410Parameters params = key.getParameters(); - BigInteger zero = BigInteger.valueOf(0); - - if (zero.compareTo(r) >= 0 || params.getQ().compareTo(r) <= 0) - { - return false; - } - - if (zero.compareTo(s) >= 0 || params.getQ().compareTo(s) <= 0) - { - return false; - } - - BigInteger v = m.modPow(params.getQ().subtract(new BigInteger("2")),params.getQ()); - - BigInteger z1 = s.multiply(v).mod(params.getQ()); - BigInteger z2 = (params.getQ().subtract(r)).multiply(v).mod(params.getQ()); - - z1 = params.getA().modPow(z1, params.getP()); - z2 = ((GOST3410PublicKeyParameters)key).getY().modPow(z2, params.getP()); - - BigInteger u = z1.multiply(z2).mod(params.getP()).mod(params.getQ()); - - return u.equals(r); - } -} diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/signers/GenericSigner.java b/bcprov/src/main/java/org/bouncycastle/crypto/signers/GenericSigner.java deleted file mode 100644 index add087e..0000000 --- a/bcprov/src/main/java/org/bouncycastle/crypto/signers/GenericSigner.java +++ /dev/null @@ -1,144 +0,0 @@ -package org.bouncycastle.crypto.signers; - -import org.bouncycastle.crypto.AsymmetricBlockCipher; -import org.bouncycastle.crypto.CipherParameters; -import org.bouncycastle.crypto.CryptoException; -import org.bouncycastle.crypto.DataLengthException; -import org.bouncycastle.crypto.Digest; -import org.bouncycastle.crypto.Signer; -import org.bouncycastle.crypto.params.AsymmetricKeyParameter; -import org.bouncycastle.crypto.params.ParametersWithRandom; -import org.bouncycastle.util.Arrays; - -public class GenericSigner - implements Signer -{ - private final AsymmetricBlockCipher engine; - private final Digest digest; - private boolean forSigning; - - public GenericSigner( - AsymmetricBlockCipher engine, - Digest digest) - { - this.engine = engine; - this.digest = digest; - } - - /** - * initialise the signer for signing or verification. - * - * @param forSigning - * true if for signing, false otherwise - * @param parameters - * necessary parameters. - */ - public void init( - boolean forSigning, - CipherParameters parameters) - { - this.forSigning = forSigning; - AsymmetricKeyParameter k; - - if (parameters instanceof ParametersWithRandom) - { - k = (AsymmetricKeyParameter)((ParametersWithRandom)parameters).getParameters(); - } - else - { - k = (AsymmetricKeyParameter)parameters; - } - - if (forSigning && !k.isPrivate()) - { - throw new IllegalArgumentException("signing requires private key"); - } - - if (!forSigning && k.isPrivate()) - { - throw new IllegalArgumentException("verification requires public key"); - } - - reset(); - - engine.init(forSigning, parameters); - } - - /** - * update the internal digest with the byte b - */ - public void update( - byte input) - { - digest.update(input); - } - - /** - * update the internal digest with the byte array in - */ - public void update( - byte[] input, - int inOff, - int length) - { - digest.update(input, inOff, length); - } - - /** - * Generate a signature for the message we've been loaded with using the key - * we were initialised with. - */ - public byte[] generateSignature() - throws CryptoException, DataLengthException - { - if (!forSigning) - { - throw new IllegalStateException("GenericSigner not initialised for signature generation."); - } - - byte[] hash = new byte[digest.getDigestSize()]; - digest.doFinal(hash, 0); - - return engine.processBlock(hash, 0, hash.length); - } - - /** - * return true if the internal state represents the signature described in - * the passed in array. - */ - public boolean verifySignature( - byte[] signature) - { - if (forSigning) - { - throw new IllegalStateException("GenericSigner not initialised for verification"); - } - - byte[] hash = new byte[digest.getDigestSize()]; - digest.doFinal(hash, 0); - - try - { - byte[] sig = engine.processBlock(signature, 0, signature.length); - - // Extend with leading zeroes to match the digest size, if necessary. - if (sig.length < hash.length) - { - byte[] tmp = new byte[hash.length]; - System.arraycopy(sig, 0, tmp, tmp.length - sig.length, sig.length); - sig = tmp; - } - - return Arrays.constantTimeAreEqual(sig, hash); - } - catch (Exception e) - { - return false; - } - } - - public void reset() - { - digest.reset(); - } -} diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/signers/HMacDSAKCalculator.java b/bcprov/src/main/java/org/bouncycastle/crypto/signers/HMacDSAKCalculator.java deleted file mode 100644 index 0fb7375..0000000 --- a/bcprov/src/main/java/org/bouncycastle/crypto/signers/HMacDSAKCalculator.java +++ /dev/null @@ -1,152 +0,0 @@ -package org.bouncycastle.crypto.signers; - -import java.math.BigInteger; -import java.security.SecureRandom; - -import org.bouncycastle.crypto.Digest; -import org.bouncycastle.crypto.macs.HMac; -import org.bouncycastle.crypto.params.KeyParameter; -import org.bouncycastle.util.Arrays; -import org.bouncycastle.util.BigIntegers; - -/** - * A deterministic K calculator based on the algorithm in section 3.2 of RFC 6979. - */ -public class HMacDSAKCalculator - implements DSAKCalculator -{ - private static final BigInteger ZERO = BigInteger.valueOf(0); - - private final HMac hMac; - private final byte[] K; - private final byte[] V; - - private BigInteger n; - - /** - * Base constructor. - * - * @param digest digest to build the HMAC on. - */ - public HMacDSAKCalculator(Digest digest) - { - this.hMac = new HMac(digest); - this.V = new byte[hMac.getMacSize()]; - this.K = new byte[hMac.getMacSize()]; - } - - public boolean isDeterministic() - { - return true; - } - - public void init(BigInteger n, SecureRandom random) - { - throw new IllegalStateException("Operation not supported"); - } - - public void init(BigInteger n, BigInteger d, byte[] message) - { - this.n = n; - - Arrays.fill(V, (byte)0x01); - Arrays.fill(K, (byte)0); - - byte[] x = new byte[(n.bitLength() + 7) / 8]; - byte[] dVal = BigIntegers.asUnsignedByteArray(d); - - System.arraycopy(dVal, 0, x, x.length - dVal.length, dVal.length); - - byte[] m = new byte[(n.bitLength() + 7) / 8]; - - BigInteger mInt = bitsToInt(message); - - if (mInt.compareTo(n) >= 0) - { - mInt = mInt.subtract(n); - } - - byte[] mVal = BigIntegers.asUnsignedByteArray(mInt); - - System.arraycopy(mVal, 0, m, m.length - mVal.length, mVal.length); - - hMac.init(new KeyParameter(K)); - - hMac.update(V, 0, V.length); - hMac.update((byte)0x00); - hMac.update(x, 0, x.length); - hMac.update(m, 0, m.length); - - hMac.doFinal(K, 0); - - hMac.init(new KeyParameter(K)); - - hMac.update(V, 0, V.length); - - hMac.doFinal(V, 0); - - hMac.update(V, 0, V.length); - hMac.update((byte)0x01); - hMac.update(x, 0, x.length); - hMac.update(m, 0, m.length); - - hMac.doFinal(K, 0); - - hMac.init(new KeyParameter(K)); - - hMac.update(V, 0, V.length); - - hMac.doFinal(V, 0); - } - - public BigInteger nextK() - { - byte[] t = new byte[((n.bitLength() + 7) / 8)]; - - for (;;) - { - int tOff = 0; - - while (tOff < t.length) - { - hMac.update(V, 0, V.length); - - hMac.doFinal(V, 0); - - int len = Math.min(t.length - tOff, V.length); - System.arraycopy(V, 0, t, tOff, len); - tOff += len; - } - - BigInteger k = bitsToInt(t); - - if (k.compareTo(ZERO) > 0 && k.compareTo(n) < 0) - { - return k; - } - - hMac.update(V, 0, V.length); - hMac.update((byte)0x00); - - hMac.doFinal(K, 0); - - hMac.init(new KeyParameter(K)); - - hMac.update(V, 0, V.length); - - hMac.doFinal(V, 0); - } - } - - private BigInteger bitsToInt(byte[] t) - { - BigInteger v = new BigInteger(1, t); - - if (t.length * 8 > n.bitLength()) - { - v = v.shiftRight(t.length * 8 - n.bitLength()); - } - - return v; - } -} diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/signers/ISO9796d2PSSSigner.java b/bcprov/src/main/java/org/bouncycastle/crypto/signers/ISO9796d2PSSSigner.java deleted file mode 100644 index fcd5816..0000000 --- a/bcprov/src/main/java/org/bouncycastle/crypto/signers/ISO9796d2PSSSigner.java +++ /dev/null @@ -1,668 +0,0 @@ -package org.bouncycastle.crypto.signers; - -import java.security.SecureRandom; -import java.util.Hashtable; - -import org.bouncycastle.crypto.AsymmetricBlockCipher; -import org.bouncycastle.crypto.CipherParameters; -import org.bouncycastle.crypto.CryptoException; -import org.bouncycastle.crypto.Digest; -import org.bouncycastle.crypto.InvalidCipherTextException; -import org.bouncycastle.crypto.SignerWithRecovery; -import org.bouncycastle.crypto.params.ParametersWithRandom; -import org.bouncycastle.crypto.params.ParametersWithSalt; -import org.bouncycastle.crypto.params.RSAKeyParameters; -import org.bouncycastle.util.Arrays; -import org.bouncycastle.util.Integers; - -/** - * ISO9796-2 - mechanism using a hash function with recovery (scheme 2 and 3). - * <p> - * Note: the usual length for the salt is the length of the hash - * function used in bytes. - */ -public class ISO9796d2PSSSigner - implements SignerWithRecovery -{ - static final public int TRAILER_IMPLICIT = 0xBC; - static final public int TRAILER_RIPEMD160 = 0x31CC; - static final public int TRAILER_RIPEMD128 = 0x32CC; - static final public int TRAILER_SHA1 = 0x33CC; - static final public int TRAILER_SHA256 = 0x34CC; - static final public int TRAILER_SHA512 = 0x35CC; - static final public int TRAILER_SHA384 = 0x36CC; - static final public int TRAILER_WHIRLPOOL = 0x37CC; - - private static Hashtable trailerMap = new Hashtable(); - - static - { - trailerMap.put("RIPEMD128", Integers.valueOf(TRAILER_RIPEMD128)); - trailerMap.put("RIPEMD160", Integers.valueOf(TRAILER_RIPEMD160)); - - trailerMap.put("SHA-1", Integers.valueOf(TRAILER_SHA1)); - trailerMap.put("SHA-256", Integers.valueOf(TRAILER_SHA256)); - trailerMap.put("SHA-384", Integers.valueOf(TRAILER_SHA384)); - trailerMap.put("SHA-512", Integers.valueOf(TRAILER_SHA512)); - - trailerMap.put("Whirlpool", Integers.valueOf(TRAILER_WHIRLPOOL)); - } - - private Digest digest; - private AsymmetricBlockCipher cipher; - - private SecureRandom random; - private byte[] standardSalt; - - private int hLen; - private int trailer; - private int keyBits; - private byte[] block; - private byte[] mBuf; - private int messageLength; - private int saltLength; - private boolean fullMessage; - private byte[] recoveredMessage; - - private byte[] preSig; - private byte[] preBlock; - private int preMStart; - private int preTLength; - - /** - * Generate a signer for the with either implicit or explicit trailers - * for ISO9796-2, scheme 2 or 3. - * - * @param cipher base cipher to use for signature creation/verification - * @param digest digest to use. - * @param saltLength length of salt in bytes. - * @param implicit whether or not the trailer is implicit or gives the hash. - */ - public ISO9796d2PSSSigner( - AsymmetricBlockCipher cipher, - Digest digest, - int saltLength, - boolean implicit) - { - this.cipher = cipher; - this.digest = digest; - this.hLen = digest.getDigestSize(); - this.saltLength = saltLength; - - if (implicit) - { - trailer = TRAILER_IMPLICIT; - } - else - { - Integer trailerObj = (Integer)trailerMap.get(digest.getAlgorithmName()); - - if (trailerObj != null) - { - trailer = trailerObj.intValue(); - } - else - { - throw new IllegalArgumentException("no valid trailer for digest"); - } - } - } - - /** - * Constructor for a signer with an explicit digest trailer. - * - * @param cipher cipher to use. - * @param digest digest to sign with. - * @param saltLength length of salt in bytes. - */ - public ISO9796d2PSSSigner( - AsymmetricBlockCipher cipher, - Digest digest, - int saltLength) - { - this(cipher, digest, saltLength, false); - } - - /** - * Initialise the signer. - * - * @param forSigning true if for signing, false if for verification. - * @param param parameters for signature generation/verification. If the - * parameters are for generation they should be a ParametersWithRandom, - * a ParametersWithSalt, or just an RSAKeyParameters object. If RSAKeyParameters - * are passed in a SecureRandom will be created. - * @throws IllegalArgumentException if wrong parameter type or a fixed - * salt is passed in which is the wrong length. - */ - public void init( - boolean forSigning, - CipherParameters param) - { - RSAKeyParameters kParam; - int lengthOfSalt = saltLength; - - if (param instanceof ParametersWithRandom) - { - ParametersWithRandom p = (ParametersWithRandom)param; - - kParam = (RSAKeyParameters)p.getParameters(); - if (forSigning) - { - random = p.getRandom(); - } - } - else if (param instanceof ParametersWithSalt) - { - ParametersWithSalt p = (ParametersWithSalt)param; - - kParam = (RSAKeyParameters)p.getParameters(); - standardSalt = p.getSalt(); - lengthOfSalt = standardSalt.length; - if (standardSalt.length != saltLength) - { - throw new IllegalArgumentException("Fixed salt is of wrong length"); - } - } - else - { - kParam = (RSAKeyParameters)param; - if (forSigning) - { - random = new SecureRandom(); - } - } - - cipher.init(forSigning, kParam); - - keyBits = kParam.getModulus().bitLength(); - - block = new byte[(keyBits + 7) / 8]; - - if (trailer == TRAILER_IMPLICIT) - { - mBuf = new byte[block.length - digest.getDigestSize() - lengthOfSalt - 1 - 1]; - } - else - { - mBuf = new byte[block.length - digest.getDigestSize() - lengthOfSalt - 1 - 2]; - } - - reset(); - } - - /** - * compare two byte arrays - constant time - */ - private boolean isSameAs( - byte[] a, - byte[] b) - { - boolean isOkay = true; - - if (messageLength != b.length) - { - isOkay = false; - } - - for (int i = 0; i != b.length; i++) - { - if (a[i] != b[i]) - { - isOkay = false; - } - } - - return isOkay; - } - - /** - * clear possible sensitive data - */ - private void clearBlock( - byte[] block) - { - for (int i = 0; i != block.length; i++) - { - block[i] = 0; - } - } - - public void updateWithRecoveredMessage(byte[] signature) - throws InvalidCipherTextException - { - byte[] block = cipher.processBlock(signature, 0, signature.length); - - // - // adjust block size for leading zeroes if necessary - // - if (block.length < (keyBits + 7) / 8) - { - byte[] tmp = new byte[(keyBits + 7) / 8]; - - System.arraycopy(block, 0, tmp, tmp.length - block.length, block.length); - clearBlock(block); - block = tmp; - } - - int tLength; - - if (((block[block.length - 1] & 0xFF) ^ 0xBC) == 0) - { - tLength = 1; - } - else - { - int sigTrail = ((block[block.length - 2] & 0xFF) << 8) | (block[block.length - 1] & 0xFF); - - Integer trailerObj = (Integer)trailerMap.get(digest.getAlgorithmName()); - - if (trailerObj != null) - { - if (sigTrail != trailerObj.intValue()) - { - throw new IllegalStateException("signer initialised with wrong digest for trailer " + sigTrail); - } - } - else - { - throw new IllegalArgumentException("unrecognised hash in signature"); - } - - tLength = 2; - } - - // - // calculate H(m2) - // - byte[] m2Hash = new byte[hLen]; - digest.doFinal(m2Hash, 0); - - // - // remove the mask - // - byte[] dbMask = maskGeneratorFunction1(block, block.length - hLen - tLength, hLen, block.length - hLen - tLength); - for (int i = 0; i != dbMask.length; i++) - { - block[i] ^= dbMask[i]; - } - - block[0] &= 0x7f; - - // - // find out how much padding we've got - // - int mStart = 0; - for (; mStart != block.length; mStart++) - { - if (block[mStart] == 0x01) - { - break; - } - } - - mStart++; - - if (mStart >= block.length) - { - clearBlock(block); - } - - fullMessage = (mStart > 1); - - recoveredMessage = new byte[dbMask.length - mStart - saltLength]; - - System.arraycopy(block, mStart, recoveredMessage, 0, recoveredMessage.length); - System.arraycopy(recoveredMessage, 0, mBuf, 0, recoveredMessage.length); - - preSig = signature; - preBlock = block; - preMStart = mStart; - preTLength = tLength; - } - - /** - * update the internal digest with the byte b - */ - public void update( - byte b) - { - if (preSig == null && messageLength < mBuf.length) - { - mBuf[messageLength++] = b; - } - else - { - digest.update(b); - } - } - - /** - * update the internal digest with the byte array in - */ - public void update( - byte[] in, - int off, - int len) - { - if (preSig == null) - { - while (len > 0 && messageLength < mBuf.length) - { - this.update(in[off]); - off++; - len--; - } - } - - if (len > 0) - { - digest.update(in, off, len); - } - } - - /** - * reset the internal state - */ - public void reset() - { - digest.reset(); - messageLength = 0; - if (mBuf != null) - { - clearBlock(mBuf); - } - if (recoveredMessage != null) - { - clearBlock(recoveredMessage); - recoveredMessage = null; - } - fullMessage = false; - if (preSig != null) - { - preSig = null; - clearBlock(preBlock); - preBlock = null; - } - } - - /** - * generate a signature for the loaded message using the key we were - * initialised with. - */ - public byte[] generateSignature() - throws CryptoException - { - int digSize = digest.getDigestSize(); - - byte[] m2Hash = new byte[digSize]; - - digest.doFinal(m2Hash, 0); - - byte[] C = new byte[8]; - LtoOSP(messageLength * 8, C); - - digest.update(C, 0, C.length); - - digest.update(mBuf, 0, messageLength); - - digest.update(m2Hash, 0, m2Hash.length); - - byte[] salt; - - if (standardSalt != null) - { - salt = standardSalt; - } - else - { - salt = new byte[saltLength]; - random.nextBytes(salt); - } - - digest.update(salt, 0, salt.length); - - byte[] hash = new byte[digest.getDigestSize()]; - - digest.doFinal(hash, 0); - - int tLength = 2; - if (trailer == TRAILER_IMPLICIT) - { - tLength = 1; - } - - int off = block.length - messageLength - salt.length - hLen - tLength - 1; - - block[off] = 0x01; - - System.arraycopy(mBuf, 0, block, off + 1, messageLength); - System.arraycopy(salt, 0, block, off + 1 + messageLength, salt.length); - - byte[] dbMask = maskGeneratorFunction1(hash, 0, hash.length, block.length - hLen - tLength); - for (int i = 0; i != dbMask.length; i++) - { - block[i] ^= dbMask[i]; - } - - System.arraycopy(hash, 0, block, block.length - hLen - tLength, hLen); - - if (trailer == TRAILER_IMPLICIT) - { - block[block.length - 1] = (byte)TRAILER_IMPLICIT; - } - else - { - block[block.length - 2] = (byte)(trailer >>> 8); - block[block.length - 1] = (byte)trailer; - } - - block[0] &= 0x7f; - - byte[] b = cipher.processBlock(block, 0, block.length); - - clearBlock(mBuf); - clearBlock(block); - messageLength = 0; - - return b; - } - - /** - * return true if the signature represents a ISO9796-2 signature - * for the passed in message. - */ - public boolean verifySignature( - byte[] signature) - { - // - // calculate H(m2) - // - byte[] m2Hash = new byte[hLen]; - digest.doFinal(m2Hash, 0); - - byte[] block; - int tLength; - int mStart = 0; - - if (preSig == null) - { - try - { - updateWithRecoveredMessage(signature); - } - catch (Exception e) - { - return false; - } - } - else - { - if (!Arrays.areEqual(preSig, signature)) - { - throw new IllegalStateException("updateWithRecoveredMessage called on different signature"); - } - } - - block = preBlock; - mStart = preMStart; - tLength = preTLength; - - preSig = null; - preBlock = null; - - // - // check the hashes - // - byte[] C = new byte[8]; - LtoOSP(recoveredMessage.length * 8, C); - - digest.update(C, 0, C.length); - - if (recoveredMessage.length != 0) - { - digest.update(recoveredMessage, 0, recoveredMessage.length); - } - - digest.update(m2Hash, 0, m2Hash.length); - - // Update for the salt - digest.update(block, mStart + recoveredMessage.length, saltLength); - - byte[] hash = new byte[digest.getDigestSize()]; - digest.doFinal(hash, 0); - - int off = block.length - tLength - hash.length; - - boolean isOkay = true; - - for (int i = 0; i != hash.length; i++) - { - if (hash[i] != block[off + i]) - { - isOkay = false; - } - } - - clearBlock(block); - clearBlock(hash); - - if (!isOkay) - { - fullMessage = false; - clearBlock(recoveredMessage); - return false; - } - - // - // if they've input a message check what we've recovered against - // what was input. - // - if (messageLength != 0) - { - if (!isSameAs(mBuf, recoveredMessage)) - { - clearBlock(mBuf); - return false; - } - messageLength = 0; - } - - clearBlock(mBuf); - return true; - } - - /** - * Return true if the full message was recoveredMessage. - * - * @return true on full message recovery, false otherwise, or if not sure. - * @see org.bouncycastle.crypto.SignerWithRecovery#hasFullMessage() - */ - public boolean hasFullMessage() - { - return fullMessage; - } - - /** - * Return a reference to the recoveredMessage message. - * - * @return the full/partial recoveredMessage message. - * @see org.bouncycastle.crypto.SignerWithRecovery#getRecoveredMessage() - */ - public byte[] getRecoveredMessage() - { - return recoveredMessage; - } - - /** - * int to octet string. - */ - private void ItoOSP( - int i, - byte[] sp) - { - sp[0] = (byte)(i >>> 24); - sp[1] = (byte)(i >>> 16); - sp[2] = (byte)(i >>> 8); - sp[3] = (byte)(i >>> 0); - } - - /** - * long to octet string. - */ - private void LtoOSP( - long l, - byte[] sp) - { - sp[0] = (byte)(l >>> 56); - sp[1] = (byte)(l >>> 48); - sp[2] = (byte)(l >>> 40); - sp[3] = (byte)(l >>> 32); - sp[4] = (byte)(l >>> 24); - sp[5] = (byte)(l >>> 16); - sp[6] = (byte)(l >>> 8); - sp[7] = (byte)(l >>> 0); - } - - /** - * mask generator function, as described in PKCS1v2. - */ - private byte[] maskGeneratorFunction1( - byte[] Z, - int zOff, - int zLen, - int length) - { - byte[] mask = new byte[length]; - byte[] hashBuf = new byte[hLen]; - byte[] C = new byte[4]; - int counter = 0; - - digest.reset(); - - while (counter < (length / hLen)) - { - ItoOSP(counter, C); - - digest.update(Z, zOff, zLen); - digest.update(C, 0, C.length); - digest.doFinal(hashBuf, 0); - - System.arraycopy(hashBuf, 0, mask, counter * hLen, hLen); - - counter++; - } - - if ((counter * hLen) < length) - { - ItoOSP(counter, C); - - digest.update(Z, zOff, zLen); - digest.update(C, 0, C.length); - digest.doFinal(hashBuf, 0); - - System.arraycopy(hashBuf, 0, mask, counter * hLen, mask.length - (counter * hLen)); - } - - return mask; - } -} diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/signers/ISO9796d2Signer.java b/bcprov/src/main/java/org/bouncycastle/crypto/signers/ISO9796d2Signer.java deleted file mode 100644 index 563fae6..0000000 --- a/bcprov/src/main/java/org/bouncycastle/crypto/signers/ISO9796d2Signer.java +++ /dev/null @@ -1,618 +0,0 @@ -package org.bouncycastle.crypto.signers; - -import java.util.Hashtable; - -import org.bouncycastle.crypto.AsymmetricBlockCipher; -import org.bouncycastle.crypto.CipherParameters; -import org.bouncycastle.crypto.CryptoException; -import org.bouncycastle.crypto.Digest; -import org.bouncycastle.crypto.InvalidCipherTextException; -import org.bouncycastle.crypto.SignerWithRecovery; -import org.bouncycastle.crypto.params.RSAKeyParameters; -import org.bouncycastle.util.Arrays; -import org.bouncycastle.util.Integers; - -/** - * ISO9796-2 - mechanism using a hash function with recovery (scheme 1) - */ -public class ISO9796d2Signer - implements SignerWithRecovery -{ - static final public int TRAILER_IMPLICIT = 0xBC; - static final public int TRAILER_RIPEMD160 = 0x31CC; - static final public int TRAILER_RIPEMD128 = 0x32CC; - static final public int TRAILER_SHA1 = 0x33CC; - static final public int TRAILER_SHA256 = 0x34CC; - static final public int TRAILER_SHA512 = 0x35CC; - static final public int TRAILER_SHA384 = 0x36CC; - static final public int TRAILER_WHIRLPOOL = 0x37CC; - - private static Hashtable trailerMap = new Hashtable(); - - static - { - trailerMap.put("RIPEMD128", Integers.valueOf(TRAILER_RIPEMD128)); - trailerMap.put("RIPEMD160", Integers.valueOf(TRAILER_RIPEMD160)); - - trailerMap.put("SHA-1", Integers.valueOf(TRAILER_SHA1)); - trailerMap.put("SHA-256", Integers.valueOf(TRAILER_SHA256)); - trailerMap.put("SHA-384", Integers.valueOf(TRAILER_SHA384)); - trailerMap.put("SHA-512", Integers.valueOf(TRAILER_SHA512)); - - trailerMap.put("Whirlpool", Integers.valueOf(TRAILER_WHIRLPOOL)); - } - - private Digest digest; - private AsymmetricBlockCipher cipher; - - private int trailer; - private int keyBits; - private byte[] block; - private byte[] mBuf; - private int messageLength; - private boolean fullMessage; - private byte[] recoveredMessage; - - private byte[] preSig; - private byte[] preBlock; - - /** - * Generate a signer for the with either implicit or explicit trailers - * for ISO9796-2. - * - * @param cipher base cipher to use for signature creation/verification - * @param digest digest to use. - * @param implicit whether or not the trailer is implicit or gives the hash. - */ - public ISO9796d2Signer( - AsymmetricBlockCipher cipher, - Digest digest, - boolean implicit) - { - this.cipher = cipher; - this.digest = digest; - - if (implicit) - { - trailer = TRAILER_IMPLICIT; - } - else - { - Integer trailerObj = (Integer)trailerMap.get(digest.getAlgorithmName()); - - if (trailerObj != null) - { - trailer = trailerObj.intValue(); - } - else - { - throw new IllegalArgumentException("no valid trailer for digest"); - } - } - } - - /** - * Constructor for a signer with an explicit digest trailer. - * - * @param cipher cipher to use. - * @param digest digest to sign with. - */ - public ISO9796d2Signer( - AsymmetricBlockCipher cipher, - Digest digest) - { - this(cipher, digest, false); - } - - public void init( - boolean forSigning, - CipherParameters param) - { - RSAKeyParameters kParam = (RSAKeyParameters)param; - - cipher.init(forSigning, kParam); - - keyBits = kParam.getModulus().bitLength(); - - block = new byte[(keyBits + 7) / 8]; - - if (trailer == TRAILER_IMPLICIT) - { - mBuf = new byte[block.length - digest.getDigestSize() - 2]; - } - else - { - mBuf = new byte[block.length - digest.getDigestSize() - 3]; - } - - reset(); - } - - /** - * compare two byte arrays - constant time - */ - private boolean isSameAs( - byte[] a, - byte[] b) - { - boolean isOkay = true; - - if (messageLength > mBuf.length) - { - if (mBuf.length > b.length) - { - isOkay = false; - } - - for (int i = 0; i != mBuf.length; i++) - { - if (a[i] != b[i]) - { - isOkay = false; - } - } - } - else - { - if (messageLength != b.length) - { - isOkay = false; - } - - for (int i = 0; i != b.length; i++) - { - if (a[i] != b[i]) - { - isOkay = false; - } - } - } - - return isOkay; - } - - /** - * clear possible sensitive data - */ - private void clearBlock( - byte[] block) - { - for (int i = 0; i != block.length; i++) - { - block[i] = 0; - } - } - - public void updateWithRecoveredMessage(byte[] signature) - throws InvalidCipherTextException - { - byte[] block = cipher.processBlock(signature, 0, signature.length); - - if (((block[0] & 0xC0) ^ 0x40) != 0) - { - throw new InvalidCipherTextException("malformed signature"); - } - - if (((block[block.length - 1] & 0xF) ^ 0xC) != 0) - { - throw new InvalidCipherTextException("malformed signature"); - } - - int delta = 0; - - if (((block[block.length - 1] & 0xFF) ^ 0xBC) == 0) - { - delta = 1; - } - else - { - int sigTrail = ((block[block.length - 2] & 0xFF) << 8) | (block[block.length - 1] & 0xFF); - Integer trailerObj = (Integer)trailerMap.get(digest.getAlgorithmName()); - - if (trailerObj != null) - { - if (sigTrail != trailerObj.intValue()) - { - throw new IllegalStateException("signer initialised with wrong digest for trailer " + sigTrail); - } - } - else - { - throw new IllegalArgumentException("unrecognised hash in signature"); - } - - delta = 2; - } - - // - // find out how much padding we've got - // - int mStart = 0; - - for (mStart = 0; mStart != block.length; mStart++) - { - if (((block[mStart] & 0x0f) ^ 0x0a) == 0) - { - break; - } - } - - mStart++; - - int off = block.length - delta - digest.getDigestSize(); - - // - // there must be at least one byte of message string - // - if ((off - mStart) <= 0) - { - throw new InvalidCipherTextException("malformed block"); - } - - // - // if we contain the whole message as well, check the hash of that. - // - if ((block[0] & 0x20) == 0) - { - fullMessage = true; - - recoveredMessage = new byte[off - mStart]; - System.arraycopy(block, mStart, recoveredMessage, 0, recoveredMessage.length); - } - else - { - fullMessage = false; - - recoveredMessage = new byte[off - mStart]; - System.arraycopy(block, mStart, recoveredMessage, 0, recoveredMessage.length); - } - - preSig = signature; - preBlock = block; - - digest.update(recoveredMessage, 0, recoveredMessage.length); - messageLength = recoveredMessage.length; - System.arraycopy(recoveredMessage, 0, mBuf, 0, recoveredMessage.length); - } - - /** - * update the internal digest with the byte b - */ - public void update( - byte b) - { - digest.update(b); - - if (messageLength < mBuf.length) - { - mBuf[messageLength] = b; - } - - messageLength++; - } - - /** - * update the internal digest with the byte array in - */ - public void update( - byte[] in, - int off, - int len) - { - while (len > 0 && messageLength < mBuf.length) - { - this.update(in[off]); - off++; - len--; - } - - digest.update(in, off, len); - messageLength += len; - } - - /** - * reset the internal state - */ - public void reset() - { - digest.reset(); - messageLength = 0; - clearBlock(mBuf); - - if (recoveredMessage != null) - { - clearBlock(recoveredMessage); - } - - recoveredMessage = null; - fullMessage = false; - - if (preSig != null) - { - preSig = null; - clearBlock(preBlock); - preBlock = null; - } - } - - /** - * generate a signature for the loaded message using the key we were - * initialised with. - */ - public byte[] generateSignature() - throws CryptoException - { - int digSize = digest.getDigestSize(); - - int t = 0; - int delta = 0; - - if (trailer == TRAILER_IMPLICIT) - { - t = 8; - delta = block.length - digSize - 1; - digest.doFinal(block, delta); - block[block.length - 1] = (byte)TRAILER_IMPLICIT; - } - else - { - t = 16; - delta = block.length - digSize - 2; - digest.doFinal(block, delta); - block[block.length - 2] = (byte)(trailer >>> 8); - block[block.length - 1] = (byte)trailer; - } - - byte header = 0; - int x = (digSize + messageLength) * 8 + t + 4 - keyBits; - - if (x > 0) - { - int mR = messageLength - ((x + 7) / 8); - header = 0x60; - - delta -= mR; - - System.arraycopy(mBuf, 0, block, delta, mR); - } - else - { - header = 0x40; - delta -= messageLength; - - System.arraycopy(mBuf, 0, block, delta, messageLength); - } - - if ((delta - 1) > 0) - { - for (int i = delta - 1; i != 0; i--) - { - block[i] = (byte)0xbb; - } - block[delta - 1] ^= (byte)0x01; - block[0] = (byte)0x0b; - block[0] |= header; - } - else - { - block[0] = (byte)0x0a; - block[0] |= header; - } - - byte[] b = cipher.processBlock(block, 0, block.length); - - clearBlock(mBuf); - clearBlock(block); - - return b; - } - - /** - * return true if the signature represents a ISO9796-2 signature - * for the passed in message. - */ - public boolean verifySignature( - byte[] signature) - { - byte[] block = null; - - if (preSig == null) - { - try - { - block = cipher.processBlock(signature, 0, signature.length); - } - catch (Exception e) - { - return false; - } - } - else - { - if (!Arrays.areEqual(preSig, signature)) - { - throw new IllegalStateException("updateWithRecoveredMessage called on different signature"); - } - - block = preBlock; - - preSig = null; - preBlock = null; - } - - if (((block[0] & 0xC0) ^ 0x40) != 0) - { - return returnFalse(block); - } - - if (((block[block.length - 1] & 0xF) ^ 0xC) != 0) - { - return returnFalse(block); - } - - int delta = 0; - - if (((block[block.length - 1] & 0xFF) ^ 0xBC) == 0) - { - delta = 1; - } - else - { - int sigTrail = ((block[block.length - 2] & 0xFF) << 8) | (block[block.length - 1] & 0xFF); - Integer trailerObj = (Integer)trailerMap.get(digest.getAlgorithmName()); - - if (trailerObj != null) - { - if (sigTrail != trailerObj.intValue()) - { - throw new IllegalStateException("signer initialised with wrong digest for trailer " + sigTrail); - } - } - else - { - throw new IllegalArgumentException("unrecognised hash in signature"); - } - - delta = 2; - } - - // - // find out how much padding we've got - // - int mStart = 0; - - for (mStart = 0; mStart != block.length; mStart++) - { - if (((block[mStart] & 0x0f) ^ 0x0a) == 0) - { - break; - } - } - - mStart++; - - // - // check the hashes - // - byte[] hash = new byte[digest.getDigestSize()]; - - int off = block.length - delta - hash.length; - - // - // there must be at least one byte of message string - // - if ((off - mStart) <= 0) - { - return returnFalse(block); - } - - // - // if we contain the whole message as well, check the hash of that. - // - if ((block[0] & 0x20) == 0) - { - fullMessage = true; - - // check right number of bytes passed in. - if (messageLength > off - mStart) - { - return returnFalse(block); - } - - digest.reset(); - digest.update(block, mStart, off - mStart); - digest.doFinal(hash, 0); - - boolean isOkay = true; - - for (int i = 0; i != hash.length; i++) - { - block[off + i] ^= hash[i]; - if (block[off + i] != 0) - { - isOkay = false; - } - } - - if (!isOkay) - { - return returnFalse(block); - } - - recoveredMessage = new byte[off - mStart]; - System.arraycopy(block, mStart, recoveredMessage, 0, recoveredMessage.length); - } - else - { - fullMessage = false; - - digest.doFinal(hash, 0); - - boolean isOkay = true; - - for (int i = 0; i != hash.length; i++) - { - block[off + i] ^= hash[i]; - if (block[off + i] != 0) - { - isOkay = false; - } - } - - if (!isOkay) - { - return returnFalse(block); - } - - recoveredMessage = new byte[off - mStart]; - System.arraycopy(block, mStart, recoveredMessage, 0, recoveredMessage.length); - } - - // - // if they've input a message check what we've recovered against - // what was input. - // - if (messageLength != 0) - { - if (!isSameAs(mBuf, recoveredMessage)) - { - return returnFalse(block); - } - } - - clearBlock(mBuf); - clearBlock(block); - - return true; - } - - private boolean returnFalse(byte[] block) - { - clearBlock(mBuf); - clearBlock(block); - - return false; - } - - /** - * Return true if the full message was recoveredMessage. - * - * @return true on full message recovery, false otherwise. - * @see org.bouncycastle.crypto.SignerWithRecovery#hasFullMessage() - */ - public boolean hasFullMessage() - { - return fullMessage; - } - - /** - * Return a reference to the recoveredMessage message. - * - * @return the full/partial recoveredMessage message. - * @see org.bouncycastle.crypto.SignerWithRecovery#getRecoveredMessage() - */ - public byte[] getRecoveredMessage() - { - return recoveredMessage; - } -} diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/signers/PSSSigner.java b/bcprov/src/main/java/org/bouncycastle/crypto/signers/PSSSigner.java deleted file mode 100644 index 8c9eb94..0000000 --- a/bcprov/src/main/java/org/bouncycastle/crypto/signers/PSSSigner.java +++ /dev/null @@ -1,348 +0,0 @@ -package org.bouncycastle.crypto.signers; - -import java.security.SecureRandom; - -import org.bouncycastle.crypto.AsymmetricBlockCipher; -import org.bouncycastle.crypto.CipherParameters; -import org.bouncycastle.crypto.CryptoException; -import org.bouncycastle.crypto.DataLengthException; -import org.bouncycastle.crypto.Digest; -import org.bouncycastle.crypto.Signer; -import org.bouncycastle.crypto.params.ParametersWithRandom; -import org.bouncycastle.crypto.params.RSABlindingParameters; -import org.bouncycastle.crypto.params.RSAKeyParameters; - -/** - * RSA-PSS as described in PKCS# 1 v 2.1. - * <p> - * Note: the usual value for the salt length is the number of - * bytes in the hash function. - */ -public class PSSSigner - implements Signer -{ - static final public byte TRAILER_IMPLICIT = (byte)0xBC; - - private Digest contentDigest; - private Digest mgfDigest; - private AsymmetricBlockCipher cipher; - private SecureRandom random; - - private int hLen; - private int mgfhLen; - private int sLen; - private int emBits; - private byte[] salt; - private byte[] mDash; - private byte[] block; - private byte trailer; - - /** - * basic constructor - * - * @param cipher the asymmetric cipher to use. - * @param digest the digest to use. - * @param sLen the length of the salt to use (in bytes). - */ - public PSSSigner( - AsymmetricBlockCipher cipher, - Digest digest, - int sLen) - { - this(cipher, digest, sLen, TRAILER_IMPLICIT); - } - - public PSSSigner( - AsymmetricBlockCipher cipher, - Digest contentDigest, - Digest mgfDigest, - int sLen) - { - this(cipher, contentDigest, mgfDigest, sLen, TRAILER_IMPLICIT); - } - - public PSSSigner( - AsymmetricBlockCipher cipher, - Digest digest, - int sLen, - byte trailer) - { - this(cipher, digest, digest, sLen, trailer); - } - - public PSSSigner( - AsymmetricBlockCipher cipher, - Digest contentDigest, - Digest mgfDigest, - int sLen, - byte trailer) - { - this.cipher = cipher; - this.contentDigest = contentDigest; - this.mgfDigest = mgfDigest; - this.hLen = contentDigest.getDigestSize(); - this.mgfhLen = mgfDigest.getDigestSize(); - this.sLen = sLen; - this.salt = new byte[sLen]; - this.mDash = new byte[8 + sLen + hLen]; - this.trailer = trailer; - } - - public void init( - boolean forSigning, - CipherParameters param) - { - CipherParameters params; - - if (param instanceof ParametersWithRandom) - { - ParametersWithRandom p = (ParametersWithRandom)param; - - params = p.getParameters(); - random = p.getRandom(); - } - else - { - params = param; - if (forSigning) - { - random = new SecureRandom(); - } - } - - cipher.init(forSigning, params); - - RSAKeyParameters kParam; - - if (params instanceof RSABlindingParameters) - { - kParam = ((RSABlindingParameters)params).getPublicKey(); - } - else - { - kParam = (RSAKeyParameters)params; - } - - emBits = kParam.getModulus().bitLength() - 1; - - if (emBits < (8 * hLen + 8 * sLen + 9)) - { - throw new IllegalArgumentException("key too small for specified hash and salt lengths"); - } - - block = new byte[(emBits + 7) / 8]; - - reset(); - } - - /** - * clear possible sensitive data - */ - private void clearBlock( - byte[] block) - { - for (int i = 0; i != block.length; i++) - { - block[i] = 0; - } - } - - /** - * update the internal digest with the byte b - */ - public void update( - byte b) - { - contentDigest.update(b); - } - - /** - * update the internal digest with the byte array in - */ - public void update( - byte[] in, - int off, - int len) - { - contentDigest.update(in, off, len); - } - - /** - * reset the internal state - */ - public void reset() - { - contentDigest.reset(); - } - - /** - * generate a signature for the message we've been loaded with using - * the key we were initialised with. - */ - public byte[] generateSignature() - throws CryptoException, DataLengthException - { - contentDigest.doFinal(mDash, mDash.length - hLen - sLen); - - if (sLen != 0) - { - random.nextBytes(salt); - - System.arraycopy(salt, 0, mDash, mDash.length - sLen, sLen); - } - - byte[] h = new byte[hLen]; - - contentDigest.update(mDash, 0, mDash.length); - - contentDigest.doFinal(h, 0); - - block[block.length - sLen - 1 - hLen - 1] = 0x01; - System.arraycopy(salt, 0, block, block.length - sLen - hLen - 1, sLen); - - byte[] dbMask = maskGeneratorFunction1(h, 0, h.length, block.length - hLen - 1); - for (int i = 0; i != dbMask.length; i++) - { - block[i] ^= dbMask[i]; - } - - block[0] &= (0xff >> ((block.length * 8) - emBits)); - - System.arraycopy(h, 0, block, block.length - hLen - 1, hLen); - - block[block.length - 1] = trailer; - - byte[] b = cipher.processBlock(block, 0, block.length); - - clearBlock(block); - - return b; - } - - /** - * return true if the internal state represents the signature described - * in the passed in array. - */ - public boolean verifySignature( - byte[] signature) - { - contentDigest.doFinal(mDash, mDash.length - hLen - sLen); - - try - { - byte[] b = cipher.processBlock(signature, 0, signature.length); - System.arraycopy(b, 0, block, block.length - b.length, b.length); - } - catch (Exception e) - { - return false; - } - - if (block[block.length - 1] != trailer) - { - clearBlock(block); - return false; - } - - byte[] dbMask = maskGeneratorFunction1(block, block.length - hLen - 1, hLen, block.length - hLen - 1); - - for (int i = 0; i != dbMask.length; i++) - { - block[i] ^= dbMask[i]; - } - - block[0] &= (0xff >> ((block.length * 8) - emBits)); - - for (int i = 0; i != block.length - hLen - sLen - 2; i++) - { - if (block[i] != 0) - { - clearBlock(block); - return false; - } - } - - if (block[block.length - hLen - sLen - 2] != 0x01) - { - clearBlock(block); - return false; - } - - System.arraycopy(block, block.length - sLen - hLen - 1, mDash, mDash.length - sLen, sLen); - - contentDigest.update(mDash, 0, mDash.length); - contentDigest.doFinal(mDash, mDash.length - hLen); - - for (int i = block.length - hLen - 1, j = mDash.length - hLen; - j != mDash.length; i++, j++) - { - if ((block[i] ^ mDash[j]) != 0) - { - clearBlock(mDash); - clearBlock(block); - return false; - } - } - - clearBlock(mDash); - clearBlock(block); - - return true; - } - - /** - * int to octet string. - */ - private void ItoOSP( - int i, - byte[] sp) - { - sp[0] = (byte)(i >>> 24); - sp[1] = (byte)(i >>> 16); - sp[2] = (byte)(i >>> 8); - sp[3] = (byte)(i >>> 0); - } - - /** - * mask generator function, as described in PKCS1v2. - */ - private byte[] maskGeneratorFunction1( - byte[] Z, - int zOff, - int zLen, - int length) - { - byte[] mask = new byte[length]; - byte[] hashBuf = new byte[mgfhLen]; - byte[] C = new byte[4]; - int counter = 0; - - mgfDigest.reset(); - - while (counter < (length / mgfhLen)) - { - ItoOSP(counter, C); - - mgfDigest.update(Z, zOff, zLen); - mgfDigest.update(C, 0, C.length); - mgfDigest.doFinal(hashBuf, 0); - - System.arraycopy(hashBuf, 0, mask, counter * mgfhLen, mgfhLen); - - counter++; - } - - if ((counter * mgfhLen) < length) - { - ItoOSP(counter, C); - - mgfDigest.update(Z, zOff, zLen); - mgfDigest.update(C, 0, C.length); - mgfDigest.doFinal(hashBuf, 0); - - System.arraycopy(hashBuf, 0, mask, counter * mgfhLen, mask.length - (counter * mgfhLen)); - } - - return mask; - } -} diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/signers/RSADigestSigner.java b/bcprov/src/main/java/org/bouncycastle/crypto/signers/RSADigestSigner.java index 69d9918..a8ef959 100644 --- a/bcprov/src/main/java/org/bouncycastle/crypto/signers/RSADigestSigner.java +++ b/bcprov/src/main/java/org/bouncycastle/crypto/signers/RSADigestSigner.java @@ -39,9 +39,11 @@ public class RSADigestSigner */ static { - oidMap.put("RIPEMD128", TeleTrusTObjectIdentifiers.ripemd128); - oidMap.put("RIPEMD160", TeleTrusTObjectIdentifiers.ripemd160); - oidMap.put("RIPEMD256", TeleTrusTObjectIdentifiers.ripemd256); + // BEGIN android-removed + // oidMap.put("RIPEMD128", TeleTrusTObjectIdentifiers.ripemd128); + // oidMap.put("RIPEMD160", TeleTrusTObjectIdentifiers.ripemd160); + // oidMap.put("RIPEMD256", TeleTrusTObjectIdentifiers.ripemd256); + // END android-removed oidMap.put("SHA-1", X509ObjectIdentifiers.id_SHA1); oidMap.put("SHA-224", NISTObjectIdentifiers.id_sha224); @@ -51,8 +53,10 @@ public class RSADigestSigner oidMap.put("SHA-512/224", NISTObjectIdentifiers.id_sha512_224); oidMap.put("SHA-512/256", NISTObjectIdentifiers.id_sha512_256); - oidMap.put("MD2", PKCSObjectIdentifiers.md2); - oidMap.put("MD4", PKCSObjectIdentifiers.md4); + // BEGIN android-removed + // oidMap.put("MD2", PKCSObjectIdentifiers.md2); + // oidMap.put("MD4", PKCSObjectIdentifiers.md4); + // END android-removed oidMap.put("MD5", PKCSObjectIdentifiers.md5); } diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/signers/X931Signer.java b/bcprov/src/main/java/org/bouncycastle/crypto/signers/X931Signer.java deleted file mode 100644 index 7197404..0000000 --- a/bcprov/src/main/java/org/bouncycastle/crypto/signers/X931Signer.java +++ /dev/null @@ -1,269 +0,0 @@ -package org.bouncycastle.crypto.signers; - -import java.math.BigInteger; -import java.util.Hashtable; - -import org.bouncycastle.crypto.AsymmetricBlockCipher; -import org.bouncycastle.crypto.CipherParameters; -import org.bouncycastle.crypto.CryptoException; -import org.bouncycastle.crypto.Digest; -import org.bouncycastle.crypto.InvalidCipherTextException; -import org.bouncycastle.crypto.Signer; -import org.bouncycastle.crypto.SignerWithRecovery; -import org.bouncycastle.crypto.params.RSAKeyParameters; -import org.bouncycastle.util.Arrays; -import org.bouncycastle.util.BigIntegers; -import org.bouncycastle.util.Integers; -import org.bouncycastle.util.encoders.Hex; - -/** - * X9.31-1998 - signing using a hash. - * <p> - * The message digest hash, H, is encapsulated to form a byte string as follows - * <pre> - * EB = 06 || PS || 0xBA || H || TRAILER - * </pre> - * where PS is a string of bytes all of value 0xBB of length such that |EB|=|n|, and TRAILER is the ISO/IEC 10118 part number†for the digest. The byte string, EB, is converted to an integer value, the message representative, f. - */ -public class X931Signer - implements Signer -{ - static final public int TRAILER_IMPLICIT = 0xBC; - static final public int TRAILER_RIPEMD160 = 0x31CC; - static final public int TRAILER_RIPEMD128 = 0x32CC; - static final public int TRAILER_SHA1 = 0x33CC; - static final public int TRAILER_SHA256 = 0x34CC; - static final public int TRAILER_SHA512 = 0x35CC; - static final public int TRAILER_SHA384 = 0x36CC; - static final public int TRAILER_WHIRLPOOL = 0x37CC; - static final public int TRAILER_SHA224 = 0x38CC; - - private static Hashtable trailerMap = new Hashtable(); - - static - { - trailerMap.put("RIPEMD128", Integers.valueOf(TRAILER_RIPEMD128)); - trailerMap.put("RIPEMD160", Integers.valueOf(TRAILER_RIPEMD160)); - - trailerMap.put("SHA-1", Integers.valueOf(TRAILER_SHA1)); - trailerMap.put("SHA-224", Integers.valueOf(TRAILER_SHA224)); - trailerMap.put("SHA-256", Integers.valueOf(TRAILER_SHA256)); - trailerMap.put("SHA-384", Integers.valueOf(TRAILER_SHA384)); - trailerMap.put("SHA-512", Integers.valueOf(TRAILER_SHA512)); - - trailerMap.put("Whirlpool", Integers.valueOf(TRAILER_WHIRLPOOL)); - } - - private Digest digest; - private AsymmetricBlockCipher cipher; - private RSAKeyParameters kParam; - - private int trailer; - private int keyBits; - private byte[] block; - - /** - * Generate a signer for the with either implicit or explicit trailers - * for ISO9796-2. - * - * @param cipher base cipher to use for signature creation/verification - * @param digest digest to use. - * @param implicit whether or not the trailer is implicit or gives the hash. - */ - public X931Signer( - AsymmetricBlockCipher cipher, - Digest digest, - boolean implicit) - { - this.cipher = cipher; - this.digest = digest; - - if (implicit) - { - trailer = TRAILER_IMPLICIT; - } - else - { - Integer trailerObj = (Integer)trailerMap.get(digest.getAlgorithmName()); - - if (trailerObj != null) - { - trailer = trailerObj.intValue(); - } - else - { - throw new IllegalArgumentException("no valid trailer for digest"); - } - } - } - - /** - * Constructor for a signer with an explicit digest trailer. - * - * @param cipher cipher to use. - * @param digest digest to sign with. - */ - public X931Signer( - AsymmetricBlockCipher cipher, - Digest digest) - { - this(cipher, digest, false); - } - - public void init( - boolean forSigning, - CipherParameters param) - { - kParam = (RSAKeyParameters)param; - - cipher.init(forSigning, kParam); - - keyBits = kParam.getModulus().bitLength(); - - block = new byte[(keyBits + 7) / 8]; - - reset(); - } - - /** - * clear possible sensitive data - */ - private void clearBlock( - byte[] block) - { - for (int i = 0; i != block.length; i++) - { - block[i] = 0; - } - } - - /** - * update the internal digest with the byte b - */ - public void update( - byte b) - { - digest.update(b); - } - - /** - * update the internal digest with the byte array in - */ - public void update( - byte[] in, - int off, - int len) - { - digest.update(in, off, len); - } - - /** - * reset the internal state - */ - public void reset() - { - digest.reset(); - } - - /** - * generate a signature for the loaded message using the key we were - * initialised with. - */ - public byte[] generateSignature() - throws CryptoException - { - createSignatureBlock(); - - BigInteger t = new BigInteger(1, cipher.processBlock(block, 0, block.length)); - BigInteger nSubT = kParam.getModulus().subtract(t); - - clearBlock(block); - - BigInteger v = kParam.getModulus().shiftRight(2); - - if (t.compareTo(nSubT) > 0) - { - return BigIntegers.asUnsignedByteArray((kParam.getModulus().bitLength() + 7) / 8, nSubT); - } - else - { - return BigIntegers.asUnsignedByteArray((kParam.getModulus().bitLength() + 7) / 8, t); - } - } - - private void createSignatureBlock() - { - int digSize = digest.getDigestSize(); - - int delta; - - if (trailer == TRAILER_IMPLICIT) - { - delta = block.length - digSize - 1; - digest.doFinal(block, delta); - block[block.length - 1] = (byte)TRAILER_IMPLICIT; - } - else - { - delta = block.length - digSize - 2; - digest.doFinal(block, delta); - block[block.length - 2] = (byte)(trailer >>> 8); - block[block.length - 1] = (byte)trailer; - } - - block[0] = 0x6b; - for (int i = delta - 2; i != 0; i--) - { - block[i] = (byte)0xbb; - } - block[delta - 1] = (byte)0xba; - } - - /** - * return true if the signature represents a ISO9796-2 signature - * for the passed in message. - */ - public boolean verifySignature( - byte[] signature) - { - try - { - block = cipher.processBlock(signature, 0, signature.length); - } - catch (Exception e) - { - return false; - } - - BigInteger t = new BigInteger(block); - BigInteger f; - - if (t.mod(BigInteger.valueOf(16)).equals(BigInteger.valueOf(12))) - { - f = t; - } - else - { - t = kParam.getModulus().subtract(t); - if (t.mod(BigInteger.valueOf(16)).equals(BigInteger.valueOf(12))) - { - f = t; - } - else - { - return false; - } - } - - createSignatureBlock(); - - byte[] fBlock = BigIntegers.asUnsignedByteArray(block.length, f); - - boolean rv = Arrays.constantTimeAreEqual(block, fBlock); - - clearBlock(block); - clearBlock(fBlock); - - return rv; - } -} diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/signers/package.html b/bcprov/src/main/java/org/bouncycastle/crypto/signers/package.html deleted file mode 100644 index 151d3d5..0000000 --- a/bcprov/src/main/java/org/bouncycastle/crypto/signers/package.html +++ /dev/null @@ -1,5 +0,0 @@ -<html> -<body bgcolor="#ffffff"> -Basic signers. -</body> -</html> |