Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Make possible to get Buffer from crypto calls #3989

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/node.cc
Expand Up @@ -1069,6 +1069,8 @@ enum encoding ParseEncoding(Handle<Value> encoding_v, enum encoding _default) {
return BINARY; return BINARY;
} else if (strcasecmp(*encoding, "hex") == 0) { } else if (strcasecmp(*encoding, "hex") == 0) {
return HEX; return HEX;
} else if (strcasecmp(*encoding, "buffer") == 0) {
return BUFFER;
} else if (strcasecmp(*encoding, "raw") == 0) { } else if (strcasecmp(*encoding, "raw") == 0) {
if (!no_deprecation) { if (!no_deprecation) {
fprintf(stderr, "'raw' (array of integers) has been removed. " fprintf(stderr, "'raw' (array of integers) has been removed. "
Expand All @@ -1089,6 +1091,10 @@ enum encoding ParseEncoding(Handle<Value> encoding_v, enum encoding _default) {
Local<Value> Encode(const void *buf, size_t len, enum encoding encoding) { Local<Value> Encode(const void *buf, size_t len, enum encoding encoding) {
HandleScope scope; HandleScope scope;


if (encoding == BUFFER) {
return scope.Close(Buffer::New(static_cast<const char*>(buf), len)->handle_);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simplify this to something like:

if (encoding == BUFFER) {
  Buffer* b = Buffer::New(len);
  memcpy(Buffer::Data(b), buf, len);
  return scope.Close(b->handle_);
}


if (!len) return scope.Close(String::Empty()); if (!len) return scope.Close(String::Empty());


if (encoding == BINARY) { if (encoding == BINARY) {
Expand Down
2 changes: 1 addition & 1 deletion src/node.h
Expand Up @@ -127,7 +127,7 @@ void SetPrototypeMethod(target_t target,
#define NODE_SET_METHOD node::SetMethod #define NODE_SET_METHOD node::SetMethod
#define NODE_SET_PROTOTYPE_METHOD node::SetPrototypeMethod #define NODE_SET_PROTOTYPE_METHOD node::SetPrototypeMethod


enum encoding {ASCII, UTF8, BASE64, UCS2, BINARY, HEX}; enum encoding {ASCII, UTF8, BASE64, UCS2, BINARY, HEX, BUFFER};
enum encoding ParseEncoding(v8::Handle<v8::Value> encoding_v, enum encoding ParseEncoding(v8::Handle<v8::Value> encoding_v,
enum encoding _default = BINARY); enum encoding _default = BINARY);
NODE_EXTERN void FatalException(v8::TryCatch &try_catch); NODE_EXTERN void FatalException(v8::TryCatch &try_catch);
Expand Down
6 changes: 4 additions & 2 deletions src/node_buffer.cc
Expand Up @@ -137,14 +137,14 @@ Buffer* Buffer::New(size_t length) {
} }




Buffer* Buffer::New(char* data, size_t length) { Buffer* Buffer::New(const char* data, size_t length) {
HandleScope scope; HandleScope scope;


Local<Value> arg = Integer::NewFromUnsigned(0); Local<Value> arg = Integer::NewFromUnsigned(0);
Local<Object> obj = constructor_template->GetFunction()->NewInstance(1, &arg); Local<Object> obj = constructor_template->GetFunction()->NewInstance(1, &arg);


Buffer *buffer = ObjectWrap::Unwrap<Buffer>(obj); Buffer *buffer = ObjectWrap::Unwrap<Buffer>(obj);
buffer->Replace(data, length, NULL, NULL); buffer->Replace(const_cast<char*>(data), length, NULL, NULL);


return buffer; return buffer;
} }
Expand Down Expand Up @@ -198,6 +198,8 @@ Buffer::~Buffer() {
} }




// if replace doesn't have a callback, data must be copied
// const_cast in Buffer::New requires this
void Buffer::Replace(char *data, size_t length, void Buffer::Replace(char *data, size_t length,
free_callback callback, void *hint) { free_callback callback, void *hint) {
HandleScope scope; HandleScope scope;
Expand Down
10 changes: 7 additions & 3 deletions src/node_buffer.h
Expand Up @@ -97,10 +97,14 @@ class NODE_EXTERN Buffer: public ObjectWrap {
static v8::Handle<v8::Object> New(v8::Handle<v8::String> string); static v8::Handle<v8::Object> New(v8::Handle<v8::String> string);


static void Initialize(v8::Handle<v8::Object> target); static void Initialize(v8::Handle<v8::Object> target);
static Buffer* New(size_t length); // public constructor
static Buffer* New(char *data, size_t len); // public constructor // public constructor
static Buffer* New(size_t length);
// public constructor - data is copied
static Buffer* New(const char *data, size_t len);
// public constructor
static Buffer* New(char *data, size_t length, static Buffer* New(char *data, size_t length,
free_callback callback, void *hint); // public constructor free_callback callback, void *hint);


private: private:
static v8::Handle<v8::Value> New(const v8::Arguments &args); static v8::Handle<v8::Value> New(const v8::Arguments &args);
Expand Down
48 changes: 24 additions & 24 deletions src/node_crypto.cc
Expand Up @@ -2497,11 +2497,11 @@ class Cipher : public ObjectWrap {
base64(out, out_len, &out_hexdigest, &out_hex_len); base64(out, out_len, &out_hexdigest, &out_hex_len);
outString = Encode(out_hexdigest, out_hex_len, BINARY); outString = Encode(out_hexdigest, out_hex_len, BINARY);
delete [] out_hexdigest; delete [] out_hexdigest;
} else if (enc == BINARY) { } else if (enc == BINARY || enc == BUFFER) {
outString = Encode(out, out_len, BINARY); outString = Encode(out, out_len, enc);
} else { } else {
fprintf(stderr, "node-crypto : Cipher .update encoding " fprintf(stderr, "node-crypto : Cipher .update encoding "
"can be binary, hex or base64\n"); "can be binary, hex, base64 or buffer\n");
} }
} }


Expand Down Expand Up @@ -2570,11 +2570,11 @@ class Cipher : public ObjectWrap {
base64(out_value, out_len, &out_hexdigest, &out_hex_len); base64(out_value, out_len, &out_hexdigest, &out_hex_len);
outString = Encode(out_hexdigest, out_hex_len, BINARY); outString = Encode(out_hexdigest, out_hex_len, BINARY);
delete [] out_hexdigest; delete [] out_hexdigest;
} else if (enc == BINARY) { } else if (enc == BINARY || enc == BUFFER) {
outString = Encode(out_value, out_len, BINARY); outString = Encode(out_value, out_len, enc);
} else { } else {
fprintf(stderr, "node-crypto : Cipher .final encoding " fprintf(stderr, "node-crypto : Cipher .final encoding "
"can be binary, hex or base64\n"); "can be binary, hex, base64 or buffer\n");
} }


delete [] out_value; delete [] out_value;
Expand Down Expand Up @@ -2909,12 +2909,12 @@ class Decipher : public ObjectWrap {
len = ciphertext_len; len = ciphertext_len;
alloc_buf = true; alloc_buf = true;


} else if (enc == BINARY) { } else if (enc == BINARY || enc == BUFFER) {
// Binary - do nothing // Binary - do nothing


} else { } else {
fprintf(stderr, "node-crypto : Decipher .update encoding " fprintf(stderr, "node-crypto : Decipher .update encoding "
"can be binary, hex or base64\n"); "can be binary, hex, base64 or buffer\n");
} }


unsigned char *out=0; unsigned char *out=0;
Expand Down Expand Up @@ -3216,11 +3216,11 @@ class Hmac : public ObjectWrap {
base64(md_value, md_len, &md_hexdigest, &md_hex_len); base64(md_value, md_len, &md_hexdigest, &md_hex_len);
outString = Encode(md_hexdigest, md_hex_len, BINARY); outString = Encode(md_hexdigest, md_hex_len, BINARY);
delete [] md_hexdigest; delete [] md_hexdigest;
} else if (enc == BINARY) { } else if (enc == BINARY || enc == BUFFER) {
outString = Encode(md_value, md_len, BINARY); outString = Encode(md_value, md_len, enc);
} else { } else {
fprintf(stderr, "node-crypto : Hmac .digest encoding " fprintf(stderr, "node-crypto : Hmac .digest encoding "
"can be binary, hex or base64\n"); "can be binary, hex, base64 or buffer\n");
} }
delete [] md_value; delete [] md_value;
return scope.Close(outString); return scope.Close(outString);
Expand Down Expand Up @@ -3371,11 +3371,11 @@ class Hash : public ObjectWrap {
base64(md_value, md_len, &md_hexdigest, &md_hex_len); base64(md_value, md_len, &md_hexdigest, &md_hex_len);
outString = Encode(md_hexdigest, md_hex_len, BINARY); outString = Encode(md_hexdigest, md_hex_len, BINARY);
delete [] md_hexdigest; delete [] md_hexdigest;
} else if (enc == BINARY) { } else if (enc == BINARY || enc == BUFFER) {
outString = Encode(md_value, md_len, BINARY); outString = Encode(md_value, md_len, enc);
} else { } else {
fprintf(stderr, "node-crypto : Hash .digest encoding " fprintf(stderr, "node-crypto : Hash .digest encoding "
"can be binary, hex or base64\n"); "can be binary, hex, base64 or buffer\n");
} }


return scope.Close(outString); return scope.Close(outString);
Expand Down Expand Up @@ -3573,12 +3573,12 @@ class Sign : public ObjectWrap {
base64(md_value, md_len, &md_hexdigest, &md_hex_len); base64(md_value, md_len, &md_hexdigest, &md_hex_len);
outString = Encode(md_hexdigest, md_hex_len, BINARY); outString = Encode(md_hexdigest, md_hex_len, BINARY);
delete [] md_hexdigest; delete [] md_hexdigest;
} else if (enc == BINARY) { } else if (enc == BINARY || enc == BUFFER) {
outString = Encode(md_value, md_len, BINARY); outString = Encode(md_value, md_len, enc);
} else { } else {
outString = String::New(""); outString = String::New("");
fprintf(stderr, "node-crypto : Sign .sign encoding " fprintf(stderr, "node-crypto : Sign .sign encoding "
"can be binary, hex or base64\n"); "can be binary, hex, base64 or buffer\n");
} }


delete [] md_value; delete [] md_value;
Expand Down Expand Up @@ -3825,11 +3825,11 @@ class Verify : public ObjectWrap {
unbase64(hbuf, hlen, (char **)&dbuf, &dlen); unbase64(hbuf, hlen, (char **)&dbuf, &dlen);
r = verify->VerifyFinal(kbuf, klen, dbuf, dlen); r = verify->VerifyFinal(kbuf, klen, dbuf, dlen);
delete [] dbuf; delete [] dbuf;
} else if (enc == BINARY) { } else if (enc == BINARY || enc == BUFFER) {
r = verify->VerifyFinal(kbuf, klen, hbuf, hlen); r = verify->VerifyFinal(kbuf, klen, hbuf, hlen);
} else { } else {
fprintf(stderr, "node-crypto : Verify .verify encoding " fprintf(stderr, "node-crypto : Verify .verify encoding "
"can be binary, hex or base64\n"); "can be binary, hex, base64 or buffer\n");
} }


delete [] kbuf; delete [] kbuf;
Expand Down Expand Up @@ -4381,11 +4381,11 @@ class DiffieHellman : public ObjectWrap {
} else if (enc == BASE64) { } else if (enc == BASE64) {
unbase64((unsigned char*)*buf, len, &retbuf, &retlen); unbase64((unsigned char*)*buf, len, &retbuf, &retlen);


} else if (enc == BINARY) { } else if (enc == BINARY || enc == BUFFER) {
// Binary - do nothing // Binary - do nothing
} else { } else {
fprintf(stderr, "node-crypto : Diffie-Hellman parameter encoding " fprintf(stderr, "node-crypto : Diffie-Hellman parameter encoding "
"can be binary, hex or base64\n"); "can be binary, hex, base64 or buffer\n");
} }


if (retbuf != 0) { if (retbuf != 0) {
Expand Down Expand Up @@ -4415,11 +4415,11 @@ class DiffieHellman : public ObjectWrap {
base64(reinterpret_cast<unsigned char*>(buf), len, &retbuf, &retlen); base64(reinterpret_cast<unsigned char*>(buf), len, &retbuf, &retlen);
outString = Encode(retbuf, retlen, BINARY); outString = Encode(retbuf, retlen, BINARY);
delete [] retbuf; delete [] retbuf;
} else if (enc == BINARY) { } else if (enc == BINARY || enc == BUFFER) {
outString = Encode(buf, len, BINARY); outString = Encode(buf, len, enc);
} else { } else {
fprintf(stderr, "node-crypto : Diffie-Hellman parameter encoding " fprintf(stderr, "node-crypto : Diffie-Hellman parameter encoding "
"can be binary, hex or base64\n"); "can be binary, hex, base64 or buffer\n");
} }


return scope.Close(outString); return scope.Close(outString);
Expand Down
7 changes: 7 additions & 0 deletions test/simple/test-crypto.js
Expand Up @@ -369,6 +369,7 @@ var a0 = crypto.createHash('sha1').update('Test123').digest('hex');
var a1 = crypto.createHash('md5').update('Test123').digest('binary'); var a1 = crypto.createHash('md5').update('Test123').digest('binary');
var a2 = crypto.createHash('sha256').update('Test123').digest('base64'); var a2 = crypto.createHash('sha256').update('Test123').digest('base64');
var a3 = crypto.createHash('sha512').update('Test123').digest(); // binary var a3 = crypto.createHash('sha512').update('Test123').digest(); // binary
var a4 = crypto.createHash('sha512').update('Test123').digest('buffer');


assert.equal(a0, '8308651804facb7b9af8ffc53a33a22d6a1c8ac2', 'Test SHA1'); assert.equal(a0, '8308651804facb7b9af8ffc53a33a22d6a1c8ac2', 'Test SHA1');
assert.equal(a1, 'h\u00ea\u00cb\u0097\u00d8o\fF!\u00fa+\u000e\u0017\u00ca' + assert.equal(a1, 'h\u00ea\u00cb\u0097\u00d8o\fF!\u00fa+\u000e\u0017\u00ca' +
Expand All @@ -381,6 +382,12 @@ assert.equal(a3, '\u00c1(4\u00f1\u0003\u001fd\u0097!O\'\u00d4C/&Qz\u00d4' +
'\u00d7\u00d6\u00a2\u00a8\u0085\u00e3<\u0083\u009c\u0093' + '\u00d7\u00d6\u00a2\u00a8\u0085\u00e3<\u0083\u009c\u0093' +
'\u00c2\u0006\u00da0\u00a1\u00879(G\u00ed\'', '\u00c2\u0006\u00da0\u00a1\u00879(G\u00ed\'',
'Test SHA512 as assumed binary'); 'Test SHA512 as assumed binary');
assert.ok(a4 instanceof Buffer, 'Test SHA512 if output is Buffer');
assert.deepEqual(a4,
new Buffer('c12834f1031f6497214f27d4432f26517ad494156cb8'+
'8d512bdb1dc4b57db2d692a3dfa269a19b0a0a2a0fd7'+
'd6a2a885e33c839c93c206da30a187392847ed27', 'hex'),
'Test SHA512 as assumed buffer');


// Test multiple updates to same hash // Test multiple updates to same hash
var h1 = crypto.createHash('sha1').update('Test123').digest('hex'); var h1 = crypto.createHash('sha1').update('Test123').digest('hex');
Expand Down