/* 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.security.cert.CertificateException; import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateNotYetValidException; import java.security.cert.X509Certificate; import java.util.List; import org.spongycastle.cert.ocsp.OCSPException; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.res.Resources; import android.graphics.Point; import android.net.ConnectivityManager; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; import android.text.method.ScrollingMovementMethod; import android.view.Display; import android.view.LayoutInflater; import android.view.View; import android.view.Window; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.view.WindowManager; import android.widget.Button; import android.widget.CheckBox; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; public class CertValidatorActivity extends Activity implements OnClickListener { private final static int PENDING = -1; private final static int VALID = 0; private final static int INVALID = 1; private final static int ERROR = 2; private final static int NOT_CONNECTED = 3; //TODO: NEW private final static int EXPIRED = 4; private final static int NOTYETVALID = 5; private CertValidatorView viewHolder; private String alias; private List files; private AsyncTask certInfoTask = null; private AsyncTask validateTask = null; private int result = PENDING; boolean embedSignature; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { //Estilando la barra de titulo final boolean customTitleSupported = requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); super.onCreate(savedInstanceState); this.viewHolder = new CertValidatorView(); this.alias = getIntent().getStringExtra(IntentExtraField.ALIAS); this.files = getIntent().getParcelableArrayListExtra(IntentExtraField.FILES); this.embedSignature = getIntent().getBooleanExtra(IntentExtraField.EMBED_SIGNATURE_IN_PDF, false); Toast.makeText(this, "embebed="+embedSignature, Toast.LENGTH_SHORT).show(); if (files.isEmpty()) finish(); if (savedInstanceState == null || (this.result = savedInstanceState.getInt("result")) == PENDING) { startValidation(); } else { if (isConnected() && FsUtils.containsPDF(this.files)) { // CertValidatorActivity.this.viewHolder.embedSignature.setEnabled(true); } setValidationResult(this.result); } //Estilando Barra de titulo if(customTitleSupported) getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.title_bar); } @Override protected void onDestroy() { super.onDestroy(); if (this.certInfoTask != null) { this.certInfoTask.cancel(true); } if (this.validateTask != null) { this.validateTask.cancel(true); } } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putInt("result", this.result); } @Override public void onClick(View view) { switch (view.getId()) { case R.id.button_cancel_zone: setResult(RESULT_CANCELED); finish(); break; case R.id.button_accept_zone: Intent intent = new Intent(); intent.putExtra(IntentExtraField.EMBED_SIGNATURE_IN_PDF, embedSignature); setResult(Activity.RESULT_OK, intent); finish(); } } private boolean isConnected() { ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); return cm.getActiveNetworkInfo() != null && cm.getActiveNetworkInfo().isConnected(); } private void startValidation() { this.certInfoTask = new AsyncTask() { @Override protected X509Certificate[] doInBackground(String... alias) { KeyChainStrategy keyChain = KeyChainStrategy.getInstance(); X509Certificate[] chain = null; try { chain = keyChain.getCertificateChain(alias[0]); } catch (Exception e) { return null; } return chain; } @Override protected void onPostExecute(X509Certificate[] chain) { if (chain == null) { setValidationResult(CertValidatorActivity.ERROR); } else { CertValidatorActivity.this.viewHolder.setData( CertificateUtils.getSubject(chain[0]), CertificateUtils.getSerial(chain[0]), CertificateUtils.getIssuer(chain[0]), CertValidatorActivity.this.files); if (isConnected()) { if (FsUtils.containsPDF(CertValidatorActivity.this.files)) { // CertValidatorActivity.this.viewHolder.embedSignature.setEnabled(true); } // validate(chain); } else { setValidationResult(NOT_CONNECTED); } } } }.execute(alias); } private void validate(X509Certificate[] chain) { this.validateTask = new AsyncTask() { @Override protected Integer doInBackground(X509Certificate... params) { if (params.length < 2) { return ValidationResult.ERROR_CHAIN_RESULT; } try { params[0].checkValidity(); String DEFAULT_OCSP_RESPONDER = "http://ocsp.suscerte.gob.ve/"; //Antiguo /*if (CertificateUtils.checkWithOCSP(params[0], params[2],DEFAULT_OCSP_RESPONDER)) { return VALID; } else { return INVALID; }*/ ValidationResult res; res= CertificateUtils.checkWithOCSP(params[0], params[params.length-1],DEFAULT_OCSP_RESPONDER); int result = res.getResultValue(); if (result==ValidationResult.GOOD_RESULT) return VALID; else if (result==ValidationResult.ERROR_CONNECTION_RESULT) return NOT_CONNECTED; else return result; } catch (CertificateExpiredException e) { return EXPIRED; } catch (CertificateNotYetValidException e) { return NOTYETVALID; } catch (CertificateException e) { return ValidationResult.UNKNOWN_RESULT; } catch (OCSPException e) { return ValidationResult.UNKNOWN_RESULT; } catch (Exception e) { return ERROR; } } @Override protected void onPostExecute(Integer result) { CertValidatorActivity.this.setValidationResult(result); } }.execute(chain); } private void setValidationResult(int result) { this.result = result; this.viewHolder.accept.setEnabled(true); // this.viewHolder.validationStatus.removeAllViews(); LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams ( LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT, 0.5F); View v = null; TextView text; // switch (result) { // // // // case VALID: // v = inflater.inflate(R.layout.certificate_valid, null); // this.viewHolder.validationStatus.addView(v, params); // break; // case INVALID: // v = inflater.inflate(R.layout.certificate_not_valid, null); // this.viewHolder.validationStatus.addView(v, params); // break; // // case ERROR: // v=inflater.inflate(R.layout.certificate_validation_failed, null); // this.viewHolder.validationStatus.addView(v, params); // break; // // // //TODO: NEW MESSAGES // case ValidationResult.ERROR_CHAIN_RESULT: // v=inflater.inflate(R.layout.certificate_validation_failed, null); // text = (TextView) v.findViewById(R.id.fail_text); // text.setText(R.string.ERROR_CHAIN_RESULT); // this.viewHolder.validationStatus.addView(v, params); // break; // case ValidationResult.GOOD_RESULT: // v = inflater.inflate(R.layout.certificate_valid, null); // this.viewHolder.validationStatus.addView(v, params); // break; // // case ValidationResult.ERROR_CONNECTION_RESULT: // v = inflater.inflate(R.layout.certificate_not_connected, null); // this.viewHolder.validationStatus.addView(v, params); // break; // case ValidationResult.GOOD_UNTRUSTED_RESULT: // v=inflater.inflate(R.layout.certificate_validation_failed, null); // text = (TextView) v.findViewById(R.id.fail_text); // text.setText(R.string.GOOD_UNTRUSTED_RESULT); // this.viewHolder.validationStatus.addView(v, params); // break; // // case ValidationResult.REVOKED_RESULT: // v=inflater.inflate(R.layout.certificate_validation_failed, null); // text = (TextView) v.findViewById(R.id.fail_text); // text.setText(R.string.REVOKED_RESULT); // this.viewHolder.validationStatus.addView(v, params); // break; // // case ValidationResult.UNKNOWN_RESULT: // v=inflater.inflate(R.layout.certificate_validation_failed, null); // text = (TextView) v.findViewById(R.id.fail_text); // text.setText(R.string.UNKNOWN_RESULT); // this.viewHolder.validationStatus.addView(v, params); // break; // // case EXPIRED: // v=inflater.inflate(R.layout.certificate_validation_failed, null); // text = (TextView) v.findViewById(R.id.fail_text); // text.setText(R.string.EXPIRED); // this.viewHolder.validationStatus.addView(v, params); // break; // // case NOTYETVALID: // v=inflater.inflate(R.layout.certificate_validation_failed, null); // text = (TextView) v.findViewById(R.id.fail_text); // text.setText(R.string.NOTYETVALID); // this.viewHolder.validationStatus.addView(v, params); // break; // // default: // NOT_CONNECTED // v = inflater.inflate(R.layout.certificate_not_connected, null); // this.viewHolder.validationStatus.addView(v, params); // } WindowManager wm = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE); Display display = wm.getDefaultDisplay(); // this.viewHolder.validationStatus.setMinimumWidth(display.getWidth()/2); // this.viewHolder.embedSignature.setMinimumWidth(display.getWidth()/2); this.viewHolder.fixing.getParent().childDrawableStateChanged(this.viewHolder.fixing); } private class CertValidatorView { // public CheckBox embedSignature; public TextView certificateData; public TextView documentsData; // public ViewGroup validationStatus; public LinearLayout accept; public LinearLayout cancel; public LinearLayout fixing; public CertValidatorView() { setContentView(R.layout.cert_validation); // this.embedSignature = (CheckBox) findViewById(R.id.embed_signature); this.certificateData = (TextView) findViewById(R.id.cert_data); this.documentsData = (TextView) findViewById(R.id.docs_data); this.certificateData.setMovementMethod(new ScrollingMovementMethod()); this.documentsData.setMovementMethod(new ScrollingMovementMethod()); // this.validationStatus = (ViewGroup) findViewById(R.id.validation_status); this.accept = (LinearLayout) findViewById(R.id.button_accept_zone); this.accept.setOnClickListener(CertValidatorActivity.this); // this.accept.setEnabled(false); this.cancel = (LinearLayout) findViewById(R.id.button_cancel_zone); this.cancel.setOnClickListener(CertValidatorActivity.this); this.fixing = (LinearLayout) findViewById(R.id.fixing); } public void setData(String subject, String serial, String issuer, List files) { StringBuilder builder = new StringBuilder(); StringBuilder builderDocs = new StringBuilder(); Resources res = CertValidatorActivity.this.getResources(); builder.append(res.getString(R.string.subject)); builder.append(":\n"); builder.append(subject); builder.append("\n\n"); builder.append(res.getString(R.string.serial_number)); builder.append(":\n"); builder.append(serial); builder.append("\n\n"); builder.append(res.getString(R.string.issuer)); builder.append(":\n"); builder.append(issuer); builder.append("\n\n"); for (Uri file : files) { builderDocs.append("\n - "); builderDocs.append(file.getLastPathSegment()); } this.certificateData.setText(builder.toString()); this.documentsData.setText(builderDocs.toString()); } } }