Crescendo SDK
Loading...
Searching...
No Matches
Examples

Note
Advanced / more detailed C# code examples can also be found in the Examples folder inside the released SDK package. The folder contains a complete solution (Examples.sln file) and individual projects (*.csproj files) for each example, so that you can run them directly.

All strings, hex-strings and other values used in the examples are arbitrary, just to show the functionality of the SDK. Replace them when using the SDK in your own environment.

Device Management

List Connected Tokens/Readers

This function will list all connected readers, tokens and their respective ATRs.

Command Line Tool

To list all the readers with connected tokens, use the token-info command:

.\CrescendoCLI.exe token-info --log-level info

An example response to this command might look like this:

[2024-05-31 15:40:50.516][INFO] Log level is set to "INFO".
[2024-05-31 15:40:50.570][INFO] All connected tokens:
- Reader Name: Circle Idaxis SecurePIV 0
- Token: Crescendo 4000
- Token ATR: 3B-D5-96-FF-81-91-FE-1F-C3-43-34-30-30-30-C9
- Assigned number for the "-t" parameter: 0
- Reader Name: VMware Virtual USB CCID 0
- Token: Crescendo Key V3
- Token ATR: 3B-D9-96-FF-81-91-FE-1F-C3-43-34-30-30-30-2D-4B-45-59-BF
- Assigned number for the "-t" parameter: 1

C#

You can use one of three possible functions to list token/reader info:

  • GetAllAvailableTokens - returns a list of all available tokens with their names, ATRs, and the reader name.
  • GetAllAvailableReaders - returns a list of all available reader names, regardless of whether they have tokens connected or not. Does not communicate with tokens at all, and should be faster than the other two methods.
  • GetAllReaderInfo - returns a comprehensive list of ReaderInfo objects, that contain detailed information about each reader, including the connected tokens and their ATRs.
List<(string ReaderName, byte[] TokenATR, string TokenName, int TokenIndex)> allAvailableTokens = SDKCore.GetAllAvailableTokens();
List<string> allReaders = SDKCore.GetAllAvailableReaders();
List<ReaderInfo> allReadersWithDetails = SDKCore.GetAllReaderInfo();

Python

You can call GetAllAvailableTokens method directly like this:

readerList = SDKCore.GetAllAvailableTokens()

Token connection monitoring

Note
More detailed C# code example can be found in the Examples/LiveReaderTokenMonitoring folder inside the released SDK package.

You can use the SDK to monitor the present tokens and readers, to detect when a card, USB token or a reader is inserted or removed. By using the OnReadersChanged event, you can get notified about changes in the readers and tokens and then run any other code or method you want. The monitoring can be started with the StartMonitoring method and stopped with the EndMonitoring method. For example:

// Do initial scan for tokens, so you can select one to work with
List<(string ReaderName, byte[] TokenATR, string TokenName, int TokenIndex)> allAvailableTokens = SDKCore.GetAllAvailableTokens();
// Subscribe to live monitoring events
SDKCore.OnReadersChanged += (allReaders, changes) =>
{
// Define the action to be taken when readers or tokens change
};
// Start background monitoring
SDKCore.StartMonitoring();
// Select one specific token and continue to work with it
using (SDKCore methods = new(allAvailableTokens[0].ReaderName))
{
// Do the desired operations with given token here
}
// End the background monitoring
SDKCore.EndMonitoring();

Get CUID of a token

To obtain a CUID of a token, use the token-cuid command:

.\CrescendoCLI.exe token-cuid -t 0 --log-level info

An example response to this command might look like this:

[2025-04-28 10:16:47.333][INFO] Log level is set to "INFO".
[2025-04-28 10:16:47.493][INFO] Connected to:
[2025-04-28 10:16:47.494][INFO] - Reader: "Circle Idaxis SecurePIV 0"
[2025-04-28 10:16:47.494][INFO] - Token: "Crescendo 4000"
[2025-04-28 10:16:47.494][INFO] - ATR: 3B-D5-96-FF-81-91-FE-1F-C3-43-34-30-30-30-C9
[2025-04-28 10:16:47.581][INFO] The token CUID is: 4790D600535905872620
4790D600535905872620

C#

After the initial set-up, you can call the GetTokenCUID method like this:

SDKCore.Result<string> result = transaction.GetTokenCUID();

Python

After the initial set-up, you can call the GetTokenCUID method like this:

dllMethodsInstance.GetTokenCUID()

Change PIN

This function will change the PIN on the token and output the newly set PIN.

Important input parameters

  • --pin - PIN to be used for authentication. String env can be used to read an Environment Variable PIN as a valid key. String interactive can be used to utilize the Windows interactive window for PIN entering.
  • --new-pin - New PIN value. If no value is entered, then a random 6 digit numeric-only number will be used as a new PIN value.

Command Line Tool

Example of pin-change command usage:

.\CrescendoCLI.exe pin-change -p 123456 -n 654321 --log-level info

This will change the PIN from 123456 to 654321. An example response to this command might look like this:

[2024-04-18 15:36:26.659][INFO] Log level is set to "INFO".
[2024-04-18 15:36:26.707][INFO] Connected to:
[2024-04-18 15:36:26.708][INFO] - Reader: "Circle Idaxis SecurePIV 0"
[2024-04-18 15:36:26.708][INFO] - Token: "Crescendo 4000"
[2024-04-18 15:36:26.708][INFO] - ATR: 3B-D5-96-FF-81-91-FE-1F-C3-43-34-30-30-30-C9
[2024-04-18 15:36:26.760][INFO] Trying to change PIN from "123456" to "654321"
[2024-04-18 15:36:26.836][INFO] PIN was successfully verified on ACA applet.
[2024-04-18 15:36:26.891][INFO] PIN was successfully verified on PIV applet.
[2024-04-18 15:36:26.929][INFO] PIN successfully changed to "654321".
654321

C#

After the initial set-up, you can call the ChangePIN method like this:

SDKCore.Result<string> result = transaction.ChangePin("123456");

Python

After the initial set-up, you can call the ChangePIN method like this:

params = {
'newPin': '654321',
}
dllMethodsInstance.ChangePIN(**params)

Set or change XAUTH

This function will set or change the XAUTH (Management key) on the token.

Command Line Tool

Example of xauth-key-put command usage:

.\CrescendoCLI.exe xauth-key-put -p 321321 -x 12345678123456781234567812345678 --log-level info

This will change the XAUTH to 12345678123456781234567812345678. An example response to this command might look like this:

[2024-09-03 15:32:22.422][INFO] Log level is set to "INFO".
[2024-09-03 15:32:22.455][INFO] Connected to:
[2024-09-03 15:32:22.455][INFO] - Reader: "HID Global OMNIKEY 5422 Smartcard Reader 0"
[2024-09-03 15:32:22.455][INFO] - Token: "Crescendo 4000"
[2024-09-03 15:32:22.455][INFO] - ATR: 3B-D5-96-FF-81-91-FE-1F-C3-43-34-30-30-30-C9
[2024-09-03 15:32:22.551][INFO] PIN was successfully verified on ACA applet.
[2024-09-03 15:32:22.627][INFO] Symmetric XAUTH "AES" key was successfully put onto the token.

C#

After the initial set-up, you can call the PutXAUTHKey method like this:

SDKCore.Result result = transaction.PutXAUTHKey("12345678123456781234567812345678", default!, "");

Python

After the initial set-up, you can call the PutXAUTHKey method like this:

params = {
'xauthKey': '12345678123456781234567812345678',
'xauthKeyType': None,
'jsonInputPath': '',
}
dllMethodsInstance1.PutXAUTHKey(**params)

Reset Token

This function will reset the token to its default state and remove any data, keys or certificates stored on the key.

Command Line Tool

Example of token-reset command usage:

.\CrescendoCLI.exe token-reset -p 123456 --log-level info

This will reset the token. An example response to this command might look like this:

[2024-04-18 15:59:15.989][INFO] Log level is set to "INFO".
[2024-04-18 15:59:16.105][INFO] Connected to:
[2024-04-18 15:59:16.106][INFO] - Reader: "Circle Idaxis SecurePIV 0"
[2024-04-18 15:59:16.106][INFO] - Token: "Crescendo 4000"
[2024-04-18 15:59:16.106][INFO] - ATR: 3B-D5-96-FF-81-91-FE-1F-C3-43-34-30-30-30-C9
[2024-04-18 15:59:16.191][INFO] PIN was successfully verified on ACA applet.
[2024-04-18 15:59:16.192][INFO] Trying to reset the token:
[2024-04-18 15:59:16.930][INFO] PIN was successfully verified on ACA applet.
[2024-04-18 15:59:16.984][INFO] PIN was successfully verified on PIV applet.
[2024-04-18 15:59:17.133][INFO] Token was successfully reset.

C#

After the initial set-up, you can call the ResetToken method like this:

SDKCore.Result result = transaction.ResetToken();

Python

After the initial set-up, you can call the ResetToken method like this:

dllMethodsInstance.ResetToken()

PIV Configuration

Generate Key Pair / Retrieve Public Key

This function allows to generate an Asymmetric Key Pair on the token, or retrieve the Public key, if the Key Pair was already generated in the past. It will always return the public key.

Important input parameters

  • --crypto-mechanism - The desired cryptographic mechanism. Valid options can be found here.
  • --key-reference - Key Reference where the generated Key Pair will be stored.
  • --retrieve-key - If the Key Pair was generated previously, use this to just retrieve it instead of generating a new Key Pair.
  • --output-file **(Available in CLI Tool only)** - Path to an output file that should contain the public key. When left empty, the public key will simply be logged.

Command Line Tool

Example of piv-key-pair-gen command usage:

.\CrescendoCLI.exe piv-key-pair-gen -p 123456 --crypto-mechanism RSA3072 --key-reference B0 --output-file C:\Temp\publicKey.pem --log-level info

This will generate a RSA3072 key pair on the Key Reference B0 and save the public key (modulus and exponent) to the defined file C:\Temp\publicKey.pem. An example response to this command might look like this:

[2024-04-18 14:25:44.326][INFO] Log level is set to "INFO".
[2024-04-18 14:25:44.354][INFO] Connected to:
[2024-04-18 14:25:44.355][INFO] - Reader: "Circle Idaxis SecurePIV 0"
[2024-04-18 14:25:44.355][INFO] - Token: "Crescendo 4000"
[2024-04-18 14:25:44.355][INFO] - ATR: 3B-D5-96-FF-81-91-FE-1F-C3-43-34-30-30-30-C9
[2024-04-18 14:25:44.430][INFO] PIN was successfully verified on ACA applet.
[2024-04-18 14:25:44.448][INFO] Trying to generate asymmetric key pair on Key Reference "B0". This will take several seconds.
[2024-04-18 14:26:00.778][INFO] PIN was successfully verified on PIV applet.
[2024-04-18 14:26:00.795][INFO] Successful addition of tags and specified data to buffer "5FC160".
[2024-04-18 14:26:00.817][INFO] Successful generation of the asymmetric key pair.

C#

After the initial set-up, you can call the PIVGenerateKeyPair method like this:

SDKCore.Result<string> result = transaction.PIVGenerateKeyPair(PIVCryptographicMechanismIdentifier.RSA3072, "B0");
File.WriteAllText("C:\Temp\publicKey.pem", result.Value);

Python

After the initial set-up, you can call the PIVGenerateKeyPair method like this:

from CrescendoDLL.PCSC import PIVCryptographicMechanismIdentifier
params = {
'cryptoMechanism': PIVCryptographicMechanismIdentifier.RSA3072,
'keyReference': 'B0',
'getExistingPublicKey': False,
}
dllMethodsInstance.PIVGenerateKeyPair(**params)
The CrescendoDLL.PCSC namespace contains Enums relevant to public methods from the main CrescendoDLL ...
Definition APDUEngine.cs:8

Load Key / Certificate

This function allows to put private key, certificate, or both, to the token.

Important input parameters

  • --input-file - Path to an input file containing either a private key, certificate, or a combination of both. The supported file formats are *.PEM, *.CRT, *.PFX and *.P12. If there are multiple certificates present in the input file, only the first one will be imported. If the --object-type parameter is set to both, then a first certificate that also has a private key will be imported.
  • --input-pass - Password for opening the input file
  • --key-reference - Key Reference where the private key will be stored.
  • --ber-tlv-tag - BER-TLV Tag of the data object where the certificate will be stored.
  • --object-type - Parameter for specifying what type of PKI object should be imported to the token. Valid options can be found here.
  • --key-name - Key Name, that can be stored on the token and later used to identify the key.

Command Line Tool

Example of piv-pki-put command usage:

.\CrescendoCLI.exe piv-pki-put -p 123456 --key-reference 9C --input-file "C:\Temp\ECCCert.p12" --input-pass password --object-type both --key-name MyNewKey --log-level info

This will load both Private Key and a certificate from file located at C:\Temp\ECCCert.p12 to the token. An example response to this command might look like this:

[2024-04-18 14:26:22.120][INFO] Log level is set to "INFO".
[2024-04-18 14:26:22.238][INFO] Connected to:
[2024-04-18 14:26:22.239][INFO] - Reader: "Circle Idaxis SecurePIV 0"
[2024-04-18 14:26:22.239][INFO] - Token: "Crescendo 4000"
[2024-04-18 14:26:22.239][INFO] - ATR: 3B-D5-96-FF-81-91-FE-1F-C3-43-34-30-30-30-C9
[2024-04-18 14:26:22.387][INFO] PIN was successfully verified on ACA applet.
[2024-04-18 14:26:22.441][INFO] Trying to inject RSA key - "p" component.
[2024-04-18 14:26:22.621][INFO] Trying to inject RSA key - "q" component.
[2024-04-18 14:26:22.645][INFO] Trying to inject RSA key - "q^(-1)" component.
[2024-04-18 14:26:22.670][INFO] Trying to inject RSA key - "dP" component.
[2024-04-18 14:26:22.694][INFO] Trying to inject RSA key - "dQ" component.
[2024-04-18 14:26:22.760][INFO] PIN was successfully verified on PIV applet.
[2024-04-18 14:26:22.835][INFO] PIN was successfully verified on PIV applet.
[2024-04-18 14:26:23.048][INFO] PIN was successfully verified on PIV applet.
[2024-04-18 14:26:23.088][INFO] Successful addition of tags and specified data to buffer "5FC10A".
[2024-04-18 14:26:23.089][INFO] Successful injection of private key with name "MyNewKey" to the key reference "9C".
[2024-04-18 14:26:23.128][INFO] PIN was successfully verified on PIV applet.
[2024-04-18 14:26:23.484][INFO] PIN was successfully verified on PIV applet.
[2024-04-18 14:26:23.524][INFO] Successful addition of tags and specified data to buffer "5FC10A".

C#

After the initial set-up, you can call the PIVPutPKIData method like this:

SDKCore.Result result = transaction.PIVPutPKIData("C:\\Temp\\ECCCert.p12", "password", PIVObjectType.both, "9C", "", "MyNewKey");

Python

After the initial set-up, you can call the PIVPutPKIData method like this:

from CrescendoDLL.PCSC import PIVObjectType
params = {
'inputfilePath': 'C:\Temp\ECCCert.p12',
'password': 'password',
'pkiObjectType': PIVObjectType.both,
'keyReference': '9C',
'berTLVtag': '',
'keyName': 'MyNewKey',
}
dllMethodsInstance.PIVPutPKIData(**params)

Sign Data

This function will take data from input file or input string, create a Hash of the data and send it to the token to get the hash signed back using a specified private key.

Important input parameters

  • --key-reference - Key Reference defining the private key that will be used for signing.
  • --input-file - Path to file that with the data to be hashed and signed.
  • --input-string - Input string that should be hashed and signed.
  • --input-type - Encoding of the input string. Valid options (case-insensitive) are HEX, BASE64, BASE64URL, UTF8 and BIN. BIN does only make sense when using an input file to read all bytes directly.
  • --output-file - Path to an output file that should contain the signature. When left empty, the signature will simply be logged.
  • --output-type - Encoding of the output string containing the signature. Valid options (case-insensitive) are HEX, BASE64, BASE64URL, UTF8 and BIN (to save the signature bytes directly without any encoding).
  • --hash - Hash algorithm to be used for hashing the input data. Valid options (case-insensitive) are: SHA1, SHA256 and SHA512.

Command Line Tool

Example of piv-data-sign command usage:

.\CrescendoCLI.exe piv-data-sign -p 123456 -i "C:\Temp\LoremIpsum.txt" --input-type utf8 --key-reference 9a --log-level info

This will return a signature of data stored in C:\Temp\LoremIpsum.txt using a private key stored on Key Reference 9A. An example response to this command might look like this:

[2024-05-31 15:55:07.135][INFO] Log level is set to "INFO".
[2024-05-31 15:55:07.260][INFO] Connected to:
[2024-05-31 15:55:07.260][INFO] - Reader: "Circle Idaxis SecurePIV 0"
[2024-05-31 15:55:07.260][INFO] - Token: "Crescendo 4000"
[2024-05-31 15:55:07.260][INFO] - ATR: 3B-D5-96-FF-81-91-FE-1F-C3-43-34-30-30-30-C9
[2024-05-31 15:55:07.349][INFO] PIN was successfully verified on ACA applet.
[2024-05-31 15:55:07.486][INFO] PIN was successfully verified on PIV applet.
[2024-05-31 15:55:07.984][INFO] Successful signing of the input data.
ZA2XlPJ6r5JJMVhXBA2cvQFJFDc5Ua7RlW53q2HoGKptEav7jYO/lfud82YHldqw0Ln92u2Br2TYjJDhZLLs68j2EmoyifYpt+rj3wL56IkRhAm1r1pLc9B2w69ntL35YEwXjoeDGQEFzho2VwGVpPVeRVm/pb0/vJYTBRHIHe+ZzkN0WbGZ77gW4qpXHIeyM+HMq4CwFIDmNmuQ4l/X4+cgcadYtbs+AthsnrcgXytIp3vEANPul/PoS2w4VloTRIkMSCv9dZRMSJ5qrqHA/An4+x/YGdBR34a3FILTi4XUyy3ZZ7n1LBO0Dwfx1MC1b73auI2p8L9elY8T60+lgDvFPEHA2B6sQjbuF/jWe3j6Opf0yCK+Poz5rBpLx3P0iIQn40vnWK1w7enBXhyS90KG9OH/xpBpMHcFlborrWju8QdrnoivoT/O0dBW9X6bNIxz9ORUVfAttNzVpcxBBahg74sBO00ufkYeTZ6qDgIuS+T92+Xc3e0b+mH8APrsRq1T2bJbtDgTkvP4k6ZzhsSvHdED3tfYEA2IxW1OHiitkosdWDy6ZwvOPlSYw8TU/pwSvqEFm1mJrxirToEtyWddEzL6OCUM8kxGqbUKgh19BzZYI9FAFhs+oWXupHZKmdcNWiWkAQhrGimts7+88mN8nFWa2eSyW792GE/vAsY=

C#

After the initial set-up, you can call the PIVSignData method like this:

SDKCore.Result<string> result = transaction.PIVSignData("9A", DataType.UTF8, "", "C:\\Temp\\LoremIpsum.txt", DataType.BASE64, HashAlgoValues.SHA256);

Python

After the initial set-up, you can call the PIVSignData method like this:

from CrescendoDLL.PCSC DataType, HashAlgoValues
params = {
'keyReference': '9A',
'inputType': DataType.UTF8,
'inputString': '',
'inputFilePath': 'C:\Temp\LoremIpsum.txt',
'outputType': DataType.BASE64,
'hashAlgo': HashAlgoValues.SHA256,
}
dllMethodsInstance.PIVSignData(**params)

OTP Configuration

Configure OTP

This function will configure selected OTP slot, so that it can be used for OTP generation. Various input parameters can be specified. The function will also generate (or update already existing) PKCS file.

Important input parameters

  • --oath-slot - OATH slot number (case-insensitive). Valid options for V3 applet are: 1-3, valid options for V4 applet are: C0-CF for user slots, 00-0F for managed slots. The parameter --button-press will overrule this one in case both are entered.
  • --button-press - Parameter for identifying OATH button-press slots. With Crescendo Key V1 & V2 (applet V3) you can configure the single button-press slot also by using --oath-slot 1. Valid options are 1 for single press (on both applet V3 and V4) and 2 for double press (applet V4 only).
  • --oath-key - OATH key (secret) to be stored to the token.
  • --mode - OATH mode to be used. Valid options can be found here
  • --pskc-path - Path to a PSKC file. If the PSKC file already exists in the specified path, it will get updated. Otherwise new file will be generated. Without defining explicit path, the file will be stored in .\PSKC under the token CUID and *.pskc extension.
  • --transport-key - Transport key used for creation of the PSKC file content.
  • --friendly-name - Friendly name for description. Must be max 64 bytes (characters) long for applet V3, 32 bytes (characters) for applet V4.
  • --require-touch - Set this parameter with Crescendo Key V3 to require PIN + button press to retrieve the OTP.

Command Line Tool

Example of otp-slot-configure command usage:

.\CrescendoCLI.exe otp-slot-configure -p 123456 --oath-slot C5 --oath-key 0910f75fb6 --mode TOTP --friendly-name "OATH TOTP" --pskc-path "c:\Temp\PSKCFile.pskc" --transport-key 12345678123456781234567812345678 --log-level info

This will configure the oath slot C5 to use TOTP on a single button-press and store the secret 0910f75fb6 to the token, so that OTP can be used. An example response to this command might look like this:

[2024-04-18 14:39:44.373][INFO] Log level is set to "INFO".
[2024-04-18 14:39:44.421][INFO] Connected to:
[2024-04-18 14:39:44.422][INFO] - Reader: "Circle Idaxis SecurePIV 0"
[2024-04-18 14:39:44.422][INFO] - Token: "Crescendo 4000"
[2024-04-18 14:39:44.422][INFO] - ATR: 3B-D5-96-FF-81-91-FE-1F-C3-43-34-30-30-30-C9
[2024-04-18 14:39:44.506][INFO] PIN was successfully verified on ACA applet.
[2024-04-18 14:39:44.724][INFO] The OATH configuration was successfully put to slot "C5".
[2024-04-18 14:39:44.764][INFO] The OATH key was successfully put to slot "C5".
[2024-04-18 14:39:44.819][INFO] PIN was successfully verified on PIV applet.
[2024-04-18 14:39:44.978][INFO] Successfully updated the PSKC file located at "c:\Temp\PSKCFile.pskc".

C#

After the initial set-up, you can call the ConfigureOATHSlot method like this:

SDKCore.Result<string> result = transaction.ConfigureOATHSlot("C5", 0, "0910f75fb6", 30, OATHModeName.TOTP, "0000000000000000", HashAlgoValues.SHA1, 6, "OATH TOTP", 16, "12345678123456781234567812345678", "", false);

Python

After the initial set-up, you can call the ConfigureOATHSlot method like this:

from CrescendoDLL.PCSC import OATHModeName, HashAlgoValues
params = {
'oathSlot': 'C5',
'buttonPress': 0,
'oathKey': '0910f75fb6',
'jsonInputPath': '',
'timeStep': 30,
'oathMode': OATHModeName.TOTP,
'oathCounter': '0000000000000000',
'oathHash': HashAlgoValues.SHA1,
'codeDigits': 6,
'friendlyName': 'OATH TOTP',
'truncationOffset': 16,
'transportKey': '12345678123456781234567812345678',
'pskcString': '',
'requireTouch': false,
}
dllMethodsInstance.ConfigureOATHSlot(**params)

Generate OTP

This function will return an OTP generated from the specified OTP slot.

Important input parameters

  • --oath-slot - OATH slot number (case-insensitive). Valid options for V3 applet are: 1-3, valid options for V4 applet are: C0-CF for user slots, 00-0F for managed slots. The parameter --button-press will overrule this one in case both are entered.
  • --button-press - Parameter for identifying OATH button-press slots. With Crescendo Key V1 & V2 (applet V3) you can configure the single button-press slot also by using --oath-slot 1. Valid options are 1 for single press (on both applet V3 and V4) and 2 for double press (applet V4 only).

Command Line Tool

Example of otp-generate command usage:

.\CrescendoCLI.exe otp-generate --oath-slot C5 -p 123456 --log-level info

This will configure the oath slot C5 to use TOTP and store the secret 0910f75fb6 to the token, so that OTP can be used. An example response to this command might look like this:

[2024-04-18 15:19:47.584][INFO] Log level is set to "INFO".
[2024-04-18 15:19:47.779][INFO] Connected to:
[2024-04-18 15:19:47.780][INFO] - Reader: "Circle Idaxis SecurePIV 0"
[2024-04-18 15:19:47.780][INFO] - Token: "Crescendo 4000"
[2024-04-18 15:19:47.780][INFO] - ATR: 3B-D5-96-FF-81-91-FE-1F-C3-43-34-30-30-30-C9
[2024-04-18 15:19:47.920][INFO] PIN was successfully verified on ACA applet.
[2024-04-18 15:19:47.925][INFO] Trying to generate OTP with key from OATH slot C5.
328482

C#

After the initial set-up, you can call the GenerateOTP method like this:

SDKCore.Result<string> result = transaction.GenerateOTP("C5", 0);

Python

After the initial set-up, you can call the GenerateOTP method like this:

params = {
'oathSlot': 'C5',
'buttonPress': 0,
}
dllMethodsInstance.GenerateOTP(**params)

FIDO Configuration

The SDK provides a set of functions that can be used to manage the FIDO configuration and perform FIDO operations, as per the FIDO CTAP2 standard. All possible request and response parameters are defined as an objects in the SDK (CrescendoDLL.PCSC.FIDODataStructures class), so the user does not have to deal with the raw byte arrays. All functions return a Result<T> object, which contains the response object (if any) and the status of the operation. The following functions directly from the FIDO CTAP2 standard are available:

To simplify the usage of FIDO CTAP2 functions, the SDK also provides a set of functions that automatically perform the full authentication flow, meaning the user does not have to deal with externally computing the shared secret, determining the CTAP version (pinUvAuthProtocol) etc. Functions listed below will also automatically determine CTAP versions supported by the protocol, and use the newest one (for Crescendo devices, this would most likely be CTAP2.1).

Note
Elevated privileges are needed to automatically determine the supported CTAP version, and therefore all methods in the list below require elevated privileges.

The following functions are available for simplified FIDO CTAP2 usage:

The SDK also provides a way to unblock the FIDO PIN without having to reset all FIDO credentials. To achieve that, there are two functions available. Elevated privileges are not needed for this workflow.

In addition, the SDK provides legacy functions for support of FIDO U2F (CTAP1) protocol. Again, all possible request and response parameters are defined as an objects in the SDK (CrescendoDLL.PCSC.FIDODataStructures class), so the user does not have to deal with the raw byte arrays, and all functions return a Result<T> object, which contains the response object (if any) and the status of the operation. The following functions directly from the FIDO U2F standard are available:

authenticatorGetInfo

After the initial set-up, you can call the AuthenticatorGetInfo method like this:

SDKCore.Result<CrescendoDLL.PCSC.FIDODataStructures.AuthenticatorInfo> result = transaction.AuthenticatorGetInfo();
Represents the response from FIDO CTAP2 authenticatorGetInfo command.
Definition FIDO.cs:2178
Represents the data structures used in FIDO (CTAP1 & CTAP2) communication, as defined in the latest F...
Definition FIDO.cs:862
The CrescendoDLL namespace contains classes and methods that allow the user to perform various operat...
Definition Cryptography.cs:15

When successful, the result.Value will contain the AuthenticatorInfo object.

authenticatorClientPin

After the initial set-up, you can call the AuthenticatorClientPIN directly. For example to get the PIN retires left, you can call the AuthenticatorClientPIN method like this:

// Define the request data object
{
PinProtocol = 2, // Select the pinUVAuthProtocol to be used.
SubCommand = (byte)AuthenticatorClientPINSubCommand.getPINRetries // Select the subcommand to be used.
// Any other optional parameters can be set here.
};
// Call the ClientPINResponse method with the request data object:
SDKCore.Result<FIDODataStructures.ClientPINResponse> clientPinResult = AuthenticatorClientPIN(clientPinRequest)
Represents parameters for the FIDO CTAP2 authenticatorClientPIN command.
Definition FIDO.cs:1204

When successful, the result.Value will contain the ClientPINResponse object.

authenticatorMakeCredential

After the initial set-up, you can call the AuthenticatorMakeCredential directly.

Note
Shared secret needs to be established first using the authenticatorClientPin method.

Assuming you have the previously established shared secret, here is an example of registering a credential for some sample data - Relaying Party (RP) webauthn.io, User and Public Key Credential Parameters (PubKeyCredParams) using the CTAP 2.1 protocol:

// Previously established shared secret
byte[] sharedSecret;
// Define the request data object
{
ClientDataHash = Convert.FromHexString("269286B9CDAF6487E00EA5F9AE93063C259BBDAD389A4C6EE365A72F9CE793E9"),
Rp = new() { Id = "webauthn.io", Name = "webauthn.io" },
User = new() { Id = System.Text.Encoding.ASCII.GetBytes("webauthnio-Tempname"), Name = "Tempname", DisplayName = "Tempname" },
PubKeyCredParams =
[
new() { Alg = -8, Type = "public-key"},
new() { Alg = -7, Type = "public-key"},
new() { Alg = -257, Type = "public-key"}
],
Extensions = new() { { "credProtect", 2 } },
Options = new() { { "rk", true } },
PinUvAuthParam = sharedSecret,
PinUvAuthProtocol = 2
};
// Call the AuthenticatorMakeCredential method with the request data object:
SDKCore.Result<CrescendoDLL.PCSC.FIDODataStructures.MakeCredentialResponse> makeCredentialResponse = transaction.AuthenticatorMakeCredential(makeCredentialRequest);
Represents parameters for the FIDO CTAP2 authenticatorMakeCredential command.
Definition FIDO.cs:1658
Represents the response from a FIDO CTAP2 authenticatorMakeCredential command.
Definition FIDO.cs:1747

When successful, the makeCredentialResponse.Value will contain the newly created credential inside the MakeCredentialResponse object.

authenticatorGetAssertion

After the initial set-up, you can call the AuthenticatorGetAssertion method directly.

Note
Shared secret needs to be established first using the authenticatorClientPin method.

Assuming you have the previously established shared secret, here is an example of asking for an assertion for Relaying Party (RP) webauthn.io and specified ClientDataHash using the CTAP 2.1 protocol:

// Previously established shared secret
byte[] sharedSecret;
// Define the get assertion request data object
{
RpId = "webauthn.io",
ClientDataHash = Convert.FromHexString("6bd0c12ffd90dfd8d38df2f8c9a450263f1cbee70b1fb629d7609d065b4b2351"),
// If you know the Public Key Credential ID (Credential ID) of the credential you want to use, you can specify it in the AllowList.
//AllowList =
//[
// new() { Id = Convert.FromHexString("65d9261086ae33dc02dacaa144871ea7da7e147448036f71eebb95e2f0ae58e009e7b81c33a7859cf36e3372e6aabe21499740141724f96ebc1def3f2bc2382739bccad8492cb067756f0ac919f175b446ae659021564d37eaade0f23a0f"), Type = "public-key"}
//],
Options = new() { { "up", false } },
PinUvAuthParam = sharedSecret,
PinUvAuthProtocol = 2
};
// Call the AuthenticatorGetAssertion method with the request data object:
SDKCore.Result<CrescendoDLL.PCSC.FIDODataStructures.GetAssertionResponse> getAssertionResponse = transaction.AuthenticatorGetAssertion(getAssertionRequest);
Represents parameters for the FIDO CTAP2 authenticatorGetAssertion command.
Definition FIDO.cs:1505
Represents the response from a FIDO CTAP2 authenticatorGetAssertion command.
Definition FIDO.cs:1578

When successful, the getAssertionResponse.Value will contain the newly created credential inside the GetAssertionResponse object.

authenticatorGetNextAssertion

After the initial set-up, you can call the AuthenticatorGetNextAssertion method directly.

Note
Shared secret needs to be established using the authenticatorClientPin method, and authenticatorGetAssertion method was called. After all, you are asking for "Next assertion", implying you have asked for assertion with given parameters previously.

This would be an example of using the AuthenticatorGetNextAssertion:

// Previously established shared secret
byte[] sharedSecret;
// Define the get assertion request data object
{
RpId = "webauthn.io",
ClientDataHash = Convert.FromHexString("6bd0c12ffd90dfd8d38df2f8c9a450263f1cbee70b1fb629d7609d065b4b2351"),
// If you know the Public Key Credential ID (Credential ID) of the credential you want to use, you can specify it in the AllowList.
//AllowList =
//[
// new() { Id = Convert.FromHexString("65d9261086ae33dc02dacaa144871ea7da7e147448036f71eebb95e2f0ae58e009e7b81c33a7859cf36e3372e6aabe21499740141724f96ebc1def3f2bc2382739bccad8492cb067756f0ac919f175b446ae659021564d37eaade0f23a0f"), Type = "public-key"}
//],
Options = new() { { "up", false } },
PinUvAuthParam = sharedSecret,
PinUvAuthProtocol = 2
};
// Call the AuthenticatorGetAssertion method with the request data object to ask for the first assertion:
SDKCore.Result<CrescendoDLL.PCSC.FIDODataStructures.GetAssertionResponse> getAssertionResponse = transaction.AuthenticatorGetAssertion(getAssertionRequest);
// Call the AuthenticatorGetNextAssertion method to get the next assetion with the same parameters you used previously:
SDKCore.Result<CrescendoDLL.PCSC.FIDODataStructures.GetAssertionResponse> getNextAssertionResponse = transaction.AuthenticatorGetNextAssertion();

When successful, the getNextAssertionResponse.Value will contain the newly created credential inside the GetAssertionResponse object.

authenticatorReset

After the initial set-up, you can call the AuthenticatorReset method directly.

Note
This command will erase all FIDO credentials and reset the FIDO PIN.

An example of AuthenticatorReset would look like this:

SDKCore.Result resetResult = transaction.AuthenticatorReset();

authenticatorCredentialManagement

Note
Shared secret needs to be established first using the authenticatorClientPin method.
Note
More detailed C# code example can be found in the Examples/FIDO-ListCredentials folder inside the released SDK package.

After the initial set-up, you can call the AuthenticatorCredentialManagement method directly. For example if we want to list a credential for a Relaying Party (RP) webauthn.io, this is what the request using the CTAP 2.1 protocol would look like:

// Previously established shared secret
byte[] sharedSecret;
// Convert the RP ID to bytes
byte[] rpBytes = System.Text.Encoding.UTF8.GetBytes("webauth.io");
// Example subCommandParams setup here, to make it easier to read:
{
RpIDHash = System.Security.Cryptography.SHA256.HashData(rpBytes), // Example RP ID hash
// If you know the Credential ID of the credential you want to use, you can specify it in the CredentialID, or you can leave it empty to list all credentials.
//CredentialID = new CrescendoDLL.PCSC.FIDODataStructures.PublicKeyCredentialDescriptor
//{
// Type = "public-key",
// Id = [0x04, 0x05, 0x06 ] // Example credential ID
//},
// If you know the User ID of the credential you want to use, you can specify it in the User, or you can leave it empty to list all credentials.
//User = new CrescendoDLL.PCSC.FIDODataStructures.PublicKeyCredentialUserEntity
//{
// Id = [0x07, 0x08, 0x09 ], // Example user ID
// Name = "TestUser", // Example user name
// DisplayName = "Test Display Name" // Example display name
//},
};
// Example CredentialManagementRequest setup:
{
SubCommand = CrescendoDLL.PCSC.AuthenticatorCredentialManagementSubCommand.enumerateCredentialsBegin, // Example subcommand (e.g., enumerateCredentialsBegin)
SubCommandParams = subCommandParams, // Attach subCommandParams
PinUvAuthParam = sharedSecret,
PinUvAuthProtocol = 2
};
// Call the AuthenticatorCredentialManagement method with the request data object:
SDKCore.Result<CrescendoDLL.PCSC.FIDODataStructures.CredentialManagementResponse> credentialManagementResponse = transaction.AuthenticatorCredentialManagement(request);
Represents parameters for FIDO CTAP2 authenticatorCredentialManagement command.
Definition FIDO.cs:1878
Represents the response from FIDO CTAP2 authenticatorCredentialManagement command.
Definition FIDO.cs:1930
Represents subcommand-specific parameters for CTAP2 authenticatorCredentialManagement command.
Definition FIDO.cs:1823

When successful, the credentialManagementResponse.Value will contain the requested details inside the CredentialManagementResponse object.

authenticatorConfig

After the initial set-up, you can call the AuthenticatorConfig method directly.

Note
Shared secret needs to be established first using the authenticatorClientPin method.
Note
Token must support CTAP 2.1 protocol to use the AuthenticatorConfig method.

For example to change the minimum PIN length to 6, this is what the request would look like:

// Previously established shared secret
byte[] sharedSecret;
// Example ConfigRequest setup:
{
SubCommand = CrescendoDLL.PCSC.AuthenticatorConfigSubCommand.setMinPinLength,
SubCommandParams = new()
{
NewMinPINLength = 6
},
};
// Call the AuthenticatorConfig method with the request data object:
SDKCore.Result configResult = transaction.AuthenticatorConfig(configRequest);
Represents parameters for FIDO CTAP2 authenticatorConfig command.
Definition FIDO.cs:2097

FIDOSetPIN

Note
Elevated privileges are required.

After the initial set-up, you can call the FIDOSetPIN method like this:

// The newPin parameter can also be left empty to generate a random 6 digit numeric-only number.
// This will however use a specific value - "123456" as the new PIN.
SDKCore.Result<string> result = transaction.FIDOSetPIN("123456");

When successful, the result.Value will contain the newly set PIN.

FIDOChangePIN

Note
Elevated privileges are required.

After the initial set-up, you can call the FIDOChangePIN method like this:

// The newPin parameter can also be left empty to generate a random 6 digit numeric-only number.
// This will however use a specific value - "123456" as the new PIN.
SDKCore.Result<string> result = transaction.FIDOChangePIN("123456");

When successful, the result.Value will contain the newly set PIN.

FIDOGetChallenge and FIDOUnblockPIN

After the initial set-up, you can call the FIDOGetChallenge method to get a challenge code for unblocking the FIDO PIN. This challenge code must be shared with the administrator, who can provide a response code (cryptogram) to unblock the FIDO PIN. You can then call the FIDOUnblockPIN method with the response code and the new PIN value to unblock the FIDO PIN. Neither of these methods require elevated privileges, but it is recommended to use them in a secure environment.

Note
The SCardTransaction must stay open between the calls to FIDOGetChallenge and FIDOUnblockPIN. MaintainTransactionAsync can be used to keep the transaction open between the calls.
Note
More detailed C# code example (including the transaction handling) can be found in the Examples/FIDO-PinUnblock folder inside the released SDK package.

This is how an example of the FIDO PIN unblocking flow would look like:

// Get the challenge code for unblocking the FIDO PIN
SDKCore.Result<string> challengeResponse = transaction.FIDOGetChallenge();
// Provide this challenge code `challengeResponse.Value` to the administrator, who can generate a response code (cryptogram) to unblock the FIDO PIN.
// After receiving the response code from the administrator, you can call the FIDOUnblockPIN method to unblock the FIDO PIN.
string newPin = "123456"; // The new PIN value to set after unblocking the FIDO PIN"
string responseCode = "0C39B515C246EC8EFE502C41FFCCB5DA"; // The response code (cryptogram) provided by the administrator. Should be 16 bytes as a hex string
SDKCore.Result unblockResult = transaction.FIDOUnblockPIN(responseCode, newPin);

When successful, the FIDO PIN will be newly set to the value newPin, and all FIDO credentials will remain intact.

FIDOMakeCredential

Note
Elevated privileges are required.
Note
More detailed C# code example (including the following authneticatorGetAssertion) can be found in the Examples/FIDO-MakeCredentialAndGetAssertion folder inside the released SDK package.

After the initial set-up, you can call the FIDOMakeCredential method directly. First fill out the MakeCredentialRequest object with the desired credentials, then use it as an input to the FIDOMakeCredential method. For example here is a request object with some sample data for Relaying Party (RP), User and Public Key Credential Parameters (PubKeyCredParams):

// Define the request data object
{
ClientDataHash = Convert.FromHexString("269286B9CDAF6487E00EA5F9AE93063C259BBDAD389A4C6EE365A72F9CE793E9"),
Rp = new() { Id = "webauthn.io", Name = "webauthn.io" },
User = new() { Id = System.Text.Encoding.ASCII.GetBytes("webauthnio-Tempname"), Name = "Tempname", DisplayName = "Tempname" },
PubKeyCredParams =
[
new() { Alg = -8, Type = "public-key"},
new() { Alg = -7, Type = "public-key"},
new() { Alg = -257, Type = "public-key"}
],
Extensions = new() { { "credProtect", 2 } },
Options = new() { { "rk", true } }
};
// Call the FIDOMakeCredential method with the request data object:
SDKCore.Result<CrescendoDLL.PCSC.FIDODataStructures.MakeCredentialResponse> makeCredentialResponse = transaction.FIDOMakeCredential(makeCredentialRequest);

When successful, the makeCredentialResponse.Value will contain the newly created credential inside the MakeCredentialResponse object.

FIDOGetAssertion

Note
Elevated privileges are required.
Note
More detailed C# code example (including the preceding authneticatorMakeCredential) can be found in the Examples/FIDO-MakeCredentialAndGetAssertion folder inside the released SDK package.

After the initial set-up, you can call the FIDOGetAssertion method directly. First fill out the GetAssertionRequest object with the desired credentials, then use it as an input to the FIDOGetAssertion method. For example here is a request object asking for an assertion for Relaying Party (RP) webauthn.io and specified ClientDataHash:

// Define the request data object
{
RpId = "webauthn.io",
ClientDataHash = Convert.FromHexString("6bd0c12ffd90dfd8d38df2f8c9a450263f1cbee70b1fb629d7609d065b4b2351"),
// If you know the Public Key Credential ID (Credential ID) of the credential you want to use, you can specify it in the AllowList.
//AllowList =
//[
// new() { Id = Convert.FromHexString("65d9261086ae33dc02dacaa144871ea7da7e147448036f71eebb95e2f0ae58e009e7b81c33a7859cf36e3372e6aabe21499740141724f96ebc1def3f2bc2382739bccad8492cb067756f0ac919f175b446ae659021564d37eaade0f23a0f"), Type = "public-key"}
//],
Options = new() { { "up", false } }
};
// Call the FIDOGetAssertion method with the request data object:
SDKCore.Result<CrescendoDLL.PCSC.FIDODataStructures.GetAssertionResponse> getAssertionResponse = transaction.FIDOGetAssertion(getAssertionRequest);

When successful, the getAssertionResponse.Value will contain the newly created credential inside the GetAssertionResponse object.

FIDOCredentialManagement

Note
Elevated privileges are required.
Note
More detailed C# code example can be found in the Examples/FIDO-ListCredentials folder inside the released SDK package.

After the initial set-up, you can call the FIDOCredentialManagement method directly. First fill out the CredentialManagementRequest object with the desired credentials, then use it as an input to the FIDOCredentialManagement method.

For example if we want to list a credential for a Relaying Party (RP) webauthn.io, this is what the request object would look like:

// Convert the RP ID to bytes
byte[] rpBytes = System.Text.Encoding.UTF8.GetBytes("webauth.io");
// Example subCommandParams setup here, to make it easier to read:
{
RpIDHash = System.Security.Cryptography.SHA256.HashData(rpBytes), // Example RP ID hash
// If you know the Credential ID of the credential you want to use, you can specify it in the CredentialID, or you can leave it empty to list all credentials.
//CredentialID = new CrescendoDLL.PCSC.FIDODataStructures.PublicKeyCredentialDescriptor
//{
// Type = "public-key",
// Id = [0x04, 0x05, 0x06 ] // Example credential ID
//},
// If you know the User ID of the credential you want to use, you can specify it in the User, or you can leave it empty to list all credentials.
//User = new CrescendoDLL.PCSC.FIDODataStructures.PublicKeyCredentialUserEntity
//{
// Id = [0x07, 0x08, 0x09 ], // Example user ID
// Name = "TestUser", // Example user name
// DisplayName = "Test Display Name" // Example display name
//}
};
// Example CredentialManagementRequest setup:
{
SubCommand = CrescendoDLL.PCSC.AuthenticatorCredentialManagementSubCommand.enumerateCredentialsBegin, // Example subcommand (e.g., enumerateCredentialsBegin)
SubCommandParams = subCommandParams // Attach subCommandParams
};
// Call the FIDOCredentialManagement method with the request data object:
SDKCore.Result<CrescendoDLL.PCSC.FIDODataStructures.CredentialManagementResponse> credentialManagementResponse = transaction.FIDOCredentialManagement(request);

When successful, the credentialManagementResponse.Value will contain the requested details inside the CredentialManagementResponse object.

FIDOConfig

Note
Token must support CTAP 2.1 protocol to use the FIDOConfig method.
Note
Elevated privileges are required.
Note
More detailed C# code example (including the mandatory PIN change) can be found in the Examples/FIDO-ConfigurationAndPinChange folder inside the released SDK package.

After the initial set-up, you can call the FIDOConfig method directly. For example to change the minimum PIN length to 6, this is what it would look like:

// Example ConfigRequest setup:
{
SubCommand = CrescendoDLL.PCSC.AuthenticatorConfigSubCommand.setMinPinLength,
SubCommandParams = new()
{
NewMinPINLength = 6
},
};
// Call the AuthenticatorConfig method with the request data object:
SDKCore.Result configResult = transaction.FIDOConfig(configRequest);

U2FRegistration

Note
Elevated privileges are required.
Note
More detailed C# code example (including the following U2F Authentication) can be found in the Examples/FIDO-U2FRegistrationAndAuthentication folder inside the released SDK package.

After the initial set-up, you can call the U2FRegistration method directly. First fill out the U2FRegistrationRequest object with the desired credentials, then use it as an input to the U2FRegistration method.

Here is an example of registering a credential for some sample data - Relaying Party (RP) webauthn.io, and some 32-byte challenge using the FIDO U2F protocol:

// Example U2FRegistrationRequest setup:
{
ChallengeParameter = Convert.FromHexString("269286B9CDAF6487E00EA5F9AE93063C259BBDAD389A4C6EE365A72F9CE793E9"),
ApplicationParameter = System.Security.Cryptography.SHA256.HashData(System.Text.Encoding.UTF8.GetBytes("webauthn.io"))
};
// Call the U2FRegistration method with the request data object:
SDKCore.Result<CrescendoDLL.PCSC.FIDODataStructures.U2FRegistrationResponse> u2FRegistrationResponse = transaction.U2FRegistration(u2fRegistrationRequest);
Represents a U2F registration request per FIDO U2F (CTAP 1) specification.
Definition FIDO.cs:867
Represents a U2F registration response per FIDO U2F (CTAP 1) specification.
Definition FIDO.cs:889

When successful, the u2FRegistrationResponse.Value will contain the requested details inside the U2FRegistrationResponse object.

U2FAuthentication

Note
Elevated privileges are required.
Note
More detailed C# code example (including the preceding U2F Registration) can be found in the Examples/FIDO-U2FRegistrationAndAuthentication folder inside the released SDK package.

After the initial set-up, you can call the U2FAuthentication method directly. First fill out the U2FAuthenticationRequest object with the desired credentials and previously learned information from U2FRegistration, then use it as an input to the U2FAuthentication method.

Here is an example of authenticating with a credential for some sample data - Relaying Party (RP) webauthn.io, some 32-byte challenge and previously gained KayHandle using the FIDO U2F protocol:

// Previous registration response - needed for the KeyHandle
SDKCore.Result<CrescendoDLL.PCSC.FIDODataStructures.U2FRegistrationResponse> u2FRegistrationResponse = transaction.U2FRegistration(u2fRegistrationRequest);
// Example U2FRegistrationRequest setup:
{
ChallengeParameter = Convert.FromHexString("269286B9CDAF6487E00EA5F9AE93063C259BBDAD389A4C6EE365A72F9CE793E9"),
ApplicationParameter = System.Security.Cryptography.SHA256.HashData(System.Text.Encoding.UTF8.GetBytes("webauthn.io")),
KeyHandleLength = u2FRegistrationResponse.Value.KeyHandleLength,
KeyHandle = u2FRegistrationResponse.Value.KeyHandle,
UserPresence = CrescendoDLL.PCSC.U2FAuthenticationOptions.EnforceUserPresenceAndSign
};
SDKCore.Result<CrescendoDLL.PCSC.FIDODataStructures.U2FAuthenticationResponse> u2FAuthenticationResponse = transaction.U2FAuthentication(u2fAuthenticationRequest);
Represents a U2F authentication request per FIDO U2F (CTAP 1) specification.
Definition FIDO.cs:984
byte KeyHandleLength
Length of key handle in bytes.
Definition FIDO.cs:998
Represents a U2F authentication response per FIDO U2F (CTAP 1) specification.
Definition FIDO.cs:1016

When successful, the u2FAuthenticationResponse.Value will contain the requested details inside the U2FAuthenticationResponse object.

U2FGetVersion

Note
Elevated privileges are required.

After the initial set-up, you can call the U2FGetVersion method directly.

SDKCore.Result<string> getVersionString = methods.U2FGetVersion();

When successful, the getVersionString.Value will contain the version string (e.g., "U2F_V2").