/* Tibisay Movil Copyright (C) 2013 Antonio Araujo (aaraujo@cenditel.gob.ve), Jose Ruiz (jruiz@cenditel.gob.ve), Fundacion Centro Nacional de Desarrollo e Investigacion en Tecnologias Libres - CENDITEL. La Fundación CENDITEL concede permiso para usar, copiar, distribuir y/o modificar este programa, reconociendo el derecho que la humanidad posee al libre acceso al conocimiento, bajo los términos de la licencia de software GPL versión 2.0 de la Free Software Foundation. Este programa se distribuye con la esperanza de que sea util, pero SIN NINGUNA GARANTIA; tampoco las implicitas garantias de MERCANTILIDAD o ADECUACION A UN PROPOSITO PARTICULAR. Para mayor información sobre los términos de la licencia ver el archivo llamado "gpl-2.0.txt" en ingles. */ package ve.gob.cenditel.tibisaymovil; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.security.cert.X509Certificate; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.Vector; import com.lowagie.text.pdf.PdfReader; import ee.sk.digidoc.DataFile; import ee.sk.digidoc.DigiDocException; import ee.sk.digidoc.SignedDoc; import ee.sk.digidoc.factory.DigiDocFactory; import ee.sk.digidoc.factory.Pkcs12SignatureFactory; import ee.sk.utils.ConfigManager; import ee.sk.xmlenc.EncryptedData; import ee.sk.xmlenc.factory.EncryptedDataParser; import ve.gob.cenditel.tibisaymovil.R; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.app.ProgressDialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; import android.os.Environment; import android.os.Looper; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.View.OnClickListener; import android.view.Window; import android.webkit.MimeTypeMap; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.RadioButton; import android.widget.TextView; import android.widget.AdapterView.OnItemClickListener; import android.widget.Toast; public class PKCS12ToDecryptActivity extends Activity implements OnItemClickListener, OnClickListener { private File cwd; private File selected; private FileBrowserView viewHolder; private FileListAdapter listAdapter; private String filterMImeType = "application/*"; // cadena que mantiene la ruta del archivo descifrar private String fileToDecrypt = null; // cadena que mantiene la ruta del archivo descifrado private String decryptedFile = null; // cadena que mantiene la ruta del archivo PKCS12 private String pkcs12File = null; // contrasena del archivo p12 private String pkcs12Password = null; @Override protected void onCreate(Bundle savedInstanceState) { //Estilando la barra de titulo final boolean customTitleSupported = requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); super.onCreate(savedInstanceState); this.viewHolder = new FileBrowserView(); if (savedInstanceState != null) { if(savedInstanceState.getString("selected") != null) this.selected = new File(savedInstanceState.getString("selected")); if (this.selected != null) { PKCS12ToDecryptActivity.this.updateButton (PKCS12ToDecryptActivity.this.viewHolder.accept,true); } this.cwd = new File(savedInstanceState.getString("cwd")); this.viewHolder.fileList.setAdapter(this.listAdapter = new FileListAdapter(this.cwd.getAbsolutePath(), filterMImeType)); } else { this.selected = null; this.viewHolder.fileList.setAdapter(this.listAdapter = new FileListAdapter()); } boolean enabled = false; if (this.selected != null) enabled = this.viewHolder.accept.isEnabled(); PKCS12ToDecryptActivity.this.updateButton (PKCS12ToDecryptActivity.this.viewHolder.accept,enabled); //Estilando Barra de titulo if(customTitleSupported) getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.title_bar); // chequear si intent tiene data final android.content.Intent intent = getIntent(); final android.net.Uri data = intent.getData(); if (data != null) { // verificar el tipo de scheme String scheme = data.getScheme(); // descifrar un archivo que esta en el dispositivo if (scheme.equals("file")) { Log.d("PKCS12ToDecryptActivity: ", "scheme == file"); //Toast.makeText(getApplicationContext(), "Descifrar archivo: "+data.getPath(), Toast.LENGTH_SHORT).show(); // obtener archivo a descifrar if (data.getPath().endsWith("cdoc")){ fileToDecrypt = data.getPath(); }else{ Toast.makeText(getApplicationContext(), "¡Intentando descifrar un archivo distinto de .cdoc!", Toast.LENGTH_SHORT).show(); Log.d("PKCS12ToDecryptActivity: ", "¡Intentando descifrar un archivo distinto de .cdoc!"); finish(); } } }else{ final Bundle bundle = getIntent().getExtras(); // verificacion de archivo desde la Activity principal if (bundle != null) { Log.d("PKCS12ToDecryptActivity: ", "bundle != null"); // Capturando archivo original que se debe descifrar fileToDecrypt = getIntent().getExtras().getString("fileToDecrypt"); } } //Capturando archivo original que se debe descifrar //fileToDecrypt = getIntent().getExtras().getString("fileToDecrypt"); } /** * Provides the data to be shown in the file browser ListView. * * @author José M. Prieto (jmprieto@emergya.com) */ private class FileListAdapter extends BaseAdapter { private final ArrayList directories; private final ArrayList files; private FileListAdapter() { this("/",filterMImeType); } private FileListAdapter(String location) { this(location, ""); } private FileListAdapter(String location, String filterMimeType) { directories = new ArrayList(); files = new ArrayList(); //Obtiene etiqueta que se colocará antes del path que visualizará el usuario String toPathText = PKCS12ToDecryptActivity.this.getString(R.string.pathstring)+": "; //Coloca el texto de la etiqueta en la vista PKCS12ToDecryptActivity.this.viewHolder.pathString.setText(toPathText); //Coloca el texto con el path actual PKCS12ToDecryptActivity.this.viewHolder.path.setText(location); //Crea un objeto file cwd con la ubicacion dada en location PKCS12ToDecryptActivity.this.cwd = new File(location); //Obtiene el directorio padre del objeto file cwd File parent = PKCS12ToDecryptActivity.this.cwd.getParentFile(); //Si tiene un padre, lo agrega en la posición cero de la lista de directorios if (parent != null) { directories.add(0, parent); } //Crea un arreglo con las lista de archivos contenidos en el directorio cwd File[] ls = PKCS12ToDecryptActivity.this.cwd.listFiles(); if (ls != null) { for (File f : ls) { //recorre todos los archivos contenidos en el directorio if (FsUtils.isHiddenOrNotReadable(f)) { // Si son ocultos no hace nada continue; } // Si son directorios los agrega a la lista de directorios a partir de la posición 1 // En la posición 0 se encuentra el directorio padre if (f.isDirectory()) { directories.add(f); } else // De lo contrario lo agrega a la lista de archivos { //Valida tipo de archivo a mostrar Uri selectedUri = Uri.fromFile(f); String fileExtension = MimeTypeMap.getFileExtensionFromUrl(selectedUri.toString()); String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileExtension); // Toast.makeText(PKCS12ToDecryptActivity.this, // "FileExtension: " + fileExtension + "\n" + // "MimeType: " + mimeType, // Toast.LENGTH_LONG).show(); // en principio no filtrar ningun archivo if(filterMimeType.isEmpty() || filterMimeType == mimeType || fileExtension.equals("p12") || fileExtension.equals("pfx")) files.add(f); } } } Collections.sort(directories); // Ordena los directorios alfabeticamente Collections.sort(files); // Ordena los archivos alfabeticamente } /** * Retorna cantidad total de elementos que se listarán en el directorio. */ @Override public int getCount() { return directories.size() + files.size(); } /** * Dada una posición en el listado del directorio, retorna un archivo o directorio * según corresponda. */ @Override public File getItem(int position) { if (position < directories.size()) { return directories.get(position); } else { return files.get(position - directories.size()); } } /** * Retorna un código hash para el archivo, permite comparar si dos archivos son los mismos */ @Override public long getItemId(int position) { return getItem(position).hashCode(); } /** * Crea la visualización de cada item del fileBrowser */ @Override public View getView(int position, View convertView, ViewGroup parent) { //Crea la vista de cada fila del filebrowser a partir del layout if (convertView == null) { LayoutInflater inflater = LayoutInflater.from(PKCS12ToDecryptActivity.this); convertView = inflater.inflate(R.layout.file_to_verify_bdoc_signature_item, parent, false); } // Se enlaza a cada componente del layout ImageView image = (ImageView) convertView.findViewById(R.id.type_image); TextView fileName = (TextView) convertView.findViewById(R.id.filename_text); TextView modified = (TextView) convertView.findViewById(R.id.filename_modified); // Se obtiene el archivo ubicado en position File file = getItem(position); //RadioButton RadioButton radio = (RadioButton) convertView.findViewById(R.id.file_radio); radio.setFocusable(false); // Se asignan los iconos según el tipo de archivo y se oculta el radio en los directorios if (file.isDirectory()) { image.setImageResource(R.drawable.ic_carpeta); radio.setVisibility(View.INVISIBLE); radio.setChecked(false); } else { image.setImageResource(R.drawable.ic_archivo); radio.setVisibility(View.VISIBLE); if (PKCS12ToDecryptActivity.this.selected == null || PKCS12ToDecryptActivity.this.selected.hashCode() != file.hashCode()){ radio.setChecked(false); } else{ radio.setChecked(true); } } // Si es el directorio que hace referencia al padre le coloca como nombre ".." if (file.isDirectory() && position == 0 && ! "/".equals(PKCS12ToDecryptActivity.this.cwd.getAbsolutePath())) { fileName.setText(".."); } else { fileName.setText(file.getName()); } //Datos de modificación del archivo SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy"); Date date = new Date(file.lastModified()); String dateString = PKCS12ToDecryptActivity.this.getString(R.string.modified)+": "; if (file.lastModified()>0) modified.setText(dateString+sdf.format(date)); else modified.setText(dateString+"-"); return convertView; } /** * Controla la selección de cada item del fileBrowser */ public void select(ListView parent, int position) { File item = getItem(position); //Si es un directorio el seleccionado se hace un llamado del fileBrowser del directorio if (item.isDirectory()) { parent.setAdapter(PKCS12ToDecryptActivity.this.listAdapter = new FileListAdapter(item.getAbsolutePath(), filterMImeType)); } else { // Si es un archivo //Se agrega el archivo a la lista de seleccionados si no se encuentra en la misma if (PKCS12ToDecryptActivity.this.selected == null || PKCS12ToDecryptActivity.this.selected.hashCode() != item.hashCode()){ PKCS12ToDecryptActivity.this.selected = item; PKCS12ToDecryptActivity.this.updateButton(PKCS12ToDecryptActivity.this.viewHolder.accept,true); } else{ // De lo contrario se elimina de la lista de seleccionados PKCS12ToDecryptActivity.this.selected = null; PKCS12ToDecryptActivity.this.updateButton(PKCS12ToDecryptActivity.this.viewHolder.accept,false); } notifyDataSetChanged(); } } } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putParcelable("intent", this.getIntent()); outState.putString("cwd", this.cwd.getAbsolutePath()); if(this.selected != null) outState.putString("selected", this.selected.getAbsolutePath()); } private void updateButton(View v, boolean bool) { try{ v.setEnabled(bool); if (v instanceof TextView){ Drawable icon = ((TextView)v).getCompoundDrawables()[1]; if (icon!=null) if (bool) icon.setAlpha(255); else icon.setAlpha(127); } if (v instanceof ImageView){ ImageView result = (ImageView) v; if (bool) result.setAlpha(255); else result.setAlpha(127); } }catch(NullPointerException e){} } private void updateButton(LinearLayout layout, boolean bool) { try{ layout.setEnabled(bool); for (int i=0; i parent, View view, int position, long id) { if (parent.getId() == R.id.file_list) { // user selects a file this.listAdapter.select((ListView) parent, position); } else { // user de-selects a file //this.listAdapter.addIfSameDirectory(selectedAdapter.doUnselect((ListView) parent, position)); } //this.viewHolder.numSelected.setText(Integer.toString(this.selected.size())); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.button_clear_zone: this.selected = null; this.listAdapter.notifyDataSetChanged(); //this.viewHolder.numSelected.setText(""+this.selected.size()); this.updateButton(this.viewHolder.accept, false); break; case R.id.button_accept_zone: // lanzar intent para compartir el archivo seleccionado pkcs12File = PKCS12ToDecryptActivity.this.selected.getAbsolutePath(); // crear dialogo para solicitar la contrasena del PKCS12 Dialog d = onCreateDialog(); d.show(); //Toast.makeText(getApplicationContext(), "PKCS12ToDecryptActivity - PKCS12: "+pkcs12File, Toast.LENGTH_SHORT).show(); break; } } // funcion para compartir el archivo private void shareIt() { Intent shareIntent = new Intent(); shareIntent.setAction(Intent.ACTION_SEND); File file = new File(fileToDecrypt); Uri uri = Uri.fromFile(file); Log.i("DEBUG", file.getPath()); //Log.d("******", getMimeType(file.getPath())); //shareIntent.setDataAndType(uri, getMimeType(file.getPath())); shareIntent.putExtra(Intent.EXTRA_STREAM, uri); shareIntent.setType("application/*"); startActivity(Intent.createChooser(shareIntent, getResources().getText(R.string.share_it_using))); } /** * Selecciona el certificado del destinatario del directorio de certificados * para cifrado * @return void */ // funcion para desplegar el gestor de certificados de destinatarios para cifrar private void selectCertificateToEncrypt(String fileToEncrypt) { // desplegar la actividad de gestor de certificados de destinatarios // chequear disponibilidad de directorio de certificados if (!checkCertificatesDirectoryAvailability()){ //Toast.makeText(getApplicationContext(), "PKCS12ToDecryptActivity: directorio no disponible", Toast.LENGTH_SHORT).show(); finish(); return; }else{ // lanzar el activity SelectCeritificateToEncryptActivity Intent intent = new Intent(this, SelectCertificateToEncryptActivity.class); intent.putExtra("fileToEncrypt", fileToEncrypt); startActivity(intent); } } // fin de selectRecipientCertificate() /** * Chequea la disponibilidad del directorio de /TibisayMovil/CertificatesToEncrypt * @return boolean */ private boolean checkCertificatesDirectoryAvailability() { // verificar acceso al directorio /mnt/sdcard/TibisayMovil/CertificatesToEncrypt boolean mExternalStorageAvailable = false; boolean mExternalStorageWriteable = false; String state = Environment.getExternalStorageState(); String certificatesDir = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + getResources().getString(R.string.app_name) + "/" + getResources().getString(R.string.certificate_dir_files) + "/"; AlertDialog.Builder builder = new AlertDialog.Builder(PKCS12ToDecryptActivity.this); if (Environment.MEDIA_MOUNTED.equals(state)) { // We can read and write the media mExternalStorageAvailable = mExternalStorageWriteable = true; //Toast.makeText(getApplicationContext(), "We can read and write the media", Toast.LENGTH_SHORT).show(); // Crear directorio CertificatesToEncrypt donde se almacenan los certificados de // destinatarios para cifrado /* String certificatesDir = Environment.getExternalStorageDirectory() + "/" + getResources().getString(R.string.app_name) + "/" + getResources().getString(R.string.certificates_dir) + "/"; */ if (prepareDirectory(certificatesDir)){ return true; }else{ builder.setMessage("No existe el directorio "+certificatesDir+" para almacenar certificados.").setTitle("Error:"); } } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) { // We can only read the media mExternalStorageAvailable = true; mExternalStorageWriteable = false; //Toast.makeText(getApplicationContext(), "We can only read the media", Toast.LENGTH_SHORT).show(); builder.setMessage("Directorio "+certificatesDir+ " montado de solo lectura. No se pueden almancenar certificados.").setTitle("Error:"); } else { // Something else is wrong. It may be one of many other states, but all we need // to know is we can neither read nor write mExternalStorageAvailable = mExternalStorageWriteable = false; //Toast.makeText(getApplicationContext(), "we can neither read nor write", Toast.LENGTH_SHORT).show(); builder.setMessage("Directorio "+certificatesDir+ " no está disponible. No se pueden almancenar certificados.").setTitle("Error:"); } builder.setNegativeButton("Cancelar", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { // User cancelled the dialog PKCS12ToDecryptActivity.this.finish(); } }); AlertDialog dialog = builder.create(); dialog.show(); return false; } // fin de checkCertificatesDirectoryAvailability /** * Prepara directorio * @return boolean */ boolean prepareDirectory(String dir) { try { if (makedirs(dir)) { return true; } else { return false; } } catch (Exception e) { e.printStackTrace(); //Toast.makeText(this, "Could not initiate File System.. Is Sdcard mounted properly?", Toast.LENGTH_LONG).show(); Toast.makeText(this, "No se pudo iniciar el sistema de archivos. ¿Está la SDCARD montada?", Toast.LENGTH_LONG).show(); return false; } } /** * Crea directorio utilizando la variable tmpDir * @return boolean */ private boolean makedirs(String dir) { //File tempdir = new File(extractedDirFiles); File tempdir = new File(dir); if (!tempdir.exists()) tempdir.mkdirs(); return (tempdir.isDirectory()); } /** * Crea dialogo para obtener la contrasena del archivo P12 * * @return Dialog */ public Dialog onCreateDialog() { LayoutInflater inflater = LayoutInflater.from(this); final View dialogview = inflater.inflate(R.layout.pkcs12_password, null); AlertDialog dialogDetails = null; final AlertDialog.Builder dialogbuilder = new AlertDialog.Builder(this); dialogbuilder.setTitle(R.string.title_pkcs12_password); dialogbuilder.setView(dialogview); final EditText password = (EditText) dialogview.findViewById(R.id.password); final Button okButton = (Button) dialogview.findViewById(R.id.button_accept); okButton.setEnabled(true); okButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // asignar la contrasena pkcs12Password = password.getText().toString(); if (!pkcs12Password.isEmpty()){ //Toast.makeText(PKCS12ToDecryptActivity.this,"PKCS12 Password : "+ password.getText().toString(), Toast.LENGTH_LONG).show(); password.setText(""); // ejecutar el proceso de descifrado. decryptFile(fileToDecrypt, pkcs12File, pkcs12Password); } // ejecutar el proceso de descifrado. //decryptFile(fileToDecrypt, pkcs12File, pkcs12Password); // borrar el contenido de pkcs12Password pkcs12Password = ""; } }); dialogDetails = dialogbuilder.create(); return dialogDetails; } /** * Descifra el archivo pasado como argumento con el archivo P12 * * @return void */ private void decryptFile(final String fileToDecrypt, final String pkcs12File, final String pkcs12Password) { //Toast.makeText(getApplicationContext(), "Decrypting file: " + fileToDecrypt, Toast.LENGTH_SHORT).show(); // ----------------------------- AsyncTask> task = new AsyncTask>() { private ProgressDialog pd; @Override protected void onPreExecute() { pd = new ProgressDialog(PKCS12ToDecryptActivity.this); pd.setTitle("Descifrando archivo"); pd.setMessage(getString(R.string.por_favor_epsere)); pd.setCancelable(false); pd.setIndeterminate(true); pd.show(); } @Override protected ArrayList doInBackground(Void... arg0) { /* try { Thread.sleep(3000); } catch(InterruptedException ex) { Thread.currentThread().interrupt(); } */ // para solventar error: // Can't create handler inside thread that has not called Looper.prepare() Looper.prepare(); // arreglo para almacenar resultado de la operacion ArrayList resultArray = new ArrayList(); resultArray.clear(); ConfigManager.init("jar://jdigidoc.cfg"); // signed doc object if used SignedDoc m_sdoc; m_sdoc = null; // encrypted data object if used EncryptedData m_cdoc; m_cdoc = null; String outFile = null, keystoreFile = null, keystorePasswd = null, keystoreType="PKCS12"; keystoreFile = pkcs12File; keystorePasswd = pkcs12Password; Log.d("Reading encrypted file: ", fileToDecrypt); try { EncryptedDataParser dencFac = ConfigManager.instance().getEncryptedDataParser(); m_cdoc = dencFac.readEncryptedData(fileToDecrypt); } catch(Exception ex) { System.err.println("ERROR: reading encrypted file: " + fileToDecrypt + " - " + ex); Log.d("ERROR: reading encrypted file: ", ex.getMessage()); ex.printStackTrace(System.err); Toast.makeText(getApplicationContext(), ex.getMessage(), Toast.LENGTH_SHORT).show(); //showDialog("Error:", ex.getMessage(), false); //return null; resultArray.add("false"); resultArray.add("Error"); resultArray.add(ex.getMessage()); return resultArray; } int nKey = -1; try{ Pkcs12SignatureFactory p12fac = new Pkcs12SignatureFactory(); p12fac.init(); System.out.println("p12fac.init " ); p12fac.load(keystoreFile, keystoreType, keystorePasswd); System.out.println("p12fac.load()"); X509Certificate cert = p12fac.getAuthCertificate(0, keystorePasswd); System.out.println("p12fac.getAuthCertificate: " + nKey); nKey = m_cdoc.getRecvIndex(cert); System.out.println("Using recipient: " + nKey); if (nKey == -1) { throw(new ArrayIndexOutOfBoundsException("")); } } // fin del try interno catch(DigiDocException ex){ System.err.println("ERROR: finding cdoc recipient: " + ex); Log.d("Error finding cdoc recipient: ", ex.getMessage()); ex.printStackTrace(System.err); Toast.makeText(getApplicationContext(), ex.getMessage(), Toast.LENGTH_SHORT).show(); if (ex.getCode() == DigiDocException.ERR_TOKEN_LOGIN) { // el pasword del PKCS12 no es correcto //showDialog(getResources().getString(R.string.msg_encryption_error), "password incorrecto", false); //return null; resultArray.add("false"); resultArray.add(getResources().getString(R.string.msg_encryption_error)); resultArray.add("contraseña incorrecta."); return resultArray; }else{ //showDialog(getResources().getString(R.string.msg_encryption_error), ex.getMessage(), false); //return null; resultArray.add("false"); resultArray.add(getResources().getString(R.string.msg_encryption_error)); resultArray.add(ex.getMessage()); return resultArray; } } catch(ArrayIndexOutOfBoundsException ex) { //showDialog(getResources().getString(R.string.msg_encryption_error), // getResources().getString(R.string.error_decrypting_file_index_out_of_bounds), false); //return null; resultArray.add("false"); resultArray.add(getResources().getString(R.string.msg_encryption_error)); resultArray.add(getResources().getString(R.string.error_decrypting_file_index_out_of_bounds)); return resultArray; } System.err.println("**** antes de ejecutar operacion m_cdoc.decryptPkcs12(nKey, keystoreFile, keystorePasswd, keystoreType)"); // ejecutar la operacion de descifrado: try { m_cdoc.decryptPkcs12(nKey, keystoreFile, keystorePasswd, keystoreType); String [] absolutePathOriginalFile = fileToDecrypt.split(".cdoc"); //String fileName = split[0]; outFile = absolutePathOriginalFile[0]; String [] path = absolutePathOriginalFile[0].split("/"); String originalFileName = path[path.length-1]; FileOutputStream fos = new FileOutputStream( outFile ); Log.d("Decrypting file", "antes de escribir archivo " + outFile); fos.write(m_cdoc.getData()); Log.d("Decrypting file", "despues de escribir archivo " + outFile); fos.close(); Log.d("Decrypting file", "despues de cerrar archivo " + outFile); DigiDocFactory digFac = ConfigManager.instance().getDigiDocFactory(); Log.d("Decrypting file", "despues ConfigManager.instance().getDigiDocFactory()"); File file = new File(outFile); InputStream selectedFile = null; selectedFile = new BufferedInputStream(new FileInputStream(file)); m_sdoc = digFac.readSignedDocFromStreamOfType(selectedFile, false); Log.d("----", "leyo el ddoc"); //Toast.makeText(getApplicationContext(), "leyó el ddoc", Toast.LENGTH_SHORT).show(); selectedFile.close(); // ******* Log.d("Decrypting file", "antes de m_sdoc.getDataFile(0)"); DataFile df = m_sdoc.getDataFile(0); Log.d("Decrypting file", "despues de m_sdoc.getDataFile(0)"); String decryptedDir = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + getResources().getString(R.string.app_name) + "/" + getResources().getString(R.string.decrypted_dir_files) + "/"; decryptedFile = decryptedDir+originalFileName; fos = new FileOutputStream(decryptedFile); InputStream is = df.getBodyAsStream(); if(is == null) { System.err.println("DataFile has no data!"); //showDialog(getResources().getString(R.string.msg_encryption_error), // "DataFile has no data!", false); //return null; resultArray.add("false"); resultArray.add(getResources().getString(R.string.msg_encryption_error)); resultArray.add("DataFile has no data!"); return resultArray; } byte[] data = new byte[4096]; int n = 0, m = 0; while((n = is.read(data)) > 0) { fos.write(data, 0, n); m += n; } fos.close(); is.close(); // borrar el archivo ddoc File ddocFile = new File(outFile); ddocFile.delete(); //Toast.makeText(getApplicationContext(), "Descifrado correctamente: " + decryptedFile, Toast.LENGTH_SHORT).show(); //showDialog("Información:", "Archivo descifrado exitosamente.", true); resultArray.add("true"); resultArray.add("Información:"); resultArray.add("Archivo descifrado exitosamente."); } catch (DigiDocException e) { //showDialog(getResources().getString(R.string.msg_encryption_error), // e.getMessage(), false); //return null; resultArray.add("false"); resultArray.add(getResources().getString(R.string.msg_encryption_error)); resultArray.add(e.getMessage()); return resultArray; } catch (FileNotFoundException e) { //showDialog(getResources().getString(R.string.msg_encryption_error), // e.getMessage(), false); //return null; resultArray.add("false"); resultArray.add(getResources().getString(R.string.msg_encryption_error)); resultArray.add(e.getMessage()); return resultArray; } catch (IOException e) { //showDialog(getResources().getString(R.string.msg_encryption_error), // e.getMessage(), false); //return null; resultArray.add("false"); resultArray.add(getResources().getString(R.string.msg_encryption_error)); resultArray.add(e.getMessage()); return resultArray; } return resultArray; } @Override protected void onPostExecute(ArrayList result) { if (result.get(0).equals("false")){ showDialog(result.get(1), result.get(2), false); }else{ showDialog(result.get(1), result.get(2), true); } pd.dismiss(); } }; task.execute((Void[])null); // ----------------------------- /* ConfigManager.init("jar://jdigidoc.cfg"); // signed doc object if used SignedDoc m_sdoc; m_sdoc = null; // encrypted data object if used EncryptedData m_cdoc; m_cdoc = null; String outFile = null, keystoreFile = null, keystorePasswd = null, keystoreType="PKCS12"; keystoreFile = pkcs12File; keystorePasswd = pkcs12Password; Log.d("Reading encrypted file: ", fileToDecrypt); try { EncryptedDataParser dencFac = ConfigManager.instance().getEncryptedDataParser(); m_cdoc = dencFac.readEncryptedData(fileToDecrypt); } catch(Exception ex) { System.err.println("ERROR: reading encrypted file: " + fileToDecrypt + " - " + ex); Log.d("ERROR: reading encrypted file: ", ex.getMessage()); ex.printStackTrace(System.err); Toast.makeText(getApplicationContext(), ex.getMessage(), Toast.LENGTH_SHORT).show(); showDialog("Error:", ex.getMessage(), false); return; } int nKey = -1; try{ Pkcs12SignatureFactory p12fac = new Pkcs12SignatureFactory(); p12fac.init(); System.out.println("p12fac.init " ); p12fac.load(keystoreFile, keystoreType, keystorePasswd); System.out.println("p12fac.load()"); X509Certificate cert = p12fac.getAuthCertificate(0, keystorePasswd); System.out.println("p12fac.getAuthCertificate: " + nKey); nKey = m_cdoc.getRecvIndex(cert); System.out.println("Using recipient: " + nKey); if (nKey == -1) { throw(new ArrayIndexOutOfBoundsException("")); } } // fin del try interno catch(DigiDocException ex){ System.err.println("ERROR: finding cdoc recipient: " + ex); Log.d("Error finding cdoc recipient: ", ex.getMessage()); ex.printStackTrace(System.err); Toast.makeText(getApplicationContext(), ex.getMessage(), Toast.LENGTH_SHORT).show(); if (ex.getCode() == DigiDocException.ERR_TOKEN_LOGIN) { // el pasword del PKCS12 no es correcto showDialog(getResources().getString(R.string.msg_encryption_error), "password incorrecto", false); return; } showDialog(getResources().getString(R.string.msg_encryption_error), ex.getMessage(), false); return; } catch(ArrayIndexOutOfBoundsException ex) { showDialog(getResources().getString(R.string.msg_encryption_error), getResources().getString(R.string.error_decrypting_file_index_out_of_bounds), false); return; } System.err.println("**** antes de ejecutar operacion m_cdoc.decryptPkcs12(nKey, keystoreFile, keystorePasswd, keystoreType)"); // ejecutar la operacion de descifrado: try { m_cdoc.decryptPkcs12(nKey, keystoreFile, keystorePasswd, keystoreType); String [] absolutePathOriginalFile = fileToDecrypt.split(".cdoc"); //String fileName = split[0]; outFile = absolutePathOriginalFile[0]; String [] path = absolutePathOriginalFile[0].split("/"); String originalFileName = path[path.length-1]; FileOutputStream fos = new FileOutputStream( outFile ); Log.d("Decrypting file", "antes de escribir archivo " + outFile); fos.write(m_cdoc.getData()); Log.d("Decrypting file", "despues de escribir archivo " + outFile); fos.close(); Log.d("Decrypting file", "despues de cerrar archivo " + outFile); DigiDocFactory digFac = ConfigManager.instance().getDigiDocFactory(); Log.d("Decrypting file", "despues ConfigManager.instance().getDigiDocFactory()"); File file = new File(outFile); InputStream selectedFile = null; selectedFile = new BufferedInputStream(new FileInputStream(file)); m_sdoc = digFac.readSignedDocFromStreamOfType(selectedFile, false); Log.d("----", "leyo el ddoc"); Toast.makeText(getApplicationContext(), "leyó el ddoc", Toast.LENGTH_SHORT).show(); selectedFile.close(); // ******* Log.d("Decrypting file", "antes de m_sdoc.getDataFile(0)"); DataFile df = m_sdoc.getDataFile(0); Log.d("Decrypting file", "despues de m_sdoc.getDataFile(0)"); String decryptedDir = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + getResources().getString(R.string.app_name) + "/" + getResources().getString(R.string.decrypted_dir_files) + "/"; decryptedFile = decryptedDir+originalFileName; fos = new FileOutputStream(decryptedFile); InputStream is = df.getBodyAsStream(); if(is == null) { System.err.println("DataFile has no data!"); showDialog(getResources().getString(R.string.msg_encryption_error), "DataFile has no data!", false); return; } byte[] data = new byte[4096]; int n = 0, m = 0; while((n = is.read(data)) > 0) { fos.write(data, 0, n); m += n; } fos.close(); is.close(); // borrar el archivo ddoc File ddocFile = new File(outFile); ddocFile.delete(); Toast.makeText(getApplicationContext(), "Descifrado correctamente: " + decryptedFile, Toast.LENGTH_SHORT).show(); showDialog("Información:", "Archivo descifrado exitosamente.", true); // TODO lanzar la actividad para mostrar el resultado del cifrado //showDecryptionResults(fileToDecrypt, decryptedFile); } catch (DigiDocException e) { showDialog(getResources().getString(R.string.msg_encryption_error), e.getMessage(), false); return; } catch (FileNotFoundException e) { showDialog(getResources().getString(R.string.msg_encryption_error), e.getMessage(), false); return; } catch (IOException e) { showDialog(getResources().getString(R.string.msg_encryption_error), e.getMessage(), false); return; } */ } // fin de void decryptFile(String fileToDecrypt, String pkcs12File) /** * Crea un dialogo con el titulo y mensaje como argumentos y lo despliega * * @return void */ public void showDialog(String title, String msg, final boolean success) { // 1. Instantiate an AlertDialog.Builder with its constructor AlertDialog.Builder builder = new AlertDialog.Builder(PKCS12ToDecryptActivity.this); // 2. Chain together various setter methods to set the dialog characteristics builder.setMessage(msg) .setTitle(title); builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { // User clicked OK button //Toast.makeText(getApplicationContext(), "User clicked OK button", Toast.LENGTH_LONG).show(); finish(); // TODO lanzar la actividad para mostrar el resultado del cifrado if (success){ showDecryptionResults(fileToDecrypt, decryptedFile); } } }); // 3. Get the AlertDialog from create() AlertDialog dialog = builder.create(); dialog.show(); } /** * Muestra la actividad de información del proceso de descifrado * * @return void */ public void showDecryptionResults(String fileToDecrypt, String decryptedFile) { // TODO lanzar el activity EncryptionResultActivity Intent intent = new Intent(this, DecryptionResultActivity.class); intent.putExtra("fileToDecrypt", fileToDecrypt); intent.putExtra("decryptedFile", decryptedFile); startActivity(intent); } }