1package com.android.hotspot2.osu; 2 3import android.util.Log; 4 5import com.android.hotspot2.flow.PlatformAdapter; 6import com.android.hotspot2.pps.HomeSP; 7 8import java.io.IOException; 9import java.net.Socket; 10import java.security.GeneralSecurityException; 11import java.security.KeyStore; 12import java.security.KeyStoreException; 13import java.security.Principal; 14import java.security.PrivateKey; 15import java.security.cert.Certificate; 16import java.security.cert.X509Certificate; 17import java.util.ArrayList; 18import java.util.HashMap; 19import java.util.List; 20import java.util.Map; 21 22import javax.net.ssl.X509KeyManager; 23 24public 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 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 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 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 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 72 public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) { 73 throw new UnsupportedOperationException(); 74 } 75 76 @Override 77 public String[] getServerAliases(String keyType, Principal[] issuers) { 78 throw new UnsupportedOperationException(); 79 } 80 81 @Override 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 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