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​

Architecture

Object handle mapping

Object handle mappingA per-session mapping table translates Oracle's integer object handles to DuoKey's durable key identifiers and back.PKCS#11 · ORACLE SIDEMAPPING SYSTEMDUOKEY COCKPITLOOKUPRETURNTRANSLATEREVERSE LOOKUPORACLEInteger handlee.g. 0x12345LIBRARYMapping tableper sessionCOCKPITKey identifierdurable UUID stringLEGENDPer-session mapping tableForward: handle to identifierReverse

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​

Sequence

Mapping a key identifier to a handle

Mapping a key identifier to a handleCockpit locates the key by label and returns its identifier; the mapping table returns the existing handle or assigns and stores a new one, which goes back to Oracle.ALTC_FindObjectsSEARCH BY LABELLOCATE KEYKEY IDENTIFIERKEY IDENTIFIERCREATE HANDLEEXISTING HANDLEASSIGN + STOREHANDLE 0x12345HANDLE 0x12345[handle exists][new handle]ORACLEOracle TDEC_* callsLIBRARYPKCS#11 layerlibdke_pkcs11.soLIBRARYHandle mappingper-session tableLIBRARYDuoKey SDKHTTPS clientCOCKPITDuoKey Cockpitkey identifiersLEGENDCallHTTPS requestReturnLocal stepHandle to Oracle

Cockpit returns the key identifier; the mapping table returns the existing handle or assigns and stores a new one.

Sequence

Using the handle

Using the handle in a wrapOn a later C_Encrypt the PKCS#11 layer looks up the key identifier for the handle, and the wrap under that master key runs in Cockpit.C_Encrypt 0x12345LOOK UP 0x12345KEY IDENTIFIERWRAP UNDER MEKWRAPWRAPPED KEYWRAPPED KEYWRAPPED RESULTORACLEOracle TDEC_* callsLIBRARYPKCS#11 layerlibdke_pkcs11.soLIBRARYHandle mappingper-session tableLIBRARYDuoKey SDKHTTPS clientCOCKPITDuoKey Cockpitkey identifiersLEGENDCallHTTPS requestReturnResult to Oracle

Later operations pass the handle; the PKCS#11 layer looks up its key identifier before the wrap runs in Cockpit.

Handle generation​

Handles are generated per session:

Flowchart

Handle generation

Handle generationAn object that already has a handle reuses it; otherwise the session assigns the next handle, stores the mapping and returns it.YESNONew object foundHandleexists?Return existing handleGenerate next handleincrement counterStore mappingsession handle tableReturn handleLEGENDStep, decision, outcomeNew handle issuedFlow

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.

Flowchart

Handle creation

Handle creationWhen an object is found or a key is generated, the library generates a handle, stores the mapping and the handle becomes active.Object foundC_FindObjects · C_GenerateKeyGenerate handlenext in sessionStore mappinghandle tableHandle activeLEGENDStep, startHandle ready for useFlow

A handle is generated and its mapping stored when an object is found or a key is generated.

Usage​

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

Cleanup​

State machine

Handle cleanup

Handle cleanupAn active handle ends when its session closes, which clears every mapping, or when C_DestroyObject removes that one mapping.SESSION CLOSED / CLEAR ALL MAPPINGSC_DestroyObject / REMOVE MAPPINGHandle activein the session tableLEGENDEvent / actionLive handle

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​