mirror of
https://github.com/mgerb/mywebsite
synced 2026-01-12 02:42:48 +00:00
updated bunch of file paths and changed the way posts are loaded
This commit is contained in:
8
node_modules/sshpk/.npmignore
generated
vendored
Normal file
8
node_modules/sshpk/.npmignore
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
.gitmodules
|
||||
deps
|
||||
docs
|
||||
Makefile
|
||||
node_modules
|
||||
test
|
||||
tools
|
||||
coverage
|
||||
11
node_modules/sshpk/.travis.yml
generated
vendored
Normal file
11
node_modules/sshpk/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "4.2"
|
||||
- "4.1"
|
||||
- "0.12"
|
||||
- "0.10"
|
||||
- "0.8"
|
||||
before_install:
|
||||
- "make check"
|
||||
after_success:
|
||||
- '[ "${TRAVIS_NODE_VERSION}" = "4.2" ] && make codecovio'
|
||||
18
node_modules/sshpk/LICENSE
generated
vendored
Normal file
18
node_modules/sshpk/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
Copyright Joyent, Inc. All rights reserved.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to
|
||||
deal in the Software without restriction, including without limitation the
|
||||
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
IN THE SOFTWARE.
|
||||
436
node_modules/sshpk/README.md
generated
vendored
Normal file
436
node_modules/sshpk/README.md
generated
vendored
Normal file
@@ -0,0 +1,436 @@
|
||||
sshpk
|
||||
=========
|
||||
|
||||
Parse, convert, fingerprint and use SSH keys (both public and private) in pure
|
||||
node -- no `ssh-keygen` or other external dependencies.
|
||||
|
||||
Supports RSA, DSA, ECDSA (nistp-\*) and ED25519 key types, in PEM (PKCS#1,
|
||||
PKCS#8) and OpenSSH formats.
|
||||
|
||||
This library has been extracted from
|
||||
[`node-http-signature`](https://github.com/joyent/node-http-signature)
|
||||
(work by [Mark Cavage](https://github.com/mcavage) and
|
||||
[Dave Eddy](https://github.com/bahamas10)) and
|
||||
[`node-ssh-fingerprint`](https://github.com/bahamas10/node-ssh-fingerprint)
|
||||
(work by Dave Eddy), with additions (including ECDSA support) by
|
||||
[Alex Wilson](https://github.com/arekinath).
|
||||
|
||||
Install
|
||||
-------
|
||||
|
||||
```
|
||||
npm install sshpk
|
||||
```
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
```js
|
||||
var sshpk = require('sshpk');
|
||||
|
||||
var fs = require('fs');
|
||||
|
||||
/* Read in an OpenSSH-format public key */
|
||||
var keyPub = fs.readFileSync('id_rsa.pub');
|
||||
var key = sshpk.parseKey(keyPub, 'ssh');
|
||||
|
||||
/* Get metadata about the key */
|
||||
console.log('type => %s', key.type);
|
||||
console.log('size => %d bits', key.size);
|
||||
console.log('comment => %s', key.comment);
|
||||
|
||||
/* Compute key fingerprints, in new OpenSSH (>6.7) format, and old MD5 */
|
||||
console.log('fingerprint => %s', key.fingerprint().toString());
|
||||
console.log('old-style fingerprint => %s', key.fingerprint('md5').toString());
|
||||
```
|
||||
|
||||
Example output:
|
||||
|
||||
```
|
||||
type => rsa
|
||||
size => 2048 bits
|
||||
comment => foo@foo.com
|
||||
fingerprint => SHA256:PYC9kPVC6J873CSIbfp0LwYeczP/W4ffObNCuDJ1u5w
|
||||
old-style fingerprint => a0:c8:ad:6c:32:9a:32:fa:59:cc:a9:8c:0a:0d:6e:bd
|
||||
```
|
||||
|
||||
More examples: converting between formats:
|
||||
|
||||
```js
|
||||
/* Read in a PEM public key */
|
||||
var keyPem = fs.readFileSync('id_rsa.pem');
|
||||
var key = sshpk.parseKey(keyPem, 'pem');
|
||||
|
||||
/* Convert to PEM PKCS#8 public key format */
|
||||
var pemBuf = key.toBuffer('pkcs8');
|
||||
|
||||
/* Convert to SSH public key format (and return as a string) */
|
||||
var sshKey = key.toString('ssh');
|
||||
```
|
||||
|
||||
Signing and verifying:
|
||||
|
||||
```js
|
||||
/* Read in an OpenSSH/PEM *private* key */
|
||||
var keyPriv = fs.readFileSync('id_ecdsa');
|
||||
var key = sshpk.parsePrivateKey(keyPriv, 'pem');
|
||||
|
||||
var data = 'some data';
|
||||
|
||||
/* Sign some data with the key */
|
||||
var s = key.createSign('sha1');
|
||||
s.update(data);
|
||||
var signature = s.sign();
|
||||
|
||||
/* Now load the public key (could also use just key.toPublic()) */
|
||||
var keyPub = fs.readFileSync('id_ecdsa.pub');
|
||||
key = sshpk.parseKey(keyPub, 'ssh');
|
||||
|
||||
/* Make a crypto.Verifier with this key */
|
||||
var v = key.createVerify('sha1');
|
||||
v.update(data);
|
||||
var valid = v.verify(signature);
|
||||
/* => true! */
|
||||
```
|
||||
|
||||
Matching fingerprints with keys:
|
||||
|
||||
```js
|
||||
var fp = sshpk.parseFingerprint('SHA256:PYC9kPVC6J873CSIbfp0LwYeczP/W4ffObNCuDJ1u5w');
|
||||
|
||||
var keys = [sshpk.parseKey(...), sshpk.parseKey(...), ...];
|
||||
|
||||
keys.forEach(function (key) {
|
||||
if (fp.matches(key))
|
||||
console.log('found it!');
|
||||
});
|
||||
```
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
## Public keys
|
||||
|
||||
### `parseKey(data[, format = 'auto'[, name]])`
|
||||
|
||||
Parses a key from a given data format and returns a new `Key` object.
|
||||
|
||||
Parameters
|
||||
|
||||
- `data` -- Either a Buffer or String, containing the key
|
||||
- `format` -- String name of format to use, valid options are:
|
||||
- `auto`: choose automatically from all below
|
||||
- `pem`: supports both PKCS#1 and PKCS#8
|
||||
- `ssh`: standard OpenSSH format,
|
||||
- `pkcs1`, `pkcs8`: variants of `pem`
|
||||
- `rfc4253`: raw OpenSSH wire format
|
||||
- `openssh`: new post-OpenSSH 6.5 internal format, produced by
|
||||
`ssh-keygen -o`
|
||||
- `name` -- Optional name for the key being parsed (eg. the filename that
|
||||
was opened). Used to generate Error messages
|
||||
|
||||
### `Key.isKey(obj)`
|
||||
|
||||
Returns `true` if the given object is a valid `Key` object created by a version
|
||||
of `sshpk` compatible with this one.
|
||||
|
||||
Parameters
|
||||
|
||||
- `obj` -- Object to identify
|
||||
|
||||
### `Key#type`
|
||||
|
||||
String, the type of key. Valid options are `rsa`, `dsa`, `ecdsa`.
|
||||
|
||||
### `Key#size`
|
||||
|
||||
Integer, "size" of the key in bits. For RSA/DSA this is the size of the modulus;
|
||||
for ECDSA this is the bit size of the curve in use.
|
||||
|
||||
### `Key#comment`
|
||||
|
||||
Optional string, a key comment used by some formats (eg the `ssh` format).
|
||||
|
||||
### `Key#curve`
|
||||
|
||||
Only present if `this.type === 'ecdsa'`, string containing the name of the
|
||||
named curve used with this key. Possible values include `nistp256`, `nistp384`
|
||||
and `nistp521`.
|
||||
|
||||
### `Key#toBuffer([format = 'ssh'])`
|
||||
|
||||
Convert the key into a given data format and return the serialized key as
|
||||
a Buffer.
|
||||
|
||||
Parameters
|
||||
|
||||
- `format` -- String name of format to use, for valid options see `parseKey()`
|
||||
|
||||
### `Key#toString([format = 'ssh])`
|
||||
|
||||
Same as `this.toBuffer(format).toString()`.
|
||||
|
||||
### `Key#fingerprint([algorithm = 'sha256'])`
|
||||
|
||||
Creates a new `Fingerprint` object representing this Key's fingerprint.
|
||||
|
||||
Parameters
|
||||
|
||||
- `algorithm` -- String name of hash algorithm to use, valid options are `md5`,
|
||||
`sha1`, `sha256`, `sha384`, `sha512`
|
||||
|
||||
### `Key#createVerify([hashAlgorithm])`
|
||||
|
||||
Creates a `crypto.Verifier` specialized to use this Key (and the correct public
|
||||
key algorithm to match it). The returned Verifier has the same API as a regular
|
||||
one, except that the `verify()` function takes only the target signature as an
|
||||
argument.
|
||||
|
||||
Parameters
|
||||
|
||||
- `hashAlgorithm` -- optional String name of hash algorithm to use, any
|
||||
supported by OpenSSL are valid, usually including
|
||||
`sha1`, `sha256`.
|
||||
|
||||
`v.verify(signature[, format])` Parameters
|
||||
|
||||
- `signature` -- either a Signature object, or a Buffer or String
|
||||
- `format` -- optional String, name of format to interpret given String with.
|
||||
Not valid if `signature` is a Signature or Buffer.
|
||||
|
||||
### `Key#createDiffieHellman()`
|
||||
### `Key#createDH()`
|
||||
|
||||
Creates a Diffie-Hellman key exchange object initialized with this key and all
|
||||
necessary parameters. This has the same API as a `crypto.DiffieHellman`
|
||||
instance, except that functions take `Key` and `PrivateKey` objects as
|
||||
arguments, and return them where indicated for.
|
||||
|
||||
This is only valid for keys belonging to a cryptosystem that supports DHE
|
||||
or a close analogue (i.e. `dsa`, `ecdsa` and `curve25519` keys). An attempt
|
||||
to call this function on other keys will yield an `Error`.
|
||||
|
||||
## Private keys
|
||||
|
||||
### `parsePrivateKey(data[, format = 'auto'[, name]])`
|
||||
|
||||
Parses a private key from a given data format and returns a new
|
||||
`PrivateKey` object.
|
||||
|
||||
Parameters
|
||||
|
||||
- `data` -- Either a Buffer or String, containing the key
|
||||
- `format` -- String name of format to use, valid options are:
|
||||
- `auto`: choose automatically from all below
|
||||
- `pem`: supports both PKCS#1 and PKCS#8
|
||||
- `ssh`, `openssh`: new post-OpenSSH 6.5 internal format, produced by
|
||||
`ssh-keygen -o`
|
||||
- `pkcs1`, `pkcs8`: variants of `pem`
|
||||
- `rfc4253`: raw OpenSSH wire format
|
||||
- `name` -- Optional name for the key being parsed (eg. the filename that
|
||||
was opened). Used to generate Error messages
|
||||
|
||||
### `PrivateKey.isPrivateKey(obj)`
|
||||
|
||||
Returns `true` if the given object is a valid `PrivateKey` object created by a
|
||||
version of `sshpk` compatible with this one.
|
||||
|
||||
Parameters
|
||||
|
||||
- `obj` -- Object to identify
|
||||
|
||||
### `PrivateKey#type`
|
||||
|
||||
String, the type of key. Valid options are `rsa`, `dsa`, `ecdsa`.
|
||||
|
||||
### `PrivateKey#size`
|
||||
|
||||
Integer, "size" of the key in bits. For RSA/DSA this is the size of the modulus;
|
||||
for ECDSA this is the bit size of the curve in use.
|
||||
|
||||
### `PrivateKey#curve`
|
||||
|
||||
Only present if `this.type === 'ecdsa'`, string containing the name of the
|
||||
named curve used with this key. Possible values include `nistp256`, `nistp384`
|
||||
and `nistp521`.
|
||||
|
||||
### `PrivateKey#toBuffer([format = 'pkcs1'])`
|
||||
|
||||
Convert the key into a given data format and return the serialized key as
|
||||
a Buffer.
|
||||
|
||||
Parameters
|
||||
|
||||
- `format` -- String name of format to use, valid options are listed under
|
||||
`parsePrivateKey`. Note that ED25519 keys default to `openssh`
|
||||
format instead (as they have no `pkcs1` representation).
|
||||
|
||||
### `PrivateKey#toString([format = 'pkcs1'])`
|
||||
|
||||
Same as `this.toBuffer(format).toString()`.
|
||||
|
||||
### `PrivateKey#toPublic()`
|
||||
|
||||
Extract just the public part of this private key, and return it as a `Key`
|
||||
object.
|
||||
|
||||
### `PrivateKey#fingerprint([algorithm = 'sha256'])`
|
||||
|
||||
Same as `this.toPublic().fingerprint()`.
|
||||
|
||||
### `PrivateKey#createVerify([hashAlgorithm])`
|
||||
|
||||
Same as `this.toPublic().createVerify()`.
|
||||
|
||||
### `PrivateKey#createSign([hashAlgorithm])`
|
||||
|
||||
Creates a `crypto.Sign` specialized to use this PrivateKey (and the correct
|
||||
key algorithm to match it). The returned Signer has the same API as a regular
|
||||
one, except that the `sign()` function takes no arguments, and returns a
|
||||
`Signature` object.
|
||||
|
||||
Parameters
|
||||
|
||||
- `hashAlgorithm` -- optional String name of hash algorithm to use, any
|
||||
supported by OpenSSL are valid, usually including
|
||||
`sha1`, `sha256`.
|
||||
|
||||
`v.sign()` Parameters
|
||||
|
||||
- none
|
||||
|
||||
### `PrivateKey#derive(newType)`
|
||||
|
||||
Derives a related key of type `newType` from this key. Currently this is
|
||||
only supported to change between `ed25519` and `curve25519` keys which are
|
||||
stored with the same private key (but usually distinct public keys in order
|
||||
to avoid degenerate keys that lead to a weak Diffie-Hellman exchange).
|
||||
|
||||
Parameters
|
||||
|
||||
- `newType` -- String, type of key to derive, either `ed25519` or `curve25519`
|
||||
|
||||
## Fingerprints
|
||||
|
||||
### `parseFingerprint(fingerprint[, algorithms])`
|
||||
|
||||
Pre-parses a fingerprint, creating a `Fingerprint` object that can be used to
|
||||
quickly locate a key by using the `Fingerprint#matches` function.
|
||||
|
||||
Parameters
|
||||
|
||||
- `fingerprint` -- String, the fingerprint value, in any supported format
|
||||
- `algorithms` -- Optional list of strings, names of hash algorithms to limit
|
||||
support to. If `fingerprint` uses a hash algorithm not on
|
||||
this list, throws `InvalidAlgorithmError`.
|
||||
|
||||
### `Fingerprint.isFingerprint(obj)`
|
||||
|
||||
Returns `true` if the given object is a valid `Fingerprint` object created by a
|
||||
version of `sshpk` compatible with this one.
|
||||
|
||||
Parameters
|
||||
|
||||
- `obj` -- Object to identify
|
||||
|
||||
### `Fingerprint#toString([format])`
|
||||
|
||||
Returns a fingerprint as a string, in the given format.
|
||||
|
||||
Parameters
|
||||
|
||||
- `format` -- Optional String, format to use, valid options are `hex` and
|
||||
`base64`. If this `Fingerprint` uses the `md5` algorithm, the
|
||||
default format is `hex`. Otherwise, the default is `base64`.
|
||||
|
||||
### `Fingerprint#matches(key)`
|
||||
|
||||
Verifies whether or not this `Fingerprint` matches a given `Key`. This function
|
||||
uses double-hashing to avoid leaking timing information. Returns a boolean.
|
||||
|
||||
Parameters
|
||||
|
||||
- `key` -- a `Key` object, the key to match this fingerprint against
|
||||
|
||||
## Signatures
|
||||
|
||||
### `parseSignature(signature, algorithm, format)`
|
||||
|
||||
Parses a signature in a given format, creating a `Signature` object. Useful
|
||||
for converting between the SSH and ASN.1 (PKCS/OpenSSL) signature formats, and
|
||||
also returned as output from `PrivateKey#createSign().sign()`.
|
||||
|
||||
A Signature object can also be passed to a verifier produced by
|
||||
`Key#createVerify()` and it will automatically be converted internally into the
|
||||
correct format for verification.
|
||||
|
||||
Parameters
|
||||
|
||||
- `signature` -- a Buffer (binary) or String (base64), data of the actual
|
||||
signature in the given format
|
||||
- `algorithm` -- a String, name of the algorithm to be used, possible values
|
||||
are `rsa`, `dsa`, `ecdsa`
|
||||
- `format` -- a String, either `asn1` or `ssh`
|
||||
|
||||
### `Signature.isSignature(obj)`
|
||||
|
||||
Returns `true` if the given object is a valid `Signature` object created by a
|
||||
version of `sshpk` compatible with this one.
|
||||
|
||||
Parameters
|
||||
|
||||
- `obj` -- Object to identify
|
||||
|
||||
### `Signature#toBuffer([format = 'asn1'])`
|
||||
|
||||
Converts a Signature to the given format and returns it as a Buffer.
|
||||
|
||||
Parameters
|
||||
|
||||
- `format` -- a String, either `asn1` or `ssh`
|
||||
|
||||
### `Signature#toString([format = 'asn1'])`
|
||||
|
||||
Same as `this.toBuffer(format).toString('base64')`.
|
||||
|
||||
Errors
|
||||
------
|
||||
|
||||
### `InvalidAlgorithmError`
|
||||
|
||||
The specified algorithm is not valid, either because it is not supported, or
|
||||
because it was not included on a list of allowed algorithms.
|
||||
|
||||
Thrown by `Fingerprint.parse`, `Key#fingerprint`.
|
||||
|
||||
Properties
|
||||
|
||||
- `algorithm` -- the algorithm that could not be validated
|
||||
|
||||
### `FingerprintFormatError`
|
||||
|
||||
The fingerprint string given could not be parsed as a supported fingerprint
|
||||
format, or the specified fingerprint format is invalid.
|
||||
|
||||
Thrown by `Fingerprint.parse`, `Fingerprint#toString`.
|
||||
|
||||
Properties
|
||||
|
||||
- `fingerprint` -- if caused by a fingerprint, the string value given
|
||||
- `format` -- if caused by an invalid format specification, the string value given
|
||||
|
||||
### `KeyParseError`
|
||||
|
||||
The key data given could not be parsed as a valid key.
|
||||
|
||||
Properties
|
||||
|
||||
- `keyName` -- `name` that was given to `Key#parse`
|
||||
- `format` -- the `format` that was trying to parse the key
|
||||
- `innerErr` -- the inner Error thrown by the format parser
|
||||
|
||||
Friends of sshpk
|
||||
----------------
|
||||
|
||||
* [`sshpk-agent`](https://github.com/arekinath/node-sshpk-agent) is a library
|
||||
for speaking the `ssh-agent` protocol from node.js, which uses `sshpk`
|
||||
183
node_modules/sshpk/bin/sshpk-conv
generated
vendored
Executable file
183
node_modules/sshpk/bin/sshpk-conv
generated
vendored
Executable file
@@ -0,0 +1,183 @@
|
||||
#!/usr/bin/env node
|
||||
// -*- mode: js -*-
|
||||
// vim: set filetype=javascript :
|
||||
// Copyright 2015 Joyent, Inc. All rights reserved.
|
||||
|
||||
var dashdash = require('dashdash');
|
||||
var sshpk = require('../lib/index');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
|
||||
var options = [
|
||||
{
|
||||
names: ['outformat', 't'],
|
||||
type: 'string',
|
||||
help: 'Output format'
|
||||
},
|
||||
{
|
||||
names: ['informat', 'T'],
|
||||
type: 'string',
|
||||
help: 'Input format'
|
||||
},
|
||||
{
|
||||
names: ['file', 'f'],
|
||||
type: 'string',
|
||||
help: 'Input file name (default stdin)'
|
||||
},
|
||||
{
|
||||
names: ['out', 'o'],
|
||||
type: 'string',
|
||||
help: 'Output file name (default stdout)'
|
||||
},
|
||||
{
|
||||
names: ['private', 'p'],
|
||||
type: 'bool',
|
||||
help: 'Produce a private key as output'
|
||||
},
|
||||
{
|
||||
names: ['derive', 'd'],
|
||||
type: 'string',
|
||||
help: 'Output a new key derived from this one, with given algo'
|
||||
},
|
||||
{
|
||||
names: ['identify', 'i'],
|
||||
type: 'bool',
|
||||
help: 'Print key metadata instead of converting'
|
||||
},
|
||||
{
|
||||
names: ['comment', 'c'],
|
||||
type: 'string',
|
||||
help: 'Set key comment, if output format supports'
|
||||
},
|
||||
{
|
||||
names: ['help', 'h'],
|
||||
type: 'bool',
|
||||
help: 'Shows this help text'
|
||||
}
|
||||
];
|
||||
|
||||
if (require.main === module) {
|
||||
var parser = dashdash.createParser({
|
||||
options: options
|
||||
});
|
||||
|
||||
try {
|
||||
var opts = parser.parse(process.argv);
|
||||
} catch (e) {
|
||||
console.error('sshpk-conv: error: %s', e.message);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (opts.help || opts._args.length > 1) {
|
||||
var help = parser.help({}).trimRight();
|
||||
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');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Key derivation can only be done on private keys, so use of the -d
|
||||
* option necessarily implies -p.
|
||||
*/
|
||||
if (opts.derive)
|
||||
opts.private = true;
|
||||
|
||||
var inFile = process.stdin;
|
||||
var inFileName = 'stdin';
|
||||
|
||||
var inFilePath;
|
||||
if (opts.file) {
|
||||
inFilePath = opts.file;
|
||||
} else if (opts._args.length === 1) {
|
||||
inFilePath = opts._args[0];
|
||||
}
|
||||
|
||||
if (inFilePath)
|
||||
inFileName = path.basename(inFilePath);
|
||||
|
||||
try {
|
||||
if (inFilePath) {
|
||||
fs.accessSync(inFilePath, fs.R_OK);
|
||||
inFile = fs.createReadStream(inFilePath);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('sshpk-conv: error opening input file' +
|
||||
': ' + e.name + ': ' + e.message);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
var outFile = process.stdout;
|
||||
|
||||
try {
|
||||
if (opts.out && !opts.identify) {
|
||||
fs.accessSync(path.dirname(opts.out), fs.W_OK);
|
||||
outFile = fs.createWriteStream(opts.out);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('sshpk-conv: error opening output file' +
|
||||
': ' + e.name + ': ' + e.message);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
var bufs = [];
|
||||
inFile.on('readable', function () {
|
||||
var data;
|
||||
while ((data = inFile.read()))
|
||||
bufs.push(data);
|
||||
});
|
||||
inFile.on('end', function () {
|
||||
var buf = Buffer.concat(bufs);
|
||||
var fmt = 'auto';
|
||||
if (opts.informat)
|
||||
fmt = opts.informat;
|
||||
var f = sshpk.parseKey;
|
||||
if (opts.private)
|
||||
f = sshpk.parsePrivateKey;
|
||||
try {
|
||||
var key = f(buf, fmt, inFileName);
|
||||
} catch (e) {
|
||||
console.error('sshpk-conv: ' +
|
||||
e.name + ': ' + e.message);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (opts.derive)
|
||||
key = key.derive(opts.derive);
|
||||
|
||||
if (opts.comment)
|
||||
key.comment = opts.comment;
|
||||
|
||||
if (!opts.identify) {
|
||||
fmt = undefined;
|
||||
if (opts.outformat)
|
||||
fmt = opts.outformat;
|
||||
outFile.write(key.toBuffer(fmt));
|
||||
if (fmt === 'ssh' ||
|
||||
(!opts.private && fmt === undefined))
|
||||
outFile.write('\n');
|
||||
outFile.once('drain', function () {
|
||||
process.exit(0);
|
||||
});
|
||||
} else {
|
||||
var kind = 'public';
|
||||
if (PrivateKey.isPrivateKey(key))
|
||||
kind = 'private';
|
||||
console.log('%s: a %d bit %s %s key', inFileName,
|
||||
key.size, key.type.toUpperCase(), kind);
|
||||
if (key.type === 'ecdsa')
|
||||
console.log('ECDSA curve: %s', key.curve);
|
||||
if (key.comment)
|
||||
console.log('Comment: %s', key.comment);
|
||||
console.log('Fingerprint:');
|
||||
console.log(' ' + key.fingerprint().toString());
|
||||
console.log(' ' + key.fingerprint('md5').toString());
|
||||
process.exit(0);
|
||||
}
|
||||
});
|
||||
}
|
||||
168
node_modules/sshpk/lib/algs.js
generated
vendored
Normal file
168
node_modules/sshpk/lib/algs.js
generated
vendored
Normal file
@@ -0,0 +1,168 @@
|
||||
// Copyright 2015 Joyent, Inc.
|
||||
|
||||
var algInfo = {
|
||||
'dsa': {
|
||||
parts: ['p', 'q', 'g', 'y'],
|
||||
sizePart: 'p'
|
||||
},
|
||||
'rsa': {
|
||||
parts: ['e', 'n'],
|
||||
sizePart: 'n'
|
||||
},
|
||||
'ecdsa': {
|
||||
parts: ['curve', 'Q'],
|
||||
sizePart: 'Q'
|
||||
},
|
||||
'ed25519': {
|
||||
parts: ['R'],
|
||||
normalize: false,
|
||||
sizePart: 'R'
|
||||
}
|
||||
};
|
||||
algInfo['curve25519'] = algInfo['ed25519'];
|
||||
|
||||
var algPrivInfo = {
|
||||
'dsa': {
|
||||
parts: ['p', 'q', 'g', 'y', 'x']
|
||||
},
|
||||
'rsa': {
|
||||
parts: ['n', 'e', 'd', 'iqmp', 'p', 'q']
|
||||
},
|
||||
'ecdsa': {
|
||||
parts: ['curve', 'Q', 'd']
|
||||
},
|
||||
'ed25519': {
|
||||
parts: ['R', 'r'],
|
||||
normalize: false
|
||||
}
|
||||
};
|
||||
algPrivInfo['curve25519'] = algPrivInfo['ed25519'];
|
||||
|
||||
var hashAlgs = {
|
||||
'md5': true,
|
||||
'sha1': true,
|
||||
'sha256': true,
|
||||
'sha384': true,
|
||||
'sha512': true
|
||||
};
|
||||
|
||||
/*
|
||||
* Taken from
|
||||
* http://csrc.nist.gov/groups/ST/toolkit/documents/dss/NISTReCur.pdf
|
||||
*/
|
||||
var curves = {
|
||||
'nistp256': {
|
||||
size: 256,
|
||||
pkcs8oid: '1.2.840.10045.3.1.7',
|
||||
p: new Buffer(('00' +
|
||||
'ffffffff 00000001 00000000 00000000' +
|
||||
'00000000 ffffffff ffffffff ffffffff').
|
||||
replace(/ /g, ''), 'hex'),
|
||||
a: new Buffer(('00' +
|
||||
'FFFFFFFF 00000001 00000000 00000000' +
|
||||
'00000000 FFFFFFFF FFFFFFFF FFFFFFFC').
|
||||
replace(/ /g, ''), 'hex'),
|
||||
b: new Buffer((
|
||||
'5ac635d8 aa3a93e7 b3ebbd55 769886bc' +
|
||||
'651d06b0 cc53b0f6 3bce3c3e 27d2604b').
|
||||
replace(/ /g, ''), 'hex'),
|
||||
s: new Buffer(('00' +
|
||||
'c49d3608 86e70493 6a6678e1 139d26b7' +
|
||||
'819f7e90').
|
||||
replace(/ /g, ''), 'hex'),
|
||||
n: new Buffer(('00' +
|
||||
'ffffffff 00000000 ffffffff ffffffff' +
|
||||
'bce6faad a7179e84 f3b9cac2 fc632551').
|
||||
replace(/ /g, ''), 'hex'),
|
||||
G: new Buffer(('04' +
|
||||
'6b17d1f2 e12c4247 f8bce6e5 63a440f2' +
|
||||
'77037d81 2deb33a0 f4a13945 d898c296' +
|
||||
'4fe342e2 fe1a7f9b 8ee7eb4a 7c0f9e16' +
|
||||
'2bce3357 6b315ece cbb64068 37bf51f5').
|
||||
replace(/ /g, ''), 'hex')
|
||||
},
|
||||
'nistp384': {
|
||||
size: 384,
|
||||
pkcs8oid: '1.3.132.0.34',
|
||||
p: new Buffer(('00' +
|
||||
'ffffffff ffffffff ffffffff ffffffff' +
|
||||
'ffffffff ffffffff ffffffff fffffffe' +
|
||||
'ffffffff 00000000 00000000 ffffffff').
|
||||
replace(/ /g, ''), 'hex'),
|
||||
a: new Buffer(('00' +
|
||||
'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF' +
|
||||
'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE' +
|
||||
'FFFFFFFF 00000000 00000000 FFFFFFFC').
|
||||
replace(/ /g, ''), 'hex'),
|
||||
b: new Buffer((
|
||||
'b3312fa7 e23ee7e4 988e056b e3f82d19' +
|
||||
'181d9c6e fe814112 0314088f 5013875a' +
|
||||
'c656398d 8a2ed19d 2a85c8ed d3ec2aef').
|
||||
replace(/ /g, ''), 'hex'),
|
||||
s: new Buffer(('00' +
|
||||
'a335926a a319a27a 1d00896a 6773a482' +
|
||||
'7acdac73').
|
||||
replace(/ /g, ''), 'hex'),
|
||||
n: new Buffer(('00' +
|
||||
'ffffffff ffffffff ffffffff ffffffff' +
|
||||
'ffffffff ffffffff c7634d81 f4372ddf' +
|
||||
'581a0db2 48b0a77a ecec196a ccc52973').
|
||||
replace(/ /g, ''), 'hex'),
|
||||
G: new Buffer(('04' +
|
||||
'aa87ca22 be8b0537 8eb1c71e f320ad74' +
|
||||
'6e1d3b62 8ba79b98 59f741e0 82542a38' +
|
||||
'5502f25d bf55296c 3a545e38 72760ab7' +
|
||||
'3617de4a 96262c6f 5d9e98bf 9292dc29' +
|
||||
'f8f41dbd 289a147c e9da3113 b5f0b8c0' +
|
||||
'0a60b1ce 1d7e819d 7a431d7c 90ea0e5f').
|
||||
replace(/ /g, ''), 'hex')
|
||||
},
|
||||
'nistp521': {
|
||||
size: 521,
|
||||
pkcs8oid: '1.3.132.0.35',
|
||||
p: new Buffer((
|
||||
'01ffffff ffffffff ffffffff ffffffff' +
|
||||
'ffffffff ffffffff ffffffff ffffffff' +
|
||||
'ffffffff ffffffff ffffffff ffffffff' +
|
||||
'ffffffff ffffffff ffffffff ffffffff' +
|
||||
'ffff').replace(/ /g, ''), 'hex'),
|
||||
a: new Buffer(('01FF' +
|
||||
'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF' +
|
||||
'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF' +
|
||||
'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF' +
|
||||
'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFC').
|
||||
replace(/ /g, ''), 'hex'),
|
||||
b: new Buffer(('51' +
|
||||
'953eb961 8e1c9a1f 929a21a0 b68540ee' +
|
||||
'a2da725b 99b315f3 b8b48991 8ef109e1' +
|
||||
'56193951 ec7e937b 1652c0bd 3bb1bf07' +
|
||||
'3573df88 3d2c34f1 ef451fd4 6b503f00').
|
||||
replace(/ /g, ''), 'hex'),
|
||||
s: new Buffer(('00' +
|
||||
'd09e8800 291cb853 96cc6717 393284aa' +
|
||||
'a0da64ba').replace(/ /g, ''), 'hex'),
|
||||
n: new Buffer(('01ff' +
|
||||
'ffffffff ffffffff ffffffff ffffffff' +
|
||||
'ffffffff ffffffff ffffffff fffffffa' +
|
||||
'51868783 bf2f966b 7fcc0148 f709a5d0' +
|
||||
'3bb5c9b8 899c47ae bb6fb71e 91386409').
|
||||
replace(/ /g, ''), 'hex'),
|
||||
G: new Buffer(('04' +
|
||||
'00c6 858e06b7 0404e9cd 9e3ecb66 2395b442' +
|
||||
'9c648139 053fb521 f828af60 6b4d3dba' +
|
||||
'a14b5e77 efe75928 fe1dc127 a2ffa8de' +
|
||||
'3348b3c1 856a429b f97e7e31 c2e5bd66' +
|
||||
'0118 39296a78 9a3bc004 5c8a5fb4 2c7d1bd9' +
|
||||
'98f54449 579b4468 17afbd17 273e662c' +
|
||||
'97ee7299 5ef42640 c550b901 3fad0761' +
|
||||
'353c7086 a272c240 88be9476 9fd16650').
|
||||
replace(/ /g, ''), 'hex')
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
info: algInfo,
|
||||
privInfo: algPrivInfo,
|
||||
hashAlgs: hashAlgs,
|
||||
curves: curves
|
||||
};
|
||||
311
node_modules/sshpk/lib/dhe.js
generated
vendored
Normal file
311
node_modules/sshpk/lib/dhe.js
generated
vendored
Normal file
@@ -0,0 +1,311 @@
|
||||
// Copyright 2015 Joyent, Inc.
|
||||
|
||||
module.exports = DiffieHellman;
|
||||
|
||||
var assert = require('assert-plus');
|
||||
var crypto = require('crypto');
|
||||
var algs = require('./algs');
|
||||
var utils = require('./utils');
|
||||
var ed;
|
||||
|
||||
var Key = require('./key');
|
||||
var PrivateKey = require('./private-key');
|
||||
|
||||
var CRYPTO_HAVE_ECDH = (crypto.createECDH !== undefined);
|
||||
|
||||
var ecdh, ec, jsbn;
|
||||
|
||||
function DiffieHellman(key) {
|
||||
utils.assertCompatible(key, Key, [1, 4], 'key');
|
||||
this._isPriv = PrivateKey.isPrivateKey(key, [1, 3]);
|
||||
this._algo = key.type;
|
||||
this._curve = key.curve;
|
||||
this._key = key;
|
||||
if (key.type === 'dsa') {
|
||||
if (!CRYPTO_HAVE_ECDH) {
|
||||
throw (new Error('Due to bugs in the node 0.10 ' +
|
||||
'crypto API, node 0.12.x or later is required ' +
|
||||
'to use DH'));
|
||||
}
|
||||
this._dh = crypto.createDiffieHellman(
|
||||
key.part.p.data, undefined,
|
||||
key.part.g.data, undefined);
|
||||
this._p = key.part.p;
|
||||
this._g = key.part.g;
|
||||
if (this._isPriv)
|
||||
this._dh.setPrivateKey(key.part.x.data);
|
||||
this._dh.setPublicKey(key.part.y.data);
|
||||
|
||||
} else if (key.type === 'ecdsa') {
|
||||
if (!CRYPTO_HAVE_ECDH) {
|
||||
if (ecdh === undefined)
|
||||
ecdh = require('ecc-jsbn');
|
||||
if (ec === undefined)
|
||||
ec = require('ecc-jsbn/lib/ec');
|
||||
if (jsbn === undefined)
|
||||
jsbn = require('jsbn').BigInteger;
|
||||
|
||||
this._ecParams = new X9ECParameters(this._curve);
|
||||
|
||||
if (this._isPriv) {
|
||||
this._priv = new ECPrivate(
|
||||
this._ecParams, key.part.d.data);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var curve = {
|
||||
'nistp256': 'prime256v1',
|
||||
'nistp384': 'secp384r1',
|
||||
'nistp521': 'secp521r1'
|
||||
}[key.curve];
|
||||
this._dh = crypto.createECDH(curve);
|
||||
if (typeof (this._dh) !== 'object' ||
|
||||
typeof (this._dh.setPrivateKey) !== 'function') {
|
||||
CRYPTO_HAVE_ECDH = false;
|
||||
DiffieHellman.call(this, key);
|
||||
return;
|
||||
}
|
||||
if (this._isPriv)
|
||||
this._dh.setPrivateKey(key.part.d.data);
|
||||
this._dh.setPublicKey(key.part.Q.data);
|
||||
|
||||
} else if (key.type === 'curve25519') {
|
||||
if (ed === undefined)
|
||||
ed = require('jodid25519');
|
||||
|
||||
if (this._isPriv) {
|
||||
this._priv = key.part.r.data;
|
||||
if (this._priv[0] === 0x00)
|
||||
this._priv = this._priv.slice(1);
|
||||
this._priv = this._priv.slice(0, 32);
|
||||
}
|
||||
|
||||
} else {
|
||||
throw (new Error('DH not supported for ' + key.type + ' keys'));
|
||||
}
|
||||
}
|
||||
|
||||
DiffieHellman.prototype.getPublicKey = function () {
|
||||
if (this._isPriv)
|
||||
return (this._key.toPublic());
|
||||
return (this._key);
|
||||
};
|
||||
|
||||
DiffieHellman.prototype.getPrivateKey = function () {
|
||||
if (this._isPriv)
|
||||
return (this._key);
|
||||
else
|
||||
return (undefined);
|
||||
};
|
||||
DiffieHellman.prototype.getKey = DiffieHellman.prototype.getPrivateKey;
|
||||
|
||||
DiffieHellman.prototype._keyCheck = function (pk, isPub) {
|
||||
assert.object(pk, 'key');
|
||||
if (!isPub)
|
||||
utils.assertCompatible(pk, PrivateKey, [1, 3], 'key');
|
||||
utils.assertCompatible(pk, Key, [1, 4], 'key');
|
||||
|
||||
if (pk.type !== this._algo) {
|
||||
throw (new Error('A ' + pk.type + ' key cannot be used in ' +
|
||||
this._algo + ' Diffie-Hellman'));
|
||||
}
|
||||
|
||||
if (pk.curve !== this._curve) {
|
||||
throw (new Error('A key from the ' + pk.curve + ' curve ' +
|
||||
'cannot be used with a ' + this._curve +
|
||||
' Diffie-Hellman'));
|
||||
}
|
||||
|
||||
if (pk.type === 'dsa') {
|
||||
assert.deepEqual(pk.part.p, this._p,
|
||||
'DSA key prime does not match');
|
||||
assert.deepEqual(pk.part.g, this._g,
|
||||
'DSA key generator does not match');
|
||||
}
|
||||
};
|
||||
|
||||
DiffieHellman.prototype.setKey = function (pk) {
|
||||
this._keyCheck(pk);
|
||||
|
||||
if (pk.type === 'dsa') {
|
||||
this._dh.setPrivateKey(pk.part.x.data);
|
||||
this._dh.setPublicKey(pk.part.y.data);
|
||||
|
||||
} else if (pk.type === 'ecdsa') {
|
||||
if (CRYPTO_HAVE_ECDH) {
|
||||
this._dh.setPrivateKey(pk.part.d.data);
|
||||
this._dh.setPublicKey(pk.part.Q.data);
|
||||
} else {
|
||||
this._priv = new ECPrivate(
|
||||
this._ecParams, pk.part.d.data);
|
||||
}
|
||||
|
||||
} else if (pk.type === 'curve25519') {
|
||||
this._priv = pk.part.r.data;
|
||||
if (this._priv[0] === 0x00)
|
||||
this._priv = this._priv.slice(1);
|
||||
this._priv = this._priv.slice(0, 32);
|
||||
}
|
||||
this._key = pk;
|
||||
this._isPriv = true;
|
||||
};
|
||||
DiffieHellman.prototype.setPrivateKey = DiffieHellman.prototype.setKey;
|
||||
|
||||
DiffieHellman.prototype.computeSecret = function (otherpk) {
|
||||
this._keyCheck(otherpk, true);
|
||||
if (!this._isPriv)
|
||||
throw (new Error('DH exchange has not been initialized with ' +
|
||||
'a private key yet'));
|
||||
|
||||
var pub;
|
||||
if (this._algo === 'dsa') {
|
||||
return (this._dh.computeSecret(
|
||||
otherpk.part.y.data));
|
||||
|
||||
} else if (this._algo === 'ecdsa') {
|
||||
if (CRYPTO_HAVE_ECDH) {
|
||||
return (this._dh.computeSecret(
|
||||
otherpk.part.Q.data));
|
||||
} else {
|
||||
pub = new ECPublic(
|
||||
this._ecParams, otherpk.part.Q.data);
|
||||
return (this._priv.deriveSharedSecret(pub));
|
||||
}
|
||||
|
||||
} else if (this._algo === 'curve25519') {
|
||||
pub = otherpk.part.R.data;
|
||||
if (pub[0] === 0x00)
|
||||
pub = pub.slice(1);
|
||||
|
||||
var secret = ed.dh.computeKey(
|
||||
this._priv.toString('binary'),
|
||||
pub.toString('binary'));
|
||||
|
||||
return (new Buffer(secret, 'binary'));
|
||||
}
|
||||
|
||||
throw (new Error('Invalid algorithm: ' + this._algo));
|
||||
};
|
||||
|
||||
DiffieHellman.prototype.generateKey = function () {
|
||||
var parts = [];
|
||||
var priv, pub;
|
||||
if (this._algo === 'dsa') {
|
||||
this._dh.generateKeys();
|
||||
|
||||
parts.push({name: 'p', data: this._p.data});
|
||||
parts.push({name: 'q', data: this._key.part.q.data});
|
||||
parts.push({name: 'g', data: this._g.data});
|
||||
parts.push({name: 'y', data: this._dh.getPublicKey()});
|
||||
parts.push({name: 'x', data: this._dh.getPrivateKey()});
|
||||
this._key = new PrivateKey({
|
||||
type: 'dsa',
|
||||
parts: parts
|
||||
});
|
||||
this._isPriv = true;
|
||||
return (this._key);
|
||||
|
||||
} else if (this._algo === 'ecdsa') {
|
||||
if (CRYPTO_HAVE_ECDH) {
|
||||
this._dh.generateKeys();
|
||||
|
||||
parts.push({name: 'curve',
|
||||
data: new Buffer(this._curve)});
|
||||
parts.push({name: 'Q', data: this._dh.getPublicKey()});
|
||||
parts.push({name: 'd', data: this._dh.getPrivateKey()});
|
||||
this._key = new PrivateKey({
|
||||
type: 'ecdsa',
|
||||
curve: this._curve,
|
||||
parts: parts
|
||||
});
|
||||
this._isPriv = true;
|
||||
return (this._key);
|
||||
|
||||
} else {
|
||||
var n = this._ecParams.getN();
|
||||
var r = new jsbn(crypto.randomBytes(n.bitLength()));
|
||||
var n1 = n.subtract(jsbn.ONE);
|
||||
priv = r.mod(n1).add(jsbn.ONE);
|
||||
pub = this._ecParams.getG().multiply(priv);
|
||||
|
||||
priv = new Buffer(priv.toByteArray());
|
||||
pub = new Buffer(this._ecParams.getCurve().
|
||||
encodePointHex(pub), 'hex');
|
||||
|
||||
this._priv = new ECPrivate(this._ecParams, priv);
|
||||
|
||||
parts.push({name: 'curve',
|
||||
data: new Buffer(this._curve)});
|
||||
parts.push({name: 'Q', data: pub});
|
||||
parts.push({name: 'd', data: priv});
|
||||
|
||||
this._key = new PrivateKey({
|
||||
type: 'ecdsa',
|
||||
curve: this._curve,
|
||||
parts: parts
|
||||
});
|
||||
this._isPriv = true;
|
||||
return (this._key);
|
||||
}
|
||||
|
||||
} else if (this._algo === 'curve25519') {
|
||||
priv = ed.dh.generateKey();
|
||||
pub = ed.dh.publicKey(priv);
|
||||
this._priv = priv = new Buffer(priv, 'binary');
|
||||
pub = new Buffer(pub, 'binary');
|
||||
|
||||
parts.push({name: 'R', data: pub});
|
||||
parts.push({name: 'r', data: Buffer.concat([priv, pub])});
|
||||
this._key = new PrivateKey({
|
||||
type: 'curve25519',
|
||||
parts: parts
|
||||
});
|
||||
this._isPriv = true;
|
||||
return (this._key);
|
||||
}
|
||||
|
||||
throw (new Error('Invalid algorithm: ' + this._algo));
|
||||
};
|
||||
DiffieHellman.prototype.generateKeys = DiffieHellman.prototype.generateKey;
|
||||
|
||||
/* These are helpers for using ecc-jsbn (for node 0.10 compatibility). */
|
||||
|
||||
function X9ECParameters(name) {
|
||||
var params = algs.curves[name];
|
||||
assert.object(params);
|
||||
|
||||
var p = new jsbn(params.p);
|
||||
var a = new jsbn(params.a);
|
||||
var b = new jsbn(params.b);
|
||||
var n = new jsbn(params.n);
|
||||
var h = jsbn.ONE;
|
||||
var curve = new ec.ECCurveFp(p, a, b);
|
||||
var G = curve.decodePointHex(params.G.toString('hex'));
|
||||
|
||||
this.curve = curve;
|
||||
this.g = G;
|
||||
this.n = n;
|
||||
this.h = h;
|
||||
}
|
||||
X9ECParameters.prototype.getCurve = function () { return (this.curve); };
|
||||
X9ECParameters.prototype.getG = function () { return (this.g); };
|
||||
X9ECParameters.prototype.getN = function () { return (this.n); };
|
||||
X9ECParameters.prototype.getH = function () { return (this.h); };
|
||||
|
||||
function ECPublic(params, buffer) {
|
||||
this._params = params;
|
||||
if (buffer[0] === 0x00)
|
||||
buffer = buffer.slice(1);
|
||||
this._pub = params.getCurve().decodePointHex(buffer.toString('hex'));
|
||||
}
|
||||
|
||||
function ECPrivate(params, buffer) {
|
||||
this._params = params;
|
||||
this._priv = new jsbn(utils.mpNormalize(buffer));
|
||||
}
|
||||
ECPrivate.prototype.deriveSharedSecret = function (pubKey) {
|
||||
assert.ok(pubKey instanceof ECPublic);
|
||||
var S = pubKey._pub.multiply(this._priv);
|
||||
return (new Buffer(S.getX().toBigInteger().toByteArray()));
|
||||
};
|
||||
94
node_modules/sshpk/lib/ed-compat.js
generated
vendored
Normal file
94
node_modules/sshpk/lib/ed-compat.js
generated
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
// Copyright 2015 Joyent, Inc.
|
||||
|
||||
module.exports = {
|
||||
Verifier: Verifier,
|
||||
Signer: Signer
|
||||
};
|
||||
|
||||
var nacl;
|
||||
var stream = require('stream');
|
||||
var util = require('util');
|
||||
var assert = require('assert-plus');
|
||||
var Signature = require('./signature');
|
||||
|
||||
function Verifier(key, hashAlgo) {
|
||||
if (nacl === undefined)
|
||||
nacl = require('tweetnacl');
|
||||
|
||||
if (hashAlgo.toLowerCase() !== 'sha512')
|
||||
throw (new Error('ED25519 only supports the use of ' +
|
||||
'SHA-512 hashes'));
|
||||
|
||||
this.key = key;
|
||||
this.chunks = [];
|
||||
|
||||
stream.Writable.call(this, {});
|
||||
}
|
||||
util.inherits(Verifier, stream.Writable);
|
||||
|
||||
Verifier.prototype._write = function (chunk, enc, cb) {
|
||||
this.chunks.push(chunk);
|
||||
cb();
|
||||
};
|
||||
|
||||
Verifier.prototype.update = function (chunk) {
|
||||
if (typeof (chunk) === 'string')
|
||||
chunk = new Buffer(chunk, 'binary');
|
||||
this.chunks.push(chunk);
|
||||
};
|
||||
|
||||
Verifier.prototype.verify = function (signature, fmt) {
|
||||
var sig;
|
||||
if (Signature.isSignature(signature, [2, 0])) {
|
||||
sig = signature.toBuffer('raw');
|
||||
|
||||
} else if (typeof (signature) === 'string') {
|
||||
sig = new Buffer(signature, 'base64');
|
||||
|
||||
} else if (Signature.isSignature(signature, [1, 0])) {
|
||||
throw (new Error('signature was created by too old ' +
|
||||
'a version of sshpk and cannot be verified'));
|
||||
}
|
||||
|
||||
assert.buffer(sig);
|
||||
return (nacl.sign.detached.verify(
|
||||
new Uint8Array(Buffer.concat(this.chunks)),
|
||||
new Uint8Array(sig),
|
||||
new Uint8Array(this.key.part.R.data)));
|
||||
};
|
||||
|
||||
function Signer(key, hashAlgo) {
|
||||
if (nacl === undefined)
|
||||
nacl = require('tweetnacl');
|
||||
|
||||
if (hashAlgo.toLowerCase() !== 'sha512')
|
||||
throw (new Error('ED25519 only supports the use of ' +
|
||||
'SHA-512 hashes'));
|
||||
|
||||
this.key = key;
|
||||
this.chunks = [];
|
||||
|
||||
stream.Writable.call(this, {});
|
||||
}
|
||||
util.inherits(Signer, stream.Writable);
|
||||
|
||||
Signer.prototype._write = function (chunk, enc, cb) {
|
||||
this.chunks.push(chunk);
|
||||
cb();
|
||||
};
|
||||
|
||||
Signer.prototype.update = function (chunk) {
|
||||
if (typeof (chunk) === 'string')
|
||||
chunk = new Buffer(chunk, 'binary');
|
||||
this.chunks.push(chunk);
|
||||
};
|
||||
|
||||
Signer.prototype.sign = function () {
|
||||
var sig = nacl.sign.detached(
|
||||
new Uint8Array(Buffer.concat(this.chunks)),
|
||||
new Uint8Array(this.key.part.r.data));
|
||||
var sigBuf = new Buffer(sig);
|
||||
var sigObj = Signature.parse(sigBuf, 'ed25519', 'raw');
|
||||
sigObj.hashAlgorithm = 'sha512';
|
||||
return (sigObj);
|
||||
};
|
||||
58
node_modules/sshpk/lib/errors.js
generated
vendored
Normal file
58
node_modules/sshpk/lib/errors.js
generated
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
// Copyright 2015 Joyent, Inc.
|
||||
|
||||
var assert = require('assert-plus');
|
||||
var util = require('util');
|
||||
|
||||
function FingerprintFormatError(fp, format) {
|
||||
if (Error.captureStackTrace)
|
||||
Error.captureStackTrace(this, FingerprintFormatError);
|
||||
this.name = 'FingerprintFormatError';
|
||||
this.fingerprint = fp;
|
||||
this.format = format;
|
||||
this.message = 'Fingerprint format is not supported, or is invalid: ';
|
||||
if (fp !== undefined)
|
||||
this.message += ' fingerprint = ' + fp;
|
||||
if (format !== undefined)
|
||||
this.message += ' format = ' + format;
|
||||
}
|
||||
util.inherits(FingerprintFormatError, Error);
|
||||
|
||||
function InvalidAlgorithmError(alg) {
|
||||
if (Error.captureStackTrace)
|
||||
Error.captureStackTrace(this, InvalidAlgorithmError);
|
||||
this.name = 'InvalidAlgorithmError';
|
||||
this.algorithm = alg;
|
||||
this.message = 'Algorithm "' + alg + '" is not supported';
|
||||
}
|
||||
util.inherits(InvalidAlgorithmError, Error);
|
||||
|
||||
function KeyParseError(name, format, innerErr) {
|
||||
if (Error.captureStackTrace)
|
||||
Error.captureStackTrace(this, KeyParseError);
|
||||
this.name = 'KeyParseError';
|
||||
this.format = format;
|
||||
this.keyName = name;
|
||||
this.innerErr = innerErr;
|
||||
this.message = 'Failed to parse ' + name + ' as a valid ' + format +
|
||||
' format key: ' + innerErr.message;
|
||||
}
|
||||
util.inherits(KeyParseError, Error);
|
||||
|
||||
function SignatureParseError(type, format, innerErr) {
|
||||
if (Error.captureStackTrace)
|
||||
Error.captureStackTrace(this, SignatureParseError);
|
||||
this.name = 'SignatureParseError';
|
||||
this.type = type;
|
||||
this.format = format;
|
||||
this.innerErr = innerErr;
|
||||
this.message = 'Failed to parse the given data as a ' + type +
|
||||
' signature in ' + format + ' format: ' + innerErr.message;
|
||||
}
|
||||
util.inherits(SignatureParseError, Error);
|
||||
|
||||
module.exports = {
|
||||
FingerprintFormatError: FingerprintFormatError,
|
||||
InvalidAlgorithmError: InvalidAlgorithmError,
|
||||
KeyParseError: KeyParseError,
|
||||
SignatureParseError: SignatureParseError
|
||||
};
|
||||
140
node_modules/sshpk/lib/fingerprint.js
generated
vendored
Normal file
140
node_modules/sshpk/lib/fingerprint.js
generated
vendored
Normal file
@@ -0,0 +1,140 @@
|
||||
// Copyright 2015 Joyent, Inc.
|
||||
|
||||
module.exports = Fingerprint;
|
||||
|
||||
var assert = require('assert-plus');
|
||||
var algs = require('./algs');
|
||||
var crypto = require('crypto');
|
||||
var errs = require('./errors');
|
||||
var Key = require('./key');
|
||||
var utils = require('./utils');
|
||||
|
||||
var FingerprintFormatError = errs.FingerprintFormatError;
|
||||
var InvalidAlgorithmError = errs.InvalidAlgorithmError;
|
||||
|
||||
function Fingerprint(opts) {
|
||||
assert.object(opts, 'options');
|
||||
assert.buffer(opts.hash, 'options.hash');
|
||||
assert.string(opts.algorithm, 'options.algorithm');
|
||||
|
||||
this.algorithm = opts.algorithm.toLowerCase();
|
||||
if (algs.hashAlgs[this.algorithm] !== true)
|
||||
throw (new InvalidAlgorithmError(this.algorithm));
|
||||
|
||||
this.hash = opts.hash;
|
||||
}
|
||||
|
||||
Fingerprint.prototype.toString = function (format) {
|
||||
if (format === undefined) {
|
||||
if (this.algorithm === 'md5')
|
||||
format = 'hex';
|
||||
else
|
||||
format = 'base64';
|
||||
}
|
||||
assert.string(format);
|
||||
|
||||
switch (format) {
|
||||
case 'hex':
|
||||
return (addColons(this.hash.toString('hex')));
|
||||
case 'base64':
|
||||
return (sshBase64Format(this.algorithm,
|
||||
this.hash.toString('base64')));
|
||||
default:
|
||||
throw (new FingerprintFormatError(undefined, format));
|
||||
}
|
||||
};
|
||||
|
||||
Fingerprint.prototype.matches = function (key) {
|
||||
assert.object(key, 'key');
|
||||
utils.assertCompatible(key, Key, [1, 0], 'key');
|
||||
|
||||
var theirHash = key.hash(this.algorithm);
|
||||
var theirHash2 = crypto.createHash(this.algorithm).
|
||||
update(theirHash).digest('base64');
|
||||
|
||||
if (this.hash2 === undefined)
|
||||
this.hash2 = crypto.createHash(this.algorithm).
|
||||
update(this.hash).digest('base64');
|
||||
|
||||
return (this.hash2 === theirHash2);
|
||||
};
|
||||
|
||||
Fingerprint.parse = function (fp, enAlgs) {
|
||||
assert.string(fp, 'fingerprint');
|
||||
|
||||
var alg, hash;
|
||||
assert.optionalArrayOfString(enAlgs, 'algorithms');
|
||||
|
||||
var parts = fp.split(':');
|
||||
if (parts.length == 2) {
|
||||
alg = parts[0].toLowerCase();
|
||||
/*JSSTYLED*/
|
||||
var base64RE = /^[A-Za-z0-9+\/=]+$/;
|
||||
if (!base64RE.test(parts[1]))
|
||||
throw (new FingerprintFormatError(fp));
|
||||
try {
|
||||
hash = new Buffer(parts[1], 'base64');
|
||||
} catch (e) {
|
||||
throw (new FingerprintFormatError(fp));
|
||||
}
|
||||
} else if (parts.length > 2) {
|
||||
alg = 'md5';
|
||||
if (parts[0].toLowerCase() === 'md5')
|
||||
parts = parts.slice(1);
|
||||
parts = parts.join('');
|
||||
/*JSSTYLED*/
|
||||
var md5RE = /^[a-fA-F0-9]+$/;
|
||||
if (!md5RE.test(parts))
|
||||
throw (new FingerprintFormatError(fp));
|
||||
try {
|
||||
hash = new Buffer(parts, 'hex');
|
||||
} catch (e) {
|
||||
throw (new FingerprintFormatError(fp));
|
||||
}
|
||||
}
|
||||
|
||||
if (alg === undefined)
|
||||
throw (new FingerprintFormatError(fp));
|
||||
|
||||
if (algs.hashAlgs[alg] === undefined)
|
||||
throw (new InvalidAlgorithmError(alg));
|
||||
|
||||
if (enAlgs !== undefined) {
|
||||
enAlgs = enAlgs.map(function (a) { return a.toLowerCase(); });
|
||||
if (enAlgs.indexOf(alg) === -1)
|
||||
throw (new InvalidAlgorithmError(alg));
|
||||
}
|
||||
|
||||
return (new Fingerprint({algorithm: alg, hash: hash}));
|
||||
};
|
||||
|
||||
function addColons(s) {
|
||||
/*JSSTYLED*/
|
||||
return (s.replace(/(.{2})(?=.)/g, '$1:'));
|
||||
}
|
||||
|
||||
function base64Strip(s) {
|
||||
/*JSSTYLED*/
|
||||
return (s.replace(/=*$/, ''));
|
||||
}
|
||||
|
||||
function sshBase64Format(alg, h) {
|
||||
return (alg.toUpperCase() + ':' + base64Strip(h));
|
||||
}
|
||||
|
||||
Fingerprint.isFingerprint = function (obj, ver) {
|
||||
return (utils.isCompatible(obj, Fingerprint, ver));
|
||||
};
|
||||
|
||||
/*
|
||||
* API versions for Fingerprint:
|
||||
* [1,0] -- initial ver
|
||||
* [1,1] -- first tagged ver
|
||||
*/
|
||||
Fingerprint.prototype._sshpkApiVersion = [1, 1];
|
||||
|
||||
Fingerprint._oldVersionDetect = function (obj) {
|
||||
assert.func(obj.toString);
|
||||
assert.func(obj.matches);
|
||||
return ([1, 0]);
|
||||
};
|
||||
73
node_modules/sshpk/lib/formats/auto.js
generated
vendored
Normal file
73
node_modules/sshpk/lib/formats/auto.js
generated
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
// Copyright 2015 Joyent, Inc.
|
||||
|
||||
module.exports = {
|
||||
read: read,
|
||||
write: write
|
||||
};
|
||||
|
||||
var assert = require('assert-plus');
|
||||
var utils = require('../utils');
|
||||
var Key = require('../key');
|
||||
var PrivateKey = require('../private-key');
|
||||
|
||||
var pem = require('./pem');
|
||||
var ssh = require('./ssh');
|
||||
var rfc4253 = require('./rfc4253');
|
||||
|
||||
function read(buf) {
|
||||
if (typeof (buf) === 'string') {
|
||||
if (buf.trim().match(/^[-]+[ ]*BEGIN/))
|
||||
return (pem.read(buf));
|
||||
if (buf.match(/^\s*ssh-[a-z]/))
|
||||
return (ssh.read(buf));
|
||||
if (buf.match(/^\s*ecdsa-/))
|
||||
return (ssh.read(buf));
|
||||
buf = new Buffer(buf, 'binary');
|
||||
} else {
|
||||
assert.buffer(buf);
|
||||
if (findPEMHeader(buf))
|
||||
return (pem.read(buf));
|
||||
if (findSSHHeader(buf))
|
||||
return (ssh.read(buf));
|
||||
}
|
||||
if (buf.readUInt32BE(0) < buf.length)
|
||||
return (rfc4253.read(buf));
|
||||
throw (new Error('Failed to auto-detect format of key'));
|
||||
}
|
||||
|
||||
function findSSHHeader(buf) {
|
||||
var offset = 0;
|
||||
while (offset < buf.length &&
|
||||
(buf[offset] === 32 || buf[offset] === 10 || buf[offset] === 9))
|
||||
++offset;
|
||||
if (offset + 4 <= buf.length &&
|
||||
buf.slice(offset, offset + 4).toString('ascii') === 'ssh-')
|
||||
return (true);
|
||||
if (offset + 6 <= buf.length &&
|
||||
buf.slice(offset, offset + 6).toString('ascii') === 'ecdsa-')
|
||||
return (true);
|
||||
return (false);
|
||||
}
|
||||
|
||||
function findPEMHeader(buf) {
|
||||
var offset = 0;
|
||||
while (offset < buf.length &&
|
||||
(buf[offset] === 32 || buf[offset] === 10))
|
||||
++offset;
|
||||
if (buf[offset] !== 45)
|
||||
return (false);
|
||||
while (offset < buf.length &&
|
||||
(buf[offset] === 45))
|
||||
++offset;
|
||||
while (offset < buf.length &&
|
||||
(buf[offset] === 32))
|
||||
++offset;
|
||||
if (offset + 5 > buf.length ||
|
||||
buf.slice(offset, offset + 5).toString('ascii') !== 'BEGIN')
|
||||
return (false);
|
||||
return (true);
|
||||
}
|
||||
|
||||
function write(key) {
|
||||
throw (new Error('"auto" format cannot be used for writing'));
|
||||
}
|
||||
152
node_modules/sshpk/lib/formats/pem.js
generated
vendored
Normal file
152
node_modules/sshpk/lib/formats/pem.js
generated
vendored
Normal file
@@ -0,0 +1,152 @@
|
||||
// Copyright 2015 Joyent, Inc.
|
||||
|
||||
module.exports = {
|
||||
read: read,
|
||||
write: write
|
||||
};
|
||||
|
||||
var assert = require('assert-plus');
|
||||
var asn1 = require('asn1');
|
||||
var algs = require('../algs');
|
||||
var utils = require('../utils');
|
||||
var Key = require('../key');
|
||||
var PrivateKey = require('../private-key');
|
||||
|
||||
var pkcs1 = require('./pkcs1');
|
||||
var pkcs8 = require('./pkcs8');
|
||||
var sshpriv = require('./ssh-private');
|
||||
var rfc4253 = require('./rfc4253');
|
||||
|
||||
/*
|
||||
* For reading we support both PKCS#1 and PKCS#8. If we find a private key,
|
||||
* we just take the public component of it and use that.
|
||||
*/
|
||||
function read(buf, forceType) {
|
||||
var input = buf;
|
||||
if (typeof (buf) !== 'string') {
|
||||
assert.buffer(buf, 'buf');
|
||||
buf = buf.toString('ascii');
|
||||
}
|
||||
|
||||
var lines = buf.trim().split('\n');
|
||||
|
||||
var m = lines[0].match(/*JSSTYLED*/
|
||||
/[-]+[ ]*BEGIN ([A-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[ ]*[-]+/);
|
||||
assert.ok(m2, 'invalid PEM footer');
|
||||
|
||||
/* Begin and end banners must match key type */
|
||||
assert.equal(m[2], m2[2]);
|
||||
var type = m[2].toLowerCase();
|
||||
|
||||
var alg;
|
||||
if (m[1]) {
|
||||
/* They also must match algorithms, if given */
|
||||
assert.equal(m[1], m2[1], 'PEM header and footer mismatch');
|
||||
alg = m[1].trim();
|
||||
}
|
||||
|
||||
var headers = {};
|
||||
while (true) {
|
||||
lines = lines.slice(1);
|
||||
m = lines[0].match(/*JSSTYLED*/
|
||||
/^([A-Za-z0-9-]+): (.+)$/);
|
||||
if (!m)
|
||||
break;
|
||||
headers[m[1].toLowerCase()] = m[2];
|
||||
}
|
||||
if (headers['proc-type']) {
|
||||
var parts = headers['proc-type'].split(',');
|
||||
if (parts[0] === '4' && parts[1] === 'ENCRYPTED') {
|
||||
throw (new Error('PEM key is encrypted ' +
|
||||
'(password-protected). Please use the ' +
|
||||
'SSH agent or decrypt the key.'));
|
||||
}
|
||||
}
|
||||
|
||||
/* Chop off the first and last lines */
|
||||
lines = lines.slice(0, -1).join('');
|
||||
buf = new Buffer(lines, 'base64');
|
||||
|
||||
/* The new OpenSSH internal format abuses PEM headers */
|
||||
if (alg && alg.toLowerCase() === 'openssh')
|
||||
return (sshpriv.readSSHPrivate(type, buf));
|
||||
if (alg && alg.toLowerCase() === 'ssh2')
|
||||
return (rfc4253.readType(type, buf));
|
||||
|
||||
var der = new asn1.BerReader(buf);
|
||||
der.originalInput = input;
|
||||
|
||||
/*
|
||||
* All of the PEM file types start with a sequence tag, so chop it
|
||||
* off here
|
||||
*/
|
||||
der.readSequence();
|
||||
|
||||
/* PKCS#1 type keys name an algorithm in the banner explicitly */
|
||||
if (alg) {
|
||||
if (forceType)
|
||||
assert.strictEqual(forceType, 'pkcs1');
|
||||
return (pkcs1.readPkcs1(alg, type, der));
|
||||
} else {
|
||||
if (forceType)
|
||||
assert.strictEqual(forceType, 'pkcs8');
|
||||
return (pkcs8.readPkcs8(alg, type, der));
|
||||
}
|
||||
}
|
||||
|
||||
function write(key, type) {
|
||||
assert.object(key);
|
||||
|
||||
var alg = {'ecdsa': 'EC', 'rsa': 'RSA', 'dsa': 'DSA'}[key.type];
|
||||
var header;
|
||||
|
||||
var der = new asn1.BerWriter();
|
||||
|
||||
if (PrivateKey.isPrivateKey(key)) {
|
||||
if (type && type === 'pkcs8') {
|
||||
header = 'PRIVATE KEY';
|
||||
pkcs8.writePkcs8(der, key);
|
||||
} else {
|
||||
if (type)
|
||||
assert.strictEqual(type, 'pkcs1');
|
||||
header = alg + ' PRIVATE KEY';
|
||||
pkcs1.writePkcs1(der, key);
|
||||
}
|
||||
|
||||
} else if (Key.isKey(key)) {
|
||||
if (type && type === 'pkcs1') {
|
||||
header = alg + ' PUBLIC KEY';
|
||||
pkcs1.writePkcs1(der, key);
|
||||
} else {
|
||||
if (type)
|
||||
assert.strictEqual(type, 'pkcs8');
|
||||
header = 'PUBLIC KEY';
|
||||
pkcs8.writePkcs8(der, key);
|
||||
}
|
||||
|
||||
} else {
|
||||
throw (new Error('key is not a Key or PrivateKey'));
|
||||
}
|
||||
|
||||
var tmp = der.buffer.toString('base64');
|
||||
var len = tmp.length + (tmp.length / 64) +
|
||||
18 + 16 + header.length*2 + 10;
|
||||
var buf = new Buffer(len);
|
||||
var o = 0;
|
||||
o += buf.write('-----BEGIN ' + header + '-----\n', o);
|
||||
for (var i = 0; i < tmp.length; ) {
|
||||
var limit = i + 64;
|
||||
if (limit > tmp.length)
|
||||
limit = tmp.length;
|
||||
o += buf.write(tmp.slice(i, limit), o);
|
||||
buf[o++] = 10;
|
||||
i = limit;
|
||||
}
|
||||
o += buf.write('-----END ' + header + '-----\n', o);
|
||||
|
||||
return (buf.slice(0, o));
|
||||
}
|
||||
320
node_modules/sshpk/lib/formats/pkcs1.js
generated
vendored
Normal file
320
node_modules/sshpk/lib/formats/pkcs1.js
generated
vendored
Normal file
@@ -0,0 +1,320 @@
|
||||
// Copyright 2015 Joyent, Inc.
|
||||
|
||||
module.exports = {
|
||||
read: read,
|
||||
readPkcs1: readPkcs1,
|
||||
write: write,
|
||||
writePkcs1: writePkcs1
|
||||
};
|
||||
|
||||
var assert = require('assert-plus');
|
||||
var asn1 = require('asn1');
|
||||
var algs = require('../algs');
|
||||
var utils = require('../utils');
|
||||
|
||||
var Key = require('../key');
|
||||
var PrivateKey = require('../private-key');
|
||||
var pem = require('./pem');
|
||||
|
||||
var pkcs8 = require('./pkcs8');
|
||||
var readECDSACurve = pkcs8.readECDSACurve;
|
||||
|
||||
function read(buf) {
|
||||
return (pem.read(buf, 'pkcs1'));
|
||||
}
|
||||
|
||||
function write(key) {
|
||||
return (pem.write(key, 'pkcs1'));
|
||||
}
|
||||
|
||||
/* Helper to read in a single mpint */
|
||||
function readMPInt(der, nm) {
|
||||
assert.strictEqual(der.peek(), asn1.Ber.Integer,
|
||||
nm + ' is not an Integer');
|
||||
return (utils.mpNormalize(der.readString(asn1.Ber.Integer, true)));
|
||||
}
|
||||
|
||||
function readPkcs1(alg, type, der) {
|
||||
switch (alg) {
|
||||
case 'RSA':
|
||||
if (type === 'public')
|
||||
return (readPkcs1RSAPublic(der));
|
||||
else if (type === 'private')
|
||||
return (readPkcs1RSAPrivate(der));
|
||||
throw (new Error('Unknown key type: ' + type));
|
||||
case 'DSA':
|
||||
if (type === 'public')
|
||||
return (readPkcs1DSAPublic(der));
|
||||
else if (type === 'private')
|
||||
return (readPkcs1DSAPrivate(der));
|
||||
throw (new Error('Unknown key type: ' + type));
|
||||
case 'EC':
|
||||
case 'ECDSA':
|
||||
if (type === 'private')
|
||||
return (readPkcs1ECDSAPrivate(der));
|
||||
else if (type === 'public')
|
||||
return (readPkcs1ECDSAPublic(der));
|
||||
throw (new Error('Unknown key type: ' + type));
|
||||
default:
|
||||
throw (new Error('Unknown key algo: ' + alg));
|
||||
}
|
||||
}
|
||||
|
||||
function readPkcs1RSAPublic(der) {
|
||||
// modulus and exponent
|
||||
var n = readMPInt(der, 'modulus');
|
||||
var e = readMPInt(der, 'exponent');
|
||||
|
||||
// now, make the key
|
||||
var key = {
|
||||
type: 'rsa',
|
||||
parts: [
|
||||
{ name: 'e', data: e },
|
||||
{ name: 'n', data: n }
|
||||
]
|
||||
};
|
||||
|
||||
return (new Key(key));
|
||||
}
|
||||
|
||||
function readPkcs1RSAPrivate(der) {
|
||||
var version = readMPInt(der, 'version');
|
||||
assert.strictEqual(version[0], 0);
|
||||
|
||||
// modulus then public exponent
|
||||
var n = readMPInt(der, 'modulus');
|
||||
var e = readMPInt(der, 'public exponent');
|
||||
var d = readMPInt(der, 'private exponent');
|
||||
var p = readMPInt(der, 'prime1');
|
||||
var q = readMPInt(der, 'prime2');
|
||||
var dmodp = readMPInt(der, 'exponent1');
|
||||
var dmodq = readMPInt(der, 'exponent2');
|
||||
var iqmp = readMPInt(der, 'iqmp');
|
||||
|
||||
// now, make the key
|
||||
var key = {
|
||||
type: 'rsa',
|
||||
parts: [
|
||||
{ name: 'n', data: n },
|
||||
{ name: 'e', data: e },
|
||||
{ name: 'd', data: d },
|
||||
{ name: 'iqmp', data: iqmp },
|
||||
{ name: 'p', data: p },
|
||||
{ name: 'q', data: q },
|
||||
{ name: 'dmodp', data: dmodp },
|
||||
{ name: 'dmodq', data: dmodq }
|
||||
]
|
||||
};
|
||||
|
||||
return (new PrivateKey(key));
|
||||
}
|
||||
|
||||
function readPkcs1DSAPrivate(der) {
|
||||
var version = readMPInt(der, 'version');
|
||||
assert.strictEqual(version.readUInt8(0), 0);
|
||||
|
||||
var p = readMPInt(der, 'p');
|
||||
var q = readMPInt(der, 'q');
|
||||
var g = readMPInt(der, 'g');
|
||||
var y = readMPInt(der, 'y');
|
||||
var x = readMPInt(der, 'x');
|
||||
|
||||
// now, make the key
|
||||
var key = {
|
||||
type: 'dsa',
|
||||
parts: [
|
||||
{ name: 'p', data: p },
|
||||
{ name: 'q', data: q },
|
||||
{ name: 'g', data: g },
|
||||
{ name: 'y', data: y },
|
||||
{ name: 'x', data: x }
|
||||
]
|
||||
};
|
||||
|
||||
return (new PrivateKey(key));
|
||||
}
|
||||
|
||||
function readPkcs1DSAPublic(der) {
|
||||
var y = readMPInt(der, 'y');
|
||||
var p = readMPInt(der, 'p');
|
||||
var q = readMPInt(der, 'q');
|
||||
var g = readMPInt(der, 'g');
|
||||
|
||||
var key = {
|
||||
type: 'dsa',
|
||||
parts: [
|
||||
{ name: 'y', data: y },
|
||||
{ name: 'p', data: p },
|
||||
{ name: 'q', data: q },
|
||||
{ name: 'g', data: g }
|
||||
]
|
||||
};
|
||||
|
||||
return (new Key(key));
|
||||
}
|
||||
|
||||
function readPkcs1ECDSAPublic(der) {
|
||||
der.readSequence();
|
||||
|
||||
var oid = der.readOID();
|
||||
assert.strictEqual(oid, '1.2.840.10045.2.1', 'must be ecPublicKey');
|
||||
|
||||
var curveOid = der.readOID();
|
||||
|
||||
var curve;
|
||||
var curves = Object.keys(algs.curves);
|
||||
for (var j = 0; j < curves.length; ++j) {
|
||||
var c = curves[j];
|
||||
var cd = algs.curves[c];
|
||||
if (cd.pkcs8oid === curveOid) {
|
||||
curve = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert.string(curve, 'a known ECDSA named curve');
|
||||
|
||||
var Q = der.readString(asn1.Ber.BitString, true);
|
||||
Q = utils.ecNormalize(Q);
|
||||
|
||||
var key = {
|
||||
type: 'ecdsa',
|
||||
parts: [
|
||||
{ name: 'curve', data: new Buffer(curve) },
|
||||
{ name: 'Q', data: Q }
|
||||
]
|
||||
};
|
||||
|
||||
return (new Key(key));
|
||||
}
|
||||
|
||||
function readPkcs1ECDSAPrivate(der) {
|
||||
var version = readMPInt(der, 'version');
|
||||
assert.strictEqual(version.readUInt8(0), 1);
|
||||
|
||||
// private key
|
||||
var d = der.readString(asn1.Ber.OctetString, true);
|
||||
|
||||
der.readSequence(0xa0);
|
||||
var curve = readECDSACurve(der);
|
||||
assert.string(curve, 'a known elliptic curve');
|
||||
|
||||
der.readSequence(0xa1);
|
||||
var Q = der.readString(asn1.Ber.BitString, true);
|
||||
Q = utils.ecNormalize(Q);
|
||||
|
||||
var key = {
|
||||
type: 'ecdsa',
|
||||
parts: [
|
||||
{ name: 'curve', data: new Buffer(curve) },
|
||||
{ name: 'Q', data: Q },
|
||||
{ name: 'd', data: d }
|
||||
]
|
||||
};
|
||||
|
||||
return (new PrivateKey(key));
|
||||
}
|
||||
|
||||
function writePkcs1(der, key) {
|
||||
der.startSequence();
|
||||
|
||||
switch (key.type) {
|
||||
case 'rsa':
|
||||
if (PrivateKey.isPrivateKey(key))
|
||||
writePkcs1RSAPrivate(der, key);
|
||||
else
|
||||
writePkcs1RSAPublic(der, key);
|
||||
break;
|
||||
case 'dsa':
|
||||
if (PrivateKey.isPrivateKey(key))
|
||||
writePkcs1DSAPrivate(der, key);
|
||||
else
|
||||
writePkcs1DSAPublic(der, key);
|
||||
break;
|
||||
case 'ecdsa':
|
||||
if (PrivateKey.isPrivateKey(key))
|
||||
writePkcs1ECDSAPrivate(der, key);
|
||||
else
|
||||
writePkcs1ECDSAPublic(der, key);
|
||||
break;
|
||||
default:
|
||||
throw (new Error('Unknown key algo: ' + key.type));
|
||||
}
|
||||
|
||||
der.endSequence();
|
||||
}
|
||||
|
||||
function writePkcs1RSAPublic(der, key) {
|
||||
der.writeBuffer(key.part.n.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.e.data, asn1.Ber.Integer);
|
||||
}
|
||||
|
||||
function writePkcs1RSAPrivate(der, key) {
|
||||
var ver = new Buffer(1);
|
||||
ver[0] = 0;
|
||||
der.writeBuffer(ver, asn1.Ber.Integer);
|
||||
|
||||
der.writeBuffer(key.part.n.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.e.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.d.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.p.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.q.data, asn1.Ber.Integer);
|
||||
if (!key.part.dmodp || !key.part.dmodq)
|
||||
utils.addRSAMissing(key);
|
||||
der.writeBuffer(key.part.dmodp.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.dmodq.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.iqmp.data, asn1.Ber.Integer);
|
||||
}
|
||||
|
||||
function writePkcs1DSAPrivate(der, key) {
|
||||
var ver = new Buffer(1);
|
||||
ver[0] = 0;
|
||||
der.writeBuffer(ver, asn1.Ber.Integer);
|
||||
|
||||
der.writeBuffer(key.part.p.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.q.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.g.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.y.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.x.data, asn1.Ber.Integer);
|
||||
}
|
||||
|
||||
function writePkcs1DSAPublic(der, key) {
|
||||
der.writeBuffer(key.part.y.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.p.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.q.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.g.data, asn1.Ber.Integer);
|
||||
}
|
||||
|
||||
function writePkcs1ECDSAPublic(der, key) {
|
||||
der.startSequence();
|
||||
|
||||
der.writeOID('1.2.840.10045.2.1'); /* ecPublicKey */
|
||||
var curve = key.part.curve.data.toString();
|
||||
var curveOid = algs.curves[curve].pkcs8oid;
|
||||
assert.string(curveOid, 'a known ECDSA named curve');
|
||||
der.writeOID(curveOid);
|
||||
|
||||
der.endSequence();
|
||||
|
||||
var Q = utils.ecNormalize(key.part.Q.data, true);
|
||||
der.writeBuffer(Q, asn1.Ber.BitString);
|
||||
}
|
||||
|
||||
function writePkcs1ECDSAPrivate(der, key) {
|
||||
var ver = new Buffer(1);
|
||||
ver[0] = 1;
|
||||
der.writeBuffer(ver, asn1.Ber.Integer);
|
||||
|
||||
der.writeBuffer(key.part.d.data, asn1.Ber.OctetString);
|
||||
|
||||
der.startSequence(0xa0);
|
||||
var curve = key.part.curve.data.toString();
|
||||
var curveOid = algs.curves[curve].pkcs8oid;
|
||||
assert.string(curveOid, 'a known ECDSA named curve');
|
||||
der.writeOID(curveOid);
|
||||
der.endSequence();
|
||||
|
||||
der.startSequence(0xa1);
|
||||
var Q = utils.ecNormalize(key.part.Q.data, true);
|
||||
der.writeBuffer(Q, asn1.Ber.BitString);
|
||||
der.endSequence();
|
||||
}
|
||||
510
node_modules/sshpk/lib/formats/pkcs8.js
generated
vendored
Normal file
510
node_modules/sshpk/lib/formats/pkcs8.js
generated
vendored
Normal file
@@ -0,0 +1,510 @@
|
||||
// Copyright 2015 Joyent, Inc.
|
||||
|
||||
module.exports = {
|
||||
read: read,
|
||||
readPkcs8: readPkcs8,
|
||||
write: write,
|
||||
writePkcs8: writePkcs8,
|
||||
|
||||
readECDSACurve: readECDSACurve,
|
||||
writeECDSACurve: writeECDSACurve
|
||||
};
|
||||
|
||||
var assert = require('assert-plus');
|
||||
var asn1 = require('asn1');
|
||||
var algs = require('../algs');
|
||||
var utils = require('../utils');
|
||||
var Key = require('../key');
|
||||
var PrivateKey = require('../private-key');
|
||||
var pem = require('./pem');
|
||||
|
||||
function read(buf) {
|
||||
return (pem.read(buf, 'pkcs8'));
|
||||
}
|
||||
|
||||
function write(key) {
|
||||
return (pem.write(key, 'pkcs8'));
|
||||
}
|
||||
|
||||
/* Helper to read in a single mpint */
|
||||
function readMPInt(der, nm) {
|
||||
assert.strictEqual(der.peek(), asn1.Ber.Integer,
|
||||
nm + ' is not an Integer');
|
||||
return (utils.mpNormalize(der.readString(asn1.Ber.Integer, true)));
|
||||
}
|
||||
|
||||
function readPkcs8(alg, type, der) {
|
||||
/* Private keys in pkcs#8 format have a weird extra int */
|
||||
if (der.peek() === asn1.Ber.Integer) {
|
||||
assert.strictEqual(type, 'private',
|
||||
'unexpected Integer at start of public key');
|
||||
der.readString(asn1.Ber.Integer, true);
|
||||
}
|
||||
|
||||
der.readSequence();
|
||||
|
||||
var oid = der.readOID();
|
||||
switch (oid) {
|
||||
case '1.2.840.113549.1.1.1':
|
||||
if (type === 'public')
|
||||
return (readPkcs8RSAPublic(der));
|
||||
else
|
||||
return (readPkcs8RSAPrivate(der));
|
||||
case '1.2.840.10040.4.1':
|
||||
if (type === 'public')
|
||||
return (readPkcs8DSAPublic(der));
|
||||
else
|
||||
return (readPkcs8DSAPrivate(der));
|
||||
case '1.2.840.10045.2.1':
|
||||
if (type === 'public')
|
||||
return (readPkcs8ECDSAPublic(der));
|
||||
else
|
||||
return (readPkcs8ECDSAPrivate(der));
|
||||
default:
|
||||
throw (new Error('Unknown key type OID ' + oid));
|
||||
}
|
||||
}
|
||||
|
||||
function readPkcs8RSAPublic(der) {
|
||||
// Null -- XXX this probably isn't good practice
|
||||
der.readByte();
|
||||
der.readByte();
|
||||
|
||||
// bit string sequence
|
||||
der.readSequence(asn1.Ber.BitString);
|
||||
der.readByte();
|
||||
der.readSequence();
|
||||
|
||||
// modulus
|
||||
var n = readMPInt(der, 'modulus');
|
||||
var e = readMPInt(der, 'exponent');
|
||||
|
||||
// now, make the key
|
||||
var key = {
|
||||
type: 'rsa',
|
||||
source: der.originalInput,
|
||||
parts: [
|
||||
{ name: 'e', data: e },
|
||||
{ name: 'n', data: n }
|
||||
]
|
||||
};
|
||||
|
||||
return (new Key(key));
|
||||
}
|
||||
|
||||
function readPkcs8RSAPrivate(der) {
|
||||
der.readByte();
|
||||
der.readByte();
|
||||
|
||||
der.readSequence(asn1.Ber.OctetString);
|
||||
der.readSequence();
|
||||
|
||||
var ver = readMPInt(der, 'version');
|
||||
assert.equal(ver[0], 0x0, 'unknown RSA private key version');
|
||||
|
||||
// modulus then public exponent
|
||||
var n = readMPInt(der, 'modulus');
|
||||
var e = readMPInt(der, 'public exponent');
|
||||
var d = readMPInt(der, 'private exponent');
|
||||
var p = readMPInt(der, 'prime1');
|
||||
var q = readMPInt(der, 'prime2');
|
||||
var dmodp = readMPInt(der, 'exponent1');
|
||||
var dmodq = readMPInt(der, 'exponent2');
|
||||
var iqmp = readMPInt(der, 'iqmp');
|
||||
|
||||
// now, make the key
|
||||
var key = {
|
||||
type: 'rsa',
|
||||
parts: [
|
||||
{ name: 'n', data: n },
|
||||
{ name: 'e', data: e },
|
||||
{ name: 'd', data: d },
|
||||
{ name: 'iqmp', data: iqmp },
|
||||
{ name: 'p', data: p },
|
||||
{ name: 'q', data: q },
|
||||
{ name: 'dmodp', data: dmodp },
|
||||
{ name: 'dmodq', data: dmodq }
|
||||
]
|
||||
};
|
||||
|
||||
return (new PrivateKey(key));
|
||||
}
|
||||
|
||||
function readPkcs8DSAPublic(der) {
|
||||
der.readSequence();
|
||||
|
||||
var p = readMPInt(der, 'p');
|
||||
var q = readMPInt(der, 'q');
|
||||
var g = readMPInt(der, 'g');
|
||||
|
||||
// bit string sequence
|
||||
der.readSequence(asn1.Ber.BitString);
|
||||
der.readByte();
|
||||
|
||||
var y = readMPInt(der, 'y');
|
||||
|
||||
// now, make the key
|
||||
var key = {
|
||||
type: 'dsa',
|
||||
parts: [
|
||||
{ name: 'p', data: p },
|
||||
{ name: 'q', data: q },
|
||||
{ name: 'g', data: g },
|
||||
{ name: 'y', data: y }
|
||||
]
|
||||
};
|
||||
|
||||
return (new Key(key));
|
||||
}
|
||||
|
||||
function readPkcs8DSAPrivate(der) {
|
||||
der.readSequence();
|
||||
|
||||
var p = readMPInt(der, 'p');
|
||||
var q = readMPInt(der, 'q');
|
||||
var g = readMPInt(der, 'g');
|
||||
|
||||
der.readSequence(asn1.Ber.OctetString);
|
||||
var x = readMPInt(der, 'x');
|
||||
|
||||
/* The pkcs#8 format does not include the public key */
|
||||
var y = utils.calculateDSAPublic(g, p, x);
|
||||
|
||||
var key = {
|
||||
type: 'dsa',
|
||||
parts: [
|
||||
{ name: 'p', data: p },
|
||||
{ name: 'q', data: q },
|
||||
{ name: 'g', data: g },
|
||||
{ name: 'y', data: y },
|
||||
{ name: 'x', data: x }
|
||||
]
|
||||
};
|
||||
|
||||
return (new PrivateKey(key));
|
||||
}
|
||||
|
||||
function readECDSACurve(der) {
|
||||
var curveName, curveNames;
|
||||
var j, c, cd;
|
||||
|
||||
if (der.peek() === asn1.Ber.OID) {
|
||||
var oid = der.readOID();
|
||||
|
||||
curveNames = Object.keys(algs.curves);
|
||||
for (j = 0; j < curveNames.length; ++j) {
|
||||
c = curveNames[j];
|
||||
cd = algs.curves[c];
|
||||
if (cd.pkcs8oid === oid) {
|
||||
curveName = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// ECParameters sequence
|
||||
der.readSequence();
|
||||
var version = der.readString(asn1.Ber.Integer, true);
|
||||
assert.strictEqual(version[0], 1, 'ECDSA key not version 1');
|
||||
|
||||
var curve = {};
|
||||
|
||||
// FieldID sequence
|
||||
der.readSequence();
|
||||
var fieldTypeOid = der.readOID();
|
||||
assert.strictEqual(fieldTypeOid, '1.2.840.10045.1.1',
|
||||
'ECDSA key is not from a prime-field');
|
||||
var p = curve.p = utils.mpNormalize(
|
||||
der.readString(asn1.Ber.Integer, true));
|
||||
/*
|
||||
* p always starts with a 1 bit, so count the zeros to get its
|
||||
* real size.
|
||||
*/
|
||||
curve.size = p.length * 8 - utils.countZeros(p);
|
||||
|
||||
// Curve sequence
|
||||
der.readSequence();
|
||||
curve.a = utils.mpNormalize(
|
||||
der.readString(asn1.Ber.OctetString, true));
|
||||
curve.b = utils.mpNormalize(
|
||||
der.readString(asn1.Ber.OctetString, true));
|
||||
if (der.peek() === asn1.Ber.BitString)
|
||||
curve.s = der.readString(asn1.Ber.BitString, true);
|
||||
|
||||
// Combined Gx and Gy
|
||||
curve.G = der.readString(asn1.Ber.OctetString, true);
|
||||
assert.strictEqual(curve.G[0], 0x4,
|
||||
'uncompressed G is required');
|
||||
|
||||
curve.n = utils.mpNormalize(
|
||||
der.readString(asn1.Ber.Integer, true));
|
||||
curve.h = utils.mpNormalize(
|
||||
der.readString(asn1.Ber.Integer, true));
|
||||
assert.strictEqual(curve.h[0], 0x1, 'a cofactor=1 curve is ' +
|
||||
'required');
|
||||
|
||||
curveNames = Object.keys(algs.curves);
|
||||
var ks = Object.keys(curve);
|
||||
for (j = 0; j < curveNames.length; ++j) {
|
||||
c = curveNames[j];
|
||||
cd = algs.curves[c];
|
||||
var equal = true;
|
||||
for (var i = 0; i < ks.length; ++i) {
|
||||
var k = ks[i];
|
||||
if (cd[k] === undefined)
|
||||
continue;
|
||||
if (typeof (cd[k]) === 'object' &&
|
||||
cd[k].equals !== undefined) {
|
||||
if (!cd[k].equals(curve[k])) {
|
||||
equal = false;
|
||||
break;
|
||||
}
|
||||
} else if (Buffer.isBuffer(cd[k])) {
|
||||
if (cd[k].toString('binary')
|
||||
!== curve[k].toString('binary')) {
|
||||
equal = false;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (cd[k] !== curve[k]) {
|
||||
equal = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (equal) {
|
||||
curveName = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (curveName);
|
||||
}
|
||||
|
||||
function readPkcs8ECDSAPrivate(der) {
|
||||
var curveName = readECDSACurve(der);
|
||||
assert.string(curveName, 'a known elliptic curve');
|
||||
|
||||
der.readSequence(asn1.Ber.OctetString);
|
||||
der.readSequence();
|
||||
|
||||
var version = readMPInt(der, 'version');
|
||||
assert.equal(version[0], 1, 'unknown version of ECDSA key');
|
||||
|
||||
var d = der.readString(asn1.Ber.OctetString, true);
|
||||
der.readSequence(0xa1);
|
||||
|
||||
var Q = der.readString(asn1.Ber.BitString, true);
|
||||
Q = utils.ecNormalize(Q);
|
||||
|
||||
var key = {
|
||||
type: 'ecdsa',
|
||||
parts: [
|
||||
{ name: 'curve', data: new Buffer(curveName) },
|
||||
{ name: 'Q', data: Q },
|
||||
{ name: 'd', data: d }
|
||||
]
|
||||
};
|
||||
|
||||
return (new PrivateKey(key));
|
||||
}
|
||||
|
||||
function readPkcs8ECDSAPublic(der) {
|
||||
var curveName = readECDSACurve(der);
|
||||
assert.string(curveName, 'a known elliptic curve');
|
||||
|
||||
var Q = der.readString(asn1.Ber.BitString, true);
|
||||
Q = utils.ecNormalize(Q);
|
||||
|
||||
var key = {
|
||||
type: 'ecdsa',
|
||||
parts: [
|
||||
{ name: 'curve', data: new Buffer(curveName) },
|
||||
{ name: 'Q', data: Q }
|
||||
]
|
||||
};
|
||||
|
||||
return (new Key(key));
|
||||
}
|
||||
|
||||
function writePkcs8(der, key) {
|
||||
der.startSequence();
|
||||
|
||||
if (PrivateKey.isPrivateKey(key)) {
|
||||
var sillyInt = new Buffer(1);
|
||||
sillyInt[0] = 0x0;
|
||||
der.writeBuffer(sillyInt, asn1.Ber.Integer);
|
||||
}
|
||||
|
||||
der.startSequence();
|
||||
switch (key.type) {
|
||||
case 'rsa':
|
||||
der.writeOID('1.2.840.113549.1.1.1');
|
||||
if (PrivateKey.isPrivateKey(key))
|
||||
writePkcs8RSAPrivate(key, der);
|
||||
else
|
||||
writePkcs8RSAPublic(key, der);
|
||||
break;
|
||||
case 'dsa':
|
||||
der.writeOID('1.2.840.10040.4.1');
|
||||
if (PrivateKey.isPrivateKey(key))
|
||||
writePkcs8DSAPrivate(key, der);
|
||||
else
|
||||
writePkcs8DSAPublic(key, der);
|
||||
break;
|
||||
case 'ecdsa':
|
||||
der.writeOID('1.2.840.10045.2.1');
|
||||
if (PrivateKey.isPrivateKey(key))
|
||||
writePkcs8ECDSAPrivate(key, der);
|
||||
else
|
||||
writePkcs8ECDSAPublic(key, der);
|
||||
break;
|
||||
default:
|
||||
throw (new Error('Unsupported key type: ' + key.type));
|
||||
}
|
||||
|
||||
der.endSequence();
|
||||
}
|
||||
|
||||
function writePkcs8RSAPrivate(key, der) {
|
||||
der.writeNull();
|
||||
der.endSequence();
|
||||
|
||||
der.startSequence(asn1.Ber.OctetString);
|
||||
der.startSequence();
|
||||
|
||||
var version = new Buffer(1);
|
||||
version[0] = 0;
|
||||
der.writeBuffer(version, asn1.Ber.Integer);
|
||||
|
||||
der.writeBuffer(key.part.n.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.e.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.d.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.p.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.q.data, asn1.Ber.Integer);
|
||||
if (!key.part.dmodp || !key.part.dmodq)
|
||||
utils.addRSAMissing(key);
|
||||
der.writeBuffer(key.part.dmodp.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.dmodq.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.iqmp.data, asn1.Ber.Integer);
|
||||
|
||||
der.endSequence();
|
||||
der.endSequence();
|
||||
}
|
||||
|
||||
function writePkcs8RSAPublic(key, der) {
|
||||
der.writeNull();
|
||||
der.endSequence();
|
||||
|
||||
der.startSequence(asn1.Ber.BitString);
|
||||
der.writeByte(0x00);
|
||||
|
||||
der.startSequence();
|
||||
der.writeBuffer(key.part.n.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.e.data, asn1.Ber.Integer);
|
||||
der.endSequence();
|
||||
|
||||
der.endSequence();
|
||||
}
|
||||
|
||||
function writePkcs8DSAPrivate(key, der) {
|
||||
der.startSequence();
|
||||
der.writeBuffer(key.part.p.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.q.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.g.data, asn1.Ber.Integer);
|
||||
der.endSequence();
|
||||
|
||||
der.endSequence();
|
||||
|
||||
der.startSequence(asn1.Ber.OctetString);
|
||||
der.writeBuffer(key.part.x.data, asn1.Ber.Integer);
|
||||
der.endSequence();
|
||||
}
|
||||
|
||||
function writePkcs8DSAPublic(key, der) {
|
||||
der.startSequence();
|
||||
der.writeBuffer(key.part.p.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.q.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.g.data, asn1.Ber.Integer);
|
||||
der.endSequence();
|
||||
der.endSequence();
|
||||
|
||||
der.startSequence(asn1.Ber.BitString);
|
||||
der.writeByte(0x00);
|
||||
der.writeBuffer(key.part.y.data, asn1.Ber.Integer);
|
||||
der.endSequence();
|
||||
}
|
||||
|
||||
function writeECDSACurve(key, der) {
|
||||
var curve = algs.curves[key.curve];
|
||||
if (curve.pkcs8oid) {
|
||||
/* This one has a name in pkcs#8, so just write the oid */
|
||||
der.writeOID(curve.pkcs8oid);
|
||||
|
||||
} else {
|
||||
// ECParameters sequence
|
||||
der.startSequence();
|
||||
|
||||
var version = new Buffer(1);
|
||||
version.writeUInt8(1, 0);
|
||||
der.writeBuffer(version, asn1.Ber.Integer);
|
||||
|
||||
// FieldID sequence
|
||||
der.startSequence();
|
||||
der.writeOID('1.2.840.10045.1.1'); // prime-field
|
||||
der.writeBuffer(curve.p, asn1.Ber.Integer);
|
||||
der.endSequence();
|
||||
|
||||
// Curve sequence
|
||||
der.startSequence();
|
||||
var a = curve.p;
|
||||
if (a[0] === 0x0)
|
||||
a = a.slice(1);
|
||||
der.writeBuffer(a, asn1.Ber.OctetString);
|
||||
der.writeBuffer(curve.b, asn1.Ber.OctetString);
|
||||
der.writeBuffer(curve.s, asn1.Ber.BitString);
|
||||
der.endSequence();
|
||||
|
||||
der.writeBuffer(curve.G, asn1.Ber.OctetString);
|
||||
der.writeBuffer(curve.n, asn1.Ber.Integer);
|
||||
var h = curve.h;
|
||||
if (!h) {
|
||||
h = new Buffer(1);
|
||||
h[0] = 1;
|
||||
}
|
||||
der.writeBuffer(h, asn1.Ber.Integer);
|
||||
|
||||
// ECParameters
|
||||
der.endSequence();
|
||||
}
|
||||
}
|
||||
|
||||
function writePkcs8ECDSAPublic(key, der) {
|
||||
writeECDSACurve(key, der);
|
||||
der.endSequence();
|
||||
|
||||
var Q = utils.ecNormalize(key.part.Q.data, true);
|
||||
der.writeBuffer(Q, asn1.Ber.BitString);
|
||||
}
|
||||
|
||||
function writePkcs8ECDSAPrivate(key, der) {
|
||||
writeECDSACurve(key, der);
|
||||
der.endSequence();
|
||||
|
||||
der.startSequence(asn1.Ber.OctetString);
|
||||
der.startSequence();
|
||||
|
||||
var version = new Buffer(1);
|
||||
version[0] = 1;
|
||||
der.writeBuffer(version, asn1.Ber.Integer);
|
||||
|
||||
der.writeBuffer(key.part.d.data, asn1.Ber.OctetString);
|
||||
|
||||
der.startSequence(0xa1);
|
||||
var Q = utils.ecNormalize(key.part.Q.data, true);
|
||||
der.writeBuffer(Q, asn1.Ber.BitString);
|
||||
der.endSequence();
|
||||
|
||||
der.endSequence();
|
||||
der.endSequence();
|
||||
}
|
||||
145
node_modules/sshpk/lib/formats/rfc4253.js
generated
vendored
Normal file
145
node_modules/sshpk/lib/formats/rfc4253.js
generated
vendored
Normal file
@@ -0,0 +1,145 @@
|
||||
// Copyright 2015 Joyent, Inc.
|
||||
|
||||
module.exports = {
|
||||
read: read.bind(undefined, false, undefined),
|
||||
readType: read.bind(undefined, false),
|
||||
write: write,
|
||||
/* semi-private api, used by sshpk-agent */
|
||||
readPartial: read.bind(undefined, true),
|
||||
|
||||
/* shared with ssh format */
|
||||
readInternal: read,
|
||||
keyTypeToAlg: keyTypeToAlg,
|
||||
algToKeyType: algToKeyType
|
||||
};
|
||||
|
||||
var assert = require('assert-plus');
|
||||
var algs = require('../algs');
|
||||
var utils = require('../utils');
|
||||
var Key = require('../key');
|
||||
var PrivateKey = require('../private-key');
|
||||
var SSHBuffer = require('../ssh-buffer');
|
||||
|
||||
function algToKeyType(alg) {
|
||||
assert.string(alg);
|
||||
if (alg === 'ssh-dss')
|
||||
return ('dsa');
|
||||
else if (alg === 'ssh-rsa')
|
||||
return ('rsa');
|
||||
else if (alg === 'ssh-ed25519')
|
||||
return ('ed25519');
|
||||
else if (alg === 'ssh-curve25519')
|
||||
return ('curve25519');
|
||||
else if (alg.match(/^ecdsa-sha2-/))
|
||||
return ('ecdsa');
|
||||
else
|
||||
throw (new Error('Unknown algorithm ' + alg));
|
||||
}
|
||||
|
||||
function keyTypeToAlg(key) {
|
||||
assert.object(key);
|
||||
if (key.type === 'dsa')
|
||||
return ('ssh-dss');
|
||||
else if (key.type === 'rsa')
|
||||
return ('ssh-rsa');
|
||||
else if (key.type === 'ed25519')
|
||||
return ('ssh-ed25519');
|
||||
else if (key.type === 'curve25519')
|
||||
return ('ssh-curve25519');
|
||||
else if (key.type === 'ecdsa')
|
||||
return ('ecdsa-sha2-' + key.part.curve.data.toString());
|
||||
else
|
||||
throw (new Error('Unknown key type ' + key.type));
|
||||
}
|
||||
|
||||
function read(partial, type, buf) {
|
||||
if (typeof (buf) === 'string')
|
||||
buf = new Buffer(buf);
|
||||
assert.buffer(buf, 'buf');
|
||||
|
||||
var key = {};
|
||||
|
||||
var parts = key.parts = [];
|
||||
var sshbuf = new SSHBuffer({buffer: buf});
|
||||
|
||||
var alg = sshbuf.readString();
|
||||
assert.ok(!sshbuf.atEnd(), 'key must have at least one part');
|
||||
|
||||
key.type = algToKeyType(alg);
|
||||
|
||||
var partCount = algs.info[key.type].parts.length;
|
||||
if (type && type === 'private')
|
||||
partCount = algs.privInfo[key.type].parts.length;
|
||||
|
||||
while (!sshbuf.atEnd() && parts.length < partCount)
|
||||
parts.push(sshbuf.readPart());
|
||||
while (!partial && !sshbuf.atEnd())
|
||||
parts.push(sshbuf.readPart());
|
||||
|
||||
assert.ok(parts.length >= 1,
|
||||
'key must have at least one part');
|
||||
assert.ok(partial || sshbuf.atEnd(),
|
||||
'leftover bytes at end of key');
|
||||
|
||||
var Constructor = Key;
|
||||
var algInfo = algs.info[key.type];
|
||||
if (type === 'private' || algInfo.parts.length !== parts.length) {
|
||||
algInfo = algs.privInfo[key.type];
|
||||
Constructor = PrivateKey;
|
||||
}
|
||||
assert.strictEqual(algInfo.parts.length, parts.length);
|
||||
|
||||
if (key.type === 'ecdsa') {
|
||||
var res = /^ecdsa-sha2-(.+)$/.exec(alg);
|
||||
assert.ok(res !== null);
|
||||
assert.strictEqual(res[1], parts[0].data.toString());
|
||||
}
|
||||
|
||||
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) {
|
||||
p.data = nd;
|
||||
normalized = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (normalized)
|
||||
key._rfc4253Cache = sshbuf.toBuffer();
|
||||
|
||||
if (partial && typeof (partial) === 'object') {
|
||||
partial.remainder = sshbuf.remainder();
|
||||
partial.consumed = sshbuf._offset;
|
||||
}
|
||||
|
||||
return (new Constructor(key));
|
||||
}
|
||||
|
||||
function write(key) {
|
||||
assert.object(key);
|
||||
|
||||
var alg = keyTypeToAlg(key);
|
||||
var i;
|
||||
|
||||
var algInfo = algs.info[key.type];
|
||||
if (PrivateKey.isPrivateKey(key))
|
||||
algInfo = algs.privInfo[key.type];
|
||||
var parts = algInfo.parts;
|
||||
|
||||
var buf = new SSHBuffer({});
|
||||
|
||||
buf.writeString(alg);
|
||||
|
||||
for (i = 0; i < parts.length; ++i) {
|
||||
var data = key.part[parts[i]].data;
|
||||
data = utils.mpNormalize(data);
|
||||
buf.writeBuffer(data);
|
||||
}
|
||||
|
||||
return (buf.toBuffer());
|
||||
}
|
||||
138
node_modules/sshpk/lib/formats/ssh-private.js
generated
vendored
Normal file
138
node_modules/sshpk/lib/formats/ssh-private.js
generated
vendored
Normal file
@@ -0,0 +1,138 @@
|
||||
// Copyright 2015 Joyent, Inc.
|
||||
|
||||
module.exports = {
|
||||
read: read,
|
||||
readSSHPrivate: readSSHPrivate,
|
||||
write: write
|
||||
};
|
||||
|
||||
var assert = require('assert-plus');
|
||||
var asn1 = require('asn1');
|
||||
var algs = require('../algs');
|
||||
var utils = require('../utils');
|
||||
var crypto = require('crypto');
|
||||
|
||||
var Key = require('../key');
|
||||
var PrivateKey = require('../private-key');
|
||||
var pem = require('./pem');
|
||||
var rfc4253 = require('./rfc4253');
|
||||
var SSHBuffer = require('../ssh-buffer');
|
||||
|
||||
function read(buf) {
|
||||
return (pem.read(buf));
|
||||
}
|
||||
|
||||
var MAGIC = 'openssh-key-v1';
|
||||
|
||||
function readSSHPrivate(type, buf) {
|
||||
buf = new SSHBuffer({buffer: buf});
|
||||
|
||||
var magic = buf.readCString();
|
||||
assert.strictEqual(magic, MAGIC, 'bad magic string');
|
||||
|
||||
var cipher = buf.readString();
|
||||
var kdf = buf.readString();
|
||||
|
||||
/* We only support unencrypted keys. */
|
||||
if (cipher !== 'none' || kdf !== 'none') {
|
||||
throw (new Error('OpenSSH-format key is encrypted ' +
|
||||
'(password-protected). Please use the SSH agent ' +
|
||||
'or decrypt the key.'));
|
||||
}
|
||||
|
||||
/* Skip over kdfoptions. */
|
||||
buf.readString();
|
||||
|
||||
var nkeys = buf.readInt();
|
||||
if (nkeys !== 1) {
|
||||
throw (new Error('OpenSSH-format key file contains ' +
|
||||
'multiple keys: this is unsupported.'));
|
||||
}
|
||||
|
||||
var pubKey = buf.readBuffer();
|
||||
|
||||
if (type === 'public') {
|
||||
assert.ok(buf.atEnd(), 'excess bytes left after key');
|
||||
return (rfc4253.read(pubKey));
|
||||
}
|
||||
|
||||
var privKeyBlob = buf.readBuffer();
|
||||
assert.ok(buf.atEnd(), 'excess bytes left after key');
|
||||
|
||||
buf = new SSHBuffer({buffer: privKeyBlob});
|
||||
|
||||
var checkInt1 = buf.readInt();
|
||||
var checkInt2 = buf.readInt();
|
||||
assert.strictEqual(checkInt1, checkInt2, 'checkints do not match');
|
||||
|
||||
var ret = {};
|
||||
var key = rfc4253.readInternal(ret, 'private', buf.remainder());
|
||||
|
||||
buf.skip(ret.consumed);
|
||||
|
||||
var comment = buf.readString();
|
||||
key.comment = comment;
|
||||
|
||||
return (key);
|
||||
}
|
||||
|
||||
function write(key) {
|
||||
var pubKey;
|
||||
if (PrivateKey.isPrivateKey(key))
|
||||
pubKey = key.toPublic();
|
||||
else
|
||||
pubKey = key;
|
||||
|
||||
var privBuf;
|
||||
if (PrivateKey.isPrivateKey(key)) {
|
||||
privBuf = new SSHBuffer({});
|
||||
var checkInt = crypto.randomBytes(4).readUInt32BE(0);
|
||||
privBuf.writeInt(checkInt);
|
||||
privBuf.writeInt(checkInt);
|
||||
privBuf.write(key.toBuffer('rfc4253'));
|
||||
privBuf.writeString(key.comment || '');
|
||||
|
||||
var n = 1;
|
||||
while (privBuf._offset % 8 !== 0)
|
||||
privBuf.writeChar(n++);
|
||||
}
|
||||
|
||||
var buf = new SSHBuffer({});
|
||||
|
||||
buf.writeCString(MAGIC);
|
||||
buf.writeString('none'); /* cipher */
|
||||
buf.writeString('none'); /* kdf */
|
||||
buf.writeBuffer(new Buffer(0)); /* kdfoptions */
|
||||
|
||||
buf.writeInt(1); /* nkeys */
|
||||
buf.writeBuffer(pubKey.toBuffer('rfc4253'));
|
||||
|
||||
if (privBuf)
|
||||
buf.writeBuffer(privBuf.toBuffer());
|
||||
|
||||
buf = buf.toBuffer();
|
||||
|
||||
var header;
|
||||
if (PrivateKey.isPrivateKey(key))
|
||||
header = 'OPENSSH PRIVATE KEY';
|
||||
else
|
||||
header = 'OPENSSH PUBLIC KEY';
|
||||
|
||||
var tmp = buf.toString('base64');
|
||||
var len = tmp.length + (tmp.length / 70) +
|
||||
18 + 16 + header.length*2 + 10;
|
||||
buf = new Buffer(len);
|
||||
var o = 0;
|
||||
o += buf.write('-----BEGIN ' + header + '-----\n', o);
|
||||
for (var i = 0; i < tmp.length; ) {
|
||||
var limit = i + 70;
|
||||
if (limit > tmp.length)
|
||||
limit = tmp.length;
|
||||
o += buf.write(tmp.slice(i, limit), o);
|
||||
buf[o++] = 10;
|
||||
i = limit;
|
||||
}
|
||||
o += buf.write('-----END ' + header + '-----\n', o);
|
||||
|
||||
return (buf.slice(0, o));
|
||||
}
|
||||
114
node_modules/sshpk/lib/formats/ssh.js
generated
vendored
Normal file
114
node_modules/sshpk/lib/formats/ssh.js
generated
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
// Copyright 2015 Joyent, Inc.
|
||||
|
||||
module.exports = {
|
||||
read: read,
|
||||
write: write
|
||||
};
|
||||
|
||||
var assert = require('assert-plus');
|
||||
var rfc4253 = require('./rfc4253');
|
||||
var utils = require('../utils');
|
||||
var Key = require('../key');
|
||||
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]+))?$/;
|
||||
/*JSSTYLED*/
|
||||
var SSHKEY_RE2 = /^([a-z0-9-]+)[ \t]+([a-zA-Z0-9+\/ \t\n]+[=]*)(.*)$/;
|
||||
|
||||
function read(buf) {
|
||||
if (typeof (buf) !== 'string') {
|
||||
assert.buffer(buf, 'buf');
|
||||
buf = buf.toString('ascii');
|
||||
}
|
||||
|
||||
var trimmed = buf.trim().replace(/[\\\r]/g, '');
|
||||
var m = trimmed.match(SSHKEY_RE);
|
||||
if (!m)
|
||||
m = trimmed.match(SSHKEY_RE2);
|
||||
assert.ok(m, 'key must match regex');
|
||||
|
||||
var type = rfc4253.algToKeyType(m[1]);
|
||||
var kbuf = new Buffer(m[2], 'base64');
|
||||
|
||||
/*
|
||||
* This is a bit tricky. If we managed to parse the key and locate the
|
||||
* key comment with the regex, then do a non-partial read and assert
|
||||
* that we have consumed all bytes. If we couldn't locate the key
|
||||
* comment, though, there may be whitespace shenanigans going on that
|
||||
* have conjoined the comment to the rest of the key. We do a partial
|
||||
* read in this case to try to make the best out of a sorry situation.
|
||||
*/
|
||||
var key;
|
||||
var ret = {};
|
||||
if (m[4]) {
|
||||
try {
|
||||
key = rfc4253.read(kbuf);
|
||||
|
||||
} catch (e) {
|
||||
m = trimmed.match(SSHKEY_RE2);
|
||||
assert.ok(m, 'key must match regex');
|
||||
kbuf = new Buffer(m[2], 'base64');
|
||||
key = rfc4253.readInternal(ret, 'public', kbuf);
|
||||
}
|
||||
} else {
|
||||
key = rfc4253.readInternal(ret, 'public', kbuf);
|
||||
}
|
||||
|
||||
assert.strictEqual(type, key.type);
|
||||
|
||||
if (m[4] && m[4].length > 0) {
|
||||
key.comment = m[4];
|
||||
|
||||
} else if (ret.consumed) {
|
||||
/*
|
||||
* Now the magic: trying to recover the key comment when it's
|
||||
* gotten conjoined to the key or otherwise shenanigan'd.
|
||||
*
|
||||
* Work out how much base64 we used, then drop all non-base64
|
||||
* 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 realOffset = Math.ceil(ret.consumed / 3) * 4;
|
||||
data = data.slice(0, realOffset - 2). /*JSSTYLED*/
|
||||
replace(/[^a-zA-Z0-9+\/=]/g, '') +
|
||||
data.slice(realOffset - 2);
|
||||
|
||||
var padding = ret.consumed % 3;
|
||||
if (padding > 0 &&
|
||||
data.slice(realOffset - 1, realOffset) !== '=')
|
||||
realOffset--;
|
||||
while (data.slice(realOffset, realOffset + 1) === '=')
|
||||
realOffset++;
|
||||
|
||||
/* Finally, grab what we think is the comment & clean it up. */
|
||||
var trailer = data.slice(realOffset);
|
||||
trailer = trailer.replace(/[\r\n]/g, ' ').
|
||||
replace(/^\s+/, '');
|
||||
if (trailer.match(/^[a-zA-Z0-9]/))
|
||||
key.comment = trailer;
|
||||
}
|
||||
|
||||
return (key);
|
||||
}
|
||||
|
||||
function write(key) {
|
||||
assert.object(key);
|
||||
if (!Key.isKey(key))
|
||||
throw (new Error('Must be a public key'));
|
||||
|
||||
var parts = [];
|
||||
var alg = rfc4253.keyTypeToAlg(key);
|
||||
parts.push(alg);
|
||||
|
||||
var buf = rfc4253.write(key);
|
||||
parts.push(buf.toString('base64'));
|
||||
|
||||
if (key.comment)
|
||||
parts.push(key.comment);
|
||||
|
||||
return (new Buffer(parts.join(' ')));
|
||||
}
|
||||
25
node_modules/sshpk/lib/index.js
generated
vendored
Normal file
25
node_modules/sshpk/lib/index.js
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
// Copyright 2015 Joyent, Inc.
|
||||
|
||||
var Key = require('./key');
|
||||
var Fingerprint = require('./fingerprint');
|
||||
var Signature = require('./signature');
|
||||
var PrivateKey = require('./private-key');
|
||||
var errs = require('./errors');
|
||||
|
||||
module.exports = {
|
||||
/* top-level classes */
|
||||
Key: Key,
|
||||
parseKey: Key.parse,
|
||||
Fingerprint: Fingerprint,
|
||||
parseFingerprint: Fingerprint.parse,
|
||||
Signature: Signature,
|
||||
parseSignature: Signature.parse,
|
||||
PrivateKey: PrivateKey,
|
||||
parsePrivateKey: PrivateKey.parse,
|
||||
|
||||
/* errors */
|
||||
FingerprintFormatError: errs.FingerprintFormatError,
|
||||
InvalidAlgorithmError: errs.InvalidAlgorithmError,
|
||||
KeyParseError: errs.KeyParseError,
|
||||
SignatureParseError: errs.SignatureParseError
|
||||
};
|
||||
260
node_modules/sshpk/lib/key.js
generated
vendored
Normal file
260
node_modules/sshpk/lib/key.js
generated
vendored
Normal file
@@ -0,0 +1,260 @@
|
||||
// Copyright 2015 Joyent, Inc.
|
||||
|
||||
module.exports = Key;
|
||||
|
||||
var assert = require('assert-plus');
|
||||
var algs = require('./algs');
|
||||
var crypto = require('crypto');
|
||||
var Fingerprint = require('./fingerprint');
|
||||
var Signature = require('./signature');
|
||||
var DiffieHellman = require('./dhe');
|
||||
var errs = require('./errors');
|
||||
var utils = require('./utils');
|
||||
var PrivateKey = require('./private-key');
|
||||
var edCompat;
|
||||
|
||||
try {
|
||||
edCompat = require('./ed-compat');
|
||||
} catch (e) {
|
||||
/* Just continue through, and bail out if we try to use it. */
|
||||
}
|
||||
|
||||
var InvalidAlgorithmError = errs.InvalidAlgorithmError;
|
||||
var KeyParseError = errs.KeyParseError;
|
||||
|
||||
var formats = {};
|
||||
formats['auto'] = require('./formats/auto');
|
||||
formats['pem'] = require('./formats/pem');
|
||||
formats['pkcs1'] = require('./formats/pkcs1');
|
||||
formats['pkcs8'] = require('./formats/pkcs8');
|
||||
formats['rfc4253'] = require('./formats/rfc4253');
|
||||
formats['ssh'] = require('./formats/ssh');
|
||||
formats['ssh-private'] = require('./formats/ssh-private');
|
||||
formats['openssh'] = formats['ssh-private'];
|
||||
|
||||
function Key(opts) {
|
||||
assert.object(opts, 'options');
|
||||
assert.arrayOfObject(opts.parts, 'options.parts');
|
||||
assert.string(opts.type, 'options.type');
|
||||
assert.optionalString(opts.comment, 'options.comment');
|
||||
|
||||
var algInfo = algs.info[opts.type];
|
||||
if (typeof (algInfo) !== 'object')
|
||||
throw (new InvalidAlgorithmError(opts.type));
|
||||
|
||||
var partLookup = {};
|
||||
for (var i = 0; i < opts.parts.length; ++i) {
|
||||
var part = opts.parts[i];
|
||||
partLookup[part.name] = part;
|
||||
}
|
||||
|
||||
this.type = opts.type;
|
||||
this.parts = opts.parts;
|
||||
this.part = partLookup;
|
||||
this.comment = undefined;
|
||||
this.source = opts.source;
|
||||
|
||||
/* for speeding up hashing/fingerprint operations */
|
||||
this._rfc4253Cache = opts._rfc4253Cache;
|
||||
this._hashCache = {};
|
||||
|
||||
var sz;
|
||||
this.curve = undefined;
|
||||
if (this.type === 'ecdsa') {
|
||||
var curve = this.part.curve.data.toString();
|
||||
this.curve = curve;
|
||||
sz = algs.curves[curve].size;
|
||||
} else if (this.type === 'ed25519') {
|
||||
sz = 256;
|
||||
this.curve = 'curve25519';
|
||||
} else {
|
||||
var szPart = this.part[algInfo.sizePart];
|
||||
sz = szPart.data.length;
|
||||
sz = sz * 8 - utils.countZeros(szPart.data);
|
||||
}
|
||||
this.size = sz;
|
||||
}
|
||||
|
||||
Key.formats = formats;
|
||||
|
||||
Key.prototype.toBuffer = function (format) {
|
||||
if (format === undefined)
|
||||
format = 'ssh';
|
||||
assert.string(format, 'format');
|
||||
assert.object(formats[format], 'formats[format]');
|
||||
|
||||
if (format === 'rfc4253') {
|
||||
if (this._rfc4253Cache === undefined)
|
||||
this._rfc4253Cache = formats['rfc4253'].write(this);
|
||||
return (this._rfc4253Cache);
|
||||
}
|
||||
|
||||
return (formats[format].write(this));
|
||||
};
|
||||
|
||||
Key.prototype.toString = function (format) {
|
||||
return (this.toBuffer(format).toString());
|
||||
};
|
||||
|
||||
Key.prototype.hash = function (algo) {
|
||||
assert.string(algo, 'algorithm');
|
||||
algo = algo.toLowerCase();
|
||||
if (algs.hashAlgs[algo] === undefined)
|
||||
throw (new InvalidAlgorithmError(algo));
|
||||
|
||||
if (this._hashCache[algo])
|
||||
return (this._hashCache[algo]);
|
||||
|
||||
var hash = crypto.createHash(algo).
|
||||
update(this.toBuffer('rfc4253')).digest();
|
||||
/* Workaround for node 0.8 */
|
||||
if (typeof (hash) === 'string')
|
||||
hash = new Buffer(hash, 'binary');
|
||||
this._hashCache[algo] = hash;
|
||||
return (hash);
|
||||
};
|
||||
|
||||
Key.prototype.fingerprint = function (algo) {
|
||||
if (algo === undefined)
|
||||
algo = 'sha256';
|
||||
assert.string(algo, 'algorithm');
|
||||
var opts = {
|
||||
hash: this.hash(algo),
|
||||
algorithm: algo
|
||||
};
|
||||
return (new Fingerprint(opts));
|
||||
};
|
||||
|
||||
Key.prototype.defaultHashAlgorithm = function () {
|
||||
var hashAlgo = 'sha1';
|
||||
if (this.type === 'rsa')
|
||||
hashAlgo = 'sha256';
|
||||
if (this.type === 'dsa' && this.size > 1024)
|
||||
hashAlgo = 'sha256';
|
||||
if (this.type === 'ed25519')
|
||||
hashAlgo = 'sha512';
|
||||
if (this.type === 'ecdsa') {
|
||||
if (this.size <= 256)
|
||||
hashAlgo = 'sha256';
|
||||
else if (this.size <= 384)
|
||||
hashAlgo = 'sha384';
|
||||
else
|
||||
hashAlgo = 'sha512';
|
||||
}
|
||||
return (hashAlgo);
|
||||
};
|
||||
|
||||
Key.prototype.createVerify = function (hashAlgo) {
|
||||
if (hashAlgo === undefined)
|
||||
hashAlgo = this.defaultHashAlgorithm();
|
||||
assert.string(hashAlgo, 'hash algorithm');
|
||||
|
||||
/* ED25519 is not supported by OpenSSL, use a javascript impl. */
|
||||
if (this.type === 'ed25519' && edCompat !== undefined)
|
||||
return (new edCompat.Verifier(this, hashAlgo));
|
||||
if (this.type === 'curve25519')
|
||||
throw (new Error('Curve25519 keys are not suitable for ' +
|
||||
'signing or verification'));
|
||||
|
||||
var v, nm, err;
|
||||
try {
|
||||
nm = this.type.toUpperCase() + '-';
|
||||
if (this.type === 'ecdsa')
|
||||
nm = 'ecdsa-with-';
|
||||
nm += hashAlgo.toUpperCase();
|
||||
v = crypto.createVerify(nm);
|
||||
} catch (e) {
|
||||
err = e;
|
||||
}
|
||||
if (v === undefined || (err instanceof Error &&
|
||||
err.message.match(/Unknown message digest/))) {
|
||||
nm = 'RSA-';
|
||||
nm += hashAlgo.toUpperCase();
|
||||
v = crypto.createVerify(nm);
|
||||
}
|
||||
assert.ok(v, 'failed to create verifier');
|
||||
var oldVerify = v.verify.bind(v);
|
||||
var key = this.toBuffer('pkcs8');
|
||||
v.verify = function (signature, fmt) {
|
||||
if (Signature.isSignature(signature, [2, 0])) {
|
||||
return (oldVerify(key, signature.toBuffer('asn1')));
|
||||
|
||||
} else if (typeof (signature) === 'string' ||
|
||||
Buffer.isBuffer(signature)) {
|
||||
return (oldVerify(key, signature, fmt));
|
||||
|
||||
/*
|
||||
* Avoid doing this on valid arguments, walking the prototype
|
||||
* chain can be quite slow.
|
||||
*/
|
||||
} else if (Signature.isSignature(signature, [1, 0])) {
|
||||
throw (new Error('signature was created by too old ' +
|
||||
'a version of sshpk and cannot be verified'));
|
||||
|
||||
} else {
|
||||
throw (new TypeError('signature must be a string, ' +
|
||||
'Buffer, or Signature object'));
|
||||
}
|
||||
};
|
||||
return (v);
|
||||
};
|
||||
|
||||
Key.prototype.createDiffieHellman = function () {
|
||||
if (this.type === 'rsa')
|
||||
throw (new Error('RSA keys do not support Diffie-Hellman'));
|
||||
|
||||
return (new DiffieHellman(this));
|
||||
};
|
||||
Key.prototype.createDH = Key.prototype.createDiffieHellman;
|
||||
|
||||
Key.parse = function (data, format, name) {
|
||||
if (typeof (data) !== 'string')
|
||||
assert.buffer(data, 'data');
|
||||
if (format === undefined)
|
||||
format = 'auto';
|
||||
assert.string(format, 'format');
|
||||
if (name === undefined)
|
||||
name = '(unnamed)';
|
||||
|
||||
assert.object(formats[format], 'formats[format]');
|
||||
|
||||
try {
|
||||
var k = formats[format].read(data);
|
||||
if (k instanceof PrivateKey)
|
||||
k = k.toPublic();
|
||||
if (!k.comment)
|
||||
k.comment = name;
|
||||
return (k);
|
||||
} catch (e) {
|
||||
throw (new KeyParseError(name, format, e));
|
||||
}
|
||||
};
|
||||
|
||||
Key.isKey = function (obj, ver) {
|
||||
return (utils.isCompatible(obj, Key, ver));
|
||||
};
|
||||
|
||||
/*
|
||||
* API versions for Key:
|
||||
* [1,0] -- initial ver, may take Signature for createVerify or may not
|
||||
* [1,1] -- added pkcs1, pkcs8 formats
|
||||
* [1,2] -- added auto, ssh-private, openssh formats
|
||||
* [1,3] -- added defaultHashAlgorithm
|
||||
* [1,4] -- added ed support, createDH
|
||||
* [1,5] -- first explicitly tagged version
|
||||
*/
|
||||
Key.prototype._sshpkApiVersion = [1, 5];
|
||||
|
||||
Key._oldVersionDetect = function (obj) {
|
||||
assert.func(obj.toBuffer);
|
||||
assert.func(obj.fingerprint);
|
||||
if (obj.createDH)
|
||||
return ([1, 4]);
|
||||
if (obj.defaultHashAlgorithm)
|
||||
return ([1, 3]);
|
||||
if (obj.formats['auto'])
|
||||
return ([1, 2]);
|
||||
if (obj.formats['pkcs1'])
|
||||
return ([1, 1]);
|
||||
return ([1, 0]);
|
||||
};
|
||||
224
node_modules/sshpk/lib/private-key.js
generated
vendored
Normal file
224
node_modules/sshpk/lib/private-key.js
generated
vendored
Normal file
@@ -0,0 +1,224 @@
|
||||
// Copyright 2015 Joyent, Inc.
|
||||
|
||||
module.exports = PrivateKey;
|
||||
|
||||
var assert = require('assert-plus');
|
||||
var algs = require('./algs');
|
||||
var crypto = require('crypto');
|
||||
var Fingerprint = require('./fingerprint');
|
||||
var Signature = require('./signature');
|
||||
var errs = require('./errors');
|
||||
var util = require('util');
|
||||
var utils = require('./utils');
|
||||
var edCompat;
|
||||
var ed;
|
||||
|
||||
try {
|
||||
edCompat = require('./ed-compat');
|
||||
} catch (e) {
|
||||
/* Just continue through, and bail out if we try to use it. */
|
||||
}
|
||||
|
||||
var Key = require('./key');
|
||||
|
||||
var InvalidAlgorithmError = errs.InvalidAlgorithmError;
|
||||
var KeyParseError = errs.KeyParseError;
|
||||
|
||||
var formats = {};
|
||||
formats['auto'] = require('./formats/auto');
|
||||
formats['pem'] = require('./formats/pem');
|
||||
formats['pkcs1'] = require('./formats/pkcs1');
|
||||
formats['pkcs8'] = require('./formats/pkcs8');
|
||||
formats['rfc4253'] = require('./formats/rfc4253');
|
||||
formats['ssh-private'] = require('./formats/ssh-private');
|
||||
formats['openssh'] = formats['ssh-private'];
|
||||
formats['ssh'] = formats['ssh-private'];
|
||||
|
||||
function PrivateKey(opts) {
|
||||
assert.object(opts, 'options');
|
||||
Key.call(this, opts);
|
||||
|
||||
this._pubCache = undefined;
|
||||
}
|
||||
util.inherits(PrivateKey, Key);
|
||||
|
||||
PrivateKey.formats = formats;
|
||||
|
||||
PrivateKey.prototype.toBuffer = function (format) {
|
||||
if (format === undefined)
|
||||
format = 'pkcs1';
|
||||
assert.string(format, 'format');
|
||||
assert.object(formats[format], 'formats[format]');
|
||||
|
||||
return (formats[format].write(this));
|
||||
};
|
||||
|
||||
PrivateKey.prototype.hash = function (algo) {
|
||||
return (this.toPublic().hash(algo));
|
||||
};
|
||||
|
||||
PrivateKey.prototype.toPublic = function () {
|
||||
if (this._pubCache)
|
||||
return (this._pubCache);
|
||||
|
||||
var algInfo = algs.info[this.type];
|
||||
var pubParts = [];
|
||||
for (var i = 0; i < algInfo.parts.length; ++i) {
|
||||
var p = algInfo.parts[i];
|
||||
pubParts.push(this.part[p]);
|
||||
}
|
||||
|
||||
this._pubCache = new Key({
|
||||
type: this.type,
|
||||
source: this,
|
||||
parts: pubParts
|
||||
});
|
||||
if (this.comment)
|
||||
this._pubCache.comment = this.comment;
|
||||
return (this._pubCache);
|
||||
};
|
||||
|
||||
PrivateKey.prototype.derive = function (newType, newSize) {
|
||||
assert.string(newType, 'type');
|
||||
assert.optionalNumber(newSize, 'size');
|
||||
var priv, pub;
|
||||
|
||||
if (this.type === 'ed25519' && newType === 'curve25519') {
|
||||
if (ed === undefined)
|
||||
ed = require('jodid25519');
|
||||
|
||||
priv = this.part.r.data;
|
||||
if (priv[0] === 0x00)
|
||||
priv = priv.slice(1);
|
||||
priv = priv.slice(0, 32);
|
||||
|
||||
pub = ed.dh.publicKey(priv);
|
||||
priv = utils.mpNormalize(Buffer.concat([priv, pub]));
|
||||
|
||||
return (new PrivateKey({
|
||||
type: 'curve25519',
|
||||
parts: [
|
||||
{ name: 'R', data: utils.mpNormalize(pub) },
|
||||
{ name: 'r', data: priv }
|
||||
]
|
||||
}));
|
||||
} else if (this.type === 'curve25519' && newType === 'ed25519') {
|
||||
if (ed === undefined)
|
||||
ed = require('jodid25519');
|
||||
|
||||
priv = this.part.r.data;
|
||||
if (priv[0] === 0x00)
|
||||
priv = priv.slice(1);
|
||||
priv = priv.slice(0, 32);
|
||||
|
||||
pub = ed.eddsa.publicKey(priv.toString('binary'));
|
||||
pub = new Buffer(pub, 'binary');
|
||||
|
||||
priv = utils.mpNormalize(Buffer.concat([priv, pub]));
|
||||
|
||||
return (new PrivateKey({
|
||||
type: 'ed25519',
|
||||
parts: [
|
||||
{ name: 'R', data: utils.mpNormalize(pub) },
|
||||
{ name: 'r', data: priv }
|
||||
]
|
||||
}));
|
||||
}
|
||||
throw (new Error('Key derivation not supported from ' + this.type +
|
||||
' to ' + newType));
|
||||
};
|
||||
|
||||
PrivateKey.prototype.createVerify = function (hashAlgo) {
|
||||
return (this.toPublic().createVerify(hashAlgo));
|
||||
};
|
||||
|
||||
PrivateKey.prototype.createSign = function (hashAlgo) {
|
||||
if (hashAlgo === undefined)
|
||||
hashAlgo = this.defaultHashAlgorithm();
|
||||
assert.string(hashAlgo, 'hash algorithm');
|
||||
|
||||
/* ED25519 is not supported by OpenSSL, use a javascript impl. */
|
||||
if (this.type === 'ed25519' && edCompat !== undefined)
|
||||
return (new edCompat.Signer(this, hashAlgo));
|
||||
if (this.type === 'curve25519')
|
||||
throw (new Error('Curve25519 keys are not suitable for ' +
|
||||
'signing or verification'));
|
||||
|
||||
var v, nm, err;
|
||||
try {
|
||||
nm = this.type.toUpperCase() + '-';
|
||||
if (this.type === 'ecdsa')
|
||||
nm = 'ecdsa-with-';
|
||||
nm += hashAlgo.toUpperCase();
|
||||
v = crypto.createSign(nm);
|
||||
} catch (e) {
|
||||
err = e;
|
||||
}
|
||||
if (v === undefined || (err instanceof Error &&
|
||||
err.message.match(/Unknown message digest/))) {
|
||||
nm = 'RSA-';
|
||||
nm += hashAlgo.toUpperCase();
|
||||
v = crypto.createSign(nm);
|
||||
}
|
||||
assert.ok(v, 'failed to create verifier');
|
||||
var oldSign = v.sign.bind(v);
|
||||
var key = this.toBuffer('pkcs1');
|
||||
var type = this.type;
|
||||
v.sign = function () {
|
||||
var sig = oldSign(key);
|
||||
if (typeof (sig) === 'string')
|
||||
sig = new Buffer(sig, 'binary');
|
||||
sig = Signature.parse(sig, type, 'asn1');
|
||||
sig.hashAlgorithm = hashAlgo;
|
||||
return (sig);
|
||||
};
|
||||
return (v);
|
||||
};
|
||||
|
||||
PrivateKey.parse = function (data, format, name) {
|
||||
if (typeof (data) !== 'string')
|
||||
assert.buffer(data, 'data');
|
||||
if (format === undefined)
|
||||
format = 'auto';
|
||||
assert.string(format, 'format');
|
||||
if (name === undefined)
|
||||
name = '(unnamed)';
|
||||
|
||||
assert.object(formats[format], 'formats[format]');
|
||||
|
||||
try {
|
||||
var k = formats[format].read(data);
|
||||
assert.ok(k instanceof PrivateKey, 'key is not a private key');
|
||||
if (!k.comment)
|
||||
k.comment = name;
|
||||
return (k);
|
||||
} catch (e) {
|
||||
throw (new KeyParseError(name, format, e));
|
||||
}
|
||||
};
|
||||
|
||||
PrivateKey.isPrivateKey = function (obj, ver) {
|
||||
return (utils.isCompatible(obj, PrivateKey, ver));
|
||||
};
|
||||
|
||||
/*
|
||||
* API versions for PrivateKey:
|
||||
* [1,0] -- initial ver
|
||||
* [1,1] -- added auto, pkcs[18], openssh/ssh-private formats
|
||||
* [1,2] -- added defaultHashAlgorithm
|
||||
* [1,3] -- added derive, ed, createDH
|
||||
* [1,4] -- first tagged version
|
||||
*/
|
||||
PrivateKey.prototype._sshpkApiVersion = [1, 4];
|
||||
|
||||
PrivateKey._oldVersionDetect = function (obj) {
|
||||
assert.func(obj.toPublic);
|
||||
assert.func(obj.createSign);
|
||||
if (obj.derive)
|
||||
return ([1, 3]);
|
||||
if (obj.defaultHashAlgorithm)
|
||||
return ([1, 2]);
|
||||
if (obj.formats['auto'])
|
||||
return ([1, 1]);
|
||||
return ([1, 0]);
|
||||
};
|
||||
237
node_modules/sshpk/lib/signature.js
generated
vendored
Normal file
237
node_modules/sshpk/lib/signature.js
generated
vendored
Normal file
@@ -0,0 +1,237 @@
|
||||
// Copyright 2015 Joyent, Inc.
|
||||
|
||||
module.exports = Signature;
|
||||
|
||||
var assert = require('assert-plus');
|
||||
var algs = require('./algs');
|
||||
var crypto = require('crypto');
|
||||
var errs = require('./errors');
|
||||
var utils = require('./utils');
|
||||
var asn1 = require('asn1');
|
||||
var SSHBuffer = require('./ssh-buffer');
|
||||
|
||||
var InvalidAlgorithmError = errs.InvalidAlgorithmError;
|
||||
var SignatureParseError = errs.SignatureParseError;
|
||||
|
||||
function Signature(opts) {
|
||||
assert.object(opts, 'options');
|
||||
assert.arrayOfObject(opts.parts, 'options.parts');
|
||||
assert.string(opts.type, 'options.type');
|
||||
|
||||
var partLookup = {};
|
||||
for (var i = 0; i < opts.parts.length; ++i) {
|
||||
var part = opts.parts[i];
|
||||
partLookup[part.name] = part;
|
||||
}
|
||||
|
||||
this.type = opts.type;
|
||||
this.hashAlgorithm = opts.hashAlgo;
|
||||
this.parts = opts.parts;
|
||||
this.part = partLookup;
|
||||
}
|
||||
|
||||
Signature.prototype.toBuffer = function (format) {
|
||||
if (format === undefined)
|
||||
format = 'asn1';
|
||||
assert.string(format, 'format');
|
||||
|
||||
var buf;
|
||||
|
||||
switch (this.type) {
|
||||
case 'rsa':
|
||||
case 'ed25519':
|
||||
if (format === 'ssh') {
|
||||
buf = new SSHBuffer({});
|
||||
buf.writeString('ssh-' + this.type);
|
||||
buf.writePart(this.part.sig);
|
||||
return (buf.toBuffer());
|
||||
} else {
|
||||
return (this.part.sig.data);
|
||||
}
|
||||
|
||||
case 'dsa':
|
||||
case 'ecdsa':
|
||||
var r, s;
|
||||
if (format === 'asn1') {
|
||||
var der = new asn1.BerWriter();
|
||||
der.startSequence();
|
||||
r = utils.mpNormalize(this.part.r.data);
|
||||
s = utils.mpNormalize(this.part.s.data);
|
||||
der.writeBuffer(r, asn1.Ber.Integer);
|
||||
der.writeBuffer(s, asn1.Ber.Integer);
|
||||
der.endSequence();
|
||||
return (der.buffer);
|
||||
} else if (format === 'ssh' && this.type === 'dsa') {
|
||||
buf = new SSHBuffer({});
|
||||
buf.writeString('ssh-dss');
|
||||
r = this.part.r.data;
|
||||
if (r[0] === 0x00)
|
||||
r = r.slice(1);
|
||||
s = this.part.s.data;
|
||||
buf.writeBuffer(Buffer.concat([r, s]));
|
||||
return (buf.toBuffer());
|
||||
} else if (format === 'ssh' && this.type === 'ecdsa') {
|
||||
var inner = new SSHBuffer({});
|
||||
r = this.part.r;
|
||||
if (r[0] === 0x00)
|
||||
r = r.slice(1);
|
||||
inner.writePart(r);
|
||||
inner.writePart(this.part.s);
|
||||
|
||||
buf = new SSHBuffer({});
|
||||
/* XXX: find a more proper way to do this? */
|
||||
var curve;
|
||||
var sz = this.part.r.data.length * 8;
|
||||
if (sz === 256)
|
||||
curve = 'nistp256';
|
||||
else if (sz === 384)
|
||||
curve = 'nistp384';
|
||||
else if (sz === 528)
|
||||
curve = 'nistp521';
|
||||
buf.writeString('ecdsa-sha2-' + curve);
|
||||
buf.writeBuffer(inner.toBuffer());
|
||||
return (buf.toBuffer());
|
||||
}
|
||||
throw (new Error('Invalid signature format'));
|
||||
default:
|
||||
throw (new Error('Invalid signature data'));
|
||||
}
|
||||
};
|
||||
|
||||
Signature.prototype.toString = function (format) {
|
||||
assert.optionalString(format, 'format');
|
||||
return (this.toBuffer(format).toString('base64'));
|
||||
};
|
||||
|
||||
Signature.parse = function (data, type, format) {
|
||||
if (typeof (data) === 'string')
|
||||
data = new Buffer(data, 'base64');
|
||||
assert.buffer(data, 'data');
|
||||
assert.string(format, 'format');
|
||||
assert.string(type, 'type');
|
||||
|
||||
var opts = {};
|
||||
opts.type = type.toLowerCase();
|
||||
opts.parts = [];
|
||||
|
||||
try {
|
||||
assert.ok(data.length > 0, 'signature must not be empty');
|
||||
switch (opts.type) {
|
||||
case 'rsa':
|
||||
return (parseOneNum(data, type, format, opts,
|
||||
'ssh-rsa'));
|
||||
case 'ed25519':
|
||||
return (parseOneNum(data, type, format, opts,
|
||||
'ssh-ed25519'));
|
||||
|
||||
case 'dsa':
|
||||
case 'ecdsa':
|
||||
if (format === 'asn1')
|
||||
return (parseDSAasn1(data, type, format, opts));
|
||||
else if (opts.type === 'dsa')
|
||||
return (parseDSA(data, type, format, opts));
|
||||
else
|
||||
return (parseECDSA(data, type, format, opts));
|
||||
|
||||
default:
|
||||
throw (new InvalidAlgorithmError(type));
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
if (e instanceof InvalidAlgorithmError)
|
||||
throw (e);
|
||||
throw (new SignatureParseError(type, format, e));
|
||||
}
|
||||
};
|
||||
|
||||
function parseOneNum(data, type, format, opts, headType) {
|
||||
if (format === 'ssh') {
|
||||
try {
|
||||
var buf = new SSHBuffer({buffer: data});
|
||||
var head = buf.readString();
|
||||
} catch (e) {
|
||||
/* fall through */
|
||||
}
|
||||
if (head === headType) {
|
||||
var sig = buf.readPart();
|
||||
assert.ok(buf.atEnd(), 'extra trailing bytes');
|
||||
sig.name = 'sig';
|
||||
opts.parts.push(sig);
|
||||
return (new Signature(opts));
|
||||
}
|
||||
}
|
||||
opts.parts.push({name: 'sig', data: data});
|
||||
return (new Signature(opts));
|
||||
}
|
||||
|
||||
function parseDSAasn1(data, type, format, opts) {
|
||||
var der = new asn1.BerReader(data);
|
||||
der.readSequence();
|
||||
var r = der.readString(asn1.Ber.Integer, true);
|
||||
var s = der.readString(asn1.Ber.Integer, true);
|
||||
|
||||
opts.parts.push({name: 'r', data: utils.mpNormalize(r)});
|
||||
opts.parts.push({name: 's', data: utils.mpNormalize(s)});
|
||||
|
||||
return (new Signature(opts));
|
||||
}
|
||||
|
||||
function parseDSA(data, type, format, opts) {
|
||||
if (data.length != 40) {
|
||||
var buf = new SSHBuffer({buffer: data});
|
||||
var d = buf.readBuffer();
|
||||
if (d.toString('ascii') === 'ssh-dss')
|
||||
d = buf.readBuffer();
|
||||
assert.ok(buf.atEnd(), 'extra trailing bytes');
|
||||
assert.strictEqual(d.length, 40, 'invalid inner length');
|
||||
data = d;
|
||||
}
|
||||
opts.parts.push({name: 'r', data: data.slice(0, 20)});
|
||||
opts.parts.push({name: 's', data: data.slice(20, 40)});
|
||||
return (new Signature(opts));
|
||||
}
|
||||
|
||||
function parseECDSA(data, type, format, opts) {
|
||||
var buf = new SSHBuffer({buffer: data});
|
||||
|
||||
var r, s;
|
||||
var inner = buf.readBuffer();
|
||||
if (inner.toString('ascii').match(/^ecdsa-/)) {
|
||||
inner = buf.readBuffer();
|
||||
assert.ok(buf.atEnd(), 'extra trailing bytes on outer');
|
||||
buf = new SSHBuffer({buffer: inner});
|
||||
r = buf.readPart();
|
||||
} else {
|
||||
r = {data: inner};
|
||||
}
|
||||
|
||||
s = buf.readPart();
|
||||
assert.ok(buf.atEnd(), 'extra trailing bytes');
|
||||
|
||||
r.name = 'r';
|
||||
s.name = 's';
|
||||
|
||||
opts.parts.push(r);
|
||||
opts.parts.push(s);
|
||||
return (new Signature(opts));
|
||||
}
|
||||
|
||||
Signature.isSignature = function (obj, ver) {
|
||||
return (utils.isCompatible(obj, Signature, ver));
|
||||
};
|
||||
|
||||
/*
|
||||
* API versions for Signature:
|
||||
* [1,0] -- initial ver
|
||||
* [2,0] -- support for rsa in full ssh format, compat with sshpk-agent
|
||||
* hashAlgorithm property
|
||||
* [2,1] -- first tagged version
|
||||
*/
|
||||
Signature.prototype._sshpkApiVersion = [2, 1];
|
||||
|
||||
Signature._oldVersionDetect = function (obj) {
|
||||
assert.func(obj.toBuffer);
|
||||
if (obj.hasOwnProperty('hashAlgorithm'))
|
||||
return ([2, 0]);
|
||||
return ([1, 0]);
|
||||
};
|
||||
123
node_modules/sshpk/lib/ssh-buffer.js
generated
vendored
Normal file
123
node_modules/sshpk/lib/ssh-buffer.js
generated
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
// Copyright 2015 Joyent, Inc.
|
||||
|
||||
module.exports = SSHBuffer;
|
||||
|
||||
var assert = require('assert-plus');
|
||||
|
||||
function SSHBuffer(opts) {
|
||||
assert.object(opts, 'options');
|
||||
if (opts.buffer !== undefined)
|
||||
assert.buffer(opts.buffer, 'options.buffer');
|
||||
|
||||
this._size = opts.buffer ? opts.buffer.length : 1024;
|
||||
this._buffer = opts.buffer || (new Buffer(this._size));
|
||||
this._offset = 0;
|
||||
}
|
||||
|
||||
SSHBuffer.prototype.toBuffer = function () {
|
||||
return (this._buffer.slice(0, this._offset));
|
||||
};
|
||||
|
||||
SSHBuffer.prototype.atEnd = function () {
|
||||
return (this._offset >= this._buffer.length);
|
||||
};
|
||||
|
||||
SSHBuffer.prototype.remainder = function () {
|
||||
return (this._buffer.slice(this._offset));
|
||||
};
|
||||
|
||||
SSHBuffer.prototype.skip = function (n) {
|
||||
this._offset += n;
|
||||
};
|
||||
|
||||
SSHBuffer.prototype.expand = function () {
|
||||
this._size *= 2;
|
||||
var buf = new Buffer(this._size);
|
||||
this._buffer.copy(buf, 0);
|
||||
this._buffer = buf;
|
||||
};
|
||||
|
||||
SSHBuffer.prototype.readPart = function () {
|
||||
return ({data: this.readBuffer()});
|
||||
};
|
||||
|
||||
SSHBuffer.prototype.readBuffer = function () {
|
||||
var len = this._buffer.readUInt32BE(this._offset);
|
||||
this._offset += 4;
|
||||
assert.ok(this._offset + len <= this._buffer.length,
|
||||
'length out of bounds at +0x' + this._offset.toString(16));
|
||||
var buf = this._buffer.slice(this._offset, this._offset + len);
|
||||
this._offset += len;
|
||||
return (buf);
|
||||
};
|
||||
|
||||
SSHBuffer.prototype.readString = function () {
|
||||
return (this.readBuffer().toString());
|
||||
};
|
||||
|
||||
SSHBuffer.prototype.readCString = function () {
|
||||
var offset = this._offset;
|
||||
while (offset < this._buffer.length &&
|
||||
this._buffer[offset] !== 0x00)
|
||||
offset++;
|
||||
assert.ok(offset < this._buffer.length, 'c string does not terminate');
|
||||
var str = this._buffer.slice(this._offset, offset).toString();
|
||||
this._offset = offset + 1;
|
||||
return (str);
|
||||
};
|
||||
|
||||
SSHBuffer.prototype.readInt = function () {
|
||||
var v = this._buffer.readUInt32BE(this._offset);
|
||||
this._offset += 4;
|
||||
return (v);
|
||||
};
|
||||
|
||||
SSHBuffer.prototype.readChar = function () {
|
||||
var v = this._buffer[this._offset++];
|
||||
return (v);
|
||||
};
|
||||
|
||||
SSHBuffer.prototype.writeBuffer = function (buf) {
|
||||
while (this._offset + 4 + buf.length > this._size)
|
||||
this.expand();
|
||||
this._buffer.writeUInt32BE(buf.length, this._offset);
|
||||
this._offset += 4;
|
||||
buf.copy(this._buffer, this._offset);
|
||||
this._offset += buf.length;
|
||||
};
|
||||
|
||||
SSHBuffer.prototype.writeString = function (str) {
|
||||
this.writeBuffer(new Buffer(str, 'utf8'));
|
||||
};
|
||||
|
||||
SSHBuffer.prototype.writeCString = function (str) {
|
||||
while (this._offset + 1 + str.length > this._size)
|
||||
this.expand();
|
||||
this._buffer.write(str, this._offset);
|
||||
this._offset += str.length;
|
||||
this._buffer[this._offset++] = 0;
|
||||
};
|
||||
|
||||
SSHBuffer.prototype.writeInt = function (v) {
|
||||
while (this._offset + 4 > this._size)
|
||||
this.expand();
|
||||
this._buffer.writeUInt32BE(v, this._offset);
|
||||
this._offset += 4;
|
||||
};
|
||||
|
||||
SSHBuffer.prototype.writeChar = function (v) {
|
||||
while (this._offset + 1 > this._size)
|
||||
this.expand();
|
||||
this._buffer[this._offset++] = v;
|
||||
};
|
||||
|
||||
SSHBuffer.prototype.writePart = function (p) {
|
||||
this.writeBuffer(p.data);
|
||||
};
|
||||
|
||||
SSHBuffer.prototype.write = function (buf) {
|
||||
while (this._offset + buf.length > this._size)
|
||||
this.expand();
|
||||
buf.copy(this._buffer, this._offset);
|
||||
this._offset += buf.length;
|
||||
};
|
||||
207
node_modules/sshpk/lib/utils.js
generated
vendored
Normal file
207
node_modules/sshpk/lib/utils.js
generated
vendored
Normal file
@@ -0,0 +1,207 @@
|
||||
// Copyright 2015 Joyent, Inc.
|
||||
|
||||
module.exports = {
|
||||
bufferSplit: bufferSplit,
|
||||
addRSAMissing: addRSAMissing,
|
||||
calculateDSAPublic: calculateDSAPublic,
|
||||
mpNormalize: mpNormalize,
|
||||
ecNormalize: ecNormalize,
|
||||
countZeros: countZeros,
|
||||
assertCompatible: assertCompatible,
|
||||
isCompatible: isCompatible
|
||||
};
|
||||
|
||||
var assert = require('assert-plus');
|
||||
var PrivateKey = require('./private-key');
|
||||
|
||||
var MAX_CLASS_DEPTH = 3;
|
||||
|
||||
function isCompatible(obj, klass, needVer) {
|
||||
if (obj === null || typeof (obj) !== 'object')
|
||||
return (false);
|
||||
if (needVer === undefined)
|
||||
needVer = klass.prototype._sshpkApiVersion;
|
||||
if (obj instanceof klass &&
|
||||
klass.prototype._sshpkApiVersion[0] == needVer[0])
|
||||
return (true);
|
||||
var proto = Object.getPrototypeOf(obj);
|
||||
var depth = 0;
|
||||
while (proto.constructor.name !== klass.name) {
|
||||
proto = Object.getPrototypeOf(proto);
|
||||
if (!proto || ++depth > MAX_CLASS_DEPTH)
|
||||
return (false);
|
||||
}
|
||||
if (proto.constructor.name !== klass.name)
|
||||
return (false);
|
||||
var ver = proto._sshpkApiVersion;
|
||||
if (ver === undefined)
|
||||
ver = klass._oldVersionDetect(obj);
|
||||
if (ver[0] != needVer[0] || ver[1] < needVer[1])
|
||||
return (false);
|
||||
return (true);
|
||||
}
|
||||
|
||||
function assertCompatible(obj, klass, needVer, name) {
|
||||
if (name === undefined)
|
||||
name = 'object';
|
||||
assert.ok(obj, name + ' must not be null');
|
||||
assert.object(obj, name + ' must be an object');
|
||||
if (needVer === undefined)
|
||||
needVer = klass.prototype._sshpkApiVersion;
|
||||
if (obj instanceof klass &&
|
||||
klass.prototype._sshpkApiVersion[0] == needVer[0])
|
||||
return;
|
||||
var proto = Object.getPrototypeOf(obj);
|
||||
var depth = 0;
|
||||
while (proto.constructor.name !== klass.name) {
|
||||
proto = Object.getPrototypeOf(proto);
|
||||
assert.ok(proto && ++depth <= MAX_CLASS_DEPTH,
|
||||
name + ' must be a ' + klass.name + ' instance');
|
||||
}
|
||||
assert.strictEqual(proto.constructor.name, klass.name,
|
||||
name + ' must be a ' + klass.name + ' instance');
|
||||
var ver = proto._sshpkApiVersion;
|
||||
if (ver === undefined)
|
||||
ver = klass._oldVersionDetect(obj);
|
||||
assert.ok(ver[0] == needVer[0] && ver[1] >= needVer[1],
|
||||
name + ' must be compatible with ' + klass.name + ' klass ' +
|
||||
'version ' + needVer[0] + '.' + needVer[1]);
|
||||
}
|
||||
|
||||
/* Count leading zero bits on a buffer */
|
||||
function countZeros(buf) {
|
||||
var o = 0, obit = 8;
|
||||
while (o < buf.length) {
|
||||
var mask = (1 << obit);
|
||||
if ((buf[o] & mask) === mask)
|
||||
break;
|
||||
obit--;
|
||||
if (obit < 0) {
|
||||
o++;
|
||||
obit = 8;
|
||||
}
|
||||
}
|
||||
return (o*8 + (8 - obit) - 1);
|
||||
}
|
||||
|
||||
function bufferSplit(buf, chr) {
|
||||
assert.buffer(buf);
|
||||
assert.string(chr);
|
||||
|
||||
var parts = [];
|
||||
var lastPart = 0;
|
||||
var matches = 0;
|
||||
for (var i = 0; i < buf.length; ++i) {
|
||||
if (buf[i] === chr.charCodeAt(matches))
|
||||
++matches;
|
||||
else if (buf[i] === chr.charCodeAt(0))
|
||||
matches = 1;
|
||||
else
|
||||
matches = 0;
|
||||
|
||||
if (matches >= chr.length) {
|
||||
var newPart = i + 1;
|
||||
parts.push(buf.slice(lastPart, newPart - matches));
|
||||
lastPart = newPart;
|
||||
matches = 0;
|
||||
}
|
||||
}
|
||||
if (lastPart <= buf.length)
|
||||
parts.push(buf.slice(lastPart, buf.length));
|
||||
|
||||
return (parts);
|
||||
}
|
||||
|
||||
function ecNormalize(buf, addZero) {
|
||||
assert.buffer(buf);
|
||||
if (buf[0] === 0x00 && buf[1] === 0x04) {
|
||||
if (addZero)
|
||||
return (buf);
|
||||
return (buf.slice(1));
|
||||
} else if (buf[0] === 0x04) {
|
||||
if (!addZero)
|
||||
return (buf);
|
||||
} else {
|
||||
while (buf[0] === 0x00)
|
||||
buf = buf.slice(1);
|
||||
if (buf[0] === 0x02 || buf[0] === 0x03)
|
||||
throw (new Error('Compressed elliptic curve points ' +
|
||||
'are not supported'));
|
||||
if (buf[0] !== 0x04)
|
||||
throw (new Error('Not a valid elliptic curve point'));
|
||||
if (!addZero)
|
||||
return (buf);
|
||||
}
|
||||
var b = new Buffer(buf.length + 1);
|
||||
b[0] = 0x0;
|
||||
buf.copy(b, 1);
|
||||
return (b);
|
||||
}
|
||||
|
||||
function mpNormalize(buf) {
|
||||
assert.buffer(buf);
|
||||
while (buf.length > 1 && buf[0] === 0x00 && (buf[1] & 0x80) === 0x00)
|
||||
buf = buf.slice(1);
|
||||
if ((buf[0] & 0x80) === 0x80) {
|
||||
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);
|
||||
return (buf);
|
||||
}
|
||||
|
||||
function calculateDSAPublic(g, p, x) {
|
||||
assert.buffer(g);
|
||||
assert.buffer(p);
|
||||
assert.buffer(x);
|
||||
try {
|
||||
var bigInt = require('jsbn').BigInteger;
|
||||
} catch (e) {
|
||||
throw (new Error('To load a PKCS#8 format DSA private key, ' +
|
||||
'the node jsbn library is required.'));
|
||||
}
|
||||
g = new bigInt(g);
|
||||
p = new bigInt(p);
|
||||
x = new bigInt(x);
|
||||
var y = g.modPow(x, p);
|
||||
var ybuf = bigintToMpBuf(y);
|
||||
return (ybuf);
|
||||
}
|
||||
|
||||
function addRSAMissing(key) {
|
||||
assert.object(key);
|
||||
assertCompatible(key, PrivateKey, [1, 1]);
|
||||
try {
|
||||
var bigInt = require('jsbn').BigInteger;
|
||||
} catch (e) {
|
||||
throw (new Error('To write a PEM private key from ' +
|
||||
'this source, the node jsbn lib is required.'));
|
||||
}
|
||||
|
||||
var d = new bigInt(key.part.d.data);
|
||||
var buf;
|
||||
|
||||
if (!key.part.dmodp) {
|
||||
var p = new bigInt(key.part.p.data);
|
||||
var dmodp = d.mod(p.subtract(1));
|
||||
|
||||
buf = bigintToMpBuf(dmodp);
|
||||
key.part.dmodp = {name: 'dmodp', data: buf};
|
||||
key.parts.push(key.part.dmodp);
|
||||
}
|
||||
if (!key.part.dmodq) {
|
||||
var q = new bigInt(key.part.q.data);
|
||||
var dmodq = d.mod(q.subtract(1));
|
||||
|
||||
buf = bigintToMpBuf(dmodq);
|
||||
key.part.dmodq = {name: 'dmodq', data: buf};
|
||||
key.parts.push(key.part.dmodq);
|
||||
}
|
||||
}
|
||||
6
node_modules/sshpk/node_modules/assert-plus/AUTHORS
generated
vendored
Normal file
6
node_modules/sshpk/node_modules/assert-plus/AUTHORS
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
Dave Eddy <dave@daveeddy.com>
|
||||
Fred Kuo <fred.kuo@joyent.com>
|
||||
Lars-Magnus Skog <ralphtheninja@riseup.net>
|
||||
Mark Cavage <mcavage@gmail.com>
|
||||
Patrick Mooney <pmooney@pfmooney.com>
|
||||
Rob Gulewich <robert.gulewich@joyent.com>
|
||||
8
node_modules/sshpk/node_modules/assert-plus/CHANGES.md
generated
vendored
Normal file
8
node_modules/sshpk/node_modules/assert-plus/CHANGES.md
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
# assert-plus Changelog
|
||||
|
||||
## 0.2.0
|
||||
|
||||
- Fix `assert.object(null)` so it throws
|
||||
- Fix optional/arrayOf exports for non-type-of asserts
|
||||
- Add optiona/arrayOf exports for Stream/Date/Regex/uuid
|
||||
- Add basic unit test coverage
|
||||
155
node_modules/sshpk/node_modules/assert-plus/README.md
generated
vendored
Normal file
155
node_modules/sshpk/node_modules/assert-plus/README.md
generated
vendored
Normal file
@@ -0,0 +1,155 @@
|
||||
# assert-plus
|
||||
|
||||
This library is a super small wrapper over node's assert module that has two
|
||||
things: (1) the ability to disable assertions with the environment variable
|
||||
NODE\_NDEBUG, and (2) some API wrappers for argument testing. Like
|
||||
`assert.string(myArg, 'myArg')`. As a simple example, most of my code looks
|
||||
like this:
|
||||
|
||||
```javascript
|
||||
var assert = require('assert-plus');
|
||||
|
||||
function fooAccount(options, callback) {
|
||||
assert.object(options, 'options');
|
||||
assert.number(options.id, 'options.id');
|
||||
assert.bool(options.isManager, 'options.isManager');
|
||||
assert.string(options.name, 'options.name');
|
||||
assert.arrayOfString(options.email, 'options.email');
|
||||
assert.func(callback, 'callback');
|
||||
|
||||
// Do stuff
|
||||
callback(null, {});
|
||||
}
|
||||
```
|
||||
|
||||
# API
|
||||
|
||||
All methods that *aren't* part of node's core assert API are simply assumed to
|
||||
take an argument, and then a string 'name' that's not a message; `AssertionError`
|
||||
will be thrown if the assertion fails with a message like:
|
||||
|
||||
AssertionError: foo (string) is required
|
||||
at test (/home/mark/work/foo/foo.js:3:9)
|
||||
at Object.<anonymous> (/home/mark/work/foo/foo.js:15:1)
|
||||
at Module._compile (module.js:446:26)
|
||||
at Object..js (module.js:464:10)
|
||||
at Module.load (module.js:353:31)
|
||||
at Function._load (module.js:311:12)
|
||||
at Array.0 (module.js:484:10)
|
||||
at EventEmitter._tickCallback (node.js:190:38)
|
||||
|
||||
from:
|
||||
|
||||
```javascript
|
||||
function test(foo) {
|
||||
assert.string(foo, 'foo');
|
||||
}
|
||||
```
|
||||
|
||||
There you go. You can check that arrays are of a homogeneous type with `Arrayof$Type`:
|
||||
|
||||
```javascript
|
||||
function test(foo) {
|
||||
assert.arrayOfString(foo, 'foo');
|
||||
}
|
||||
```
|
||||
|
||||
You can assert IFF an argument is not `undefined` (i.e., an optional arg):
|
||||
|
||||
```javascript
|
||||
assert.optionalString(foo, 'foo');
|
||||
```
|
||||
|
||||
Lastly, you can opt-out of assertion checking altogether by setting the
|
||||
environment variable `NODE_NDEBUG=1`. This is pseudo-useful if you have
|
||||
lots of assertions, and don't want to pay `typeof ()` taxes to v8 in
|
||||
production. Be advised: The standard functions re-exported from `assert` are
|
||||
also disabled in assert-plus if NDEBUG is specified. Using them directly from
|
||||
the `assert` module avoids this behavior.
|
||||
|
||||
The complete list of APIs is:
|
||||
|
||||
* assert.array
|
||||
* assert.bool
|
||||
* assert.buffer
|
||||
* assert.func
|
||||
* assert.number
|
||||
* assert.object
|
||||
* assert.string
|
||||
* assert.stream
|
||||
* assert.date
|
||||
* assert.regex
|
||||
* assert.uuid
|
||||
* assert.arrayOfArray
|
||||
* assert.arrayOfBool
|
||||
* assert.arrayOfBuffer
|
||||
* assert.arrayOfFunc
|
||||
* assert.arrayOfNumber
|
||||
* assert.arrayOfObject
|
||||
* assert.arrayOfString
|
||||
* assert.arrayOfStream
|
||||
* assert.arrayOfDate
|
||||
* assert.arrayOfUuid
|
||||
* assert.optionalArray
|
||||
* assert.optionalBool
|
||||
* assert.optionalBuffer
|
||||
* assert.optionalFunc
|
||||
* assert.optionalNumber
|
||||
* assert.optionalObject
|
||||
* assert.optionalString
|
||||
* assert.optionalStream
|
||||
* assert.optionalDate
|
||||
* assert.optionalUuid
|
||||
* assert.optionalArrayOfArray
|
||||
* assert.optionalArrayOfBool
|
||||
* assert.optionalArrayOfBuffer
|
||||
* assert.optionalArrayOfFunc
|
||||
* assert.optionalArrayOfNumber
|
||||
* assert.optionalArrayOfObject
|
||||
* assert.optionalArrayOfString
|
||||
* assert.optionalArrayOfStream
|
||||
* assert.optionalArrayOfDate
|
||||
* assert.optionalArrayOfUuid
|
||||
* assert.AssertionError
|
||||
* assert.fail
|
||||
* assert.ok
|
||||
* assert.equal
|
||||
* assert.notEqual
|
||||
* assert.deepEqual
|
||||
* assert.notDeepEqual
|
||||
* assert.strictEqual
|
||||
* assert.notStrictEqual
|
||||
* assert.throws
|
||||
* assert.doesNotThrow
|
||||
* assert.ifError
|
||||
|
||||
# Installation
|
||||
|
||||
npm install assert-plus
|
||||
|
||||
## License
|
||||
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2012 Mark Cavage
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
## Bugs
|
||||
|
||||
See <https://github.com/mcavage/node-assert-plus/issues>.
|
||||
206
node_modules/sshpk/node_modules/assert-plus/assert.js
generated
vendored
Normal file
206
node_modules/sshpk/node_modules/assert-plus/assert.js
generated
vendored
Normal file
@@ -0,0 +1,206 @@
|
||||
// Copyright (c) 2012, Mark Cavage. All rights reserved.
|
||||
// Copyright 2015 Joyent, Inc.
|
||||
|
||||
var assert = require('assert');
|
||||
var Stream = require('stream').Stream;
|
||||
var util = require('util');
|
||||
|
||||
|
||||
///--- Globals
|
||||
|
||||
/* JSSTYLED */
|
||||
var UUID_REGEXP = /^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$/;
|
||||
|
||||
|
||||
///--- Internal
|
||||
|
||||
function _capitalize(str) {
|
||||
return (str.charAt(0).toUpperCase() + str.slice(1));
|
||||
}
|
||||
|
||||
function _toss(name, expected, oper, arg, actual) {
|
||||
throw new assert.AssertionError({
|
||||
message: util.format('%s (%s) is required', name, expected),
|
||||
actual: (actual === undefined) ? typeof (arg) : actual(arg),
|
||||
expected: expected,
|
||||
operator: oper || '===',
|
||||
stackStartFunction: _toss.caller
|
||||
});
|
||||
}
|
||||
|
||||
function _getClass(arg) {
|
||||
return (Object.prototype.toString.call(arg).slice(8, -1));
|
||||
}
|
||||
|
||||
function noop() {
|
||||
// Why even bother with asserts?
|
||||
}
|
||||
|
||||
|
||||
///--- Exports
|
||||
|
||||
var types = {
|
||||
bool: {
|
||||
check: function (arg) { return typeof (arg) === 'boolean'; }
|
||||
},
|
||||
func: {
|
||||
check: function (arg) { return typeof (arg) === 'function'; }
|
||||
},
|
||||
string: {
|
||||
check: function (arg) { return typeof (arg) === 'string'; }
|
||||
},
|
||||
object: {
|
||||
check: function (arg) {
|
||||
return typeof (arg) === 'object' && arg !== null;
|
||||
}
|
||||
},
|
||||
number: {
|
||||
check: function (arg) {
|
||||
return typeof (arg) === 'number' && !isNaN(arg) && isFinite(arg);
|
||||
}
|
||||
},
|
||||
buffer: {
|
||||
check: function (arg) { return Buffer.isBuffer(arg); },
|
||||
operator: 'Buffer.isBuffer'
|
||||
},
|
||||
array: {
|
||||
check: function (arg) { return Array.isArray(arg); },
|
||||
operator: 'Array.isArray'
|
||||
},
|
||||
stream: {
|
||||
check: function (arg) { return arg instanceof Stream; },
|
||||
operator: 'instanceof',
|
||||
actual: _getClass
|
||||
},
|
||||
date: {
|
||||
check: function (arg) { return arg instanceof Date; },
|
||||
operator: 'instanceof',
|
||||
actual: _getClass
|
||||
},
|
||||
regexp: {
|
||||
check: function (arg) { return arg instanceof RegExp; },
|
||||
operator: 'instanceof',
|
||||
actual: _getClass
|
||||
},
|
||||
uuid: {
|
||||
check: function (arg) {
|
||||
return typeof (arg) === 'string' && UUID_REGEXP.test(arg);
|
||||
},
|
||||
operator: 'isUUID'
|
||||
}
|
||||
};
|
||||
|
||||
function _setExports(ndebug) {
|
||||
var keys = Object.keys(types);
|
||||
var out;
|
||||
|
||||
/* re-export standard assert */
|
||||
if (process.env.NODE_NDEBUG) {
|
||||
out = noop;
|
||||
} else {
|
||||
out = function (arg, msg) {
|
||||
if (!arg) {
|
||||
_toss(msg, 'true', arg);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/* standard checks */
|
||||
keys.forEach(function (k) {
|
||||
if (ndebug) {
|
||||
out[k] = noop;
|
||||
return;
|
||||
}
|
||||
var type = types[k];
|
||||
out[k] = function (arg, msg) {
|
||||
if (!type.check(arg)) {
|
||||
_toss(msg, k, type.operator, arg, type.actual);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
/* optional checks */
|
||||
keys.forEach(function (k) {
|
||||
var name = 'optional' + _capitalize(k);
|
||||
if (ndebug) {
|
||||
out[name] = noop;
|
||||
return;
|
||||
}
|
||||
var type = types[k];
|
||||
out[name] = function (arg, msg) {
|
||||
if (arg === undefined || arg === null) {
|
||||
return;
|
||||
}
|
||||
if (!type.check(arg)) {
|
||||
_toss(msg, k, type.operator, arg, type.actual);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
/* arrayOf checks */
|
||||
keys.forEach(function (k) {
|
||||
var name = 'arrayOf' + _capitalize(k);
|
||||
if (ndebug) {
|
||||
out[name] = noop;
|
||||
return;
|
||||
}
|
||||
var type = types[k];
|
||||
var expected = '[' + k + ']';
|
||||
out[name] = function (arg, msg) {
|
||||
if (!Array.isArray(arg)) {
|
||||
_toss(msg, expected, type.operator, arg, type.actual);
|
||||
}
|
||||
var i;
|
||||
for (i = 0; i < arg.length; i++) {
|
||||
if (!type.check(arg[i])) {
|
||||
_toss(msg, expected, type.operator, arg, type.actual);
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
/* optionalArrayOf checks */
|
||||
keys.forEach(function (k) {
|
||||
var name = 'optionalArrayOf' + _capitalize(k);
|
||||
if (ndebug) {
|
||||
out[name] = noop;
|
||||
return;
|
||||
}
|
||||
var type = types[k];
|
||||
var expected = '[' + k + ']';
|
||||
out[name] = function (arg, msg) {
|
||||
if (arg === undefined || arg === null) {
|
||||
return;
|
||||
}
|
||||
if (!Array.isArray(arg)) {
|
||||
_toss(msg, expected, type.operator, arg, type.actual);
|
||||
}
|
||||
var i;
|
||||
for (i = 0; i < arg.length; i++) {
|
||||
if (!type.check(arg[i])) {
|
||||
_toss(msg, expected, type.operator, arg, type.actual);
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
/* re-export built-in assertions */
|
||||
Object.keys(assert).forEach(function (k) {
|
||||
if (k === 'AssertionError') {
|
||||
out[k] = assert[k];
|
||||
return;
|
||||
}
|
||||
if (ndebug) {
|
||||
out[k] = noop;
|
||||
return;
|
||||
}
|
||||
out[k] = assert[k];
|
||||
});
|
||||
|
||||
/* export ourselves (for unit tests _only_) */
|
||||
out._setExports = _setExports;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
module.exports = _setExports(process.env.NODE_NDEBUG);
|
||||
107
node_modules/sshpk/node_modules/assert-plus/package.json
generated
vendored
Normal file
107
node_modules/sshpk/node_modules/assert-plus/package.json
generated
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
{
|
||||
"_args": [
|
||||
[
|
||||
"assert-plus@>=0.2.0 <0.3.0",
|
||||
"/home/mitchell/Desktop/test-mywebsite/mywebsite/node_modules/sshpk"
|
||||
]
|
||||
],
|
||||
"_from": "assert-plus@>=0.2.0 <0.3.0",
|
||||
"_id": "assert-plus@0.2.0",
|
||||
"_inCache": true,
|
||||
"_installable": true,
|
||||
"_location": "/sshpk/assert-plus",
|
||||
"_nodeVersion": "0.10.36",
|
||||
"_npmUser": {
|
||||
"email": "patrick.f.mooney@gmail.com",
|
||||
"name": "pfmooney"
|
||||
},
|
||||
"_npmVersion": "3.3.8",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"name": "assert-plus",
|
||||
"raw": "assert-plus@>=0.2.0 <0.3.0",
|
||||
"rawSpec": ">=0.2.0 <0.3.0",
|
||||
"scope": null,
|
||||
"spec": ">=0.2.0 <0.3.0",
|
||||
"type": "range"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/sshpk"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz",
|
||||
"_shasum": "d74e1b87e7affc0db8aadb7021f3fe48101ab234",
|
||||
"_shrinkwrap": null,
|
||||
"_spec": "assert-plus@>=0.2.0 <0.3.0",
|
||||
"_where": "/home/mitchell/Desktop/test-mywebsite/mywebsite/node_modules/sshpk",
|
||||
"author": {
|
||||
"email": "mcavage@gmail.com",
|
||||
"name": "Mark Cavage"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/mcavage/node-assert-plus/issues"
|
||||
},
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Dave Eddy",
|
||||
"email": "dave@daveeddy.com"
|
||||
},
|
||||
{
|
||||
"name": "Fred Kuo",
|
||||
"email": "fred.kuo@joyent.com"
|
||||
},
|
||||
{
|
||||
"name": "Lars-Magnus Skog",
|
||||
"email": "ralphtheninja@riseup.net"
|
||||
},
|
||||
{
|
||||
"name": "Mark Cavage",
|
||||
"email": "mcavage@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Patrick Mooney",
|
||||
"email": "pmooney@pfmooney.com"
|
||||
},
|
||||
{
|
||||
"name": "Rob Gulewich",
|
||||
"email": "robert.gulewich@joyent.com"
|
||||
}
|
||||
],
|
||||
"dependencies": {},
|
||||
"description": "Extra assertions on top of node's assert module",
|
||||
"devDependencies": {
|
||||
"faucet": "0.0.1",
|
||||
"tape": "4.2.2"
|
||||
},
|
||||
"directories": {},
|
||||
"dist": {
|
||||
"shasum": "d74e1b87e7affc0db8aadb7021f3fe48101ab234",
|
||||
"tarball": "http://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
},
|
||||
"homepage": "https://github.com/mcavage/node-assert-plus#readme",
|
||||
"license": "MIT",
|
||||
"main": "./assert.js",
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "mcavage",
|
||||
"email": "mcavage@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "pfmooney",
|
||||
"email": "patrick.f.mooney@gmail.com"
|
||||
}
|
||||
],
|
||||
"name": "assert-plus",
|
||||
"optionalDependencies": {},
|
||||
"readme": "ERROR: No README data found!",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/mcavage/node-assert-plus.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "tape tests/*.js | ./node_modules/.bin/faucet"
|
||||
},
|
||||
"version": "0.2.0"
|
||||
}
|
||||
111
node_modules/sshpk/package.json
generated
vendored
Normal file
111
node_modules/sshpk/package.json
generated
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
{
|
||||
"_args": [
|
||||
[
|
||||
"sshpk@^1.7.0",
|
||||
"/home/mitchell/Desktop/test-mywebsite/mywebsite/node_modules/http-signature"
|
||||
]
|
||||
],
|
||||
"_from": "sshpk@>=1.7.0 <2.0.0",
|
||||
"_id": "sshpk@1.7.1",
|
||||
"_inCache": true,
|
||||
"_installable": true,
|
||||
"_location": "/sshpk",
|
||||
"_nodeVersion": "0.12.7",
|
||||
"_npmUser": {
|
||||
"email": "alex@cooperi.net",
|
||||
"name": "arekinath"
|
||||
},
|
||||
"_npmVersion": "2.14.4",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"name": "sshpk",
|
||||
"raw": "sshpk@^1.7.0",
|
||||
"rawSpec": "^1.7.0",
|
||||
"scope": null,
|
||||
"spec": ">=1.7.0 <2.0.0",
|
||||
"type": "range"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/http-signature"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.7.1.tgz",
|
||||
"_shasum": "565e386c42a77e6062fbd14c0472ff21cd53398c",
|
||||
"_shrinkwrap": null,
|
||||
"_spec": "sshpk@^1.7.0",
|
||||
"_where": "/home/mitchell/Desktop/test-mywebsite/mywebsite/node_modules/http-signature",
|
||||
"author": {
|
||||
"name": "Joyent, Inc"
|
||||
},
|
||||
"bin": {
|
||||
"sshpk-conv": "bin/sshpk-conv"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/arekinath/node-sshpk/issues"
|
||||
},
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Dave Eddy",
|
||||
"email": "dave@daveeddy.com"
|
||||
},
|
||||
{
|
||||
"name": "Mark Cavage",
|
||||
"email": "mcavage@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Alex Wilson",
|
||||
"email": "alex@cooperi.net"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"asn1": ">=0.2.3 <0.3.0",
|
||||
"assert-plus": ">=0.2.0 <0.3.0",
|
||||
"dashdash": ">=1.10.1 <2.0.0",
|
||||
"ecc-jsbn": ">=0.0.1 <1.0.0",
|
||||
"jodid25519": ">=1.0.0 <2.0.0",
|
||||
"jsbn": ">=0.1.0 <0.2.0",
|
||||
"tweetnacl": ">=0.13.0 <1.0.0"
|
||||
},
|
||||
"description": "A library for finding and using SSH public keys",
|
||||
"devDependencies": {
|
||||
"benchmark": ">=1.0.0 <2.0.0",
|
||||
"sinon": ">=1.17.2 <2.0.0",
|
||||
"tape": ">=3.5.0 <4.0.0"
|
||||
},
|
||||
"directories": {
|
||||
"bin": "./bin",
|
||||
"lib": "./lib"
|
||||
},
|
||||
"dist": {
|
||||
"shasum": "565e386c42a77e6062fbd14c0472ff21cd53398c",
|
||||
"tarball": "http://registry.npmjs.org/sshpk/-/sshpk-1.7.1.tgz"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
},
|
||||
"gitHead": "71dd768e94d6214a0b8e1196ca78297b582c6fb0",
|
||||
"homepage": "https://github.com/arekinath/node-sshpk#readme",
|
||||
"license": "MIT",
|
||||
"main": "lib/index.js",
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "arekinath",
|
||||
"email": "alex@cooperi.net"
|
||||
}
|
||||
],
|
||||
"name": "sshpk",
|
||||
"optionalDependencies": {
|
||||
"ecc-jsbn": ">=0.0.1 <1.0.0",
|
||||
"jodid25519": ">=1.0.0 <2.0.0",
|
||||
"jsbn": ">=0.1.0 <0.2.0",
|
||||
"tweetnacl": ">=0.13.0 <1.0.0"
|
||||
},
|
||||
"readme": "ERROR: No README data found!",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/arekinath/node-sshpk.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "tape test/*.js"
|
||||
},
|
||||
"version": "1.7.1"
|
||||
}
|
||||
Reference in New Issue
Block a user