Skip to main content

Object Handle Mapping

A key aspect of the DuoKey PKCS#11 library is the Object Handle Mapping system, which bridges PKCS#11's integer object handles and DuoKey Cockpit's durable key identifiers.

Overview​

Object handle mapping
PKCS#11 (Oracle side)
Integer handlee.g. 0x12345
lookup / return
Mapping system
Per-session mapping tablehandle to key identifier
translate / reverse lookup
DuoKey Cockpit
Key identifierdurable string (UUID)

The mapping system bridges PKCS#11 integer handles and DuoKey's durable key identifiers, in both directions.

The Problem​

PKCS#11 references objects with integer handles (the platform's unsigned long — 64 bits wide on the Linux x86-64 hosts Oracle runs on), while DuoKey Cockpit references keys with durable identifiers (UUID-format strings). The mapping system translates between the two.

PKCS#11 handles​

  • Type: CK_OBJECT_HANDLE (an unsigned integer, sized to the platform's native unsigned long — 64 bits on the Linux x86-64 targets Oracle runs on)
  • Scope: per-session (handles are session-specific)
  • Lifetime: valid only while the session is open

DuoKey key identifiers​

  • Type: string (UUID format, e.g. xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
  • Scope: durable and unique across the platform
  • Lifetime: persistent (identifiers do not change)

How It Works​

Mapping process​

This flow is kept as a sequence diagram because of the "handle exists / new handle" branch (alt) in the middle, which a linear diagram cannot represent faithfully.

Handle generation​

Handles are generated per session:

Handle generation
New object found
Handle exists?
YesReturn existing handle
NoGenerate next handle
increment counter
Store mapping
return handle
Return handle

Handles are generated per session; an existing identifier reuses its handle.

Algorithm:

  1. Assign the first handle to the first object.
  2. Increment for each new object.
  3. Store the mapping in the session's handle table.

Mapping table​

Each session maintains its own mapping table with two views:

  • Forward: handle → key identifier
  • Reverse: key identifier → handle (for fast reverse lookup)

Operations: insert a new mapping, look up an identifier for a handle, reverse-look-up a handle for an identifier, and delete a mapping when an object is destroyed.

Object Types​

Secret keys​

AES keys used for the wrap / unwrap operations.

Handle: 0x12345
Type: CKO_SECRET_KEY
Algorithm: AES-256

Handle Lifecycle​

Creation​

Handles are created when objects are found (C_FindObjects) or when a key is generated (C_GenerateKey). C_CreateObject is not implemented by the library — it returns CKR_FUNCTION_NOT_SUPPORTED — so handles are never created that way.

Handle creation
Object found / created
generate handle
Generate handle
store in table
Store mapping
Handle active

Usage​

Operations that take a handle: C_Encrypt / C_Decrypt (wrap / unwrap), C_GetAttributeValue, and C_DestroyObject.

Cleanup​

Handle cleanup
Handle active
Session closed
Clear all mappings
C_DestroyObject()
Remove from table

Handles are cleared when the session closes; an individual mapping is removed when its object is destroyed.

Handles are invalidated when the session closes; an individual mapping is removed when its object is destroyed.

Example Scenarios​

Scenario 1: finding an existing master key​

  1. Oracle calls C_FindObjects with a template such as { CKA_LABEL: "TDE-MASTER-20251219" }.
  2. The library asks Cockpit to locate the key by that label.
  3. Cockpit returns the key identifier.
  4. The library checks its mapping table; the identifier is new, so it assigns a handle (e.g. 0x12345) and stores the mapping.
  5. It returns handle 0x12345 to Oracle.

Scenario 2: wrapping a tablespace key​

  1. Oracle calls C_Encrypt(session, 0x12345, tablespaceKey).
  2. The library looks up the key identifier for handle 0x12345.
  3. The library asks Cockpit to wrap the tablespace key under that master key (length-preserving AES-CBC-PAD).
  4. Cockpit returns the wrapped key.
  5. The library returns the wrapped key to Oracle.

Scenario 3: generating a new master key​

  1. Oracle calls C_GenerateKey(session, mechanism, template) for an AES-256 key.
  2. The library asks Cockpit to provision the key.
  3. Cockpit returns the new key identifier.
  4. The library assigns a handle (e.g. 0x12346) and stores the mapping.
  5. It returns handle 0x12346 to Oracle.

Performance Considerations​

  • Lookup: O(1) average case (hash-map lookup).
  • Handle reuse: if the same identifier is requested again, the existing handle is returned to avoid duplicate mappings.
  • Reverse lookup: an identifier → handle map supports fast reverse lookups.
  • Memory: mappings are cleared when the session closes.

Error Handling​

ScenarioResponse
Oracle supplies a handle not in the mapping tableCKR_OBJECT_HANDLE_INVALID
A key identifier returned earlier no longer exists (object deleted between operations)CKR_DEVICE_ERROR

Best Practices​

  • Don't cache handles across sessions — they are session-specific.
  • Validate handles before use.
  • Clean up mappings on session close.
  • Delete properly with C_DestroyObject so mappings are removed.

Next Steps​