crypto: allow padding in RSA methods
Reviewed-By: Trevor Norris <trevnorris@gmail.com>
This commit is contained in:
parent
8a7d7f8b2b
commit
6adf3ecebb
@ -597,17 +597,36 @@ Exports the encoded challenge associated with the SPKAC.
|
|||||||
|
|
||||||
Encrypts `buffer` with `public_key`. Only RSA is currently supported.
|
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`.
|
||||||
|
|
||||||
|
`public_key`:
|
||||||
|
|
||||||
|
* `key` : A string holding the PEM encoded private key
|
||||||
|
* `padding` : An optional padding value, one of the following:
|
||||||
|
* `constants.RSA_NO_PADDING`
|
||||||
|
* `constants.RSA_PKCS1_PADDING`
|
||||||
|
* `constants.RSA_PKCS1_OAEP_PADDING`
|
||||||
|
|
||||||
|
NOTE: All paddings are defined in `constants` module.
|
||||||
|
|
||||||
## crypto.privateDecrypt(private_key, buffer)
|
## crypto.privateDecrypt(private_key, buffer)
|
||||||
|
|
||||||
Decrypts `buffer` with `private_key`.
|
Decrypts `buffer` with `private_key`.
|
||||||
|
|
||||||
`private_key` can be an object or a string. If `private_key` is a string, it is
|
`private_key` can be an object or a string. If `private_key` is a string, it is
|
||||||
treated as the key with no passphrase.
|
treated as the key with no passphrase and will use `RSA_PKCS1_OAEP_PADDING`.
|
||||||
|
|
||||||
`private_key`:
|
`private_key`:
|
||||||
|
|
||||||
* `key` : A string holding the PEM encoded private key
|
* `key` : A string holding the PEM encoded private key
|
||||||
* `passphrase` : A string of passphrase for the 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`
|
||||||
|
* `constants.RSA_PKCS1_OAEP_PADDING`
|
||||||
|
|
||||||
|
NOTE: All paddings are defined in `constants` module.
|
||||||
|
|
||||||
## crypto.DEFAULT_ENCODING
|
## crypto.DEFAULT_ENCODING
|
||||||
|
|
||||||
|
@ -355,14 +355,17 @@ Verify.prototype.verify = function(object, signature, sigEncoding) {
|
|||||||
return this._handle.verify(toBuf(object), toBuf(signature, sigEncoding));
|
return this._handle.verify(toBuf(object), toBuf(signature, sigEncoding));
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.publicEncrypt = function(object, buffer) {
|
exports.publicEncrypt = function(options, buffer) {
|
||||||
return binding.publicEncrypt(toBuf(object), buffer);
|
var key = options.key || options;
|
||||||
|
var padding = options.padding || constants.RSA_PKCS1_OAEP_PADDING;
|
||||||
|
return binding.publicEncrypt(toBuf(key), buffer, padding);
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.privateDecrypt = function(options, buffer) {
|
exports.privateDecrypt = function(options, buffer) {
|
||||||
var key = options.key || options;
|
var key = options.key || options;
|
||||||
var passphrase = options.passphrase || null;
|
var passphrase = options.passphrase || null;
|
||||||
return binding.privateDecrypt(toBuf(key), buffer, passphrase);
|
var padding = options.padding || constants.RSA_PKCS1_OAEP_PADDING;
|
||||||
|
return binding.privateDecrypt(toBuf(key), buffer, padding, passphrase);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -950,6 +950,30 @@ void DefineOpenSSLConstants(Handle<Object> target) {
|
|||||||
#define NPN_ENABLED 1
|
#define NPN_ENABLED 1
|
||||||
NODE_DEFINE_CONSTANT(target, NPN_ENABLED);
|
NODE_DEFINE_CONSTANT(target, NPN_ENABLED);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef RSA_PKCS1_PADDING
|
||||||
|
NODE_DEFINE_CONSTANT(target, RSA_PKCS1_PADDING);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef RSA_SSLV23_PADDING
|
||||||
|
NODE_DEFINE_CONSTANT(target, RSA_SSLV23_PADDING);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef RSA_NO_PADDING
|
||||||
|
NODE_DEFINE_CONSTANT(target, RSA_NO_PADDING);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef RSA_PKCS1_OAEP_PADDING
|
||||||
|
NODE_DEFINE_CONSTANT(target, RSA_PKCS1_OAEP_PADDING);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef RSA_X931_PADDING
|
||||||
|
NODE_DEFINE_CONSTANT(target, RSA_X931_PADDING);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef RSA_PKCS1_PSS_PADDING
|
||||||
|
NODE_DEFINE_CONSTANT(target, RSA_PKCS1_PSS_PADDING);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefineSystemConstants(Handle<Object> target) {
|
void DefineSystemConstants(Handle<Object> target) {
|
||||||
|
@ -3552,6 +3552,7 @@ template <PublicKeyCipher::Operation operation,
|
|||||||
bool PublicKeyCipher::Cipher(const char* key_pem,
|
bool PublicKeyCipher::Cipher(const char* key_pem,
|
||||||
int key_pem_len,
|
int key_pem_len,
|
||||||
const char* passphrase,
|
const char* passphrase,
|
||||||
|
int padding,
|
||||||
const unsigned char* data,
|
const unsigned char* data,
|
||||||
int len,
|
int len,
|
||||||
unsigned char** out,
|
unsigned char** out,
|
||||||
@ -3610,8 +3611,9 @@ bool PublicKeyCipher::Cipher(const char* key_pem,
|
|||||||
goto exit;
|
goto exit;
|
||||||
if (EVP_PKEY_cipher_init(ctx) <= 0)
|
if (EVP_PKEY_cipher_init(ctx) <= 0)
|
||||||
goto exit;
|
goto exit;
|
||||||
if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING) <= 0)
|
if (EVP_PKEY_CTX_set_rsa_padding(ctx, padding) <= 0)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
if (EVP_PKEY_cipher(ctx, NULL, out_len, data, len) <= 0)
|
if (EVP_PKEY_cipher(ctx, NULL, out_len, data, len) <= 0)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
@ -3649,7 +3651,9 @@ void PublicKeyCipher::Cipher(const FunctionCallbackInfo<Value>& args) {
|
|||||||
char* buf = Buffer::Data(args[1]);
|
char* buf = Buffer::Data(args[1]);
|
||||||
ssize_t len = Buffer::Length(args[1]);
|
ssize_t len = Buffer::Length(args[1]);
|
||||||
|
|
||||||
String::Utf8Value passphrase(args[2]);
|
int padding = args[2]->Uint32Value();
|
||||||
|
|
||||||
|
String::Utf8Value passphrase(args[3]);
|
||||||
|
|
||||||
unsigned char* out_value = NULL;
|
unsigned char* out_value = NULL;
|
||||||
size_t out_len = -1;
|
size_t out_len = -1;
|
||||||
@ -3658,6 +3662,7 @@ void PublicKeyCipher::Cipher(const FunctionCallbackInfo<Value>& args) {
|
|||||||
kbuf,
|
kbuf,
|
||||||
klen,
|
klen,
|
||||||
args.Length() >= 3 && !args[2]->IsNull() ? *passphrase : NULL,
|
args.Length() >= 3 && !args[2]->IsNull() ? *passphrase : NULL,
|
||||||
|
padding,
|
||||||
reinterpret_cast<const unsigned char*>(buf),
|
reinterpret_cast<const unsigned char*>(buf),
|
||||||
len,
|
len,
|
||||||
&out_value,
|
&out_value,
|
||||||
|
@ -577,6 +577,7 @@ class PublicKeyCipher {
|
|||||||
static bool Cipher(const char* key_pem,
|
static bool Cipher(const char* key_pem,
|
||||||
int key_pem_len,
|
int key_pem_len,
|
||||||
const char* passphrase,
|
const char* passphrase,
|
||||||
|
int padding,
|
||||||
const unsigned char* data,
|
const unsigned char* data,
|
||||||
int len,
|
int len,
|
||||||
unsigned char** out,
|
unsigned char** out,
|
||||||
|
@ -857,6 +857,30 @@ assert.equal(bad_dh.verifyError, constants.DH_NOT_SUITABLE_GENERATOR);
|
|||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
function test_rsa(padding) {
|
||||||
|
var input = new Buffer(padding === 'RSA_NO_PADDING' ? 1024 / 8 : 32);
|
||||||
|
for (var i = 0; i < input.length; i++)
|
||||||
|
input[i] = (i * 7 + 11) & 0xff;
|
||||||
|
var bufferToEncrypt = new Buffer(input);
|
||||||
|
|
||||||
|
padding = constants[padding];
|
||||||
|
|
||||||
|
var encryptedBuffer = crypto.publicEncrypt({
|
||||||
|
key: rsaPubPem,
|
||||||
|
padding: padding
|
||||||
|
}, bufferToEncrypt);
|
||||||
|
|
||||||
|
var decryptedBuffer = crypto.privateDecrypt({
|
||||||
|
key: rsaKeyPem,
|
||||||
|
padding: padding
|
||||||
|
}, encryptedBuffer);
|
||||||
|
assert.equal(input, decryptedBuffer.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
test_rsa('RSA_NO_PADDING');
|
||||||
|
test_rsa('RSA_PKCS1_PADDING');
|
||||||
|
test_rsa('RSA_PKCS1_OAEP_PADDING');
|
||||||
|
|
||||||
// Test RSA key signing/verification
|
// Test RSA key signing/verification
|
||||||
var rsaSign = crypto.createSign('RSA-SHA1');
|
var rsaSign = crypto.createSign('RSA-SHA1');
|
||||||
var rsaVerify = crypto.createVerify('RSA-SHA1');
|
var rsaVerify = crypto.createVerify('RSA-SHA1');
|
||||||
|
Loading…
x
Reference in New Issue
Block a user