[androidtv] Moves Shim PKI to AndroidTVPKI and adds Trusted CA Certificate functions (#15174)

Signed-off-by: Ben Rosenblum <rosenblumb@gmail.com>
This commit is contained in:
morph166955 2023-07-15 02:40:41 -05:00 committed by GitHub
parent cad86bc83b
commit ee687aa1cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 40 additions and 20 deletions

View File

@ -18,7 +18,6 @@ import static org.openhab.binding.androidtv.internal.protocol.googletv.GoogleTVC
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.InterruptedIOException;
@ -33,11 +32,9 @@ import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.concurrent.BlockingQueue;
@ -369,17 +366,20 @@ public class GoogleTVConnectionManager {
try {
this.shimX509ClientChain = shimX509ClientChain;
logger.trace("Setting shimX509ClientChain {}", config.port);
if (shimX509ClientChain != null && logger.isTraceEnabled()) {
for (int cert = 0; cert < shimX509ClientChain.length; cert++) {
logger.trace("Subject DN: {}", shimX509ClientChain[cert].getSubjectX500Principal());
logger.trace("Issuer DN: {}", shimX509ClientChain[cert].getIssuerX500Principal());
logger.trace("Serial number: {}", shimX509ClientChain[cert].getSerialNumber());
if (shimX509ClientChain != null) {
if (logger.isTraceEnabled()) {
logger.trace("Subject DN: {}", shimX509ClientChain[0].getSubjectX500Principal());
logger.trace("Issuer DN: {}", shimX509ClientChain[0].getIssuerX500Principal());
logger.trace("Serial number: {}", shimX509ClientChain[0].getSerialNumber());
logger.trace("Cert: {}", GoogleTVRequest
.decodeMessage(GoogleTVUtils.byteArrayToString(shimX509ClientChain[cert].getEncoded())));
.decodeMessage(GoogleTVUtils.byteArrayToString(shimX509ClientChain[0].getEncoded())));
}
androidtvPKI.setCaCert(shimX509ClientChain[0]);
androidtvPKI.saveKeyStore(config.keystorePassword, this.encryptionKey);
}
} catch (CertificateEncodingException e) {
logger.trace("setShimX509ClientChain CertificateEncodingException", e);
} catch (Exception e) {
logger.trace("setShimX509ClientChain Exception", e);
}
}
@ -617,19 +617,13 @@ public class GoogleTVConnectionManager {
public void shimInitialize() {
synchronized (connectionLock) {
AndroidTVPKI shimPKI = new AndroidTVPKI();
byte[] shimEncryptionKey = shimPKI.generateEncryptionKey();
SSLContext sslContext;
try {
shimPKI.generateNewKeyPair(shimEncryptionKey);
// Move this to PKI. Shim requires a trusted cert chain in the keystore.
KeyStore keystore = KeyStore.getInstance("JKS");
FileInputStream keystoreInputStream = new FileInputStream(config.keystoreFileName);
keystore.load(keystoreInputStream, config.keystorePassword.toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(keystore, config.keystorePassword.toCharArray());
kmf.init(androidtvPKI.getKeyStore(config.keystorePassword, this.encryptionKey),
config.keystorePassword.toCharArray());
TrustManager[] trustManagers = defineNoOpTrustManager();
sslContext = SSLContext.getInstance("TLS");
@ -671,6 +665,10 @@ public class GoogleTVConnectionManager {
logger.trace("Connection from: {}",
((X509Certificate) cchain2[i]).getSubjectX500Principal());
shimX509ClientChain[i] = ((X509Certificate) cchain2[i]);
if (this.config.mode.equals(DEFAULT_MODE) && logger.isTraceEnabled()) {
logger.trace("Cert: {}", GoogleTVRequest.decodeMessage(
GoogleTVUtils.byteArrayToString(((X509Certificate) cchain2[i]).getEncoded())));
}
}
if (this.config.mode.equals(PIN_MODE)) {

View File

@ -74,6 +74,7 @@ public class AndroidTVPKI {
private String privKey = "";
private String cert = "";
private String caCert = "";
private String keystoreFileName = "";
private String keystoreAlgorithm = "RSA";
private int keyLength = 2048;
@ -170,6 +171,20 @@ public class AndroidTVPKI {
return cert;
}
public void setCaCert(String caCert) {
this.caCert = caCert;
}
public void setCaCert(Certificate caCert) throws CertificateEncodingException {
this.caCert = new String(Base64.getEncoder().encode(caCert.getEncoded()));
}
public Certificate getCaCert() throws CertificateException {
Certificate caCert = CertificateFactory.getInstance("X.509")
.generateCertificate(new ByteArrayInputStream(Base64.getDecoder().decode(this.caCert.getBytes())));
return caCert;
}
public void setAlias(String alias) {
this.alias = alias;
}
@ -234,6 +249,10 @@ public class AndroidTVPKI {
byte[] byteKey = keystore.getKey(this.alias, keystorePassword.toCharArray()).getEncoded();
this.privKey = encrypt(new String(Base64.getEncoder().encode(byteKey)), key);
setCert(keystore.getCertificate(this.alias));
Certificate caCert = keystore.getCertificate("trustedCa");
if (caCert != null) {
setCaCert(caCert);
}
}
public KeyStore getKeyStore(String keystorePassword, byte[] keyString)
@ -245,6 +264,9 @@ public class AndroidTVPKI {
KeyFactory kf = KeyFactory.getInstance(this.keystoreAlgorithm);
keystore.setKeyEntry(this.alias, kf.generatePrivate(keySpec), keystorePassword.toCharArray(),
new java.security.cert.Certificate[] { getCert() });
if (!caCert.isEmpty()) {
keystore.setCertificateEntry("trustedCa", getCaCert());
}
return keystore;
}