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; 238d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden 240efca17105d112a0ff568602831b22bdafa00433Brian Carlstromimport com.android.org.bouncycastle.util.io.pem.PemObject; 250efca17105d112a0ff568602831b22bdafa00433Brian Carlstromimport com.android.org.bouncycastle.util.io.pem.PemReader; 260efca17105d112a0ff568602831b22bdafa00433Brian Carlstromimport com.android.org.bouncycastle.util.io.pem.PemWriter; 278d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden 289d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstromimport java.io.ByteArrayInputStream; 299d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstromimport java.io.ByteArrayOutputStream; 309d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstromimport java.io.IOException; 319d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstromimport java.io.InputStreamReader; 329d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstromimport java.io.OutputStreamWriter; 339d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstromimport java.io.Reader; 349d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstromimport java.io.Writer; 35d396a448b2e36e29598c954b64bfddef73f3fae0Elliott Hughesimport java.nio.charset.StandardCharsets; 369b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yehimport java.security.KeyPair; 370efca17105d112a0ff568602831b22bdafa00433Brian Carlstromimport java.security.cert.Certificate; 380efca17105d112a0ff568602831b22bdafa00433Brian Carlstromimport java.security.cert.CertificateEncodingException; 390efca17105d112a0ff568602831b22bdafa00433Brian Carlstromimport java.security.cert.CertificateException; 400efca17105d112a0ff568602831b22bdafa00433Brian Carlstromimport java.security.cert.CertificateFactory; 415423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Rootimport java.security.cert.X509Certificate; 429d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstromimport java.util.ArrayList; 439d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstromimport java.util.List; 449b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh 459b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh/** 469b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh * {@hide} 479b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh */ 489b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yehpublic class Credentials { 499b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh private static final String LOGTAG = "Credentials"; 5044039172627d1c15737ea73836ad375559d76211Chia-chi Yeh 5144039172627d1c15737ea73836ad375559d76211Chia-chi Yeh public static final String INSTALL_ACTION = "android.credentials.INSTALL"; 5244039172627d1c15737ea73836ad375559d76211Chia-chi Yeh 533e7be43e2555bbdfe311dcbd9a36f7f05321a2d8Kenny Root public static final String INSTALL_AS_USER_ACTION = "android.credentials.INSTALL_AS_USER"; 543e7be43e2555bbdfe311dcbd9a36f7f05321a2d8Kenny Root 554a9e1a2494f2e48b157506d7c731187907b7fd4eBrian Carlstrom public static final String UNLOCK_ACTION = "com.android.credentials.UNLOCK"; 564a9e1a2494f2e48b157506d7c731187907b7fd4eBrian Carlstrom 579b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh /** Key prefix for CA certificates. */ 589b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh public static final String CA_CERTIFICATE = "CACERT_"; 599b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh 609b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh /** Key prefix for user certificates. */ 619b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh public static final String USER_CERTIFICATE = "USRCERT_"; 629b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh 6364338c0e4d0ec64c55abc34c0559d94ee352723cJanis Danisevskis /** Key prefix for user private and secret keys. */ 649b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh public static final String USER_PRIVATE_KEY = "USRPKEY_"; 659b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh 6664338c0e4d0ec64c55abc34c0559d94ee352723cJanis Danisevskis /** Key prefix for user secret keys. 6764338c0e4d0ec64c55abc34c0559d94ee352723cJanis Danisevskis * @deprecated use {@code USER_PRIVATE_KEY} for this category instead. 6864338c0e4d0ec64c55abc34c0559d94ee352723cJanis Danisevskis */ 69baf2838fd2c7ddf517bd5bd9917551a4706af5b6Alex Klyubin public static final String USER_SECRET_KEY = "USRSKEY_"; 70baf2838fd2c7ddf517bd5bd9917551a4706af5b6Alex Klyubin 719b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh /** Key prefix for VPN. */ 729b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh public static final String VPN = "VPN_"; 739b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh 749b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh /** Key prefix for WIFI. */ 759b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh public static final String WIFI = "WIFI_"; 769b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh 7769ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey /** Key containing suffix of lockdown VPN profile. */ 7869ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey public static final String LOCKDOWN_VPN = "LOCKDOWN_VPN"; 7969ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey 809b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh /** Data type for public keys. */ 81a00a2b33ccc6bc079c3ee57a938f62947b48a001Brian Carlstrom public static final String EXTRA_PUBLIC_KEY = "KEY"; 829b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh 839b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh /** Data type for private keys. */ 84a00a2b33ccc6bc079c3ee57a938f62947b48a001Brian Carlstrom public static final String EXTRA_PRIVATE_KEY = "PKEY"; 859b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh 8667c30dfe8e4bff11a4660ac23e8679b5deb59457Brian Carlstrom // historically used by Android 8767c30dfe8e4bff11a4660ac23e8679b5deb59457Brian Carlstrom public static final String EXTENSION_CRT = ".crt"; 8867c30dfe8e4bff11a4660ac23e8679b5deb59457Brian Carlstrom public static final String EXTENSION_P12 = ".p12"; 8967c30dfe8e4bff11a4660ac23e8679b5deb59457Brian Carlstrom // commonly used on Windows 9067c30dfe8e4bff11a4660ac23e8679b5deb59457Brian Carlstrom public static final String EXTENSION_CER = ".cer"; 9167c30dfe8e4bff11a4660ac23e8679b5deb59457Brian Carlstrom public static final String EXTENSION_PFX = ".pfx"; 9267c30dfe8e4bff11a4660ac23e8679b5deb59457Brian Carlstrom 939d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom /** 943e7be43e2555bbdfe311dcbd9a36f7f05321a2d8Kenny Root * Intent extra: install the certificate bundle as this UID instead of 953e7be43e2555bbdfe311dcbd9a36f7f05321a2d8Kenny Root * system. 963e7be43e2555bbdfe311dcbd9a36f7f05321a2d8Kenny Root */ 973e7be43e2555bbdfe311dcbd9a36f7f05321a2d8Kenny Root public static final String EXTRA_INSTALL_AS_UID = "install_as_uid"; 983e7be43e2555bbdfe311dcbd9a36f7f05321a2d8Kenny Root 993e7be43e2555bbdfe311dcbd9a36f7f05321a2d8Kenny Root /** 1005423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root * Intent extra: name for the user's private key. 1015423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root */ 1025423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root public static final String EXTRA_USER_PRIVATE_KEY_NAME = "user_private_key_name"; 1035423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root 1045423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root /** 1055423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root * Intent extra: data for the user's private key in PEM-encoded PKCS#8. 1065423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root */ 1075423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root public static final String EXTRA_USER_PRIVATE_KEY_DATA = "user_private_key_data"; 1085423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root 1095423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root /** 1105423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root * Intent extra: name for the user's certificate. 1115423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root */ 1125423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root public static final String EXTRA_USER_CERTIFICATE_NAME = "user_certificate_name"; 1135423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root 1145423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root /** 1155423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root * Intent extra: data for the user's certificate in PEM-encoded X.509. 1165423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root */ 1175423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root public static final String EXTRA_USER_CERTIFICATE_DATA = "user_certificate_data"; 1185423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root 1195423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root /** 1205423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root * Intent extra: name for CA certificate chain 1215423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root */ 1225423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root public static final String EXTRA_CA_CERTIFICATES_NAME = "ca_certificates_name"; 1235423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root 1245423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root /** 1255423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root * Intent extra: data for CA certificate chain in PEM-encoded X.509. 1265423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root */ 1275423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root public static final String EXTRA_CA_CERTIFICATES_DATA = "ca_certificates_data"; 1285423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root 1295423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root /** 1300efca17105d112a0ff568602831b22bdafa00433Brian Carlstrom * Convert objects to a PEM format which is used for 1310efca17105d112a0ff568602831b22bdafa00433Brian Carlstrom * CA_CERTIFICATE and USER_CERTIFICATE entries. 1329d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom */ 1330efca17105d112a0ff568602831b22bdafa00433Brian Carlstrom public static byte[] convertToPem(Certificate... objects) 1340efca17105d112a0ff568602831b22bdafa00433Brian Carlstrom throws IOException, CertificateEncodingException { 1359d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom ByteArrayOutputStream bao = new ByteArrayOutputStream(); 136d396a448b2e36e29598c954b64bfddef73f3fae0Elliott Hughes Writer writer = new OutputStreamWriter(bao, StandardCharsets.US_ASCII); 1370efca17105d112a0ff568602831b22bdafa00433Brian Carlstrom PemWriter pw = new PemWriter(writer); 1380efca17105d112a0ff568602831b22bdafa00433Brian Carlstrom for (Certificate o : objects) { 1390efca17105d112a0ff568602831b22bdafa00433Brian Carlstrom pw.writeObject(new PemObject("CERTIFICATE", o.getEncoded())); 1409d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom } 1419d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom pw.close(); 1429d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom return bao.toByteArray(); 1439d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom } 1449d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom /** 1459d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom * Convert objects from PEM format, which is used for 1460efca17105d112a0ff568602831b22bdafa00433Brian Carlstrom * CA_CERTIFICATE and USER_CERTIFICATE entries. 1479d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom */ 1480efca17105d112a0ff568602831b22bdafa00433Brian Carlstrom public static List<X509Certificate> convertFromPem(byte[] bytes) 1490efca17105d112a0ff568602831b22bdafa00433Brian Carlstrom throws IOException, CertificateException { 1509d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom ByteArrayInputStream bai = new ByteArrayInputStream(bytes); 151d396a448b2e36e29598c954b64bfddef73f3fae0Elliott Hughes Reader reader = new InputStreamReader(bai, StandardCharsets.US_ASCII); 1520efca17105d112a0ff568602831b22bdafa00433Brian Carlstrom PemReader pr = new PemReader(reader); 1530efca17105d112a0ff568602831b22bdafa00433Brian Carlstrom 1548d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden try { 1558d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden CertificateFactory cf = CertificateFactory.getInstance("X509"); 1568d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden 1578d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden List<X509Certificate> result = new ArrayList<X509Certificate>(); 1588d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden PemObject o; 1598d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden while ((o = pr.readPemObject()) != null) { 1608d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden if (o.getType().equals("CERTIFICATE")) { 1618d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden Certificate c = cf.generateCertificate(new ByteArrayInputStream(o.getContent())); 1628d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden result.add((X509Certificate) c); 1638d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden } else { 1648d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden throw new IllegalArgumentException("Unknown type " + o.getType()); 1658d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden } 1660efca17105d112a0ff568602831b22bdafa00433Brian Carlstrom } 1678d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden return result; 1688d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden } finally { 1698d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden pr.close(); 1709d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom } 1719d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom } 1729d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom 17344039172627d1c15737ea73836ad375559d76211Chia-chi Yeh private static Credentials singleton; 17444039172627d1c15737ea73836ad375559d76211Chia-chi Yeh 1759b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh public static Credentials getInstance() { 1769b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh if (singleton == null) { 1779b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh singleton = new Credentials(); 1789b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh } 1799b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh return singleton; 1809b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh } 1819b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh 1829b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh public void unlock(Context context) { 1839b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh try { 1844a9e1a2494f2e48b157506d7c731187907b7fd4eBrian Carlstrom Intent intent = new Intent(UNLOCK_ACTION); 1859b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh context.startActivity(intent); 1869b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh } catch (ActivityNotFoundException e) { 1879b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh Log.w(LOGTAG, e.toString()); 1889b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh } 1899b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh } 1909b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh 19167c30dfe8e4bff11a4660ac23e8679b5deb59457Brian Carlstrom public void install(Context context) { 19267c30dfe8e4bff11a4660ac23e8679b5deb59457Brian Carlstrom try { 193a00a2b33ccc6bc079c3ee57a938f62947b48a001Brian Carlstrom Intent intent = KeyChain.createInstallIntent(); 19467c30dfe8e4bff11a4660ac23e8679b5deb59457Brian Carlstrom context.startActivity(intent); 19567c30dfe8e4bff11a4660ac23e8679b5deb59457Brian Carlstrom } catch (ActivityNotFoundException e) { 19667c30dfe8e4bff11a4660ac23e8679b5deb59457Brian Carlstrom Log.w(LOGTAG, e.toString()); 19767c30dfe8e4bff11a4660ac23e8679b5deb59457Brian Carlstrom } 19867c30dfe8e4bff11a4660ac23e8679b5deb59457Brian Carlstrom } 19967c30dfe8e4bff11a4660ac23e8679b5deb59457Brian Carlstrom 2009b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh public void install(Context context, KeyPair pair) { 2019b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh try { 202a00a2b33ccc6bc079c3ee57a938f62947b48a001Brian Carlstrom Intent intent = KeyChain.createInstallIntent(); 203a00a2b33ccc6bc079c3ee57a938f62947b48a001Brian Carlstrom intent.putExtra(EXTRA_PRIVATE_KEY, pair.getPrivate().getEncoded()); 204a00a2b33ccc6bc079c3ee57a938f62947b48a001Brian Carlstrom intent.putExtra(EXTRA_PUBLIC_KEY, pair.getPublic().getEncoded()); 2059b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh context.startActivity(intent); 2069b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh } catch (ActivityNotFoundException e) { 2079b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh Log.w(LOGTAG, e.toString()); 2089b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh } 2099b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh } 2109b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh 2119b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh public void install(Context context, String type, byte[] value) { 2129b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh try { 213a00a2b33ccc6bc079c3ee57a938f62947b48a001Brian Carlstrom Intent intent = KeyChain.createInstallIntent(); 2149b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh intent.putExtra(type, value); 2159b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh context.startActivity(intent); 2169b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh } catch (ActivityNotFoundException e) { 2179b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh Log.w(LOGTAG, e.toString()); 2189b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh } 2199b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh } 220db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 221db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root /** 222e4487ea288e9fea837995d9bc4608c8a4a253ec8Robin Lee * Delete all types (private key, user certificate, CA certificate) for a 223db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * particular {@code alias}. All three can exist for any given alias. 224e4487ea288e9fea837995d9bc4608c8a4a253ec8Robin Lee * Returns {@code true} if the alias no longer contains any types. 225db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root */ 226dcdaf87ed0aa99073638bcfe645949f130f0c7adAlex Klyubin public static boolean deleteAllTypesForAlias(KeyStore keystore, String alias) { 2273876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin return deleteAllTypesForAlias(keystore, alias, KeyStore.UID_SELF); 2283876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin } 2293876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin 2303876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin /** 231e4487ea288e9fea837995d9bc4608c8a4a253ec8Robin Lee * Delete all types (private key, user certificate, CA certificate) for a 2323876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin * particular {@code alias}. All three can exist for any given alias. 233e4487ea288e9fea837995d9bc4608c8a4a253ec8Robin Lee * Returns {@code true} if the alias no longer contains any types. 2343876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin */ 2353876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin public static boolean deleteAllTypesForAlias(KeyStore keystore, String alias, int uid) { 236db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root /* 237db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * Make sure every type is deleted. There can be all three types, so 238db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * don't use a conditional here. 239db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root */ 24064338c0e4d0ec64c55abc34c0559d94ee352723cJanis Danisevskis return deleteUserKeyTypeForAlias(keystore, alias, uid) 241e4487ea288e9fea837995d9bc4608c8a4a253ec8Robin Lee & deleteCertificateTypesForAlias(keystore, alias, uid); 242802768dd86c4e8a933dbfbac2e9f1a1daa5f93faKenny Root } 243802768dd86c4e8a933dbfbac2e9f1a1daa5f93faKenny Root 244802768dd86c4e8a933dbfbac2e9f1a1daa5f93faKenny Root /** 245e4487ea288e9fea837995d9bc4608c8a4a253ec8Robin Lee * Delete certificate types (user certificate, CA certificate) for a 246e4487ea288e9fea837995d9bc4608c8a4a253ec8Robin Lee * particular {@code alias}. Both can exist for any given alias. 247e4487ea288e9fea837995d9bc4608c8a4a253ec8Robin Lee * Returns {@code true} if the alias no longer contains either type. 248802768dd86c4e8a933dbfbac2e9f1a1daa5f93faKenny Root */ 249dcdaf87ed0aa99073638bcfe645949f130f0c7adAlex Klyubin public static boolean deleteCertificateTypesForAlias(KeyStore keystore, String alias) { 2503876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin return deleteCertificateTypesForAlias(keystore, alias, KeyStore.UID_SELF); 2513876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin } 2523876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin 2533876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin /** 254e4487ea288e9fea837995d9bc4608c8a4a253ec8Robin Lee * Delete certificate types (user certificate, CA certificate) for a 255e4487ea288e9fea837995d9bc4608c8a4a253ec8Robin Lee * particular {@code alias}. Both can exist for any given alias. 256e4487ea288e9fea837995d9bc4608c8a4a253ec8Robin Lee * Returns {@code true} if the alias no longer contains either type. 2573876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin */ 2583876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin public static boolean deleteCertificateTypesForAlias(KeyStore keystore, String alias, int uid) { 259802768dd86c4e8a933dbfbac2e9f1a1daa5f93faKenny Root /* 260802768dd86c4e8a933dbfbac2e9f1a1daa5f93faKenny Root * Make sure every certificate type is deleted. There can be two types, 261802768dd86c4e8a933dbfbac2e9f1a1daa5f93faKenny Root * so don't use a conditional here. 262802768dd86c4e8a933dbfbac2e9f1a1daa5f93faKenny Root */ 2633876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin return keystore.delete(Credentials.USER_CERTIFICATE + alias, uid) 264e4487ea288e9fea837995d9bc4608c8a4a253ec8Robin Lee & keystore.delete(Credentials.CA_CERTIFICATE + alias, uid); 265db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root } 266baf2838fd2c7ddf517bd5bd9917551a4706af5b6Alex Klyubin 267baf2838fd2c7ddf517bd5bd9917551a4706af5b6Alex Klyubin /** 26864338c0e4d0ec64c55abc34c0559d94ee352723cJanis Danisevskis * Delete user key for a particular {@code alias}. 269e4487ea288e9fea837995d9bc4608c8a4a253ec8Robin Lee * Returns {@code true} if the entry no longer exists. 2703876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin */ 27164338c0e4d0ec64c55abc34c0559d94ee352723cJanis Danisevskis public static boolean deleteUserKeyTypeForAlias(KeyStore keystore, String alias) { 27264338c0e4d0ec64c55abc34c0559d94ee352723cJanis Danisevskis return deleteUserKeyTypeForAlias(keystore, alias, KeyStore.UID_SELF); 273baf2838fd2c7ddf517bd5bd9917551a4706af5b6Alex Klyubin } 274baf2838fd2c7ddf517bd5bd9917551a4706af5b6Alex Klyubin 275baf2838fd2c7ddf517bd5bd9917551a4706af5b6Alex Klyubin /** 27664338c0e4d0ec64c55abc34c0559d94ee352723cJanis Danisevskis * Delete user key for a particular {@code alias}. 277e4487ea288e9fea837995d9bc4608c8a4a253ec8Robin Lee * Returns {@code true} if the entry no longer exists. 278baf2838fd2c7ddf517bd5bd9917551a4706af5b6Alex Klyubin */ 27964338c0e4d0ec64c55abc34c0559d94ee352723cJanis Danisevskis public static boolean deleteUserKeyTypeForAlias(KeyStore keystore, String alias, int uid) { 28064338c0e4d0ec64c55abc34c0559d94ee352723cJanis Danisevskis return keystore.delete(Credentials.USER_PRIVATE_KEY + alias, uid) || 28164338c0e4d0ec64c55abc34c0559d94ee352723cJanis Danisevskis keystore.delete(Credentials.USER_SECRET_KEY + alias, uid); 2823876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin } 2833876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin 2843876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin /** 28564338c0e4d0ec64c55abc34c0559d94ee352723cJanis Danisevskis * Delete legacy prefixed entry for a particular {@code alias} 286e4487ea288e9fea837995d9bc4608c8a4a253ec8Robin Lee * Returns {@code true} if the entry no longer exists. 2873876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin */ 28864338c0e4d0ec64c55abc34c0559d94ee352723cJanis Danisevskis public static boolean deleteLegacyKeyForAlias(KeyStore keystore, String alias, int uid) { 2893876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin return keystore.delete(Credentials.USER_SECRET_KEY + alias, uid); 290baf2838fd2c7ddf517bd5bd9917551a4706af5b6Alex Klyubin } 2919b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh} 292