Home | History | Annotate | Download | only in certinstaller
      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