PKCS11 Keystore

Sample code uses ES6 language features such as arrow functions and promises. For compatibility with IE11, code written with these features must be either transpiled using tools like Babel or refactored accordingly using callbacks.

Interface

interface AbstractPkcs11Generic {
    uploadConfig(config: string, callback?: (error: T1CLibException, data: Pkcs11UploadConfigResponse) => void): Promise<Pkcs11UploadConfigResponse>;
    getConfig(callback?: (error: T1CLibException, data: Pkcs11GetConfigResponse) => void): Promise<Pkcs11GetConfigResponse>;
    clearConfig(callback?: (error: T1CLibException, data: Pkcs11ClearConfigResponse) => void): Promise<Pkcs11ClearConfigResponse>;
    os(callback?: (error: T1CLibException, data: OsResponse) => void): Promise<OsResponse>;
    info(callback?: (error: T1CLibException, data: Pkcs11InfoResponse) => void): Promise<Pkcs11InfoResponse>;
    slots(callback?: (error: T1CLibException, data: Pkcs11SlotsResponse) => void): Promise<Pkcs11SlotsResponse>;
    slotsWithTokenPresent(callback?: (error: T1CLibException, data: Pkcs11SlotsResponse) => void): Promise<Pkcs11SlotsResponse>;
    slotInfo(slotId: string, callback?: (error: T1CLibException, data: Pkcs11SlotInfoResponse) => void): Promise<Pkcs11SlotInfoResponse>;
    token(slotId: string, callback?: (error: T1CLibException, data: Pkcs11TokenResponse) => void): Promise<Pkcs11TokenResponse>;
    getAliases(slotId: string, data: Pkcs11VerifyPinRequest, callback?: (error: T1CLibException, data: AliasesResponse) => void): Promise<AliasesResponse>;
    getPrivateKeyType(slotId: string, alias: string, data: Pkcs11VerifyPinRequest, callback?: (error: T1CLibException, data: PrivateKeyTypeResponse) => void): Promise<PrivateKeyTypeResponse>;
    getCertificates(slotId: string, alias: string, data: Pkcs11VerifyPinRequest, callback?: (error: T1CLibException, data: Pkcs11CertificatesResponse) => void): Promise<Pkcs11CertificatesResponse>;
    sign(slotId: string, alias: string, data: Pkcs11SignRequest, callback?: (error: T1CLibException, data: DataResponse) => void): Promise<DataResponse>;
    verifyPin(slotId: string, alias: string, data: Pkcs11VerifyPinRequest, callback?: (error: T1CLibException, data: BoolDataResponse) => void): Promise<BoolDataResponse>;
}

Models

export class Pkcs11VerifyPinRequest {
    constructor(public pin?: string) {
    }
}

export class OsResponse {
    constructor(public data: Os, public success: boolean) {
    }
}

export class Os {
    constructor(public id: string, public version: string) {
    }
}

export class PrivateKeyTypeResponse {
    constructor(public data: PrivateKeyType, public success: boolean) {
    }
}

export class PrivateKeyType {
    constructor(public data: string) {
    }
}

export class Certificate {
    constructor(public certificate?: string, certSn?: string) {
    }
}


export class AliasesResponse {
    constructor(public data: Aliases, public success: boolean) {
    }
}

export class Aliases {
    constructor(public aliases: Alias[]) {
    }
}

export class Alias {
    constructor(public ref: string) {
    }
}


export class Pkcs11UploadConfigResponse {
    constructor(public data: string, public success: boolean) {
    }
}

export class Pkcs11ClearConfigResponse {
    constructor(public data: string, public success: boolean) {
    }
}

export class Pkcs11GetConfigResponse {
    constructor(public data: Pkcs11GetConfig, public success: boolean) {
    }
}

export class Pkcs11GetConfig {
    constructor(public sessionRef?: string, public tempPath?: string) {
    }
}

export class Pkcs11InfoResponse {
    constructor(public data: Pkcs11Info, public success: boolean) {
    }
}

export class Pkcs11SlotInfoResponse {
    constructor(public data: Pkcs11Slot, public success: boolean) {
    }
}


export class Pkcs11Info {
    constructor(public cryptokiVersion: string,
                public manufacturerId: string,
                public libraryDescription: string,
                public libraryVersion: string) {
    }
}

export class Pkcs11Slots {
    constructor(public slots: Pkcs11Slot[]) {
    }
}

export class Pkcs11Slot {
    constructor(public slot: string,
                public description: string) {
    }
}

export class Pkcs11SlotsResponse {
    constructor(public data: Pkcs11Slots, public success: boolean) {
    }
}

export class Pkcs11Certificate {
    constructor(public cert: string, public certSn: string, public parsed?: object) {
    }
}

export class Pkcs11CertificatesResponse {
    constructor(public data: Pkcs11Certificate[], public success: boolean) {
    }
}

export class Pkcs11SignRequest {
    constructor(public algorithm: string,
                public data: string,
                public pin?: string) {
    }
}

export class Pkcs11Config {
    constructor(public config: string) {
    }
}

export class Pkcs11TokenInfo {
    constructor(public slot: string,
                public label: string,
                public manufacturerId: string,
                public model: string,
                public serialNumber: string,
                public flags: string,
                public ulMaxSessionCount: number,
                public ulSessionCount: number,
                public ulMaxRwSessionCount: number,
                public ulMaxPinLen: number,
                public ulMinPinLen: number,
                public ulTotalPublicMemory: number,
                public ulFreePublicMemory: number,
                public ulTotalPrivateMemory: number,
                public ulFreePrivateMemory: number,
                public hardwareVersion: string,
                public firmwareVersion: string) {
    }
}

export class Pkcs11TokenResponse {
    constructor(public data: Pkcs11TokenInfo, public success: boolean) {
    }
}

export class Pkcs11ModuleConfig {
    constructor(public linux: string, public mac: string, public win: string) {
    }
}

Initialising the SDK

Before you are able to use the SDK's methods you need to initialise the trust1connector javascript SDK. Below you can find an example of how to do this. You can also check the integration in web applications page.

function initT1C() {
    console.log("Start initializing T1C");
    var configoptions = new T1CSdk.T1CConfigOptions(
        environment.t1cApiUrl,
        environment.t1cApiPort,
        environment.t1cRpcPort,
        undefined,
        undefined,
        pkcs11,
        undefined,
        undefined,
        undefined,
        undefined,
        undefined,
        undefined,
        undefined,
        true,
        undefined,
        undefined,
        undefined,
        undefined,
        "3.0.0",
        undefined,
    );
    config = new T1CSdk.T1CConfig(configoptions);
    T1CSdk.T1CClient.initialize(config).then(res => {
        client = res;
        core = client.core();
        core.version().then(versionResult => console.log("T1C running on core "+ versionResult));
        getPkcs11Configuration();
        getSlots(); //get slots
    }, err => {
        console.log("T1C error:", err)
    });
}

In this example you can see when the connector is initialised we try to fetch the pkcs11 configuration already loaded in (if present), if this is not loaded you still need to upload the configuration. (line 30)

we store the client data for later use (line 27)

After initialising the configuration we can fetch all available slots to display on the screen. (line 31)

Configuration

Example

Example config contents

name = Safenet
library = /usr/local/lib/libeTPkcs11.dylib
showInfo=true
slot=0

The most important config values are the name and the library (location of the PKCS11 dylib or DLL).

Base64 ecoding the config contents described in the codeblock above and sending them via the uploadConfig method of the JS sdk will enable you to upload and use that pkcs11 configuration.

Upload configuration

To be able to use the PKCS11 generic you need to upload a correct configuration file, which includes the name and library to be used. We use a html file chooser to fetch a file and use the FilereaderAPI to retrieve the contents of the selected file, then we convert it to a base64 string which we send to the uploadConfig method

const selectedFile = document.querySelector("#pkcs11ConfigFile").files[0];
var reader = new FileReader();
reader.onload = function(evt) {
    client.pkcs11Generic().uploadConfig(btoa(evt.target.result))
        .then(res => {
            // Display something in the UI
        })
        .catch(err => {
            // Display something in the UI
        })
};
reader.readAsText(selectedFile);

Get configuration

client.pkcs11Generic().getConfig()
        .then(res => {
            // Display current config in UI
        }, err => {
            // error code 806 will be thrown when no config present
        })

Clear configuration

This method is used to clear a currently active configuration

client.pkcs11Generic().clearConfig()
        .then(res => {
            // clear success
        })
        .catch(err => {
            // display error
        })

Os information

Via the following endpoint your're able to retrieve OS information if required

client.pkcs11Generic().os()
        .then(res => {
            // OS information
        })
        .catch(err => {
            // display error
        })

Info

Retrieve the library information of the loaded configuration. When the loaded config is not present it will throw a configuration exception

Requirements: loaded configuration

client.pkcs11Generic().info()
        .then(res => {
            // Library information
        })
        .catch(err => {
            // display error
        })

slots

Retrieve all available slots

Requirements: loaded configuration

client.pkcs11Genericfo().slots()
        .then(res => {
            // Array of all slots available
        })
        .catch(err => {
            // display error
        })

The same endpoint can be triggered but only showing the slots present;

client.pkcs11Genericfo().slotsWithTokenPresent()
        .then(res => {
            // Array of all slots available with token present
        })
        .catch(err => {
            // display error
        })

Slot information

Retrieve relevant slot information

Requirements: loaded configuration, slotId

client.pkcs11Genericfo().slotInfo(slotId)
        .then(res => {
            // Slot information
        })
        .catch(err => {
            // display error
        })

Token information

Retrieve information about the selected token

Requirements: loaded configuration, slotId

client.pkcs11Genericfo().token(slotId)
        .then(res => {
            // Token information
        })
        .catch(err => {
            // display error
        })

Retrieve aliasses

Retrieve all aliasses for a specific token.

Requirements: loaded configuration, slotId, verifyPin object

const verifyPinData = {
    pin: "****"
}
client.pkcs11Genericfo().getAliases(slotId, verifyPinData)
        .then(res => {
            // Token information
        })
        .catch(err => {
            // display error
        })

Retrieve the Private key type

Returns the name of the algorithm associated with this key

Requirements: loaded configuration, slotId, Alias, verifyPin object

const verifyPinData = {
    pin: "****"
}
client.pkcs11Genericfo().getPrivateKeyType(slotId, alias, verifyPinData)
        .then(res => {
            // Token information
        })
        .catch(err => {
            // display error
        })

Retrieve the certificates

Retrieve all certificates present for a specific token.

Requirements: loaded configuration, slotId, Alias, verifyPin object

const verifyPinData = {
    pin: "****"
}
client.pkcs11Genericfo().getCertificates(slotId, alias, verifyPinData)
        .then(res => {
            // certificates array
        })
        .catch(err => {
            // display error
        })

Sign

Sign base64 data object.

Requirements: loaded configuration, slotId, Alias, signData object

const signData = {
    algorithm: 'sha256', 
    data: "E1uHACbPvhLew0gGmBH83lvtKIAKxU2/RezfBOsT6Vs=", 
    pin: "****"
}
client.pkcs11Genericfo().sign(slotId, alias, signData)
        .then(res => {
            // sign response
        })
        .catch(err => {
            // display error
        })

Verify pin

Verify the pin of a specific token.

Requirements: loaded configuration, slotId, Alias, VerifyPin object

const verifyPinData = {
    pin: "****"
}
client.pkcs11Genericfo().verifyPin(slotId, alias, verifyPinData)
        .then(res => {
            // boolean wether verify was success
        })
        .catch(err => {
            // display error
        })

Status/error codes

TBD

Last updated