243 lines
12 KiB
Java
243 lines
12 KiB
Java
package org.bouncycastle.crypto.tls;
|
|
|
|
import java.io.ByteArrayOutputStream;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.io.OutputStream;
|
|
import java.util.Vector;
|
|
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
|
|
import org.bouncycastle.crypto.params.DHParameters;
|
|
import org.bouncycastle.crypto.params.DHPrivateKeyParameters;
|
|
import org.bouncycastle.crypto.params.DHPublicKeyParameters;
|
|
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
|
|
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
|
|
import org.bouncycastle.crypto.params.RSAKeyParameters;
|
|
import org.bouncycastle.crypto.util.PublicKeyFactory;
|
|
import org.bouncycastle.util.Arrays;
|
|
import org.bouncycastle.util.io.Streams;
|
|
|
|
/* loaded from: classes6.dex */
|
|
public class TlsPSKKeyExchange extends AbstractTlsKeyExchange {
|
|
protected short[] clientECPointFormats;
|
|
protected DHPrivateKeyParameters dhAgreePrivateKey;
|
|
protected DHPublicKeyParameters dhAgreePublicKey;
|
|
protected DHParameters dhParameters;
|
|
protected ECPrivateKeyParameters ecAgreePrivateKey;
|
|
protected ECPublicKeyParameters ecAgreePublicKey;
|
|
protected int[] namedCurves;
|
|
protected byte[] premasterSecret;
|
|
protected byte[] psk;
|
|
protected TlsPSKIdentity pskIdentity;
|
|
protected TlsPSKIdentityManager pskIdentityManager;
|
|
protected byte[] psk_identity_hint;
|
|
protected RSAKeyParameters rsaServerPublicKey;
|
|
protected TlsEncryptionCredentials serverCredentials;
|
|
protected short[] serverECPointFormats;
|
|
protected AsymmetricKeyParameter serverPublicKey;
|
|
|
|
protected RSAKeyParameters validateRSAPublicKey(RSAKeyParameters rSAKeyParameters) throws IOException {
|
|
if (rSAKeyParameters.getExponent().isProbablePrime(2)) {
|
|
return rSAKeyParameters;
|
|
}
|
|
throw new TlsFatalAlert((short) 47);
|
|
}
|
|
|
|
@Override // org.bouncycastle.crypto.tls.TlsKeyExchange
|
|
public void validateCertificateRequest(CertificateRequest certificateRequest) throws IOException {
|
|
throw new TlsFatalAlert((short) 10);
|
|
}
|
|
|
|
@Override // org.bouncycastle.crypto.tls.TlsKeyExchange
|
|
public void skipServerCredentials() throws IOException {
|
|
if (this.keyExchange == 15) {
|
|
throw new TlsFatalAlert((short) 10);
|
|
}
|
|
}
|
|
|
|
@Override // org.bouncycastle.crypto.tls.AbstractTlsKeyExchange, org.bouncycastle.crypto.tls.TlsKeyExchange
|
|
public boolean requiresServerKeyExchange() {
|
|
int i = this.keyExchange;
|
|
return i == 14 || i == 24;
|
|
}
|
|
|
|
@Override // org.bouncycastle.crypto.tls.AbstractTlsKeyExchange, org.bouncycastle.crypto.tls.TlsKeyExchange
|
|
public void processServerKeyExchange(InputStream inputStream) throws IOException {
|
|
this.psk_identity_hint = TlsUtils.readOpaque16(inputStream);
|
|
if (this.keyExchange == 14) {
|
|
DHPublicKeyParameters validateDHPublicKey = TlsDHUtils.validateDHPublicKey(ServerDHParams.parse(inputStream).getPublicKey());
|
|
this.dhAgreePublicKey = validateDHPublicKey;
|
|
this.dhParameters = validateDHPublicKey.getParameters();
|
|
} else if (this.keyExchange == 24) {
|
|
this.ecAgreePublicKey = TlsECCUtils.validateECPublicKey(TlsECCUtils.deserializeECPublicKey(this.clientECPointFormats, TlsECCUtils.readECParameters(this.namedCurves, this.clientECPointFormats, inputStream), TlsUtils.readOpaque8(inputStream)));
|
|
}
|
|
}
|
|
|
|
@Override // org.bouncycastle.crypto.tls.AbstractTlsKeyExchange, org.bouncycastle.crypto.tls.TlsKeyExchange
|
|
public void processServerCredentials(TlsCredentials tlsCredentials) throws IOException {
|
|
if (!(tlsCredentials instanceof TlsEncryptionCredentials)) {
|
|
throw new TlsFatalAlert((short) 80);
|
|
}
|
|
processServerCertificate(tlsCredentials.getCertificate());
|
|
this.serverCredentials = (TlsEncryptionCredentials) tlsCredentials;
|
|
}
|
|
|
|
@Override // org.bouncycastle.crypto.tls.AbstractTlsKeyExchange, org.bouncycastle.crypto.tls.TlsKeyExchange
|
|
public void processServerCertificate(Certificate certificate) throws IOException {
|
|
if (this.keyExchange != 15) {
|
|
throw new TlsFatalAlert((short) 10);
|
|
}
|
|
if (certificate.isEmpty()) {
|
|
throw new TlsFatalAlert((short) 42);
|
|
}
|
|
org.bouncycastle.asn1.x509.Certificate certificateAt = certificate.getCertificateAt(0);
|
|
try {
|
|
AsymmetricKeyParameter createKey = PublicKeyFactory.createKey(certificateAt.getSubjectPublicKeyInfo());
|
|
this.serverPublicKey = createKey;
|
|
if (createKey.isPrivate()) {
|
|
throw new TlsFatalAlert((short) 80);
|
|
}
|
|
this.rsaServerPublicKey = validateRSAPublicKey((RSAKeyParameters) this.serverPublicKey);
|
|
TlsUtils.validateKeyUsage(certificateAt, 32);
|
|
super.processServerCertificate(certificate);
|
|
} catch (RuntimeException e) {
|
|
throw new TlsFatalAlert((short) 43, e);
|
|
}
|
|
}
|
|
|
|
@Override // org.bouncycastle.crypto.tls.AbstractTlsKeyExchange, org.bouncycastle.crypto.tls.TlsKeyExchange
|
|
public void processClientKeyExchange(InputStream inputStream) throws IOException {
|
|
byte[] readOpaque16 = TlsUtils.readOpaque16(inputStream);
|
|
byte[] psk = this.pskIdentityManager.getPSK(readOpaque16);
|
|
this.psk = psk;
|
|
if (psk == null) {
|
|
throw new TlsFatalAlert(AlertDescription.unknown_psk_identity);
|
|
}
|
|
this.context.getSecurityParameters().pskIdentity = readOpaque16;
|
|
if (this.keyExchange == 14) {
|
|
this.dhAgreePublicKey = TlsDHUtils.validateDHPublicKey(new DHPublicKeyParameters(TlsDHUtils.readDHParameter(inputStream), this.dhParameters));
|
|
return;
|
|
}
|
|
if (this.keyExchange == 24) {
|
|
this.ecAgreePublicKey = TlsECCUtils.validateECPublicKey(TlsECCUtils.deserializeECPublicKey(this.serverECPointFormats, this.ecAgreePrivateKey.getParameters(), TlsUtils.readOpaque8(inputStream)));
|
|
} else if (this.keyExchange == 15) {
|
|
this.premasterSecret = this.serverCredentials.decryptPreMasterSecret(TlsUtils.isSSL(this.context) ? Streams.readAll(inputStream) : TlsUtils.readOpaque16(inputStream));
|
|
}
|
|
}
|
|
|
|
@Override // org.bouncycastle.crypto.tls.TlsKeyExchange
|
|
public void processClientCredentials(TlsCredentials tlsCredentials) throws IOException {
|
|
throw new TlsFatalAlert((short) 80);
|
|
}
|
|
|
|
@Override // org.bouncycastle.crypto.tls.AbstractTlsKeyExchange, org.bouncycastle.crypto.tls.TlsKeyExchange
|
|
public byte[] generateServerKeyExchange() throws IOException {
|
|
byte[] hint = this.pskIdentityManager.getHint();
|
|
this.psk_identity_hint = hint;
|
|
if (hint == null && !requiresServerKeyExchange()) {
|
|
return null;
|
|
}
|
|
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
|
byte[] bArr = this.psk_identity_hint;
|
|
if (bArr == null) {
|
|
TlsUtils.writeOpaque16(TlsUtils.EMPTY_BYTES, byteArrayOutputStream);
|
|
} else {
|
|
TlsUtils.writeOpaque16(bArr, byteArrayOutputStream);
|
|
}
|
|
if (this.keyExchange == 14) {
|
|
if (this.dhParameters == null) {
|
|
throw new TlsFatalAlert((short) 80);
|
|
}
|
|
this.dhAgreePrivateKey = TlsDHUtils.generateEphemeralServerKeyExchange(this.context.getSecureRandom(), this.dhParameters, byteArrayOutputStream);
|
|
} else if (this.keyExchange == 24) {
|
|
this.ecAgreePrivateKey = TlsECCUtils.generateEphemeralServerKeyExchange(this.context.getSecureRandom(), this.namedCurves, this.clientECPointFormats, byteArrayOutputStream);
|
|
}
|
|
return byteArrayOutputStream.toByteArray();
|
|
}
|
|
|
|
@Override // org.bouncycastle.crypto.tls.TlsKeyExchange
|
|
public byte[] generatePremasterSecret() throws IOException {
|
|
byte[] generateOtherSecret = generateOtherSecret(this.psk.length);
|
|
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(generateOtherSecret.length + 4 + this.psk.length);
|
|
TlsUtils.writeOpaque16(generateOtherSecret, byteArrayOutputStream);
|
|
TlsUtils.writeOpaque16(this.psk, byteArrayOutputStream);
|
|
Arrays.fill(this.psk, (byte) 0);
|
|
this.psk = null;
|
|
return byteArrayOutputStream.toByteArray();
|
|
}
|
|
|
|
protected byte[] generateOtherSecret(int i) throws IOException {
|
|
if (this.keyExchange == 14) {
|
|
DHPrivateKeyParameters dHPrivateKeyParameters = this.dhAgreePrivateKey;
|
|
if (dHPrivateKeyParameters != null) {
|
|
return TlsDHUtils.calculateDHBasicAgreement(this.dhAgreePublicKey, dHPrivateKeyParameters);
|
|
}
|
|
throw new TlsFatalAlert((short) 80);
|
|
}
|
|
if (this.keyExchange != 24) {
|
|
return this.keyExchange == 15 ? this.premasterSecret : new byte[i];
|
|
}
|
|
ECPrivateKeyParameters eCPrivateKeyParameters = this.ecAgreePrivateKey;
|
|
if (eCPrivateKeyParameters != null) {
|
|
return TlsECCUtils.calculateECDHBasicAgreement(this.ecAgreePublicKey, eCPrivateKeyParameters);
|
|
}
|
|
throw new TlsFatalAlert((short) 80);
|
|
}
|
|
|
|
@Override // org.bouncycastle.crypto.tls.TlsKeyExchange
|
|
public void generateClientKeyExchange(OutputStream outputStream) throws IOException {
|
|
byte[] bArr = this.psk_identity_hint;
|
|
if (bArr == null) {
|
|
this.pskIdentity.skipIdentityHint();
|
|
} else {
|
|
this.pskIdentity.notifyIdentityHint(bArr);
|
|
}
|
|
byte[] pSKIdentity = this.pskIdentity.getPSKIdentity();
|
|
if (pSKIdentity == null) {
|
|
throw new TlsFatalAlert((short) 80);
|
|
}
|
|
byte[] psk = this.pskIdentity.getPSK();
|
|
this.psk = psk;
|
|
if (psk == null) {
|
|
throw new TlsFatalAlert((short) 80);
|
|
}
|
|
TlsUtils.writeOpaque16(pSKIdentity, outputStream);
|
|
this.context.getSecurityParameters().pskIdentity = Arrays.clone(pSKIdentity);
|
|
if (this.keyExchange == 14) {
|
|
this.dhAgreePrivateKey = TlsDHUtils.generateEphemeralClientKeyExchange(this.context.getSecureRandom(), this.dhParameters, outputStream);
|
|
} else if (this.keyExchange == 24) {
|
|
this.ecAgreePrivateKey = TlsECCUtils.generateEphemeralClientKeyExchange(this.context.getSecureRandom(), this.serverECPointFormats, this.ecAgreePublicKey.getParameters(), outputStream);
|
|
} else if (this.keyExchange == 15) {
|
|
this.premasterSecret = TlsRSAUtils.generateEncryptedPreMasterSecret(this.context, this.rsaServerPublicKey, outputStream);
|
|
}
|
|
}
|
|
|
|
public TlsPSKKeyExchange(int i, Vector vector, TlsPSKIdentity tlsPSKIdentity, TlsPSKIdentityManager tlsPSKIdentityManager, DHParameters dHParameters, int[] iArr, short[] sArr, short[] sArr2) {
|
|
super(i, vector);
|
|
this.psk_identity_hint = null;
|
|
this.psk = null;
|
|
this.dhAgreePrivateKey = null;
|
|
this.dhAgreePublicKey = null;
|
|
this.ecAgreePrivateKey = null;
|
|
this.ecAgreePublicKey = null;
|
|
this.serverPublicKey = null;
|
|
this.rsaServerPublicKey = null;
|
|
this.serverCredentials = null;
|
|
if (i != 24) {
|
|
switch (i) {
|
|
case 13:
|
|
case 14:
|
|
case 15:
|
|
break;
|
|
default:
|
|
throw new IllegalArgumentException("unsupported key exchange algorithm");
|
|
}
|
|
}
|
|
this.pskIdentity = tlsPSKIdentity;
|
|
this.pskIdentityManager = tlsPSKIdentityManager;
|
|
this.dhParameters = dHParameters;
|
|
this.namedCurves = iArr;
|
|
this.clientECPointFormats = sArr;
|
|
this.serverECPointFormats = sArr2;
|
|
}
|
|
}
|