UNPKG

@microsoft/dev-tunnels-ssh

Version:
119 lines 4.61 kB
"use strict"; // // Copyright (c) Microsoft Corporation. All rights reserved. // Object.defineProperty(exports, "__esModule", { value: true }); exports.JsonWebKeyFormatter = void 0; const bigInt_1 = require("../../io/bigInt"); const ecdsaCurves_1 = require("../ecdsaCurves"); /** * Provides *minimal* JWK import/export support for web keys. * * This code is redundant with some of the JWK import/export code in the separate * `ssh-keys` library; that is intentional, and necessary to support a consistent * interface for importing/exporting key parameters in the core `ssh` library. */ class JsonWebKeyFormatter { static formatRsa(rsa, includePrivate) { const formatBigInt = JsonWebKeyFormatter.formatBigInt; let jwk; if (includePrivate !== false && rsa.d && rsa.p && rsa.q && rsa.dp && rsa.dq && rsa.qi) { jwk = { kty: 'RSA', n: formatBigInt(rsa.modulus), e: formatBigInt(rsa.exponent), d: formatBigInt(rsa.d), p: formatBigInt(rsa.p), q: formatBigInt(rsa.q), dp: formatBigInt(rsa.dp), dq: formatBigInt(rsa.dq), qi: formatBigInt(rsa.qi), }; } else if (!includePrivate) { jwk = { kty: 'RSA', n: formatBigInt(rsa.modulus), e: formatBigInt(rsa.exponent), }; } else { throw new Error('Missing private key parameters.'); } return jwk; } static parseRsa(jwk, includePrivate) { if ((jwk === null || jwk === void 0 ? void 0 : jwk.kty) !== 'RSA' || !(jwk.n && jwk.e)) throw new Error('Invalid RSA JWK.'); const parseBigInt = JsonWebKeyFormatter.parseBigInt; let rsa; if (includePrivate !== false && jwk.d && jwk.p && jwk.q && jwk.dp && jwk.dq && jwk.qi) { rsa = { modulus: parseBigInt(jwk.n), exponent: parseBigInt(jwk.e), d: parseBigInt(jwk.d), p: parseBigInt(jwk.p), q: parseBigInt(jwk.q), dp: parseBigInt(jwk.dp), dq: parseBigInt(jwk.dq), qi: parseBigInt(jwk.qi), }; } else { rsa = { modulus: parseBigInt(jwk.n), exponent: parseBigInt(jwk.e), }; } return rsa; } static formatEC(ec, includePrivate) { const formatBigInt = JsonWebKeyFormatter.formatBigInt; const curve = ecdsaCurves_1.curves.find((c) => c.oid === ec.curve.oid || c.name === ec.curve.name || c.shortName === ec.curve.name); const keySizeInBytes = Math.ceil(curve.keySize / 8); const jwk = { kty: 'EC', crv: ec.curve.name, x: formatBigInt(ec.x, keySizeInBytes), y: formatBigInt(ec.y, keySizeInBytes), }; if (includePrivate !== false && ec.d) { jwk.d = formatBigInt(ec.d, keySizeInBytes); } else if (includePrivate) { throw new Error('Missing private key parameters.'); } return jwk; } static parseEC(jwk, includePrivate) { if ((jwk === null || jwk === void 0 ? void 0 : jwk.kty) !== 'EC' || !(jwk.crv && jwk.x && jwk.y)) throw new Error('Invalid EC JWK.'); const parseBigInt = JsonWebKeyFormatter.parseBigInt; const ec = { curve: { name: jwk.crv }, x: parseBigInt(jwk.x), y: parseBigInt(jwk.y), }; if (includePrivate !== false && jwk.d) { ec.d = parseBigInt(jwk.d); } return ec; } static formatBigInt(value, length) { return JsonWebKeyFormatter.base64UrlEncode(value.toBytes({ unsigned: true, length })); } static parseBigInt(value) { return bigInt_1.BigInt.fromBytes(Buffer.from(value, 'base64'), { unsigned: true }); } static base64UrlEncode(data) { // JWK format uses base64-url-encoding, which is base64 but with 2 substituted characters. // (Note Buffer's base64 DECODING implicitly supports this format.) return data .toString('base64') .replace(/=+$/g, '') .replace(/\+/g, '-') .replace(/\//g, '_'); } } exports.JsonWebKeyFormatter = JsonWebKeyFormatter; //# sourceMappingURL=jsonWebKeyFormatter.js.map