what-the-bank/sources/org/bouncycastle/crypto/signers/ISO9796d2Signer.java

372 lines
14 KiB
Java

package org.bouncycastle.crypto.signers;
import com.google.common.primitives.UnsignedBytes;
import net.sf.scuba.smartcards.ISO7816;
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;
/* loaded from: classes6.dex */
public class ISO9796d2Signer implements SignerWithRecovery {
public static final int TRAILER_IMPLICIT = 188;
public static final int TRAILER_RIPEMD128 = 13004;
public static final int TRAILER_RIPEMD160 = 12748;
public static final int TRAILER_SHA1 = 13260;
public static final int TRAILER_SHA256 = 13516;
public static final int TRAILER_SHA384 = 14028;
public static final int TRAILER_SHA512 = 13772;
public static final int TRAILER_WHIRLPOOL = 14284;
private byte[] block;
private AsymmetricBlockCipher cipher;
private Digest digest;
private boolean fullMessage;
private int keyBits;
private byte[] mBuf;
private int messageLength;
private byte[] preBlock;
private byte[] preSig;
private byte[] recoveredMessage;
private int trailer;
@Override // org.bouncycastle.crypto.Signer
public boolean verifySignature(byte[] bArr) {
byte[] processBlock;
int i;
byte[] bArr2 = this.preSig;
if (bArr2 == null) {
try {
processBlock = this.cipher.processBlock(bArr, 0, bArr.length);
} catch (Exception unused) {
return false;
}
} else {
if (!Arrays.areEqual(bArr2, bArr)) {
throw new IllegalStateException("updateWithRecoveredMessage called on different signature");
}
processBlock = this.preBlock;
this.preSig = null;
this.preBlock = null;
}
if (((processBlock[0] & ISO7816.INS_GET_RESPONSE) ^ 64) == 0 && ((processBlock[processBlock.length - 1] & 15) ^ 12) == 0) {
if (((processBlock[processBlock.length - 1] & UnsignedBytes.MAX_VALUE) ^ 188) == 0) {
i = 1;
} else {
i = 2;
int i2 = ((processBlock[processBlock.length - 2] & UnsignedBytes.MAX_VALUE) << 8) | (processBlock[processBlock.length - 1] & UnsignedBytes.MAX_VALUE);
Integer trailer = ISOTrailers.getTrailer(this.digest);
if (trailer == null) {
throw new IllegalArgumentException("unrecognised hash in signature");
}
if (i2 != trailer.intValue()) {
throw new IllegalStateException("signer initialised with wrong digest for trailer ".concat(String.valueOf(i2)));
}
}
int i3 = 0;
while (i3 != processBlock.length && ((processBlock[i3] & 15) ^ 10) != 0) {
i3++;
}
int i4 = i3 + 1;
int digestSize = this.digest.getDigestSize();
byte[] bArr3 = new byte[digestSize];
int length = (processBlock.length - i) - digestSize;
int i5 = length - i4;
if (i5 <= 0) {
return returnFalse(processBlock);
}
if ((processBlock[0] & 32) == 0) {
this.fullMessage = true;
if (this.messageLength > i5) {
return returnFalse(processBlock);
}
this.digest.reset();
this.digest.update(processBlock, i4, i5);
this.digest.doFinal(bArr3, 0);
boolean z = true;
for (int i6 = 0; i6 != digestSize; i6++) {
int i7 = length + i6;
byte b = (byte) (processBlock[i7] ^ bArr3[i6]);
processBlock[i7] = b;
if (b != 0) {
z = false;
}
}
if (!z) {
return returnFalse(processBlock);
}
byte[] bArr4 = new byte[i5];
this.recoveredMessage = bArr4;
System.arraycopy(processBlock, i4, bArr4, 0, i5);
} else {
this.fullMessage = false;
this.digest.doFinal(bArr3, 0);
boolean z2 = true;
for (int i8 = 0; i8 != digestSize; i8++) {
int i9 = length + i8;
byte b2 = (byte) (processBlock[i9] ^ bArr3[i8]);
processBlock[i9] = b2;
if (b2 != 0) {
z2 = false;
}
}
if (!z2) {
return returnFalse(processBlock);
}
byte[] bArr5 = new byte[i5];
this.recoveredMessage = bArr5;
System.arraycopy(processBlock, i4, bArr5, 0, i5);
}
if (this.messageLength != 0 && !isSameAs(this.mBuf, this.recoveredMessage)) {
return returnFalse(processBlock);
}
clearBlock(this.mBuf);
clearBlock(processBlock);
return true;
}
return returnFalse(processBlock);
}
@Override // org.bouncycastle.crypto.SignerWithRecovery
public void updateWithRecoveredMessage(byte[] bArr) throws InvalidCipherTextException {
int i;
byte[] processBlock = this.cipher.processBlock(bArr, 0, bArr.length);
if (((processBlock[0] & ISO7816.INS_GET_RESPONSE) ^ 64) != 0) {
throw new InvalidCipherTextException("malformed signature");
}
if (((processBlock[processBlock.length - 1] & 15) ^ 12) != 0) {
throw new InvalidCipherTextException("malformed signature");
}
if (((processBlock[processBlock.length - 1] & UnsignedBytes.MAX_VALUE) ^ 188) == 0) {
i = 1;
} else {
i = 2;
int i2 = ((processBlock[processBlock.length - 2] & UnsignedBytes.MAX_VALUE) << 8) | (processBlock[processBlock.length - 1] & UnsignedBytes.MAX_VALUE);
Integer trailer = ISOTrailers.getTrailer(this.digest);
if (trailer == null) {
throw new IllegalArgumentException("unrecognised hash in signature");
}
if (i2 != trailer.intValue()) {
throw new IllegalStateException("signer initialised with wrong digest for trailer ".concat(String.valueOf(i2)));
}
}
int i3 = 0;
while (i3 != processBlock.length && ((processBlock[i3] & 15) ^ 10) != 0) {
i3++;
}
int i4 = i3 + 1;
int length = ((processBlock.length - i) - this.digest.getDigestSize()) - i4;
if (length <= 0) {
throw new InvalidCipherTextException("malformed block");
}
if ((processBlock[0] & 32) == 0) {
this.fullMessage = true;
byte[] bArr2 = new byte[length];
this.recoveredMessage = bArr2;
System.arraycopy(processBlock, i4, bArr2, 0, length);
} else {
this.fullMessage = false;
byte[] bArr3 = new byte[length];
this.recoveredMessage = bArr3;
System.arraycopy(processBlock, i4, bArr3, 0, length);
}
this.preSig = bArr;
this.preBlock = processBlock;
Digest digest = this.digest;
byte[] bArr4 = this.recoveredMessage;
digest.update(bArr4, 0, bArr4.length);
byte[] bArr5 = this.recoveredMessage;
this.messageLength = bArr5.length;
System.arraycopy(bArr5, 0, this.mBuf, 0, bArr5.length);
}
@Override // org.bouncycastle.crypto.Signer
public void update(byte[] bArr, int i, int i2) {
while (i2 > 0 && this.messageLength < this.mBuf.length) {
update(bArr[i]);
i++;
i2--;
}
this.digest.update(bArr, i, i2);
this.messageLength += i2;
}
@Override // org.bouncycastle.crypto.Signer
public void update(byte b) {
this.digest.update(b);
int i = this.messageLength;
byte[] bArr = this.mBuf;
if (i < bArr.length) {
bArr[i] = b;
}
this.messageLength = i + 1;
}
@Override // org.bouncycastle.crypto.Signer
public void reset() {
this.digest.reset();
this.messageLength = 0;
clearBlock(this.mBuf);
byte[] bArr = this.recoveredMessage;
if (bArr != null) {
clearBlock(bArr);
}
this.recoveredMessage = null;
this.fullMessage = false;
if (this.preSig != null) {
this.preSig = null;
clearBlock(this.preBlock);
this.preBlock = null;
}
}
@Override // org.bouncycastle.crypto.Signer
public void init(boolean z, CipherParameters cipherParameters) {
RSAKeyParameters rSAKeyParameters = (RSAKeyParameters) cipherParameters;
this.cipher.init(z, rSAKeyParameters);
int bitLength = rSAKeyParameters.getModulus().bitLength();
this.keyBits = bitLength;
this.block = new byte[(bitLength + 7) / 8];
if (this.trailer == 188) {
this.mBuf = new byte[(r2 - this.digest.getDigestSize()) - 2];
} else {
this.mBuf = new byte[(r2 - this.digest.getDigestSize()) - 3];
}
reset();
}
@Override // org.bouncycastle.crypto.SignerWithRecovery
public boolean hasFullMessage() {
return this.fullMessage;
}
@Override // org.bouncycastle.crypto.SignerWithRecovery
public byte[] getRecoveredMessage() {
return this.recoveredMessage;
}
@Override // org.bouncycastle.crypto.Signer
public byte[] generateSignature() throws CryptoException {
int length;
int i;
int i2;
int i3;
int digestSize = this.digest.getDigestSize();
if (this.trailer == 188) {
byte[] bArr = this.block;
length = (bArr.length - digestSize) - 1;
this.digest.doFinal(bArr, length);
byte[] bArr2 = this.block;
bArr2[bArr2.length - 1] = PSSSigner.TRAILER_IMPLICIT;
i = 8;
} else {
byte[] bArr3 = this.block;
length = (bArr3.length - digestSize) - 2;
this.digest.doFinal(bArr3, length);
byte[] bArr4 = this.block;
int length2 = bArr4.length;
int i4 = this.trailer;
bArr4[length2 - 2] = (byte) (i4 >>> 8);
bArr4[bArr4.length - 1] = (byte) i4;
i = 16;
}
int i5 = this.messageLength;
int i6 = ((((digestSize + i5) << 3) + i) + 4) - this.keyBits;
if (i6 > 0) {
int i7 = i5 - ((i6 + 7) / 8);
i2 = length - i7;
System.arraycopy(this.mBuf, 0, this.block, i2, i7);
this.recoveredMessage = new byte[i7];
i3 = 96;
} else {
i2 = length - i5;
System.arraycopy(this.mBuf, 0, this.block, i2, i5);
this.recoveredMessage = new byte[this.messageLength];
i3 = 64;
}
int i8 = i2 - 1;
if (i8 > 0) {
for (int i9 = i8; i9 != 0; i9--) {
this.block[i9] = -69;
}
byte[] bArr5 = this.block;
bArr5[i8] = (byte) (bArr5[i8] ^ 1);
bArr5[0] = 11;
bArr5[0] = (byte) (i3 | 11);
} else {
byte[] bArr6 = this.block;
bArr6[0] = 10;
bArr6[0] = (byte) (i3 | 10);
}
AsymmetricBlockCipher asymmetricBlockCipher = this.cipher;
byte[] bArr7 = this.block;
byte[] processBlock = asymmetricBlockCipher.processBlock(bArr7, 0, bArr7.length);
this.fullMessage = (i3 & 32) == 0;
byte[] bArr8 = this.mBuf;
byte[] bArr9 = this.recoveredMessage;
System.arraycopy(bArr8, 0, bArr9, 0, bArr9.length);
clearBlock(this.mBuf);
clearBlock(this.block);
return processBlock;
}
private boolean returnFalse(byte[] bArr) {
clearBlock(this.mBuf);
clearBlock(bArr);
return false;
}
private boolean isSameAs(byte[] bArr, byte[] bArr2) {
boolean z;
int i = this.messageLength;
byte[] bArr3 = this.mBuf;
if (i > bArr3.length) {
z = bArr3.length <= bArr2.length;
for (int i2 = 0; i2 != this.mBuf.length; i2++) {
if (bArr[i2] != bArr2[i2]) {
z = false;
}
}
} else {
z = i == bArr2.length;
for (int i3 = 0; i3 != bArr2.length; i3++) {
if (bArr[i3] != bArr2[i3]) {
z = false;
}
}
}
return z;
}
private void clearBlock(byte[] bArr) {
for (int i = 0; i != bArr.length; i++) {
bArr[i] = 0;
}
}
public ISO9796d2Signer(AsymmetricBlockCipher asymmetricBlockCipher, Digest digest, boolean z) {
int intValue;
this.cipher = asymmetricBlockCipher;
this.digest = digest;
if (z) {
intValue = 188;
} else {
Integer trailer = ISOTrailers.getTrailer(digest);
if (trailer == null) {
StringBuilder sb = new StringBuilder("no valid trailer for digest: ");
sb.append(digest.getAlgorithmName());
throw new IllegalArgumentException(sb.toString());
}
intValue = trailer.intValue();
}
this.trailer = intValue;
}
public ISO9796d2Signer(AsymmetricBlockCipher asymmetricBlockCipher, Digest digest) {
this(asymmetricBlockCipher, digest, false);
}
}