2

我读过这个:https ://github.com/TooTallNate/node-gyp/wiki/Linking-to-OpenSSL ,但由于某种原因它对我不起作用。尝试从节点请求插件时,我收到“未定义的符号:SHA1”。这是我的代码(src/sha_export.cc):

#include <node.h>
#include <node_buffer.h>
#include <v8.h>

#include <openssl/sha.h>

using namespace v8;

Handle<Value> Sha1(const Arguments& args) {
  HandleScope scope;

  if (args.Length() < 1) {
    ThrowException(Exception::TypeError(String::New("Wrong number of arguments")));
    return scope.Close(Undefined());
  }

  unsigned char*msg = (unsigned char*) node::Buffer::Data(args[0]->ToObject());
  size_t msglen = node::Buffer::Length(args[0]->ToObject());
  unsigned char dgst[20];

  SHA1(msg, msglen, dgst);

  return scope.Close(node::Buffer::New((const char*)dgst, 20)->handle_);
}

void init(Handle<Object> exports) {
  exports->Set(String::NewSymbol("sha1"),
    FunctionTemplate::New(Sha1)->GetFunction());
}

NODE_MODULE(token, init)

这是binding.gyp:

{
  'targets': [
    {
       "target_name": "token"
     , "sources": [ "src/sha_export.cc" ]
     ,'conditions': [
        ['node_shared_openssl=="false"', {
          # so when "node_shared_openssl" is "false", then OpenSSL has been
          # bundled into the node executable. So we need to include the same
          # header files that were used when building node.
          'include_dirs': [
            '<(node_root_dir)/deps/openssl/openssl/include'
          ],
          "conditions" : [
            ["target_arch=='ia32'", {
              "include_dirs": [ "<(node_root_dir)/deps/openssl/config/piii" ]
            }],
            ["target_arch=='x64'", {
              "include_dirs": [ "<(node_root_dir)/deps/openssl/config/k8" ]
            }],
            ["target_arch=='arm'", {
              "include_dirs": [ "<(node_root_dir)/deps/openssl/config/arm" ]
            }]
          ]
        }]
      ]
    }
  ]
}

我检查了我在 config.gypi 中是否将 node_shared_openssl 设置为 false,甚至在 /deps/openssl 中的 sha.h 中添加了 #error 以确保它被包含在内。但是,在需要插件时,我仍然会收到“未定义的符号:SHA1”,这显然意味着链接到捆绑的 OpenSSL 不起作用。如果我添加

     , 'link_settings': {
          'libraries': [
              '-lcrypto'
          ]
      }

之后sources,一切正常,但随后ldd token.node显示libcrypto.so.1.0.0 => /lib/i386-linux-gnu/libcrypto.so.1.0.0 (0xb7525000) 这意味着我现在正在链接到共享的动态 OpenSSL。所以我的问题是:是否有可能链接到与节点静态捆绑的 OpenSSL?那我做错了什么?

非常感谢!

PS 以防万一:操作系统是 Ubuntu 12.04 LTS

4

1 回答 1

2

好吧,回答我自己的问题......在 node.js IRC 上从 Ben Noordhuison 那里得到了一些帮助。非常感谢本!

显然,节点可执行文件公开的 OpenSSL 例程数量有限,基本上,只有那些节点自己使用,在我的情况下,它不包括更高级别的 SHA1 函数,但它确实包括较低级别的:SHA1_Init, SHA1_Update 和 SHA1_Final。改变了我的代码看起来像

SHA_CTX ctx;
SHA1_Init(&ctx);
SHA1_Update(&ctx, msg, msglen);
SHA1_Final(dgst, &ctx);

而不是只是SHA1(msg, msglen, dgst); ,它可以在没有外部依赖的情况下正常工作。

根据 Ben 的说法,在 Windows 上链接到静态 OpenSSL 也可能存在一些问题:无法对此发表评论,仅使用 Linux。

于 2013-09-21T15:16:27.477 回答