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