socketio / socketio/socket.io

Error in mTLS in node js using PKCS11 proxy and HSM

Open
#5,480 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

question
Dominant language
TypeScript
Stars
63.2k
Forks
10.3k
Avg merge
11d 20h
Merged PRs (30d)
2

Description

Description

I am implementing mutual TLS (mTLS) between a Node.js server and client using private keys stored in an HSM, accessed via a local PKCS#11 proxy on each machine.

Setup
  • Both server and client have their own HSM + PKCS#11 proxy running locally
  • Server and client are running on different machines
  • Each side uses its own HSM instance for private key operations
  • Private keys are accessed via PKCS#11 proxy
  • Certificates are loaded from local PEM files
Architecture Diagram
        ┌──────────────────────────────┐          ┌──────────────────────────────┐
        │        Server Machine        │          │        Client Machine        │
        │                              │          │                              │
        │   +----------------------+   │          │   +----------------------+   │
        │   |        HSM           |   │          │   |        HSM           |   │
        │   |  (Private Key:      |   │          │   |  (Private Key:      |   │
        │   |   CORE0001)         |   │          │   |   EDGE0001)         |   │
        │   +----------+-----------+  │          │   +----------+-----------+  │
        │              |              │          │              |              │
        │              | PKCS#11      │          │              | PKCS#11      │
        │              |              │          │              |              │
        │   +----------v-----------+  │          │   +----------v-----------+  │
        │   |   PKCS#11 Proxy      |  │          │   |   PKCS#11 Proxy      |  │
        │   |   (Local)            |  │          │   |   (Local)            |  │
        │   +----------+-----------+  │          │   +----------+-----------+  │
        │              |              │          │              |              │
        │   +----------v-----------+  │          │   +----------v-----------+  │
        │   |    Node.js Server    |  │          │   |    Node.js Client    |  │
        │   |    (socket.io)       |  │          │   | (socket.io-client)   |  │
        │   +----------------------+  │          │   +----------------------+  │
        │                              │          │                              │
        └──────────────┬───────────────┘          └──────────────┬───────────────┘
                       │                                         │
                       │<---------- mTLS (HTTPS) --------------->│
                       │                                         │
Libraries
  • Server: socket.io (^4.8.0)
  • Client: socket.io-client (^4.8.0)
Server (Working)

Key TLS config:

const httpsOptions = {
  cert: serverCert,
  privateKeyEngine: "pkcs11",
  privateKeyIdentifier: PKCS11_KEY_URI,
  ca: caCert,
  requestCert: true,
  rejectUnauthorized: true,
  minVersion: "TLSv1.2",
  maxVersion: "TLSv1.2",
};

Server starts successfully and loads the private key from HSM without issues.

Client (Failing)

Key TLS setup:

const secureContext = createSecureContext({
  cert: clientCert,
  privateKeyEngine: "pkcs11",
  privateKeyIdentifier: PKCS11_KEY_URI,
  ca: caCert,
  minVersion: "TLSv1.2",
});

const agent = new HttpsAgent({
  secureContext,
  rejectUnauthorized: true,
  checkServerIdentity: () => undefined,
});

Socket.IO connection:

const socket = io(SERVER_URL, {
  agent,
  rejectUnauthorized: true,
  transports: ["websocket", "polling"],
  timeout: 20000,
});
Issue
  • Client connection times out
  • No TLS handshake is completed
  • No useful TLS errors on client or server
  • Server never logs secureConnection
Observations
  • Server works correctly with PKCS#11 key
  • Client fails only when using PKCS#11 private key
  • Both sides use same CA
  • Network connectivity is confirmed
  • Each side uses its own HSM + PKCS#11 proxy locally
Expected Behavior

Client should complete TLS handshake using private key from HSM and connect successfully.

Question

Is there any limitation or required configuration when using privateKeyEngine + privateKeyIdentifier with socket.io-client (via https.Agent)?

Any guidance on debugging PKCS#11-based TLS handshake in Node.js would be helpful.

Image

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

No repository file or test is named. Start at the socket.io-client connection path using the Node.js createSecureContext and https.Agent configuration, then reproduce the client handshake with TLS diagnostics enabled. Done means identifying whether the PKCS#11 options are supported there and documenting a confirmed configuration or limitation.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, node.js
Domain
api, backend, security
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.