what-the-bank/sources/org/bouncycastle/crypto/tls/TlsClientProtocol.java

455 lines
22 KiB
Java
Raw Permalink Normal View History

2024-07-27 18:17:47 +07:00
package org.bouncycastle.crypto.tls;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.SecureRandom;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
import org.bouncycastle.crypto.tls.TlsProtocol;
import org.bouncycastle.util.Arrays;
/* loaded from: classes6.dex */
public class TlsClientProtocol extends TlsProtocol {
protected TlsAuthentication authentication;
protected CertificateRequest certificateRequest;
protected CertificateStatus certificateStatus;
protected TlsKeyExchange keyExchange;
protected byte[] selectedSessionID;
protected TlsClient tlsClient;
TlsClientContextImpl tlsClientContext;
protected void sendClientKeyExchangeMessage() throws IOException {
TlsProtocol.HandshakeMessage handshakeMessage = new TlsProtocol.HandshakeMessage(this, (short) 16);
this.keyExchange.generateClientKeyExchange(handshakeMessage);
handshakeMessage.writeToRecordStream();
}
protected void sendClientHelloMessage() throws IOException {
this.recordStream.setWriteVersion(this.tlsClient.getClientHelloRecordLayerVersion());
ProtocolVersion clientVersion = this.tlsClient.getClientVersion();
if (clientVersion.isDTLS()) {
throw new TlsFatalAlert((short) 80);
}
getContextAdmin().setClientVersion(clientVersion);
byte[] bArr = TlsUtils.EMPTY_BYTES;
if (this.tlsSession != null && ((bArr = this.tlsSession.getSessionID()) == null || bArr.length > 32)) {
bArr = TlsUtils.EMPTY_BYTES;
}
boolean isFallback = this.tlsClient.isFallback();
this.offeredCipherSuites = this.tlsClient.getCipherSuites();
this.offeredCompressionMethods = this.tlsClient.getCompressionMethods();
if (bArr.length > 0 && this.sessionParameters != null && (!Arrays.contains(this.offeredCipherSuites, this.sessionParameters.getCipherSuite()) || !Arrays.contains(this.offeredCompressionMethods, this.sessionParameters.getCompressionAlgorithm()))) {
bArr = TlsUtils.EMPTY_BYTES;
}
this.clientExtensions = this.tlsClient.getClientExtensions();
TlsProtocol.HandshakeMessage handshakeMessage = new TlsProtocol.HandshakeMessage(this, (short) 1);
TlsUtils.writeVersion(clientVersion, handshakeMessage);
handshakeMessage.write(this.securityParameters.getClientRandom());
TlsUtils.writeOpaque8(bArr, handshakeMessage);
boolean z = TlsUtils.getExtensionData(this.clientExtensions, EXT_RenegotiationInfo) == null;
boolean contains = Arrays.contains(this.offeredCipherSuites, 255);
if (z && (!contains)) {
this.offeredCipherSuites = Arrays.append(this.offeredCipherSuites, 255);
}
if (isFallback && !Arrays.contains(this.offeredCipherSuites, CipherSuite.TLS_FALLBACK_SCSV)) {
this.offeredCipherSuites = Arrays.append(this.offeredCipherSuites, CipherSuite.TLS_FALLBACK_SCSV);
}
TlsUtils.writeUint16ArrayWithUint16Length(this.offeredCipherSuites, handshakeMessage);
TlsUtils.writeUint8ArrayWithUint8Length(this.offeredCompressionMethods, handshakeMessage);
if (this.clientExtensions != null) {
writeExtensions(handshakeMessage, this.clientExtensions);
}
handshakeMessage.writeToRecordStream();
}
protected void sendCertificateVerifyMessage(DigitallySigned digitallySigned) throws IOException {
TlsProtocol.HandshakeMessage handshakeMessage = new TlsProtocol.HandshakeMessage(this, (short) 15);
digitallySigned.encode(handshakeMessage);
handshakeMessage.writeToRecordStream();
}
protected void receiveServerHelloMessage(ByteArrayInputStream byteArrayInputStream) throws IOException {
ProtocolVersion readVersion = TlsUtils.readVersion(byteArrayInputStream);
if (readVersion.isDTLS()) {
throw new TlsFatalAlert((short) 47);
}
if (!readVersion.equals(this.recordStream.getReadVersion())) {
throw new TlsFatalAlert((short) 47);
}
if (!readVersion.isEqualOrEarlierVersionOf(getContext().getClientVersion())) {
throw new TlsFatalAlert((short) 47);
}
this.recordStream.setWriteVersion(readVersion);
getContextAdmin().setServerVersion(readVersion);
this.tlsClient.notifyServerVersion(readVersion);
this.securityParameters.serverRandom = TlsUtils.readFully(32, byteArrayInputStream);
byte[] readOpaque8 = TlsUtils.readOpaque8(byteArrayInputStream);
this.selectedSessionID = readOpaque8;
if (readOpaque8.length > 32) {
throw new TlsFatalAlert((short) 47);
}
this.tlsClient.notifySessionID(readOpaque8);
this.resumedSession = this.selectedSessionID.length > 0 && this.tlsSession != null && Arrays.areEqual(this.selectedSessionID, this.tlsSession.getSessionID());
int readUint16 = TlsUtils.readUint16(byteArrayInputStream);
if (!Arrays.contains(this.offeredCipherSuites, readUint16) || readUint16 == 0 || CipherSuite.isSCSV(readUint16) || !TlsUtils.isValidCipherSuiteForVersion(readUint16, getContext().getServerVersion())) {
throw new TlsFatalAlert((short) 47);
}
this.tlsClient.notifySelectedCipherSuite(readUint16);
short readUint8 = TlsUtils.readUint8(byteArrayInputStream);
if (!Arrays.contains(this.offeredCompressionMethods, readUint8)) {
throw new TlsFatalAlert((short) 47);
}
this.tlsClient.notifySelectedCompressionMethod(readUint8);
this.serverExtensions = readExtensions(byteArrayInputStream);
if (this.serverExtensions != null) {
Enumeration keys = this.serverExtensions.keys();
while (keys.hasMoreElements()) {
Integer num = (Integer) keys.nextElement();
if (!num.equals(EXT_RenegotiationInfo)) {
if (TlsUtils.getExtensionData(this.clientExtensions, num) == null) {
throw new TlsFatalAlert(AlertDescription.unsupported_extension);
}
boolean z = this.resumedSession;
}
}
}
byte[] extensionData = TlsUtils.getExtensionData(this.serverExtensions, EXT_RenegotiationInfo);
if (extensionData != null) {
this.secure_renegotiation = true;
if (!Arrays.constantTimeAreEqual(extensionData, createRenegotiationInfo(TlsUtils.EMPTY_BYTES))) {
throw new TlsFatalAlert((short) 40);
}
}
this.tlsClient.notifySecureRenegotiation(this.secure_renegotiation);
Hashtable hashtable = this.clientExtensions;
Hashtable hashtable2 = this.serverExtensions;
if (this.resumedSession) {
if (readUint16 != this.sessionParameters.getCipherSuite() || readUint8 != this.sessionParameters.getCompressionAlgorithm()) {
throw new TlsFatalAlert((short) 47);
}
hashtable2 = this.sessionParameters.readServerExtensions();
hashtable = null;
}
this.securityParameters.cipherSuite = readUint16;
this.securityParameters.compressionAlgorithm = readUint8;
if (hashtable2 != null) {
boolean hasEncryptThenMACExtension = TlsExtensionsUtils.hasEncryptThenMACExtension(hashtable2);
if (hasEncryptThenMACExtension && !TlsUtils.isBlockCipherSuite(readUint16)) {
throw new TlsFatalAlert((short) 47);
}
this.securityParameters.encryptThenMAC = hasEncryptThenMACExtension;
this.securityParameters.extendedMasterSecret = TlsExtensionsUtils.hasExtendedMasterSecretExtension(hashtable2);
this.securityParameters.maxFragmentLength = processMaxFragmentLengthExtension(hashtable, hashtable2, (short) 47);
this.securityParameters.truncatedHMac = TlsExtensionsUtils.hasTruncatedHMacExtension(hashtable2);
this.allowCertificateStatus = !this.resumedSession && TlsUtils.hasExpectedEmptyExtensionData(hashtable2, TlsExtensionsUtils.EXT_status_request, (short) 47);
this.expectSessionTicket = !this.resumedSession && TlsUtils.hasExpectedEmptyExtensionData(hashtable2, TlsProtocol.EXT_SessionTicket, (short) 47);
}
if (hashtable != null) {
this.tlsClient.processServerExtensions(hashtable2);
}
this.securityParameters.prfAlgorithm = getPRFAlgorithm(getContext(), this.securityParameters.getCipherSuite());
this.securityParameters.verifyDataLength = 12;
}
protected void receiveNewSessionTicketMessage(ByteArrayInputStream byteArrayInputStream) throws IOException {
NewSessionTicket parse = NewSessionTicket.parse(byteArrayInputStream);
assertEmpty(byteArrayInputStream);
this.tlsClient.notifyNewSessionTicket(parse);
}
protected void handleSupplementalData(Vector vector) throws IOException {
this.tlsClient.processServerSupplementalData(vector);
this.connection_state = (short) 3;
TlsKeyExchange keyExchange = this.tlsClient.getKeyExchange();
this.keyExchange = keyExchange;
keyExchange.init(getContext());
}
/* JADX WARN: Failed to find 'out' block for switch in B:26:0x0054. Please report as an issue. */
@Override // org.bouncycastle.crypto.tls.TlsProtocol
protected void handleHandshakeMessage(short s, byte[] bArr) throws IOException {
TlsCredentials clientCredentials;
Certificate certificate;
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bArr);
if (this.resumedSession) {
if (s != 20 || this.connection_state != 2) {
throw new TlsFatalAlert((short) 10);
}
processFinishedMessage(byteArrayInputStream);
this.connection_state = (short) 15;
sendFinishedMessage();
this.connection_state = (short) 13;
this.connection_state = (short) 16;
completeHandshake();
return;
}
if (s == 0) {
assertEmpty(byteArrayInputStream);
if (this.connection_state == 16) {
refuseRenegotiation();
return;
}
return;
}
if (s == 2) {
if (this.connection_state != 1) {
throw new TlsFatalAlert((short) 10);
}
receiveServerHelloMessage(byteArrayInputStream);
this.connection_state = (short) 2;
this.recordStream.notifyHelloComplete();
applyMaxFragmentLengthExtension();
if (this.resumedSession) {
this.securityParameters.masterSecret = Arrays.clone(this.sessionParameters.getMasterSecret());
this.recordStream.setPendingConnectionState(getPeer().getCompression(), getPeer().getCipher());
sendChangeCipherSpecMessage();
return;
} else {
invalidateSession();
byte[] bArr2 = this.selectedSessionID;
if (bArr2.length > 0) {
this.tlsSession = new TlsSessionImpl(bArr2, null);
return;
}
return;
}
}
if (s == 4) {
if (this.connection_state != 13) {
throw new TlsFatalAlert((short) 10);
}
if (!this.expectSessionTicket) {
throw new TlsFatalAlert((short) 10);
}
invalidateSession();
receiveNewSessionTicketMessage(byteArrayInputStream);
this.connection_state = (short) 14;
return;
}
if (s == 20) {
short s2 = this.connection_state;
if (s2 != 13) {
if (s2 != 14) {
throw new TlsFatalAlert((short) 10);
}
} else if (this.expectSessionTicket) {
throw new TlsFatalAlert((short) 10);
}
processFinishedMessage(byteArrayInputStream);
this.connection_state = (short) 15;
this.connection_state = (short) 16;
completeHandshake();
return;
}
if (s == 22) {
if (this.connection_state != 4) {
throw new TlsFatalAlert((short) 10);
}
if (!this.allowCertificateStatus) {
throw new TlsFatalAlert((short) 10);
}
this.certificateStatus = CertificateStatus.parse(byteArrayInputStream);
assertEmpty(byteArrayInputStream);
this.connection_state = (short) 5;
return;
}
if (s == 23) {
if (this.connection_state != 2) {
throw new TlsFatalAlert((short) 10);
}
handleSupplementalData(readSupplementalDataMessage(byteArrayInputStream));
return;
}
switch (s) {
case 11:
short s3 = this.connection_state;
if (s3 == 2) {
handleSupplementalData(null);
} else if (s3 != 3) {
throw new TlsFatalAlert((short) 10);
}
this.peerCertificate = Certificate.parse(byteArrayInputStream);
assertEmpty(byteArrayInputStream);
if (this.peerCertificate == null || this.peerCertificate.isEmpty()) {
this.allowCertificateStatus = false;
}
this.keyExchange.processServerCertificate(this.peerCertificate);
TlsAuthentication authentication = this.tlsClient.getAuthentication();
this.authentication = authentication;
authentication.notifyServerCertificate(this.peerCertificate);
this.connection_state = (short) 4;
return;
case 12:
short s4 = this.connection_state;
if (s4 == 2) {
handleSupplementalData(null);
} else if (s4 != 3) {
if (s4 != 4 && s4 != 5) {
throw new TlsFatalAlert((short) 10);
}
this.keyExchange.processServerKeyExchange(byteArrayInputStream);
assertEmpty(byteArrayInputStream);
this.connection_state = (short) 6;
return;
}
this.keyExchange.skipServerCredentials();
this.authentication = null;
this.keyExchange.processServerKeyExchange(byteArrayInputStream);
assertEmpty(byteArrayInputStream);
this.connection_state = (short) 6;
return;
case 13:
short s5 = this.connection_state;
if (s5 == 4 || s5 == 5) {
this.keyExchange.skipServerKeyExchange();
} else if (s5 != 6) {
throw new TlsFatalAlert((short) 10);
}
if (this.authentication == null) {
throw new TlsFatalAlert((short) 40);
}
this.certificateRequest = CertificateRequest.parse(getContext(), byteArrayInputStream);
assertEmpty(byteArrayInputStream);
this.keyExchange.validateCertificateRequest(this.certificateRequest);
TlsUtils.trackHashAlgorithms(this.recordStream.getHandshakeHash(), this.certificateRequest.getSupportedSignatureAlgorithms());
this.connection_state = (short) 7;
return;
case 14:
switch (this.connection_state) {
case 2:
handleSupplementalData(null);
case 3:
this.keyExchange.skipServerCredentials();
this.authentication = null;
case 4:
case 5:
this.keyExchange.skipServerKeyExchange();
case 6:
case 7:
assertEmpty(byteArrayInputStream);
this.connection_state = (short) 8;
this.recordStream.getHandshakeHash().sealHashAlgorithms();
Vector clientSupplementalData = this.tlsClient.getClientSupplementalData();
if (clientSupplementalData != null) {
sendSupplementalDataMessage(clientSupplementalData);
}
this.connection_state = (short) 9;
CertificateRequest certificateRequest = this.certificateRequest;
if (certificateRequest == null) {
this.keyExchange.skipClientCredentials();
clientCredentials = null;
} else {
clientCredentials = this.authentication.getClientCredentials(certificateRequest);
TlsKeyExchange tlsKeyExchange = this.keyExchange;
if (clientCredentials == null) {
tlsKeyExchange.skipClientCredentials();
certificate = Certificate.EMPTY_CHAIN;
} else {
tlsKeyExchange.processClientCredentials(clientCredentials);
certificate = clientCredentials.getCertificate();
}
sendCertificateMessage(certificate);
}
this.connection_state = (short) 10;
sendClientKeyExchangeMessage();
this.connection_state = (short) 11;
TlsHandshakeHash prepareToFinish = this.recordStream.prepareToFinish();
this.securityParameters.sessionHash = getCurrentPRFHash(getContext(), prepareToFinish, null);
establishMasterSecret(getContext(), this.keyExchange);
this.recordStream.setPendingConnectionState(getPeer().getCompression(), getPeer().getCipher());
if (clientCredentials != null && (clientCredentials instanceof TlsSignerCredentials)) {
TlsSignerCredentials tlsSignerCredentials = (TlsSignerCredentials) clientCredentials;
SignatureAndHashAlgorithm signatureAndHashAlgorithm = TlsUtils.getSignatureAndHashAlgorithm(getContext(), tlsSignerCredentials);
sendCertificateVerifyMessage(new DigitallySigned(signatureAndHashAlgorithm, tlsSignerCredentials.generateCertificateSignature(signatureAndHashAlgorithm == null ? this.securityParameters.getSessionHash() : prepareToFinish.getFinalHash(signatureAndHashAlgorithm.getHash()))));
this.connection_state = (short) 12;
}
sendChangeCipherSpecMessage();
sendFinishedMessage();
this.connection_state = (short) 13;
return;
default:
throw new TlsFatalAlert((short) 40);
}
break;
default:
throw new TlsFatalAlert((short) 10);
}
}
@Override // org.bouncycastle.crypto.tls.TlsProtocol
protected TlsPeer getPeer() {
return this.tlsClient;
}
@Override // org.bouncycastle.crypto.tls.TlsProtocol
AbstractTlsContext getContextAdmin() {
return this.tlsClientContext;
}
@Override // org.bouncycastle.crypto.tls.TlsProtocol
protected TlsContext getContext() {
return this.tlsClientContext;
}
public void connect(TlsClient tlsClient) throws IOException {
SessionParameters exportSessionParameters;
if (tlsClient == null) {
throw new IllegalArgumentException("'tlsClient' cannot be null");
}
if (this.tlsClient != null) {
throw new IllegalStateException("'connect' can only be called once");
}
this.tlsClient = tlsClient;
this.securityParameters = new SecurityParameters();
this.securityParameters.entity = 1;
this.tlsClientContext = new TlsClientContextImpl(this.secureRandom, this.securityParameters);
this.securityParameters.clientRandom = createRandomBlock(tlsClient.shouldUseGMTUnixTime(), this.tlsClientContext.getNonceRandomGenerator());
this.tlsClient.init(this.tlsClientContext);
this.recordStream.init(this.tlsClientContext);
TlsSession sessionToResume = tlsClient.getSessionToResume();
if (sessionToResume != null && sessionToResume.isResumable() && (exportSessionParameters = sessionToResume.exportSessionParameters()) != null) {
this.tlsSession = sessionToResume;
this.sessionParameters = exportSessionParameters;
}
sendClientHelloMessage();
this.connection_state = (short) 1;
blockForHandshake();
}
/* JADX INFO: Access modifiers changed from: protected */
@Override // org.bouncycastle.crypto.tls.TlsProtocol
public void cleanupHandshake() {
super.cleanupHandshake();
this.selectedSessionID = null;
this.keyExchange = null;
this.authentication = null;
this.certificateStatus = null;
this.certificateRequest = null;
}
public TlsClientProtocol(SecureRandom secureRandom) {
super(secureRandom);
this.tlsClient = null;
this.tlsClientContext = null;
this.selectedSessionID = null;
this.keyExchange = null;
this.authentication = null;
this.certificateStatus = null;
this.certificateRequest = null;
}
public TlsClientProtocol(InputStream inputStream, OutputStream outputStream, SecureRandom secureRandom) {
super(inputStream, outputStream, secureRandom);
this.tlsClient = null;
this.tlsClientContext = null;
this.selectedSessionID = null;
this.keyExchange = null;
this.authentication = null;
this.certificateStatus = null;
this.certificateRequest = null;
}
}