1 #include <assert.h>
2 #include <node.h>
3 #include <openssl/md5.h>
4 #include <openssl/rand.h>
5 #include <openssl/ssl.h>
6
7 namespace {
8
RandomBytes(const v8::FunctionCallbackInfo<v8::Value>& info)9 inline void RandomBytes(const v8::FunctionCallbackInfo<v8::Value>& info) {
10 assert(info[0]->IsArrayBufferView());
11 auto view = info[0].As<v8::ArrayBufferView>();
12 auto byte_offset = view->ByteOffset();
13 auto byte_length = view->ByteLength();
14 assert(view->HasBuffer());
15 auto buffer = view->Buffer();
16 auto contents = buffer->GetBackingStore();
17 auto data = static_cast<unsigned char*>(contents->Data()) + byte_offset;
18 assert(RAND_poll());
19 auto rval = RAND_bytes(data, static_cast<int>(byte_length));
20 info.GetReturnValue().Set(rval > 0);
21 }
22
Hash(const v8::FunctionCallbackInfo<v8::Value>& info)23 inline void Hash(const v8::FunctionCallbackInfo<v8::Value>& info) {
24 assert(info[0]->IsArrayBufferView());
25 auto view = info[0].As<v8::ArrayBufferView>();
26 auto byte_offset = view->ByteOffset();
27 auto len = view->ByteLength();
28 assert(view->HasBuffer());
29 auto buffer = view->Buffer();
30 auto contents = buffer->GetBackingStore();
31 auto data = static_cast<unsigned char*>(contents->Data()) + byte_offset;
32 unsigned char md[MD5_DIGEST_LENGTH];
33 MD5_CTX c;
34 auto rval = MD5_Init(&c) && MD5_Update(&c, data, len) && MD5_Final(md, &c);
35 info.GetReturnValue().Set(rval > 0);
36 }
37
Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> module, v8::Local<v8::Context> context)38 inline void Initialize(v8::Local<v8::Object> exports,
39 v8::Local<v8::Value> module,
40 v8::Local<v8::Context> context) {
41 auto isolate = context->GetIsolate();
42 auto key = v8::String::NewFromUtf8(
43 isolate, "randomBytes").ToLocalChecked();
44 auto value = v8::FunctionTemplate::New(isolate, RandomBytes)
45 ->GetFunction(context)
46 .ToLocalChecked();
47 assert(exports->Set(context, key, value).IsJust());
48
49 const SSL_METHOD* method = TLSv1_2_server_method();
50 assert(method != nullptr);
51
52 key = v8::String::NewFromUtf8(isolate, "hash").ToLocalChecked();
53 value = v8::FunctionTemplate::New(isolate, Hash)
54 ->GetFunction(context)
55 .ToLocalChecked();
56 assert(exports->Set(context, key, value).IsJust());
57 }
58
59 } // anonymous namespace
60
61 NODE_MODULE_CONTEXT_AWARE(NODE_GYP_MODULE_NAME, Initialize)
62