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
639b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh    /** Key prefix for user private keys. */
649b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh    public static final String USER_PRIVATE_KEY = "USRPKEY_";
659b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh
66baf2838fd2c7ddf517bd5bd9917551a4706af5b6Alex Klyubin    /** Key prefix for user secret keys. */
67baf2838fd2c7ddf517bd5bd9917551a4706af5b6Alex Klyubin    public static final String USER_SECRET_KEY = "USRSKEY_";
68baf2838fd2c7ddf517bd5bd9917551a4706af5b6Alex Klyubin
699b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh    /** Key prefix for VPN. */
709b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh    public static final String VPN = "VPN_";
719b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh
729b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh    /** Key prefix for WIFI. */
739b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh    public static final String WIFI = "WIFI_";
749b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh
7569ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey    /** Key containing suffix of lockdown VPN profile. */
7669ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey    public static final String LOCKDOWN_VPN = "LOCKDOWN_VPN";
7769ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey
789b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh    /** Data type for public keys. */
79a00a2b33ccc6bc079c3ee57a938f62947b48a001Brian Carlstrom    public static final String EXTRA_PUBLIC_KEY = "KEY";
809b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh
819b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh    /** Data type for private keys. */
82a00a2b33ccc6bc079c3ee57a938f62947b48a001Brian Carlstrom    public static final String EXTRA_PRIVATE_KEY = "PKEY";
839b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh
8467c30dfe8e4bff11a4660ac23e8679b5deb59457Brian Carlstrom    // historically used by Android
8567c30dfe8e4bff11a4660ac23e8679b5deb59457Brian Carlstrom    public static final String EXTENSION_CRT = ".crt";
8667c30dfe8e4bff11a4660ac23e8679b5deb59457Brian Carlstrom    public static final String EXTENSION_P12 = ".p12";
8767c30dfe8e4bff11a4660ac23e8679b5deb59457Brian Carlstrom    // commonly used on Windows
8867c30dfe8e4bff11a4660ac23e8679b5deb59457Brian Carlstrom    public static final String EXTENSION_CER = ".cer";
8967c30dfe8e4bff11a4660ac23e8679b5deb59457Brian Carlstrom    public static final String EXTENSION_PFX = ".pfx";
9067c30dfe8e4bff11a4660ac23e8679b5deb59457Brian Carlstrom
919d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom    /**
923e7be43e2555bbdfe311dcbd9a36f7f05321a2d8Kenny Root     * Intent extra: install the certificate bundle as this UID instead of
933e7be43e2555bbdfe311dcbd9a36f7f05321a2d8Kenny Root     * system.
943e7be43e2555bbdfe311dcbd9a36f7f05321a2d8Kenny Root     */
953e7be43e2555bbdfe311dcbd9a36f7f05321a2d8Kenny Root    public static final String EXTRA_INSTALL_AS_UID = "install_as_uid";
963e7be43e2555bbdfe311dcbd9a36f7f05321a2d8Kenny Root
973e7be43e2555bbdfe311dcbd9a36f7f05321a2d8Kenny Root    /**
985423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root     * Intent extra: name for the user's private key.
995423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root     */
1005423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    public static final String EXTRA_USER_PRIVATE_KEY_NAME = "user_private_key_name";
1015423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root
1025423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    /**
1035423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root     * Intent extra: data for the user's private key in PEM-encoded PKCS#8.
1045423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root     */
1055423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    public static final String EXTRA_USER_PRIVATE_KEY_DATA = "user_private_key_data";
1065423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root
1075423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    /**
1085423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root     * Intent extra: name for the user's certificate.
1095423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root     */
1105423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    public static final String EXTRA_USER_CERTIFICATE_NAME = "user_certificate_name";
1115423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root
1125423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    /**
1135423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root     * Intent extra: data for the user's certificate in PEM-encoded X.509.
1145423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root     */
1155423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    public static final String EXTRA_USER_CERTIFICATE_DATA = "user_certificate_data";
1165423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root
1175423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    /**
1185423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root     * Intent extra: name for CA certificate chain
1195423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root     */
1205423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    public static final String EXTRA_CA_CERTIFICATES_NAME = "ca_certificates_name";
1215423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root
1225423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    /**
1235423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root     * Intent extra: data for CA certificate chain in PEM-encoded X.509.
1245423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root     */
1255423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    public static final String EXTRA_CA_CERTIFICATES_DATA = "ca_certificates_data";
1265423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root
1275423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    /**
1280efca17105d112a0ff568602831b22bdafa00433Brian Carlstrom     * Convert objects to a PEM format which is used for
1290efca17105d112a0ff568602831b22bdafa00433Brian Carlstrom     * CA_CERTIFICATE and USER_CERTIFICATE entries.
1309d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom     */
1310efca17105d112a0ff568602831b22bdafa00433Brian Carlstrom    public static byte[] convertToPem(Certificate... objects)
1320efca17105d112a0ff568602831b22bdafa00433Brian Carlstrom            throws IOException, CertificateEncodingException {
1339d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom        ByteArrayOutputStream bao = new ByteArrayOutputStream();
134d396a448b2e36e29598c954b64bfddef73f3fae0Elliott Hughes        Writer writer = new OutputStreamWriter(bao, StandardCharsets.US_ASCII);
1350efca17105d112a0ff568602831b22bdafa00433Brian Carlstrom        PemWriter pw = new PemWriter(writer);
1360efca17105d112a0ff568602831b22bdafa00433Brian Carlstrom        for (Certificate o : objects) {
1370efca17105d112a0ff568602831b22bdafa00433Brian Carlstrom            pw.writeObject(new PemObject("CERTIFICATE", o.getEncoded()));
1389d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom        }
1399d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom        pw.close();
1409d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom        return bao.toByteArray();
1419d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom    }
1429d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom    /**
1439d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom     * Convert objects from PEM format, which is used for
1440efca17105d112a0ff568602831b22bdafa00433Brian Carlstrom     * CA_CERTIFICATE and USER_CERTIFICATE entries.
1459d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom     */
1460efca17105d112a0ff568602831b22bdafa00433Brian Carlstrom    public static List<X509Certificate> convertFromPem(byte[] bytes)
1470efca17105d112a0ff568602831b22bdafa00433Brian Carlstrom            throws IOException, CertificateException {
1489d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom        ByteArrayInputStream bai = new ByteArrayInputStream(bytes);
149d396a448b2e36e29598c954b64bfddef73f3fae0Elliott Hughes        Reader reader = new InputStreamReader(bai, StandardCharsets.US_ASCII);
1500efca17105d112a0ff568602831b22bdafa00433Brian Carlstrom        PemReader pr = new PemReader(reader);
1510efca17105d112a0ff568602831b22bdafa00433Brian Carlstrom
1528d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden        try {
1538d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden            CertificateFactory cf = CertificateFactory.getInstance("X509");
1548d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden
1558d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden            List<X509Certificate> result = new ArrayList<X509Certificate>();
1568d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden            PemObject o;
1578d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden            while ((o = pr.readPemObject()) != null) {
1588d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden                if (o.getType().equals("CERTIFICATE")) {
1598d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden                    Certificate c = cf.generateCertificate(new ByteArrayInputStream(o.getContent()));
1608d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden                    result.add((X509Certificate) c);
1618d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden                } else {
1628d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden                    throw new IllegalArgumentException("Unknown type " + o.getType());
1638d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden                }
1640efca17105d112a0ff568602831b22bdafa00433Brian Carlstrom            }
1658d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden            return result;
1668d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden        } finally {
1678d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden            pr.close();
1689d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom        }
1699d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom    }
1709d7faa91be6661eccf73494f1ab96ae9a28d42d7Brian Carlstrom
17144039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    private static Credentials singleton;
17244039172627d1c15737ea73836ad375559d76211Chia-chi Yeh
1739b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh    public static Credentials getInstance() {
1749b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh        if (singleton == null) {
1759b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh            singleton = new Credentials();
1769b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh        }
1779b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh        return singleton;
1789b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh    }
1799b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh
1809b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh    public void unlock(Context context) {
1819b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh        try {
1824a9e1a2494f2e48b157506d7c731187907b7fd4eBrian Carlstrom            Intent intent = new Intent(UNLOCK_ACTION);
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
18967c30dfe8e4bff11a4660ac23e8679b5deb59457Brian Carlstrom    public void install(Context context) {
19067c30dfe8e4bff11a4660ac23e8679b5deb59457Brian Carlstrom        try {
191a00a2b33ccc6bc079c3ee57a938f62947b48a001Brian Carlstrom            Intent intent = KeyChain.createInstallIntent();
19267c30dfe8e4bff11a4660ac23e8679b5deb59457Brian Carlstrom            context.startActivity(intent);
19367c30dfe8e4bff11a4660ac23e8679b5deb59457Brian Carlstrom        } catch (ActivityNotFoundException e) {
19467c30dfe8e4bff11a4660ac23e8679b5deb59457Brian Carlstrom            Log.w(LOGTAG, e.toString());
19567c30dfe8e4bff11a4660ac23e8679b5deb59457Brian Carlstrom        }
19667c30dfe8e4bff11a4660ac23e8679b5deb59457Brian Carlstrom    }
19767c30dfe8e4bff11a4660ac23e8679b5deb59457Brian Carlstrom
1989b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh    public void install(Context context, KeyPair pair) {
1999b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh        try {
200a00a2b33ccc6bc079c3ee57a938f62947b48a001Brian Carlstrom            Intent intent = KeyChain.createInstallIntent();
201a00a2b33ccc6bc079c3ee57a938f62947b48a001Brian Carlstrom            intent.putExtra(EXTRA_PRIVATE_KEY, pair.getPrivate().getEncoded());
202a00a2b33ccc6bc079c3ee57a938f62947b48a001Brian Carlstrom            intent.putExtra(EXTRA_PUBLIC_KEY, pair.getPublic().getEncoded());
2039b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh            context.startActivity(intent);
2049b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh        } catch (ActivityNotFoundException e) {
2059b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh            Log.w(LOGTAG, e.toString());
2069b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh        }
2079b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh    }
2089b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh
2099b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh    public void install(Context context, String type, byte[] value) {
2109b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh        try {
211a00a2b33ccc6bc079c3ee57a938f62947b48a001Brian Carlstrom            Intent intent = KeyChain.createInstallIntent();
2129b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh            intent.putExtra(type, value);
2139b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh            context.startActivity(intent);
2149b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh        } catch (ActivityNotFoundException e) {
2159b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh            Log.w(LOGTAG, e.toString());
2169b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh        }
2179b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh    }
218db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root
219db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root    /**
220e4487ea288e9fea837995d9bc4608c8a4a253ec8Robin Lee     * Delete all types (private key, user certificate, CA certificate) for a
221db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     * particular {@code alias}. All three can exist for any given alias.
222e4487ea288e9fea837995d9bc4608c8a4a253ec8Robin Lee     * Returns {@code true} if the alias no longer contains any types.
223db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     */
224dcdaf87ed0aa99073638bcfe645949f130f0c7adAlex Klyubin    public static boolean deleteAllTypesForAlias(KeyStore keystore, String alias) {
2253876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin        return deleteAllTypesForAlias(keystore, alias, KeyStore.UID_SELF);
2263876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin    }
2273876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin
2283876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin    /**
229e4487ea288e9fea837995d9bc4608c8a4a253ec8Robin Lee     * Delete all types (private key, user certificate, CA certificate) for a
2303876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin     * particular {@code alias}. All three can exist for any given alias.
231e4487ea288e9fea837995d9bc4608c8a4a253ec8Robin Lee     * Returns {@code true} if the alias no longer contains any types.
2323876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin     */
2333876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin    public static boolean deleteAllTypesForAlias(KeyStore keystore, String alias, int uid) {
234db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root        /*
235db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root         * Make sure every type is deleted. There can be all three types, so
236db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root         * don't use a conditional here.
237db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root         */
238e4487ea288e9fea837995d9bc4608c8a4a253ec8Robin Lee        return deletePrivateKeyTypeForAlias(keystore, alias, uid)
239e4487ea288e9fea837995d9bc4608c8a4a253ec8Robin Lee                & deleteSecretKeyTypeForAlias(keystore, alias, uid)
240e4487ea288e9fea837995d9bc4608c8a4a253ec8Robin Lee                & deleteCertificateTypesForAlias(keystore, alias, uid);
241802768dd86c4e8a933dbfbac2e9f1a1daa5f93faKenny Root    }
242802768dd86c4e8a933dbfbac2e9f1a1daa5f93faKenny Root
243802768dd86c4e8a933dbfbac2e9f1a1daa5f93faKenny Root    /**
244e4487ea288e9fea837995d9bc4608c8a4a253ec8Robin Lee     * Delete certificate types (user certificate, CA certificate) for a
245e4487ea288e9fea837995d9bc4608c8a4a253ec8Robin Lee     * particular {@code alias}. Both can exist for any given alias.
246e4487ea288e9fea837995d9bc4608c8a4a253ec8Robin Lee     * Returns {@code true} if the alias no longer contains either type.
247802768dd86c4e8a933dbfbac2e9f1a1daa5f93faKenny Root     */
248dcdaf87ed0aa99073638bcfe645949f130f0c7adAlex Klyubin    public static boolean deleteCertificateTypesForAlias(KeyStore keystore, String alias) {
2493876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin        return deleteCertificateTypesForAlias(keystore, alias, KeyStore.UID_SELF);
2503876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin    }
2513876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin
2523876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin    /**
253e4487ea288e9fea837995d9bc4608c8a4a253ec8Robin Lee     * Delete certificate types (user certificate, CA certificate) for a
254e4487ea288e9fea837995d9bc4608c8a4a253ec8Robin Lee     * particular {@code alias}. Both can exist for any given alias.
255e4487ea288e9fea837995d9bc4608c8a4a253ec8Robin Lee     * Returns {@code true} if the alias no longer contains either type.
2563876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin     */
2573876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin    public static boolean deleteCertificateTypesForAlias(KeyStore keystore, String alias, int uid) {
258802768dd86c4e8a933dbfbac2e9f1a1daa5f93faKenny Root        /*
259802768dd86c4e8a933dbfbac2e9f1a1daa5f93faKenny Root         * Make sure every certificate type is deleted. There can be two types,
260802768dd86c4e8a933dbfbac2e9f1a1daa5f93faKenny Root         * so don't use a conditional here.
261802768dd86c4e8a933dbfbac2e9f1a1daa5f93faKenny Root         */
2623876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin        return keystore.delete(Credentials.USER_CERTIFICATE + alias, uid)
263e4487ea288e9fea837995d9bc4608c8a4a253ec8Robin Lee                & keystore.delete(Credentials.CA_CERTIFICATE + alias, uid);
264db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root    }
265baf2838fd2c7ddf517bd5bd9917551a4706af5b6Alex Klyubin
266baf2838fd2c7ddf517bd5bd9917551a4706af5b6Alex Klyubin    /**
267baf2838fd2c7ddf517bd5bd9917551a4706af5b6Alex Klyubin     * Delete private key for a particular {@code alias}.
268e4487ea288e9fea837995d9bc4608c8a4a253ec8Robin Lee     * Returns {@code true} if the entry no longer exists.
269baf2838fd2c7ddf517bd5bd9917551a4706af5b6Alex Klyubin     */
270baf2838fd2c7ddf517bd5bd9917551a4706af5b6Alex Klyubin    static boolean deletePrivateKeyTypeForAlias(KeyStore keystore, String alias) {
2713876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin        return deletePrivateKeyTypeForAlias(keystore, alias, KeyStore.UID_SELF);
2723876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin    }
2733876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin
2743876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin    /**
2753876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin     * Delete private key for a particular {@code alias}.
276e4487ea288e9fea837995d9bc4608c8a4a253ec8Robin Lee     * Returns {@code true} if the entry no longer exists.
2773876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin     */
2783876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin    static boolean deletePrivateKeyTypeForAlias(KeyStore keystore, String alias, int uid) {
2793876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin        return keystore.delete(Credentials.USER_PRIVATE_KEY + alias, uid);
280baf2838fd2c7ddf517bd5bd9917551a4706af5b6Alex Klyubin    }
281baf2838fd2c7ddf517bd5bd9917551a4706af5b6Alex Klyubin
282baf2838fd2c7ddf517bd5bd9917551a4706af5b6Alex Klyubin    /**
283baf2838fd2c7ddf517bd5bd9917551a4706af5b6Alex Klyubin     * Delete secret key for a particular {@code alias}.
284e4487ea288e9fea837995d9bc4608c8a4a253ec8Robin Lee     * Returns {@code true} if the entry no longer exists.
285baf2838fd2c7ddf517bd5bd9917551a4706af5b6Alex Klyubin     */
286dcdaf87ed0aa99073638bcfe645949f130f0c7adAlex Klyubin    public static boolean deleteSecretKeyTypeForAlias(KeyStore keystore, String alias) {
2873876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin        return deleteSecretKeyTypeForAlias(keystore, alias, KeyStore.UID_SELF);
2883876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin    }
2893876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin
2903876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin    /**
2913876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin     * Delete secret key for a particular {@code alias}.
292e4487ea288e9fea837995d9bc4608c8a4a253ec8Robin Lee     * Returns {@code true} if the entry no longer exists.
2933876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin     */
2943876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin    public static boolean deleteSecretKeyTypeForAlias(KeyStore keystore, String alias, int uid) {
2953876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin        return keystore.delete(Credentials.USER_SECRET_KEY + alias, uid);
296baf2838fd2c7ddf517bd5bd9917551a4706af5b6Alex Klyubin    }
2979b7a3f1a6437605022568cad0b92d5006a2ab391Chia-chi Yeh}
298