From 87e62bd4c87e8674e3d1c432506e9b4991784ee2 Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Tue, 27 Jan 2015 22:58:14 +0300 Subject: [PATCH] crypto: implement privateEncrypt/publicDecrypt PR-URL: https://github.com/iojs/io.js/pull/625 Reviewed-By: Ben Noordhuis Fix iojs/io.js#477 --- doc/api/crypto.markdown | 8 ++++++++ lib/crypto.js | 34 +++++++++++++++++++++++----------- src/node_crypto.cc | 18 +++++++++++++----- src/node_crypto.h | 4 ++-- test/parallel/test-crypto.js | 5 +++++ 5 files changed, 51 insertions(+), 18 deletions(-) diff --git a/doc/api/crypto.markdown b/doc/api/crypto.markdown index 84cd27a12c57ee..b6834d0a945979 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 8e3a84350df124..2d0843356363a8 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 b76a1a607ed598..3ad4af230ca762 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 target, env->SetMethod(target, "getCiphers", GetCiphers); env->SetMethod(target, "getHashes", GetHashes); env->SetMethod(target, "publicEncrypt", - PublicKeyCipher::Cipher); env->SetMethod(target, "privateDecrypt", - PublicKeyCipher::Cipher); + env->SetMethod(target, "privateEncrypt", + PublicKeyCipher::Cipher); + env->SetMethod(target, "publicDecrypt", + PublicKeyCipher::Cipher); } } // namespace crypto diff --git a/src/node_crypto.h b/src/node_crypto.h index 05ab0739c180a3..75ffe4f31ddeea 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