Sample code for 30+ languages & platforms
SQL Server

PKCS11 Discover Readers and Smart Cards / Tokens

See more PKCS11 Examples

Example showing how to discover the readers (slots) and smart cards and tokens available through a vendor's PKCS11 Cryptoki module.

Note: This example requires Chilkat v9.5.0.88 or later.

Chilkat SQL Server Downloads

SQL Server
-- Important: See this note about string length limitations for strings returned by sp_OAMethod calls.
--
CREATE PROCEDURE ChilkatSample
AS
BEGIN
    DECLARE @hr int
    -- Important: Do not use nvarchar(max).  See the warning about using nvarchar(max).
    DECLARE @sTmp0 nvarchar(4000)
    DECLARE @success int
    SELECT @success = 0

    -- This example requires the Chilkat API to have been previously unlocked.
    -- See Global Unlock Sample for sample code.

    -- Note: Chilkat's PKCS11 implementation runs on Windows, Linux, Mac OS X, and other supported operating systems.

    DECLARE @pkcs11 int
    EXEC @hr = sp_OACreate 'Chilkat.Pkcs11', @pkcs11 OUT
    IF @hr <> 0
    BEGIN
        PRINT 'Failed to create ActiveX component'
        RETURN
    END

    -- Specify the vendor's Cryptoki module DLL / shared lib.
    EXEC sp_OASetProperty @pkcs11, 'SharedLibPath', 'aetpkss1.dll'

    EXEC sp_OAMethod @pkcs11, 'Initialize', @success OUT
    IF @success = 0
      BEGIN
        EXEC sp_OAGetProperty @pkcs11, 'LastErrorText', @sTmp0 OUT
        PRINT @sTmp0
        EXEC @hr = sp_OADestroy @pkcs11
        RETURN
      END

    -- Call Discover to discover what's available.
    -- Indicate that we only want to return slots (readers) where tokens (smart cards) are present.
    -- (If the device is a USB token, such as an ePass300Auto, then by definition it has a "token" present.)
    DECLARE @onlyTokensPresent int
    SELECT @onlyTokensPresent = 1
    DECLARE @json int
    EXEC @hr = sp_OACreate 'Chilkat.JsonObject', @json OUT

    EXEC sp_OAMethod @pkcs11, 'Discover', @success OUT, @onlyTokensPresent, @json
    IF @success = 0
      BEGIN
        EXEC sp_OAGetProperty @pkcs11, 'LastErrorText', @sTmp0 OUT
        PRINT @sTmp0
        EXEC @hr = sp_OADestroy @pkcs11
        EXEC @hr = sp_OADestroy @json
        RETURN
      END

    EXEC sp_OASetProperty @json, 'EmitCompact', 0
    EXEC sp_OAMethod @json, 'Emit', @sTmp0 OUT
    PRINT @sTmp0

    -- Sample JSON output.
    -- Code for parsing this JSON is shown below..

    -- {
    --   "cryptokiVersion": {
    --     "major": 2,
    --     "minor": 20
    --   },
    --   "manufacturerID": "A.E.T. Europe B.V.",
    --   "libraryDescription": "Cryptographic Token Interface",
    --   "libraryVersion": {
    --     "major": 3,
    --     "minor": 0
    --   },
    --   "slot": [
    --     {
    --       "id": 52482,
    --       "slotDescription": "SCM Microsystems Inc. SCR33x USB Smart Card Reader 0",
    --       "manufacturerID": "SCM Microsystems Inc. SCR33x USB",
    --       "tokenPresent": true,
    --       "removableDevice": true,
    --       "hardwareSlot": true,
    --       "hardwareVersion": {
    --         "major": 0,
    --         "minor": 0
    --       },
    --       "firmwareVersion": {
    --         "major": 0,
    --         "minor": 0
    --       },
    --       "token": {
    --         "label": "chilkat",
    --         "manufacturerID": "A.E.T. Europe B.V.",
    --         "model": "19C40406010D00C0",
    --         "serialNumber": "21619600583C4505",
    --         "flags": [
    --           "CKF_RNG",
    --           "CKF_LOGIN_REQUIRED",
    --           "CKF_USER_PIN_INITIALIZED",
    --           "CKF_TOKEN_INITIALIZED"
    --         ],
    --         "maxSessionCount": 126,
    --         "sessionCount": 0,
    --         "maxRwSessionCount": 126,
    --         "rwSessionCount": 0,
    --         "maxPinLen": 15,
    --         "minPinLen": 4,
    --         "totalPublicMemory": 32767,
    --         "freePublicMemory": 32767,
    --         "totalPrivateMemory": 32767,
    --         "freePrivateMemory": 32767,
    --         "hardwareVersion": {
    --           "major": 0,
    --           "minor": 0
    --         },
    --         "firmwareVersion": {
    --           "major": 0,
    --           "minor": 0
    --         },
    --         "utcTime": "",
    --         "rsa": {
    --           "minKeySize": 768,
    --           "maxKeySize": 2048
    --         },
    --         "mechanism": [
    --           "CKM_RSA_PKCS",
    --           "CKM_RSA_X_509",
    --           "CKM_RSA_PKCS_OAEP",
    --           "CKM_MD5_RSA_PKCS",
    --           "CKM_SHA1_RSA_PKCS",
    --           "CKM_SHA224_RSA_PKCS",
    --           "CKM_SHA256_RSA_PKCS",
    --           "CKM_SHA384_RSA_PKCS",
    --           "CKM_SHA512_RSA_PKCS",
    --           "CKM_RIPEMD160_RSA_PKCS",
    --           "CKM_CPK_ECDSA",
    --           "CKM_CPK_ECDSA_SHA1",
    --           "CKM_CPK_ECIES",
    --           "CKM_CPK_ECIES_STDDH_SHA1KDF_DES3CBC_PAD_SHA1HMAC",
    --           "CKM_CPK_ECIES_STDDH_SHA1KDF_AES128CBC_PAD_SHA1HMAC",
    --           "CKM_CPK_PKCS7_SIGNED",
    --           "CKM_CPK_PKCS7_ENVELOPE_DES3CBC_PAD",
    --           "CKM_RSA_PKCS_PSS",
    --           "CKM_RSA_PKCS_KEY_PAIR_GEN",
    --           "CKM_RC2_KEY_GEN",
    --           "CKM_RC2_ECB",
    --           "CKM_RC2_CBC",
    --           "CKM_RC2_CBC_PAD",
    --           "CKM_RC4_KEY_GEN",
    --           "CKM_RC4",
    --           "CKM_DES_KEY_GEN",
    --           "CKM_DES2_KEY_GEN",
    --           "CKM_DES3_KEY_GEN",
    --           "CKM_DES_ECB",
    --           "CKM_DES_CBC",
    --           "CKM_DES3_ECB",
    --           "CKM_DES3_CBC",
    --           "CKM_DES_CBC_PAD",
    --           "CKM_DES3_CBC_PAD",
    --           "CKM_MD5",
    --           "CKM_SHA_1",
    --           "CKM_SHA224",
    --           "CKM_SHA256",
    --           "CKM_SHA384",
    --           "CKM_SHA512",
    --           "CKM_RIPEMD160"
    --         ]
    --       }
    --     }
    --   ]
    -- }

    -- Use this online tool to generate parsing code from sample JSON: 
    -- Generate Parsing Code from JSON

    DECLARE @id int

    DECLARE @slotDescription nvarchar(4000)

    DECLARE @tokenPresent int

    DECLARE @removableDevice int

    DECLARE @hardwareSlot int

    DECLARE @hardwareVersionMajor int

    DECLARE @hardwareVersionMinor int

    DECLARE @firmwareVersionMajor int

    DECLARE @firmwareVersionMinor int

    DECLARE @tokenLabel nvarchar(4000)

    DECLARE @tokenManufacturerID nvarchar(4000)

    DECLARE @tokenModel nvarchar(4000)

    DECLARE @tokenSerialNumber nvarchar(4000)

    DECLARE @tokenMaxSessionCount int

    DECLARE @tokenSessionCount int

    DECLARE @tokenMaxRwSessionCount int

    DECLARE @tokenRwSessionCount int

    DECLARE @tokenMaxPinLen int

    DECLARE @tokenMinPinLen int

    DECLARE @tokenTotalPublicMemory int

    DECLARE @tokenFreePublicMemory int

    DECLARE @tokenTotalPrivateMemory int

    DECLARE @tokenFreePrivateMemory int

    DECLARE @tokenHardwareVersionMajor int

    DECLARE @tokenHardwareVersionMinor int

    DECLARE @tokenFirmwareVersionMajor int

    DECLARE @tokenFirmwareVersionMinor int

    DECLARE @tokenUtcTime nvarchar(4000)

    DECLARE @tokenRsaMinKeySize int

    DECLARE @tokenRsaMaxKeySize int

    DECLARE @j int

    DECLARE @count_j int

    DECLARE @strVal nvarchar(4000)

    -- Use this online tool to generate parsing code from sample JSON: 
    -- Generate Parsing Code from JSON

    DECLARE @cryptokiVersionMajor int
    EXEC sp_OAMethod @json, 'IntOf', @cryptokiVersionMajor OUT, 'cryptokiVersion.major'
    DECLARE @cryptokiVersionMinor int
    EXEC sp_OAMethod @json, 'IntOf', @cryptokiVersionMinor OUT, 'cryptokiVersion.minor'
    DECLARE @manufacturerID nvarchar(4000)
    EXEC sp_OAMethod @json, 'StringOf', @manufacturerID OUT, 'manufacturerID'
    DECLARE @libraryDescription nvarchar(4000)
    EXEC sp_OAMethod @json, 'StringOf', @libraryDescription OUT, 'libraryDescription'
    DECLARE @libraryVersionMajor int
    EXEC sp_OAMethod @json, 'IntOf', @libraryVersionMajor OUT, 'libraryVersion.major'
    DECLARE @libraryVersionMinor int
    EXEC sp_OAMethod @json, 'IntOf', @libraryVersionMinor OUT, 'libraryVersion.minor'
    DECLARE @i int
    SELECT @i = 0
    DECLARE @count_i int
    EXEC sp_OAMethod @json, 'SizeOfArray', @count_i OUT, 'slot'
    WHILE @i < @count_i
      BEGIN
        EXEC sp_OASetProperty @json, 'I', @i
        EXEC sp_OAMethod @json, 'IntOf', @id OUT, 'slot[i].id'
        EXEC sp_OAMethod @json, 'StringOf', @slotDescription OUT, 'slot[i].slotDescription'
        EXEC sp_OAMethod @json, 'StringOf', @manufacturerID OUT, 'slot[i].manufacturerID'
        EXEC sp_OAMethod @json, 'BoolOf', @tokenPresent OUT, 'slot[i].tokenPresent'
        EXEC sp_OAMethod @json, 'BoolOf', @removableDevice OUT, 'slot[i].removableDevice'
        EXEC sp_OAMethod @json, 'BoolOf', @hardwareSlot OUT, 'slot[i].hardwareSlot'
        EXEC sp_OAMethod @json, 'IntOf', @hardwareVersionMajor OUT, 'slot[i].hardwareVersion.major'
        EXEC sp_OAMethod @json, 'IntOf', @hardwareVersionMinor OUT, 'slot[i].hardwareVersion.minor'
        EXEC sp_OAMethod @json, 'IntOf', @firmwareVersionMajor OUT, 'slot[i].firmwareVersion.major'
        EXEC sp_OAMethod @json, 'IntOf', @firmwareVersionMinor OUT, 'slot[i].firmwareVersion.minor'
        EXEC sp_OAMethod @json, 'StringOf', @tokenLabel OUT, 'slot[i].token.label'
        EXEC sp_OAMethod @json, 'StringOf', @tokenManufacturerID OUT, 'slot[i].token.manufacturerID'
        EXEC sp_OAMethod @json, 'StringOf', @tokenModel OUT, 'slot[i].token.model'
        EXEC sp_OAMethod @json, 'StringOf', @tokenSerialNumber OUT, 'slot[i].token.serialNumber'
        EXEC sp_OAMethod @json, 'IntOf', @tokenMaxSessionCount OUT, 'slot[i].token.maxSessionCount'
        EXEC sp_OAMethod @json, 'IntOf', @tokenSessionCount OUT, 'slot[i].token.sessionCount'
        EXEC sp_OAMethod @json, 'IntOf', @tokenMaxRwSessionCount OUT, 'slot[i].token.maxRwSessionCount'
        EXEC sp_OAMethod @json, 'IntOf', @tokenRwSessionCount OUT, 'slot[i].token.rwSessionCount'
        EXEC sp_OAMethod @json, 'IntOf', @tokenMaxPinLen OUT, 'slot[i].token.maxPinLen'
        EXEC sp_OAMethod @json, 'IntOf', @tokenMinPinLen OUT, 'slot[i].token.minPinLen'
        EXEC sp_OAMethod @json, 'IntOf', @tokenTotalPublicMemory OUT, 'slot[i].token.totalPublicMemory'
        EXEC sp_OAMethod @json, 'IntOf', @tokenFreePublicMemory OUT, 'slot[i].token.freePublicMemory'
        EXEC sp_OAMethod @json, 'IntOf', @tokenTotalPrivateMemory OUT, 'slot[i].token.totalPrivateMemory'
        EXEC sp_OAMethod @json, 'IntOf', @tokenFreePrivateMemory OUT, 'slot[i].token.freePrivateMemory'
        EXEC sp_OAMethod @json, 'IntOf', @tokenHardwareVersionMajor OUT, 'slot[i].token.hardwareVersion.major'
        EXEC sp_OAMethod @json, 'IntOf', @tokenHardwareVersionMinor OUT, 'slot[i].token.hardwareVersion.minor'
        EXEC sp_OAMethod @json, 'IntOf', @tokenFirmwareVersionMajor OUT, 'slot[i].token.firmwareVersion.major'
        EXEC sp_OAMethod @json, 'IntOf', @tokenFirmwareVersionMinor OUT, 'slot[i].token.firmwareVersion.minor'
        EXEC sp_OAMethod @json, 'StringOf', @tokenUtcTime OUT, 'slot[i].token.utcTime'
        EXEC sp_OAMethod @json, 'IntOf', @tokenRsaMinKeySize OUT, 'slot[i].token.rsa.minKeySize'
        EXEC sp_OAMethod @json, 'IntOf', @tokenRsaMaxKeySize OUT, 'slot[i].token.rsa.maxKeySize'
        SELECT @j = 0
        EXEC sp_OAMethod @json, 'SizeOfArray', @count_j OUT, 'slot[i].token.flags'
        WHILE @j < @count_j
          BEGIN
            EXEC sp_OASetProperty @json, 'J', @j
            EXEC sp_OAMethod @json, 'StringOf', @strVal OUT, 'slot[i].token.flags[j]'
            SELECT @j = @j + 1
          END
        SELECT @j = 0
        EXEC sp_OAMethod @json, 'SizeOfArray', @count_j OUT, 'slot[i].token.mechanism'
        WHILE @j < @count_j
          BEGIN
            EXEC sp_OASetProperty @json, 'J', @j
            EXEC sp_OAMethod @json, 'StringOf', @strVal OUT, 'slot[i].token.mechanism[j]'
            SELECT @j = @j + 1
          END
        SELECT @i = @i + 1
      END

    EXEC @hr = sp_OADestroy @pkcs11
    EXEC @hr = sp_OADestroy @json


END
GO