summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--node.gyp56
-rw-r--r--test/addons/openssl-binding/binding.cc35
-rw-r--r--test/addons/openssl-binding/binding.gyp9
-rw-r--r--test/addons/openssl-binding/test.js8
-rwxr-xr-xtools/mkssldef.py44
5 files changed, 152 insertions, 0 deletions
diff --git a/node.gyp b/node.gyp
index 8c9f9c6984..a1a5284292 100644
--- a/node.gyp
+++ b/node.gyp
@@ -109,6 +109,13 @@
}, {
'node_target_type%': 'executable',
}],
+ [ 'OS=="win" and '
+ 'node_use_openssl=="true" and '
+ 'node_shared_openssl=="false"', {
+ 'use_openssl_def': 1,
+ }, {
+ 'use_openssl_def': 0,
+ }],
],
},
@@ -354,6 +361,9 @@
'-Wl,--no-whole-archive',
],
}],
+ ['use_openssl_def==1', {
+ 'sources': ['<(SHARED_INTERMEDIATE_DIR)/openssl.def'],
+ }],
],
}],
],
@@ -530,6 +540,52 @@
}],
],
},
+ {
+ 'target_name': 'mkssldef',
+ 'type': 'none',
+ # TODO(bnoordhuis) Make all platforms export the same list of symbols.
+ # Teach mkssldef.py to generate linker maps that UNIX linkers understand.
+ 'conditions': [
+ [ 'use_openssl_def==1', {
+ 'variables': {
+ 'mkssldef_flags': [
+ # Categories to export.
+ '-CAES,BF,BIO,DES,DH,DSA,EC,ECDH,ECDSA,ENGINE,EVP,HMAC,MD4,MD5,'
+ 'NEXTPROTONEG,PSK,RC2,RC4,RSA,SHA,SHA0,SHA1,SHA256,SHA512,TLSEXT',
+ # Defines.
+ '-DWIN32',
+ # Symbols to filter from the export list.
+ '-X^DSO',
+ '-X^_',
+ '-X^private_',
+ ],
+ },
+ 'conditions': [
+ ['openssl_fips!=""', {
+ 'variables': { 'mkssldef_flags': ['-DOPENSSL_FIPS'] },
+ }],
+ ],
+ 'actions': [
+ {
+ 'action_name': 'mkssldef',
+ 'inputs': [
+ 'deps/openssl/openssl/util/libeay.num',
+ 'deps/openssl/openssl/util/ssleay.num',
+ ],
+ 'outputs': ['<(SHARED_INTERMEDIATE_DIR)/openssl.def'],
+ 'action': [
+ 'python',
+ 'tools/mkssldef.py',
+ '<@(mkssldef_flags)',
+ '-o',
+ '<@(_outputs)',
+ '<@(_inputs)',
+ ],
+ },
+ ],
+ }],
+ ],
+ },
# generate ETW header and resource files
{
'target_name': 'node_etw',
diff --git a/test/addons/openssl-binding/binding.cc b/test/addons/openssl-binding/binding.cc
new file mode 100644
index 0000000000..59819cd33d
--- /dev/null
+++ b/test/addons/openssl-binding/binding.cc
@@ -0,0 +1,35 @@
+#include "node.h"
+#include "../../../src/util.h"
+#include "../../../src/util-inl.h"
+
+#include <assert.h>
+#include <openssl/rand.h>
+
+namespace {
+
+inline void RandomBytes(const v8::FunctionCallbackInfo<v8::Value>& info) {
+ assert(info[0]->IsArrayBufferView());
+ auto view = info[0].As<v8::ArrayBufferView>();
+ auto byte_offset = view->ByteOffset();
+ auto byte_length = view->ByteLength();
+ assert(view->HasBuffer());
+ auto buffer = view->Buffer();
+ auto contents = buffer->GetContents();
+ auto data = static_cast<unsigned char*>(contents.Data()) + byte_offset;
+ assert(RAND_poll());
+ auto rval = RAND_bytes(data, static_cast<int>(byte_length));
+ info.GetReturnValue().Set(rval > 0);
+}
+
+inline void Initialize(v8::Local<v8::Object> exports,
+ v8::Local<v8::Value> module,
+ v8::Local<v8::Context> context) {
+ auto isolate = context->GetIsolate();
+ auto key = v8::String::NewFromUtf8(isolate, "randomBytes");
+ auto value = v8::FunctionTemplate::New(isolate, RandomBytes)->GetFunction();
+ assert(exports->Set(context, key, value).IsJust());
+}
+
+} // anonymous namespace
+
+NODE_MODULE_CONTEXT_AWARE(binding, Initialize)
diff --git a/test/addons/openssl-binding/binding.gyp b/test/addons/openssl-binding/binding.gyp
new file mode 100644
index 0000000000..672f84bb86
--- /dev/null
+++ b/test/addons/openssl-binding/binding.gyp
@@ -0,0 +1,9 @@
+{
+ 'targets': [
+ {
+ 'target_name': 'binding',
+ 'sources': ['binding.cc'],
+ 'include_dirs': ['../../../deps/openssl/openssl/include'],
+ },
+ ]
+}
diff --git a/test/addons/openssl-binding/test.js b/test/addons/openssl-binding/test.js
new file mode 100644
index 0000000000..aa515bac9a
--- /dev/null
+++ b/test/addons/openssl-binding/test.js
@@ -0,0 +1,8 @@
+'use strict';
+
+require('../../common');
+const assert = require('assert');
+const binding = require('./build/Release/binding');
+const bytes = new Uint8Array(1024);
+assert(binding.randomBytes(bytes));
+assert(bytes.reduce((v, a) => v + a) > 0);
diff --git a/tools/mkssldef.py b/tools/mkssldef.py
new file mode 100755
index 0000000000..8cbdbabd97
--- /dev/null
+++ b/tools/mkssldef.py
@@ -0,0 +1,44 @@
+#!/usr/bin/env python
+
+from __future__ import print_function
+import re
+import sys
+
+categories = []
+defines = []
+excludes = []
+
+if __name__ == '__main__':
+ out = sys.stdout
+ filenames = sys.argv[1:]
+
+ while filenames and filenames[0].startswith('-'):
+ option = filenames.pop(0)
+ if option == '-o': out = open(filenames.pop(0), 'w')
+ elif option.startswith('-C'): categories += option[2:].split(',')
+ elif option.startswith('-D'): defines += option[2:].split(',')
+ elif option.startswith('-X'): excludes += option[2:].split(',')
+
+ excludes = map(re.compile, excludes)
+ exported = []
+
+ for filename in filenames:
+ for line in open(filename).readlines():
+ name, _, meta, _ = re.split('\s+', line)
+ if any(map(lambda p: p.match(name), excludes)): continue
+ meta = meta.split(':')
+ assert meta[0] in ('EXIST', 'NOEXIST')
+ assert meta[2] in ('FUNCTION', 'VARIABLE')
+ if meta[0] != 'EXIST': continue
+ if meta[2] != 'FUNCTION': continue
+ def satisfy(expr, rules):
+ def test(expr):
+ if expr.startswith('!'): return not expr[1:] in rules
+ return expr == '' or expr in rules
+ return all(map(test, expr.split(',')))
+ if not satisfy(meta[1], defines): continue
+ if not satisfy(meta[3], categories): continue
+ exported.append(name)
+
+ print('EXPORTS', file=out)
+ for name in sorted(exported): print(' ', name, file=out)