# PKCS #11

The PKCS #11 standard defines a platform-independent API to cryptographic tokens, such as hardware security modules (HSM), smart cards, and names the API itself "Cryptoki" (from "cryptographic token interface" and pronounced as "crypto-key" - but "PKCS #11" is often used to refer to the API as well as the standard that defines it).\
The API defines most commonly used cryptographic object types (RSAX.509 keys, DES/Triple DES Certificates/keys, etc.) and all the functions needed to use, create/generate, modify and delete those objects.\
This container relies on a PKCS#11 a library which handles the communication with the token/card. This can be a vendor specific library or an opensource one, please select the correct one depending on the type of token/card you are using.

## Interface Summary

The Abstract PKCS #11 smartcard interface is summarized in the following snippet:

```javascript
interface AbstractPkcs11{
    certificates(slotId: number,
                 options?: Options,
                 callback?: (error: RestException, data: SafeNetCertificatesResponse) => void): Promise<SafeNetCertificatesResponse>;
    info(callback?: (error: RestException, data: InfoResponse) => void): Promise<InfoResponse>;
    signData(data: SafeNetSignData, callback?: (error: RestException, data: DataResponse) => void): Promise<DataResponse>;
    slots(callback?: (error: RestException, data: SlotsResponse) => void): Promise<SlotsResponse>;
    slotsWithTokenPresent(callback?: (error: RestException, data: SlotsResponse) => void): Promise<SlotsResponse>;
    token(callback?: (error: RestException, data: TokensResponse) => void): Promise<TokensResponse>;
    verifySignedData(data: Pkcs11VerifySignedData,
                     callback?: (error: RestException, data: BoolDataResponse) => void): Promise<BoolDataResponse>;
}
```

Each interface will be covered on this wiki, accompanied with example code and response objects.

## Get the PKCS #11 container object

For more information on how to configure the T1C-JS client library see [Client Configuration](/t1c-js-guide/core/client-configuration.md).\
To set the locations of the PCKS#11 library, pass a `ModuleConfig` object when initializing the client:

```javascript
var moduleConfig = {
    "linux": "/usr/local/lib/libeTPkcs11.so",
    "mac": "/usr/local/lib/libeTPkcs11.dylib",
    "win": "C:\\Windows\\System32\\eTPKCS11.dll"
}

var config = new GCLConfig("ds uri", "apikey", moduleConfig);

GCLLib.GCLClient.initialize(config, function(err, gclClient) {
    // gclClient ready to use
});
```

Then grab a reference to the pkcs11 container:

```javascript
var pkcs11 = gclClient.pkcs11();
```

Call a function for the PKCS #11 container:

```javascript
function callback(err,data) {
    if(err){console.log("Error:",JSON.stringify(err, null, '  '));}
    else {console.log(JSON.stringify(data, null, '  '));}
}

gclClient.pkcs11(moduleConfig).certificates(callback);
```

## Reading data

### Info

This methods returns more information about the PKCS #11 library you are using.

```javascript
gclClient.pkcs11(moduleConfig).info(callback);
```

An example response:

```javascript
{
    "data":
    {
        "cryptoki_version": "2.20",
        "manufacturer_id": "SafeNet, Inc.",
        "flags": 7,
        "library_description": "eToken PKCS#11",
        "library_version": "9.1"
    }
    "success": true    
}
```

### Slots

This methods returns the available slots on the system.

```javascript
gclClient.pkcs11(moduleConfig).slots(callback);
```

An example response:

```javascript
{
    "data":
    [
        {
            "slot_id": 0,
            "description": "eToken 5100",
            "flags": 7,
            "hardware_version": "2.0",
            "firmware_version": "0.0"
        },
        {
            "slot_id": 1,
            "description": "",
            "flags": 2,
            "hardware_version": "2.0",
            "firmware_version": "0.0"
        }
    ]
    "success": true    
}
```

The flags value gives more information about the slot, possible values are

| Value | Description                                      |
| ----- | ------------------------------------------------ |
| 0     | Empty                                            |
| 1     | Token present                                    |
| 2     | Removable device                                 |
| 3     | Token present + removable device                 |
| 4     | Hardware slot                                    |
| 5     | Token present + hardware slot                    |
| 6     | Removable device + hardware slot                 |
| 7     | Token present + removable device + hardware slot |
| 32    | Unknown                                          |

### Slots with tokens present

This method is similar the the slots endpoint but only returns a list of slots where a token is present.

```javascript
gclClient.pkcs11(moduleConfig).slotsWithTokenPresent(callback);
```

An example response:

```javascript
{
    "data":
    [
        {
            "slot_id": 0,
            "description": "eToken 5100",
            "flags": 7,
            "hardware_version": "2.0",
            "firmware_version": "0.0"
        }
    ]
    "success": true    
}
```

### Token

This methods returns the token information for a slot.

```javascript
gclClient.pkcs11(moduleConfig).token(slot_id, callback);
```

An example response:

```javascript
{
    "data":
    {
        "slot_id": 1,
        "label": "Token Label",
        "manufacturer_id": "Gemalto",
        "model": "Safenet Token e5100",
        "serial_number": "1234567890",
        "flags": 7,
        "max_session_count": 10,
        "session_count": 1,
        "max_rw_session_count": 5,
        "rw_session_count": 1,
        "max_pin_length": 20,
        "min_pin_length": 8,
        "total_public_memory": 10000,
        "free_public_memory": 5000,
        "total_private_memory": 1000,
        "free_private_memory": 50,
        "hardware_version": "1",
        "firmware_version": "1"
    },
    "success": true    
}
```

### Certificates

This methods allows you to retrieve the certificates from the PKCS #11 token.

```javascript
// retrieve certificates for token in slot_id 0
gclClient.pkcs11(moduleConfig).certificates(0, { parseCerts: false }, callback);
```

An example callback:

```javascript
function callback(err,data) {
    if(err) {
        console.log("Error:",JSON.stringify(err, null, '  '));
    }
    else {
        console.log(JSON.stringify(data, null, '  '));
    }
}
```

Response:

```javascript
{
  "data": [
    {
      "base64": "MIIFjjCCA3agAwI...rTBDdrlEWVaLrY+M+xeIctrC0WnP7u4xg==",
      "id": "E8CE05618E79A79825722AE067EC0029851D860D"
    },
    {
      "base64": "MIIFjjCCA3agAwI...rTBDdrlEWVaLrY+M+xeIctrC0WnP7u4xg==",
      "id": "9F8F1CD68867526B1DF919832219B217282D2B0B"
    }
  ],
  "success": true
}
```

## Signing data

To successfully sign data, we need the following parameters:

* Slot ID of the token to use
* Certificate ID of the signing certificate
* PIN code
* Hashed data to sign
* Hashing algorithm used

The **slot id** can be found using either a call to `slots`, `slotsWithTokenPresent`. Once the slot id is found, the certificates can be retrieved with a call to `certificates`. This then returns the **certificate id**. Now we can combine this with the **PIN code** and hashed data + hashing algorithm (SHA1, SHA256, SHA384, SHA512) to create the final signData call:

### signData call

Returns signed data for provided input data.

```javascript
var signDataPayload = {
    slot_id: 1,
    cert_id: "9F8F1CD68867526B1DF919832219B217282D2B0B",
    pin: "thepincodeforthetoken",
    data: "hashed data"
    algorithm_reference: "sha256"
}

gclClient.pkcs11(moduleConfig).signData(signDataPayload, callback);
```

An example response:

```javascript
{
    "data": "L3BWs7lvoajPg5tC9GEmlSMdXMcDkNDUVVvt+KFqbJbXkJdI3DGoM3IOeXLaeTCxKmJ33/QQApL1nEAMuHY38V41czyswfSdpnqeex3EisXKkiYHeNzt9AXeoxDtsWbGkejKqru6X4xzAy/1SnccjZ2BQB/uUwyfyyweFjbZAGCLfTzWraCxG0ud2c8itsjmsBgXSuGjLqxKIJXbtuX22gd0nc4LeZLA91sxaoNFBCEVlOgJ/oJncFylf6T/Tz9R4VOA9kSf6NB1tAMsFEsihgjZafu/rzlrOfzZw4YY/T32LKY4Y2zNnDhJAucqflZjopGadDvkkSmTvxxEJuE+Bw==",
    "success": true    
}
```

### verifySignedData call

This call can be used to verify if the signed data is correct. The request is similar to `signData`, but we also pass in the signed hash:

```javascript
var verifyDataPayload = {
    slot_id: 1,
    cert_id: "9F8F1CD68867526B1DF919832219B217282D2B0B",
    pin: "thepincodeforthetoken",
    data: "hashed data"
    algorithm_reference: "sha256",
    signature: "signed hash"
}

gclClient.pkcs11(moduleConfig).verifySignedData(verifyDataPayload, callback);
```

An example response:

```javascript
{
    "data": true,
    "success": true    
}
```

## Error Handling

### Error Object

The functions specified are asynchronous and always need a callback function.\
The callback function will reply with a data object in case of success, or with an error object in case of an error. An example callback:

```javascript
function callback(err,data) {
    if(err){
        console.log("Error:",JSON.stringify(err, null, '  '));
    }
    else {
        console.log(JSON.stringify(data, null, '  '));
    }
}
```

The error object returned:

```javascript
{
  success: false,
  description: "some error description",
  code: "some error code"
}
```

For the error codes and description, see [Status codes](/t1c-js-guide/core/status-codes.md).


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://t1t.gitbook.io/t1c-js-guide/containers/pkcs/pkcs-11.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
