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 }