IKeyCallback interface
Contents
- Introduction to the Library
- Basic support package (com.kryptel.bslx)
- Kryptel API Commons package (com.kryptel)
- Cipher package (com.kryptel.cipher)
- Compressor package (com.kryptel.compressor)
- Exceptions package (com.kryptel.exceptions)
- Hash function package (com.kryptel.hash_function)
- MAC function package (com.kryptel.mac)
- Key-related functions (com.kryptel.key)
- KeyRecord structure
- IKeyCallback interface
- BinaryKeyFile class
- KeyBlock class
- Example: Writing a key callback
- Silver Key engine (com.kryptel.silver_key)
- Kryptel encrypted storage (com.kryptel.storage)
Declaration
package com.kryptel.key; public interface IKeyCallback { // // Legacy (pre- Kryptel 8 / Silver Key 5) methods // // Allowed key material static final int USER_DEFINED_KEY = 0x00000001; // User-defined raw binary key static final int FILE_BASED_KEY = 0x00000002; static final int BINARY_KEY = 0x00000010; // Key file static final int PROTECTED_KEY = 0x00000020; // Key file + password static final int PUBLIC_KEY = 0x00001000; static final int PASSWORD = 0x00040000; static final int LOWERCASE_PASSWORD = 0x00080000; static final int YUBIKEY = 0x02000000; static final int YUBIKEY_PASSWORD = 0x04000000; static final int PASSWORDS = PASSWORD | LOWERCASE_PASSWORD; static final int KEY_FILES = BINARY_KEY | PROTECTED_KEY; static final int YUBIKEYS = YUBIKEY | YUBIKEY_PASSWORD; static final int ANY_KEY_MATERIAL = USER_DEFINED_KEY | FILE_BASED_KEY | KEY_FILES | PUBLIC_KEY | PASSWORDS | YUBIKEYS; KeyRecord Callback(Object arg, String prompt, int allowed, UUID expected) throws Exception; // // New Kryptel 8+ / Silver Key 5+ methods // final class KeyData { public byte flags; public byte[] baseKey; public byte[] keyRecord; } KeyData EncryptionKeyCallback(Object arg, String prompt, KeyBlock.ComponentDescriptor desc) throws Exception; KeyData DecryptionKeyCallback(Object arg, String prompt, byte[] keyRecord, KeyBlock.ComponentDescriptor desc) throws Exception; }
Description
This interface defines key callback functions; high-level Kryptel components such as storage handlers obtain key material by calling this client-provided callback.
Note that there are two groups of completely different methods: the legacy function Callback, and the pair of new functions EncryptionKeyCallback and DecryptionKeyCallback.
The legacy callback should be defined only if compatibility with Kryptel 7 or Silver Key 4 is required. If support for old file formats is not needed, the Callback methods may contain a dummy implementation or throw an exception Not implemented.
New Callbacks
Kryptel 8 and Silver Key 5 introduced a new Unified Key Block that was compatible with Secure Password Manager. Unfortunately, the new-style key handling was completely incompatible with the old callback function.
Normally an end-user application needs to implement only the new-style callback. The old-style callback function may simply throw a Not implemented exception. However if the application must be able to work with legacy files then you will need to implement both new- and old-style callbacks.
EncryptionKeyCallback
KeyData EncryptionKeyCallback(Object arg, String prompt, KeyBlock.ComponentDescriptor desc) throws Exception;
This callback is called when the component creates a new file.
Parameters
- arg
- This argument is supplied by the client during component initialization; the component just passes it to the callback. It usually represents the execution context, or null is the operation is context-independent.
- prompt
- A string to be shown in a password dialog, usually the name of the file to be encrypted or decrypted.
- desc
- A descriptor containing information about the cipher and the hash function that are to be used for actual key production.
Return
On return the function fills the KeyData structure.
- flags
- Key flags PASSWORD_* of the provided key as defined in KeyBlock class.
- baseKey
- Base key that will be used to produce the actual encryption key and other key-related material, specifically the HMAC key and the initialization vector.
- keyRecord
- Unified key block, which will be stored in the output file as is.
DecryptionKeyCallback
KeyData DecryptionKeyCallback(Object arg, String prompt, byte[] keyRecord, KeyBlock.ComponentDescriptor desc) throws Exception;
This callback is called when the component opens an existing file for reading (i.e. decrypting) or for modification.
Parameters
- arg
- This argument is supplied by the client during component initialization; the component just passes it to the callback. It usually represents the execution context, or null is the operation is context-independent.
- prompt
- A string to be shown in a password dialog, usually the name of the file to be encrypted or decrypted.
- keyRecord
- The unified key block read from the input encrypted file.
- desc
- Component descriptor containing information about the cipher and the hash function that are to be used for actual key production.
Return
On return the function returns a filled KeyData structure.
- flags
- Key flags PASSWORD_* of the provided key as defined in KeyBlock class.
- baseKey
- Base key that will be used to produce the actual decryption key and other key-related material, specifically the HMAC key and the initialization vector.
- keyRecord
- Contains a pointer to the input keyRecord (or to its copy).
Legacy Callback
This callback is called by the legacy components only.
Callback
KeyRecord Callback(Object arg, String prompt, int allowed, UUID expected) throws Exception;
A component calls this function to get key material in KeyRecord structure. The component's client program may obtain the key material in many possible ways – ask the user, get as a command-line parameter, read from a passwords manager database, and so on.
Parameters
- arg
- This argument is supplied by the client during component initialization; the component just passes it to the callback. It usually represents the execution context, or null is the operation is context-independent.
- prompt
- A string to be shown in a password dialog, usually the name of the file to be encrypted or decrypted.
- allowed
- A mask of allowed key material. If several types of key material are allowed, the corresponding bits are combined with bitwise OR.
- expected
- Key file ID of the key file that we are expecting.
Return
On return KeyRecord.keyMaterial must contain the ID of the key material. Depending on this field the remaining fields must be set as follows:
- IDENT_PASSWORD and IDENT_LOWERCASE_PASSWORD
- KeyRecord.password contains the password.
- ID of a key file
- KeyRecord.keyData contains the binary key and KeyRecord.keyPath is the path to the key file.
- IDENT_PROTECTED_KEY
- KeyRecord.password contains the password, KeyRecord.keyPath is the path to the key file, KeyRecord.keyAssociatedMaterial contains the ID of the key file, and KeyRecord.keyAssociatedData contains the binary key.
If this function returns null, the calling component will throw UserAbortException. Typically, the callback function should return null if the user requested abort, for instance, by pressing Cancel button in the password dialog.
Notes on allowed and expected
On encryption, the allowed argument indicates what types of key material the calling component supports (or allowed by the current capabilities set). The expected argument is always IDENT_NULL.
On decryption, both of these arguments are significant. The allowed argument typically corresponds to the expected argument, which is the ID of the required key material. More precisely, allowed is the result of ExpectedKeyMaterial function:
allowed = ApiHelpers.ExpectedKeyMaterial(expected);
In case of composite keys the dependency is more complex. Specifically, for a protected key allowed value is PROTECTED_KEY, and expected contains the ID of the key file.
Password matching
Kryptel storage offers a useful feature called password matching, i.e. trying the password without leaving the key callback. This way entering a wrong password does not abort the file open sequence.
For instance, when user opens a file in Kryptel Browser, the password is saved in the password cache. On the subsequent open operations the browser tries the passwords in the cache first, and if the matching password is found, the browser does not show the password dialog.
See IEncryptedStorageInfo.TestPassword for a detailed discussion.