1#include <assert.h>
2#include <node.h>
3#include <openssl/md5.h>
4#include <openssl/rand.h>
5#include <openssl/ssl.h>
6
7namespace {
8
9inline 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
23inline 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
38inline 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
61NODE_MODULE_CONTEXT_AWARE(NODE_GYP_MODULE_NAME, Initialize)
62