Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use private keys persisted in the TPM with tpm2-openssl OpenSSL Provider #4413

Closed
2 tasks done
nuts-i77 opened this issue Jun 5, 2024 · 3 comments
Closed
2 tasks done

Comments

@nuts-i77
Copy link

nuts-i77 commented Jun 5, 2024

Node.js Version

v18.19.1

NPM Version

v9.2.0

Operating System

Linux test1 6.8.0-35-generic #35-Ubuntu SMP PREEMPT_DYNAMIC Mon May 20 15:51:52 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux

Subsystem

https

Description

I am trying to use the OpenSSL Provider's tpm2-openssl and the TPM for client certificate authentication in a Node.js application.
I was able to use a private key in PEM (TSS2 PRIVATE KEY) key format.
However, when I try to use a private key persisted in the TPM from Node.js, I get the ERR_OSSL_UNSUPPORTED error.

Does anyone have any ideas on how to use a private key persisted in a TPM from Node.js?

tpm2-openssl
https://github.com/tpm2-software/tpm2-openssl

Client certificate authentication using a PEM (TSS2 PRIVATE KEY) format key was successful using the following procedure.

Generate a private key
openssl genpkey -provider tpm2 -algorithm RSA -out clkey

Generate a CSR and issue a certificate from a CA using client.csr and save it as clcert.
openssl req -new -key clkey -provider tpm2 -provider base -out client.csr

Creating openssl.cnf

nodejs_conf = nodejs_init

[nodejs_init]
providers = provider_sect

[provider_sect]
default = default_sect
tpm2 = tpm2_section

[tpm2_section]
dynamic_path=/usr/lib/x86_64-linux-gnu/ossl-modules/tpm2.so
activate = 1

[default_sect]
activate = 1

Creating a Node.js test program

const https = require('https');
const fs    = require('fs');

console.time('request');

const options = {
  hostname: 'example.com',
  port: 443,
  path: '/',
  method: 'GET',

  // private key file(TSS2 PRIVATE KEY format)
  key: fs.readFileSync('clkey'),

  // client cert
  cert: fs.readFileSync('clcert'),
};

const req = https.request(options, (res) => {
    res.on('data', (d) => process.stdout.write(d));
    console.timeEnd('request');
});

req.on('error', (e) => console.error(e))

req.end();

Start test program

request: 211.767ms
{}

However, when I try to use a private key persisted in the TPM from Node.js, I get the ERR_OSSL_UNSUPPORTED error.

Persist the private key in the TPM handler

tpm2_createek -G rsa -c ek_rsa.ctx
tpm2_createak -C ek_rsa.ctx -G rsa -g sha256 -s rsassa -c ak_rsa.ctx
tpm2_evictcontrol -c ak_rsa.ctx 0x81008100

Generate a CSR and issue a certificate from a CA using client.csr and save it as clcert.
openssl req -new -key handle:0x81008100 -provider tpm2 -provider base -out client.csr

Creating openssl.cnf

nodejs_conf = nodejs_init

[nodejs_init]
providers = provider_sect

[provider_sect]
default = default_sect
tpm2 = tpm2_section

[tpm2_section]
dynamic_path=/usr/lib/x86_64-linux-gnu/ossl-modules/tpm2.so
activate = 1

[default_sect]
activate = 1

Creating a Node.js test program

const https = require('https');
const fs    = require('fs');

console.time('request');

const options = {
  hostname: 'example.com',
  port: 443,
  path: '/',
  method: 'GET',

  // handle of the private key
  key: "handle:0x81008100",

  // client cert
  cert: fs.readFileSync('clcert'),
};

const req = https.request(options, (res) => {
    res.on('data', (d) => process.stdout.write(d));
    console.timeEnd('request');
});

req.on('error', (e) => console.error(e))

req.end();

Start test program

node --openssl-config=openssl.cnf test.js
request: 211.767ms
node:internal/tls/secure-context:93
  context.setKey(key, passphrase);
          ^

Error: error:1E08010C:DECODER routines::unsupported
    at setKey (node:internal/tls/secure-context:93:11)
    at configSecureContext (node:internal/tls/secure-context:175:7)
    at Object.createSecureContext (node:_tls_common:117:3)
    at Object.connect (node:_tls_wrap:1750:48)
    at Agent.createConnection (node:https:158:22)
    at Agent.createSocket (node:_http_agent:341:26)
    at Agent.addRequest (node:_http_agent:288:10)
    at new ClientRequest (node:_http_client:342:16)
    at Object.request (node:https:366:10)
    at Object.<anonymous> (/root/test2.js:42:19) {
  library: 'DECODER routines',
  reason: 'unsupported',
  code: 'ERR_OSSL_UNSUPPORTED'
}


Minimal Reproduction

No response

Output

No response

Before You Submit

  • I have looked for issues that already exist before submitting this
  • My issue follows the guidelines in the README file, and follows the 'How to ask a good question' guide at https://stackoverflow.com/help/how-to-ask
@nuts-i77 nuts-i77 changed the title How to use private keys persisted in the TPM with tpm2-tools OpenSSL Provider How to use private keys persisted in the TPM with tpm2-openssl OpenSSL Provider Jun 5, 2024
@OSkrk
Copy link

OSkrk commented Jul 31, 2024

@nuts-i77 in the first case, the command below generates a standard PEM key not a TSS2 PRIVATE KEY. You can check the content of the clkey file:

openssl genpkey -provider tpm2 -algorithm RSA -out clkey

So it works for you with the PEM file as you are using the standard procedure (not using the TPM). I'm also trying to use a TSS2 PRIVATE KEY for a client mTLS session, so please let me know if you found a solution. In my case I'm getting the following error for both handle and TSS2 file:

node:internal/tls/secure-context:93
  context.setKey(key, passphrase);
          ^

Error: error:1E08010C:DECODER routines::unsupported
    at setKey (node:internal/tls/secure-context:93:11)
    at configSecureContext (node:internal/tls/secure-context:175:7)
    at Object.createSecureContext (node:_tls_common:117:3)
    at Object.connect (node:_tls_wrap:1750:48)
    at Agent.createConnection (node:https:158:22)
    at Agent.createSocket (node:_http_agent:341:26)
    at Agent.addRequest (node:_http_agent:288:10)
    at new ClientRequest (node:_http_client:342:16)
    at Object.request (node:https:366:10)
    at Object.<anonymous> (/home/oscar/app.js:19:19) {
  library: 'DECODER routines',
  reason: 'unsupported',
  code: 'ERR_OSSL_UNSUPPORTED'
}

Copy link

It seems there has been no activity on this issue for a while, and it is being closed in 30 days. If you believe this issue should remain open, please leave a comment.
If you need further assistance or have questions, you can also search for similar issues on Stack Overflow.
Make sure to look at the README file for the most updated links.

@github-actions github-actions bot added the stale label Jan 28, 2025
Copy link

It seems there has been no activity on this issue for a while, and it is being closed. If you believe this issue should remain open, please leave a comment.
If you need further assistance or have questions, you can also search for similar issues on Stack Overflow.
Make sure to look at the README file for the most updated links.

@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Feb 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants