crypto: Pass strings to binding layer directly
This commit is contained in:
parent
119354f735
commit
a1eacdf12a
@ -163,6 +163,8 @@ util.inherits(LazyTransform, stream.Transform);
|
|||||||
Object.defineProperty(LazyTransform.prototype, prop, {
|
Object.defineProperty(LazyTransform.prototype, prop, {
|
||||||
get: function() {
|
get: function() {
|
||||||
stream.Transform.call(this, this._options);
|
stream.Transform.call(this, this._options);
|
||||||
|
this._writableState.decodeStrings = false;
|
||||||
|
this._writableState.defaultEncoding = 'binary';
|
||||||
return this[prop];
|
return this[prop];
|
||||||
},
|
},
|
||||||
set: function(val) {
|
set: function(val) {
|
||||||
@ -201,8 +203,9 @@ Hash.prototype._flush = function(callback) {
|
|||||||
|
|
||||||
Hash.prototype.update = function(data, encoding) {
|
Hash.prototype.update = function(data, encoding) {
|
||||||
encoding = encoding || exports.DEFAULT_ENCODING;
|
encoding = encoding || exports.DEFAULT_ENCODING;
|
||||||
data = toBuf(data, encoding);
|
if (encoding === 'buffer' && typeof data === 'string')
|
||||||
this._binding.update(data);
|
encoding = 'binary';
|
||||||
|
this._binding.update(data, encoding);
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -268,9 +271,8 @@ Cipher.prototype._flush = function(callback) {
|
|||||||
Cipher.prototype.update = function(data, inputEncoding, outputEncoding) {
|
Cipher.prototype.update = function(data, inputEncoding, outputEncoding) {
|
||||||
inputEncoding = inputEncoding || exports.DEFAULT_ENCODING;
|
inputEncoding = inputEncoding || exports.DEFAULT_ENCODING;
|
||||||
outputEncoding = outputEncoding || exports.DEFAULT_ENCODING;
|
outputEncoding = outputEncoding || exports.DEFAULT_ENCODING;
|
||||||
data = toBuf(data, inputEncoding);
|
|
||||||
|
|
||||||
var ret = this._binding.update(data);
|
var ret = this._binding.update(data, inputEncoding);
|
||||||
|
|
||||||
if (outputEncoding && outputEncoding !== 'buffer') {
|
if (outputEncoding && outputEncoding !== 'buffer') {
|
||||||
this._decoder = getDecoder(this._decoder, outputEncoding);
|
this._decoder = getDecoder(this._decoder, outputEncoding);
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
#include "node_buffer.h"
|
#include "node_buffer.h"
|
||||||
|
#include "string_bytes.h"
|
||||||
#include "node_root_certs.h"
|
#include "node_root_certs.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -41,6 +42,12 @@
|
|||||||
# define OPENSSL_CONST
|
# define OPENSSL_CONST
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define ASSERT_IS_STRING_OR_BUFFER(val) \
|
||||||
|
if (!Buffer::HasInstance(val) && !val->IsString()) { \
|
||||||
|
return ThrowException(Exception::TypeError(String::New( \
|
||||||
|
"Not a string or buffer"))); \
|
||||||
|
}
|
||||||
|
|
||||||
#define ASSERT_IS_BUFFER(val) \
|
#define ASSERT_IS_BUFFER(val) \
|
||||||
if (!Buffer::HasInstance(val)) { \
|
if (!Buffer::HasInstance(val)) { \
|
||||||
return ThrowException(Exception::TypeError(String::New("Not a buffer"))); \
|
return ThrowException(Exception::TypeError(String::New("Not a buffer"))); \
|
||||||
@ -2225,24 +2232,33 @@ class Cipher : public ObjectWrap {
|
|||||||
|
|
||||||
HandleScope scope;
|
HandleScope scope;
|
||||||
|
|
||||||
ASSERT_IS_BUFFER(args[0]);
|
ASSERT_IS_STRING_OR_BUFFER(args[0]);
|
||||||
|
|
||||||
|
// Only copy the data if we have to, because it's a string
|
||||||
unsigned char* out=0;
|
unsigned char* out=0;
|
||||||
int out_len=0, r;
|
int out_len=0, r;
|
||||||
char* buffer_data = Buffer::Data(args[0]);
|
if (args[0]->IsString()) {
|
||||||
size_t buffer_length = Buffer::Length(args[0]);
|
enum encoding encoding = ParseEncoding(args[1], BINARY);
|
||||||
|
size_t buflen = StringBytes::SizeFast(args[0], encoding);
|
||||||
r = cipher->CipherUpdate(buffer_data, buffer_length, &out, &out_len);
|
char* buf = static_cast<char*>(malloc(buflen));
|
||||||
|
size_t written = StringBytes::Write(buf, buflen, args[0], encoding);
|
||||||
|
r = cipher->CipherUpdate(buf, written, &out, &out_len);
|
||||||
|
free(buf);
|
||||||
|
} else {
|
||||||
|
char* buf = Buffer::Data(args[0]);
|
||||||
|
size_t buflen = Buffer::Length(args[0]);
|
||||||
|
r = cipher->CipherUpdate(buf, buflen, &out, &out_len);
|
||||||
|
}
|
||||||
|
|
||||||
if (r == 0) {
|
if (r == 0) {
|
||||||
delete [] out;
|
delete[] out;
|
||||||
return ThrowCryptoTypeError(ERR_get_error());
|
return ThrowCryptoTypeError(ERR_get_error());
|
||||||
}
|
}
|
||||||
|
|
||||||
Local<Value> outString;
|
Local<Value> outString;
|
||||||
outString = Encode(out, out_len, BUFFER);
|
outString = Encode(out, out_len, BUFFER);
|
||||||
|
|
||||||
if (out) delete [] out;
|
if (out) delete[] out;
|
||||||
|
|
||||||
return scope.Close(outString);
|
return scope.Close(outString);
|
||||||
}
|
}
|
||||||
@ -2525,25 +2541,26 @@ class Decipher : public ObjectWrap {
|
|||||||
|
|
||||||
Decipher *cipher = ObjectWrap::Unwrap<Decipher>(args.This());
|
Decipher *cipher = ObjectWrap::Unwrap<Decipher>(args.This());
|
||||||
|
|
||||||
ASSERT_IS_BUFFER(args[0]);
|
ASSERT_IS_STRING_OR_BUFFER(args[0]);
|
||||||
|
|
||||||
ssize_t len;
|
|
||||||
|
|
||||||
char* buf;
|
|
||||||
// if alloc_buf then buf must be deleted later
|
|
||||||
bool alloc_buf = false;
|
|
||||||
char* buffer_data = Buffer::Data(args[0]);
|
|
||||||
size_t buffer_length = Buffer::Length(args[0]);
|
|
||||||
|
|
||||||
buf = buffer_data;
|
|
||||||
len = buffer_length;
|
|
||||||
|
|
||||||
|
// Only copy the data if we have to, because it's a string
|
||||||
unsigned char* out=0;
|
unsigned char* out=0;
|
||||||
int out_len=0;
|
int out_len=0, r;
|
||||||
int r = cipher->DecipherUpdate(buf, len, &out, &out_len);
|
if (args[0]->IsString()) {
|
||||||
|
enum encoding encoding = ParseEncoding(args[1], BINARY);
|
||||||
|
size_t buflen = StringBytes::SizeFast(args[0], encoding);
|
||||||
|
char* buf = static_cast<char*>(malloc(buflen));
|
||||||
|
size_t written = StringBytes::Write(buf, buflen, args[0], encoding);
|
||||||
|
r = cipher->DecipherUpdate(buf, written, &out, &out_len);
|
||||||
|
free(buf);
|
||||||
|
} else {
|
||||||
|
char* buf = Buffer::Data(args[0]);
|
||||||
|
size_t buflen = Buffer::Length(args[0]);
|
||||||
|
r = cipher->DecipherUpdate(buf, buflen, &out, &out_len);
|
||||||
|
}
|
||||||
|
|
||||||
if (!r) {
|
if (r == 0) {
|
||||||
delete [] out;
|
delete[] out;
|
||||||
return ThrowCryptoTypeError(ERR_get_error());
|
return ThrowCryptoTypeError(ERR_get_error());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2552,9 +2569,7 @@ class Decipher : public ObjectWrap {
|
|||||||
|
|
||||||
if (out) delete [] out;
|
if (out) delete [] out;
|
||||||
|
|
||||||
if (alloc_buf) delete [] buf;
|
|
||||||
return scope.Close(outString);
|
return scope.Close(outString);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Handle<Value> SetAutoPadding(const Arguments& args) {
|
static Handle<Value> SetAutoPadding(const Arguments& args) {
|
||||||
@ -2716,14 +2731,22 @@ class Hmac : public ObjectWrap {
|
|||||||
|
|
||||||
HandleScope scope;
|
HandleScope scope;
|
||||||
|
|
||||||
ASSERT_IS_BUFFER(args[0]);
|
ASSERT_IS_STRING_OR_BUFFER(args[0]);
|
||||||
|
|
||||||
|
// Only copy the data if we have to, because it's a string
|
||||||
int r;
|
int r;
|
||||||
|
if (args[0]->IsString()) {
|
||||||
char* buffer_data = Buffer::Data(args[0]);
|
enum encoding encoding = ParseEncoding(args[1], BINARY);
|
||||||
size_t buffer_length = Buffer::Length(args[0]);
|
size_t buflen = StringBytes::SizeFast(args[0], encoding);
|
||||||
|
char* buf = static_cast<char*>(malloc(buflen));
|
||||||
r = hmac->HmacUpdate(buffer_data, buffer_length);
|
size_t written = StringBytes::Write(buf, buflen, args[0], encoding);
|
||||||
|
r = hmac->HmacUpdate(buf, written);
|
||||||
|
free(buf);
|
||||||
|
} else {
|
||||||
|
char* buf = Buffer::Data(args[0]);
|
||||||
|
size_t buflen = Buffer::Length(args[0]);
|
||||||
|
r = hmac->HmacUpdate(buf, buflen);
|
||||||
|
}
|
||||||
|
|
||||||
if (!r) {
|
if (!r) {
|
||||||
Local<Value> exception = Exception::TypeError(String::New("HmacUpdate fail"));
|
Local<Value> exception = Exception::TypeError(String::New("HmacUpdate fail"));
|
||||||
@ -2831,13 +2854,22 @@ class Hash : public ObjectWrap {
|
|||||||
|
|
||||||
Hash *hash = ObjectWrap::Unwrap<Hash>(args.This());
|
Hash *hash = ObjectWrap::Unwrap<Hash>(args.This());
|
||||||
|
|
||||||
ASSERT_IS_BUFFER(args[0]);
|
ASSERT_IS_STRING_OR_BUFFER(args[0]);
|
||||||
|
|
||||||
|
// Only copy the data if we have to, because it's a string
|
||||||
int r;
|
int r;
|
||||||
|
if (args[0]->IsString()) {
|
||||||
char* buffer_data = Buffer::Data(args[0]);
|
enum encoding encoding = ParseEncoding(args[1], BINARY);
|
||||||
size_t buffer_length = Buffer::Length(args[0]);
|
size_t buflen = StringBytes::SizeFast(args[0], encoding);
|
||||||
r = hash->HashUpdate(buffer_data, buffer_length);
|
char* buf = static_cast<char*>(malloc(buflen));
|
||||||
|
size_t written = StringBytes::Write(buf, buflen, args[0], encoding);
|
||||||
|
r = hash->HashUpdate(buf, written);
|
||||||
|
free(buf);
|
||||||
|
} else {
|
||||||
|
char* buf = Buffer::Data(args[0]);
|
||||||
|
size_t buflen = Buffer::Length(args[0]);
|
||||||
|
r = hash->HashUpdate(buf, buflen);
|
||||||
|
}
|
||||||
|
|
||||||
if (!r) {
|
if (!r) {
|
||||||
Local<Value> exception = Exception::TypeError(String::New("HashUpdate fail"));
|
Local<Value> exception = Exception::TypeError(String::New("HashUpdate fail"));
|
||||||
@ -2983,14 +3015,22 @@ class Sign : public ObjectWrap {
|
|||||||
|
|
||||||
HandleScope scope;
|
HandleScope scope;
|
||||||
|
|
||||||
ASSERT_IS_BUFFER(args[0]);
|
ASSERT_IS_STRING_OR_BUFFER(args[0]);
|
||||||
|
|
||||||
|
// Only copy the data if we have to, because it's a string
|
||||||
int r;
|
int r;
|
||||||
|
if (args[0]->IsString()) {
|
||||||
char* buffer_data = Buffer::Data(args[0]);
|
enum encoding encoding = ParseEncoding(args[1], BINARY);
|
||||||
size_t buffer_length = Buffer::Length(args[0]);
|
size_t buflen = StringBytes::SizeFast(args[0], encoding);
|
||||||
|
char* buf = static_cast<char*>(malloc(buflen));
|
||||||
r = sign->SignUpdate(buffer_data, buffer_length);
|
size_t written = StringBytes::Write(buf, buflen, args[0], encoding);
|
||||||
|
r = sign->SignUpdate(buf, written);
|
||||||
|
free(buf);
|
||||||
|
} else {
|
||||||
|
char* buf = Buffer::Data(args[0]);
|
||||||
|
size_t buflen = Buffer::Length(args[0]);
|
||||||
|
r = sign->SignUpdate(buf, buflen);
|
||||||
|
}
|
||||||
|
|
||||||
if (!r) {
|
if (!r) {
|
||||||
Local<Value> exception = Exception::TypeError(String::New("SignUpdate fail"));
|
Local<Value> exception = Exception::TypeError(String::New("SignUpdate fail"));
|
||||||
@ -3194,14 +3234,22 @@ class Verify : public ObjectWrap {
|
|||||||
|
|
||||||
Verify *verify = ObjectWrap::Unwrap<Verify>(args.This());
|
Verify *verify = ObjectWrap::Unwrap<Verify>(args.This());
|
||||||
|
|
||||||
ASSERT_IS_BUFFER(args[0]);
|
ASSERT_IS_STRING_OR_BUFFER(args[0]);
|
||||||
|
|
||||||
|
// Only copy the data if we have to, because it's a string
|
||||||
int r;
|
int r;
|
||||||
|
if (args[0]->IsString()) {
|
||||||
char* buffer_data = Buffer::Data(args[0]);
|
enum encoding encoding = ParseEncoding(args[1], BINARY);
|
||||||
size_t buffer_length = Buffer::Length(args[0]);
|
size_t buflen = StringBytes::SizeFast(args[0], encoding);
|
||||||
|
char* buf = static_cast<char*>(malloc(buflen));
|
||||||
r = verify->VerifyUpdate(buffer_data, buffer_length);
|
size_t written = StringBytes::Write(buf, buflen, args[0], encoding);
|
||||||
|
r = verify->VerifyUpdate(buf, written);
|
||||||
|
free(buf);
|
||||||
|
} else {
|
||||||
|
char* buf = Buffer::Data(args[0]);
|
||||||
|
size_t buflen = Buffer::Length(args[0]);
|
||||||
|
r = verify->VerifyUpdate(buf, buflen);
|
||||||
|
}
|
||||||
|
|
||||||
if (!r) {
|
if (!r) {
|
||||||
Local<Value> exception = Exception::TypeError(String::New("VerifyUpdate fail"));
|
Local<Value> exception = Exception::TypeError(String::New("VerifyUpdate fail"));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user