SConnect & WebSigner add-on set up

SConnect is the generic framework required to be installed on the end-user computer to host the WebSigner add-on. The installation, setup and configuration is automatically done from the web application.

The web application must declare in its HTML code the following JavaScript libraries:

  • sconnect.js (or sconnect_uc.js for readable version)
  • websigner.js

The SConnect framework is automatically installed when the function 'Install' is invoked. At that time SConnect loads your custom server configuration (a set of path describing where on your server are deployed the SConnect componnet to use when the web application is running. See the 'serverConfiguration' variable below to have a complete example of server configuration). This is generally done whe the web application page is load (see 'onPageUnload' function below). The SConnect installation is operated interactively wth the end-user.


    var serverConfiguration = {
            // Define the server configuration to use by SConnect to check or get SConnect installers and add-ons
    // In this example the SConnect component are stored at the URL "https://your-web-server-url/path-to-your-SConnect-repository"
    serverConfiguration = {
        // Mind to modify the URL to connect to your web server.
        // THE "impPath", "extPath", "eulaPath", "faqPath" AND "addonPath" URLS ARE ALWAYS ABSOLUTE PATH.
        imgPath: "https://your-web-server-url/path-to-your-SConnect-repository/images/",
        extPath: "https://your-web-server-url/path-to-your-SConnect-repository/extensions/",
        eulaPath: "https://your-web-server-url/path-to-your-SConnect-repository/eula/",
        faqPath: "https://your-web-server-url/path-to-your-SConnect-repository/faq/",
        addonPath: "https://your-web-server-url/path-to-your-SConnect-repository/addons/"
        // Mind to modify the licensePath URL accordingdly to your web server.
        // THE LICENSE PATH IS ALWAYS RELATIVE PATH.
        //,licensePath : "/sconnect.lic"
    };
    
    // Configure the path to reach the SConnect components
    SConnect.ConfigResources(serverConfiguration);

    // Start the SConnect initialization or the automatic installation if SConnect is not installed on the end-user computer
    SConnect.Install(installCallback);
    

Once the installation succesfully done (see 'installationCallback'), the function 'ValidateServer' must be invoked to check the security between the SConnect framework and the web application server.


var installCallback = {

    success: function () {

        log('sconnect-install-success');

        SConnect.ValidateServer(validateCallback);
    },

    error: function (code) {

        log('sconnect-install-failed, reason: ' + code);
    }
};

Once the validation succesfully done (see 'validateCallback'), the function 'InstallAddOns' must be invoked to install atutomatically or set up the already installed add-ons required by the web application.


var validateCallback = {

    success: function () {

        'use strict';
        log('sconnect-validate-success');

        SConnect.InstallAddOns([new SConnect.WebSignerInfo()], installAddOnsCallback);
    },

    error: function (code) {

        'use strict';
        log('validate-server-failed, reason: ' + code);
    }
};                             

Once the add-on installation succesfully done (see 'installAddOnsCallback'), the web application creates the WebSigner onstance to be used to apply the WebSigner API (See function 'SConnect.WebSigner.Create').



var installAddOnsCallback = {

    success: function () {

        'use strict';
        log('install-addon-success');
        SConnect.WebSigner.Create(createCallback);
    },

    error: function (code, info) {

        'use strict';
        log('install-addons-failed, reason: ' + code);
    }
};                       

Once the WebSigner instance created (see 'createCallback'), the web application is ready to use the WebSigner API.


var createCallback = {

    success: function (WebSigner) {
        'use strict';
        theObjectWebSigner = WebSigner;
    },

    error: function (code) {
        'use strict';
        log('failed to create WebSigner instance, reason: ' + code);
    }
};

When the WebSigner instance created is no more required, the web application must dispose the WebSigner instance and the listener must be stopped. This is generally done when the web application page is unload.


function onPageUnload() {

    'use strict';

    // Release the WebSigner object
    if (theObjectWebSigner) {
        theObjectWebSigner.dispose();
    }
}

Here is the full code used in this page:


                            
////////////////////////////////////////////////////////////
//
// SConnect initialization & WebSigner addon creation
//
///////////////////////////////////////////////////////////

var serverConfiguration = {
        // Mind to modify the URL to connect to your web server.
        // THE "impPath", "extPath", "eulaPath", "faqPath" AND "addonPath" URLS ARE ALWAYS ABSOLUTE PATH.
        imgPath: "https://your-web-server-url/path-to-your-SConnect-repository/images/",
        extPath: "https://your-web-server-url/path-to-your-SConnect-repository/extensions/",
        eulaPath: "https://your-web-server-url/path-to-your-SConnect-repository/eula/",
        faqPath: "https://your-web-server-url/path-to-your-SConnect-repository/faq/",
        addonPath: "https://your-web-server-url/path-to-your-SConnect-repository/addons/"
        // Mind to modify the licensePath URL accordingdly to your web server.
        // THE LICENSE PATH IS ALWAYS RELATIVE PATH.
        //,licensePath : "/sconnect.lic"
    };
    
var createCallback = {

    success: function (WebSigner) {
        'use strict';
        theObjectWebSigner = WebSigner;
    },

    error: function (code) {
        'use strict';
        log('failed to create WebSigner instance, reason: ' + code);
    }
};

var installAddOnsCallback = {

    success: function () {

        'use strict';
        log('install-addon-success');
        SConnect.WebSigner.Create(createCallback)
    },

    error: function (code, info) {

        'use strict';
        log('install-addons-failed, reason: ' + code);
    }
};

var validateCallback = {

    success: function () {

        'use strict';
        log('sconnect-validate-success');

        SConnect.InstallAddOns([new SConnect.WebSignerInfo()], installAddOnsCallback);
    },

    error: function (code) {

        'use strict';
        log('validate-server-failed, reason: ' + code);
    }
};

var installCallback = {

    success: function () {

        log('sconnect-install-success');

        SConnect.ValidateServer(validateCallback);
    },

    error: function (code) {

        log('sconnect-install-failed, reason: ' + code);
    }
};


/**
* Starts the SConnect installation or setup
*/
function onPageLoad() {

    'use strict';

    // Configure the path to reach the SConnect components
    SConnect.ConfigResources(serverConfiguration);

    // Start the SConnect initialization or the automatic installation if SConnect is not installed on the end-user computer
    SConnect.Install(installCallback);
}


/**
 * Releases all SConnect & WebSigner resources
 */
function onPageUnload() {

    'use strict';

    // Release the WebSigner object
    if (theObjectWebSigner) {
        theObjectWebSigner.dispose();
    }
}


// Initialize the SConnect & WebSigner addon when the web page is load
window.onload = onPageLoad;


// Release all resources when the page is unload
window.onunload = onPageUnload;

                            

wysiwys

Takes the provided image data and compares them with a screenshot of the user's screen(s). Returns the number of occurrences of the image in the screenshot.

                            
var callback = { 
    
        success : function (status, data) { 
            var message = "The function has found " + data.result + " occurrences of the reference image in the screen."; 
            alert(message); 
        }, 

        error : function (errorCode) { 
            alert("The function failed with code (" + errorCode + ")."); 
        }
    },
    data = [255, 0, 0, 255, 0, 255, 0, 255, 0, 0, 255, 255, 0, 0, 0, 255], // 4 pixels, red, green, blue and black in a 2x2 square 
    width = 2, 
    height = 2, 
    format = 0, // raw RGBA 
    matchType = 0; // perfect matching 
    
    theObjectWebSigner.wysiwys(data, width, height, format, matchType, callback);
                            

Try it !

Click the button to invoke the function.

 

getAuthenticatedAttributes

Generates digest info of authenticated attributes (with content, message digest and signing time inside) suitable for consumption by the C_Sign function.

The Byte Array object parameter 'dataDigest' is the hash of the input data.

The Number parameter 'digestType' is the hashing mechanism used to produce the 'dataDigest' parameter. The value is equal to the integer value of the mechanism constant (CKM_...) as specified in pkcs11t.h. Currently, only CKM_SHA256 (value of 592 / 0x250) is supported.

The Object parameter 'signingTime' is the signing time to be put in the authenticated attributes. It is composed of the following properties:

  • The Number 'time' which is the UTC/Unix timestamp (number of seconds since Jan 01 1970)
  • The Number parameter 'timezoneOffset' is the timezone offset of the signing time in seconds (0 for UTC/GMT).

If the 'signingTime' object is set to null then the current time will be used.

The result of the 'getAuthenticatedAttributes' function is passed to the callback in the following 'data' object's properties:

  • The object 'signingTime' holding the given or generated time stamp(see 'signingTime' parameter above).
  • The Byte Array object property 'digest' holding the hash ready to be signed by ETC_SignEx.
  • The Byte Array object property 'data' holding the hash ready to be signed by C_Sign.

var callback = {
    success : function (status, data) {
            var message = "The authenticated attributes are:";
            message += " - digest (" + data.digest + ")";
            message += " - data (" + data.data + ")";
            message += " - signing time (" + data.signingTime.time + ")";
            message += " - signing time timezone offset (" + data.signingTime.timezoneOffset + ")";
            alert(message);
    },
    error : function (errorCode) {
        alert("The function failed with code (" + errorCode + ").");
    }
},
dataDigest = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31], // SHA256 hash of the data to be signed
digestType = 592 // or 0x250 for CKM_SHA256
signingTime = null; // insert current time into the authenticated attributes
// Otherwise compose the 'sigingTime' object with the expected properties
// For example : "signingTime" = { "time" : 1484391323, "timezoneOffset" : 0 }

theObjectWebSigner.getAuthenticatedAttributes(dataDigest, digestType, signingTime, callback);
                            

Try it !

Click the button to invoke the function.

 

createPKCS7

Builds a PKCS7 signature from the provided components.


The Byte Array object parameter 'inputData' is the input data that are the subject of the PKCS7 signature.
The Byte Array object parameter 'digestData' is the digest of the input data.
The Number parameter 'digestType' is the hashing mechanism used to produce the 'dataDigest' parameter. The value is equal to the integer value of the mechanism constant (CKM_...) as specified in pkcs11t.h. Currently, only CKM_SHA256 (value of 0x250) is supported.
The String parameter 'signingTime' is the signing time UTCTime string as received from 'getAuthenticatedAttributes' function.
The Byte Array object parameter 'signerCertificate' is DER encoded X509 signer certificate.
The Array of Byte Array objects parameter 'otherCertificates' are other certificates to be added to the signature, DER encoded X509 certificates, same as 'signerCertificate'.
The Byte Array object parameter 'cardSignature' is the RSA signature of the authenticated attributes (usually obtained by calling C_Sign or ETC_SignEx on the authenticated attributes digestInfo).
The object parameter 'unauthenticatedAttributes' is an object holding additional PKCS7 attributes not secured by the signature. Use null value to omit the unauthenticated attributes. If not null, the object is expected to have the following properties:
  • The Byte Array object property named 'deviceSignature' holding the device signature data (SWYS) produced by the C_Sign function (if available)
  • The Number property 'deviceSignatureType' holding the type of the device signature (SWYS). Supported values are 0 (zero) for OATH_OCRA_OTP or 1 for PKI_SIGNATURE.
  • The Byte Array object property name 'deviceSerialNumber' holding the serial number of the SWYS reader that has produced the device signature. ASCII format (one hexadecimal digit per character of the string) , i.e. 0x1234 ~ [ 0x31, 0x32, 0x33, 0x34 ]

The result of the 'createPKCS7' function is passed to the callback in the following 'data' object's attribute:

  • The String attribute 'signature' holding the base64 encoded PKCS7 signature created from the provided input parameters.

Possible errors are reported through the errorCode parameter passed to the callback.



var callback = { 
        success : function (status, data) { 
            var message = "The function produced the following PKCS7 " + JSON.stringigy(data) + "'.";
            alert(message); 
        },
        error : function (errorCode) { 
            alert("The function failed with code (" + errorCode + ")."); 
        }
    },
    // Set the digest type as 0x250 for CKM_SHA256
    digestType = 0x250,
    signingTime = "170728081057Z",
    
    // No other certificates to be stored in the signature
    otherCertificates = null,
    cardSignature = [ ... card signature as received from the C_Sign call, converted to byte array ... ],
    unauthenticatedAttributes = { 
        deviceSignature : [ ... device signature as received from the C_Sign call, converted to byte array ... ],
        deviceSignatureType : 1,
        readerSerialNumber : [0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34]
    };
    
    // The content is the string "Some data to be signed" converted to byte array (decimal represented here)
    var content = [83,111,109,101,32,100,97,116,97,32,116,111,32,98,101,32,115,105,103,110,101,100],
        // The digest type used is SHA256 (as 0x250 for CKM_SHA256 according PKCS11 specification values)
        digestType = 592,
        // DER encoded X509 certificate used for the signature, converted to byte array
        signerCertificate = [ ... ],
        // Array of other certificates
        otherCertificates = [ [... DER encoded X509 certificate ...], ..., [... DER encoded X509 certificate ...]],
        authenticatedAttributes = [ .. Object returned by the 'getAuthenticatedAttributes ...]
        cardSignature = [ .. smart card signature (as returned by the ETC_SignEx function for example) ...],
        unsignedAttributes;
        
        unsignedAttributes.deviceSignature = [ .. device signature (as returned by the ETC_SignEx function for example) ...];
        unsignedAttributes.deviceSignatureType = 1; // 1 for PKI or 0 for OTP
        unsignedAttributes.readerSerialNumber = [72,49,54,67,48,49,52,53,52,57,48,48,49,50];

    theObjectWebSigner.createPKCS7(content, digestType, signerCertificate, otherCertificates, authenticatedAttributes, cardSignature, unsignedAttributes, callback)
                            

Try it !

Click the button to invoke the function.