Loading…

Kryptel/Java

KeyBlock class

Declaration

package com.kryptel.key;

public class KeyBlock {

    // Key IDs
    
    public final static byte KEY_LEVEL_0        = (byte)0;
    public final static byte KEY_LEVEL_3        = (byte)(3 << 5);
    public final static byte KEY_LEVEL_5        = (byte)(5 << 5);

    public final static byte KEY_PASSWORD       = (byte)(0x01 | KEY_LEVEL_0);
    public final static byte KEY_BINARY_KEY     = (byte)(0x05 | KEY_LEVEL_0);
    public final static byte KEY_COMPOSITE      = (byte)(0x0F | KEY_LEVEL_3);
    public final static byte KEY_GROUP          = (byte)(0x1C | KEY_LEVEL_5);

    // Allowed / expected key material

    public final static byte KEY_MATERIAL_PASSWORD      = (byte)0x01;
    public final static byte KEY_MATERIAL_BINARY_KEY    = (byte)0x02;
    public final static byte KEY_MATERIAL_YUBIKEY       = (byte)0x04;
    public final static byte KEY_MATERIAL_COMPOSITE     = (byte)0x10;
    public final static byte KEY_MATERIAL_GROUP         = (byte)0x20;
    public final static byte KEY_MATERIAL_EVERYTHING    = (byte)0x7F;

    // Matching result
    
    public final static byte KEY_MATERIAL_MATCHED       = (byte)0x00;
    public final static byte KEY_MATERIAL_FAILED        = (byte)0x80;


    //
    //Password/key flags 
    //

    public final static byte PASSWORD_CAN_CREATE        = (byte)0x01;
    public final static byte PASSWORD_CAN_MODIFY        = (byte)0x02;
    public final static byte PASSWORD_CAN_DECRYPT       = (byte)0x04;
    public final static byte PASSWORD_MASTER_KEY        = (byte)0x80;

    public final static byte PASSWORD_DEFAULT_FLAGS     =
            (byte)(PASSWORD_CAN_CREATE | PASSWORD_CAN_MODIFY | PASSWORD_CAN_DECRYPT);


    public final static class ComponentDescriptor {
        public UUID hashFunction;
        public int hashSize;
        public int hashPasses;
        public byte hashScheme;

        public UUID cipher;
        public int cipherKeySize;
        public int cipherBlockSize;
        public int cipherRounds;
        public byte cipherScheme;
    }


    //**********************************************************************
    //*** Key classes

    public class Password {
        public Password(String password, byte flags) throws Exception;
    }

    public class BinaryKey {
        public BinaryKey(byte[] binaryKey, byte flags) throws Exception;
    }

    public class CompositeKey {
        public CompositeKey(byte flags);
    }

    public class GroupKey {
        public GroupKey() throws Exception;

        public void AddSubkey(Key subkey) throws Exception;
        public void AddKeysFrom(GroupKey fromGroup) throws Exception;
    }


    //**********************************************************************
    //*** CKeyBlock

    public KeyBlock(ComponentDescriptor descr) throws Exception;
    public KeyBlock(ComponentDescriptor descr, byte[] salt) throws Exception;
    
    public byte Expected() throws Exception;
    public boolean IsMatched() throws Exception;
    public byte KeyMaterial() throws Exception;

    public byte GetFlags() throws Exception;

    public byte MatchPassword(String password) throws Exception;
    public byte MatchBinaryKey(byte[] binaryKey) throws Exception;

    public void AddKey(Key subkey) throws Exception;

    public void LoadKeyBlock(byte[] keyBlockRecord) throws Exception;

    public byte[] GetBaseKey() throws Exception;

    public byte[] GetKeyBlock() throws Exception;

    public void CleanUp() throws Exception;
}

Description

This class incapsulates the functionality for key matching and key block handling. See Unified Key Block for a description of key block format. The article Key Callback Example is an example of converting and matching user-supplied key material.

The internal key classes are used for building a new key block from user-supplied key material. See the article Passwords and Keys for a discussion of supported key material.

Kryptel/Java does not support Yubikeys as the manufacturer does not provide any Java interface library for Yubikey.

There are two ways to obtain a key block – either create an empty block and add a key (or keys), or load it from a byte array. Depending on whether the key block was created or loaded, different operation are allowed. For example, the matching functions are used on loaded blocks only.

Constructor

public KeyBlock(ComponentDescriptor descr) throws Exception;
public KeyBlock(ComponentDescriptor descr, byte[] salt) throws Exception;

The first form of the constructor calls the second form with null salt argument to generate a random salt.

Expected

public byte Expected() throws Exception;

Returns a set of KEY_MATERIAL_* flags indicating what types of key material remain unmatched. Matching all of them may be not necessary; for example if the key block has a group key consisting of a password and a binary key, this function will return KEY_MATERIAL_PASSWORD | KEY_MATERIAL_BINARY_KEY, however it will be enough to provide any of them.

This function is valid for a loaded key block only.

IsMatched

public boolean IsMatched() throws Exception;

Returns true if the loaded key block can produce the base key.

KeyMaterial

public byte KeyMaterial() throws Exception;

Returns a set of KEY_MATERIAL_* flags showing the types of the keys that the key block contains.

GetFlags

public byte GetFlags() throws Exception;

Returns a set of PASSWORD_* flags that represent the rights of the matched key.

Key rights mask just shows what rights the key issuer assigned to that specific key. Enforcing those rights is the responsibility of the key callback. If the key rights are not sufficient for the requested operation, the callback may throw an exception, or pass the responsibility to the caller, or even completely ignore the key rights by assigning a new mask.

Matching functions

public byte MatchPassword(String password) throws Exception;
public byte MatchBinaryKey(byte[] binaryKey) throws Exception;

These functions match the user-provided key material against the loaded key block.

Return

The functions return KEY_MATERIAL_* mask.

KEY_MATERIAL_MATCHED
The matched key material is sufficient to produce the base key. This is not a bit mask; the result must be directly compared with KEY_MATERIAL_MATCHED, which equals to zero (i.e. has no mask bit set).
KEY_MATERIAL_FAILED
If this bit is set, the provided key material did not match any key in the key block. Typically the callback should show a warning message and request another key. The result also contains a combination of other KEY_MATERIAL_* bits for expected key material.
Any other combination of KEY_MATERIAL_* bits
A subkey of a composite key has been matched successfully, but more key material is needed to produce the base key.

This function is valid for a loaded key block only.

AddKey

public void AddKey(Key subkey) throws Exception;

Add a new key to the key block. If the key block already has an attached key, it will be converted to a group key. This function is valid for a created key block only.

LoadKeyBlock

public void LoadKeyBlock(byte[] keyBlockRecord) throws Exception;

Load the key block from a byte array containing a unified key block.

GetBaseKey

public byte[] GetBaseKey() throws Exception;

Produces the base key that may be used to produce derived key material, in particular, the actual encryption key. The key block must be either created or fully matched.

GetKeyBlock

public byte[] GetKeyBlock() throws Exception;

Converts the created key block to a byte array containing a unified key block.

CleanUp

public void CleanUp() throws Exception;

Cleans up all sensitive data contained in the keyblock and destroys the attached key(s).