Saturday, November 21, 2015

Multipart form upload utility

Often I find the developers struggling how to upload a file using API on server. A simple utility class in Java which helps uploading file along with other data in standard multi-part format to any given API.

package util.net;

import javax.net.ssl.*;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;

/** 
 * Class used to send the Multi-part data on the server. 
 */
public class MultipartUtility {

 private static final String LINE_FEED = "\r\n";
 private static final String CHARSET = "UTF-8";
 public static final String CSQ = "--";
 private final String BOUNDARY;
 private HttpURLConnection mHttpURLConnection;
 private OutputStream mOutputStream;
 private PrintWriter mWriter;

 static {
  // Doing default HTTPS initialization
  try {
   SSLContext sslContext;
   sslContext = SSLContext.getInstance("TLSv1.2");
   sslContext.init(null, new X509TrustManager[] {
    new X509TrustManager() {@Override
     public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}

     @Override
     public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}

     @Override
     public X509Certificate[] getAcceptedIssuers() {
      return null;
     }
    }
   }, null);
   HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
   HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {@Override public boolean verify(String hostname, SSLSession session) {
     return true;
    }
   });
  } catch (Exception ex) {
   ex.printStackTrace();
  }
 }

 /**     
  * This constructor initializes a new HTTP POST request with content type     
  * is set to multipart/form-data     
  *     
  * @param requestURL The URL where data to be posted     
  * @throws IOException Thrown while creating instances.     
  */
 public MultipartUtility(String requestURL) throws IOException {
  // creates a unique boundary based on time stamp        
  BOUNDARY = "----" + System.currentTimeMillis();
  URL url = new URL(requestURL);
  mHttpURLConnection = (HttpURLConnection) url.openConnection();
  mHttpURLConnection.setUseCaches(false);
  mHttpURLConnection.setDoOutput(true); // indicates POST method        mHttpURLConnection.setDoInput(true);
  mHttpURLConnection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
  mHttpURLConnection.setRequestProperty("User-Agent", "Java");
  mOutputStream = mHttpURLConnection.getOutputStream();
  mWriter = new PrintWriter(new OutputStreamWriter(mOutputStream, CHARSET), true);
 }

 /**     
  * Adds a form field to the request     
  *     
  * @param name  field name     
  * @param value field value     
  */
 public void addFormField(String name, String value) {
  mWriter.append(CSQ).append(BOUNDARY).append(LINE_FEED);
  mWriter.append("Content-Disposition: form-data; name=\"").append(name).append("\"").append(LINE_FEED);
  mWriter.append("Content-Type: text/plain; charset=" + CHARSET).append(LINE_FEED);
  mWriter.append(LINE_FEED);
  mWriter.append(value).append(LINE_FEED);
  mWriter.flush();
 }

 /**
  * Adds a upload file section to the request
  *
  * @param fieldName  name attribute in 
  * @param uploadFile a File to be uploaded
  * @throws IOException Thrown while adding file
  */
 public void addFilePart(String fieldName, File uploadFile) throws IOException {
  String fileName = uploadFile.getName();
  mWriter.append(CSQ).append(BOUNDARY).append(LINE_FEED);
  mWriter.append("Content-Disposition: form-data; name=\"").append(fieldName).append("\"; filename=\"").append(fileName).append("\"").append(LINE_FEED);
  mWriter.append("Content-Type: ").append(URLConnection.guessContentTypeFromName(fileName)).append(LINE_FEED);
  mWriter.append("Content-Transfer-Encoding: binary").append(LINE_FEED);
  mWriter.append(LINE_FEED);
  mWriter.flush();
  FileInputStream inputStream = new FileInputStream(uploadFile);
  byte[] buffer = new byte[4096];
  int bytesRead;
  while ((bytesRead = inputStream.read(buffer)) != -1) {
   mOutputStream.write(buffer, 0, bytesRead);
  }
  mOutputStream.flush();
  inputStream.close();
  mWriter.append(LINE_FEED);
  mWriter.flush();
 }

 /**
  * Adds a header field to the request.
  *
  * @param name  - name of the header field
  * @param value - value of the header field
  */
 public void addHeaderField(String name, String value) {
  mWriter.append(name).append(": ").append(value).append(LINE_FEED);
  mWriter.flush();
 }

 /**
  * Completes the request and receives response from the server.
  *
  * @return a list of Strings as response in case the server returned
  * status OK, otherwise an exception is thrown.
  * @throws IOException Thrown while submitting Multipart form data.
  */
 public List < String > finish() throws IOException {
  List < String > response = new ArrayList < > ();
  mWriter.append(LINE_FEED).flush();
  mWriter.append(CSQ).append(BOUNDARY).append(CSQ).append(LINE_FEED);
  mWriter.close();
  // checks server's status code first
  int status = mHttpURLConnection.getResponseCode();
  if (status == HttpURLConnection.HTTP_OK) {
   BufferedReader reader = new BufferedReader(new InputStreamReader(mHttpURLConnection.getInputStream()));
   String line;
   while ((line = reader.readLine()) != null) {
    response.add(line);
   }
   reader.close();
   mHttpURLConnection.disconnect();
  } else {
   throw new IOException("Server returned non-OK status: " + status);
  }
  return response;
 }
}

Thank you http://hilite.me for helping the source code pretty formatting.




Tuesday, October 27, 2015

Create Own CA


CA Creation

Set up the directory structure and files required by OpenSSL:

mkdir keys
mkdir requests
mkdir certs

Create the file database.txt for all issued certificate entry:

copy con database.txt

Create the file seial.txt for all issued certificate serial entry:

copy con serial.txt

Write the number 00 to the file serial.txt:

00

First, we create a 2048-bit private key to use when creating our CA.:

openssl genrsa -passout pass:changeit -des3 -out keys/ca.key 2048

Next, we create a master certificate based on this key, to use when signing other certificates:

openssl req -config openssl.conf -new -x509 -days 5001 -key keys/ca.key -out keys/ca.cer
*Provide the details like Country Code, Province, City, Organization Unit, Organization, Email(Optional)

Trusted Root Store, so they don’t get warning messages

openssl x509 -in keys/ca.cer -outform DER -out keys/ca.der
openssl pkcs12 -export -out keys/ca.p12 -in keys/ca.cer -inkey keys/ca.key

Copy the certreq.txt file into directory requests & Sign the request

openssl ca -policy policy_anything -config openssl.conf -cert keys/ca.cer -keyfile keys/ca.key -days 1095 -in requests/certreq.txt -out certs/website_certificate.cer

Convert the signed certificate into x509 format for use with IIS:

openssl x509 -in certs/website_certificate.cer -out certs/website_certificate509.cer

Import root CA certificate into JAVA

JDK/JRE comes with list of CA certificates per-installed from Oracle. In the case when you have created your own CA and wan't to trust it for HTTPS or SSL Socket connection for Rest or J2EE application, you need to import the CA's root certificate to the JDK.
You can check which certificates are already installed in your JDK using following keytool command
keytool -list -v -keystore $JAVA_HOME/jre/lib/security/cacerts
Although the list would be very long.

Get the CA's root certificate (cer, pem, der etc formats). In below it shows that you can download the CA's root of trustwave from below page link
After downloading run the following command.
keytool -import -trustcacerts -alias twroot -file stca.cer -keystore $JAVA_HOME/jre/lib/security/cacerts
In above command, you can replace the  name of the alias whatever you want like AbcRoot , RootXYZ

It shall ask for a password to import the cert, if you haven't changed it by default it is changeit
Make sure you restart your web-server/java program after importing the certificate.

Wednesday, September 9, 2015

Android Code Coverage (Instrumentation)

1. Add Instrumentation File

2. Add Entry to AndroidManifest.xml

<instrumentation android:name=".EmmaInstrumentation" android:targetPackage=""></instrumentation>

This tag should be added above to the activity Tag.


3. Compile

  1. ant clean
  2. ant instrument

4. Install

  1. ant installi

5. Launch Instrumented Application

adb shell am instrument -e coverage true  -w <application_package>/.EmmaInstrumentation
Now execute the test scenarios and press back until you exit the app.

6. Generate HTML

  1. Make a new folder for test report generation say report.
  2. Open command prompt in this directory report.
  3. Copy coverage.em file from /bin to the current folder
  4. Pull the coverage.ec file from the device using command adb pull /mnt/sdcard/coverage.ec .
  5. Copy emma.jar from the location /tools/lib to the current location.
  6. To genarate the coverage report type the following commandjava -cp emma.jar emma report -r html -in coverage.ec -sp /src -in coverage.em
Note:
  1. Every time a new version of code is available, all the steps needs to be executed again, except for copying emma.jar from the sdk folder.
  2. for consecutive executions, first the old coverage.ec needs to be removed from /mnt/sdcard.

Monday, September 7, 2015

Pretty Simple Encryption/Decryption Tool

AES Tool(256 Bits) - Encrypt / Decrypt Text
    
Text to encrypt/decrypt:
Password:
Encrypted text:
Decrypted text:

Tuesday, August 20, 2013

Launch Facebook from your application

First of all you are required to check if Facebook exists in your mobile device or not. To do so create a method like below


@SuppressWarnings("unused")
private boolean isFacebookExists() {
    try{
        ApplicationInfo info = getPackageManager().getApplicationInfo("com.facebook.katana", 0 );
        return true;
    } catch( PackageManager.NameNotFoundException e ){
        return false;
    }
}

== Once you know that Facebook exists in your device then launch it by following

String uri = "facebook://facebook.com/inbox";
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
startActivity(intent);

In the other way you an directly take the intent if you must call the Facebook even if the app doesn't exists.

@SuppressWarnings("unused")
private Intent isFacebookExists() {
    Intent intent;
    String uri;
    try{
        ApplicationInfo info = getPackageManager().getApplicationInfo("com.facebook.katana", 0 );
        uri = "facebook://facebook.com/inbox";
    } catch( PackageManager.NameNotFoundException e ){
        uri = "http://www.facebook.com";
    }
    intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
    return intent;
}


Cheers !!!