package ve.gob.cenditel.tibisaymovil; import java.io.BufferedInputStream; import java.io.File; import java.io.InputStream; import android.net.Uri; import android.os.Bundle; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.view.View.OnClickListener; import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; import java.security.*; import java.security.cert.Certificate; import java.security.cert.CertificateFactory; import java.io.*; import java.lang.reflect.Field; import com.lowagie.text.pdf.*; import ee.sk.digidoc.SignedDoc; import ee.sk.utils.ConvertUtils; import java.util.Calendar; import java.util.ArrayList; import java.util.Random; import java.security.cert.X509Certificate; import java.text.SimpleDateFormat; public class PDFVerifyResultActivity extends Activity { private LinearLayout button_share; private LinearLayout button_finish; // ruta absoluta al archivo a verificar private String pdfToVerify; @Override protected void onCreate(Bundle savedInstanceState) { //Estilando la barra de titulo final boolean customTitleSupported = requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); super.onCreate(savedInstanceState); setContentView(R.layout.activity_verify_result_pdf); //Estilando Barra de titulo if(customTitleSupported) getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.title_bar); // obtener el archivo pdf a verificar Bundle bundle = getIntent().getExtras(); pdfToVerify = bundle.getString("pdfToVerify"); TextView pdfName = (TextView) this.findViewById(R.id.filename_text); pdfName.setText(pdfToVerify); // ejecutar el proceso de verificacion del pdf doVerification(pdfToVerify); // habilitar opciones de botones inferiores button_share = (LinearLayout) this.findViewById(R.id.button_remove_certificate_zone); button_finish = (LinearLayout) this.findViewById(R.id.button_add_certificate_zone); // habilita el click sobre la acción de finalizar la verificacion de firma y regresar button_finish.setOnClickListener(new OnClickListener() { public void onClick(View v) { Intent oIntent = new Intent(PDFVerifyResultActivity.this, TibisayMovilActivity.class); oIntent.setAction(Intent.ACTION_VIEW); oIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(oIntent); finish(); } }); // habilita el click sobre la acción de compartir el archivo button_share.setOnClickListener(new OnClickListener() { public void onClick(View v) { shareIt(); } }); } // fin de onCreate /** * Ejecuta la verificacion de la firma del pdf utilizando la biblioteca droidtext * * */ private void doVerification(String pdfToVerify) { try { Random rnd = new Random(); PdfReader reader = new PdfReader(pdfToVerify); Log.d("VerificadorPDF", "new PdfReader"); AcroFields af = reader.getAcroFields(); Log.d("VerificadorPDF", "reader.getAcroFields()"); ArrayList names = af.getSignatureNames(); Log.d("VerificadorPDF", "af.getSignatureNames()"); Toast.makeText(getApplicationContext(), "names.size: "+ Integer.toString(names.size()), Toast.LENGTH_SHORT).show(); Log.d("VerificadorPDF", Integer.toString(names.size())); if (names.size() == 0) { // el archivo no posee firmas TextView signatureMessage = (TextView) this.findViewById(R.id.archivo_original_a_descifrar); signatureMessage.setText("El documento PDF no está firmado electrónicamente."); TextView labelSignature = (TextView) this.findViewById(R.id.label_archivo_original); labelSignature.setText("Documento:"); TextView labelSigners = (TextView) this.findViewById(R.id.label_destinatario_cifrado); labelSigners.setVisibility(View.GONE); ListView listViewSigners = (ListView) this.findViewById(R.id.signatures_list); listViewSigners.setVisibility(View.GONE); return; }else{ // el documento si posee firmas //KeyStore kall = PdfPKCS7.loadCacertsKeyStore(); // crear certificate factory CertificateFactory cf = CertificateFactory.getInstance("X.509"); // crear un KeyStore String keyStoreType = KeyStore.getDefaultType(); KeyStore kall = KeyStore.getInstance(keyStoreType); kall.load(null, null); // obtener vector de campos de /res/raw Field[] fields = R.raw.class.getFields(); InputStream caInput = null; // iterar sobre todos los certificados incluidos en /res/raw y cargarlos // en el KeyStore for (int l=0; l < fields.length; l++) { try { Toast.makeText(getApplicationContext(), "PDFVerifyResultActivity - reading certificate: "+Integer.toString(l)+ " "+ Integer.toString(fields[l].getInt(null)), Toast.LENGTH_SHORT).show(); caInput = new BufferedInputStream(getResources().openRawResource(fields[l].getInt(null))); } catch (IllegalArgumentException e) { Toast.makeText(getApplicationContext(), "PDFVerifyResultActivity: IllegalArgumentException "+e.getMessage(), Toast.LENGTH_SHORT).show(); break; } catch (IllegalAccessException e) { Toast.makeText(getApplicationContext(), "PDFVerifyResultActivity: IllegalAccessException "+e.getMessage(), Toast.LENGTH_SHORT).show(); break; } Certificate ca; try { ca = cf.generateCertificate(caInput); //Log.d("**ca:", ((X509Certificate) ca).getSubjectDN()); //Log.d("*** try: ca.toString()", ca.toString()); } finally { caInput.close(); } kall.setCertificateEntry("ca"+Integer.toString(l), ca); }// fin de la iteracion sobre /res/raw // se crea el adaptador para mostrar los firmantes del contenedor ListView signerListView = (ListView) findViewById(R.id.signatures_list); final ArrayList signers = new ArrayList(); boolean invalidSignature = false; for (int i = 0; i < names.size(); i++){ String name = (String)names.get(i); PdfPKCS7 pk = af.verifySignature(name); Calendar cal = pk.getSignDate(); Certificate pkc[] = pk.getCertificates(); X509Certificate cert = (X509Certificate) pk.getSigningCertificate(); String cn = cert.getSubjectDN().toString(); String signerName = ConvertUtils.getCommonName(cn); SimpleDateFormat date_format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SS"); String date = date_format.format(pk.getSignDate().getTime()); String certificateSerial = cert.getSerialNumber().toString(); String validFrom = cert.getNotBefore().toString(); String validUntil = cert.getNotAfter().toString(); String certificateIssuer = cert.getIssuerDN().toString(); Object fails[] = PdfPKCS7.verifyCertificates(pkc, kall, null, cal); if (fails == null) { System.out.print(pk.getSignName()); Toast.makeText(getApplicationContext(), "Firma Válida", Toast.LENGTH_SHORT).show(); } else { System.out.print("Firma no válida"); Toast.makeText(getApplicationContext(), "Firma NO Válida", Toast.LENGTH_SHORT).show(); invalidSignature = true; } // agregar el nombre comun del firmante y la fecha y la hora signers.add(new SignerFromPDF(signerName, cn, date, certificateSerial, validFrom, validUntil, certificateIssuer)); TextView signatureValidation = (TextView) this.findViewById(R.id.archivo_original_a_descifrar); if (invalidSignature){ signatureValidation.setText("Firma Inválida"); }else{ signatureValidation.setText("Firma Válida"); } } SignerFromPDFAdapter signerAdapter = new SignerFromPDFAdapter(PDFVerifyResultActivity.this, signers); signerListView.setAdapter(signerAdapter); signerListView.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView parent, View view, int position, long id) { Toast.makeText(getApplicationContext(), "SE DEBE MOSTRAR INFORMACIÓN DEL FIRMANTE", Toast.LENGTH_SHORT).show(); showSignatureDetails(position, signers); } }); } // fin de else: el documento posee firmas }catch(Exception e){ Toast.makeText(getApplicationContext(), "Error al verificar pdf:"+e.getMessage(), Toast.LENGTH_LONG).show(); } } // funcion para compartir el documento private void shareIt() { Intent shareIntent = new Intent(); shareIntent.setAction(Intent.ACTION_SEND); File file = new File(pdfToVerify); 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))); } // class que abstrae un firmante incluido en un contenedor BDOC private class SignerFromPDF { // nombre del firmante private String mName; // nombre comun del firmante private String mCN; // fecha y hora de la firma private String mDate; // serial del certificado private String mCertificateSerial; // fecha de validez inicial private String mValidFrom; // fecha de validez final private String mValidUntil; // emisor del certificado private String mCertificateIssuer; public SignerFromPDF(String name, String cn, String date, String serial, String validFrom, String validUntil, String issuer){ mName = name; mCN = cn; mDate = date; mCertificateSerial = serial; mValidFrom = validFrom; mValidUntil = validUntil; mCertificateIssuer = issuer; } public void setName(String name) { this.mName = name; } public String getName() { return mName; } public void setCN(String cn) { this.mCN = cn; } public String getCN() { return mCN; } public void setDate(String date) { this.mDate = date; } public String getDate() { return mDate; } public void setCertificateSerial(String certSerial) { this.mCertificateSerial = certSerial; } public String getCertificateSerial() { return mCertificateSerial; } public void setValidFrom(String validFrom) { this.mValidFrom = validFrom; } public String getValidFrom() { return mValidFrom; } public void setValidUntil(String validUntil) { this.mValidUntil = validUntil; } public String getValidUntil() { return mValidUntil; } public void setCertificateIssuer(String certIssuer) { this.mCertificateIssuer = certIssuer; } public String getCertificateIssuer() { return mCertificateIssuer; } } // fin de clase SignerFromPDF // clase que abstrae el adaptador para llenar el ListView de documentos que // se encuentran dentro del contenedor BDOC private class SignerFromPDFAdapter extends BaseAdapter { private ArrayList mSignerFromPDFList; private LayoutInflater lInflater; private SignerFromPDFAdapter(Context context, ArrayList signers) { this.lInflater = LayoutInflater.from(context); this.mSignerFromPDFList = signers; } @Override public int getCount() { return mSignerFromPDFList.size(); } @Override public Object getItem(int position) { return mSignerFromPDFList.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder container = null; if (convertView == null){ container = new ViewHolder(); convertView = lInflater.inflate(R.layout.signer_inside_bdoc_item, null); container.signer_text = (TextView) convertView.findViewById(R.id.signer_info); container.signer_modified = (TextView) convertView.findViewById(R.id.signature_errors); container.type_image = (ImageView) convertView.findViewById(R.id.type_image); convertView.setTag(container); }else{ container = (ViewHolder) convertView.getTag(); } SignerFromPDF doc = (SignerFromPDF) getItem(position); container.signer_text.setText(doc.getName()); container.signer_modified.setText(doc.getName()); container.type_image.setImageResource(R.drawable.ic_pluma); return convertView; } class ViewHolder{ TextView signer_text; TextView signer_modified; ImageView type_image; } } /** * Lanza la actividad para mostrar detalles de un firmante * * */ private void showSignatureDetails(int position, ArrayList signers) { Log.d("**showSignatureDetails", Integer.toString(position)); Log.d("** nombre", signers.get(position).getName()); Intent intent = new Intent(this, ActivitySignerInfo.class); intent.putExtra("name", signers.get(position).getName()); intent.putExtra("cn", signers.get(position).getCN()); intent.putExtra("date", signers.get(position).getDate()); intent.putExtra("certificateSerial", signers.get(position).getCertificateSerial()); intent.putExtra("validFrom", signers.get(position).getValidFrom()); intent.putExtra("validUntil", signers.get(position).getValidUntil()); intent.putExtra("certificateIssuer", signers.get(position).getCertificateIssuer()); startActivity(intent); } }