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