package ve.gob.cenditel.tibisaymovil; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.ObjectOutputStream; import java.security.PrivateKey; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.List; import com.sun.jersey.api.client.ClientHandlerException; import com.sun.jersey.api.client.UniformInterfaceException; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.res.Resources; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.text.method.ScrollingMovementMethod; import android.util.Log; import android.view.View; import android.view.Window; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; import com.lowagie.text.exceptions.InvalidPdfException; // prueba de droidtext import com.lowagie.text.pdf.*; import com.lowagie.text.*; public class SignActivity extends Activity implements OnClickListener { private boolean embedInPdf; private String alias; private List uris; private SignView viewHolder; private List signed; private List unsigned; private ArrayList send = new ArrayList(); private SignTask task; /** 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.embedInPdf = getIntent().getBooleanExtra(IntentExtraField.EMBED_SIGNATURE_IN_PDF, false); this.alias = getIntent().getStringExtra(IntentExtraField.ALIAS); this.uris = getIntent().getParcelableArrayListExtra(IntentExtraField.FILES); this.viewHolder = new SignView(); this.task = (SignTask) getLastNonConfigurationInstance(); if (this.task != null) { this.task.activity = this; } else if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) { this.task = (SignTask) new SignTask(this, FsUtils.createOutputDirectory(this), this).execute( uris.toArray(new Uri[uris.size()])); } else { this.viewHolder.noStorageError(); } if (savedInstanceState != null) { this.send = savedInstanceState.getParcelableArrayList("send"); this.viewHolder.done(); } //Estilando Barra de titulo if(customTitleSupported) getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.title_bar); } @Override public Object onRetainNonConfigurationInstance() { return this.task; } @Override protected void onDestroy() { this.task.cancel(true); if (this.task != null) { this.task.activity = null; } super.onDestroy(); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putParcelableArrayList("send", this.send); } @Override public void onBackPressed() { Intent back = new Intent(this, TibisayMovilActivity.class); startActivity(back); finish(); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.button_finish_zone: Intent back = new Intent(this, TibisayMovilActivity.class); startActivity(back); finish(); break; case R.id.button_share_zone: Intent intent = IntentUtils.sendMultipleFiles(this.send); //In case user has no email application. try{ startActivity(intent); finish(); }catch (android.content.ActivityNotFoundException e){ Toast.makeText(this, this.getString(R.string.errornoemail), Toast.LENGTH_SHORT).show(); } } } private static class SignTask extends AsyncErrorTask> { private SignActivity activity; private String directory; private Context context; public SignTask(SignActivity activity, String directory, Context context) { this.activity = activity; this.directory = directory; this.context = context; } @Override protected List doInBackground(Uri... uris) { X509Certificate[] chain; X509Certificate certificate; PrivateKey key; KeyChainStrategy keyChain = KeyChainStrategy.getInstance(); try { chain = keyChain.getCertificateChain(this.activity.alias); certificate = chain[0]; key = keyChain.getPrivateKey(this.activity.alias); } catch (Exception e) { this.cancel(true); chain=null; key=null; certificate=null; throw new RuntimeException(e); } ArrayList signed = new ArrayList(uris.length); //NEW: History. ArrayList sourcesPath = new ArrayList(); ArrayList destinationsPath = new ArrayList(); Log.d("SignActivity:SignTask", "antes del for"); for (Uri uri : uris) { Uri signedUri = null; try { String inputFilename = uri.getPath(); if (this.activity.embedInPdf && FsUtils.isPDF(inputFilename)) { // ******************************************************************** Log.d("SignActivity", "antes de CryptoUtils.signPDF"); PdfReader reader = new PdfReader(inputFilename); Log.d("SignActivity", "new PdfReader"); int n; String targetFilename = new File(this.directory, uri.getLastPathSegment()).getPath(); if ((n = targetFilename.lastIndexOf(".")) > targetFilename.lastIndexOf("/")) { targetFilename = targetFilename.substring(0, n) + "-firma.pdf"; } else { targetFilename = targetFilename + "-firma.pdf"; } Log.d("SignActivity", "targetFilename: "+targetFilename); FileOutputStream fout = new FileOutputStream(targetFilename); PdfStamper stp = PdfStamper.createSignature(reader, fout, '?'); Log.d("SignActivity", "PdfStamper.createSignature"); PdfSignatureAppearance sap = stp.getSignatureAppearance(); Log.d("SignActivity", "stp.getSignatureAppearance()"); sap.setCrypto(key, chain, null, PdfSignatureAppearance.WINCER_SIGNED); Log.d("SignActivity", "sap.setCrypto"); sap.setReason("Firma PKCS12 Android"); Log.d("SignActivity", "sap.setReason"); sap.setLocation("Imaginanet"); Log.d("SignActivity", "sap.setLocation"); stp.close(); Log.d("SignActivity", "stp.close"); //signedUri = FsUtils.saveToFile(fout, targetFilename); File file = new File(targetFilename); signedUri = Uri.fromFile(file); // ******************************************************************** /* InputStream signedPDF = CryptoUtils.signPDF(new File(inputFilename), chain, key, this.context); int n; String targetFilename = new File(this.directory, uri.getLastPathSegment()).getPath(); if ((n = targetFilename.lastIndexOf(".")) > targetFilename.lastIndexOf("/")) { targetFilename = targetFilename.substring(0, n) + "-firma.pdf"; } else { targetFilename = targetFilename + "-firma.pdf"; } signedUri = FsUtils.saveToFile(signedPDF, targetFilename); */ //TODO: signedUri for uri signed.add(uri); this.activity.send.add(signedUri); } else { FsUtils.copyTo(new File(uri.getPath()), this.directory); Log.d("SignActivity", "antes de CryptoUtils.signPKCS7"); byte[] signature = CryptoUtils.signPKCS7(new File(inputFilename), certificate, key); int n; String targetFilename = new File(this.directory, uri.getLastPathSegment()).getPath(); if ((n = targetFilename.lastIndexOf(".")) > targetFilename.lastIndexOf("/")) { targetFilename = targetFilename.substring(0, n) + ".p7b"; } else { targetFilename = targetFilename + ".p7b"; } Log.d("SignActivity", "antes de signedUri"); signedUri = FsUtils.saveToFile(signature, targetFilename); signed.add(uri); this.activity.send.add(uri); this.activity.send.add(signedUri); Log.d("SignActivity", "despues de signedUri"); } } catch (FileAlreadyExistsException e) { final Activity act = ((Activity) this.context); Toast.makeText(act, act.getString(R.string.errorServerNotReachable), Toast.LENGTH_SHORT).show(); //} catch (DocumentWritingException e) { } catch (ClientHandlerException e){ final Activity act = ((Activity) this.context); act.runOnUiThread(new Runnable() { public void run() { Toast.makeText(act, act.getString(R.string.errorServerNotReachable), Toast.LENGTH_SHORT).show(); } }); } catch (UniformInterfaceException e) { final Activity act = ((Activity) this.context); act.runOnUiThread(new Runnable() { public void run() { Toast.makeText(act, act.getString(R.string.errorConnection), Toast.LENGTH_SHORT).show(); } }); } catch (InvalidPdfException e) { //empty } catch (Exception e) { final Activity act = ((Activity) this.context); Toast.makeText(act, "exception", Toast.LENGTH_SHORT).show(); FsUtils.checkOutOfSpace(e, true); this.cancel(true); //throw new RuntimeException(e); } //HISTORY: //Fixed spaces path error with getPath instead of getEncodedPath finally{ sourcesPath.add(uri.getPath()); if (signedUri!=null) destinationsPath.add(signedUri.getPath()); else destinationsPath.add(""); } } // DIR Save history.mbs String[] pathSplit = this.directory.split("/"); String dirName = pathSplit[pathSplit.length-1]; File targetHistory = new File(this.directory, dirName); //File targetHistory = new File(this.directory, "history.mbs"); String alias = this.activity.alias; // this.saveHistoryData(alias, CertificateUtils.getSubject(chain[0]), // CertificateUtils.getSerial(chain[0]), // CertificateUtils.getIssuer(chain[0]),sourcesPath, destinationsPath, targetHistory); //---------- return signed; } @Override protected void onPostExecute(List signed) { if (this.activity != null) { if (getError() != null) { if (getError().getCause() instanceof OutOfSpaceError) { this.activity.viewHolder.outOfSpaceError(); } else { this.activity.viewHolder.unknownError(); } return; } this.activity.signed = signed; if (signed.size() < this.activity.uris.size()) { this.activity.unsigned = new ArrayList(this.activity.uris); this.activity.unsigned.removeAll(signed); } this.activity.viewHolder.update(); } } // private void saveHistoryData(String alias, String subject, String serial, String issuer, List files, // ArrayList unsigned, File path) { // // // HistoryData data = new HistoryData (alias, subject, serial, issuer, files, unsigned); // // ByteArrayOutputStream baos = new ByteArrayOutputStream(); // try{ // ObjectOutputStream oos = new ObjectOutputStream(baos); // oos.writeObject(data); // oos.flush(); // oos.close(); // }catch(IOException e){} // InputStream is = new ByteArrayInputStream(baos.toByteArray()); // // try { // FsUtils.saveToFile(is, path.getPath()); // } catch (Exception e){} // // // } } private class SignView { public LinearLayout finish; public LinearLayout share; public TextView summary; public TextView summary2; public View signing; public SignView () { setContentView(R.layout.sign); this.finish = (LinearLayout) findViewById(R.id.button_finish_zone); this.finish.setOnClickListener(SignActivity.this); this.share = (LinearLayout) findViewById(R.id.button_share_zone); this.share.setOnClickListener(SignActivity.this); this.summary = (TextView) findViewById(R.id.summary); this.summary.setMovementMethod(new ScrollingMovementMethod()); this.summary2 = (TextView) findViewById(R.id.summary2); this.summary2.setMovementMethod(new ScrollingMovementMethod()); this.signing = findViewById(R.id.signing); } public void noStorageError() { this.summary.setText(R.string.no_storage); this.signing.setVisibility(View.GONE); } public void outOfSpaceError() { this.summary.setText(R.string.error_no_space); this.signing.setVisibility(View.GONE); } public void unknownError() { this.summary.setText(R.string.error_unknown); this.signing.setVisibility(View.GONE); } public void update() { StringBuilder builder = new StringBuilder(); StringBuilder builder2 = new StringBuilder(); Resources res = SignActivity.this.getResources(); //Fix Error #75235 if (SignActivity.this.signed != null && !SignActivity.this.signed.isEmpty()) { // builder.append(res.getString(R.string.signedfiles)); for (Uri file : SignActivity.this.signed) { builder.append("\n - "); builder.append(file.getLastPathSegment()); } // builder.append("\n\n"); } if (SignActivity.this.unsigned != null && !SignActivity.this.unsigned.isEmpty()) { builder2.append(res.getString(R.string.unsigned2)); for (Uri file : SignActivity.this.unsigned) { builder2.append("\n - "); builder2.append(file.getLastPathSegment()); } } this.summary.setText(builder); this.summary2.setText(builder2); done(); } public void done() { this.signing.setVisibility(View.GONE); this.share.setEnabled(true); } } }