Overview of the WebUtil Application

WebUtil is a simple Java application that generates the signature for an IAAS request to the Web service. WebUtil uses the SHA512withRSA method and base64 encoding to sign the required data.

The following is the code of the WebUtil application. You can build the application with the javac compiler; it is possible that two warnings are displayed when building the application.

/*
 *  Copyright (c) 2007, 2012 Oracle and/or its affiliates.  All rights reserved.
 *  Use is subject to license terms.
 */
import java.io.*;
import java.nio.charset.Charset;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.interfaces.RSAPrivateKey;
public class WebUtil {
        final static String UTF_8_ENCODER = "UTF-8";
        private static final Charset CHARSET_ENCODING_UTF_8    = Charset.forName("UTF-8");
        private static final long   IAAS_REQUEST_TIMEOUT_MS = 300000; //default expiry time is 5 minutes
        public static void main(String[] args) {
        if(args.length<=0) {
                WebUtil.usage();
        }
        String argument=new String(args[0]);        
        if(argument.compareTo("signature") ==0 && args.length != 6){
                WebUtil.usage();
        }
        if(argument.compareTo("template") == 0 && args.length != 2){
                WebUtil.usage();                
        }
                
        try{
 
        if(argument.compareTo("template") == 0){
                WebUtil.generateTemplate(args[1]);              
        
        }       
        
        if(argument.compareTo("signature") ==0 && args.length == 6){            
                WebUtil.signDataToFile(args[1],args[2],args[3],args[4],args[5]);
                
        }       
 
        }catch (Exception e){
                System.err.println("Caught exception " + e.toString());
        }
 
 
 
        }
        static void usage(){
                
            System.out.println("Usage: WebUtil template destinationFile");
            System.out.println("Usage: WebUtil signature privateKeyDER  HTTP_TYPE  HOST_IP  DATA_TO_SIGN  signatureData");
            System.out.println("Usage: HTTP_TYPE: POST or GET\n   HOST_IP=ip address of OC \n    DATA_TO_SIGN:without Timestamp and Expire but needs to have the access key id \n  signatureData:filename to store the signature");
            System.exit(0);
            
        }
 
        static void generateTemplate(String filename)throws Exception {
                StringBuilder message = new StringBuilder();
 
                message.setLength(0);
                message.append("POST").append("\n");
                message.append("192.0.2.76").append("\n");
                message.append("/iaas/").append("\n");
                message.append("Action=DescribeVnets&Version=1");
                message.append("&Timestamp=1330797956376");
                message.append("&Expires=1330798256376");
                message.append("&AccessKeyId=AK_1");
                message.append("\n");
                FileOutputStream iaas = new FileOutputStream(filename);
                iaas.write(message.toString().getBytes(CHARSET_ENCODING_UTF_8));
                iaas.close();
        }       
 
 
        static void signDataToFile(String keyPrivFile, String httpType, String host, String dataRequest,String signedDataFile) throws Exception {
                
                
long tsnow = System.currentTimeMillis();
long tsexpires = tsnow + IAAS_REQUEST_TIMEOUT_MS;
String tNow=Long.toString(tsnow);
String tEXPIRE=Long.toString(tsexpires);
 
StringBuilder message = new StringBuilder();
message.setLength(0);
message.append(httpType).append("\n");
message.append(host).append("\n");
message.append("/iaas/").append("\n");
message.append(dataRequest);
message.append("&Timestamp="); message.append(tNow);
message.append("&Expires="); message.append(tEXPIRE);
message.append("\n");
 
StringBuilder iaasmessage = new StringBuilder();
iaasmessage.append("https://").append(host);
iaasmessage.append("/iaas/?").append(dataRequest);
iaasmessage.append("&Timestamp="); iaasmessage.append(tNow);
iaasmessage.append("&Expires="); iaasmessage.append(tEXPIRE);
iaasmessage.append("&SignatureMethod=SHA512withRSA&SignatureVersion=1");
iaasmessage.append("&Signature=");
        
                
                String messageStr = message.toString();        
                
 
                /* Read private keyfile DER */
                FileInputStream in = new FileInputStream( keyPrivFile);
 
                FileInputStream keyfis =    new FileInputStream(keyPrivFile);
                byte[] encKey = new byte[keyfis.available()];
                keyfis.read(encKey);
                keyfis.close();
 
                PKCS8EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(encKey);
 
                KeyFactory keyFactory =    KeyFactory.getInstance("RSA");
                PrivateKey privKey =    keyFactory.generatePrivate(privKeySpec);
 
                Signature rsa = Signature.getInstance("SHA512withRSA"); 
 
                rsa.initSign(privKey);
                rsa.update(messageStr.getBytes(CHARSET_ENCODING_UTF_8));
 
                /* Now that all the data to be signed has been read in, 
                    generate a signature for it */
 
                byte[] realSig = rsa.sign();
                
                /* base64 encode the signed data */
                String signatureUrlEncoded = getBase64Encoder().encode(realSig);
 
 
        
                /* Copy data to file */
        
                FileOutputStream iaas = new FileOutputStream(signedDataFile);
                iaas.write(signatureUrlEncoded.getBytes(CHARSET_ENCODING_UTF_8));
                iaas.close();
 
                /* copy part of request to request file */
                FileOutputStream iaasreq = new FileOutputStream("iaasPartRequest");
                iaasreq.write(iaasmessage.toString().getBytes(CHARSET_ENCODING_UTF_8));
                iaasreq.close();
 
 
        }       
 
/**
     * @return a new base 64 encoder
     */
    public static sun.misc.BASE64Encoder getBase64Encoder() {
        /*
         * This helper method was introduced to minimize the warnings about
         * using a Sun proprietary API. Use full package names to avoid
         * warning on import statement.
         */
        return new sun.misc.BASE64Encoder();
    }
 
}

How the WebUtil Application Works

Describes how to generate an HTTP request.

WebUtil application requires an access key for the account. See "Creating an Access Key" for information about how to create the access key.

After the access key is created, the IAAS data must be defined, as explained in "IAAS Data Used for Signature".

The following is an example of the IAAS data for viewing vNets information:

POST
<EnterpriseControllerHostname>
Action=DescribeVnets&Version=1&accessKeyId=AK_1&Timestamp=12333333&Expires=13333444

To generate the signature and base64 encoding, use the WebUtil by running the following command:

java WebUtil signature  privatekey.DER "POST" "<EnterpriseControllerHostname>"  "Action=DescribeVnets&Version=1&accessKeyId=AK_1" signedData

WebUtil generates and stores the signed data in the signedData file:

Content of the signedData file: bj8GfJCqvPZZPU2JoWAGzZdCF+N767rQejILMQwNdgKLfoGGqAwDPRYMr/ghUoBc6RB3nKYgAyPdmtCfhzRGTqECgUWy0jCrE99+utGeeJ0/XRQ9LxyYeBgzjO3lHP+hFhUo+gUtQaSYPhUHH7eTkxg/CrolMxibglypJM/rIf90yEqSeqhphQt7hWxlT0DNAy6/cZt8isT/Tu8V7ZFjBFkEpLfN97bIOJ2vIIpOeetmftuw4ObtqjbUp6+7dpVkhhCQnX0MAIDj+mjorEOzcwK+F1pYuzES0fjaW0MowG+cA/9gttDjg7r5H29i3qbbjIlvAt6fk1HPpSxQTSTOTg==

WebUtil also generates the iaasPartRequest file with the following information:

https://<EnterpriseControllerHostname>/iaas/?Action=DescribeVnets&Version=1&AccessKeyId=AK_1&Timestamp=1331058169938&Expires=1331058469938&SignatureMethod=SHA512withRSA&SignatureVersion=1&Signature=

To generate the complete HTTP request, append the content of the signedData file to the iaasPartRequest file as a single-line command. After that, the HTTP request can be sent, see "Sending a Web Service Request".