what-the-bank/sources/org/bouncycastle/crypto/encodings/PKCS1Encoding.java

223 lines
8.6 KiB
Java
Raw Permalink Normal View History

2024-07-27 18:17:47 +07:00
package org.bouncycastle.crypto.encodings;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.SecureRandom;
import org.bouncycastle.crypto.AsymmetricBlockCipher;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import org.bouncycastle.crypto.params.ParametersWithRandom;
/* loaded from: classes6.dex */
public class PKCS1Encoding implements AsymmetricBlockCipher {
private static final int HEADER_LENGTH = 10;
public static final String NOT_STRICT_LENGTH_ENABLED_PROPERTY = "org.bouncycastle.pkcs1.not_strict";
public static final String STRICT_LENGTH_ENABLED_PROPERTY = "org.bouncycastle.pkcs1.strict";
private AsymmetricBlockCipher engine;
private byte[] fallback;
private boolean forEncryption;
private boolean forPrivateKey;
private int pLen;
private SecureRandom random;
private boolean useStrictLength;
@Override // org.bouncycastle.crypto.AsymmetricBlockCipher
public byte[] processBlock(byte[] bArr, int i, int i2) throws InvalidCipherTextException {
return this.forEncryption ? encodeBlock(bArr, i, i2) : decodeBlock(bArr, i, i2);
}
@Override // org.bouncycastle.crypto.AsymmetricBlockCipher
public void init(boolean z, CipherParameters cipherParameters) {
AsymmetricKeyParameter asymmetricKeyParameter;
if (cipherParameters instanceof ParametersWithRandom) {
ParametersWithRandom parametersWithRandom = (ParametersWithRandom) cipherParameters;
this.random = parametersWithRandom.getRandom();
asymmetricKeyParameter = (AsymmetricKeyParameter) parametersWithRandom.getParameters();
} else {
asymmetricKeyParameter = (AsymmetricKeyParameter) cipherParameters;
if (!asymmetricKeyParameter.isPrivate() && z) {
this.random = new SecureRandom();
}
}
this.engine.init(z, cipherParameters);
this.forPrivateKey = asymmetricKeyParameter.isPrivate();
this.forEncryption = z;
}
public AsymmetricBlockCipher getUnderlyingCipher() {
return this.engine;
}
@Override // org.bouncycastle.crypto.AsymmetricBlockCipher
public int getOutputBlockSize() {
int outputBlockSize = this.engine.getOutputBlockSize();
return this.forEncryption ? outputBlockSize : outputBlockSize - 10;
}
@Override // org.bouncycastle.crypto.AsymmetricBlockCipher
public int getInputBlockSize() {
int inputBlockSize = this.engine.getInputBlockSize();
return this.forEncryption ? inputBlockSize - 10 : inputBlockSize;
}
private boolean useStrict() {
String str = (String) AccessController.doPrivileged(new PrivilegedAction(this) { // from class: org.bouncycastle.crypto.encodings.PKCS1Encoding.1
final PKCS1Encoding this$0;
@Override // java.security.PrivilegedAction
public Object run() {
return System.getProperty(PKCS1Encoding.STRICT_LENGTH_ENABLED_PROPERTY);
}
{
this.this$0 = this;
}
});
return ((String) AccessController.doPrivileged(new PrivilegedAction(this) { // from class: org.bouncycastle.crypto.encodings.PKCS1Encoding.2
final PKCS1Encoding this$0;
@Override // java.security.PrivilegedAction
public Object run() {
return System.getProperty(PKCS1Encoding.NOT_STRICT_LENGTH_ENABLED_PROPERTY);
}
{
this.this$0 = this;
}
})) != null ? !r1.equals("true") : str == null || str.equals("true");
}
private byte[] encodeBlock(byte[] bArr, int i, int i2) throws InvalidCipherTextException {
if (i2 > getInputBlockSize()) {
throw new IllegalArgumentException("input data too large");
}
int inputBlockSize = this.engine.getInputBlockSize();
byte[] bArr2 = new byte[inputBlockSize];
if (this.forPrivateKey) {
bArr2[0] = 1;
for (int i3 = 1; i3 != (inputBlockSize - i2) - 1; i3++) {
bArr2[i3] = -1;
}
} else {
this.random.nextBytes(bArr2);
bArr2[0] = 2;
for (int i4 = 1; i4 != (inputBlockSize - i2) - 1; i4++) {
while (bArr2[i4] == 0) {
bArr2[i4] = (byte) this.random.nextInt();
}
}
}
int i5 = inputBlockSize - i2;
bArr2[i5 - 1] = 0;
System.arraycopy(bArr, i, bArr2, i5, i2);
return this.engine.processBlock(bArr2, 0, inputBlockSize);
}
private byte[] decodeBlockOrRandom(byte[] bArr, int i, int i2) throws InvalidCipherTextException {
if (!this.forPrivateKey) {
throw new InvalidCipherTextException("sorry, this method is only for decryption, not for signing");
}
byte[] processBlock = this.engine.processBlock(bArr, i, i2);
byte[] bArr2 = this.fallback;
if (bArr2 == null) {
bArr2 = new byte[this.pLen];
this.random.nextBytes(bArr2);
}
if (processBlock.length < getOutputBlockSize()) {
throw new InvalidCipherTextException("block truncated");
}
if (this.useStrictLength && processBlock.length != this.engine.getOutputBlockSize()) {
throw new InvalidCipherTextException("block incorrect size");
}
int checkPkcs1Encoding = checkPkcs1Encoding(processBlock, this.pLen);
byte[] bArr3 = new byte[this.pLen];
int i3 = 0;
while (true) {
int i4 = this.pLen;
if (i3 >= i4) {
return bArr3;
}
bArr3[i3] = (byte) ((processBlock[(processBlock.length - i4) + i3] & (~checkPkcs1Encoding)) | (bArr2[i3] & checkPkcs1Encoding));
i3++;
}
}
private byte[] decodeBlock(byte[] bArr, int i, int i2) throws InvalidCipherTextException {
byte b;
if (this.pLen != -1) {
return decodeBlockOrRandom(bArr, i, i2);
}
byte[] processBlock = this.engine.processBlock(bArr, i, i2);
if (processBlock.length < getOutputBlockSize()) {
throw new InvalidCipherTextException("block truncated");
}
byte b2 = processBlock[0];
if (this.forPrivateKey) {
if (b2 != 2) {
throw new InvalidCipherTextException("unknown block type");
}
} else if (b2 != 1) {
throw new InvalidCipherTextException("unknown block type");
}
if (this.useStrictLength && processBlock.length != this.engine.getOutputBlockSize()) {
throw new InvalidCipherTextException("block incorrect size");
}
int i3 = 1;
while (i3 != processBlock.length && (b = processBlock[i3]) != 0) {
if (b2 == 1 && b != -1) {
throw new InvalidCipherTextException("block padding incorrect");
}
i3++;
}
int i4 = i3 + 1;
if (i4 > processBlock.length || i4 < 10) {
throw new InvalidCipherTextException("no data in block");
}
int length = processBlock.length - i4;
byte[] bArr2 = new byte[length];
System.arraycopy(processBlock, i4, bArr2, 0, length);
return bArr2;
}
private static int checkPkcs1Encoding(byte[] bArr, int i) {
int i2 = bArr[0] ^ 2;
int length = bArr.length;
int i3 = i + 1;
for (int i4 = 1; i4 < length - i3; i4++) {
byte b = bArr[i4];
int i5 = b | (b >> 1);
int i6 = i5 | (i5 >> 2);
i2 |= ((i6 | (i6 >> 4)) & 1) - 1;
}
int i7 = bArr[bArr.length - i3] | i2;
int i8 = i7 | (i7 >> 1);
int i9 = i8 | (i8 >> 2);
return ~(((i9 | (i9 >> 4)) & 1) - 1);
}
public PKCS1Encoding(AsymmetricBlockCipher asymmetricBlockCipher, byte[] bArr) {
this.pLen = -1;
this.fallback = null;
this.engine = asymmetricBlockCipher;
this.useStrictLength = useStrict();
this.fallback = bArr;
this.pLen = bArr.length;
}
public PKCS1Encoding(AsymmetricBlockCipher asymmetricBlockCipher, int i) {
this.pLen = -1;
this.fallback = null;
this.engine = asymmetricBlockCipher;
this.useStrictLength = useStrict();
this.pLen = i;
}
public PKCS1Encoding(AsymmetricBlockCipher asymmetricBlockCipher) {
this.pLen = -1;
this.fallback = null;
this.engine = asymmetricBlockCipher;
this.useStrictLength = useStrict();
}
}