Skip to content

Commit

Permalink
allow encrypted private key on streaming interface
Browse files Browse the repository at this point in the history
Fixes #39
  • Loading branch information
omsmith committed Jan 17, 2016
1 parent cb71055 commit 1291acf
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 1 deletion.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
node_modules
/test/keys
/test/*.pem
/test/encrypted-key-passphrase
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ test/keys:
@openssl ec -in test/ec384-wrong-private.pem -pubout > test/ec384-wrong-public.pem
@openssl ec -in test/ec512-private.pem -pubout > test/ec512-public.pem
@openssl ec -in test/ec512-wrong-private.pem -pubout > test/ec512-wrong-public.pem
@echo foo > test/encrypted-key-passphrase
@openssl rsa -passin file:test/encrypted-key-passphrase -in test/rsa-private.pem > test/rsa-private-encrypted.pem
@touch test/keys

clean:
Expand Down
4 changes: 3 additions & 1 deletion lib/data-stream.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,16 @@ function DataStream(data) {
}

// Buffer or String
if (data.length) {
// or Object (assumedly a passworded key)
if (data.length || typeof data === 'object') {
this.buffer = data;
this.writable = false;
process.nextTick(function () {
this.emit('end', data);
this.readable = false;
this.emit('close');
}.bind(this));
return this;
}

throw new TypeError('Unexpected data type ('+ typeof data + ')');
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"jwa": "^1.1.0"
},
"devDependencies": {
"semver": "^5.1.0",
"tape": "~2.14.0"
}
}
4 changes: 4 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ Options:

Other than `header`, all options expect a string or a buffer when the
value is known ahead of time, or a stream for convenience.
`key`/`privateKey`/`secret` may also be an object when using an encrypted
private key, see the [crypto documentation][encrypted-key-docs].

Example
```js
Expand Down Expand Up @@ -242,3 +244,5 @@ 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.
```

[encrypted-key-docs]: https://nodejs.org/api/crypto.html#crypto_sign_sign_private_key_output_format
42 changes: 42 additions & 0 deletions test/jws.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ const fs = require('fs');
const test = require('tape');
const jws = require('..');

const NODE_VERSION = require('semver').clean(process.version);
const SUPPORTS_ENCRYPTED_KEYS = require('semver').gte(NODE_VERSION, '0.11.8');

function readfile(path) {
return fs.readFileSync(__dirname + '/' + path).toString();
}
Expand All @@ -13,6 +16,8 @@ function readstream(path) {
}

const rsaPrivateKey = readfile('rsa-private.pem');
const rsaPrivateKeyEncrypted = readfile('rsa-private-encrypted.pem');
const encryptedPassphrase = readfile('encrypted-key-passphrase');
const rsaPublicKey = readfile('rsa-public.pem');
const rsaWrongPublicKey = readfile('rsa-wrong-public.pem');
const ecdsaPrivateKey = {
Expand Down Expand Up @@ -234,6 +239,43 @@ test('Streaming verify: errors during verify should emit as "error"', function (
});
});

if (SUPPORTS_ENCRYPTED_KEYS) {
test('Signing: should accept an encrypted key', function (t) {
const alg = 'RS256';
const signature = jws.sign({
header: { alg: alg },
payload: 'verifyme',
privateKey: {
key: rsaPrivateKeyEncrypted,
passphrase: encryptedPassphrase
}
});
t.ok(jws.verify(signature, 'RS256', rsaPublicKey));
t.end();
});

test('Streaming sign: should accept an encrypted key', function (t) {
const alg = 'RS256';
const signer = jws.createSign({
header: { alg: alg },
payload: 'verifyme',
privateKey: {
key: rsaPrivateKeyEncrypted,
passphrase: encryptedPassphrase
}
});
const verifier = jws.createVerify({
algorithm: alg,
signature: signer,
publicKey: rsaPublicKey
});
verifier.on('done', function (verified) {
t.ok(verified);
t.end();
});
});
}

test('jws.decode: not a jws signature', function (t) {
t.same(jws.decode('some garbage string'), null);
t.same(jws.decode('http://sub.domain.org'), null);
Expand Down

0 comments on commit 1291acf

Please sign in to comment.