summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/api/crypto.markdown8
-rw-r--r--lib/crypto.js34
-rw-r--r--src/node_crypto.cc18
-rw-r--r--src/node_crypto.h4
-rw-r--r--test/parallel/test-crypto.js5
5 files changed, 51 insertions, 18 deletions
diff --git a/doc/api/crypto.markdown b/doc/api/crypto.markdown
index 84cd27a12c..b6834d0a94 100644
--- a/doc/api/crypto.markdown
+++ b/doc/api/crypto.markdown
@@ -707,6 +707,14 @@ treated as the key with no passphrase and will use `RSA_PKCS1_OAEP_PADDING`.
NOTE: All paddings are defined in `constants` module.
+## crypto.privateEncrypt(private_key, buffer)
+
+See above for details. Has the same API as `crypto.privateDecrypt`.
+
+## crypto.publicDecrypt(public_key, buffer)
+
+See above for details. Has the same API as `crypto.publicEncrypt`.
+
## crypto.DEFAULT_ENCODING
The default encoding to use for functions that can take either strings
diff --git a/lib/crypto.js b/lib/crypto.js
index 8e3a84350d..2d08433563 100644
--- a/lib/crypto.js
+++ b/lib/crypto.js
@@ -337,19 +337,31 @@ Verify.prototype.verify = function(object, signature, sigEncoding) {
return this._handle.verify(toBuf(object), toBuf(signature, sigEncoding));
};
-exports.publicEncrypt = function(options, buffer) {
- var key = options.key || options;
- var padding = options.padding || constants.RSA_PKCS1_OAEP_PADDING;
- return binding.publicEncrypt(toBuf(key), buffer, padding);
-};
+function rsaPublic(method, defaultPadding) {
+ return function(options, buffer) {
+ var key = options.key || options;
+ var padding = options.padding || defaultPadding;
+ return method(toBuf(key), buffer, padding);
+ };
+}
-exports.privateDecrypt = function(options, buffer) {
- var key = options.key || options;
- var passphrase = options.passphrase || null;
- var padding = options.padding || constants.RSA_PKCS1_OAEP_PADDING;
- return binding.privateDecrypt(toBuf(key), buffer, padding, passphrase);
-};
+function rsaPrivate(method, defaultPadding) {
+ return function(options, buffer) {
+ var key = options.key || options;
+ var passphrase = options.passphrase || null;
+ var padding = options.padding || defaultPadding;
+ return method(toBuf(key), buffer, padding, passphrase);
+ };
+}
+exports.publicEncrypt = rsaPublic(binding.publicEncrypt,
+ constants.RSA_PKCS1_OAEP_PADDING);
+exports.publicDecrypt = rsaPublic(binding.publicDecrypt,
+ constants.RSA_PKCS1_PADDING);
+exports.privateEncrypt = rsaPrivate(binding.privateEncrypt,
+ constants.RSA_PKCS1_PADDING);
+exports.privateDecrypt = rsaPrivate(binding.privateDecrypt,
+ constants.RSA_PKCS1_OAEP_PADDING);
exports.createDiffieHellman = exports.DiffieHellman = DiffieHellman;
diff --git a/src/node_crypto.cc b/src/node_crypto.cc
index b76a1a607e..3ad4af230c 100644
--- a/src/node_crypto.cc
+++ b/src/node_crypto.cc
@@ -3561,12 +3561,12 @@ bool PublicKeyCipher::Cipher(const char* key_pem,
// Check if this is a PKCS#8 or RSA public key before trying as X.509 and
// private key.
- if (operation == kEncrypt &&
+ if (operation == kPublic &&
strncmp(key_pem, PUBLIC_KEY_PFX, PUBLIC_KEY_PFX_LEN) == 0) {
pkey = PEM_read_bio_PUBKEY(bp, nullptr, nullptr, nullptr);
if (pkey == nullptr)
goto exit;
- } else if (operation == kEncrypt &&
+ } else if (operation == kPublic &&
strncmp(key_pem, PUBRSA_KEY_PFX, PUBRSA_KEY_PFX_LEN) == 0) {
RSA* rsa = PEM_read_bio_RSAPublicKey(bp, nullptr, nullptr, nullptr);
if (rsa) {
@@ -3577,7 +3577,7 @@ bool PublicKeyCipher::Cipher(const char* key_pem,
}
if (pkey == nullptr)
goto exit;
- } else if (operation == kEncrypt &&
+ } else if (operation == kPublic &&
strncmp(key_pem, CERTIFICATE_PFX, CERTIFICATE_PFX_LEN) == 0) {
x509 = PEM_read_bio_X509(bp, nullptr, CryptoPemCallback, nullptr);
if (x509 == nullptr)
@@ -5038,13 +5038,21 @@ void InitCrypto(Handle<Object> target,
env->SetMethod(target, "getCiphers", GetCiphers);
env->SetMethod(target, "getHashes", GetHashes);
env->SetMethod(target, "publicEncrypt",
- PublicKeyCipher::Cipher<PublicKeyCipher::kEncrypt,
+ PublicKeyCipher::Cipher<PublicKeyCipher::kPublic,
EVP_PKEY_encrypt_init,
EVP_PKEY_encrypt>);
env->SetMethod(target, "privateDecrypt",
- PublicKeyCipher::Cipher<PublicKeyCipher::kDecrypt,
+ PublicKeyCipher::Cipher<PublicKeyCipher::kPrivate,
EVP_PKEY_decrypt_init,
EVP_PKEY_decrypt>);
+ env->SetMethod(target, "privateEncrypt",
+ PublicKeyCipher::Cipher<PublicKeyCipher::kPrivate,
+ EVP_PKEY_sign_init,
+ EVP_PKEY_sign>);
+ env->SetMethod(target, "publicDecrypt",
+ PublicKeyCipher::Cipher<PublicKeyCipher::kPublic,
+ EVP_PKEY_verify_recover_init,
+ EVP_PKEY_verify_recover>);
}
} // namespace crypto
diff --git a/src/node_crypto.h b/src/node_crypto.h
index 05ab0739c1..75ffe4f31d 100644
--- a/src/node_crypto.h
+++ b/src/node_crypto.h
@@ -553,8 +553,8 @@ class PublicKeyCipher {
const unsigned char *in, size_t inlen);
enum Operation {
- kEncrypt,
- kDecrypt
+ kPublic,
+ kPrivate
};
template <Operation operation,
diff --git a/test/parallel/test-crypto.js b/test/parallel/test-crypto.js
index 970bee06e6..8198a6c9d6 100644
--- a/test/parallel/test-crypto.js
+++ b/test/parallel/test-crypto.js
@@ -841,6 +841,11 @@ assert.equal(bad_dh.verifyError, constants.DH_NOT_SUITABLE_GENERATOR);
decryptedBuffer = crypto.privateDecrypt(keyPem, encryptedBuffer);
assert.equal(input, decryptedBuffer.toString());
+ encryptedBuffer = crypto.privateEncrypt(keyPem, bufferToEncrypt);
+
+ decryptedBuffer = crypto.publicDecrypt(keyPem, encryptedBuffer);
+ assert.equal(input, decryptedBuffer.toString());
+
assert.throws(function() {
crypto.privateDecrypt({
key: rsaKeyPemEncrypted,