1 package com.android.hotspot2.osu; 2 3 import android.util.Log; 4 5 import com.android.hotspot2.flow.PlatformAdapter; 6 import com.android.hotspot2.pps.HomeSP; 7 8 import java.io.IOException; 9 import java.net.Socket; 10 import java.security.GeneralSecurityException; 11 import java.security.KeyStore; 12 import java.security.KeyStoreException; 13 import java.security.Principal; 14 import java.security.PrivateKey; 15 import java.security.cert.Certificate; 16 import java.security.cert.X509Certificate; 17 import java.util.ArrayList; 18 import java.util.HashMap; 19 import java.util.List; 20 import java.util.Map; 21 22 import javax.net.ssl.X509KeyManager; 23 24 public class ClientKeyManager implements X509KeyManager { 25 private final KeyStore mKeyStore; 26 private final Map<OSUCertType, String> mAliasMap; 27 private final Map<OSUCertType, Object> mTempKeys; 28 29 private static final String sTempAlias = "client-alias"; 30 ClientKeyManager(HomeSP homeSP, KeyStore keyStore)31 public ClientKeyManager(HomeSP homeSP, KeyStore keyStore) throws IOException { 32 mKeyStore = keyStore; 33 mAliasMap = new HashMap<>(); 34 mAliasMap.put(OSUCertType.AAA, PlatformAdapter.CERT_CLT_CA_ALIAS + homeSP.getFQDN()); 35 mAliasMap.put(OSUCertType.Client, PlatformAdapter.CERT_CLT_CERT_ALIAS + homeSP.getFQDN()); 36 mAliasMap.put(OSUCertType.PrivateKey, PlatformAdapter.CERT_CLT_KEY_ALIAS + homeSP.getFQDN()); 37 mTempKeys = new HashMap<>(); 38 } 39 reloadKeys(Map<OSUCertType, List<X509Certificate>> certs, PrivateKey key)40 public void reloadKeys(Map<OSUCertType, List<X509Certificate>> certs, PrivateKey key) 41 throws IOException { 42 List<X509Certificate> clientCerts = certs.get(OSUCertType.Client); 43 X509Certificate[] certArray = new X509Certificate[clientCerts.size()]; 44 int n = 0; 45 for (X509Certificate cert : clientCerts) { 46 certArray[n++] = cert; 47 } 48 mTempKeys.put(OSUCertType.Client, certArray); 49 mTempKeys.put(OSUCertType.PrivateKey, key); 50 } 51 52 @Override chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket)53 public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) { 54 if (mTempKeys.isEmpty()) { 55 return mAliasMap.get(OSUCertType.Client); 56 } else { 57 return sTempAlias; 58 } 59 } 60 61 @Override getClientAliases(String keyType, Principal[] issuers)62 public String[] getClientAliases(String keyType, Principal[] issuers) { 63 if (mTempKeys.isEmpty()) { 64 String alias = mAliasMap.get(OSUCertType.Client); 65 return alias != null ? new String[]{alias} : null; 66 } else { 67 return new String[]{sTempAlias}; 68 } 69 } 70 71 @Override chooseServerAlias(String keyType, Principal[] issuers, Socket socket)72 public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) { 73 throw new UnsupportedOperationException(); 74 } 75 76 @Override getServerAliases(String keyType, Principal[] issuers)77 public String[] getServerAliases(String keyType, Principal[] issuers) { 78 throw new UnsupportedOperationException(); 79 } 80 81 @Override getCertificateChain(String alias)82 public X509Certificate[] getCertificateChain(String alias) { 83 if (mTempKeys.isEmpty()) { 84 if (!mAliasMap.get(OSUCertType.Client).equals(alias)) { 85 Log.w(OSUManager.TAG, "Bad cert alias requested: '" + alias + "'"); 86 return null; 87 } 88 try { 89 Certificate cert = mKeyStore.getCertificate(alias); 90 return new X509Certificate[] {(X509Certificate) cert}; 91 } catch (KeyStoreException kse) { 92 Log.w(OSUManager.TAG, "Failed to retrieve certificates: " + kse); 93 return null; 94 } 95 } else if (sTempAlias.equals(alias)) { 96 return (X509Certificate[]) mTempKeys.get(OSUCertType.Client); 97 } else { 98 Log.w(OSUManager.TAG, "Bad cert alias requested: '" + alias + "'"); 99 return null; 100 } 101 } 102 103 @Override getPrivateKey(String alias)104 public PrivateKey getPrivateKey(String alias) { 105 if (mTempKeys.isEmpty()) { 106 if (!mAliasMap.get(OSUCertType.Client).equals(alias)) { 107 Log.w(OSUManager.TAG, "Bad key alias requested: '" + alias + "'"); 108 } 109 try { 110 return (PrivateKey) mKeyStore.getKey(mAliasMap.get(OSUCertType.PrivateKey), null); 111 } catch (GeneralSecurityException gse) { 112 Log.w(OSUManager.TAG, "Failed to retrieve private key: " + gse); 113 return null; 114 } 115 } else if (sTempAlias.equals(alias)) { 116 return (PrivateKey) mTempKeys.get(OSUCertType.PrivateKey); 117 } else { 118 Log.w(OSUManager.TAG, "Bad cert alias requested: '" + alias + "'"); 119 return null; 120 } 121 } 122 } 123