Credentials.java revision 5423e68d5dbe048ec6f042cce52a33f94184e9fb
19b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh/* 29b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh * Copyright (C) 2009 The Android Open Source Project 39b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh * 49b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh * Licensed under the Apache License, Version 2.0 (the "License"); 59b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh * you may not use this file except in compliance with the License. 69b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh * You may obtain a copy of the License at 79b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh * 89b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh * http://www.apache.org/licenses/LICENSE-2.0 99b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh * 109b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh * Unless required by applicable law or agreed to in writing, software 119b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh * distributed under the License is distributed on an "AS IS" BASIS, 129b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh * See the License for the specific language governing permissions and 149b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh * limitations under the License. 159b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh */ 169b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh 179b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yehpackage android.security; 189b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh 199b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yehimport android.content.ActivityNotFoundException; 209b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yehimport android.content.Context; 219b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yehimport android.content.Intent; 229b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yehimport android.util.Log; 239d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstromimport com.android.org.bouncycastle.openssl.PEMReader; 249d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstromimport com.android.org.bouncycastle.openssl.PEMWriter; 259d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstromimport java.io.ByteArrayInputStream; 269d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstromimport java.io.ByteArrayOutputStream; 279d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstromimport java.io.IOException; 289d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstromimport java.io.InputStreamReader; 295423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Rootimport java.io.ObjectOutputStream; 309d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstromimport java.io.OutputStreamWriter; 319d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstromimport java.io.Reader; 329d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstromimport java.io.Writer; 339d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstromimport java.nio.charset.Charsets; 349b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yehimport java.security.KeyPair; 355423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Rootimport java.security.cert.X509Certificate; 369d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstromimport java.util.ArrayList; 379d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstromimport java.util.List; 389b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh 399b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh/** 409b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh * {@hide} 419b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh */ 429b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yehpublic class Credentials { 439b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh private static final String LOGTAG = "Credentials"; 4444039172627d1c15737ea73836ad375559d76211Chia-chi Yeh 4544039172627d1c15737ea73836ad375559d76211Chia-chi Yeh public static final String INSTALL_ACTION = "android.credentials.INSTALL"; 4644039172627d1c15737ea73836ad375559d76211Chia-chi Yeh 474a9e1a2494f2e48b157506d7c731187907b7fd4eBrian Carlstrom public static final String UNLOCK_ACTION = "com.android.credentials.UNLOCK"; 484a9e1a2494f2e48b157506d7c731187907b7fd4eBrian Carlstrom 499b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh /** Key prefix for CA certificates. */ 509b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh public static final String CA_CERTIFICATE = "CACERT_"; 519b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh 529b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh /** Key prefix for user certificates. */ 539b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh public static final String USER_CERTIFICATE = "USRCERT_"; 549b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh 559b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh /** Key prefix for user private keys. */ 569b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh public static final String USER_PRIVATE_KEY = "USRPKEY_"; 579b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh 589b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh /** Key prefix for VPN. */ 599b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh public static final String VPN = "VPN_"; 609b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh 619b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh /** Key prefix for WIFI. */ 629b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh public static final String WIFI = "WIFI_"; 639b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh 649b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh /** Data type for public keys. */ 65a00a2b33ccc6bc079c3ee57a938f62947b48a001Brian Carlstrom public static final String EXTRA_PUBLIC_KEY = "KEY"; 669b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh 679b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh /** Data type for private keys. */ 68a00a2b33ccc6bc079c3ee57a938f62947b48a001Brian Carlstrom public static final String EXTRA_PRIVATE_KEY = "PKEY"; 699b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh 7067c30dfe8e4bff11a4660ac23e8679b5deb59457Brian Carlstrom // historically used by Android 7167c30dfe8e4bff11a4660ac23e8679b5deb59457Brian Carlstrom public static final String EXTENSION_CRT = ".crt"; 7267c30dfe8e4bff11a4660ac23e8679b5deb59457Brian Carlstrom public static final String EXTENSION_P12 = ".p12"; 7367c30dfe8e4bff11a4660ac23e8679b5deb59457Brian Carlstrom // commonly used on Windows 7467c30dfe8e4bff11a4660ac23e8679b5deb59457Brian Carlstrom public static final String EXTENSION_CER = ".cer"; 7567c30dfe8e4bff11a4660ac23e8679b5deb59457Brian Carlstrom public static final String EXTENSION_PFX = ".pfx"; 7667c30dfe8e4bff11a4660ac23e8679b5deb59457Brian Carlstrom 779d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom /** 785423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root * Intent extra: name for the user's private key. 795423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root */ 805423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root public static final String EXTRA_USER_PRIVATE_KEY_NAME = "user_private_key_name"; 815423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root 825423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root /** 835423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root * Intent extra: data for the user's private key in PEM-encoded PKCS#8. 845423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root */ 855423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root public static final String EXTRA_USER_PRIVATE_KEY_DATA = "user_private_key_data"; 865423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root 875423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root /** 885423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root * Intent extra: name for the user's certificate. 895423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root */ 905423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root public static final String EXTRA_USER_CERTIFICATE_NAME = "user_certificate_name"; 915423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root 925423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root /** 935423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root * Intent extra: data for the user's certificate in PEM-encoded X.509. 945423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root */ 955423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root public static final String EXTRA_USER_CERTIFICATE_DATA = "user_certificate_data"; 965423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root 975423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root /** 985423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root * Intent extra: name for CA certificate chain 995423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root */ 1005423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root public static final String EXTRA_CA_CERTIFICATES_NAME = "ca_certificates_name"; 1015423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root 1025423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root /** 1035423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root * Intent extra: data for CA certificate chain in PEM-encoded X.509. 1045423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root */ 1055423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root public static final String EXTRA_CA_CERTIFICATES_DATA = "ca_certificates_data"; 1065423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root 1075423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root /** 1089d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom * Convert objects to a PEM format, which is used for 1099d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom * CA_CERTIFICATE, USER_CERTIFICATE, and USER_PRIVATE_KEY 1109d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom * entries. 1119d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom */ 1129d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom public static byte[] convertToPem(Object... objects) throws IOException { 1139d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom ByteArrayOutputStream bao = new ByteArrayOutputStream(); 1149d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom Writer writer = new OutputStreamWriter(bao, Charsets.US_ASCII); 1159d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom PEMWriter pw = new PEMWriter(writer); 1169d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom for (Object o : objects) { 1179d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom pw.writeObject(o); 1189d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom } 1199d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom pw.close(); 1209d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom return bao.toByteArray(); 1219d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom } 1229d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom /** 1239d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom * Convert objects from PEM format, which is used for 1249d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom * CA_CERTIFICATE, USER_CERTIFICATE, and USER_PRIVATE_KEY 1259d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom * entries. 1269d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom */ 1279d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom public static List<Object> convertFromPem(byte[] bytes) throws IOException { 1289d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom ByteArrayInputStream bai = new ByteArrayInputStream(bytes); 1299d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom Reader reader = new InputStreamReader(bai, Charsets.US_ASCII); 1309d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom PEMReader pr = new PEMReader(reader); 1319d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom 1329d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom List<Object> result = new ArrayList<Object>(); 1339d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom Object o; 1349d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom while ((o = pr.readObject()) != null) { 1359d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom result.add(o); 1369d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom } 1379d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom pr.close(); 1389d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom return result; 1399d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom } 1409d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom 14144039172627d1c15737ea73836ad375559d76211Chia-chi Yeh private static Credentials singleton; 14244039172627d1c15737ea73836ad375559d76211Chia-chi Yeh 1439b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh public static Credentials getInstance() { 1449b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh if (singleton == null) { 1459b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh singleton = new Credentials(); 1469b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh } 1479b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh return singleton; 1489b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh } 1499b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh 1509b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh public void unlock(Context context) { 1519b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh try { 1524a9e1a2494f2e48b157506d7c731187907b7fd4eBrian Carlstrom Intent intent = new Intent(UNLOCK_ACTION); 1539b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh context.startActivity(intent); 1549b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh } catch (ActivityNotFoundException e) { 1559b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh Log.w(LOGTAG, e.toString()); 1569b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh } 1579b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh } 1589b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh 15967c30dfe8e4bff11a4660ac23e8679b5deb59457Brian Carlstrom public void install(Context context) { 16067c30dfe8e4bff11a4660ac23e8679b5deb59457Brian Carlstrom try { 161a00a2b33ccc6bc079c3ee57a938f62947b48a001Brian Carlstrom Intent intent = KeyChain.createInstallIntent(); 16267c30dfe8e4bff11a4660ac23e8679b5deb59457Brian Carlstrom context.startActivity(intent); 16367c30dfe8e4bff11a4660ac23e8679b5deb59457Brian Carlstrom } catch (ActivityNotFoundException e) { 16467c30dfe8e4bff11a4660ac23e8679b5deb59457Brian Carlstrom Log.w(LOGTAG, e.toString()); 16567c30dfe8e4bff11a4660ac23e8679b5deb59457Brian Carlstrom } 16667c30dfe8e4bff11a4660ac23e8679b5deb59457Brian Carlstrom } 16767c30dfe8e4bff11a4660ac23e8679b5deb59457Brian Carlstrom 1689b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh public void install(Context context, KeyPair pair) { 1699b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh try { 170a00a2b33ccc6bc079c3ee57a938f62947b48a001Brian Carlstrom Intent intent = KeyChain.createInstallIntent(); 171a00a2b33ccc6bc079c3ee57a938f62947b48a001Brian Carlstrom intent.putExtra(EXTRA_PRIVATE_KEY, pair.getPrivate().getEncoded()); 172a00a2b33ccc6bc079c3ee57a938f62947b48a001Brian Carlstrom intent.putExtra(EXTRA_PUBLIC_KEY, pair.getPublic().getEncoded()); 1739b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh context.startActivity(intent); 1749b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh } catch (ActivityNotFoundException e) { 1759b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh Log.w(LOGTAG, e.toString()); 1769b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh } 1779b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh } 1789b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh 1799b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh public void install(Context context, String type, byte[] value) { 1809b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh try { 181a00a2b33ccc6bc079c3ee57a938f62947b48a001Brian Carlstrom Intent intent = KeyChain.createInstallIntent(); 1829b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh intent.putExtra(type, value); 1839b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh context.startActivity(intent); 1849b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh } catch (ActivityNotFoundException e) { 1859b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh Log.w(LOGTAG, e.toString()); 1869b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh } 1879b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh } 1889b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh} 189