From 6561274d2377d9fd9c55fa3ce2eb2e53c14d898e Mon Sep 17 00:00:00 2001 From: Calvin Metcalf Date: Tue, 27 Jan 2015 14:58:22 -0500 Subject: [PATCH] crypto: support passwords in publicEncrypt Private keys may be used along with publicEncrypt since the private key includes the public one. This adds the ability to use encrypted private keys which previously threw an error. This commit also makes sure the user exposed functions have names. PR-URL: https://github.com/iojs/io.js/pull/626 Reviewed-By: Ben Noordhuis --- doc/api/crypto.markdown | 3 +++ lib/crypto.js | 3 ++- test/parallel/test-crypto.js | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/doc/api/crypto.markdown b/doc/api/crypto.markdown index 2c8714f..d862f37 100644 --- a/doc/api/crypto.markdown +++ b/doc/api/crypto.markdown @@ -678,10 +678,13 @@ Encrypts `buffer` with `public_key`. Only RSA is currently supported. `public_key` can be an object or a string. If `public_key` is a string, it is treated as the key with no passphrase and will use `RSA_PKCS1_OAEP_PADDING`. +Since RSA public keys may be derived from private keys you may pass a private +key to this method. `public_key`: * `key` : A string holding the PEM encoded private key +* `passphrase` : An optional string of passphrase for the private key * `padding` : An optional padding value, one of the following: * `constants.RSA_NO_PADDING` * `constants.RSA_PKCS1_PADDING` diff --git a/lib/crypto.js b/lib/crypto.js index 42564c7..6033a85 100644 --- a/lib/crypto.js +++ b/lib/crypto.js @@ -340,7 +340,8 @@ function rsaPublic(method, defaultPadding) { return function(options, buffer) { var key = options.key || options; var padding = options.padding || defaultPadding; - return method(toBuf(key), buffer, padding); + var passphrase = options.passphrase || null; + return method(toBuf(key), buffer, padding, passphrase); }; } diff --git a/test/parallel/test-crypto.js b/test/parallel/test-crypto.js index 8198a6c..c96299a 100644 --- a/test/parallel/test-crypto.js +++ b/test/parallel/test-crypto.js @@ -831,6 +831,28 @@ assert.equal(bad_dh.verifyError, constants.DH_NOT_SUITABLE_GENERATOR); }, encryptedBuffer); assert.equal(input, decryptedBufferWithPassword.toString()); + encryptedBuffer = crypto.publicEncrypt({ + key: rsaKeyPemEncrypted, + passphrase: 'password' + }, bufferToEncrypt); + + decryptedBufferWithPassword = crypto.privateDecrypt({ + key: rsaKeyPemEncrypted, + passphrase: 'password' + }, encryptedBuffer); + assert.equal(input, decryptedBufferWithPassword.toString()); + + encryptedBuffer = crypto.privateEncrypt({ + key: rsaKeyPemEncrypted, + passphrase: new Buffer('password') + }, bufferToEncrypt); + + decryptedBufferWithPassword = crypto.publicDecrypt({ + key: rsaKeyPemEncrypted, + passphrase: new Buffer('password') + }, encryptedBuffer); + assert.equal(input, decryptedBufferWithPassword.toString()); + encryptedBuffer = crypto.publicEncrypt(certPem, bufferToEncrypt); decryptedBuffer = crypto.privateDecrypt(keyPem, encryptedBuffer); @@ -850,6 +872,25 @@ assert.equal(bad_dh.verifyError, constants.DH_NOT_SUITABLE_GENERATOR); crypto.privateDecrypt({ key: rsaKeyPemEncrypted, passphrase: 'wrong' + }, bufferToEncrypt); + }); + + assert.throws(function() { + crypto.publicEncrypt({ + key: rsaKeyPemEncrypted, + passphrase: 'wrong' + }, encryptedBuffer); + }); + + encryptedBuffer = crypto.privateEncrypt({ + key: rsaKeyPemEncrypted, + passphrase: new Buffer('password') + }, bufferToEncrypt); + + assert.throws(function() { + crypto.publicDecrypt({ + key: rsaKeyPemEncrypted, + passphrase: [].concat.apply([], new Buffer('password')) }, encryptedBuffer); }); })(); -- 2.7.4