From 67bb76d19eb1fa2f5ff2b6b77e867de6af12b148 Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Tue, 20 Nov 2018 23:55:17 -0700 Subject: [PATCH] v1.2.0 add ability to read ssh pub files --- README.md | 2 ++ lib/eckles.js | 35 +++++++++++++++++++++++++++++++++-- package.json | 4 ++-- test.sh | 9 +++++++++ 4 files changed, 46 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 8fa53db..cef868a 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ ECDSA (elliptic curve) tools. Lightweight. Zero Dependencies. Universal compatib * [x] PEM-to-JWK * [x] JWK-to-PEM +* [x] SSH "pub" format This project is fully functional and tested (and the code is pretty clean). @@ -18,6 +19,7 @@ It is considered to be complete, but if you find a bug please open an issue. * [x] SEC1/X9.62, PKCS#8, SPKI/PKIX * [x] P-256 (prime256v1, secp256r1), P-384 (secp384r1) +* [x] SSH (RFC4716), (RFC 4716/SSH2) ```js var eckles = require('eckles'); diff --git a/lib/eckles.js b/lib/eckles.js index d07aa9a..a3a0d9b 100644 --- a/lib/eckles.js +++ b/lib/eckles.js @@ -16,6 +16,13 @@ var OBJ_ID_EC_384 = '06 05 2B81040022'.replace(/\s+/g, '').toLowerCase(); // ecPublicKey (ANSI X9.62 public key type) var OBJ_ID_EC_PUB = '06 07 2A8648CE3D0201'.replace(/\s+/g, '').toLowerCase(); + // 19 e c d s a - s h a 2 - n i s t p 2 5 6 +var SSH_EC_P256 = '00000013 65 63 64 73 61 2d 73 68 61 32 2d 6e 69 73 74 70 32 35 36' + .replace(/\s+/g, '').toLowerCase(); + + // 19 e c d s a - s h a 2 - n i s t p 3 8 4 +var SSH_EC_P384 = '00000013 65 63 64 73 61 2d 73 68 61 32 2d 6e 69 73 74 70 33 38 34' + .replace(/\s+/g, '').toLowerCase(); // The one good thing that came from the b***kchain hysteria: good EC documentation // https://davidederosa.com/basic-blockchain-programming/elliptic-curve-keys/ @@ -226,11 +233,35 @@ EC.parseSpki = function parsePem(u8, jwk) { }; EC.parsePkix = EC.parseSpki; +EC.parseSsh = function (pem) { + var jwk = { kty: 'EC', crv: null, x: null, y: null }; + var b64 = pem.split(/\s+/g)[1]; + var buf = Buffer.from(b64, 'base64'); + var hex = buf.toString('hex'); + var index = 40; + var len; + if (0 === hex.indexOf(SSH_EC_P256)) { + jwk.crv = 'P-256'; + len = 32; + } else if (0 === hex.indexOf(SSH_EC_P384)) { + jwk.crv = 'P-384'; + len = 48; + } + var x = buf.slice(index, index + len); + var y = buf.slice(index + len, index + len + len); + jwk.x = PEM._toUrlSafeBase64(x); + jwk.y = PEM._toUrlSafeBase64(y); + return jwk; +}; + /*global Promise*/ EC.parse = function parseEc(opts) { return Promise.resolve().then(function () { - if (!opts || !opts.pem) { - throw new Error("must pass { pem: pem }"); + if (!opts || !opts.pem || 'string' !== typeof opts.pem) { + throw new Error("must pass { pem: pem } as a string"); + } + if (0 === opts.pem.indexOf('ecdsa-sha2-')) { + return EC.parseSsh(opts.pem); } var pem = opts.pem; var u8 = PEM.parseBlock(pem).der; diff --git a/package.json b/package.json index 4a6c590..6724948 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "eckles", - "version": "1.1.1", - "description": "PEM-to-JWK and JWK-to-PEM for ECDSA keys in a lightweight, zero-dependency library focused on perfect universal compatibility.", + "version": "1.2.0", + "description": "PEM-to-JWK and JWK-to-PEM (and SSH) for ECDSA keys in a lightweight, zero-dependency library focused on perfect universal compatibility.", "homepage": "https://git.coolaj86.com/coolaj86/eckles.js", "main": "index.js", "bin": { diff --git a/test.sh b/test.sh index 37b4a4b..1f4ea32 100644 --- a/test.sh +++ b/test.sh @@ -11,6 +11,10 @@ node bin/eckles.js fixtures/privkey-ec-p256.pkcs8.pem | tee fixtures/privkey-ec- diff fixtures/privkey-ec-p256.jwk.json fixtures/privkey-ec-p256.jwk.2 node bin/eckles.js fixtures/pub-ec-p256.spki.pem | tee fixtures/pub-ec-p256.jwk.2 diff fixtures/pub-ec-p256.jwk.json fixtures/pub-ec-p256.jwk.2 +# +node bin/eckles.js fixtures/pub-ec-p256.ssh.pub | tee fixtures/pub-ec-p256.jwk.2 +diff fixtures/pub-ec-p256.jwk.2 fixtures/pub-ec-p256.jwk.2 + echo "" echo "" @@ -22,6 +26,10 @@ node bin/eckles.js fixtures/privkey-ec-p384.pkcs8.pem | tee fixtures/privkey-ec- diff fixtures/privkey-ec-p384.jwk.json fixtures/privkey-ec-p384.jwk.2.2 node bin/eckles.js fixtures/pub-ec-p384.spki.pem | tee fixtures/pub-ec-p384.jwk.2 diff fixtures/pub-ec-p384.jwk.json fixtures/pub-ec-p384.jwk.2 +# +node bin/eckles.js fixtures/pub-ec-p384.ssh.pub | tee fixtures/pub-ec-p384.jwk.2 +diff fixtures/pub-ec-p384.jwk.2 fixtures/pub-ec-p384.jwk.2 + echo "" echo "" @@ -39,6 +47,7 @@ diff fixtures/pub-ec-p256.spki.pem fixtures/pub-ec-p256.spki.pem.2 node bin/eckles.js fixtures/pub-ec-p256.jwk.json ssh | tee fixtures/pub-ec-p256.ssh.pub.2 diff fixtures/pub-ec-p256.ssh.pub fixtures/pub-ec-p256.ssh.pub.2 + echo "" echo "" echo "Testing JWK-to-PEM P-384"