summaryrefslogtreecommitdiff
path: root/node_modules/sshpk/lib/formats/dnssec.js
diff options
context:
space:
mode:
authorLinuxWizard42 <computerwizard@linuxmail.org>2022-10-12 22:54:37 +0300
committerLinuxWizard42 <computerwizard@linuxmail.org>2022-10-12 22:54:37 +0300
commit703e03aba33f234712206769f57717ba7d92d23d (patch)
tree0041f04ccb75bd5379c764e9fe42249fffe75fc3 /node_modules/sshpk/lib/formats/dnssec.js
parentab6e257e6e9d9a483d7e86f220d8b209a2cd7753 (diff)
downloadFlashRunner-703e03aba33f234712206769f57717ba7d92d23d.tar.gz
FlashRunner-703e03aba33f234712206769f57717ba7d92d23d.tar.zst
Added export_allowed file to make repository visible in cgit
Diffstat (limited to 'node_modules/sshpk/lib/formats/dnssec.js')
-rw-r--r--node_modules/sshpk/lib/formats/dnssec.js287
1 files changed, 287 insertions, 0 deletions
diff --git a/node_modules/sshpk/lib/formats/dnssec.js b/node_modules/sshpk/lib/formats/dnssec.js
new file mode 100644
index 0000000..a74ea9c
--- /dev/null
+++ b/node_modules/sshpk/lib/formats/dnssec.js
@@ -0,0 +1,287 @@
+// Copyright 2017 Joyent, Inc.
+
+module.exports = {
+ read: read,
+ write: write
+};
+
+var assert = require('assert-plus');
+var Buffer = require('safer-buffer').Buffer;
+var Key = require('../key');
+var PrivateKey = require('../private-key');
+var utils = require('../utils');
+var SSHBuffer = require('../ssh-buffer');
+var Dhe = require('../dhe');
+
+var supportedAlgos = {
+ 'rsa-sha1' : 5,
+ 'rsa-sha256' : 8,
+ 'rsa-sha512' : 10,
+ 'ecdsa-p256-sha256' : 13,
+ 'ecdsa-p384-sha384' : 14
+ /*
+ * ed25519 is hypothetically supported with id 15
+ * but the common tools available don't appear to be
+ * capable of generating/using ed25519 keys
+ */
+};
+
+var supportedAlgosById = {};
+Object.keys(supportedAlgos).forEach(function (k) {
+ supportedAlgosById[supportedAlgos[k]] = k.toUpperCase();
+});
+
+function read(buf, options) {
+ if (typeof (buf) !== 'string') {
+ assert.buffer(buf, 'buf');
+ buf = buf.toString('ascii');
+ }
+ var lines = buf.split('\n');
+ if (lines[0].match(/^Private-key-format\: v1/)) {
+ var algElems = lines[1].split(' ');
+ var algoNum = parseInt(algElems[1], 10);
+ var algoName = algElems[2];
+ if (!supportedAlgosById[algoNum])
+ throw (new Error('Unsupported algorithm: ' + algoName));
+ return (readDNSSECPrivateKey(algoNum, lines.slice(2)));
+ }
+
+ // skip any comment-lines
+ var line = 0;
+ /* JSSTYLED */
+ while (lines[line].match(/^\;/))
+ line++;
+ // we should now have *one single* line left with our KEY on it.
+ if ((lines[line].match(/\. IN KEY /) ||
+ lines[line].match(/\. IN DNSKEY /)) && lines[line+1].length === 0) {
+ return (readRFC3110(lines[line]));
+ }
+ throw (new Error('Cannot parse dnssec key'));
+}
+
+function readRFC3110(keyString) {
+ var elems = keyString.split(' ');
+ //unused var flags = parseInt(elems[3], 10);
+ //unused var protocol = parseInt(elems[4], 10);
+ var algorithm = parseInt(elems[5], 10);
+ if (!supportedAlgosById[algorithm])
+ throw (new Error('Unsupported algorithm: ' + algorithm));
+ var base64key = elems.slice(6, elems.length).join();
+ var keyBuffer = Buffer.from(base64key, 'base64');
+ if (supportedAlgosById[algorithm].match(/^RSA-/)) {
+ // join the rest of the body into a single base64-blob
+ var publicExponentLen = keyBuffer.readUInt8(0);
+ if (publicExponentLen != 3 && publicExponentLen != 1)
+ throw (new Error('Cannot parse dnssec key: ' +
+ 'unsupported exponent length'));
+
+ var publicExponent = keyBuffer.slice(1, publicExponentLen+1);
+ publicExponent = utils.mpNormalize(publicExponent);
+ var modulus = keyBuffer.slice(1+publicExponentLen);
+ modulus = utils.mpNormalize(modulus);
+ // now, make the key
+ var rsaKey = {
+ type: 'rsa',
+ parts: []
+ };
+ rsaKey.parts.push({ name: 'e', data: publicExponent});
+ rsaKey.parts.push({ name: 'n', data: modulus});
+ return (new Key(rsaKey));
+ }
+ if (supportedAlgosById[algorithm] === 'ECDSA-P384-SHA384' ||
+ supportedAlgosById[algorithm] === 'ECDSA-P256-SHA256') {
+ var curve = 'nistp384';
+ var size = 384;
+ if (supportedAlgosById[algorithm].match(/^ECDSA-P256-SHA256/)) {
+ curve = 'nistp256';
+ size = 256;
+ }
+
+ var ecdsaKey = {
+ type: 'ecdsa',
+ curve: curve,
+ size: size,
+ parts: [
+ {name: 'curve', data: Buffer.from(curve) },
+ {name: 'Q', data: utils.ecNormalize(keyBuffer) }
+ ]
+ };
+ return (new Key(ecdsaKey));
+ }
+ throw (new Error('Unsupported algorithm: ' +
+ supportedAlgosById[algorithm]));
+}
+
+function elementToBuf(e) {
+ return (Buffer.from(e.split(' ')[1], 'base64'));
+}
+
+function readDNSSECRSAPrivateKey(elements) {
+ var rsaParams = {};
+ elements.forEach(function (element) {
+ if (element.split(' ')[0] === 'Modulus:')
+ rsaParams['n'] = elementToBuf(element);
+ else if (element.split(' ')[0] === 'PublicExponent:')
+ rsaParams['e'] = elementToBuf(element);
+ else if (element.split(' ')[0] === 'PrivateExponent:')
+ rsaParams['d'] = elementToBuf(element);
+ else if (element.split(' ')[0] === 'Prime1:')
+ rsaParams['p'] = elementToBuf(element);
+ else if (element.split(' ')[0] === 'Prime2:')
+ rsaParams['q'] = elementToBuf(element);
+ else if (element.split(' ')[0] === 'Exponent1:')
+ rsaParams['dmodp'] = elementToBuf(element);
+ else if (element.split(' ')[0] === 'Exponent2:')
+ rsaParams['dmodq'] = elementToBuf(element);
+ else if (element.split(' ')[0] === 'Coefficient:')
+ rsaParams['iqmp'] = elementToBuf(element);
+ });
+ // now, make the key
+ var key = {
+ type: 'rsa',
+ parts: [
+ { name: 'e', data: utils.mpNormalize(rsaParams['e'])},
+ { name: 'n', data: utils.mpNormalize(rsaParams['n'])},
+ { name: 'd', data: utils.mpNormalize(rsaParams['d'])},
+ { name: 'p', data: utils.mpNormalize(rsaParams['p'])},
+ { name: 'q', data: utils.mpNormalize(rsaParams['q'])},
+ { name: 'dmodp',
+ data: utils.mpNormalize(rsaParams['dmodp'])},
+ { name: 'dmodq',
+ data: utils.mpNormalize(rsaParams['dmodq'])},
+ { name: 'iqmp',
+ data: utils.mpNormalize(rsaParams['iqmp'])}
+ ]
+ };
+ return (new PrivateKey(key));
+}
+
+function readDNSSECPrivateKey(alg, elements) {
+ if (supportedAlgosById[alg].match(/^RSA-/)) {
+ return (readDNSSECRSAPrivateKey(elements));
+ }
+ if (supportedAlgosById[alg] === 'ECDSA-P384-SHA384' ||
+ supportedAlgosById[alg] === 'ECDSA-P256-SHA256') {
+ var d = Buffer.from(elements[0].split(' ')[1], 'base64');
+ var curve = 'nistp384';
+ var size = 384;
+ if (supportedAlgosById[alg] === 'ECDSA-P256-SHA256') {
+ curve = 'nistp256';
+ size = 256;
+ }
+ // DNSSEC generates the public-key on the fly (go calculate it)
+ var publicKey = utils.publicFromPrivateECDSA(curve, d);
+ var Q = publicKey.part['Q'].data;
+ var ecdsaKey = {
+ type: 'ecdsa',
+ curve: curve,
+ size: size,
+ parts: [
+ {name: 'curve', data: Buffer.from(curve) },
+ {name: 'd', data: d },
+ {name: 'Q', data: Q }
+ ]
+ };
+ return (new PrivateKey(ecdsaKey));
+ }
+ throw (new Error('Unsupported algorithm: ' + supportedAlgosById[alg]));
+}
+
+function dnssecTimestamp(date) {
+ var year = date.getFullYear() + ''; //stringify
+ var month = (date.getMonth() + 1);
+ var timestampStr = year + month + date.getUTCDate();
+ timestampStr += '' + date.getUTCHours() + date.getUTCMinutes();
+ timestampStr += date.getUTCSeconds();
+ return (timestampStr);
+}
+
+function rsaAlgFromOptions(opts) {
+ if (!opts || !opts.hashAlgo || opts.hashAlgo === 'sha1')
+ return ('5 (RSASHA1)');
+ else if (opts.hashAlgo === 'sha256')
+ return ('8 (RSASHA256)');
+ else if (opts.hashAlgo === 'sha512')
+ return ('10 (RSASHA512)');
+ else
+ throw (new Error('Unknown or unsupported hash: ' +
+ opts.hashAlgo));
+}
+
+function writeRSA(key, options) {
+ // if we're missing parts, add them.
+ if (!key.part.dmodp || !key.part.dmodq) {
+ utils.addRSAMissing(key);
+ }
+
+ var out = '';
+ out += 'Private-key-format: v1.3\n';
+ out += 'Algorithm: ' + rsaAlgFromOptions(options) + '\n';
+ var n = utils.mpDenormalize(key.part['n'].data);
+ out += 'Modulus: ' + n.toString('base64') + '\n';
+ var e = utils.mpDenormalize(key.part['e'].data);
+ out += 'PublicExponent: ' + e.toString('base64') + '\n';
+ var d = utils.mpDenormalize(key.part['d'].data);
+ out += 'PrivateExponent: ' + d.toString('base64') + '\n';
+ var p = utils.mpDenormalize(key.part['p'].data);
+ out += 'Prime1: ' + p.toString('base64') + '\n';
+ var q = utils.mpDenormalize(key.part['q'].data);
+ out += 'Prime2: ' + q.toString('base64') + '\n';
+ var dmodp = utils.mpDenormalize(key.part['dmodp'].data);
+ out += 'Exponent1: ' + dmodp.toString('base64') + '\n';
+ var dmodq = utils.mpDenormalize(key.part['dmodq'].data);
+ out += 'Exponent2: ' + dmodq.toString('base64') + '\n';
+ var iqmp = utils.mpDenormalize(key.part['iqmp'].data);
+ out += 'Coefficient: ' + iqmp.toString('base64') + '\n';
+ // Assume that we're valid as-of now
+ var timestamp = new Date();
+ out += 'Created: ' + dnssecTimestamp(timestamp) + '\n';
+ out += 'Publish: ' + dnssecTimestamp(timestamp) + '\n';
+ out += 'Activate: ' + dnssecTimestamp(timestamp) + '\n';
+ return (Buffer.from(out, 'ascii'));
+}
+
+function writeECDSA(key, options) {
+ var out = '';
+ out += 'Private-key-format: v1.3\n';
+
+ if (key.curve === 'nistp256') {
+ out += 'Algorithm: 13 (ECDSAP256SHA256)\n';
+ } else if (key.curve === 'nistp384') {
+ out += 'Algorithm: 14 (ECDSAP384SHA384)\n';
+ } else {
+ throw (new Error('Unsupported curve'));
+ }
+ var base64Key = key.part['d'].data.toString('base64');
+ out += 'PrivateKey: ' + base64Key + '\n';
+
+ // Assume that we're valid as-of now
+ var timestamp = new Date();
+ out += 'Created: ' + dnssecTimestamp(timestamp) + '\n';
+ out += 'Publish: ' + dnssecTimestamp(timestamp) + '\n';
+ out += 'Activate: ' + dnssecTimestamp(timestamp) + '\n';
+
+ return (Buffer.from(out, 'ascii'));
+}
+
+function write(key, options) {
+ if (PrivateKey.isPrivateKey(key)) {
+ if (key.type === 'rsa') {
+ return (writeRSA(key, options));
+ } else if (key.type === 'ecdsa') {
+ return (writeECDSA(key, options));
+ } else {
+ throw (new Error('Unsupported algorithm: ' + key.type));
+ }
+ } else if (Key.isKey(key)) {
+ /*
+ * RFC3110 requires a keyname, and a keytype, which we
+ * don't really have a mechanism for specifying such
+ * additional metadata.
+ */
+ throw (new Error('Format "dnssec" only supports ' +
+ 'writing private keys'));
+ } else {
+ throw (new Error('key is not a Key or PrivateKey'));
+ }
+}