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.app.Activity; 20 import android.content.Intent; 21 import android.os.Bundle; 22 import android.os.Environment; 23 import android.preference.PreferenceActivity; 24 import android.security.Credentials; 25 import android.util.Log; 26 import android.widget.Toast; 27 28 import java.io.File; 29 import java.io.FileFilter; 30 import java.io.IOException; 31 import java.util.ArrayList; 32 import java.util.Collections; 33 import java.util.List; 34 35 /** 36 * Base class that deals with certificate files on the SD card. 37 */ 38 public class CertFile extends PreferenceActivity implements FileFilter { 39 static final int CERT_READ_ERROR = R.string.cert_read_error; 40 static final int CERT_TOO_LARGE_ERROR = R.string.cert_too_large_error; 41 static final int CERT_FILE_MISSING_ERROR = R.string.cert_missing_error; 42 43 static final String DOWNLOAD_DIR = "download"; 44 45 private static final String TAG = "CertFile"; 46 47 private static final String CERT_EXT = ".crt"; 48 private static final String PKCS12_EXT = ".p12"; 49 50 private static final String CERT_FILE_KEY = "cf"; 51 private static final int MAX_FILE_SIZE = 1000000; 52 private static final int REQUEST_INSTALL_CODE = 1; 53 54 private File mCertFile; 55 56 @Override 57 protected void onSaveInstanceState(Bundle outStates) { 58 super.onSaveInstanceState(outStates); 59 if (mCertFile != null) { 60 outStates.putString(CERT_FILE_KEY, mCertFile.getAbsolutePath()); 61 } 62 } 63 64 @Override 65 protected void onRestoreInstanceState(Bundle savedStates) { 66 super.onRestoreInstanceState(savedStates); 67 String path = savedStates.getString(CERT_FILE_KEY); 68 if (path != null) mCertFile = new File(path); 69 } 70 71 @Override 72 protected void onActivityResult(int requestCode, int resultCode, Intent data) { 73 if (requestCode == REQUEST_INSTALL_CODE) { 74 onInstallationDone((resultCode == RESULT_OK) 75 && Util.deleteFile(mCertFile)); 76 mCertFile = null; 77 } else { 78 Log.w(TAG, "unknown request code: " + requestCode); 79 } 80 } 81 82 /** 83 * Called when installation is done. 84 * 85 * @param success true if installation is done successfully 86 */ 87 protected void onInstallationDone(boolean success) { 88 } 89 90 /** 91 * Called when an error occurs when reading a certificate file. 92 * 93 * @param errorId one of {@link #CERT_READ_ERROR}, 94 * {@link #CERT_TOO_LARGE_ERROR} and {@link #CERT_FILE_MISSING_ERROR} 95 */ 96 protected void onError(int errorId) { 97 } 98 99 /** 100 * Returns a list of certificate files found on the SD card. 101 */ 102 protected List<File> getAllCertFiles() { 103 List<File> allFiles = new ArrayList<File>(); 104 File root = Environment.getExternalStorageDirectory(); 105 106 File download = new File(root, DOWNLOAD_DIR); 107 if (download != null) { 108 File[] files = download.listFiles(this); 109 if (files != null) Collections.addAll(allFiles, files); 110 } 111 112 File[] files = root.listFiles(this); 113 if (files != null) Collections.addAll(allFiles, files); 114 115 return allFiles; 116 } 117 118 /** 119 * Invokes {@link CertInstaller} to install the certificate(s) in the file. 120 * 121 * @param file the certificate file 122 */ 123 protected void installFromFile(File file) { 124 Log.d(TAG, "install cert from " + file); 125 126 if (file.exists()) { 127 if (file.length() < MAX_FILE_SIZE) { 128 byte[] data = Util.readFile(file); 129 if (data == null) { 130 toastError(CERT_READ_ERROR); 131 onError(CERT_READ_ERROR); 132 return; 133 } 134 mCertFile = file; 135 install(file.getName(), data); 136 } else { 137 Log.w(TAG, "cert file is too large: " + file.length()); 138 toastError(CERT_TOO_LARGE_ERROR); 139 onError(CERT_TOO_LARGE_ERROR); 140 } 141 } else { 142 Log.w(TAG, "cert file does not exist"); 143 toastError(CERT_FILE_MISSING_ERROR); 144 onError(CERT_FILE_MISSING_ERROR); 145 } 146 } 147 148 public boolean accept(File file) { 149 if (!file.isDirectory()) { 150 return isFileAcceptable(file.getPath()); 151 } else { 152 return false; 153 } 154 } 155 156 protected boolean isFileAcceptable(String path) { 157 return (path.endsWith(PKCS12_EXT) || path.endsWith(CERT_EXT)); 158 } 159 160 protected boolean isSdCardPresent() { 161 return Environment.getExternalStorageState().equals( 162 Environment.MEDIA_MOUNTED); 163 } 164 165 private void install(String fileName, byte[] value) { 166 Intent intent = new Intent(this, CertInstaller.class); 167 intent.putExtra(CredentialHelper.CERT_NAME_KEY, fileName); 168 if (fileName.endsWith(PKCS12_EXT)) { 169 intent.putExtra(Credentials.PKCS12, value); 170 } else { 171 intent.putExtra(Credentials.CERTIFICATE, value); 172 } 173 startActivityForResult(intent, REQUEST_INSTALL_CODE); 174 } 175 176 private void toastError(int msgId) { 177 Toast.makeText(this, msgId, Toast.LENGTH_LONG).show(); 178 } 179 } 180