Skip to main content

Communication Flow

Understanding the communication flow helps troubleshoot issues and optimize performance. This page gives a high-level view of how operations flow through the system from Oracle Database to DuoKey Cockpit and back.

Overview​

Architecture

Communication overview

Oracle TDE communication overviewOracle TDE calls the PKCS#11 interface, the DuoKey SDK carries the call over HTTPS to the Cockpit API, and Cockpit key management runs it on the backend HSM.ORACLE DATABASEPKCS#11 LIBRARYDUOKEY COCKPITPKCS#11INTERNAL APIHTTPS · TLSOracle TDEC_* callsPKCS#11 interfaceCryptoki surfaceDuoKey SDKHTTPS clientCockpit APIv2 proxy endpointKey managementmaster keysBackend HSMSecurosysLEGENDCockpit entry pointOracleKey custodyHTTPS requestCall

Oracle's calls pass through the PKCS#11 library to the Cockpit API and on to the backend HSM; responses return along the same path.

Typical Operation Flow​

Initialization Flow​

Sequence

Initialization flow

Initializing the PKCS#11 providerOracle calls C_Initialize; the library reads pkcs11.toml, the SDK sends its first request with the access_token bearer credential, Cockpit validates it and resolves the tenant, and the library returns CKR_OK.C_InitializeREAD PKCS11.TOMLCONNECTBEARER TOKENVALIDATE · RESOLVE TENANTVAULT INFOKEEP ALIVEINITIALIZEDCKR_OKORACLEOracle TDEC_* callsLIBRARYPKCS#11 layerlibdke_pkcs11.soLIBRARYDuoKey SDKHTTPS clientCOCKPITDuoKey Cockpitv2 proxy endpointLEGENDCallHTTPS requestReturnLocal stepReady

The library reads pkcs11.toml and presents its access_token on the first request; Cockpit validates it and resolves the tenant, with no separate token exchange.

Steps:

  1. Oracle calls C_Initialize(): Library initialization begins
  2. Read Configuration: Library reads server_url (containing the non-secret access_guid routing id) and access_token from pkcs11.toml
  3. Authentication: The library presents its access_token bearer credential to the Cockpit on its first request
  4. Server-side Validation: The Cockpit validates the access_token and resolves the tenant from (app_id, access_guid); no separate token exchange is performed
  5. Vault Verification: Verify access to specified vault
  6. Return Success: Library ready for operations

Session Creation Flow​

Sequence

Session creation flow

Opening a sessionOracle calls C_OpenSession; the PKCS#11 layer validates the slot, creates the session and its handle mapping table locally, and returns a session handle without calling Cockpit.C_OpenSessionVALIDATE SLOTCREATE SESSION OBJECTINIT HANDLE MAPPING TABLESESSION HANDLEORACLEOracle TDEC_* callsLIBRARYPKCS#11 layerlibdke_pkcs11.soLEGENDCallLocal step, no API callHandle returned

No API call is needed for session creation; sessions are managed locally.

Steps:

  1. Oracle calls C_OpenSession(): Request new session
  2. Validate Slot: Ensure slot ID is valid
  3. Create Session: Create internal session object
  4. Initialize Tables: Create handle mapping table for session
  5. Return Handle: Return session handle to Oracle

Note: Session creation doesn't require API calls. Sessions are managed locally.

Login Flow​

Sequence

Login flow

Logging in to a sessionOracle calls C_Login; the PKCS#11 layer confirms an access_token is configured, marks the session logged in and returns CKR_OK without another call to Cockpit.C_LoginACCESS_TOKEN CONFIGURED?MARK SESSION LOGGED INCKR_OKORACLEOracle TDEC_* callsLIBRARYPKCS#11 layerlibdke_pkcs11.soLEGENDCallLocal step, no API callSuccess

The bearer token was already presented in C_Initialize(); C_Login performs no additional API call.

Steps:

  1. Oracle calls C_Login(): Request session login
  2. Check Token: Verify the access_token bearer credential is configured in pkcs11.toml
  3. Mark Session: Mark session as authenticated
  4. Return Success: Return CKR_OK

Note: For DuoKey PKCS#11, authentication happens during C_Initialize(), when the library presents its access_token bearer credential to the Cockpit. The C_Login() function confirms the token is available but doesn't perform additional API calls.

Key Generation Flow​

Sequence

Key generation flow

Generating a master keyOracle calls C_GenerateKey; the request travels through the SDK to Cockpit, the backend HSM generates the key, and the returned UUID is mapped to a handle for Oracle.C_GenerateKeyPARSE TEMPLATEGENERATE KEYGENERATE KEYGENERATEUUID + METADATAKEY CREATEDUUIDMAP UUID TO HANDLEKEY HANDLEORACLEOracle TDEC_* callsLIBRARYPKCS#11 layerhandles · templatesLIBRARYDuoKey SDKHTTPS clientCOCKPITDuoKey Cockpitv2 proxy endpointKEYSTOREBackend HSMkey materialLEGENDCallHTTPS requestReturnLocal stepHandle to Oracle

Cockpit has the backend HSM generate the key and returns its UUID, which the PKCS#11 layer maps to a handle for Oracle.

Steps:

  1. Oracle calls C_GenerateKey(): Request key generation
  2. Parse Template: Extract key attributes (type, size, label)
  3. Build API Request: Create key generation request
  4. API Call: Send the key-generation request to the Cockpit
  5. HSM Generation: Backend HSM generates key
  6. Receive UUID: Cockpit returns key UUID
  7. Create Handle: Map UUID to PKCS#11 handle
  8. Return Handle: Return handle to Oracle

Encryption Flow​

Sequence

Encryption flow

Wrapping a tablespace keyOracle asks the library to wrap a tablespace key under the master key; Cockpit has the backend HSM perform a length-preserving AES-CBC(-PAD) wrap and the wrapped key returns.C_Encrypt / C_WrapKeyLOOK UP UUID · IVWRAP REQUESTWRAP · CBC-PADAES-CBC WRAPWRAPPED KEYWRAPPED KEYWRAPPED KEYWRAPPED RESULTORACLEOracle TDEmaster-key pathLIBRARYPKCS#11 layerhandles · mechanismsLIBRARYDuoKey SDKHTTPS clientCOCKPITDuoKey Cockpitv2 proxy endpointKEYSTOREBackend HSMmaster keyLEGENDCallHTTPS requestReturnLocal stepWrapped key to Oracle

Only the master-key path reaches the Cockpit. Bulk table/tablespace AES crypto stays local (AES-NI).

Steps:

  1. Oracle calls C_Encrypt() / C_WrapKey(): Request a wrap on the master-key path (e.g. protecting a tablespace key)
  2. Handle Lookup: Find UUID for provided master key handle
  3. Parse Mechanism: Extract algorithm (AES-CBC / AES-CBC-PAD) and IV
  4. Build Request: Create wrap request
  5. API Call: Send the wrap request to the Cockpit
  6. HSM Wrap: Backend HSM performs the length-preserving AES-CBC(-PAD) wrap
  7. Receive Wrapped Key: Get wrapped data
  8. Return Result: Return to Oracle

Note: The wrap uses a length-preserving AES-CBC / AES-CBC-PAD mechanism. An expanding AES-GCM envelope must not be used on this path — it breaks Oracle's SET KEY with ORA-00600 [kcbtse_populate_tbskey_1]. Bulk table and tablespace encryption is performed locally by Oracle using AES-NI and never leaves the database.

Decryption Flow​

Sequence

Decryption flow

Unwrapping a tablespace keyOracle asks the library to unwrap a tablespace key under the master key; Cockpit has the backend HSM perform a length-preserving AES-CBC(-PAD) unwrap and the key returns.C_Decrypt / C_UnwrapKeyLOOK UP UUID · IVUNWRAP REQUESTUNWRAP · CBC-PADAES-CBC UNWRAPTABLESPACE KEYTABLESPACE KEYTABLESPACE KEYUNWRAPPED KEYORACLEOracle TDEmaster-key pathLIBRARYPKCS#11 layerhandles · mechanismsLIBRARYDuoKey SDKHTTPS clientCOCKPITDuoKey Cockpitv2 proxy endpointKEYSTOREBackend HSMmaster keyLEGENDCallHTTPS requestReturnLocal stepKey to Oracle

Only the master-key path reaches the Cockpit. Bulk table/tablespace AES crypto stays local (AES-NI).

Steps:

  1. Oracle calls C_Decrypt() / C_UnwrapKey(): Request an unwrap on the master-key path (e.g. recovering a tablespace key at keystore open / SET KEY)
  2. Handle Lookup: Find UUID for provided master key handle
  3. Parse Mechanism: Extract algorithm (AES-CBC / AES-CBC-PAD) and IV
  4. Build Request: Create unwrap request
  5. API Call: Send the unwrap request to the Cockpit
  6. HSM Unwrap: Backend HSM performs the length-preserving AES-CBC(-PAD) unwrap
  7. Receive Tablespace Key: Get the unwrapped key
  8. Return Result: Return to Oracle

Object Search Flow​

Sequence

Object search flow

Searching for the master keyOracle starts a search, the library asks Cockpit for objects matching the label and class, maps the returned UUIDs to handles and clears its search state at the end.C_FindObjectsInitSTORE SEARCH STATEC_FindObjectsSEARCH OBJECTSLABEL · CLASSMATCHING UUIDSUUIDSCREATE HANDLESHANDLE ARRAYC_FindObjectsFinalCLEAR SEARCH STATECKR_OKORACLEOracle TDEC_* callsLIBRARYPKCS#11 layersearch state · handlesLIBRARYDuoKey SDKHTTPS clientCOCKPITDuoKey Cockpitv2 proxy endpointLEGENDCallHTTPS requestReturnLocal stepHandles to Oracle

The search runs in Cockpit; the PKCS#11 layer maps the returned UUIDs to handles and keeps the search state locally.

Steps:

  1. C_FindObjectsInit(): Initialize search with template
  2. Parse Template: Extract search criteria (label, class, etc.)
  3. C_FindObjects(): Execute search
  4. API Call: Send the object-search request to the Cockpit
  5. Receive UUIDs: Get matching object UUIDs
  6. Create Handles: Map UUIDs to handles
  7. Return Handles: Return handle array to Oracle
  8. C_FindObjectsFinal(): Clean up search state

Error Handling Flow​

Network Error Handling​

Sequence

Network error handling

Network error handlingA timed-out request is retried with exponential backoff; a successful retry returns normally, while a network error or exhausted retries returns CKR_DEVICE_ERROR.ALTAPI REQUESTHTTPS REQUESTTIMEOUTEXPONENTIAL BACKOFFRETRY REQUESTSUCCESSSUCCESSCKR_DEVICE_ERROR[network timeout · retry succeeds][network error · max retries]LIBRARYPKCS#11 layerlibdke_pkcs11.soLIBRARYDuoKey SDKretry · backoffCOCKPITDuoKey Cockpitv2 proxy endpointLEGENDCallHTTPS requestReturnLocal stepRecovered

A timeout is retried with exponential backoff; a network error, or a retry that still fails at the max-retry limit, returns CKR_DEVICE_ERROR.

Authentication Error Handling​

Sequence

Authentication error handling

Authentication error handlingCockpit validates the access_token on each request; a valid token returns 200 OK, an invalid or revoked one returns 401, which the SDK maps to CKR_PIN_INCORRECT.ALTAPI REQUESTBEARER TOKENVALIDATE ACCESS_TOKEN200 OKSUCCESS401 UNAUTHORIZEDCKR_PIN_INCORRECT[valid token][invalid or revoked token]LIBRARYPKCS#11 layerlibdke_pkcs11.soLIBRARYDuoKey SDKaccess_tokenCOCKPITDuoKey Cockpitvalidates server-sideLEGENDCallHTTPS requestReturnLocal stepAuthorized

Cockpit validates the access_token on every request; a rejected token surfaces as CKR_PIN_INCORRECT and is not retried.

Note: The access_token is a single static bearer credential (distinct from the non-secret access_guid routing id in server_url). There is no token endpoint and no refresh cycle, so a rejected token is a terminal error (check access_token in pkcs11.toml) rather than something the library retries.

HSM Error Handling​

Flowchart

HSM error handling

HSM error handlingAn operation travels from the SDK to Cockpit and the HSM; a 500, 404 or 400 response is mapped to CKR_DEVICE_ERROR, CKR_OBJECT_HANDLE_INVALID or CKR_ARGUMENTS_BAD.500 INTERNAL404 NOT FOUND400 BAD REQUESTOperation requestSDK calls CockpitAPI requestCockpit calls the HSMoperationBackendresponse?HSM errorCKR_DEVICE_ERRORObject not foundCKR_OBJECT_HANDLE_INVALIDInvalid parametersCKR_ARGUMENTS_BADLEGENDStatus mapped to a PKCS#11 codeStep, outcomeFlow

The SDK layer maps each backend outcome to the matching PKCS#11 return code.

Performance Optimization​

Connection Reuse​

State machine

Connection reuse

Connection reuseThe first request creates and caches a connection; every later request reuses the cached connection instead of a new TCP and TLS handshake.FIRST REQUEST / CREATE + CACHENEXT REQUEST / REUSENo connectionConnection cachedkeep-aliveLEGENDEvent / actionReuse, no new handshakeCached connection

After the first request the connection is cached; subsequent requests reuse the cached connection.

Benefits:

  • Eliminates TCP handshake overhead
  • Reduces connection establishment time
  • Improves overall throughput

Bearer Token​

The library authenticates every request with an access_token bearer credential from pkcs11.toml. The access_guid embedded in the app proxy server_url is a separate, non-secret routing id. There is no token endpoint and no refresh cycle: the same access_token is presented on each request and validated server-side by the Cockpit, which resolves the tenant from (app_id, access_guid).

Sequence

Bearer token authentication

Bearer token authenticationThe SDK attaches the access_token to each request; Cockpit validates it, resolves the tenant from app_id and access_guid, and authorizes the call.ATTACH ACCESS_TOKENREQUEST + BEARERVALIDATE TOKENRESOLVE TENANT (APP_ID, ACCESS_GUID)AUTHORIZEDLIBRARYDuoKey SDKpkcs11.tomlCOCKPITDuoKey Cockpitv2 proxy endpointLEGENDHTTPS requestLocal stepAuthorized

The same access_token is presented on each request; Cockpit validates it and resolves the tenant from app_id and access_guid.

Benefits:

  • No token-exchange round trips
  • No runtime secret to rotate (no client_id / client_secret)
  • Connection keep-alive reduces per-operation TLS handshakes

Handle Caching​

Flowchart

Handle caching

Handle cachingA UUID already in the cache returns its handle directly; a new UUID gets a new handle, which is stored in the cache before it is used.YESNOSTORE IN CACHEFind objectUUID incache?Return cached handlecache hitCreate new handlecache missStore and return handlecached for reuseUse handleLEGENDStep, decision, outcomeFlowCache hit, no new handle

A cached UUID returns its handle directly; a new UUID is assigned a handle and stored before use.

Benefits:

  • Avoids duplicate API calls
  • Faster handle resolution
  • Reduced network traffic

Monitoring and Debugging​

Request Tracing​

Enable debug logging to trace requests:

export DKE_PKCS11_LOGGING_LEVEL=debug
export DKE_PKCS11_LOGGING_FOLDER=/var/log/dke-pkcs11

Log Output:

[2025-12-19 10:30:45] [DEBUG] C_Initialize() called
[2025-12-19 10:30:45] [DEBUG] Reading pkcs11.toml (server_url, access_token)
[2025-12-19 10:30:45] [INFO] Connecting to DuoKey Cockpit: https://cockpit-api-dev.duokey.cloud
[2025-12-19 10:30:46] [INFO] access_token bearer credential validated by Cockpit
[2025-12-19 10:30:46] [DEBUG] C_Initialize() completed: CKR_OK

Performance Metrics​

Monitor key metrics:

  • Request Latency: Time from Oracle call to response
  • API Latency: Time for DuoKey Cockpit API calls
  • Error Rate: Percentage of failed requests
  • Auth Failures: Count of rejected access_token bearer credentials

Network Monitoring​

Monitor network traffic:

  • HTTPS Connections: Number of active connections
  • Request/Response Sizes: Payload sizes
  • Retry Count: Number of retries per request
  • Timeout Events: Frequency of timeouts

Best Practices​

Error Handling​

  1. Retry Transient Errors: Network errors, timeouts
  2. Don't Retry Auth Errors: Invalid credentials
  3. Log All Errors: For troubleshooting
  4. Return Appropriate Codes: Translate to PKCS#11 codes

Performance​

  1. Reuse Connections: Use connection pooling
  2. Keep Connections Alive: Amortize TLS handshakes across operations
  3. Batch Operations: When possible (future)
  4. Monitor Latency: Track performance metrics

Security​

  1. Use TLS: All connections encrypted
  2. Validate Certificates: Strict certificate validation
  3. Secure Credentials: Never log the access_token (or the access_guid, unnecessarily)
  4. Protect pkcs11.toml: Treat the access_token as a secret; restrict file permissions. The access_guid is not secret by itself but still identifies the app, so protect the whole file

Next Steps​