• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.certinstaller;
18 
19 import android.content.Intent;
20 import android.net.Uri;
21 import android.os.Bundle;
22 import android.security.Credentials;
23 import android.security.KeyChain;
24 import android.util.Log;
25 import android.widget.Toast;
26 
27 import java.io.ByteArrayOutputStream;
28 import java.io.File;
29 import java.io.IOException;
30 import java.io.InputStream;
31 import java.util.List;
32 
33 import libcore.io.IoUtils;
34 
35 /**
36  * The main class for installing certificates to the system keystore. It reacts
37  * to the public {@link Credentials#INSTALL_ACTION} intent.
38  */
39 public class CertInstallerMain extends CertFile implements Runnable {
40     @Override
onCreate(Bundle savedInstanceState)41     protected void onCreate(Bundle savedInstanceState) {
42         super.onCreate(savedInstanceState);
43         if (savedInstanceState != null) {
44             return;
45         }
46 
47         new Thread(new Runnable() {
48             @Override
49             public void run() {
50                 // don't want to call startActivityForResult() (invoked in
51                 // installFromFile()) here as it makes the new activity (thus
52                 // the whole display) get stuck for about 5 seconds
53                 runOnUiThread(CertInstallerMain.this);
54             }
55         }).start();
56     }
57 
58     @Override
run()59     public void run() {
60         Intent intent = getIntent();
61         String action = (intent == null) ? null : intent.getAction();
62 
63         if (Credentials.INSTALL_ACTION.equals(action)) {
64             Bundle bundle = intent.getExtras();
65             // If bundle is empty of any actual credentials, install from external storage.
66             // Otherwise, pass extras to CertInstaller to install those credentials.
67             // Either way, we use KeyChain.EXTRA_NAME as the default name if available.
68             if (bundle == null
69                     || bundle.isEmpty()
70                     || (bundle.size() == 1 && bundle.containsKey(KeyChain.EXTRA_NAME))) {
71                 if (!isSdCardPresent()) {
72                     Toast.makeText(this, R.string.sdcard_not_present,
73                             Toast.LENGTH_SHORT).show();
74                 } else {
75                     List<File> allFiles = getAllCertFiles();
76                     if (allFiles.isEmpty()) {
77                         Toast.makeText(this, R.string.no_cert_file_found,
78                                 Toast.LENGTH_SHORT).show();
79                     } else if (allFiles.size() == 1) {
80                         installFromFile(allFiles.get(0));
81                         return;
82                     } else {
83                         Intent newIntent = new Intent(this, CertFileList.class);
84                         newIntent.putExtras(intent);
85                         startActivityForResult(newIntent, REQUEST_INSTALL_CODE);
86                         return;
87                     }
88                 }
89             } else {
90                 Intent newIntent = new Intent(this, CertInstaller.class);
91                 newIntent.putExtras(intent);
92                 startActivityForResult(newIntent, REQUEST_INSTALL_CODE);
93                 return;
94             }
95         } else if (Intent.ACTION_VIEW.equals(action)) {
96             Uri data = intent.getData();
97             String type = intent.getType();
98             if ((data != null) && (type != null)) {
99                 byte[] payload = null;
100                 InputStream is = null;
101                 try {
102                     is = getContentResolver().openInputStream(data);
103                     ByteArrayOutputStream out = new ByteArrayOutputStream();
104                     byte[] buffer = new byte[1024];
105                     int read = 0;
106                     while ((read = is.read(buffer)) > 0) {
107                         out.write(buffer, 0, read);
108                     }
109                     out.flush();
110                     payload = out.toByteArray();
111                 } catch (IOException ignored) {
112                     // Not much we can do - it will be logged below as an error.
113                 } finally {
114                     IoUtils.closeQuietly(is);
115                 }
116                 if (payload == null) {
117                     Log.e("CertInstaller", "Unable to read stream for for certificate");
118                 } else {
119                     installByType(type, payload);
120                 }
121             }
122         }
123         finish();
124     }
125 
installByType(String type, byte[] value)126     private void installByType(String type, byte[] value) {
127         Intent intent = new Intent(this, CertInstaller.class);
128         if ("application/x-pkcs12".equals(type)) {
129             intent.putExtra(KeyChain.EXTRA_PKCS12, value);
130         } else if ("application/x-x509-ca-cert".equals(type)
131                 || "application/x-x509-user-cert".equals(type)) {
132             intent.putExtra(KeyChain.EXTRA_CERTIFICATE, value);
133         } else {
134             throw new AssertionError("Unknown type: " + type);
135         }
136         startActivityForResult(intent, REQUEST_INSTALL_CODE);
137     }
138 
139     @Override
onInstallationDone(boolean success)140     protected void onInstallationDone(boolean success) {
141         super.onInstallationDone(success);
142         finish();
143     }
144 
145     @Override
onError(int errorId)146     protected void onError(int errorId) {
147         finish();
148     }
149 }
150