Skip to content

Instantly share code, notes, and snippets.

@mikedh
Last active November 5, 2021 19:51
Show Gist options
  • Save mikedh/7afdf2305bb5b660a7cb85e9abe8fc0a to your computer and use it in GitHub Desktop.
Save mikedh/7afdf2305bb5b660a7cb85e9abe8fc0a to your computer and use it in GitHub Desktop.
mikedh@luna:sandbox$ node key_issue.js
(node:599349) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'raw' of undefined
at spkiFromX509 (/home/mikedh/sandbox/node_modules/jose/dist/node/cjs/key/import.js:68:110)
at getSPKI (/home/mikedh/sandbox/node_modules/jose/dist/node/cjs/key/import.js:73:41)
at importX509 (/home/mikedh/sandbox/node_modules/jose/dist/node/cjs/key/import.js:86:18)
at Object.<anonymous> (/home/mikedh/sandbox/key_issue.js:3:13)
at Module._compile (internal/modules/cjs/loader.js:999:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
at Module.load (internal/modules/cjs/loader.js:863:32)
at Function.Module._load (internal/modules/cjs/loader.js:708:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:60:12)
at internal/main/run_main_module.js:17:47
(node:599349) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:599349) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
[req]
default_bits = 4096
prompt = no
default_md = sha256
x509_extensions = v3_req
distinguished_name = dn
[dn]
C = US
ST = Pennsylvania
L = Pittsburgh
O = Example, Inc.
emailAddress = example@example.com
CN = example.com
[v3_req]
subjectAltName = @alt_names
[alt_names]
DNS.1 = example.com
DNS.2 = example.ngrok.io
DNS.3 = localhost
"""
jose_repro.py
------------
Generate new ED25519 SSH certificates using `openssl`
"""
import os
import json
import string
import base64
import tempfile
import subprocess
# current working directory of this file
cwd = os.path.abspath(
os.path.expanduser(os.path.dirname(__file__)))
if __name__ == '__main__':
# how many days
days = str(int(700))
config = os.path.join(cwd, 'example.san')
# collect into `rsa` and `ed25519`
result = {}
with tempfile.TemporaryDirectory() as d:
# generate some ED25519 stuff!
# https://blog.pinterjann.is/ed25519-certificates.html
public = os.path.join(d, 'ed.crt')
request = os.path.join(d, 'ed.csr')
private = os.path.join(d, 'ed.key')
# generate the random "secret"
subprocess.call(
f'openssl genpkey -algorithm ED25519 > {private}',
shell=True)
# generate a "certificate signing request"
subprocess.call(
['openssl', 'req', '-new', '-out',
request, '-key', private, '-config', config])
# generate an actual certificate
subprocess.call(['openssl', 'x509', '-req',
'-days', days, '-in', request,
'-signkey', private, '-out', public])
with open(public, 'r') as f:
result['ed25519'] = {'publicKey': f.read()}
with open(private, 'r') as f:
result['ed25519']['privateKey'] = f.read()
with open(request, 'r') as f:
result['ed25519']['csr'] = f.read()
# verify that openssl can read our results
print('reading CSR:\n\n' + subprocess.check_output(
['openssl', 'req', '-in', request,
'-text', '-noout']).decode('utf-8'))
# for both
print('reading public:\n\n' + subprocess.check_output(
['openssl', 'x509', '-in', public, '-text',
'-noout']).decode('utf-8'))
# generate a minimal example to check the `importX509` function
script = ["const { importX509 } = require('jose')",
"const ed25519 = " + json.dumps(result['ed25519']),
"const key = importX509(ed25519.publicKey, 'EdDSA')"]
with open('key_issue.js', 'w') as f:
f.write('\n'.join(script))
const { importX509 } = require('jose')
const ed25519 = {"publicKey": "-----BEGIN CERTIFICATE-----\nMIIB0zCCAYUCFEAGUxyTR1mz/XyaVnqHUA1T0bg4MAUGAytlcDCBizELMAkGA1UE\nBhMCVVMxFTATBgNVBAgMDFBlbm5zeWx2YW5pYTETMBEGA1UEBwwKUGl0dHNidXJn\naDEWMBQGA1UECgwNRXhhbXBsZSwgSW5jLjEiMCAGCSqGSIb3DQEJARYTZXhhbXBs\nZUBleGFtcGxlLmNvbTEUMBIGA1UEAwwLZXhhbXBsZS5jb20wHhcNMjExMTA1MTkz\nNTQ4WhcNMjMxMDA2MTkzNTQ4WjCBizELMAkGA1UEBhMCVVMxFTATBgNVBAgMDFBl\nbm5zeWx2YW5pYTETMBEGA1UEBwwKUGl0dHNidXJnaDEWMBQGA1UECgwNRXhhbXBs\nZSwgSW5jLjEiMCAGCSqGSIb3DQEJARYTZXhhbXBsZUBleGFtcGxlLmNvbTEUMBIG\nA1UEAwwLZXhhbXBsZS5jb20wKjAFBgMrZXADIQCuVl9VNLFAflCTZDKRtWjGLqsD\ne/E5r+zIN1H6rWkE/DAFBgMrZXADQQDet6id3ZIBqQ4RP1GBRHN19epkb7euezw6\nYlmU09Tsz1j7utsNgs6ztF43GyzzVWrBtHkjne7qtnIONDqSvJoC\n-----END CERTIFICATE-----\n", "privateKey": "-----BEGIN PRIVATE KEY-----\nMC4CAQAwBQYDK2VwBCIEICXB7D1ntExZMLLyAIQJLP42umn571JT9igQM9wYXkT9\n-----END PRIVATE KEY-----\n", "csr": "-----BEGIN CERTIFICATE REQUEST-----\nMIIBDDCBvwIBADCBizELMAkGA1UEBhMCVVMxFTATBgNVBAgMDFBlbm5zeWx2YW5p\nYTETMBEGA1UEBwwKUGl0dHNidXJnaDEWMBQGA1UECgwNRXhhbXBsZSwgSW5jLjEi\nMCAGCSqGSIb3DQEJARYTZXhhbXBsZUBleGFtcGxlLmNvbTEUMBIGA1UEAwwLZXhh\nbXBsZS5jb20wKjAFBgMrZXADIQCuVl9VNLFAflCTZDKRtWjGLqsDe/E5r+zIN1H6\nrWkE/KAAMAUGAytlcANBADSUCTmispUEssUoE2LLG3DGeAWSQAVMBhomBzxVURwg\nYa0Uhnlr7No7ZeRpKm2mAVSAt151L9XSYWV8NNbVrwo=\n-----END CERTIFICATE REQUEST-----\n"}
const key = importX509(ed25519.publicKey, 'EdDSA')
mikedh@luna:sandbox$ python jose_repro.py
Signature ok
subject=C = US, ST = Pennsylvania, L = Pittsburgh, O = "Example, Inc.", emailAddress = example@example.com, CN = example.com
Getting Private key
reading CSR:
Certificate Request:
Data:
Version: 1 (0x0)
Subject: C = US, ST = Pennsylvania, L = Pittsburgh, O = "Example, Inc.", emailAddress = example@example.com, CN = example.com
Subject Public Key Info:
Public Key Algorithm: ED25519
ED25519 Public-Key:
pub:
52:54:9b:ad:f9:f1:c9:6c:db:6e:0b:8a:d6:05:24:
58:17:d0:fe:11:51:74:b3:6e:b1:06:fe:46:93:88:
59:56
Attributes:
a0:00
Signature Algorithm: ED25519
45:d5:be:aa:78:2f:1c:a9:86:38:8f:a7:85:d9:d2:ce:a7:c8:
af:9c:43:79:cd:1e:17:44:d7:a5:3c:28:81:30:a7:42:1b:1d:
e4:37:7b:5f:4c:90:6c:8d:4c:2c:f6:b3:fc:ca:13:03:be:10:
37:77:69:fe:87:bb:b8:5a:65:00
reading public:
Certificate:
Data:
Version: 1 (0x0)
Serial Number:
07:42:ad:11:75:67:fd:8e:33:0e:58:8d:c2:b9:f4:fa:9a:a5:14:4b
Signature Algorithm: ED25519
Issuer: C = US, ST = Pennsylvania, L = Pittsburgh, O = "Example, Inc.", emailAddress = example@example.com, CN = example.com
Validity
Not Before: Nov 5 19:47:08 2021 GMT
Not After : Oct 6 19:47:08 2023 GMT
Subject: C = US, ST = Pennsylvania, L = Pittsburgh, O = "Example, Inc.", emailAddress = example@example.com, CN = example.com
Subject Public Key Info:
Public Key Algorithm: ED25519
ED25519 Public-Key:
pub:
52:54:9b:ad:f9:f1:c9:6c:db:6e:0b:8a:d6:05:24:
58:17:d0:fe:11:51:74:b3:6e:b1:06:fe:46:93:88:
59:56
Signature Algorithm: ED25519
42:4c:32:32:4f:39:4a:36:9f:8a:42:d3:36:3f:e4:9e:f9:a1:
55:50:ef:9c:2d:52:59:bb:6e:2d:ff:07:ca:14:c5:29:0f:8e:
02:97:a3:21:e7:a0:21:6a:a7:72:4b:a5:7e:37:44:31:c1:95:
b6:a4:9a:3d:b3:6b:c0:ed:19:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment