c - EVP_UPDATE 永远不会返回

标签 c lua openssl

我正在重写 LuaCrypto,使其在 Lua 5.3 上运行并支持 SSL 1.1.0。 (其原始代码运行在 Lua 5.1 上,并支持最高 1.0 的 SSL)。

LuaCrypto 和 Lua 5.3 不兼容的主要原因是加载机制,该机制进行了重大修改,我通过替换所有与加载库相关的函数来使其工作。

LuaCrypto 和 SSL 1.1.0 之间不兼容的主要原因是现在 SSL 结构(特别是 EVP 和 HMAC)是不透明的,并且编译器不再知道这些结构的内部或其大小。

不幸的是,LibCrypto 依赖于了解此类结构的大小来将它们作为用户数据加载到 Lua 状态。显而易见的解决方案是重写该库,以便将 EVP 和 HMAC 结构加载为 lightuserdata,并重写垃圾收集器元方法以调用 SSL free/destroy/whatever,以便在不再需要这些结构时从这些结构中删除内存。

我做到了,只要我一步运行加密/解密/摘要,一切都很有趣和游戏。每当我尝试通过 EVP_UPDATE() 函数增量使用 EVP 时,机器会在调用此函数时卡住,但如果我尝试一步运行解密则不会卡住。

这是有问题的代码:

static HANDLER_EVP *evp_pget(lua_State *L, int i)
{
  if (luaL_checkudata(L, i, LUACRYPTO_EVPNAME) == NULL)
    luaL_typerror(L, i, LUACRYPTO_EVPNAME);
  return lua_touserdata(L, i);
}

void evp_pnew(lua_State *L, HANDLER_EVP *c)
{
  lua_pushlightuserdata(L, c);
  luaL_getmetatable(L, LUACRYPTO_EVPNAME);
  lua_setmetatable(L, -2);
}

static int evp_fnew(lua_State *L)

    {
  HANDLER_EVP *c = NULL;
  const char *s = luaL_checkstring(L, 1);
  DIGEST_TYPE type = DIGEST_BY_NAME(s);

  if (IS_DIGEST_INVALID(type)) {
    luaL_argerror(L, 1, "invalid digest type");
    return 0;
  }

    static int evp_update(lua_State *L)
{
  HANDLER_EVP *c = evp_pget(L, 1);
  size_t s_len;
  const char *s = luaL_checklstring(L, 2, &s_len);
  dumpStack(L);
  debug(L, "c=%p, s=\"%s\", s_len=%d", c, s, s_len);
  EVP_UPDATE(c, s, s_len); // HERE IS THE PROBLEM
  debug(L, "I AM HERE"); // never run

  lua_settop(L, 1);
  return 1;
}

这是 Lua 测试:

 for i, t in ipairs({"sha1", "md5", "sha1", "hmac"}) do
  print("testing " .. t)
  local d
  if (t == "hmac") then
    d = hmac.new("sha1", "luacrypto")
  else
    d = evp.new(t)
  end

  assert(io.input(F))
  print("all", d:digest(io.read("*all")), F, t)

  d:reset()

  assert(io.input(F))

  while true do
   local c = io.read(1)
   if c == nil then break end
   d:update(c)
  end
  print("loop", d:digest(), F, t)
  if (t ~= "hmac") then
    print("again", d:digest(), F, t)
    assert(io.input(F))
    print("alone", hmac.digest("sha1", io.read("*all"), "luacrypto"), F, t);
  else
    assert(io.input(F))
    print("alone", hmac.digest("sha1", io.read("*all"), "luacrypto"), F, t);
  end

  assert(io.input(F))
  d:reset()

  while true do
   local c = io.read(math.random(1, 16))
   if c == nil then break end
   d:update(c)
  end

  report("reset", d:digest(d), F, t)
  report("known", _G[t .. "_KNOWN"], F, t)
  print("")

end

这是输出:

testing sha1

TAG:lua_print LINE:141  

c=0xc14a8

TAG:lua_print LINE:141  

all     d6ed6e26ebeb37ba0792ec75a3d0b4dcec279d25           /mtd0/message      sha1

TAG:lua_print LINE:141  

estou aqui

TAG:lua_print LINE:141  

1: userdata

2: "T"



TAG:lua_print LINE:141  

c=0xc14a8, s="T", s_len=1

我错过了什么?

最佳答案

您无法为轻量级用户数据设置元表。

您需要将每个 SSL 结构指针装箱到(大量)用户数据中。

关于c - EVP_UPDATE 永远不会返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42210504/

相关文章:

google-chrome - 即使将证书添加到受信任的根权限存储区后,Chrome 仍显示红色 https Logo (内部使用自签名 SSL 证书)

c++ - 如何使用 SWIG 在 C++ API 上生成 C 包装器?

c# - Matlab调用C#或C并控制NI DAQ

c# - 从 linux C 到 Windows C# 的套接字问题

oauth-2.0 - 无法使用 Bearer Token 通过 Keycloak 进行身份验证

c - 在 C 中编写面向 Lua 的函数时,检查参数是否支持类表查找的好方法是什么?

lua - 在名为 foo.lua 的 Lua 文件中,名为 self.bar、foo.bar 和 bar 的变量之间有什么区别?

c - sizeof(struct) 不遵循填充

windows - OpenSSL 和读取 openssl.conf 文件时出错

openssl - 使用静态链接构建 libcurl 到 openssl