001            package com.skype.ipc;
002    
003    //import sun.misc.BASE64Decoder;
004    
005    import javax.net.ssl.X509ExtendedKeyManager;
006    import java.io.ByteArrayInputStream;
007    import java.io.IOException;
008    import java.net.Socket;
009    import java.security.*;
010    import java.security.cert.CertificateFactory;
011    import java.security.cert.X509Certificate;
012    import java.security.spec.PKCS8EncodedKeySpec;
013    import com.skype.util.Base64;
014    
015    
016    public class SkypeKeyManager extends X509ExtendedKeyManager {
017        private X509Certificate cert;
018        private PrivateKey key;
019    
020        // key and cert must be Base64 encoded
021        public SkypeKeyManager(String key, String cert) throws IOException, GeneralSecurityException {
022            this(b64Decode(key), b64Decode(cert));
023        }
024    
025        public SkypeKeyManager(byte[] key, byte[] cert) throws GeneralSecurityException {
026            CertificateFactory crt_fctry = CertificateFactory.getInstance("X.509", "BC");
027            this.cert = (X509Certificate) crt_fctry.generateCertificate(new ByteArrayInputStream(cert));
028    
029            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
030            PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(key);
031            this.key = keyFactory.generatePrivate(privSpec);
032        }
033    
034        public String[] getClientAliases(String s, Principal[] principals) {
035            return new String[0];
036        }
037    
038        public String chooseClientAlias(String[] strings, Principal[] principals, Socket socket) {
039            return "";
040        }
041    
042        public String[] getServerAliases(String s, Principal[] principals) {
043            return new String[0];
044        }
045    
046        public String chooseServerAlias(String s, Principal[] principals, Socket socket) {
047            return "";
048        }
049    
050        public X509Certificate[] getCertificateChain(String s) {
051            return new X509Certificate[]{cert};
052        }
053    
054        public PrivateKey getPrivateKey(String s) {
055            return key;
056        }
057    
058        private static byte[] b64Decode(String s) throws IOException {
059    //        BASE64Decoder decoder = new BASE64Decoder();
060     //       Base64 decoder = new Base64();
061      //      return decoder.decodeBuffer(s);
062            return Base64.decode(s);
063        }
064    
065    
066    
067        // bellow this point only test code
068        /*
069        public static void main(String[] args) throws Exception {
070            Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
071    
072            SkypeKeyManager skm = new SkypeKeyManager(KEY_STR, CERT_STR);
073    
074            SSLContext sslContext = SSLContext.getInstance("TLS");
075            TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
076            tmf.init(KeyStore.getInstance("BKS", "BC"));
077            sslContext.init(new KeyManager[]{skm}, tmf.getTrustManagers(), new java.security.SecureRandom());
078    
079    
080            ServerSocket ss = sslContext.getServerSocketFactory().createServerSocket(5555);
081            Socket s = ss.accept();
082            while(true) {
083                System.out.print((char) s.getInputStream().read());
084            }
085        }
086    
087    
088        private static final String CERT_STR =
089                "MIID4zCCAsugAwIBAgIJAPmYgI9o7pDLMA0GCSqGSIb3DQEBBQUAMFQxJDAiBgkq\n" +
090                "hkiG9w0BCQEWFXNreXBlbW9iaWxlQHNreXBlLm5ldDEUMBIGA1UEAxMLU2t5cGVN\n" +
091                "b2JpbGUxFjAUBgNVBAsTDU1vYmlsZUFuZHJvaWQwHhcNMTAxMTE1MTQxMzQ4WhcN\n" +
092                "MzUxMTA5MTQxMzQ4WjBUMSQwIgYJKoZIhvcNAQkBFhVza3lwZW1vYmlsZUBza3lw\n" +
093                "ZS5uZXQxFDASBgNVBAMTC1NreXBlTW9iaWxlMRYwFAYDVQQLEw1Nb2JpbGVBbmRy\n" +
094                "b2lkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuM5GkYfBAeQehp7F\n" +
095                "931RyHd6RtwoStWF9hytyaff6JUmn3BAYU7EM/rAofHOCZr0RNVmLU37oICZwozG\n" +
096                "5uIDSdE/JzXa5xTfIR6DjvXVYvFRx1KhpGbTsaJtaAdMMi2Sg9vOBuPX8uuwixHM\n" +
097                "Hy2VxVFRq7o1Wh/wbo8Wx5xsBz0C5GI65OVkbZHb+NNZTgg8R8aY/R5eCbdsEV7u\n" +
098                "zVg/pIxyw0brpbTcTT1o6Nl7wdowA5JAjNB4P0WbEXK+qiHDOlaszNIwCSa8A8c1\n" +
099                "Ap1Lef1IPnCXQP4prg2LvudeESX88ogx9Uot9LsAIaufl79Rj3xVJ0jH+wsf7j1g\n" +
100                "7ZuGbQIDAQABo4G3MIG0MB0GA1UdDgQWBBRY8qck63v1OZq+Y5YveEeh7vMGLzCB\n" +
101                "hAYDVR0jBH0we4AUWPKnJOt79TmavmOWL3hHoe7zBi+hWKRWMFQxJDAiBgkqhkiG\n" +
102                "9w0BCQEWFXNreXBlbW9iaWxlQHNreXBlLm5ldDEUMBIGA1UEAxMLU2t5cGVNb2Jp\n" +
103                "bGUxFjAUBgNVBAsTDU1vYmlsZUFuZHJvaWSCCQD5mICPaO6QyzAMBgNVHRMEBTAD\n" +
104                "AQH/MA0GCSqGSIb3DQEBBQUAA4IBAQCv16CltWRfqmvTe8oekqrCgwECTSmgPWnj\n" +
105                "BnIY+1z4unyPn5c9kCRsmWZKL3oDVIIWeCLTlFgGUPK28eW3bV1W+mnCUBGo+YyT\n" +
106                "Tc8nMFWtAjsSlm0jaIaF+pk1wlcvkhpk4MAYiENxQomV//kgDx9uMQm1DegQYc+V\n" +
107                "w+4NPBIqmYXZxX4VW2/TXUHl0SUv1eipqUILKg/HUOo7h3uh3K01MpG/UJbYV/md\n" +
108                "SqUoJ6lrU8BdQeLeBawPIDg9mAZkRjM96sPMB+xxFIuYRp0NPk77mmG24f7/Ajmd\n" +
109                "BPeyOAzXMdgvWRpiSsSVLgqZ2qJywwcqcDRP3+xYNOxsg6+kegms";
110    
111        private static final String KEY_STR =
112                "MIIEpAIBAAKCAQEAuM5GkYfBAeQehp7F931RyHd6RtwoStWF9hytyaff6JUmn3BA\n" +
113                "YU7EM/rAofHOCZr0RNVmLU37oICZwozG5uIDSdE/JzXa5xTfIR6DjvXVYvFRx1Kh\n" +
114                "pGbTsaJtaAdMMi2Sg9vOBuPX8uuwixHMHy2VxVFRq7o1Wh/wbo8Wx5xsBz0C5GI6\n" +
115                "5OVkbZHb+NNZTgg8R8aY/R5eCbdsEV7uzVg/pIxyw0brpbTcTT1o6Nl7wdowA5JA\n" +
116                "jNB4P0WbEXK+qiHDOlaszNIwCSa8A8c1Ap1Lef1IPnCXQP4prg2LvudeESX88ogx\n" +
117                "9Uot9LsAIaufl79Rj3xVJ0jH+wsf7j1g7ZuGbQIDAQABAoIBAG51vPBXeCGtPCGy\n" +
118                "3RkkqrFr2IZqKRsxrTSBx850rPzTyZYa/iAreFKpWmJxqXlMSRyrgLsrlW9F7qG+\n" +
119                "i1SNWvHQRDMnmYPtkcC2AGR+w+Cz5PGCjmM5oubV8xbu5bhITP7LbsXngbgM8CTv\n" +
120                "qlYoZRDfnjVKw4Du/kLW/AKrmFZqOThgSiQInm3pg0xx+KIlmUQt3AVtvvV0Tbbo\n" +
121                "qUwQCGjomVV0Pk7FNukxuFqUlUftZEEkyQg7UsnyJkjw74rt4g5IOE/sa16QorsP\n" +
122                "BT25c45c2NFlJnBKvI5Ip4/ijlxGRnWnrcsAPqa5vCS5Ry/qzJ5g/jCEm5jcIkut\n" +
123                "d8uXxQECgYEA3MHQqwqoXLutYJ3fOTHLLiio8TVPiFBRHiGtV4EqWWfJ/17yA11T\n" +
124                "ufw+9fvO4uGfD4MObPcahuOr7MqdQUr/t9F4LGNn6NFPQiI5fDGn2H1DIngEv5iw\n" +
125                "lwcbhgV+nfQn1neMtdhK7GGVyxH469Y6l05sHHQs8sqCaNh06340Q30CgYEA1k8n\n" +
126                "zfziLG7J42+6Pe/CA0Loo8/Lq1Qbi9f322P1godpelUArqXjq/xlq4uvjG3srR/q\n" +
127                "rXbjVIdoHZ4fzkd9+fjxssjnZOvMEfIq/CahvKdzwT9xGQ2XmVZsPwWmJCm4JxUE\n" +
128                "nJbT2eEzQKAyZvIMrxw/Aqf0ToA9dd09yJVI4bECgYB5SKqCLjrNp/bbTCEl5SuB\n" +
129                "0qjuzKFDfQz0BwCbQMWplRIvkVRZcN7dIa7dqljB4b9n4FL+nsweK9t7Ht5Czxer\n" +
130                "QBRMHtkp2kU3SmJWz1kt4bQOre297f+nGiqO+VnVIhz5AXl3NrwDHqITjW4689oA\n" +
131                "4v8WquU/Bu+a9sFV2GKSaQKBgQCOrcRib6pkyp2+vfPQqH8SjMk1xnJibmyoffCW\n" +
132                "L8aUUHL47v61R9x79F38B9OoOscHu+gR9MUE0eGPVmb2fsJwWj0QOpFTr2j9yay0\n" +
133                "k0O6xgFa91HkzBfSDqeijbA/A0eHPYcEeaYxuKzWqdDkmOG486U/r3IHkXlZryIj\n" +
134                "GMCdAQKBgQCqNTOyM7Msl74RASFzY64kg1egD8qYviEBg14jhzArmpnR2NquLgAc\n" +
135                "ULbTS2C76vWci5JTdCxodcFS03UMcmnCzLlY7gTt68zstm2PERtRObeDa4mrdB/q\n" +
136                "WTLBY0SR67MP/4i6h7DppaMTboTzHoP2s5NXGHFD4q2cbGTTppIYPw==";
137    */
138        }