    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        }