ssdata.p12 usage
As we saw earlier, the Transcoder "didReceiveAuthenticationChallenge" delegate method was what used the ssdata, but what is the NSUrl that was called that returned this response?
I suspect it is the request made in "fetchWhiteBoxKey:withPort" which accesses "https:/{TIVO_STREAM_IP}:49151/live-streaming/XX_DUMMY_TSN_XX/key.scbin?uuid={UNIQUE_IDENTIFIER}".
Knowing that I could not successfully hit this URL before, I am almost certain that the issue was that I did not have the ssdata.p12 client certificate, so the Tivo Stream was ignoring me.
It worked! The TiVo stream stopped ignoring us and sent us back a 200 code and populated our "whiteBox.key" file with 149 bytes.
But what is in this file??
Knowing that I could not successfully hit this URL before, I am almost certain that the issue was that I did not have the ssdata.p12 client certificate, so the Tivo Stream was ignoring me.
Converting ssdata.p12 into Java keystore
keytool -importkeystore -srckeystore ssdata.p12 -srcstoretype pkcs12 -srcstorepass WiReKYd6bEDu -destkeystore ssdata.jks -deststoretype jks -deststorepass "changeit"
Writing the program to retrieve our white box key
Let me write a quick application to test this theory:import java.net.MalformedURLException;import java.net.URL;import java.security.cert.Certificate;import java.io.*;import javax.net.ssl.HttpsURLConnection;import javax.net.ssl.SSLPeerUnverifiedException;import java.security.KeyStore;import java.security.cert.CertificateFactory;import java.security.cert.X509Certificate;import javax.net.ssl.KeyManagerFactory;import javax.net.ssl.SSLContext;import javax.net.ssl.TrustManagerFactory;import javax.net.ssl.KeyManager;import javax.net.ssl.TrustManager;import java.security.SecureRandom;import javax.net.ssl.X509TrustManager;import java.security.cert.CertificateException;import java.util.Enumeration;public class TestHTTP{public static void main(String[] args) throws Exception{new TestHTTP().testIt();}private void testIt() throws Exception {String https_url = "https://10.0.0.109:49151/live-streaming/XX_DUMMY_TSN_XX/key.scbin?uuid=001122334455667788";URL url;try {KeyStore ks = this.getKeyStore();KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");kmf.init(ks, "WiReKYd6bEDu".toCharArray());KeyManager[] kms = kmf.getKeyManagers();// Custom Trust manager that lets anything in!X509TrustManager easyTrustManager = new X509TrustManager() {public void checkClientTrusted(X509Certificate[] chain,String authType) throws CertificateException {// Oh, I am easy!}public void checkServerTrusted(X509Certificate[] chain,String authType) throws CertificateException {// Oh, I am easy!}public X509Certificate[] getAcceptedIssuers() {return null;}};// Bypass validation of authorities, this is what the iphone app doesTrustManager[] tms = new TrustManager[] {easyTrustManager};SSLContext sslContext = null;sslContext = SSLContext.getInstance("TLS");sslContext.init(kms, tms, new SecureRandom());HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());// Since the alias is "1" it will not match " 10.0.0.109" unless we override the hostname verifierHttpsURLConnection.setDefaultHostnameVerifier(new javax.net.ssl.HostnameVerifier(){public boolean verify(String hostname, javax.net.ssl.SSLSession sslSession) {System.out.println("Warning: URL Host: " + hostname + " vs. " + sslSession.getPeerHost());return true;}});url = new URL(https_url);HttpsURLConnection con = (HttpsURLConnection)url.openConnection();//dumpl all cert infoprint_https_cert(con);//dump all the contentprint_content(con);} catch (MalformedURLException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}private KeyStore getKeyStore() throws Exception {KeyStore ks = KeyStore.getInstance("JKS");java.io.FileInputStream fis = new java.io.FileInputStream("ssdata.jks");ks.load(fis, "changeit".toCharArray());fis.close();return ks;}private void print_https_cert(HttpsURLConnection con){if(con!=null){try {System.out.println("Response Code : " + con.getResponseCode());System.out.println("Cipher Suite : " + con.getCipherSuite());System.out.println("\n");Certificate[] certs = con.getServerCertificates();for(Certificate cert : certs){System.out.println("Cert Type : " + cert.getType());System.out.println("Cert Hash Code : " + cert.hashCode());System.out.println("Cert Public Key Algorithm : " + cert.getPublicKey().getAlgorithm());System.out.println("Cert Public Key Format : " + cert.getPublicKey().getFormat());System.out.println("\n");}} catch (SSLPeerUnverifiedException e) {e.printStackTrace();} catch (IOException e){e.printStackTrace();}}}private void print_content(HttpsURLConnection con){if(con!=null){try {InputStream inputStream = con.getInputStream();OutputStream out = new FileOutputStream(new File("whiteBox.key"));int read = 0;byte[] bytes = new byte[1024];while ((read = inputStream.read(bytes)) != -1) {out.write(bytes, 0, read);}inputStream.close();out.flush();out.close();} catch (IOException e) {e.printStackTrace();}}}}
Running the program
D:\Projects\TivoStream\Program\RetrieveWhiteBoxKey>java TestHTTPWarning: URL Host: 10.0.0.109 vs. 10.0.0.109Response Code : 200Cipher Suite : SSL_RSA_WITH_RC4_128_SHACert Type : X.509Cert Hash Code : 1681350Cert Public Key Algorithm : RSACert Public Key Format : X.509
It worked! The TiVo stream stopped ignoring us and sent us back a 200 code and populated our "whiteBox.key" file with 149 bytes.
But what is in this file??
No comments:
Post a Comment