代码之家  ›  专栏  ›  技术社区  ›  JBaczuk

OpenSSL:EC\u POINT\u set\u compressed\u coordinates\u GFp segfault

  •  1
  • JBaczuk  · 技术社区  · 6 年前

    使用gdb来尝试精确定位segfault(实际上没有帮助),但我可能传递了错误的参数。以下是代码和回溯:

    echd.cc公司

    #include <node.h>
    #include <nan.h>
    #include <openssl/evp.h>
    #include <openssl/ec.h>
    
    using v8::Handle;
    using v8::FunctionTemplate;
    using v8::Object;
    using v8::String;
    
    static const size_t PRIVKEY_SIZE = 32;
    static const size_t PUBKEY_SIZE = 65;
    static const size_t COMPRESSED_PUBKEY_SIZE = 33;
    
    #define CHECK(cond) do { if (!(cond)) goto error; } while (0)
    
    int derive(const uint8_t* privkey_a, const uint8_t* pubkey_b, uint8_t* shared) {
      int rc = -1;
      int res;
      BIGNUM* pkey_bn = NULL;
      EC_KEY* pkey = NULL;
      bool compressed = false;
      EC_KEY* peerkey = NULL;
      int compressed_y_bit = 0;
      EC_POINT* peerkey_p = NULL;
      const EC_GROUP* peerkey_group = NULL;
      BN_CTX* peerkey_ctx = NULL;
      BIGNUM* peerkey_bn = NULL;
      BIGNUM* peerkey_bn_x = NULL;
      BIGNUM* peerkey_bn_y = NULL;
      EVP_PKEY* evp_pkey = NULL;
      EVP_PKEY* evp_peerkey = NULL;
      EVP_PKEY_CTX* ctx = NULL;
      size_t shared_len = PRIVKEY_SIZE;
    
      // Private key A.
      CHECK((pkey_bn = BN_bin2bn(privkey_a, PRIVKEY_SIZE, NULL)) != NULL);
      CHECK((pkey = EC_KEY_new_by_curve_name(NID_secp256k1)) != NULL);
      CHECK(EC_KEY_set_private_key(pkey, pkey_bn) == 1);
      CHECK((evp_pkey = EVP_PKEY_new()) != NULL);
      CHECK(EVP_PKEY_set1_EC_KEY(evp_pkey, pkey) == 1);
    
      // Public key B.
      CHECK((peerkey = EC_KEY_new_by_curve_name(NID_secp256k1)) != NULL);
      (pubkey_b[0] == 2 || pubkey_b[0] == 3) ? compressed = true : compressed = false;
      if (compressed) {
        (pubkey_b[0] == 2) ? compressed_y_bit = 0 : compressed_y_bit = 1;
        CHECK((peerkey_group = EC_KEY_get0_group(peerkey)) != NULL);
        CHECK((peerkey_ctx = BN_CTX_new()) != NULL);
        CHECK((peerkey_bn = BN_bin2bn(pubkey_b+1, COMPRESSED_PUBKEY_SIZE, NULL)) != NULL);
        CHECK((EC_POINT_set_compressed_coordinates_GFp(peerkey_group,
                                                     peerkey_p,
                                                     peerkey_bn,
                                                     compressed_y_bit,
                                                     NULL)) != NULL);
        ...
    

    (gdb) bt
    #0  0x00000000012097a3 in EC_POINT_set_compressed_coordinates_GFp ()
    #1  0x00007ffff4648446 in derive (privkey_a=0x2214af0 '\004' <repeats 32 times>, " \332+\002", pubkey_b=0x2214ec0 "\003\033\204\305V{\022d@\231]>Õª\272\005e\327\036\030\064`H\031\377\234\027\365\351\325\335\a\217\332+\002", shared=0x222d5d0 " c,\002") at ../ecdh.cc:51
    #2  0x00007ffff4648817 in Derive (info=...) at ../ecdh.cc:117
    #3  0x00007ffff4647756 in Nan::imp::FunctionCallbackWrapper (info=...) at ../node_modules/nan/nan_callbacks_12_inl.h:176
    #4  0x0000000000a94a43 in v8::internal::FunctionCallbackArguments::Call(void (*)(v8::FunctionCallbackInfo<v8::Value> const&)) ()
    #5  0x0000000000b0bbec in v8::internal::MaybeHandle<v8::internal::Object> v8::internal::(anonymous namespace)::HandleApiCallHelper<false>(v8::internal::Isolate*, v8::internal::Handle<v8::internal::HeapObject>, v8::internal::Handle<v8::internal::HeapObject>, v8::internal::Handle<v8::internal::FunctionTemplateInfo>, v8::internal::Handle<v8::internal::Object>, v8::internal::BuiltinArguments) ()
    #6  0x0000000000b0c83f in v8::internal::Builtin_HandleApiCall(int, v8::internal::Object**, v8::internal::Isolate*) ()
    #7  0x00002b6f5fe042fd in ?? ()
    #8  0x00002b6f5fe04241 in ?? ()
    #9  0x00007fffffffc610 in ?? ()
    #10 0x0000000000000006 in ?? ()
    ---Type <return> to continue, or q <return> to quit---q
    Quit
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   Reinier Torenbeek    6 年前

    这个 peerkey_p 在你呼吁 EC_POINT_set_compressed_coordinates_GFp() NULL ,而它应该是一个初始化的 EC_POINT *

    peerkey_p = EC_POINT_new(peerkey_group);
    

    这样就能排除故障。

    你似乎又犯了一个错误 COMPRESSED_PUBKEY_SIZE 33 . 是的,公钥的总大小是 字节。但是在推进指针之后 pubkey_b 1 仅字节 32 字节仍然与 BN_bin2bn() 功能。

    EC\点\集\压缩\坐标\ GFp() 无效的 ,您应该将其与

    推荐文章