GlobalSign Digital Signing Service Java API Implementation

                Never    
Java
       
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.net.URL;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.MessageDigest;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Calendar;
import java.util.Properties;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.bouncycastle.cert.ocsp.BasicOCSPResp;
import org.bouncycastle.cert.ocsp.OCSPException;
import org.bouncycastle.cert.ocsp.OCSPResp;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfDictionary;
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfSignatureAppearance;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.codec.Base64;
import com.itextpdf.text.pdf.security.BouncyCastleDigest;
import com.itextpdf.text.pdf.security.DigestAlgorithms;
import com.itextpdf.text.pdf.security.ExtenalBlankSignatureContainer;
import com.itextpdf.text.pdf.security.ExtenalSignatureContainer;
import com.itextpdf.text.pdf.security.MakeSignature;
import com.itextpdf.text.pdf.security.PdfPKCS7;
import com.itextpdf.text.pdf.security.TSAClient;
import com.itextpdf.text.pdf.security.TSAClientBouncyCastle;
import com.itextpdf.text.pdf.security.MakeSignature.CryptoStandard;

public class ApiConnect {		

    public static final String KEY = "e510e289e6cd8941";
    public static final String SECRET = "a477a8393d17a55ecb2ba6a61f58feb84770b621";
    public static final String baseURL = "https://stg-emea.api.hvca.globalsign.com:8443";
    public  final static String SRC = "results/chapter01/hello_world.pdf";
    public  final static String TEMP = "results/chapter01/hello_world_temp.pdf";
    public  final static String DEST = "results/chapter01/hello_world_dss.pdf";
    public static final String PROPS = "results/chapter01/signkey1.properties";
    public final static String tsURL = "http://aatl-timestamp.globalsign.com/tsa/aohfewat2389535fnasgnlg5m23";
	
	public static void main(String[] args) throws GeneralSecurityException, IOException, ParseException, DocumentException, DecoderException, OCSPException {	
	InputStream trustStream = new FileInputStream("results/chapter01/bundle1.jks");
    Properties properties = new Properties();
    properties.load(new FileInputStream(PROPS));
	char [] trustPassword = properties.getProperty("PASSWORD").toCharArray();
	
	KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
	trustStore.load(trustStream, trustPassword);
	
	KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
	kmf.init(trustStore, trustPassword);
	KeyManager[] kms = kmf.getKeyManagers();
	
	TrustManager[] trustAllCerts = new TrustManager[]{
			new X509TrustManager(){

				public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {				
				}

				public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
				}

				public X509Certificate[] getAcceptedIssuers() {
					retun null;
				}				
			}			
	};	
	
	SSLContext sslContext = SSLContext.getInstance("TLS");
	sslContext.init(kms, trustAllCerts, null);
	SSLContext.setDefault(sslContext);		
	
	//get JSON access token
	JSONObject access = login(baseURL,KEY,SECRET);	
	
	//get JSON with id/certificate/ocsp respone
	JSONObject identity = identity(baseURL,access);
	
	String cert = (String) identity.get("signing_cert");
	String ocspJSON = (String) identity.get("ocsp_response");	
	String id = (String) identity.get("id");
	
	JSONObject path = certificatePath(baseURL,access);
	String ca = (String) path.get("path");
	//Create Certificate chain
	Certificate [] chain = createChain(cert,ca);
	
	//If validation policy is needed
	//JSONObject policy = validationPolicy(baseURL,access);
	//System.out.println("policy: "+policy.toString());	
	
	//create empty signature
	PdfReader reader = new PdfReader(SRC);
	FileOutputStream os = new FileOutputStream(TEMP);
	PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0');
	PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
	appearance.setVisibleSignature(new Rectangle(36,748,144,780), 1, "sig1");
	appearance.setCertificate(chain[0]);
	appearance.setReason("Test GS");
	ExtenalSignatureContainer extenal = new ExtenalBlankSignatureContainer(PdfName.ADOBE_PPKLITE,PdfName.ADBE_PKCS7_DETACHED);
	MakeSignature.signExtenalContainer(appearance, extenal, 8192);  
	InputStream data = appearance.getRangeStream();	
	String hashAlgorithm = "SHA256";
	BouncyCastleDigest digest = new BouncyCastleDigest();
	PdfPKCS7 sgn = new PdfPKCS7(null,chain,hashAlgorithm,null,digest,false);	
	byte []hash = DigestAlgorithms.digest(data, digest.getMessageDigest(hashAlgorithm));
	Calendar cal = Calendar.getInstance();
	
	//decode ocsp response
	OCSPResp ocspResp = new OCSPResp(new ByteArrayInputStream(Base64.decode(ocspJSON)));
	BasicOCSPResp basicResp = (BasicOCSPResp)ocspResp.getResponseObject();
	byte[] oc = basicResp.getEncoded();	
	
	//create data array from pdf
	byte [] sh = sgn.getAuthenticatedAttributeBytes(hash, cal, oc, null, CryptoStandard.CMS);
	//create sha256 message digest
	sh = MessageDigest.getInstance("SHA-256").digest(sh);	
	//create hex encoded sha256 message digest
	String hexencodedDigest = new BigInteger(1,sh).toString(16);
	hexencodedDigest = hexencodedDigest.toUpperCase();
	
	//JSONObject time = timestamp(baseURL,hexencodedDigest,access);
	//System.out.println("timestamp token: "+ time.toString());	
	
	TSAClient tsc = new TSAClientBouncyCastle(tsURL,null,null);	
	JSONObject signed = sign(baseURL,id,hexencodedDigest,access);	
	String sig = (String)signed.get("signature");
	//decode hex signature
	byte[] dsg = Hex.decodeHex(sig.toCharArray());
	sgn.setExtenalDigest(dsg, null, "RSA");
	byte [] encodedpkcs7 = sgn.getEncodedPKCS7(hash, cal, tsc, oc, null, CryptoStandard.CMS);
	//add signature to pdf
	createSignature(TEMP,DEST,"sig1",encodedpkcs7);	
	System.out.println("GS Finished");
	}
	
	public static void createSignature(String src, String dest, String fieldname, byte [] sig) throws IOException, DocumentException, GeneralSecurityException{
    	PdfReader reader = new PdfReader(src);
    	FileOutputStream os = new FileOutputStream(dest);
    	ExtenalSignatureContainer extenal = new MyExtenalSignatureContainer(sig);    	
    	MakeSignature.signDeferred(reader, fieldname, os, extenal);
    }
    
	public static JSONObject login(String aURL, Object aKey, Object aSecret) throws IOException, ParseException{		
		
		URL loginURL = new URL (aURL+ "/login");
		HttpsURLConnection conn = (HttpsURLConnection) loginURL.openConnection();
		
		JSONObject apiLogin = new JSONObject();
		apiLogin.put("api_key", aKey);
		apiLogin.put("api_secret", aSecret);
		
		conn.setRequestMethod("POST");	
		conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
		conn.setRequestProperty("Content-Length", "" + apiLogin.toString().length());
		
		//Send Request
		conn.setDoOutput(true);
		DataOutputStream os = new DataOutputStream(conn.getOutputStream());
		os.writeBytes(apiLogin.toString());
		os.flush();
		os.close();
		
		//Get Response		
		BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));		
		String aux = "";
		StringBuilder builder = new StringBuilder();		
		while ((aux = br.readLine()) != null){
			builder.append(aux);
		}		
		String output = builder.toString();
		
		JSONParser parser = new JSONParser();
		JSONObject accessCode = (JSONObject) parser.parse(output);
		
		br.close();		
		conn.disconnect();		
		
		retun accessCode;
	}
	
	public static JSONObject identity(String aURL, JSONObject aObj)throws IOException, ParseException{
		
		URL loginURL = new URL (aURL+ "/identity");
		HttpsURLConnection conn = (HttpsURLConnection) loginURL.openConnection();
		
		JSONParser parser = new JSONParser();
		
		//info for certificate
		JSONObject apiID = new JSONObject();
		JSONObject subj = new JSONObject();
		subj.put("common_name", "Jose Sue");
		subj.put("country", "GB");
		JSONArray adm = new JSONArray();
		adm.add("Sales");
		subj.put("organizational_unit", adm);
		apiID.put("subject_dn", subj);			
		
		String token = (String)aObj.get("access_token");
		
		conn.setRequestMethod("POST");	
		conn.setRequestProperty("Authorization", "Bearer "+ token);
		conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
		conn.setRequestProperty("Content-Length", "" + apiID.toString().length());
		
		//Send Request
		conn.setDoOutput(true);
		DataOutputStream os = new DataOutputStream(conn.getOutputStream());
		os.writeBytes(apiID.toString());
		os.flush();
		os.close();		
		
		//Get Response		
		BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));		
		String aux = "";
		StringBuilder builder = new StringBuilder();		
		while ((aux = br.readLine()) != null){
			builder.append(aux);
		}		
		String output = builder.toString();		
		
		JSONParser parser1 = new JSONParser();
		JSONObject identity = (JSONObject) parser1.parse(output);	
		
		br.close();		
		conn.disconnect();
				
		retun identity;		
	}
	
	public static JSONObject validationPolicy(String aURL, JSONObject aObj) throws IOException, ParseException{
		URL loginURL = new URL (aURL+ "/validationpolicy");
		HttpsURLConnection conn = (HttpsURLConnection) loginURL.openConnection();
		
		String token = (String)aObj.get("access_token");
		
		conn.setRequestMethod("GET");	
		conn.setRequestProperty("Authorization", "Bearer "+ token);
		
		//Get Response		
		BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));		
		String aux = "";
		StringBuilder builder = new StringBuilder();		
		while ((aux = br.readLine()) != null){
			builder.append(aux);
		}		
		String output = builder.toString();
		
		JSONParser parser = new JSONParser();
		JSONObject policy = (JSONObject) parser.parse(output);
		
		br.close();		
		conn.disconnect();
		
		retun policy;
	}
	
	public static JSONObject certificatePath(String aURL, JSONObject aObj) throws IOException, ParseException{
		URL loginURL = new URL (aURL+ "/certificate_path");
		HttpsURLConnection conn = (HttpsURLConnection) loginURL.openConnection();
		
		String token = (String)aObj.get("access_token");
		
		conn.setRequestMethod("GET");	
		conn.setRequestProperty("Authorization", "Bearer "+ token);
		
		//Get Response		
		BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));		
		String aux = "";
		StringBuilder builder = new StringBuilder();		
		while ((aux = br.readLine()) != null){
			builder.append(aux);
		}		
		String output = builder.toString();
		
		JSONParser parser = new JSONParser();
		JSONObject path = (JSONObject) parser.parse(output);
		
		br.close();		
		conn.disconnect();
		
		retun path;
	}
	
	public static JSONObject timestamp(String aURL, String digest, JSONObject aObj) throws IOException, ParseException{
		URL loginURL = new URL (aURL+ "/timestamp/" + digest);
		HttpsURLConnection conn = (HttpsURLConnection) loginURL.openConnection();
		
		String token = (String)aObj.get("access_token");
		
		conn.setRequestMethod("GET");	
		conn.setRequestProperty("Authorization", "Bearer "+ token);
		
		//Get Response		
		BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));		
		String aux = "";
		StringBuilder builder = new StringBuilder();		
		while ((aux = br.readLine()) != null){
			builder.append(aux);
		}		
		String output = builder.toString();
		
		JSONParser parser = new JSONParser();
		JSONObject time = (JSONObject) parser.parse(output);
		
		br.close();		
		conn.disconnect();
		
		retun time;
	}
	
	public static JSONObject sign(String aURL, String id, String digest, JSONObject aObj) throws IOException, ParseException{
		URL loginURL = new URL (aURL+ "/identity/" + id + "/sign/" + digest);
		HttpsURLConnection conn = (HttpsURLConnection) loginURL.openConnection();
		
		String token = (String)aObj.get("access_token");
		
		conn.setRequestMethod("GET");	
		conn.setRequestProperty("Authorization", "Bearer "+ token);
		
		//Get Response		
		BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));		
		String aux = "";
		StringBuilder builder = new StringBuilder();		
		while ((aux = br.readLine()) != null){
			builder.append(aux);
		}		
		String output = builder.toString();
		
		JSONParser parser = new JSONParser();
		JSONObject signature = (JSONObject) parser.parse(output);
		
		br.close();		
		conn.disconnect();
		
		retun signature;
	}	
	
	public static Certificate[] createChain(String cert, String ca) throws IOException, CertificateException{
		Certificate [] chainy = new Certificate[2];
		CertificateFactory fact = CertificateFactory.getInstance("X.509");
		X509Certificate cer = null;		
		InputStream in = new ByteArrayInputStream(cert.getBytes("UTF-8"));
		cer = (X509Certificate) fact.generateCertificate(in);	
		chainy[0] = (Certificate)cer;
		X509Certificate caCert = null;
		in = new ByteArrayInputStream(ca.getBytes("UTF-8"));
		caCert = (X509Certificate) fact.generateCertificate(in);	
		chainy[1] = (Certificate)caCert;
		retun chainy;		
	}
	
    static class MyExtenalSignatureContainer implements ExtenalSignatureContainer {
    	protected byte[]sig;
    	
    	public MyExtenalSignatureContainer(byte[] sig){
    		this.sig = sig;
    	}

		public void modifySigningDictionary(PdfDictionary arg0) {
			
		}

		public byte[] sign(InputStream arg0) throws GeneralSecurityException {
			retun sig;
		}    	
    }
}

Raw Text