mirror of
https://github.com/linuxserver/core.git
synced 2026-02-20 05:07:19 +08:00
Wed Mar 14 04:56:40 CET 2018
This commit is contained in:
parent
a8b05daac7
commit
6bbc0c6a4a
@ -47605,166 +47605,205 @@ define("plugins/c9.ide.clipboard/clipboard",[], function(require, exports, modul
|
||||
|
||||
define("plugins/c9.ide.save/autosave",[], function(require, exports, module) {
|
||||
main.consumes = [
|
||||
"Plugin", "c9", "ui", "layout", "tooltip",
|
||||
"anims", "menus", "tabManager", "save",
|
||||
"preferences.experimental"
|
||||
"Plugin", "c9", "settings", "tabManager", "preferences.experimental", "save", "apf"
|
||||
];
|
||||
main.provides = ["autosave"];
|
||||
return main;
|
||||
|
||||
function main(options, imports, register) {
|
||||
var c9 = imports.c9;
|
||||
var Plugin = imports.Plugin;
|
||||
var apf = imports.apf;
|
||||
var save = imports.save;
|
||||
var tooltip = imports.tooltip;
|
||||
var tabs = imports.tabManager;
|
||||
var experimental = imports["preferences.experimental"];
|
||||
var prefs = imports["preferences.experimental"];
|
||||
var Plugin = imports.Plugin;
|
||||
var settings = imports.settings;
|
||||
|
||||
var lang = require("ace/lib/lang");
|
||||
|
||||
var plugin = new Plugin("Ajax.org", main.consumes);
|
||||
|
||||
var INTERVAL = 60000;
|
||||
var CHANGE_TIMEOUT = 500;
|
||||
var CHANGE_TIMEOUT = options.changeTimeout || 1000;
|
||||
var SLOW_CHANGE_TIMEOUT = options.slowChangeTimeout || 30000;
|
||||
var SLOW_SAVE_THRESHOLD = 100 * 1024; // 100KB
|
||||
|
||||
var docChangeTimeout = null;
|
||||
var btnSave, autosave = true, saveInterval;
|
||||
var enabled = options.testing
|
||||
|| experimental.addExperiment("autosave", false, "Files/Auto-Save");
|
||||
var docChangeTimeout;
|
||||
var lastSaveTime = 0;
|
||||
var sessionId;
|
||||
var autosave;
|
||||
var saveWhenIdle;
|
||||
|
||||
var loaded = false;
|
||||
function load() {
|
||||
if (loaded || !enabled) return false;
|
||||
loaded = true;
|
||||
c9.on("stateChange", function(e) {
|
||||
if (e.state & c9.STORAGE && !(e.last & c9.STORAGE))
|
||||
check();
|
||||
}, plugin);
|
||||
|
||||
save.getElement("btnSave", function(btn) {
|
||||
btnSave = btn;
|
||||
transformButton();
|
||||
});
|
||||
|
||||
tabs.on("tabCreate", function(e) {
|
||||
var tab = e.tab;
|
||||
tab.document.undoManager.on("change", function(e) {
|
||||
if (!autosave || !tab.path)
|
||||
return;
|
||||
|
||||
clearTimeout(docChangeTimeout);
|
||||
docChangeTimeout = setTimeout(function() {
|
||||
saveTab(tab);
|
||||
}, tab.document.meta.$slowSave
|
||||
? SLOW_CHANGE_TIMEOUT
|
||||
: CHANGE_TIMEOUT);
|
||||
}, plugin);
|
||||
}, plugin);
|
||||
|
||||
tabs.on("tabDestroy", function(e) {
|
||||
if (!e.tab.path)
|
||||
return;
|
||||
|
||||
if (tabs.getTabs().length == 1)
|
||||
btnSave.hide();
|
||||
|
||||
saveTab(e.tab);
|
||||
}, plugin);
|
||||
|
||||
save.on("beforeWarn", function(e) {
|
||||
if (autosave && !e.tab.document.meta.newfile) {
|
||||
saveTab(e.tab);
|
||||
return false;
|
||||
prefs.add({
|
||||
"File": {
|
||||
position: 150,
|
||||
"Save": {
|
||||
position: 100,
|
||||
"Auto-Save Files": {
|
||||
type: "dropdown",
|
||||
position: 100,
|
||||
path: "user/general/@autosave",
|
||||
width: 130,
|
||||
items: [
|
||||
{ caption: "Off", value: false },
|
||||
{ caption: "On Focus Change", value: "onFocusChange" },
|
||||
{ caption: "After Delay", value: "afterDelay" },
|
||||
],
|
||||
}
|
||||
}
|
||||
}
|
||||
}, plugin);
|
||||
|
||||
settings.setDefaults("user/general", [["autosave", false]]);
|
||||
settings.on("read", onSettingChange, plugin);
|
||||
settings.on("user/general", onSettingChange, plugin);
|
||||
save.on("beforeWarn", function(e) {
|
||||
if (autosave && saveTab(e.tab))
|
||||
return false;
|
||||
}, plugin);
|
||||
}
|
||||
|
||||
function transformButton() {
|
||||
if (!btnSave) return;
|
||||
if (btnSave.autosave === autosave) return;
|
||||
function onSettingChange() {
|
||||
autosave = settings.get("user/general/@autosave");
|
||||
if (autosave == "off" || autosave == "false")
|
||||
autosave = false;
|
||||
|
||||
if (autosave) {
|
||||
btnSave.setAttribute("caption", "");
|
||||
btnSave.setAttribute("margin", "0 20");
|
||||
btnSave.removeAttribute("tooltip");
|
||||
btnSave.removeAttribute("command");
|
||||
apf.setStyleClass(btnSave.$ext, "btnSave");
|
||||
|
||||
tooltip.add(btnSave, {
|
||||
message: "Changes to your file are automatically saved.<br />\
|
||||
View all your changes through <a href='javascript:void(0)' \
|
||||
onclick='require(\"ext/revisions/revisions\").toggle();' \
|
||||
class='revisionsInfoLink'>the Revision History pane</a>. \
|
||||
Rollback to a previous state, or make comparisons.",
|
||||
width: "250px",
|
||||
hideonclick: true
|
||||
}, plugin);
|
||||
}
|
||||
else {
|
||||
|
||||
}
|
||||
|
||||
btnSave.autosave = autosave;
|
||||
disable();
|
||||
if (autosave == "afterDelay")
|
||||
enableDelay();
|
||||
if (autosave)
|
||||
enable();
|
||||
}
|
||||
|
||||
function check() {
|
||||
if (!autosave) return;
|
||||
|
||||
var pages = tabs.getTabs();
|
||||
for (var tab, i = 0, l = pages.length; i < l; i++) {
|
||||
if ((tab = pages[i]).document.changed && tab.path)
|
||||
|
||||
function enableDelay() {
|
||||
saveWhenIdle = lang.delayedCall(function() {
|
||||
var tab = tabs.focussedTab;
|
||||
var ace = tab && tab.editor && tab.editor.ace;
|
||||
if (ace && ace.session && sessionId == ace.session.id) {
|
||||
saveTab(tab);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function enable() {
|
||||
apf.on("movefocus", scheduleCheck);
|
||||
tabs.on("tabAfterActivate", scheduleCheck, plugin);
|
||||
if (saveWhenIdle)
|
||||
tabs.on("focusSync", attachToTab, plugin);
|
||||
window.addEventListener("blur", scheduleCheck);
|
||||
}
|
||||
|
||||
function disable() {
|
||||
sessionId = null;
|
||||
if (saveWhenIdle) {
|
||||
saveWhenIdle.cancel();
|
||||
saveWhenIdle = null;
|
||||
}
|
||||
if (docChangeTimeout) {
|
||||
clearTimeout(docChangeTimeout);
|
||||
docChangeTimeout = null;
|
||||
}
|
||||
apf.off("movefocus", scheduleCheck);
|
||||
tabs.off("tabAfterActivate", scheduleCheck);
|
||||
tabs.off("focusSync", attachToTab);
|
||||
window.removeEventListener("blur", scheduleCheck);
|
||||
}
|
||||
|
||||
function attachToTab(e) {
|
||||
var ace = e.tab && e.tab.editor && e.tab.editor.ace;
|
||||
if (ace)
|
||||
ace.on("beforeEndOperation", beforeEndOperation);
|
||||
}
|
||||
|
||||
function beforeEndOperation(e, ace) {
|
||||
if (!saveWhenIdle)
|
||||
return ace.off("beforeEndOperation", beforeEndOperation);
|
||||
if (!ace.isFocused() && !options.ignoreFocusForTesting)
|
||||
return;
|
||||
sessionId = ace.session.id;
|
||||
if (sessionId && ace.curOp.docChanged && ace.curOp.command.name) {
|
||||
var timeout = Math.min(Math.max(CHANGE_TIMEOUT, lastSaveTime || 0), SLOW_CHANGE_TIMEOUT);
|
||||
saveWhenIdle.delay(timeout);
|
||||
}
|
||||
}
|
||||
|
||||
function scheduleCheck(e) {
|
||||
if (docChangeTimeout)
|
||||
return;
|
||||
var tab;
|
||||
var fromElement = e.fromElement;
|
||||
var toElement = e.toElement;
|
||||
if (e.type == "blur") {
|
||||
tab = tabs.focussedTab;
|
||||
}
|
||||
else if (fromElement) {
|
||||
var fakePage = fromElement.$fake;
|
||||
if (toElement && (toElement == fakePage || fromElement == toElement.$fake)) {
|
||||
fakePage = fromElement.$prevFake || toElement.$prevFake;
|
||||
if (fakePage)
|
||||
return;
|
||||
}
|
||||
|
||||
tab = fromElement.cloud9tab || fakePage && fakePage.cloud9tab;
|
||||
if (!tab || !tab.path)
|
||||
return;
|
||||
while (toElement) {
|
||||
if (/window|menu|item/.test(toElement.localName))
|
||||
return;
|
||||
toElement = toElement.parentNode;
|
||||
}
|
||||
}
|
||||
else if (e.lastTab) {
|
||||
tab = e.lastTab;
|
||||
}
|
||||
if (!tab || !tab.path)
|
||||
return;
|
||||
|
||||
docChangeTimeout = setTimeout(function() {
|
||||
docChangeTimeout = null;
|
||||
var activeElement = apf.document.activeElement;
|
||||
var nodeName = activeElement && activeElement.localName;
|
||||
if (nodeName === "page" && tabs.focussedTab && tabs.focussedTab.path === tab.path)
|
||||
return;
|
||||
saveTab(tab);
|
||||
});
|
||||
}
|
||||
|
||||
function saveTab(tab, force) {
|
||||
if (!autosave) return;
|
||||
|
||||
if (!c9.has(c9.STORAGE)) {
|
||||
save.setSavingState(tab, "offline");
|
||||
return;
|
||||
}
|
||||
|
||||
var doc;
|
||||
if (!force && (!tab.path
|
||||
|| !(doc = tab.document).changed
|
||||
|| doc.meta.newfile
|
||||
|| doc.meta.nofs
|
||||
|| doc.meta.error
|
||||
|| doc.meta.$saving))
|
||||
|| doc.meta.$saving
|
||||
|| doc.meta.preview
|
||||
|| !doc.hasValue()))
|
||||
return;
|
||||
|
||||
var value = doc.value;
|
||||
var slow = value.length > SLOW_SAVE_THRESHOLD;
|
||||
if (slow && !doc.meta.$slowSave) {
|
||||
doc.meta.$slowSave = true;
|
||||
|
||||
if (!c9.has(c9.STORAGE)) {
|
||||
save.setSavingState(tab, "offline");
|
||||
return;
|
||||
}
|
||||
doc.meta.$slowSave = slow;
|
||||
|
||||
|
||||
var t = Date.now();
|
||||
save.save(tab, {
|
||||
silentsave: true,
|
||||
timeout: 1,
|
||||
value: value
|
||||
}, function() {});
|
||||
noUi: true,
|
||||
}, function() {
|
||||
lastSaveTime = t - Date.now();
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
plugin.on("load", function() {
|
||||
load();
|
||||
});
|
||||
plugin.on("enable", function() {
|
||||
autosave = true;
|
||||
transformButton();
|
||||
});
|
||||
plugin.on("disable", function() {
|
||||
autosave = false;
|
||||
transformButton();
|
||||
});
|
||||
plugin.on("unload", function() {
|
||||
if (saveInterval)
|
||||
clearInterval(saveInterval);
|
||||
|
||||
loaded = false;
|
||||
disable();
|
||||
autosave = false;
|
||||
});
|
||||
plugin.freezePublicAPI({ });
|
||||
|
||||
@ -48278,7 +48317,7 @@ define("plugins/c9.ide.save/save",[], function(require, exports, module) {
|
||||
doc.meta.$saveBuffer = true;
|
||||
}
|
||||
|
||||
setSavingState(tab, "saving");
|
||||
setSavingState(tab, "saving", null, options.noUi);
|
||||
|
||||
var bookmark = doc.undoManager.position;
|
||||
var loadStartT = Date.now();
|
||||
@ -48316,7 +48355,7 @@ define("plugins/c9.ide.save/save",[], function(require, exports, module) {
|
||||
if (options.path)
|
||||
tab.path = options.path;
|
||||
|
||||
setSavingState(tab, "saved", options.timeout);
|
||||
setSavingState(tab, "saved", options.timeout, options.noUi);
|
||||
settings.save();
|
||||
logger.log("Successfully saved " + path);
|
||||
}
|
||||
@ -48403,7 +48442,7 @@ define("plugins/c9.ide.save/save",[], function(require, exports, module) {
|
||||
}
|
||||
|
||||
var stateTimer = null, pageTimers = {};
|
||||
function setSavingState(tab, state, timeout) {
|
||||
function setSavingState(tab, state, timeout, silent) {
|
||||
clearTimeout(stateTimer);
|
||||
clearTimeout(pageTimers[tab.name]);
|
||||
|
||||
@ -48416,6 +48455,12 @@ define("plugins/c9.ide.save/save",[], function(require, exports, module) {
|
||||
else
|
||||
delete doc.meta.$saving;
|
||||
|
||||
if (!silent)
|
||||
updateSavingUi();
|
||||
emit("tabSavingState", { tab: tab });
|
||||
}
|
||||
|
||||
function updateSavingUi(tab, state, timeout) {
|
||||
if (state == "saving") {
|
||||
btnSave.show();
|
||||
|
||||
@ -48472,7 +48517,6 @@ define("plugins/c9.ide.save/save",[], function(require, exports, module) {
|
||||
btnSave.setCaption("Not saved");
|
||||
tab.classList.add("error");
|
||||
}
|
||||
emit("tabSavingState", { tab: tab });
|
||||
}
|
||||
|
||||
plugin.on("load", function() {
|
||||
@ -115300,6 +115344,7 @@ apf.page = function(struct, tagName) {
|
||||
if (this.relPage) {
|
||||
this.relPage.$ext.style.display = "";
|
||||
this.parentNode.$setStyleClass(this.relPage.$ext, "curpage");
|
||||
this.relPage.$prevFake = this.relPage.$fake;
|
||||
this.relPage.$fake = this;
|
||||
|
||||
|
||||
@ -115500,6 +115545,7 @@ apf.page = function(struct, tagName) {
|
||||
if (page && page.type == _self.id) {
|
||||
page.relPage = _self;
|
||||
if (page.$active) {
|
||||
_self.$prevFake = _self.$fake;
|
||||
_self.$fake = page;
|
||||
page.$activate();
|
||||
}
|
||||
@ -124010,16 +124056,9 @@ apf.window = function(){
|
||||
(apf.window.activeElement = amlNode).focus(true, e);
|
||||
|
||||
this.$settingFocus = null;
|
||||
|
||||
apf.dispatchEvent("movefocus", {
|
||||
toElement: amlNode
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
apf.dispatchEvent("movefocus", e);
|
||||
};
|
||||
|
||||
this.$blur = function(amlNode) {
|
||||
@ -152332,7 +152371,7 @@ define("plugins/c9.ide.editors/tabmanager",[], function(require, module, exports
|
||||
if (!loaded || tab.document.meta.preview)
|
||||
return;
|
||||
|
||||
var lastTab = focussedTab;
|
||||
var lastTab = e.lastTab || focussedTab;
|
||||
|
||||
if (!focussedTab || focussedTab.pane == tab.pane && focussedTab != tab)
|
||||
focusTab(tab, true, true);
|
||||
|
||||
2
lib/tern/node_modules/glob/node_modules/inherits/package.json
generated
vendored
2
lib/tern/node_modules/glob/node_modules/inherits/package.json
generated
vendored
@ -36,7 +36,7 @@
|
||||
"homepage": "https://github.com/isaacs/inherits#readme",
|
||||
"_id": "inherits@2.0.3",
|
||||
"_shasum": "633c2c83e3da42a502f52466022480f4208261de",
|
||||
"_from": "inherits@>=2.0.1 <2.1.0",
|
||||
"_from": "inherits@>=2.0.0 <3.0.0",
|
||||
"_npmVersion": "3.10.7",
|
||||
"_nodeVersion": "6.5.0",
|
||||
"_npmUser": {
|
||||
|
||||
@ -40,7 +40,6 @@
|
||||
"process"
|
||||
]
|
||||
},
|
||||
"gitHead": "39015d544d4c00c7899fea4c95c2e5bc2720e68e",
|
||||
"contributors": [
|
||||
{
|
||||
"name": "List of Tern contributors. Updated before every release."
|
||||
@ -241,6 +240,7 @@
|
||||
"name": "vheon"
|
||||
}
|
||||
],
|
||||
"gitHead": "39015d544d4c00c7899fea4c95c2e5bc2720e68e",
|
||||
"readme": "# Tern\n\n[](http://travis-ci.org/ternjs/tern)\n[](https://www.npmjs.org/package/tern) \n[Funding status: ](https://marijnhaverbeke.nl/fund/)\n\nThis is [Tern][1]. Tern is a stand-alone, editor-independent\nJavaScript analyzer that can be used to improve the JavaScript\nintegration of existing editors.\n\nThanks to a group of generous [crowd funders][2], Tern is open-source\nsoftware, under an MIT license.\n\nThere are currently plugins available for [Emacs][emacs] (and Emacs\n[company-mode][cmode]), [Vim][vim], [Sublime Text][st], [Eclipse (and general Java API)][ec],\n[Light Table][lt], [Atom][atom] and [gedit][gedit], and built-in support in\n[Brackets][brackets], [Edge Code][edge_code], and [CodeLite](http://codelite.org/).\n\nFor further documentation, see the [project page][1] and the\n[manual][3]. To report issues, use the\n[issue tracker](https://github.com/ternjs/tern/issues). For questions\nand documentation, see the\n[discussion forum](https://discuss.ternjs.net).\n\n[1]: http://ternjs.net\n[2]: http://www.indiegogo.com/projects/tern-intelligent-javascript-editing\n[3]: http://ternjs.net/doc/manual.html\n\n[emacs]: http://ternjs.net/doc/manual.html#emacs\n[ec]: https://github.com/angelozerr/tern.java\n[vim]: https://github.com/ternjs/tern_for_vim\n[st]: https://github.com/ternjs/tern_for_sublime\n[lt]: https://github.com/mortalapeman/LT-TernJS\n[atom]: https://atom.io/packages/atom-ternjs\n[gedit]: https://github.com/Swatinem/tern_for_gedit\n[brackets]: http://brackets.io\n[edge_code]: http://html.adobe.com/edge/code\n[cmode]: https://github.com/proofit404/company-tern\n",
|
||||
"readmeFilename": "README.md",
|
||||
"bugs": {
|
||||
@ -248,7 +248,7 @@
|
||||
},
|
||||
"homepage": "https://github.com/ternjs/tern#readme",
|
||||
"_id": "tern@0.16.1",
|
||||
"_shasum": "c89ccea2e756f052a4b28e08f67277d846983496",
|
||||
"_shasum": "e899f56ba505124cce3310ceb8414d5f1583ab38",
|
||||
"_from": "git+https://github.com/cloud9ide/tern.git#39015d544d4c00c7899fea4c95c2e5bc2720e68e",
|
||||
"_resolved": "git+https://github.com/cloud9ide/tern.git#39015d544d4c00c7899fea4c95c2e5bc2720e68e"
|
||||
}
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
"readme": "# tern_from_ts\n\nTern signatures extracted from typescript signatures.\n\nLicense: MIT\n\nSee also https://github.com/marijnh/tern and https://github.com/borisyankov/DefinitelyTyped\n",
|
||||
"readmeFilename": "README.md",
|
||||
"_id": "tern_from_ts@0.0.1",
|
||||
"_shasum": "82c5150f58103432eaaa6aadd3ecfad8331aad56",
|
||||
"_shasum": "1fed17d49d8aecdfbd1bfe4a05256105910b00b2",
|
||||
"_from": "git+https://github.com/cloud9ide/tern_from_ts.git#66df507986bbdd63f3bc4f0c53edb39169ce4f1c",
|
||||
"_resolved": "git+https://github.com/cloud9ide/tern_from_ts.git#66df507986bbdd63f3bc4f0c53edb39169ce4f1c"
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -58,5 +58,6 @@
|
||||
"tmp": "tmp/inherits-2.0.3.tgz_1473295776489_0.08142363070510328"
|
||||
},
|
||||
"directories": {},
|
||||
"_resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz"
|
||||
"_resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||
"readme": "ERROR: No README data found!"
|
||||
}
|
||||
|
||||
3
node_modules/less/node_modules/mkdirp/node_modules/minimist/package.json
generated
vendored
3
node_modules/less/node_modules/mkdirp/node_modules/minimist/package.json
generated
vendored
@ -62,6 +62,5 @@
|
||||
],
|
||||
"directories": {},
|
||||
"_shasum": "857fcabfc3397d2625b8228262e86aa7a011b05d",
|
||||
"_resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
|
||||
"readme": "ERROR: No README data found!"
|
||||
"_resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz"
|
||||
}
|
||||
|
||||
3
node_modules/less/node_modules/mkdirp/package.json
generated
vendored
3
node_modules/less/node_modules/mkdirp/package.json
generated
vendored
@ -55,6 +55,5 @@
|
||||
}
|
||||
],
|
||||
"directories": {},
|
||||
"_resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
|
||||
"readme": "ERROR: No README data found!"
|
||||
"_resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz"
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env node
|
||||
// -*- mode: js -*-
|
||||
// vim: set filetype=javascript :
|
||||
// Copyright 2015 Joyent, Inc. All rights reserved.
|
||||
// Copyright 2015 Joyent, Inc. All rights reserved.
|
||||
|
||||
var dashdash = require('dashdash');
|
||||
var sshpk = require('../lib/index');
|
||||
@ -76,11 +76,12 @@ if (require.main === module) {
|
||||
console.error('sshpk-conv: converts between SSH key formats\n');
|
||||
console.error(help);
|
||||
console.error('\navailable formats:');
|
||||
console.error(' - pem, pkcs1 eg id_rsa');
|
||||
console.error(' - ssh eg id_rsa.pub');
|
||||
console.error(' - pkcs8 format you want for openssl');
|
||||
console.error(' - openssh like output of ssh-keygen -o');
|
||||
console.error(' - rfc4253 raw OpenSSH wire format');
|
||||
console.error(' - pem, pkcs1 eg id_rsa');
|
||||
console.error(' - ssh eg id_rsa.pub');
|
||||
console.error(' - pkcs8 format you want for openssl');
|
||||
console.error(' - openssh like output of ssh-keygen -o');
|
||||
console.error(' - rfc4253 raw OpenSSH wire format');
|
||||
console.error(' - dnssec dnssec-keygen format');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
|
||||
@ -14,9 +14,8 @@ var algInfo = {
|
||||
sizePart: 'Q'
|
||||
},
|
||||
'ed25519': {
|
||||
parts: ['R'],
|
||||
normalize: false,
|
||||
sizePart: 'R'
|
||||
parts: ['A'],
|
||||
sizePart: 'A'
|
||||
}
|
||||
};
|
||||
algInfo['curve25519'] = algInfo['ed25519'];
|
||||
@ -32,8 +31,7 @@ var algPrivInfo = {
|
||||
parts: ['curve', 'Q', 'd']
|
||||
},
|
||||
'ed25519': {
|
||||
parts: ['R', 'r'],
|
||||
normalize: false
|
||||
parts: ['A', 'k']
|
||||
}
|
||||
};
|
||||
algPrivInfo['curve25519'] = algPrivInfo['ed25519'];
|
||||
|
||||
@ -79,7 +79,8 @@ function DiffieHellman(key) {
|
||||
nacl = require('tweetnacl');
|
||||
|
||||
if (this._isPriv) {
|
||||
this._priv = key.part.r.data;
|
||||
utils.assertCompatible(key, PrivateKey, [1, 5], 'key');
|
||||
this._priv = key.part.k.data;
|
||||
}
|
||||
|
||||
} else {
|
||||
@ -143,7 +144,10 @@ DiffieHellman.prototype.setKey = function (pk) {
|
||||
}
|
||||
|
||||
} else if (pk.type === 'curve25519') {
|
||||
this._priv = pk.part.r.data;
|
||||
var k = pk.part.k;
|
||||
if (!pk.part.k)
|
||||
k = pk.part.r;
|
||||
this._priv = k.data;
|
||||
if (this._priv[0] === 0x00)
|
||||
this._priv = this._priv.slice(1);
|
||||
this._priv = this._priv.slice(0, 32);
|
||||
@ -175,13 +179,12 @@ DiffieHellman.prototype.computeSecret = function (otherpk) {
|
||||
}
|
||||
|
||||
} else if (this._algo === 'curve25519') {
|
||||
pub = otherpk.part.R.data;
|
||||
pub = otherpk.part.A.data;
|
||||
while (pub[0] === 0x00 && pub.length > 32)
|
||||
pub = pub.slice(1);
|
||||
var priv = this._priv;
|
||||
assert.strictEqual(pub.length, 32);
|
||||
assert.strictEqual(this._priv.length, 64);
|
||||
|
||||
var priv = this._priv.slice(0, 32);
|
||||
assert.strictEqual(priv.length, 32);
|
||||
|
||||
var secret = nacl.box.before(new Uint8Array(pub),
|
||||
new Uint8Array(priv));
|
||||
@ -261,8 +264,8 @@ DiffieHellman.prototype.generateKey = function () {
|
||||
assert.strictEqual(priv.length, 64);
|
||||
assert.strictEqual(pub.length, 32);
|
||||
|
||||
parts.push({name: 'R', data: pub});
|
||||
parts.push({name: 'r', data: priv});
|
||||
parts.push({name: 'A', data: pub});
|
||||
parts.push({name: 'k', data: priv});
|
||||
this._key = new PrivateKey({
|
||||
type: 'curve25519',
|
||||
parts: parts
|
||||
@ -327,8 +330,8 @@ function generateED25519() {
|
||||
assert.strictEqual(pub.length, 32);
|
||||
|
||||
var parts = [];
|
||||
parts.push({name: 'R', data: pub});
|
||||
parts.push({name: 'r', data: priv});
|
||||
parts.push({name: 'A', data: pub});
|
||||
parts.push({name: 'k', data: priv.slice(0, 32)});
|
||||
var key = new PrivateKey({
|
||||
type: 'ed25519',
|
||||
parts: parts
|
||||
@ -369,7 +372,6 @@ function generateECDSA(curve) {
|
||||
parts: parts
|
||||
});
|
||||
return (key);
|
||||
|
||||
} else {
|
||||
if (ecdh === undefined)
|
||||
ecdh = require('ecc-jsbn');
|
||||
|
||||
@ -56,7 +56,7 @@ Verifier.prototype.verify = function (signature, fmt) {
|
||||
return (nacl.sign.detached.verify(
|
||||
new Uint8Array(Buffer.concat(this.chunks)),
|
||||
new Uint8Array(sig),
|
||||
new Uint8Array(this.key.part.R.data)));
|
||||
new Uint8Array(this.key.part.A.data)));
|
||||
};
|
||||
|
||||
function Signer(key, hashAlgo) {
|
||||
@ -88,7 +88,8 @@ Signer.prototype.update = function (chunk) {
|
||||
Signer.prototype.sign = function () {
|
||||
var sig = nacl.sign.detached(
|
||||
new Uint8Array(Buffer.concat(this.chunks)),
|
||||
new Uint8Array(this.key.part.r.data));
|
||||
new Uint8Array(Buffer.concat([
|
||||
this.key.part.k.data, this.key.part.A.data])));
|
||||
var sigBuf = new Buffer(sig);
|
||||
var sigObj = Signature.parse(sigBuf, 'ed25519', 'raw');
|
||||
sigObj.hashAlgorithm = 'sha512';
|
||||
|
||||
@ -13,6 +13,9 @@ var PrivateKey = require('../private-key');
|
||||
var pem = require('./pem');
|
||||
var ssh = require('./ssh');
|
||||
var rfc4253 = require('./rfc4253');
|
||||
var dnssec = require('./dnssec');
|
||||
|
||||
var DNSSEC_PRIVKEY_HEADER_PREFIX = 'Private-key-format: v1';
|
||||
|
||||
function read(buf, options) {
|
||||
if (typeof (buf) === 'string') {
|
||||
@ -22,6 +25,8 @@ function read(buf, options) {
|
||||
return (ssh.read(buf, options));
|
||||
if (buf.match(/^\s*ecdsa-/))
|
||||
return (ssh.read(buf, options));
|
||||
if (findDNSSECHeader(buf))
|
||||
return (dnssec.read(buf, options));
|
||||
buf = new Buffer(buf, 'binary');
|
||||
} else {
|
||||
assert.buffer(buf);
|
||||
@ -29,6 +34,8 @@ function read(buf, options) {
|
||||
return (pem.read(buf, options));
|
||||
if (findSSHHeader(buf))
|
||||
return (ssh.read(buf, options));
|
||||
if (findDNSSECHeader(buf))
|
||||
return (dnssec.read(buf, options));
|
||||
}
|
||||
if (buf.readUInt32BE(0) < buf.length)
|
||||
return (rfc4253.read(buf, options));
|
||||
@ -68,6 +75,32 @@ function findPEMHeader(buf) {
|
||||
return (true);
|
||||
}
|
||||
|
||||
function findDNSSECHeader(buf) {
|
||||
// private case first
|
||||
if (buf.length <= DNSSEC_PRIVKEY_HEADER_PREFIX.length)
|
||||
return (false);
|
||||
var headerCheck = buf.slice(0, DNSSEC_PRIVKEY_HEADER_PREFIX.length);
|
||||
if (headerCheck.toString('ascii') === DNSSEC_PRIVKEY_HEADER_PREFIX)
|
||||
return (true);
|
||||
|
||||
// public-key RFC3110 ?
|
||||
// 'domain.com. IN KEY ...' or 'domain.com. IN DNSKEY ...'
|
||||
// skip any comment-lines
|
||||
if (typeof (buf) !== 'string') {
|
||||
buf = buf.toString('ascii');
|
||||
}
|
||||
var lines = buf.split('\n');
|
||||
var line = 0;
|
||||
/* JSSTYLED */
|
||||
while (lines[line].match(/^\;/))
|
||||
line++;
|
||||
if (lines[line].toString('ascii').match(/\. IN KEY /))
|
||||
return (true);
|
||||
if (lines[line].toString('ascii').match(/\. IN DNSKEY /))
|
||||
return (true);
|
||||
return (false);
|
||||
}
|
||||
|
||||
function write(key, options) {
|
||||
throw (new Error('"auto" format cannot be used for writing'));
|
||||
}
|
||||
|
||||
286
node_modules/less/node_modules/request/node_modules/http-signature/node_modules/sshpk/lib/formats/dnssec.js
generated
vendored
Normal file
286
node_modules/less/node_modules/request/node_modules/http-signature/node_modules/sshpk/lib/formats/dnssec.js
generated
vendored
Normal file
@ -0,0 +1,286 @@
|
||||
// Copyright 2017 Joyent, Inc.
|
||||
|
||||
module.exports = {
|
||||
read: read,
|
||||
write: write
|
||||
};
|
||||
|
||||
var assert = require('assert-plus');
|
||||
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 = new Buffer(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: new Buffer(curve) },
|
||||
{name: 'Q', data: utils.ecNormalize(keyBuffer) }
|
||||
]
|
||||
};
|
||||
return (new Key(ecdsaKey));
|
||||
}
|
||||
throw (new Error('Unsupported algorithm: ' +
|
||||
supportedAlgosById[algorithm]));
|
||||
}
|
||||
|
||||
function elementToBuf(e) {
|
||||
return (new Buffer(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 = new Buffer(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: new Buffer(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 (new Buffer(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 (new Buffer(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'));
|
||||
}
|
||||
}
|
||||
@ -34,11 +34,11 @@ function read(buf, options, forceType) {
|
||||
var lines = buf.trim().split('\n');
|
||||
|
||||
var m = lines[0].match(/*JSSTYLED*/
|
||||
/[-]+[ ]*BEGIN ([A-Z0-9]+ )?(PUBLIC|PRIVATE) KEY[ ]*[-]+/);
|
||||
/[-]+[ ]*BEGIN ([A-Z0-9][A-Za-z0-9]+ )?(PUBLIC|PRIVATE) KEY[ ]*[-]+/);
|
||||
assert.ok(m, 'invalid PEM header');
|
||||
|
||||
var m2 = lines[lines.length - 1].match(/*JSSTYLED*/
|
||||
/[-]+[ ]*END ([A-Z0-9]+ )?(PUBLIC|PRIVATE) KEY[ ]*[-]+/);
|
||||
/[-]+[ ]*END ([A-Z0-9][A-Za-z0-9]+ )?(PUBLIC|PRIVATE) KEY[ ]*[-]+/);
|
||||
assert.ok(m2, 'invalid PEM footer');
|
||||
|
||||
/* Begin and end banners must match key type */
|
||||
@ -135,7 +135,12 @@ function read(buf, options, forceType) {
|
||||
function write(key, options, type) {
|
||||
assert.object(key);
|
||||
|
||||
var alg = {'ecdsa': 'EC', 'rsa': 'RSA', 'dsa': 'DSA'}[key.type];
|
||||
var alg = {
|
||||
'ecdsa': 'EC',
|
||||
'rsa': 'RSA',
|
||||
'dsa': 'DSA',
|
||||
'ed25519': 'EdDSA'
|
||||
}[key.type];
|
||||
var header;
|
||||
|
||||
var der = new asn1.BerWriter();
|
||||
|
||||
@ -55,6 +55,11 @@ function readPkcs1(alg, type, der) {
|
||||
else if (type === 'public')
|
||||
return (readPkcs1ECDSAPublic(der));
|
||||
throw (new Error('Unknown key type: ' + type));
|
||||
case 'EDDSA':
|
||||
case 'EdDSA':
|
||||
if (type === 'private')
|
||||
return (readPkcs1EdDSAPrivate(der));
|
||||
throw (new Error(type + ' keys not supported with EdDSA'));
|
||||
default:
|
||||
throw (new Error('Unknown key algo: ' + alg));
|
||||
}
|
||||
@ -134,6 +139,31 @@ function readPkcs1DSAPrivate(der) {
|
||||
return (new PrivateKey(key));
|
||||
}
|
||||
|
||||
function readPkcs1EdDSAPrivate(der) {
|
||||
var version = readMPInt(der, 'version');
|
||||
assert.strictEqual(version.readUInt8(0), 1);
|
||||
|
||||
// private key
|
||||
var k = der.readString(asn1.Ber.OctetString, true);
|
||||
|
||||
der.readSequence(0xa0);
|
||||
var oid = der.readOID();
|
||||
assert.strictEqual(oid, '1.3.101.112', 'the ed25519 curve identifier');
|
||||
|
||||
der.readSequence(0xa1);
|
||||
var A = utils.readBitString(der);
|
||||
|
||||
var key = {
|
||||
type: 'ed25519',
|
||||
parts: [
|
||||
{ name: 'A', data: utils.zeroPadToLength(A, 32) },
|
||||
{ name: 'k', data: k }
|
||||
]
|
||||
};
|
||||
|
||||
return (new PrivateKey(key));
|
||||
}
|
||||
|
||||
function readPkcs1DSAPublic(der) {
|
||||
var y = readMPInt(der, 'y');
|
||||
var p = readMPInt(der, 'p');
|
||||
@ -236,6 +266,12 @@ function writePkcs1(der, key) {
|
||||
else
|
||||
writePkcs1ECDSAPublic(der, key);
|
||||
break;
|
||||
case 'ed25519':
|
||||
if (PrivateKey.isPrivateKey(key))
|
||||
writePkcs1EdDSAPrivate(der, key);
|
||||
else
|
||||
writePkcs1EdDSAPublic(der, key);
|
||||
break;
|
||||
default:
|
||||
throw (new Error('Unknown key algo: ' + key.type));
|
||||
}
|
||||
@ -318,3 +354,23 @@ function writePkcs1ECDSAPrivate(der, key) {
|
||||
der.writeBuffer(Q, asn1.Ber.BitString);
|
||||
der.endSequence();
|
||||
}
|
||||
|
||||
function writePkcs1EdDSAPrivate(der, key) {
|
||||
var ver = new Buffer(1);
|
||||
ver[0] = 1;
|
||||
der.writeBuffer(ver, asn1.Ber.Integer);
|
||||
|
||||
der.writeBuffer(key.part.k.data, asn1.Ber.OctetString);
|
||||
|
||||
der.startSequence(0xa0);
|
||||
der.writeOID('1.3.101.112');
|
||||
der.endSequence();
|
||||
|
||||
der.startSequence(0xa1);
|
||||
utils.writeBitString(der, key.part.A.data);
|
||||
der.endSequence();
|
||||
}
|
||||
|
||||
function writePkcs1EdDSAPublic(der, key) {
|
||||
throw (new Error('Public keys are not supported for EdDSA PKCS#1'));
|
||||
}
|
||||
|
||||
@ -62,6 +62,18 @@ function readPkcs8(alg, type, der) {
|
||||
return (readPkcs8ECDSAPublic(der));
|
||||
else
|
||||
return (readPkcs8ECDSAPrivate(der));
|
||||
case '1.3.101.112':
|
||||
if (type === 'public') {
|
||||
return (readPkcs8EdDSAPublic(der));
|
||||
} else {
|
||||
return (readPkcs8EdDSAPrivate(der));
|
||||
}
|
||||
case '1.3.101.110':
|
||||
if (type === 'public') {
|
||||
return (readPkcs8X25519Public(der));
|
||||
} else {
|
||||
return (readPkcs8X25519Private(der));
|
||||
}
|
||||
default:
|
||||
throw (new Error('Unknown key type OID ' + oid));
|
||||
}
|
||||
@ -322,6 +334,83 @@ function readPkcs8ECDSAPublic(der) {
|
||||
return (new Key(key));
|
||||
}
|
||||
|
||||
function readPkcs8EdDSAPublic(der) {
|
||||
if (der.peek() === 0x00)
|
||||
der.readByte();
|
||||
|
||||
var A = utils.readBitString(der);
|
||||
|
||||
var key = {
|
||||
type: 'ed25519',
|
||||
parts: [
|
||||
{ name: 'A', data: utils.zeroPadToLength(A, 32) }
|
||||
]
|
||||
};
|
||||
|
||||
return (new Key(key));
|
||||
}
|
||||
|
||||
function readPkcs8X25519Public(der) {
|
||||
var A = utils.readBitString(der);
|
||||
|
||||
var key = {
|
||||
type: 'curve25519',
|
||||
parts: [
|
||||
{ name: 'A', data: utils.zeroPadToLength(A, 32) }
|
||||
]
|
||||
};
|
||||
|
||||
return (new Key(key));
|
||||
}
|
||||
|
||||
function readPkcs8EdDSAPrivate(der) {
|
||||
if (der.peek() === 0x00)
|
||||
der.readByte();
|
||||
|
||||
der.readSequence(asn1.Ber.OctetString);
|
||||
var k = der.readString(asn1.Ber.OctetString, true);
|
||||
k = utils.zeroPadToLength(k, 32);
|
||||
|
||||
var A;
|
||||
if (der.peek() === asn1.Ber.BitString) {
|
||||
A = utils.readBitString(der);
|
||||
A = utils.zeroPadToLength(A, 32);
|
||||
} else {
|
||||
A = utils.calculateED25519Public(k);
|
||||
}
|
||||
|
||||
var key = {
|
||||
type: 'ed25519',
|
||||
parts: [
|
||||
{ name: 'A', data: utils.zeroPadToLength(A, 32) },
|
||||
{ name: 'k', data: utils.zeroPadToLength(k, 32) }
|
||||
]
|
||||
};
|
||||
|
||||
return (new PrivateKey(key));
|
||||
}
|
||||
|
||||
function readPkcs8X25519Private(der) {
|
||||
if (der.peek() === 0x00)
|
||||
der.readByte();
|
||||
|
||||
der.readSequence(asn1.Ber.OctetString);
|
||||
var k = der.readString(asn1.Ber.OctetString, true);
|
||||
k = utils.zeroPadToLength(k, 32);
|
||||
|
||||
var A = utils.calculateX25519Public(k);
|
||||
|
||||
var key = {
|
||||
type: 'curve25519',
|
||||
parts: [
|
||||
{ name: 'A', data: utils.zeroPadToLength(A, 32) },
|
||||
{ name: 'k', data: utils.zeroPadToLength(k, 32) }
|
||||
]
|
||||
};
|
||||
|
||||
return (new PrivateKey(key));
|
||||
}
|
||||
|
||||
function writePkcs8(der, key) {
|
||||
der.startSequence();
|
||||
|
||||
@ -354,6 +443,13 @@ function writePkcs8(der, key) {
|
||||
else
|
||||
writePkcs8ECDSAPublic(key, der);
|
||||
break;
|
||||
case 'ed25519':
|
||||
der.writeOID('1.3.101.112');
|
||||
if (PrivateKey.isPrivateKey(key))
|
||||
throw (new Error('Ed25519 private keys in pkcs8 ' +
|
||||
'format are not supported'));
|
||||
writePkcs8EdDSAPublic(key, der);
|
||||
break;
|
||||
default:
|
||||
throw (new Error('Unsupported key type: ' + key.type));
|
||||
}
|
||||
@ -503,3 +599,18 @@ function writePkcs8ECDSAPrivate(key, der) {
|
||||
der.endSequence();
|
||||
der.endSequence();
|
||||
}
|
||||
|
||||
function writePkcs8EdDSAPublic(key, der) {
|
||||
der.endSequence();
|
||||
|
||||
utils.writeBitString(der, key.part.A.data);
|
||||
}
|
||||
|
||||
function writePkcs8EdDSAPrivate(key, der) {
|
||||
der.endSequence();
|
||||
|
||||
var k = utils.mpNormalize(key.part.k.data, true);
|
||||
der.startSequence(asn1.Ber.OctetString);
|
||||
der.writeBuffer(k, asn1.Ber.OctetString);
|
||||
der.endSequence();
|
||||
}
|
||||
|
||||
@ -97,12 +97,25 @@ function read(partial, type, buf, options) {
|
||||
|
||||
var normalized = true;
|
||||
for (var i = 0; i < algInfo.parts.length; ++i) {
|
||||
parts[i].name = algInfo.parts[i];
|
||||
if (parts[i].name !== 'curve' &&
|
||||
algInfo.normalize !== false) {
|
||||
var p = parts[i];
|
||||
var nd = utils.mpNormalize(p.data);
|
||||
if (nd !== p.data) {
|
||||
var p = parts[i];
|
||||
p.name = algInfo.parts[i];
|
||||
/*
|
||||
* OpenSSH stores ed25519 "private" keys as seed + public key
|
||||
* concat'd together (k followed by A). We want to keep them
|
||||
* separate for other formats that don't do this.
|
||||
*/
|
||||
if (key.type === 'ed25519' && p.name === 'k')
|
||||
p.data = p.data.slice(0, 32);
|
||||
|
||||
if (p.name !== 'curve' && algInfo.normalize !== false) {
|
||||
var nd;
|
||||
if (key.type === 'ed25519') {
|
||||
nd = utils.zeroPadToLength(p.data, 32);
|
||||
} else {
|
||||
nd = utils.mpNormalize(p.data);
|
||||
}
|
||||
if (nd.toString('binary') !==
|
||||
p.data.toString('binary')) {
|
||||
p.data = nd;
|
||||
normalized = false;
|
||||
}
|
||||
@ -137,8 +150,14 @@ function write(key, options) {
|
||||
|
||||
for (i = 0; i < parts.length; ++i) {
|
||||
var data = key.part[parts[i]].data;
|
||||
if (algInfo.normalize !== false)
|
||||
data = utils.mpNormalize(data);
|
||||
if (algInfo.normalize !== false) {
|
||||
if (key.type === 'ed25519')
|
||||
data = utils.zeroPadToLength(data, 32);
|
||||
else
|
||||
data = utils.mpNormalize(data);
|
||||
}
|
||||
if (key.type === 'ed25519' && parts[i] === 'k')
|
||||
data = Buffer.concat([data, key.part.A.data]);
|
||||
buf.writeBuffer(data);
|
||||
}
|
||||
|
||||
|
||||
@ -14,9 +14,9 @@ var PrivateKey = require('../private-key');
|
||||
var sshpriv = require('./ssh-private');
|
||||
|
||||
/*JSSTYLED*/
|
||||
var SSHKEY_RE = /^([a-z0-9-]+)[ \t]+([a-zA-Z0-9+\/]+[=]*)([\n \t]+([^\n]+))?$/;
|
||||
var SSHKEY_RE = /^([a-z0-9-]+)[ \t]+([a-zA-Z0-9+\/]+[=]*)([ \t]+([^ \t][^\n]*[\n]*)?)?$/;
|
||||
/*JSSTYLED*/
|
||||
var SSHKEY_RE2 = /^([a-z0-9-]+)[ \t]+([a-zA-Z0-9+\/ \t\n]+[=]*)(.*)$/;
|
||||
var SSHKEY_RE2 = /^([a-z0-9-]+)[ \t\n]+([a-zA-Z0-9+\/][a-zA-Z0-9+\/ \t\n=]*)([^a-zA-Z0-9+\/ \t\n=].*)?$/;
|
||||
|
||||
function read(buf, options) {
|
||||
if (typeof (buf) !== 'string') {
|
||||
@ -71,7 +71,7 @@ function read(buf, options) {
|
||||
* chars from the beginning up to this point in the the string.
|
||||
* Then offset in this and try to make up for missing = chars.
|
||||
*/
|
||||
var data = m[2] + m[3];
|
||||
var data = m[2] + (m[3] ? m[3] : '');
|
||||
var realOffset = Math.ceil(ret.consumed / 3) * 4;
|
||||
data = data.slice(0, realOffset - 2). /*JSSTYLED*/
|
||||
replace(/[^a-zA-Z0-9+\/=]/g, '') +
|
||||
|
||||
@ -70,7 +70,8 @@ var SIGN_ALGS = {
|
||||
'ecdsa-sha1': '1.2.840.10045.4.1',
|
||||
'ecdsa-sha256': '1.2.840.10045.4.3.2',
|
||||
'ecdsa-sha384': '1.2.840.10045.4.3.3',
|
||||
'ecdsa-sha512': '1.2.840.10045.4.3.4'
|
||||
'ecdsa-sha512': '1.2.840.10045.4.3.4',
|
||||
'ed25519-sha512': '1.3.101.112'
|
||||
};
|
||||
Object.keys(SIGN_ALGS).forEach(function (k) {
|
||||
SIGN_ALGS[SIGN_ALGS[k]] = k;
|
||||
@ -522,6 +523,8 @@ function writeTBSCert(cert, der) {
|
||||
|
||||
der.startSequence();
|
||||
der.writeOID(SIGN_ALGS[sig.algo]);
|
||||
if (sig.algo.match(/^rsa-/))
|
||||
der.writeNull();
|
||||
der.endSequence();
|
||||
|
||||
cert.issuer.toAsn1(der);
|
||||
|
||||
@ -136,14 +136,25 @@ Identity.prototype.toAsn1 = function (der, tag) {
|
||||
/*
|
||||
* If we fit in a PrintableString, use that. Otherwise use an
|
||||
* IA5String or UTF8String.
|
||||
*
|
||||
* If this identity was parsed from a DN, use the ASN.1 types
|
||||
* from the original representation (otherwise this might not
|
||||
* be a full match for the original in some validators).
|
||||
*/
|
||||
if (c.value.match(NOT_IA5)) {
|
||||
if (c.asn1type === asn1.Ber.Utf8String ||
|
||||
c.value.match(NOT_IA5)) {
|
||||
var v = new Buffer(c.value, 'utf8');
|
||||
der.writeBuffer(v, asn1.Ber.Utf8String);
|
||||
} else if (c.value.match(NOT_PRINTABLE)) {
|
||||
|
||||
} else if (c.asn1type === asn1.Ber.IA5String ||
|
||||
c.value.match(NOT_PRINTABLE)) {
|
||||
der.writeString(c.value, asn1.Ber.IA5String);
|
||||
|
||||
} else {
|
||||
der.writeString(c.value, asn1.Ber.PrintableString);
|
||||
var type = asn1.Ber.PrintableString;
|
||||
if (c.asn1type !== undefined)
|
||||
type = c.asn1type;
|
||||
der.writeString(c.value, type);
|
||||
}
|
||||
der.endSequence();
|
||||
der.endSequence();
|
||||
@ -253,7 +264,7 @@ Identity.parseAsn1 = function (der, top) {
|
||||
default:
|
||||
throw (new Error('Unknown asn1 type ' + type));
|
||||
}
|
||||
components.push({ oid: oid, value: value });
|
||||
components.push({ oid: oid, asn1type: type, value: value });
|
||||
der._offset = after;
|
||||
}
|
||||
der._offset = end;
|
||||
|
||||
@ -31,6 +31,7 @@ formats['rfc4253'] = require('./formats/rfc4253');
|
||||
formats['ssh'] = require('./formats/ssh');
|
||||
formats['ssh-private'] = require('./formats/ssh-private');
|
||||
formats['openssh'] = formats['ssh-private'];
|
||||
formats['dnssec'] = require('./formats/dnssec');
|
||||
|
||||
function Key(opts) {
|
||||
assert.object(opts, 'options');
|
||||
@ -105,7 +106,6 @@ Key.prototype.hash = function (algo) {
|
||||
|
||||
if (this._hashCache[algo])
|
||||
return (this._hashCache[algo]);
|
||||
|
||||
var hash = crypto.createHash(algo).
|
||||
update(this.toBuffer('rfc4253')).digest();
|
||||
this._hashCache[algo] = hash;
|
||||
@ -256,8 +256,9 @@ Key.isKey = function (obj, ver) {
|
||||
* [1,3] -- added defaultHashAlgorithm
|
||||
* [1,4] -- added ed support, createDH
|
||||
* [1,5] -- first explicitly tagged version
|
||||
* [1,6] -- changed ed25519 part names
|
||||
*/
|
||||
Key.prototype._sshpkApiVersion = [1, 5];
|
||||
Key.prototype._sshpkApiVersion = [1, 6];
|
||||
|
||||
Key._oldVersionDetect = function (obj) {
|
||||
assert.func(obj.toBuffer);
|
||||
|
||||
@ -37,6 +37,7 @@ formats['rfc4253'] = require('./formats/rfc4253');
|
||||
formats['ssh-private'] = require('./formats/ssh-private');
|
||||
formats['openssh'] = formats['ssh-private'];
|
||||
formats['ssh'] = formats['ssh-private'];
|
||||
formats['dnssec'] = require('./formats/dnssec');
|
||||
|
||||
function PrivateKey(opts) {
|
||||
assert.object(opts, 'options');
|
||||
@ -91,40 +92,36 @@ PrivateKey.prototype.derive = function (newType) {
|
||||
if (nacl === undefined)
|
||||
nacl = require('tweetnacl');
|
||||
|
||||
priv = this.part.r.data;
|
||||
priv = this.part.k.data;
|
||||
if (priv[0] === 0x00)
|
||||
priv = priv.slice(1);
|
||||
priv = priv.slice(0, 32);
|
||||
|
||||
pair = nacl.box.keyPair.fromSecretKey(new Uint8Array(priv));
|
||||
pub = new Buffer(pair.publicKey);
|
||||
priv = Buffer.concat([priv, pub]);
|
||||
|
||||
return (new PrivateKey({
|
||||
type: 'curve25519',
|
||||
parts: [
|
||||
{ name: 'R', data: utils.mpNormalize(pub) },
|
||||
{ name: 'r', data: priv }
|
||||
{ name: 'A', data: utils.mpNormalize(pub) },
|
||||
{ name: 'k', data: utils.mpNormalize(priv) }
|
||||
]
|
||||
}));
|
||||
} else if (this.type === 'curve25519' && newType === 'ed25519') {
|
||||
if (nacl === undefined)
|
||||
nacl = require('tweetnacl');
|
||||
|
||||
priv = this.part.r.data;
|
||||
priv = this.part.k.data;
|
||||
if (priv[0] === 0x00)
|
||||
priv = priv.slice(1);
|
||||
priv = priv.slice(0, 32);
|
||||
|
||||
pair = nacl.sign.keyPair.fromSeed(new Uint8Array(priv));
|
||||
pub = new Buffer(pair.publicKey);
|
||||
priv = Buffer.concat([priv, pub]);
|
||||
|
||||
return (new PrivateKey({
|
||||
type: 'ed25519',
|
||||
parts: [
|
||||
{ name: 'R', data: utils.mpNormalize(pub) },
|
||||
{ name: 'r', data: priv }
|
||||
{ name: 'A', data: utils.mpNormalize(pub) },
|
||||
{ name: 'k', data: utils.mpNormalize(priv) }
|
||||
]
|
||||
}));
|
||||
}
|
||||
@ -238,8 +235,9 @@ PrivateKey.generate = function (type, options) {
|
||||
* [1,2] -- added defaultHashAlgorithm
|
||||
* [1,3] -- added derive, ed, createDH
|
||||
* [1,4] -- first tagged version
|
||||
* [1,5] -- changed ed25519 part names and format
|
||||
*/
|
||||
PrivateKey.prototype._sshpkApiVersion = [1, 4];
|
||||
PrivateKey.prototype._sshpkApiVersion = [1, 5];
|
||||
|
||||
PrivateKey._oldVersionDetect = function (obj) {
|
||||
assert.func(obj.toPublic);
|
||||
|
||||
@ -4,18 +4,31 @@ module.exports = {
|
||||
bufferSplit: bufferSplit,
|
||||
addRSAMissing: addRSAMissing,
|
||||
calculateDSAPublic: calculateDSAPublic,
|
||||
calculateED25519Public: calculateED25519Public,
|
||||
calculateX25519Public: calculateX25519Public,
|
||||
mpNormalize: mpNormalize,
|
||||
mpDenormalize: mpDenormalize,
|
||||
ecNormalize: ecNormalize,
|
||||
countZeros: countZeros,
|
||||
assertCompatible: assertCompatible,
|
||||
isCompatible: isCompatible,
|
||||
opensslKeyDeriv: opensslKeyDeriv,
|
||||
opensshCipherInfo: opensshCipherInfo
|
||||
opensshCipherInfo: opensshCipherInfo,
|
||||
publicFromPrivateECDSA: publicFromPrivateECDSA,
|
||||
zeroPadToLength: zeroPadToLength,
|
||||
writeBitString: writeBitString,
|
||||
readBitString: readBitString
|
||||
};
|
||||
|
||||
var assert = require('assert-plus');
|
||||
var PrivateKey = require('./private-key');
|
||||
var Key = require('./key');
|
||||
var crypto = require('crypto');
|
||||
var algs = require('./algs');
|
||||
var asn1 = require('asn1');
|
||||
|
||||
var ec, jsbn;
|
||||
var nacl;
|
||||
|
||||
var MAX_CLASS_DEPTH = 3;
|
||||
|
||||
@ -178,6 +191,24 @@ function ecNormalize(buf, addZero) {
|
||||
return (b);
|
||||
}
|
||||
|
||||
function readBitString(der, tag) {
|
||||
if (tag === undefined)
|
||||
tag = asn1.Ber.BitString;
|
||||
var buf = der.readString(tag, true);
|
||||
assert.strictEqual(buf[0], 0x00, 'bit strings with unused bits are ' +
|
||||
'not supported (0x' + buf[0].toString(16) + ')');
|
||||
return (buf.slice(1));
|
||||
}
|
||||
|
||||
function writeBitString(der, buf, tag) {
|
||||
if (tag === undefined)
|
||||
tag = asn1.Ber.BitString;
|
||||
var b = new Buffer(buf.length + 1);
|
||||
b[0] = 0x00;
|
||||
buf.copy(b, 1);
|
||||
der.writeBuffer(b, tag);
|
||||
}
|
||||
|
||||
function mpNormalize(buf) {
|
||||
assert.buffer(buf);
|
||||
while (buf.length > 1 && buf[0] === 0x00 && (buf[1] & 0x80) === 0x00)
|
||||
@ -191,6 +222,29 @@ function mpNormalize(buf) {
|
||||
return (buf);
|
||||
}
|
||||
|
||||
function mpDenormalize(buf) {
|
||||
assert.buffer(buf);
|
||||
while (buf.length > 1 && buf[0] === 0x00)
|
||||
buf = buf.slice(1);
|
||||
return (buf);
|
||||
}
|
||||
|
||||
function zeroPadToLength(buf, len) {
|
||||
assert.buffer(buf);
|
||||
assert.number(len);
|
||||
while (buf.length > len) {
|
||||
assert.equal(buf[0], 0x00);
|
||||
buf = buf.slice(1);
|
||||
}
|
||||
while (buf.length < len) {
|
||||
var b = new Buffer(buf.length + 1);
|
||||
b[0] = 0x00;
|
||||
buf.copy(b, 1);
|
||||
buf = b;
|
||||
}
|
||||
return (buf);
|
||||
}
|
||||
|
||||
function bigintToMpBuf(bigint) {
|
||||
var buf = new Buffer(bigint.toByteArray());
|
||||
buf = mpNormalize(buf);
|
||||
@ -215,6 +269,26 @@ function calculateDSAPublic(g, p, x) {
|
||||
return (ybuf);
|
||||
}
|
||||
|
||||
function calculateED25519Public(k) {
|
||||
assert.buffer(k);
|
||||
|
||||
if (nacl === undefined)
|
||||
nacl = require('tweetnacl');
|
||||
|
||||
var kp = nacl.sign.keyPair.fromSeed(new Uint8Array(k));
|
||||
return (new Buffer(kp.publicKey));
|
||||
}
|
||||
|
||||
function calculateX25519Public(k) {
|
||||
assert.buffer(k);
|
||||
|
||||
if (nacl === undefined)
|
||||
nacl = require('tweetnacl');
|
||||
|
||||
var kp = nacl.box.keyPair.fromSeed(new Uint8Array(k));
|
||||
return (new Buffer(kp.publicKey));
|
||||
}
|
||||
|
||||
function addRSAMissing(key) {
|
||||
assert.object(key);
|
||||
assertCompatible(key, PrivateKey, [1, 1]);
|
||||
@ -246,6 +320,32 @@ function addRSAMissing(key) {
|
||||
}
|
||||
}
|
||||
|
||||
function publicFromPrivateECDSA(curveName, priv) {
|
||||
assert.string(curveName, 'curveName');
|
||||
assert.buffer(priv);
|
||||
if (ec === undefined)
|
||||
ec = require('ecc-jsbn/lib/ec');
|
||||
if (jsbn === undefined)
|
||||
jsbn = require('jsbn').BigInteger;
|
||||
var params = algs.curves[curveName];
|
||||
var p = new jsbn(params.p);
|
||||
var a = new jsbn(params.a);
|
||||
var b = new jsbn(params.b);
|
||||
var curve = new ec.ECCurveFp(p, a, b);
|
||||
var G = curve.decodePointHex(params.G.toString('hex'));
|
||||
|
||||
var d = new jsbn(mpNormalize(priv));
|
||||
var pub = G.multiply(d);
|
||||
pub = new Buffer(curve.encodePointHex(pub), 'hex');
|
||||
|
||||
var parts = [];
|
||||
parts.push({name: 'curve', data: new Buffer(curveName)});
|
||||
parts.push({name: 'Q', data: pub});
|
||||
|
||||
var key = new Key({type: 'ecdsa', curve: curve, parts: parts});
|
||||
return (key);
|
||||
}
|
||||
|
||||
function opensshCipherInfo(cipher) {
|
||||
var inf = {};
|
||||
switch (cipher) {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "sshpk",
|
||||
"version": "1.13.1",
|
||||
"version": "1.14.1",
|
||||
"description": "A library for finding and using SSH public keys",
|
||||
"main": "lib/index.js",
|
||||
"scripts": {
|
||||
@ -72,9 +72,9 @@
|
||||
"sshpk-sign": "bin/sshpk-sign",
|
||||
"sshpk-verify": "bin/sshpk-verify"
|
||||
},
|
||||
"gitHead": "a17ec8861242649038dcdba8f8d7df5edf2ddb8c",
|
||||
"_id": "sshpk@1.13.1",
|
||||
"_shasum": "512df6da6287144316dc4c18fe1cf1d940739be3",
|
||||
"gitHead": "6edb37cb986b7ddaf0d346440d37287cc059bfee",
|
||||
"_id": "sshpk@1.14.1",
|
||||
"_shasum": "130f5975eddad963f1d56f92b9ac6c51fa9f83eb",
|
||||
"_from": "sshpk@>=1.7.0 <2.0.0",
|
||||
"_npmVersion": "4.2.0",
|
||||
"_nodeVersion": "0.12.18",
|
||||
@ -83,8 +83,10 @@
|
||||
"email": "alex@cooperi.net"
|
||||
},
|
||||
"dist": {
|
||||
"shasum": "512df6da6287144316dc4c18fe1cf1d940739be3",
|
||||
"tarball": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz"
|
||||
"shasum": "130f5975eddad963f1d56f92b9ac6c51fa9f83eb",
|
||||
"tarball": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.1.tgz",
|
||||
"fileCount": 35,
|
||||
"unpackedSize": 208057
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
@ -94,7 +96,7 @@
|
||||
],
|
||||
"_npmOperationalInternal": {
|
||||
"host": "s3://npm-registry-packages",
|
||||
"tmp": "tmp/sshpk-1.13.1.tgz_1496888143718_0.9964376483112574"
|
||||
"tmp": "tmp/sshpk_1.14.1_1520899928205_0.6230534223468485"
|
||||
},
|
||||
"_resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz"
|
||||
"_resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.1.tgz"
|
||||
}
|
||||
|
||||
2
node_modules/nak/package.json
generated
vendored
2
node_modules/nak/package.json
generated
vendored
@ -52,7 +52,7 @@
|
||||
},
|
||||
"homepage": "https://github.com/gjtorikian/nak#readme",
|
||||
"_id": "nak@0.3.3",
|
||||
"_shasum": "24bf64f51c0bd9f5e13d193db392c1b2764d7e87",
|
||||
"_shasum": "7c9ec82f0c5985b45ce6ba3947351651105ce8d8",
|
||||
"_from": "git+https://github.com/cloud9ide/nak.git#6deef931594",
|
||||
"_resolved": "git+https://github.com/cloud9ide/nak.git#6deef931594787edd167040f7352e3e7533430e4"
|
||||
}
|
||||
|
||||
3
node_modules/optimist/node_modules/minimist/package.json
generated
vendored
3
node_modules/optimist/node_modules/minimist/package.json
generated
vendored
@ -62,6 +62,5 @@
|
||||
],
|
||||
"directories": {},
|
||||
"_shasum": "de3f98543dbf96082be48ad1a0c7cda836301dcf",
|
||||
"_resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz",
|
||||
"readme": "ERROR: No README data found!"
|
||||
"_resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz"
|
||||
}
|
||||
|
||||
3
node_modules/optimist/node_modules/wordwrap/package.json
generated
vendored
3
node_modules/optimist/node_modules/wordwrap/package.json
generated
vendored
@ -58,6 +58,5 @@
|
||||
"email": "mail@substack.net"
|
||||
}
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
|
||||
"readme": "ERROR: No README data found!"
|
||||
"_resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz"
|
||||
}
|
||||
|
||||
5
node_modules/optimist/package.json
generated
vendored
5
node_modules/optimist/package.json
generated
vendored
@ -16,7 +16,7 @@
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+ssh://git@github.com/substack/node-optimist.git"
|
||||
"url": "http://github.com/substack/node-optimist.git"
|
||||
},
|
||||
"keywords": [
|
||||
"argument",
|
||||
@ -59,6 +59,5 @@
|
||||
],
|
||||
"directories": {},
|
||||
"_shasum": "da3ea74686fa21a19a111c326e90eb15a0196686",
|
||||
"_resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
|
||||
"readme": "ERROR: No README data found!"
|
||||
"_resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz"
|
||||
}
|
||||
|
||||
2
node_modules/tern/node_modules/glob/node_modules/inherits/package.json
generated
vendored
2
node_modules/tern/node_modules/glob/node_modules/inherits/package.json
generated
vendored
@ -36,7 +36,7 @@
|
||||
"homepage": "https://github.com/isaacs/inherits#readme",
|
||||
"_id": "inherits@2.0.3",
|
||||
"_shasum": "633c2c83e3da42a502f52466022480f4208261de",
|
||||
"_from": "inherits@>=2.0.1 <2.1.0",
|
||||
"_from": "inherits@>=2.0.0 <3.0.0",
|
||||
"_npmVersion": "3.10.7",
|
||||
"_nodeVersion": "6.5.0",
|
||||
"_npmUser": {
|
||||
|
||||
4
node_modules/tern/package.json
generated
vendored
4
node_modules/tern/package.json
generated
vendored
@ -40,7 +40,6 @@
|
||||
"process"
|
||||
]
|
||||
},
|
||||
"gitHead": "39015d544d4c00c7899fea4c95c2e5bc2720e68e",
|
||||
"contributors": [
|
||||
{
|
||||
"name": "List of Tern contributors. Updated before every release."
|
||||
@ -241,6 +240,7 @@
|
||||
"name": "vheon"
|
||||
}
|
||||
],
|
||||
"gitHead": "39015d544d4c00c7899fea4c95c2e5bc2720e68e",
|
||||
"readme": "# Tern\n\n[](http://travis-ci.org/ternjs/tern)\n[](https://www.npmjs.org/package/tern) \n[Funding status: ](https://marijnhaverbeke.nl/fund/)\n\nThis is [Tern][1]. Tern is a stand-alone, editor-independent\nJavaScript analyzer that can be used to improve the JavaScript\nintegration of existing editors.\n\nThanks to a group of generous [crowd funders][2], Tern is open-source\nsoftware, under an MIT license.\n\nThere are currently plugins available for [Emacs][emacs] (and Emacs\n[company-mode][cmode]), [Vim][vim], [Sublime Text][st], [Eclipse (and general Java API)][ec],\n[Light Table][lt], [Atom][atom] and [gedit][gedit], and built-in support in\n[Brackets][brackets], [Edge Code][edge_code], and [CodeLite](http://codelite.org/).\n\nFor further documentation, see the [project page][1] and the\n[manual][3]. To report issues, use the\n[issue tracker](https://github.com/ternjs/tern/issues). For questions\nand documentation, see the\n[discussion forum](https://discuss.ternjs.net).\n\n[1]: http://ternjs.net\n[2]: http://www.indiegogo.com/projects/tern-intelligent-javascript-editing\n[3]: http://ternjs.net/doc/manual.html\n\n[emacs]: http://ternjs.net/doc/manual.html#emacs\n[ec]: https://github.com/angelozerr/tern.java\n[vim]: https://github.com/ternjs/tern_for_vim\n[st]: https://github.com/ternjs/tern_for_sublime\n[lt]: https://github.com/mortalapeman/LT-TernJS\n[atom]: https://atom.io/packages/atom-ternjs\n[gedit]: https://github.com/Swatinem/tern_for_gedit\n[brackets]: http://brackets.io\n[edge_code]: http://html.adobe.com/edge/code\n[cmode]: https://github.com/proofit404/company-tern\n",
|
||||
"readmeFilename": "README.md",
|
||||
"bugs": {
|
||||
@ -248,7 +248,7 @@
|
||||
},
|
||||
"homepage": "https://github.com/ternjs/tern#readme",
|
||||
"_id": "tern@0.16.1",
|
||||
"_shasum": "c89ccea2e756f052a4b28e08f67277d846983496",
|
||||
"_shasum": "e899f56ba505124cce3310ceb8414d5f1583ab38",
|
||||
"_from": "git+https://github.com/cloud9ide/tern.git#39015d544d4c00c7899fea4c95c2e5bc2720e68e",
|
||||
"_resolved": "git+https://github.com/cloud9ide/tern.git#39015d544d4c00c7899fea4c95c2e5bc2720e68e"
|
||||
}
|
||||
|
||||
2
node_modules/tern_from_ts/package.json
generated
vendored
2
node_modules/tern_from_ts/package.json
generated
vendored
@ -20,7 +20,7 @@
|
||||
"readme": "# tern_from_ts\n\nTern signatures extracted from typescript signatures.\n\nLicense: MIT\n\nSee also https://github.com/marijnh/tern and https://github.com/borisyankov/DefinitelyTyped\n",
|
||||
"readmeFilename": "README.md",
|
||||
"_id": "tern_from_ts@0.0.1",
|
||||
"_shasum": "82c5150f58103432eaaa6aadd3ecfad8331aad56",
|
||||
"_shasum": "1fed17d49d8aecdfbd1bfe4a05256105910b00b2",
|
||||
"_from": "git+https://github.com/cloud9ide/tern_from_ts.git#66df507986bbdd63f3bc4f0c53edb39169ce4f1c",
|
||||
"_resolved": "git+https://github.com/cloud9ide/tern_from_ts.git#66df507986bbdd63f3bc4f0c53edb39169ce4f1c"
|
||||
}
|
||||
|
||||
@ -49,5 +49,5 @@
|
||||
},
|
||||
"devDependencies": {},
|
||||
"licenses": [],
|
||||
"revision": "2af1c7c68e612d417f80d9feaf436da488e19103"
|
||||
"revision": "59eb6c51d6f72522362c3e540101f976851fb883"
|
||||
}
|
||||
|
||||
@ -349,7 +349,8 @@ define(function(require, exports, module) {
|
||||
"preferences.experimental": {
|
||||
addExperiment: function() {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
add: function() {},
|
||||
},
|
||||
"ace.gotoline": {},
|
||||
"ace.stripws": {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user