source: dispositivos_moviles/TibisayMovil/src/ve/gob/cenditel/tibisaymovil/PDFVerifyResultActivity.java @ 4c4873f

Last change on this file since 4c4873f was 4c4873f, checked in by Antonio Araujo Brett <aaraujo@…>, 10 years ago

Modificaciones para soportar la verificación de documentos PDF al seleccionarlos desde el sistema de archivos. La aplicación Tibisay Móvil se lista como aplicación disponible para abrir el documento PDF. En caso de estar firmado muestra los resultados de la verificación de la firma electrónica, en caso contrario permite lanzar un lector de documentos PDF.

  • Property mode set to 100644
File size: 16.8 KB
Line 
1package ve.gob.cenditel.tibisaymovil;
2
3import java.io.BufferedInputStream;
4import java.io.File;
5import java.io.InputStream;
6
7import android.net.Uri;
8import android.os.Bundle;
9import android.app.Activity;
10import android.content.Context;
11import android.content.Intent;
12import android.util.Log;
13import android.view.LayoutInflater;
14import android.view.View;
15import android.view.ViewGroup;
16import android.view.Window;
17import android.view.View.OnClickListener;
18import android.webkit.MimeTypeMap;
19import android.widget.AdapterView;
20import android.widget.BaseAdapter;
21import android.widget.ImageView;
22import android.widget.LinearLayout;
23import android.widget.ListView;
24import android.widget.TextView;
25import android.widget.Toast;
26
27import java.security.*;
28import java.security.cert.Certificate;
29import java.security.cert.CertificateFactory;
30import java.io.*;
31import java.lang.reflect.Field;
32
33import com.lowagie.text.pdf.*;
34
35import ee.sk.digidoc.SignedDoc;
36import ee.sk.utils.ConvertUtils;
37
38import java.util.Calendar;
39import java.util.ArrayList;
40import java.util.Random;
41import java.security.cert.X509Certificate;
42import java.text.SimpleDateFormat;
43
44
45
46
47
48
49
50
51public class PDFVerifyResultActivity extends Activity {
52
53        private LinearLayout button_share;
54    private LinearLayout button_finish;
55
56    // ruta absoluta al archivo a verificar
57    private String pdfToVerify;
58       
59        @Override
60        protected void onCreate(Bundle savedInstanceState) {
61               
62               
63               
64                //Estilando la barra de titulo
65                final boolean customTitleSupported = requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
66               
67                super.onCreate(savedInstanceState);
68               
69                setContentView(R.layout.activity_verify_result_pdf);
70               
71                //Estilando Barra de titulo
72                if(customTitleSupported)
73                        getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.title_bar);
74               
75                // obtener el archivo pdf a verificar
76                //Bundle bundle = getIntent().getExtras();
77                //pdfToVerify = bundle.getString("pdfToVerify");
78               
79                final android.net.Uri data = getIntent().getData ();
80         
81            if (data != null) { 
82                Toast.makeText(getApplicationContext(), "data != null", Toast.LENGTH_SHORT).show();
83                 
84                // verificar el tipo de scheme
85                String scheme = data.getScheme();
86                   
87                // verificacion de un archivo que esta en el dispositivo
88                if (scheme.equals("file")) {
89                        Toast.makeText(getApplicationContext(), "file: "+data.getPath(), Toast.LENGTH_SHORT).show();
90                        pdfToVerify = data.getPath();                     
91                }                 
92            }else{
93                // obtener el archivo pdf a verificar
94                        Bundle bundle = getIntent().getExtras();
95                        pdfToVerify = bundle.getString("pdfToVerify");
96            }     
97               
98               
99                TextView pdfName = (TextView) this.findViewById(R.id.filename_text);
100                pdfName.setText(pdfToVerify);
101               
102                // ejecutar el proceso de verificacion del pdf
103                doVerification(pdfToVerify);
104               
105                LinearLayout layoutPdfFileResult = (LinearLayout) this.findViewById(R.id.layout_pdf_signed_result);
106       
107        OnClickListener pdfFileListener = new OnClickListener() {
108            public void onClick(View v) {
109               
110                //Toast.makeText(getApplicationContext(), "**CLICK SOBRE EL archivo***", Toast.LENGTH_LONG).show();
111               
112                openIt(pdfToVerify, getMimeType(pdfToVerify));
113            }
114        };
115        layoutPdfFileResult.setOnClickListener(pdfFileListener);
116               
117               
118               
119                // habilitar opciones de botones inferiores
120                button_share = (LinearLayout) this.findViewById(R.id.button_remove_certificate_zone);
121        button_finish = (LinearLayout) this.findViewById(R.id.button_add_certificate_zone);
122               
123        // habilita el click sobre la acción de finalizar la verificacion de firma y regresar
124        button_finish.setOnClickListener(new OnClickListener() 
125        {       
126                public void onClick(View v) 
127                {
128               
129                        Intent oIntent = new Intent(PDFVerifyResultActivity.this, TibisayMovilActivity.class);
130                        oIntent.setAction(Intent.ACTION_VIEW);
131                        oIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
132                        startActivity(oIntent);
133               
134                        finish();
135                }
136        });
137
138        // habilita el click sobre la acción de compartir el archivo
139        button_share.setOnClickListener(new OnClickListener() 
140        {       
141                public void onClick(View v) 
142                {
143                        shareIt();
144                }
145        });
146
147   
148   
149        } // fin de onCreate
150       
151       
152        /**
153     * Ejecuta la verificacion de la firma del pdf utilizando la biblioteca droidtext
154     *
155     * */
156    private void doVerification(String pdfToVerify) {
157       
158       
159        try {
160
161                Random rnd = new Random();
162                       
163                PdfReader reader = new PdfReader(pdfToVerify);
164                Log.d("VerificadorPDF", "new PdfReader");
165       
166                AcroFields af = reader.getAcroFields();
167                Log.d("VerificadorPDF", "reader.getAcroFields()");
168       
169                ArrayList names = af.getSignatureNames();
170                Log.d("VerificadorPDF", "af.getSignatureNames()");
171               
172                //Toast.makeText(getApplicationContext(), "names.size: "+ Integer.toString(names.size()), Toast.LENGTH_SHORT).show();
173                Log.d("VerificadorPDF", Integer.toString(names.size()));
174               
175                if (names.size() == 0) {
176                        // el archivo no posee firmas
177                        TextView signatureMessage = (TextView) this.findViewById(R.id.archivo_original_a_descifrar);
178                        signatureMessage.setText("El documento PDF no está firmado electrónicamente.");
179                       
180                        TextView labelSignature = (TextView) this.findViewById(R.id.label_archivo_original);
181                        labelSignature.setText("Documento:");
182                       
183                        TextView labelSigners = (TextView) this.findViewById(R.id.label_destinatario_cifrado);
184                        labelSigners.setVisibility(View.GONE);
185                       
186                        ListView listViewSigners = (ListView) this.findViewById(R.id.signatures_list);
187                        listViewSigners.setVisibility(View.GONE);
188                        return;
189                }else{
190                        // el documento si posee firmas
191                        //KeyStore kall = PdfPKCS7.loadCacertsKeyStore();
192
193                        // crear certificate factory
194                        CertificateFactory cf = CertificateFactory.getInstance("X.509");
195                       
196                        // crear un KeyStore
197                        String keyStoreType = KeyStore.getDefaultType();
198                KeyStore kall = KeyStore.getInstance(keyStoreType);
199                kall.load(null, null);
200               
201             // obtener vector de campos de /res/raw
202                        Field[] fields = R.raw.class.getFields();
203                       
204                        InputStream caInput = null; 
205                       
206                        // iterar sobre todos los certificados incluidos en /res/raw y cargarlos
207                        // en el KeyStore
208                        for (int l=0; l < fields.length; l++) {
209                                try {
210                                        //Toast.makeText(getApplicationContext(), "PDFVerifyResultActivity - reading certificate: "+Integer.toString(l)+ " "+
211                                        //      Integer.toString(fields[l].getInt(null)), Toast.LENGTH_SHORT).show();
212
213                                        caInput = new BufferedInputStream(getResources().openRawResource(fields[l].getInt(null))); 
214
215                                } catch (IllegalArgumentException e) {
216
217                                        Toast.makeText(getApplicationContext(), "PDFVerifyResultActivity: IllegalArgumentException "+e.getMessage(),
218                                                        Toast.LENGTH_SHORT).show();
219                                        break;
220                                } catch (IllegalAccessException e) {
221
222                                        Toast.makeText(getApplicationContext(), "PDFVerifyResultActivity: IllegalAccessException "+e.getMessage(),
223                                                        Toast.LENGTH_SHORT).show();
224                                        break;
225                                }
226                                                                 
227                    Certificate ca;
228                    try {
229                        ca = cf.generateCertificate(caInput);
230                        //Log.d("**ca:", ((X509Certificate) ca).getSubjectDN());
231                                   
232                        //Log.d("*** try: ca.toString()", ca.toString());
233                        } finally {
234                            caInput.close();
235                        }
236                                kall.setCertificateEntry("ca"+Integer.toString(l), ca);
237                        }// fin de la iteracion sobre /res/raw
238                       
239                       
240                        // se crea el adaptador para mostrar los firmantes del contenedor
241                        ListView signerListView = (ListView) findViewById(R.id.signatures_list);
242                        final ArrayList<SignerFromPDF> signers = new ArrayList<SignerFromPDF>();
243
244                        boolean invalidSignature = false;
245                       
246                        for (int i = 0; i < names.size(); i++){                                 
247                               
248                                String name = (String)names.get(i);
249                                PdfPKCS7 pk = af.verifySignature(name);
250                    Calendar cal = pk.getSignDate();
251                    Certificate pkc[] = pk.getCertificates();
252                   
253                    X509Certificate cert = (X509Certificate) pk.getSigningCertificate();
254                                                       
255                                String cn = cert.getSubjectDN().toString();
256                        String signerName = ConvertUtils.getCommonName(cn);
257                       
258                        SimpleDateFormat date_format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SS");
259                        String date = date_format.format(pk.getSignDate().getTime());
260
261                        String certificateSerial = cert.getSerialNumber().toString();
262                        String validFrom = cert.getNotBefore().toString();
263                        String validUntil = cert.getNotAfter().toString();
264                        String certificateIssuer = cert.getIssuerDN().toString();
265                               
266                        Object fails[] = PdfPKCS7.verifyCertificates(pkc, kall, null, cal);
267                    if (fails == null) {
268                        System.out.print(pk.getSignName());
269                        Toast.makeText(getApplicationContext(), "Firma Válida", Toast.LENGTH_SHORT).show();
270                    }
271                    else {
272                        System.out.print("Firma no válida");
273                        Toast.makeText(getApplicationContext(), "Firma NO Válida", Toast.LENGTH_SHORT).show();
274                       
275                        invalidSignature = true;             
276                    }
277                       
278                        // agregar el nombre comun del firmante y la fecha y la hora
279                                signers.add(new SignerFromPDF(signerName, cn, date, certificateSerial, validFrom, validUntil, certificateIssuer));
280                               
281                                TextView signatureValidation = (TextView) this.findViewById(R.id.archivo_original_a_descifrar);
282                               
283                                if (invalidSignature){
284                                        signatureValidation.setText("Firma Inválida");
285                                }else{
286                                        signatureValidation.setText("Firma Válida");
287                                }
288                               
289                               
290                        }
291                       
292                        SignerFromPDFAdapter signerAdapter = new SignerFromPDFAdapter(PDFVerifyResultActivity.this, signers);
293                    signerListView.setAdapter(signerAdapter);
294                    signerListView.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener() {
295
296                       
297                                @Override
298                                public void onItemClick(AdapterView<?> parent, View view,
299                                                int position, long id) {
300                                                                               
301                                        //Toast.makeText(getApplicationContext(), "SE DEBE MOSTRAR INFORMACIÓN DEL FIRMANTE", Toast.LENGTH_SHORT).show();
302                                        showSignatureDetails(position, signers); 
303                                }
304                               
305                        });
306
307                       
308                       
309                } // fin de else: el documento posee firmas
310               
311               
312        }catch(Exception e){
313                Toast.makeText(getApplicationContext(), "Error al verificar pdf:"+e.getMessage(), Toast.LENGTH_LONG).show();
314        }
315       
316        }
317
318
319        // funcion para compartir el documento
320        private void shareIt() {
321               
322                Intent shareIntent = new Intent();
323                shareIntent.setAction(Intent.ACTION_SEND);
324                File file = new File(pdfToVerify);
325               
326               
327                Uri uri = Uri.fromFile(file);
328                Log.i("DEBUG", file.getPath());
329                //Log.d("******", getMimeType(file.getPath()));
330                //shareIntent.setDataAndType(uri, getMimeType(file.getPath()));
331                shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
332                shareIntent.setType("application/*");
333                startActivity(Intent.createChooser(shareIntent, getResources().getText(R.string.share_it_using)));
334        }
335
336       
337        // class que abstrae un firmante incluido en un contenedor BDOC
338        private class SignerFromPDF {
339               
340                // nombre del firmante
341                private String mName;
342               
343                // nombre comun del firmante
344                private String mCN;
345               
346                // fecha y hora de la firma
347                private String mDate;
348               
349                // serial del certificado
350                private String mCertificateSerial;
351               
352                // fecha de validez inicial
353                private String mValidFrom;
354               
355                // fecha de validez final
356                private String mValidUntil;
357               
358                // emisor del certificado
359                private String mCertificateIssuer;
360               
361                public SignerFromPDF(String name, String cn, String date, String serial, String validFrom, String validUntil, String issuer){
362                        mName = name;
363                        mCN = cn;
364                        mDate = date;
365                        mCertificateSerial = serial;
366                        mValidFrom = validFrom;
367                        mValidUntil = validUntil;
368                        mCertificateIssuer = issuer;                   
369                }
370               
371                public void setName(String name) {
372                        this.mName = name;
373                }
374               
375                public String getName() {
376                        return mName;
377                }       
378               
379                public void setCN(String cn) {
380                        this.mCN = cn;
381                }
382               
383                public String getCN() {
384                        return mCN;
385                }               
386               
387                public void setDate(String date) {
388                        this.mDate = date;
389                }
390               
391                public String getDate() {
392                        return mDate;
393                }
394               
395                public void setCertificateSerial(String certSerial) {
396                        this.mCertificateSerial = certSerial;
397                }
398               
399                public String getCertificateSerial() {
400                        return mCertificateSerial;
401                }
402               
403                public void setValidFrom(String validFrom) {
404                        this.mValidFrom = validFrom;
405                }
406               
407                public String getValidFrom() {
408                        return mValidFrom;
409                }
410               
411                public void setValidUntil(String validUntil) {
412                        this.mValidUntil = validUntil;
413                }
414               
415                public String getValidUntil() {
416                        return mValidUntil;
417                }
418               
419                public void setCertificateIssuer(String certIssuer) {
420                        this.mCertificateIssuer = certIssuer;
421                }
422               
423                public String getCertificateIssuer() {
424                        return mCertificateIssuer;
425                }
426               
427        } // fin de clase SignerFromPDF
428       
429        // clase que abstrae el adaptador para llenar el ListView de documentos que
430        // se encuentran dentro del contenedor BDOC
431        private class SignerFromPDFAdapter extends BaseAdapter {
432
433                private ArrayList<SignerFromPDF> mSignerFromPDFList;
434                private LayoutInflater lInflater;
435               
436                private SignerFromPDFAdapter(Context context, ArrayList<SignerFromPDF> signers) {
437                        this.lInflater = LayoutInflater.from(context);
438                        this.mSignerFromPDFList = signers;
439                       
440                }
441               
442               
443                @Override
444                public int getCount() {                 
445                        return mSignerFromPDFList.size();
446                }
447
448                @Override
449                public Object getItem(int position) {                   
450                        return mSignerFromPDFList.get(position);
451                }
452
453                @Override
454                public long getItemId(int position) {                   
455                        return position;
456                }
457
458                @Override
459                public View getView(int position, View convertView, ViewGroup parent) {
460                        ViewHolder container = null;
461                       
462                        if (convertView == null){
463                                container = new ViewHolder();
464                                convertView = lInflater.inflate(R.layout.signer_inside_bdoc_item, null);
465                               
466                                container.signer_text = (TextView) convertView.findViewById(R.id.signer_info);
467                                container.signer_modified = (TextView) convertView.findViewById(R.id.signature_errors);
468                                container.type_image = (ImageView) convertView.findViewById(R.id.type_image);
469                                convertView.setTag(container);
470                        }else{
471                                container = (ViewHolder) convertView.getTag();
472                        }
473                       
474                        SignerFromPDF doc = (SignerFromPDF) getItem(position);
475                        container.signer_text.setText(doc.getName());
476                        container.signer_modified.setText(doc.getName());
477                        container.type_image.setImageResource(R.drawable.ic_pluma);
478                       
479                        return convertView;
480                }
481       
482               
483                class ViewHolder{
484                      TextView signer_text;
485                      TextView signer_modified;
486                      ImageView type_image;
487                   }
488               
489        }
490       
491        /**
492     * Lanza la actividad para mostrar detalles de un firmante
493     *
494     * */
495        private void showSignatureDetails(int position, ArrayList<SignerFromPDF> signers) {
496               
497                Log.d("**showSignatureDetails", Integer.toString(position));
498                Log.d("** nombre", signers.get(position).getName());
499                Intent intent = new Intent(this, ActivitySignerInfo.class);
500               
501                intent.putExtra("name", signers.get(position).getName());
502                intent.putExtra("cn", signers.get(position).getCN());
503                intent.putExtra("date", signers.get(position).getDate());
504                intent.putExtra("certificateSerial", signers.get(position).getCertificateSerial());
505                intent.putExtra("validFrom", signers.get(position).getValidFrom());
506                intent.putExtra("validUntil", signers.get(position).getValidUntil());
507                intent.putExtra("certificateIssuer", signers.get(position).getCertificateIssuer());
508                startActivity(intent);
509        }
510       
511    // funcion para obtener el tipo mime de un archivo
512    public static String getMimeType(String url)
513    {
514        String extension = url.substring(url.lastIndexOf("."));
515        String mimeTypeMap = MimeTypeMap.getFileExtensionFromUrl(extension);
516        String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(mimeTypeMap);
517        return mimeType;
518    }
519
520       
521        // funcion para lanzar un intent que abra un archivo
522    private void openIt(String pdfFile, String mimeType) {
523               
524                Intent shareIntent = new Intent();
525                shareIntent.setAction(Intent.ACTION_VIEW);
526                File file = new File(pdfFile);
527                Uri uri = Uri.fromFile(file);
528                Log.i("DEBUG", file.getPath());
529                shareIntent.setDataAndType(uri, mimeType);             
530                startActivity(Intent.createChooser(shareIntent, getResources().getText(R.string.open_it_using)));
531        }
532       
533}
Note: See TracBrowser for help on using the repository browser.